source: trunk/hal/tsar_mips32/drivers/soclib_pic.c @ 552

Last change on this file since 552 was 550, checked in by nicolas.van.phan@…, 6 years ago

Add SD card driver in kernel

File size: 20.3 KB
RevLine 
[75]1/*
2 * soclib_pic.c - soclib PIC driver implementation.
3 *
[188]4 * Author  Alain Greiner (2016,2017)
[141]5 *
[75]6 * Copyright (c) UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH.
9 *
[141]10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
[75]11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
[141]14 * ALMOS-MKH is distributed in the hope that it will be useful, but
[75]15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
[141]20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
[75]21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
[451]24#include <hal_kernel_types.h>
[75]25#include <chdev.h>
26#include <soclib_pic.h>
27#include <errno.h>
28#include <string.h>
29#include <vfs.h>
[296]30#include <rpc.h>
[188]31#include <cluster.h>
32#include <printk.h>
33#include <core.h>
34#include <thread.h>
[75]35
[188]36//////////////////////////////////////////////////////////////////////////////////////
37//         Extern variables
38//////////////////////////////////////////////////////////////////////////////////////
39
40extern  chdev_directory_t chdev_dir;    // defined in chdev.h / allocated in kerneL-init.c
41
42extern  iopic_input_t  iopic_input;  // defined in dev_pic.h / allocated in kernel_init.c
43extern  lapic_input_t  lapic_input;  // defined in dev_pic.h / allocated in kernel_init.c
44 
[407]45
46
[188]47//////////////////////////////////////////////////////////////////////////////////////
48//        SOCLIB PIC private functions
49//////////////////////////////////////////////////////////////////////////////////////
50
51///////////////////////////////
[481]52uint32_t soclib_pic_wti_alloc( void )
[188]53{
54    uint32_t index;
55
56    // get pointer on cluster extension for SOCLIB PIC (XCU descriptor)
57    soclib_pic_cluster_t * ext_ptr = LOCAL_CLUSTER->pic_extend;
58
[492]59    assert( (ext_ptr->first_free_wti < ext_ptr->wti_nr) ,
[188]60            "no free WTI found : too much external IRQs\n");
61
62    // update WTI allocator
63    index = ext_ptr->first_free_wti;
64    ext_ptr->first_free_wti++;
65
66    return index;
67
68}  // end soclib_pic_wti_alloc()
69
70///////////////////////////////////////
[481]71inline uint32_t * soclib_pic_xcu_base( void )
[188]72{
[205]73    return ((soclib_pic_cluster_t *)(LOCAL_CLUSTER->pic_extend))->xcu_base;
74}
[188]75
[205]76/////////////////////////////////////////////////////////
77inline uint32_t * soclib_pic_remote_xcu_base( cxy_t cxy )
78{
79    soclib_pic_cluster_t * extend;
[188]80
[205]81    // get extended pointer on PIC extension in remote cluster
82    extend = hal_remote_lpt( XPTR( cxy , &cluster_manager.pic_extend ) );
[188]83
[205]84        return (uint32_t *)hal_remote_lpt( XPTR( cxy , &extend->xcu_base ) );
85                 
86}
87
[188]88///////////////////////////////////////////
89void soclib_pic_xcu_status( lid_t      lid,
90                            uint32_t * hwi_status,
91                            uint32_t * wti_status,
92                            uint32_t * pti_status )
93{
94    // get local XCU segment base
95        uint32_t * base = soclib_pic_xcu_base();
96
97    // read PRIO register
[432]98    // in TSAR : XCU output [4*lid] is connected to core [lid]
99        uint32_t prio = base[ (XCU_PRIO << 5) | (lid<<2) ];
[188]100
101    *wti_status = (prio & 0x4) ? (((prio >> 24) & 0x1F) + 1) : 0;
102    *hwi_status = (prio & 0x2) ? (((prio >> 16) & 0x1F) + 1) : 0;
103    *pti_status = (prio & 0x1) ? (((prio >>  8) & 0x1F) + 1) : 0;
104
105}
106
[279]107////////////////////////////////////////////////////
108inline uint32_t soclib_pic_xcu_ack( uint32_t * reg )
109{
110    return *reg;
111}
112
[188]113/////////////////////////////
[481]114void soclib_pic_irq_handler( void )
[188]115{
116    uint32_t   hwi_status;   // HWI index + 1  / no pending HWI if 0
117    uint32_t   wti_status;   // WTI index + 1  / no pending WTI if 0
118    uint32_t   pti_status;   // PTI index + 1  / no pending PTI if 0
119    chdev_t  * src_chdev;    // pointer on source chdev descriptor
[279]120    uint32_t   index;        // WTI / HWI / PTI index
[188]121
[406]122    uint32_t * xcu_base = soclib_pic_xcu_base();
[188]123
[406]124    core_t   * core = CURRENT_THREAD->core;
125
[188]126    // get XCU status
127    soclib_pic_xcu_status( core->lid,
128                           &hwi_status,
129                           &wti_status,
130                           &pti_status );
131
[438]132#if DEBUG_HAL_IRQS
[435]133uint32_t cycle = (uint32_t)hal_get_cycles();
[438]134if (DEBUG_HAL_IRQS < cycle )
[435]135printk("\n[DBG] %s : core[%x,%d] enter / WTI = %x / HWI = %x / PTI = %x / cycle %d\n",
136__FUNCTION__ , local_cxy , core->lid , wti_status , hwi_status , pti_status, cycle );
137#endif
[279]138
[457]139    // analyse status and handle up to 3 pending IRQs (one WTI, one HWI, one PTI)
[188]140
141    if( wti_status )          // pending WTI
142        {
143        index = wti_status - 1;
144
[438]145        ////////////////////////////////////////////////////////
[188]146        if( index < LOCAL_CLUSTER->cores_nr )   // it is an IPI
147        {
[492]148            assert( (index == core->lid) , "illegal IPI index" );
[188]149
[438]150#if DEBUG_HAL_IRQS
151if (DEBUG_HAL_IRQS < cycle )
[457]152printk("\n[DBG] %s : core[%x,%d] handling IPI\n", __FUNCTION__ , local_cxy , core->lid );
[435]153#endif
[438]154            // acknowledge IRQ (this require an XCU read)
[406]155            uint32_t   ack  = xcu_base[(XCU_WTI_REG << 5) | core->lid];
[438]156
[296]157            // check RPC FIFO,  and activate or create a RPC thread
[457]158            // condition is always true, but we use the ack value
159            // to avoid a GCC warning
[337]160            if( ack + 1 ) rpc_check();
[188]161        }
[438]162        ////////////////////////////////////////////////////////////////
163        else                                    // it is an external IRQ
[188]164        {
165            // get pointer on source chdev
166            src_chdev = ((soclib_pic_core_t *)core->pic_extend)->wti_vector[index];
167
168                    if( src_chdev == NULL )        // strange, but not fatal
169                    {
170                printk("\n[WARNING] in %s : no handler for WTI %d on core %d in cluster %x\n",
171                       __FUNCTION__ , index , core->lid , local_cxy );
172
173                    core->spurious_irqs ++;
174
[279]175                // disable WTI in local XCU controller
[438]176                xcu_base[(XCU_MSK_WTI_DISABLE << 5) | core->lid] = 1 << core->lid;
177
178                hal_fence();
[188]179            }
180            else                                 // call relevant ISR
181            {
182
[438]183#if DEBUG_HAL_IRQS
184if (DEBUG_HAL_IRQS < cycle )
[457]185printk("\n[DBG] %s : core[%x,%d] handling external WTI %d\n",
[435]186__FUNCTION__ , local_cxy , core->lid , index );
187#endif
[188]188                // call ISR
189                    src_chdev->isr( src_chdev );
190            }
191        }
192        }
193
[438]194    /////////////////////////////////////////////////////////////
195        if( hwi_status )                     // It is an Internal IRQ
[188]196        {
197        index = hwi_status - 1;
198
199        // get pointer on source chdev
200        src_chdev = ((soclib_pic_core_t *)core->pic_extend)->hwi_vector[index];
201
202                if( src_chdev == NULL )        // strange, but not fatal
203                {
204            printk("\n[WARNING] in %s : no handler for HWI %d on core %d in cluster %x\n",
205                   __FUNCTION__ , index , core->lid , local_cxy );
206
207                core->spurious_irqs ++;
208
[279]209            // disable HWI in local XCU controller
[406]210            xcu_base[(XCU_MSK_HWI_DISABLE << 5) | core->lid] = 1 << core->lid;
[438]211
212            hal_fence();
[188]213                }
214        else                    // call relevant ISR
215        {
216
[438]217#if DEBUG_HAL_IRQS
218if (DEBUG_HAL_IRQS < cycle )
[457]219printk("\n[DBG] %s : core[%x,%d] handling HWI %d\n",
[435]220__FUNCTION__ , local_cxy , core->lid , index );
221#endif
[188]222            // call ISR
223                    src_chdev->isr( src_chdev );
224        }
225        }
[438]226    ///////////////////////////////////////////////////////
227    if( pti_status )                   // It is a Timer IRQ
[188]228        {
229        index = pti_status - 1;
230
[492]231        assert( (index == core->lid) , "unconsistent PTI index\n");
[188]232
[438]233#if DEBUG_HAL_IRQS
234if (DEBUG_HAL_IRQS < cycle )
[457]235printk("\n[DBG] %s : core[%x,%d] handling PTI %d\n",
[435]236__FUNCTION__ , core->lid , local_cxy , index );
237#endif
[438]238        // acknowledge IRQ (this require a read access to XCU)
[406]239        uint32_t   ack  = xcu_base[(XCU_PTI_ACK << 5) | core->lid];
[188]240
[279]241        // execute all actions related to TICK event
[457]242        // condition is always true, but we use the ack value
243        // to avoid a GCC warning
[406]244        if( ack + 1 ) core_clock( core );
[188]245        }
246}  // end soclib_pic_irq_handler()
247
248
249
250
251//////////////////////////////////////////////////////////////////////////////////////
252//         SOCLIC PIC device  generic API
253//////////////////////////////////////////////////////////////////////////////////////
254
255/////////////////////////////////////
256void soclib_pic_init( chdev_t * pic )
257{
258    uint32_t    i;      // for loop on IOPIC inputs
259
260    // get IOPIC controller cluster and segment base pointer
[451]261    cxy_t      iopic_seg_cxy = GET_CXY( pic->base );
262    uint32_t * iopic_seg_ptr = GET_PTR( pic->base );
[188]263
[407]264    // reset the IOPIC component registers : disable all input IRQs
[188]265    for( i = 0 ; i < CONFIG_MAX_EXTERNAL_IRQS ; i++ )
266    {
267        xptr_t iopic_seg_xp = XPTR( iopic_seg_cxy,
268                                    iopic_seg_ptr + i*IOPIC_SPAN + IOPIC_MASK ); 
269        hal_remote_sw( iopic_seg_xp , 0 ); 
270    }
271
272}  // end soclib_pic_init()
273
274//////////////////////////////////////////////////
275void soclib_pic_extend_init( uint32_t * xcu_base )
276{
277    soclib_pic_cluster_t * cluster_ext_ptr;   
278    soclib_pic_core_t    * core_ext_ptr;
279    kmem_req_t             req;
280    uint32_t               lid;
281    uint32_t               idx;
282
283    cluster_t            * cluster = LOCAL_CLUSTER;
284
285    // create core extension for all cores in cluster
286    for( lid = 0 ; lid < cluster->cores_nr ; lid++ )
287    {
288        // allocate memory for core extension
289        req.type     = KMEM_GENERIC;
290        req.size     = sizeof(soclib_pic_core_t);
291        req.flags    = AF_KERNEL;
292        core_ext_ptr = kmem_alloc( &req );
293
[492]294        assert( (core_ext_ptr != NULL) ,
[188]295                "cannot allocate memory for core extension\n");
296   
297        // reset the HWI / WTI  interrupt vectors
298        for( idx = 0 ; idx < SOCLIB_MAX_HWI ; idx++ ) core_ext_ptr->hwi_vector[idx] = NULL;
299        for( idx = 0 ; idx < SOCLIB_MAX_WTI ; idx++ ) core_ext_ptr->wti_vector[idx] = NULL;
300
301        // register PIC extension in core descriptor
302        cluster->core_tbl[lid].pic_extend = core_ext_ptr;
303    }
304
305    // allocate memory for cluster extension
306    req.type        = KMEM_GENERIC;
307    req.size        = sizeof(soclib_pic_cluster_t);
308    req.flags       = AF_KERNEL;
309    cluster_ext_ptr = kmem_alloc( &req );
310
[492]311    assert( (cluster_ext_ptr != NULL) ,
[188]312            "cannot allocate memory for cluster extension\n");
313
314    // get XCU characteristics from the XCU config register
315    uint32_t  config = xcu_base[XCU_CONFIG<<5];
316    uint32_t  wti_nr = (config >> 16) & 0xFF; 
317    uint32_t  hwi_nr = (config >> 8 ) & 0xFF; 
318    uint32_t  pti_nr = (config      ) & 0xFF; 
319
320    // initialize the cluster extension
321    // The first WTI slots are for IPIs (one slot per core)
322    cluster_ext_ptr->xcu_base       = xcu_base;
323    cluster_ext_ptr->hwi_nr         = hwi_nr;
324    cluster_ext_ptr->wti_nr         = wti_nr;
325    cluster_ext_ptr->pti_nr         = pti_nr;
326    cluster_ext_ptr->first_free_wti = cluster->cores_nr;
327
328    // register PIC extension in cluster manager
329    cluster->pic_extend = cluster_ext_ptr;
330
[451]331    // reset the XCU component registers
332    // mask all HWIs, all WTIs, and all PTIs, for all cores in local cluster   
333    for( lid = 0 ; lid < cluster->cores_nr ; lid++ )
334    {
335        xcu_base[XCU_MSK_HWI_DISABLE << 5 | lid] = 0xFFFFFFFF;
336        xcu_base[XCU_MSK_WTI_DISABLE << 5 | lid] = 0xFFFFFFFF;
337        xcu_base[XCU_MSK_PTI_DISABLE << 5 | lid] = 0xFFFFFFFF;
338    }
339
[188]340}  // end soclib_pic_extend_init()
341
[75]342////////////////////////////////////////
[188]343void soclib_pic_bind_irq( lid_t     lid,
344                          chdev_t * src_chdev )
[75]345{
[435]346
[438]347#if DEBUG_HAL_IRQS
[435]348uint32_t cycle = (uint32_t)hal_get_cycles();
[438]349if( DEBUG_HAL_IRQS < cycle )
[435]350printk("\n[DBG] %s : thread %x enter for core[%x,%d] / cycle %d\n",
351__FUNCTION__ , CURRENT_THREAD , local_cxy , lid , cycle );
352#endif
353
[188]354    // get extended & local pointers on PIC chdev descriptor
355    xptr_t     pic_xp  = chdev_dir.pic;
356    cxy_t      pic_cxy = GET_CXY( pic_xp );
357    chdev_t *  pic_ptr = (chdev_t *)GET_PTR( pic_xp );
[75]358
[188]359    // get extended and local pointers on IOPIC  segment base
360    xptr_t     seg_pic_xp  = hal_remote_lwd( XPTR( pic_cxy , &pic_ptr->base ) );
361    cxy_t      seg_pic_cxy = GET_CXY( seg_pic_xp );
362    uint32_t * seg_pic_ptr = (uint32_t *)GET_PTR( seg_pic_xp );
363
364    // get local pointer on XCU segment base
365    uint32_t * seg_xcu_ptr = soclib_pic_xcu_base();
366
367    // get the source chdev functionnal type, channel, and direction
368    uint32_t func    = src_chdev->func;
[534]369    uint32_t impl    = src_chdev->impl;
[188]370    uint32_t channel = src_chdev->channel;
371    bool_t   is_rx   = src_chdev->is_rx;
372
[550]373    if( (func == DEV_FUNC_IOC && impl == IMPL_IOC_BDV) || (func == DEV_FUNC_NIC) ||
[534]374        (func == DEV_FUNC_TXT && impl == IMPL_TXT_TTY) || (func == DEV_FUNC_IOB) )          // external IRQ => WTI
[75]375    {
[188]376        // get external IRQ index
[407]377        uint32_t  hwi_id;   
378        if     (  func == DEV_FUNC_IOC            ) hwi_id = iopic_input.ioc[channel];
379        else if(  func == DEV_FUNC_TXT  &&  is_rx ) hwi_id = iopic_input.txt_rx[channel];
380        else if(  func == DEV_FUNC_TXT  && !is_rx ) hwi_id = iopic_input.txt_tx[channel];
381        else if( (func == DEV_FUNC_NIC) &&  is_rx ) hwi_id = iopic_input.nic_rx[channel];
382        else if( (func == DEV_FUNC_NIC) && !is_rx ) hwi_id = iopic_input.nic_tx[channel];
383        else if(  func == DEV_FUNC_IOB            ) hwi_id = iopic_input.iob;
[492]384        else      assert( false , "illegal device functionnal type\n");
[188]385
386        // get a WTI mailbox from local XCU descriptor 
387        uint32_t wti_id = soclib_pic_wti_alloc();
388
389        // register IRQ type and index in chdev
390        src_chdev->irq_type = SOCLIB_TYPE_WTI;
391        src_chdev->irq_id   = wti_id;
392
393        // compute extended pointer on WTI mailbox in local XCU
394        xptr_t wti_xp = XPTR( local_cxy , &seg_xcu_ptr[(XCU_WTI_REG << 5) | wti_id] );
395
396            // set the IOPIC_ADDRESS and IOPIC_EXTEND registers in IOPIC
397        uint32_t lsb_wdata = (uint32_t)wti_xp;
398        uint32_t msb_wdata = (uint32_t)(wti_xp >> 32);
[407]399        xptr_t   lsb_xp = XPTR( seg_pic_cxy , seg_pic_ptr+hwi_id*IOPIC_SPAN+IOPIC_ADDRESS );
400        xptr_t   msb_xp = XPTR( seg_pic_cxy , seg_pic_ptr+hwi_id*IOPIC_SPAN+IOPIC_EXTEND );
[188]401        hal_remote_sw( lsb_xp , lsb_wdata );
402        hal_remote_sw( msb_xp , msb_wdata );
403
[407]404        // enable IRQ in IOPIC
405        hal_remote_sw( XPTR( seg_pic_cxy , seg_pic_ptr+hwi_id*IOPIC_SPAN+IOPIC_MASK ), 1 );
[188]406
407        // update the WTI interrupt vector for core[lid]
408        core_t * core = &LOCAL_CLUSTER->core_tbl[lid];
409        ((soclib_pic_core_t *)core->pic_extend)->wti_vector[wti_id] = src_chdev;
[407]410
[438]411#if DEBUG_HAL_IRQS
412if( DEBUG_HAL_IRQS < cycle )
[435]413printk("\n[DBG] %s : %s / channel = %d / rx = %d / hwi_id = %d / wti_id = %d / cluster = %x\n",
[407]414__FUNCTION__ , chdev_func_str( func ) , channel , is_rx , hwi_id , wti_id , local_cxy );
[435]415#endif
[407]416
[75]417    }
[534]418    else if( (func == DEV_FUNC_DMA) || (func == DEV_FUNC_MMC) ||
[550]419             (func == DEV_FUNC_TXT && impl == IMPL_TXT_MTY) ||
420             (func == DEV_FUNC_IOC && impl == IMPL_IOC_SPI) )   // internal IRQ => HWI
[188]421    {
422        // get internal IRQ index
423        uint32_t hwi_id;
424        if( func == DEV_FUNC_DMA ) hwi_id = lapic_input.dma[channel];
[534]425        else if (func == DEV_FUNC_TXT ) hwi_id = lapic_input.mtty;
[550]426        else if (func == DEV_FUNC_IOC ) hwi_id = lapic_input.sdcard;
[188]427        else                       hwi_id = lapic_input.mmc;
[75]428
[188]429        // register IRQ type and index in chdev
430        src_chdev->irq_type = SOCLIB_TYPE_HWI;
431        src_chdev->irq_id   = hwi_id;
432
433        // update the HWI interrupt vector for core[lid]
434        core_t * core = &LOCAL_CLUSTER->core_tbl[lid];
[468]435        ((soclib_pic_core_t *)core->pic_extend)->hwi_vector[hwi_id] = src_chdev;
[407]436
[438]437#if DEBUG_HAL_IRQS
438if( DEBUG_HAL_IRQS < cycle )
[435]439printk("\n[DBG] %s : %s / channel = %d / hwi_id = %d / cluster = %x\n",
[407]440__FUNCTION__ , chdev_func_str( func ) , channel , hwi_id , local_cxy );
[435]441#endif
[407]442
[188]443    }
444    else
445    {
[492]446        assert( false , "illegal device functionnal type\n" );
[188]447    } 
448}  // end soclib_pic_bind_irq();
449
[205]450///////////////////////////////////////
451void soclib_pic_enable_irq( lid_t  lid,
452                            xptr_t src_chdev_xp )
[75]453{
[205]454    // get cluster and local pointer on remote src_chdev
455    cxy_t     src_chdev_cxy = GET_CXY( src_chdev_xp );
456    chdev_t * src_chdev_ptr = (chdev_t *)GET_PTR( src_chdev_xp );
[141]457
[205]458    // get local pointer on remote XCU segment base
459    uint32_t * seg_xcu_ptr = soclib_pic_remote_xcu_base( src_chdev_cxy );
460
[188]461    // get the source chdev IRQ type and index
[205]462    uint32_t irq_type = hal_remote_lw( XPTR( src_chdev_cxy , &src_chdev_ptr->irq_type ) );
463    uint32_t irq_id   = hal_remote_lw( XPTR( src_chdev_cxy , &src_chdev_ptr->irq_id ) );
[141]464
[188]465    if( irq_type == SOCLIB_TYPE_HWI )
466    {
[205]467        // enable this HWI in remote XCU controller
[432]468        // in TSAR : XCU output [4*lid] is connected to core [lid]
[205]469        hal_remote_sw( XPTR( src_chdev_cxy , 
[440]470                       &seg_xcu_ptr[ (XCU_MSK_HWI_ENABLE << 5) | (lid<<2) ] ) , (1 << irq_id) );
[188]471    }
472    else if( irq_type == SOCLIB_TYPE_WTI )
473    {
[279]474        // enable this WTI in remote XCU controller
[432]475        // in TSAR : XCU output [4*lid] is connected to core [lid]
[205]476        hal_remote_sw( XPTR( src_chdev_cxy , 
[440]477                       &seg_xcu_ptr[ (XCU_MSK_WTI_ENABLE << 5) | (lid<<2) ] ) , (1 << irq_id) );
[188]478    }
479    else
480    {
[492]481        assert( false , "illegal IRQ type\n" );
[188]482    }
483} // end soclib_pic_enable_irq()
[75]484
[205]485////////////////////////////////////////
486void soclib_pic_disable_irq( lid_t  lid,
487                             xptr_t src_chdev_xp )
[188]488{
[205]489    // get cluster and local pointer on remote src_chdev
490    cxy_t     src_chdev_cxy = GET_CXY( src_chdev_xp );
491    chdev_t * src_chdev_ptr = (chdev_t *)GET_PTR( src_chdev_xp );
[75]492
[205]493    // get local pointer on remote XCU segment base
494    uint32_t * seg_xcu_ptr = soclib_pic_remote_xcu_base( src_chdev_cxy );
495
[188]496    // get the source chdev IRQ type and index
[205]497    uint32_t irq_type = hal_remote_lw( XPTR( src_chdev_cxy , &src_chdev_ptr->irq_type ) );
498    uint32_t irq_id   = hal_remote_lw( XPTR( src_chdev_cxy , &src_chdev_ptr->irq_id ) );
[75]499
[188]500    if( irq_type == SOCLIB_TYPE_HWI )
501    {
[432]502        // enable this HWI in remote XCU controller
503        // in TSAR : XCU output [4*lid] is connected to core [lid]
[205]504        hal_remote_sw( XPTR( src_chdev_cxy , 
[432]505                       &seg_xcu_ptr[(XCU_MSK_HWI_DISABLE << 5) | (lid<<2) ] ) , (1 << irq_id) );
[188]506    }
507    else if( irq_type == SOCLIB_TYPE_WTI )
508    {
[279]509        // enable this WTI in remote XCU controller
[432]510        // in TSAR : XCU output [4*lid] is connected to core [lid]
[205]511        hal_remote_sw( XPTR( src_chdev_cxy , 
[440]512                       &seg_xcu_ptr[(XCU_MSK_WTI_DISABLE << 5) | (lid<<2) ] ) , (1 << irq_id) );
[188]513    }
514    else
515    {
[492]516        assert( false , "illegal IRQ type\n" );
[188]517    }
518} // end soclib_pic_enable_irq()
[75]519
[188]520///////////////////////////////////////////////
521void soclib_pic_enable_timer( uint32_t period )
[75]522{
[188]523    // calling core local index
[457]524    lid_t  lid = CURRENT_THREAD->core->lid;
[141]525
[188]526    // get XCU segment base
527    uint32_t * base = soclib_pic_xcu_base();
[141]528
[380]529    // set period value in XCU (in cycles)
[407]530    uint32_t cycles = period * SOCLIB_CYCLES_PER_MS;
[380]531    base[(XCU_PTI_PER << 5) | lid] = cycles;
[75]532
[279]533    // enable PTI in local XCU controller
[432]534    // In TSAR : XCU output [4*lid] is connected to core [lid]
535    base[ (XCU_MSK_PTI_ENABLE << 5) | (lid<<2) ] = 1 << lid;
[75]536}
537
[279]538////////////////////////////
[481]539void soclib_pic_enable_ipi( void )
[279]540{
541    // calling core local index
[457]542    lid_t  lid = CURRENT_THREAD->core->lid;
[279]543
544    // get XCU segment base
545    uint32_t * base = soclib_pic_xcu_base();
546
547    // enable WTI in local XCU controller
[432]548    // In TSAR : XCU output [4*lid] is connected to core [lid]
549    base[ (XCU_MSK_WTI_ENABLE << 5) | (lid<<2) ] = 1 << lid;
[279]550}
551
[188]552///////////////////////////////////////
553void soclib_pic_send_ipi( cxy_t    cxy,
554                          lid_t    lid )
[75]555{
[188]556    // get pointer on local XCU segment base
557    uint32_t * base = soclib_pic_xcu_base();
[141]558
[188]559    // write to WTI mailbox[cxy][lid]
[432]560    hal_remote_sw( XPTR( cxy , &base[(XCU_WTI_REG << 5) | lid ] ) , 0 );
[188]561}
[141]562
[407]563/////////////////////////
[481]564void soclib_pic_ack_ipi( void )
[407]565{
566    // get calling core local index
567    lid_t      lid  = CURRENT_THREAD->core->lid;
[75]568
[407]569    // get pointer on local XCU segment base
570    uint32_t * base = soclib_pic_xcu_base();
[75]571
[407]572    // acknowlege IPI
[432]573    uint32_t   ack  = base[ (XCU_WTI_REG << 5) | lid ];
[407]574
575    // we must make a fake use for ack value to avoid a warning
[424]576    if( (ack + 1) == 0 ) asm volatile( "nop" );
[407]577}
578   
579
Note: See TracBrowser for help on using the repository browser.