Changeset 203 for soft/giet_vm/sys


Ignore:
Timestamp:
Aug 13, 2012, 10:52:25 PM (12 years ago)
Author:
alain
Message:

Introducing support for XICU

Location:
soft/giet_vm/sys
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/sys/common.h

    r199 r203  
    1919extern _ld_symbol_t seg_iob_base;
    2020extern _ld_symbol_t seg_icu_base;
    21 extern _ld_symbol_t seg_timer_base;
     21extern _ld_symbol_t seg_tim_base;
    2222extern _ld_symbol_t seg_tty_base;
    2323extern _ld_symbol_t seg_gcd_base;
    2424extern _ld_symbol_t seg_dma_base;
    25 extern _ld_symbol_t seg_fb_base;
     25extern _ld_symbol_t seg_fbf_base;
    2626extern _ld_symbol_t seg_ioc_base;
    2727extern _ld_symbol_t seg_mapping_base;
  • soft/giet_vm/sys/drivers.c

    r199 r203  
    1111// - vci_multi_dma
    1212// - vci_multi_icu
    13 // - vci_xicu
     13// - vci_xicu & vci_multi_icu
    1414// - vci_gcd
    1515// - vci_frame_buffer
     
    2323// - NB_TTYS   
    2424//
    25 // The following base addresses must be defined in the sys.ld file:
     25// The following virtual base addresses must be defined in the sys.ld file:
    2626// - seg_icu_base
    27 // - seg_timer_base
     27// - seg_tim_base
    2828// - seg_tty_base
    2929// - seg_gcd_base
    3030// - seg_dma_base
    31 // - seg_fb_base
     31// - seg_fbf_base
    3232// - seg_ioc_base
    3333///////////////////////////////////////////////////////////////////////////////////
     
    9393#define in_unckdata __attribute__((section (".unckdata")))
    9494
    95 
    9695//////////////////////////////////////////////////////////////////////////////
    97 //      VciMultiTimer driver
     96//      Timers driver
    9897//////////////////////////////////////////////////////////////////////////////
    99 // There is one multi_timer (or xicu) component per cluster.
    100 // The global index is cluster_id*(NB_PROCS_MAX+NB_TIMERS_MAX) + local_id
     98// The timers can be implemented in a vci_timer component or in a vci_xicu
     99// component (depending on the GIET_USE_XICU parameter).
     100// There is one timer (or xicu) component per cluster.
    101101// There is two types of timers:
    102102// - "system" timers : one per processor, used for context switch.
    103103//   local_id in [0, NB_PROCS_MAX-1],
    104104// - "user" timers : requested by the task in the mapping_info data structure.
    105 //   local_id in [NB_PROC_MAX, NB_PROCS_MAX+NB_TIMERS_MAX-1],
    106 //   For each user timer, the tty_id is stored in the context of the task
    107 //   and must be explicitely defined in the boot code.
    108 // These timers can be implemented in a vci_multi_timer component
    109 // or in a vci_xicu component (depending on the GIET_USE_XICU parameter).
     105//   local_id in [NB_PROC_MAX, NB_PROCS_MAX + NB_TIMERS_MAX - 1]
     106//   For each user timer, the timer_id is stored in the context of the task.
     107// The global index is cluster_id * (NB_PROCS_MAX+NB_TIMERS_MAX) + local_id
    110108//////////////////////////////////////////////////////////////////////////////
    111109
     
    118116
    119117//////////////////////////////////////////////////////////////////////////////
    120 //     _timer_access()
    121 // This function is the only way to access a timer device.
    122 // It can be a multi-timer component or an xicu component.
    123 // It can be used by the kernel to initialise a "system" timer,
     118//     _timer_start()
     119// This function activates a timer in the vci_timer (or vci_xicu) component
     120// by writing in the proper register the period value.
     121// It can be used by both the kernel to initialise a "system" timer,
    124122// or by a task (through a system call) to configure an "user" timer.
    125123// Returns 0 if success, > 0 if error.
    126124//////////////////////////////////////////////////////////////////////////////
    127 unsigned int _timer_access( unsigned int        read,
    128                             unsigned int        cluster_id,
    129                             unsigned int        local_id,
    130                             unsigned int        register_id,
    131                             unsigned int*       buffer )
     125unsigned int _timer_start( unsigned int cluster_id,
     126                           unsigned int local_id,
     127                           unsigned int period )
    132128{
    133129    // parameters checking
    134     if ( register_id >= TIMER_SPAN)                                     return 1;
    135130    if ( cluster_id >= NB_CLUSTERS)                                     return 1;
    136131    if ( local_id >= NB_TIMERS_MAX + NB_PROCS_MAX ) return 1;
    137132
    138133#if GIET_USE_XICU
    139 
    140     unsigned int* timer_address = //TODO
    141 
     134    unsigned int* timer_address = (unsigned int*)&seg_icu_base +
     135                                  (cluster_id * CLUSTER_SPAN);
     136
     137    timer_address[XICU_REG(XICU_PTI_PER, local_id)] = period;
    142138#else
    143 
    144     unsigned int* timer_address = (unsigned int*)&seg_timer_base +
    145                                   (cluster_id * CLUSTER_SPAN)  +
    146                                   (local_id * TIMER_SPAN);
    147 #endif
    148 
    149     if (read)   *buffer = timer_address[register_id]; // read word
    150     else                timer_address[register_id] = *buffer; // write word
     139    unsigned int* timer_address = (unsigned int*)&seg_tim_base +
     140                                  (cluster_id * CLUSTER_SPAN);
     141
     142    timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
     143    timer_address[local_id * TIMER_SPAN + TIMER_MODE]   = 0x3;
     144#endif
     145
    151146    return 0;
    152147}
    153148//////////////////////////////////////////////////////////////////////////////
    154 //     _timer_write()
    155 // This function implements a write access to a "user" timer register.
    156 // It gets the cluster_id and local_id from the global index stored in
    157 // the task context and use the timer_access() function to make the write.
     149//     _timer_stop()
     150// This function desactivates a timer in the vci_timer (or vci_xicu) component
     151// by writing in the proper register.
    158152// Returns 0 if success, > 0 if error.
    159153//////////////////////////////////////////////////////////////////////////////
    160 unsigned int _timer_write( unsigned int register_id,
    161                            unsigned int value )
    162 {
    163     unsigned int buffer     = value;
    164     unsigned int task_id    = _get_current_task_id();
    165     unsigned int timer_id   = _get_context_slot(task_id, CTX_TIMER_ID);
    166     unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX);
    167     unsigned int local_id   = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX);
    168 
    169     // checking user timer
    170     if ( local_id < NB_PROCS_MAX )
    171     {
    172         return 2;
    173     }
    174     else
    175     {
    176         return _timer_access ( 0,                               // write access
    177                                cluster_id,
    178                                local_id,
    179                                register_id,
    180                                &buffer );
    181     }
     154unsigned int _timer_stop( unsigned int  cluster_id,
     155                          unsigned int  local_id )
     156{
     157    // parameters checking
     158    if ( cluster_id >= NB_CLUSTERS)                                     return 1;
     159    if ( local_id >= NB_TIMERS_MAX + NB_PROCS_MAX ) return 1;
     160
     161#if GIET_USE_XICU
     162    unsigned int* timer_address = (unsigned int*)&seg_icu_base +
     163                                  (cluster_id * CLUSTER_SPAN);
     164
     165    timer_address[XICU_REG(XICU_PTI_PER, local_id)] = 0;
     166#else
     167    unsigned int* timer_address = (unsigned int*)&seg_tim_base +
     168                                  (cluster_id * CLUSTER_SPAN);
     169
     170    timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0;
     171#endif
     172
     173    return 0;
    182174}
    183175//////////////////////////////////////////////////////////////////////////////
    184 //     _timer_read()
    185 // This function implements a read access to a "user" timer register.
    186 // It gets the cluster_id and local_id from the global index stored in
    187 // the task context and use the timer_access() function to make the read.
     176//     _timer_reset_irq()
     177// This function acknowlegge a timer interrupt in the vci_timer (or vci_xicu)
     178// component by writing in the proper register the period value.
     179// It can be used by both the isr_switch() for a "system" timer,
     180// or by the _isr_timer() for an "user" timer.
    188181// Returns 0 if success, > 0 if error.
    189182//////////////////////////////////////////////////////////////////////////////
    190 unsigned int _timer_read( unsigned int  register_id,
    191                           unsigned int* buffer )
    192 {
    193     unsigned int task_id    = _get_current_task_id();
    194     unsigned int timer_id   = _get_context_slot(task_id, CTX_TIMER_ID);
    195     unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX);
    196     unsigned int local_id   = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX);
    197 
    198     // checking user timer
    199     if ( local_id < NB_PROCS_MAX )
    200     {
    201         return 2;
    202     }
    203     else
    204     {
    205         return _timer_access ( 1,                               // read access
    206                                cluster_id,
    207                                local_id,
    208                                register_id,
    209                                buffer );
    210     }
    211 }
    212 /////////////////////////////////////////////////////////////////////////////////
    213 //     _timer_check()
    214 /////////////////////////////////////////////////////////////////////////////////
     183unsigned int _timer_reset_irq( unsigned int     cluster_id,
     184                               unsigned int     local_id )
     185{
     186    // parameters checking
     187    if ( cluster_id >= NB_CLUSTERS)                                     return 1;
     188    if ( local_id >= NB_TIMERS_MAX + NB_PROCS_MAX ) return 1;
     189
     190#if GIET_USE_XICU
     191    unsigned int* timer_address = (unsigned int*)&seg_icu_base +
     192                                  (cluster_id * CLUSTER_SPAN);
     193
     194    unsigned int bloup = timer_address[XICU_REG(XICU_PTI_ACK, local_id)];
     195#else
     196    unsigned int* timer_address = (unsigned int*)&seg_tim_base +
     197                                  (cluster_id * CLUSTER_SPAN);
     198
     199    timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0;
     200#endif
     201
     202    return 0;
     203}
    215204
    216205/////////////////////////////////////////////////////////////////////////////////
     
    349338//      VciMultiIcu and VciXicu drivers
    350339////////////////////////////////////////////////////////////////////////////////
    351 // There is in principle one vci_multi_icu (or vci_xicu) component per cluster,
    352 // and the number of independant ICUs is equal to NB_PROCS_MAX, because there is
    353 // one private interrupr controler per processor.
    354 ////////////////////////////////////////////////////////////////////////////////
    355 
    356 ////////////////////////////////////////////////////////////////////////////////
    357 //     _icu_write()
    358 // Write a 32-bit word in a memory mapped register of the MULTI_ICU device,
    359 // identified by the cluster index, and a processor local index.
    360 // Returns 0 if success, > 0 if error.
    361 ////////////////////////////////////////////////////////////////////////////////
    362 unsigned int _icu_write( unsigned int cluster_index,
    363                          unsigned int proc_index,
    364                          unsigned int register_index,
    365                          unsigned int value )
    366 {
     340// There is one vci_multi_icu (or vci_xicu) component per cluster,
     341// and the number of independant ICUs is equal to NB_PROCS_MAX,
     342// because there is one private interrupr controler per processor.
     343////////////////////////////////////////////////////////////////////////////////
     344
     345////////////////////////////////////////////////////////////////////////////////
     346//     _icu_set_mask()
     347// This function can be used with both the vci_xicu & vci_multi_icu components.
     348// It set the mask register for the ICU channel identified by the cluster index
     349// and the processor index: all '1' bits are set / all '0' bits are not modified.
     350// Returns 0 if success, > 0 if error.
     351////////////////////////////////////////////////////////////////////////////////
     352unsigned int _icu_set_mask( unsigned int cluster_id,
     353                            unsigned int proc_id,
     354                            unsigned int value,
     355                            unsigned int is_timer )
     356{
     357    // parameters checking
     358    if ( cluster_id >= NB_CLUSTERS)             return 1;
     359    if ( proc_id    >= NB_PROCS_MAX )   return 1;
     360
     361    unsigned int* icu_address = (unsigned int*)&seg_icu_base +
     362                                (cluster_id * CLUSTER_SPAN);
    367363#if GIET_USE_XICU
    368 
     364    if ( is_timer ) icu_address[XICU_REG(XICU_MSK_PTI_ENABLE, proc_id)] = value;
     365    else            icu_address[XICU_REG(XICU_MSK_HWI_ENABLE, proc_id)] = value;
    369366#else
    370 
     367    icu_address[proc_id * ICU_SPAN + ICU_MASK_SET] = value;
     368#endif
     369
     370    return 0;
     371}
     372////////////////////////////////////////////////////////////////////////////////
     373//     _icu_get_index()
     374// This function can be used with both the vci_xicu & vci_multi_icu components.
     375// It returns the index of the highest priority (smaller index) active HWI.
     376// The ICU channel is identified by the cluster index and the processor index.
     377// Returns 0 if success, > 0 if error.
     378////////////////////////////////////////////////////////////////////////////////
     379unsigned int _icu_get_index(  unsigned int cluster_id,
     380                              unsigned int proc_id,
     381                              unsigned int* buffer )
     382{
    371383    // parameters checking
    372     if ( register_index >= ICU_SPAN)            return 1;
    373     if ( cluster_index >= NB_CLUSTERS)          return 1;
    374     if ( proc_index >= NB_PROCS_MAX )       return 1;
    375 
    376     unsigned int *icu_address = (unsigned int*)&seg_icu_base +
    377                                 (cluster_index * CLUSTER_SPAN)  +
    378                                 (proc_index * ICU_SPAN);
    379 
    380     icu_address[register_index] = value;   // write word
     384    if ( cluster_id >= NB_CLUSTERS)             return 1;
     385    if ( proc_id    >= NB_PROCS_MAX )   return 1;
     386
     387    unsigned int* icu_address = (unsigned int*)&seg_icu_base +
     388                                (cluster_id * CLUSTER_SPAN);
     389#if GIET_USE_XICU
     390    unsigned int prio   = icu_address[XICU_REG(XICU_PRIO, proc_id)];
     391    unsigned int pti_ok = (prio & 0x00000001);
     392    unsigned int hwi_ok = (prio & 0x00000002);
     393    unsigned int swi_ok = (prio & 0x00000004);
     394    unsigned int pti_id = (prio & 0x00001F00) >> 8;
     395    unsigned int hwi_id = (prio & 0x001F0000) >> 16;
     396    unsigned int swi_id = (prio & 0x1F000000) >> 24;
     397    if      (pti_ok)    *buffer = pti_id;
     398    else if (hwi_ok)    *buffer = hwi_id;
     399    else if (swi_ok)    *buffer = swi_id;
     400    else                *buffer = 32;
     401#else
     402    *buffer = icu_address[proc_id * ICU_SPAN + ICU_IT_VECTOR];
     403#endif
     404
    381405    return 0;
    382 
    383 #endif
    384 }
    385 ////////////////////////////////////////////////////////////////////////////////
    386 //     _icu_read()
    387 // Read a 32-bit word in a memory mapped register of the MULTI_ICU device,
    388 // identified by the cluster index and a processor local index.
    389 // Returns 0 if success, > 0 if error.
    390 ////////////////////////////////////////////////////////////////////////////////
    391 unsigned int _icu_read(  unsigned int cluster_index,
    392                          unsigned int proc_index,
    393                          unsigned int register_index,
    394                          unsigned int* buffer )
    395 {
    396 #if GIET_USE_XICU
    397 
    398 #else
    399 
    400     // parameters checking
    401     if ( register_index >= ICU_SPAN)            return 1;
    402     if ( cluster_index >= NB_CLUSTERS)          return 1;
    403     if ( proc_index >= NB_PROCS_MAX )       return 1;
    404 
    405     unsigned int *icu_address = (unsigned int*)&seg_icu_base +
    406                                 (cluster_index * CLUSTER_SPAN)  +
    407                                 (proc_index * ICU_SPAN);
    408 
    409     *buffer = icu_address[register_index]; // read word
    410     return 0;
    411 
    412 #endif
    413406}
    414407
     
    763756    else
    764757    {
    765         unsigned char *fb_address = (unsigned char*)&seg_fb_base + offset;
     758        unsigned char *fb_address = (unsigned char*)&seg_fbf_base + offset;
    766759        memcpy((void*)fb_address, (void*)buffer, length);
    767760        return 0;
     
    789782    else
    790783    {
    791         unsigned char *fb_address = (unsigned char*)&seg_fb_base + offset;
     784        unsigned char *fb_address = (unsigned char*)&seg_fbf_base + offset;
    792785        memcpy((void*)buffer, (void*)fb_address, length);
    793786        return 0;
     
    833826    if ( (user_vaddr & 0x3) || (length & 0x3) )
    834827    {
     828        _get_lock(&_tty_put_lock);
    835829        _puts("[GIET ERROR] in _fbdma_access() : user buffer not word aligned\n");
     830        _release_lock(&_tty_put_lock);
    836831        return 1;
    837832    }
     
    841836
    842837    // compute frame buffer pbase address
    843     unsigned int fb_vaddr = (unsigned int)&seg_fb_base + offset;
     838    unsigned int fb_vaddr = (unsigned int)&seg_fbf_base + offset;
    844839
    845840    ko = _v2p_translate( (page_table_t*)user_ptab,
     
    851846    if ( ko )
    852847    {
     848        _get_lock(&_tty_put_lock);
    853849        _puts("[GIET ERROR] in _fbdma_access() : frame buffer unmapped\n");
     850        _release_lock(&_tty_put_lock);
    854851        return 2;
    855852    }
     
    864861    if ( ko )
    865862    {
     863        _get_lock(&_tty_put_lock);
    866864        _puts("[GIET ERROR] in _fbdma_access() : user buffer unmapped\n");
     865        _release_lock(&_tty_put_lock);
    867866        return 3;
    868867    }
    869868    if ( (flags & PTE_U) == 0 )
    870869    {
     870        _get_lock(&_tty_put_lock);
    871871        _puts("[GIET ERROR] in _fbdma_access() : user buffer not in user space\n");
     872        _release_lock(&_tty_put_lock);
    872873        return 4;
    873874    }
    874875    if ( ( (flags & PTE_W) == 0 ) && to_user )
    875876    {
     877        _get_lock(&_tty_put_lock);
    876878        _puts("[GIET ERROR] in _fbdma_access() : user buffer not writable\n");
     879        _release_lock(&_tty_put_lock);
    877880        return 5;
    878881    }
  • soft/giet_vm/sys/drivers.h

    r189 r203  
    1515extern volatile unsigned char _timer_event[];
    1616
    17 unsigned int _timer_access( unsigned int        read,           // reas if non 0
    18                             unsigned int        cluster_id,
    19                             unsigned int        local_id,
    20                             unsigned int        register_id,
    21                             unsigned int*       buffer);
     17unsigned int _timer_start( unsigned int cluster_id,
     18                           unsigned int local_id,
     19                           unsigned int period );
    2220
    23 unsigned int _timer_read(   unsigned int        register_id,
    24                             unsigned int*       buffer);
     21unsigned int _timer_stop(  unsigned int cluster_id,
     22                           unsigned int local_id );
    2523
    26 unsigned int _timer_write(  unsigned int        register_id,
    27                             unsigned int        value);
     24
     25unsigned int _timer_reset_irq( unsigned int     cluster_id,
     26                               unsigned int local_id );
    2827
    2928///////////////////////////////////////////////////////////////////////////////////
     
    4847///////////////////////////////////////////////////////////////////////////////////
    4948
    50 unsigned int _icu_read(     unsigned int        cluster_id,
     49unsigned int _icu_get_index(unsigned int        cluster_id,
    5150                            unsigned int        proc_id,
    52                             unsigned int        register_id,
    53                             unsigned int*       buffer);
     51                            unsigned int*       buffer );
    5452
    55 unsigned int _icu_write(        unsigned int    cluster_id,
     53unsigned int _icu_set_mask( unsigned int        cluster_id,
    5654                                                        unsigned int    proc_id,
    57                                                         unsigned int    register_id,
    58                                                         unsigned int    value );
     55                                                        unsigned int    mask,
     56                                                        unsigned int    is_timer );
    5957
    6058///////////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/sys/hwr_mapping.h

    r200 r203  
    6565    ICU_SPAN        = 8,
    6666};
     67enum Xicu_registers {
     68    XICU_WTI_REG = 0,
     69    XICU_PTI_PER = 1,
     70    XICU_PTI_VAL = 2,
     71    XICU_PTI_ACK = 3,
    6772
     73    XICU_MSK_PTI = 4,
     74    XICU_MSK_PTI_ENABLE = 5,
     75    XICU_MSK_PTI_DISABLE = 6,
     76    XICU_PTI_ACTIVE = 6,
     77
     78    XICU_MSK_HWI = 8,
     79    XICU_MSK_HWI_ENABLE = 9,
     80    XICU_MSK_HWI_DISABLE = 10,
     81    XICU_HWI_ACTIVE = 10,
     82
     83    XICU_MSK_WTI = 12,
     84    XICU_MSK_WTI_ENABLE = 13,
     85    XICU_MSK_WTI_DISABLE = 14,
     86    XICU_WTI_ACTIVE = 14,
     87
     88    XICU_PRIO = 15,
     89};
     90
     91#define XICU_REG(func, index) (((func)<<5)|(index))
     92       
    6893/* TIMER */
    6994enum TIMER_registers {
  • soft/giet_vm/sys/irq_handler.c

    r189 r203  
    4242
    4343    // get the highest priority active IRQ index
    44 
    45 #if GIET_USE_XICU
    46 
    47 #else
    48 
    49     if ( _icu_read( pid / NB_PROCS_MAX,
    50                     pid % NB_PROCS_MAX,
    51                     ICU_IT_VECTOR,
    52                     &irq_id ) )
     44    if ( _icu_get_index( pid / NB_PROCS_MAX,
     45                         pid % NB_PROCS_MAX,
     46                         &irq_id ) )
    5347    {
    54         _puts("\n[GIET ERROR] wrong _icu_read in _irq_demux() function\n");
    55         _exit();
     48        _get_lock(&_tty_put_lock);
     49        _puts("\n[GIET ERROR] Strange... Wrong _icu_read in _irq_demux()\n");
     50        _release_lock(&_tty_put_lock);
    5651    }
    57 
    58 #endif
    5952
    6053    if ( irq_id < 32 )  // do nothing if no interrupt active
     
    7467//      _isr_default()
    7568// The default ISR is called when no specific ISR has been installed in the
    76 // interrupt vector. It simply displays a message on kernel TTY[0].
     69// interrupt vector. It simply displays an error message on kernel TTY[0].
    7770///////////////////////////////////////////////////////////////////////////////////
    7871void _isr_default()
    7972{
    80     _puts("\n\n!!! Strange... Default ISR activated !!!\n");
     73    _get_lock(&_tty_put_lock);
     74    _puts("\n[GIET ERROR] Strange... Default ISR activated for processor ");
     75    _putd( _procid() );
     76    _puts("\n");
     77    _release_lock(&_tty_put_lock);
    8178}
    8279
     
    122119    unsigned int* ioc_address = (unsigned int*)&seg_ioc_base;
    123120
    124     _ioc_status = ioc_address[BLOCK_DEVICE_STATUS]; /* save status & reset IRQ */
    125     _ioc_done   = 1;                                /* signals completion */
     121    _ioc_status = ioc_address[BLOCK_DEVICE_STATUS]; // save status & reset IRQ
     122    _ioc_done   = 1;                                // signals completion
    126123}
    127124
    128125///////////////////////////////////////////////////////////////////////////////////
    129126//         _isr_timer()
    130 // This ISR handles the IRQs generated by the "user" timers (the IRQs
    131 // generated by the "system" timers should be handled by the _isr_switch().
     127// This ISR handles the IRQs generated by the "user" timers (the IRQs generated
     128// by the "system" timers should be handled by the _isr_switch().
    132129// These timers are distributed in all clusters, and can be implemented
    133130// in a vci_multi_timer component, or in a vci_xicu component.
    134 // The channel_id argument is the global channel index:
    135 //     channel_id = cluster_id*(NB_TIMERS_MAX+NB_PROCS_MAX) + loc_id
     131// The timer_id argument is a global index:
     132//     timer_id = cluster_id*(NB_TIMERS_MAX+NB_PROCS_MAX) + local_id
    136133// The user timer local index is (loc_id - NB_PROCS_MAX).
    137134//
    138135// The ISR acknowledges the IRQ and registers the event in the proper entry
    139 // of the _timer_event[] array.
    140 // A log message is displayed on the kernel terminal.
    141 ///////////////////////////////////////////////////////////////////////////////////
    142 void _isr_timer(unsigned int channel_id)
    143 {
    144 
    145     unsigned int cluster_id = channel_id / (NB_TIMERS_MAX + NB_PROCS_MAX);
    146     unsigned int loc_id     = channel_id % (NB_TIMERS_MAX + NB_PROCS_MAX);
    147 
    148     if (loc_id < NB_PROCS_MAX )
     136// of the _timer_event[] array, and a log message is displayed on kernel terminal.
     137///////////////////////////////////////////////////////////////////////////////////
     138void _isr_timer(unsigned int timer_id)
     139{
     140
     141    unsigned int cluster_id = timer_id / (NB_TIMERS_MAX + NB_PROCS_MAX);
     142    unsigned int local_id   = timer_id % (NB_TIMERS_MAX + NB_PROCS_MAX);
     143
     144    // checking timer type
     145    if (local_id < NB_PROCS_MAX )
    149146    {
    150         _puts("[GIET ERROR] Receiving a user timer IRQ for a system timer\n");
    151         _puts("             cluster = ");
    152         _putw(cluster_id);
    153         _puts(" / local_id = ");
    154         _putw(loc_id);
     147        _get_lock(&_tty_put_lock);
     148        _puts("[GIET ERROR] Strange... User timer ISR for a system timer\n");
     149        _release_lock(&_tty_put_lock);
    155150    }
    156151
    157 #if GIET_USE_XICU
    158 
    159 // TODO
    160 
    161 #else
    162 
    163     // compute Timer address
    164     unsigned int* timer_address = (unsigned int*)&seg_timer_base +
    165                                   (loc_id * TIMER_SPAN) +
    166                                   (cluster_id * CLUSTER_SPAN);
    167 
    168     // reset IRQ
    169     timer_address[TIMER_RESETIRQ] = 0;
    170 
    171 #endif
     152    // aknowledge IRQ
     153    _timer_reset_irq( cluster_id, local_id );
    172154
    173155#if NB_TIMERS_MAX
     
    177159
    178160    // display a message on TTY 0
    179     _puts("[GIET] User Timer IRQ / cluster = ");
    180     _putw(cluster_id);
    181     _puts(" / timer = ");
    182     _putw(loc_id - NB_PROCS_MAX);
     161    _get_lock(&_tty_put_lock);
     162    _puts("[GIET] User Timer IRQ at cycle ");
     163    _putd( _proctime() );
     164    _puts(" / index = ");
     165    _putd(timer_id);
    183166    _puts("\n");
     167    _release_lock(&_tty_put_lock);
    184168}
    185169
     
    219203    // get cluster index and proc local index
    220204    unsigned int pid        = _procid();
    221     unsigned int loc_id     = pid % NB_PROCS_MAX;
     205    unsigned int local_id   = pid % NB_PROCS_MAX;
    222206    unsigned int cluster_id = pid / NB_PROCS_MAX;
    223207
    224 #if GIET_USE_XICU
    225 
    226     unsigned int* timer_address = // TODO
    227 
    228 #else
    229 
    230     // compute Timer address
    231     unsigned int* timer_address = (unsigned int*)&seg_timer_base +
    232                                   (loc_id * TIMER_SPAN) +
    233                                   (cluster_id * CLUSTER_SPAN);
    234 
    235     // reset IRQ
    236     timer_address[TIMER_RESETIRQ] = 0;
    237 
    238 #endif
     208    // acknowledge IRQ
     209    _timer_reset_irq( cluster_id, local_id );
    239210
    240211    // performs the context switch
    241212    _ctx_switch();
    242 
    243 }
    244 
     213}
     214
  • soft/giet_vm/sys/kernel_init.c

    r199 r203  
    7676
    7777    // step 2 : initialise page table addresse arrays
    78     //          it scans all tasks contexts in the scheduler
    79     //          and get VSID, PTAB and PTPR values
     78    //          each processor scans all tasks contexts in its
     79    //          private scheduler and get VSID, PTAB and PTPR values
    8080
    8181    unsigned int ltid;
     
    8787        unsigned int ptab_vaddr = _get_context_slot( ltid , CTX_PTAB_ID );
    8888        unsigned int ptab_paddr = _get_context_slot( ltid , CTX_PTPR_ID ) << 13;
     89
    8990        _ptabs_vaddr[vspace_id] = ptab_vaddr;
    9091        _ptabs_paddr[vspace_id] = ptab_paddr;
     
    106107    }
    107108 
    108     // step 3 : compute and set ICU mask
     109    // step 3 : compute and set ICU masks
     110    //          there is at most 32 interrupts per processor
     111    //          software interrupts are not supported yet
     112
    109113    unsigned int irq_id;
    110     unsigned int mask = 0;
     114    unsigned int hwi_mask = 0;
     115    unsigned int pti_mask = 0;
     116
    111117    for ( irq_id = 0 ; irq_id < 32 ; irq_id++ )
    112118    {
    113         unsigned int entry   = _get_interrupt_vector_entry(irq_id);
    114         if ( entry ) mask = mask | 0x1<< irq_id;
    115     }
    116     _icu_write( cluster_id,
    117                 lpid,
    118                 ICU_MASK_SET,
    119                 mask );
     119        unsigned int entry  = _get_interrupt_vector_entry(irq_id);
     120        unsigned int isr    = entry & 0x000000FF;
     121
     122        if ( (isr == ISR_DMA) || (isr == ISR_IOC) || (isr == ISR_TTY) )
     123        {
     124             hwi_mask = hwi_mask | 0x1<< irq_id;
     125        }
     126        else if ( (isr == ISR_SWITCH) || (isr == ISR_TIMER) )
     127        {
     128            pti_mask = pti_mask | 0x1<< irq_id;
     129        }
     130    }
     131    _icu_set_mask( cluster_id, lpid, hwi_mask, 0 ); // set HWI_MASK
     132    _icu_set_mask( cluster_id, lpid, pti_mask, 1 );     // set PTI_MASK
    120133   
    121134#if GIET_DEBUG_INIT
     
    123136_puts("\n[GIET DEBUG] step 3 for processor ");
    124137_putd( proc_id );
    125 _puts(" / ICU mask = ");
    126 _putw( mask );
     138_puts("\n - ICU HWI_MASK = ");
     139_putw( hwi_mask );
     140_puts("\n - ICU PTI_MASK = ");
     141_putw( pti_mask );
    127142_puts("\n");
    128143_release_lock(&_tty_put_lock);
     
    133148    if ( tasks > 1 )
    134149    {
    135         unsigned int period     = GIET_TICK_VALUE;
    136         unsigned int mode       = 0x3;
    137         _timer_access( 0,                       // write access
    138                        cluster_id,
    139                        proc_id,
    140                        TIMER_PERIOD,
    141                        &period );
    142         _timer_access( 0,                       // write access
    143                        cluster_id,
    144                        proc_id,
    145                        TIMER_MODE,
    146                        &mode );
     150        _timer_start( cluster_id,
     151                      proc_id,
     152                      GIET_TICK_VALUE );
    147153       
    148154#if GIET_DEBUG_INIT
     
    150156_puts("\n[GIET DEBUG] Step 4 for processor ");
    151157_putd( proc_id );
    152 _puts(" / TICK activated\n");
     158_puts(" / context switch activated\n");
    153159_release_lock(&_tty_put_lock);
    154160#endif
  • soft/giet_vm/sys/sys.ld

    r167 r203  
    1 /****************************************************************************
    2 * Definition of the base address for all virtual segments
    3 *****************************************************************************/
    41
    5 /* The vsegs used by the system are mapped in all virtual spaces
    6    They can be identity mapping... or not */
     2/******************************************************************************/
     3/* Definition of the base addresses for all vsegs used by the GIET_VM         */
     4/******************************************************************************/
    75
    8 seg_kernel_code_base    = 0x80000000;   /* system code */
    9 seg_kernel_data_base    = 0x80010000;   /* system cacheable data */
    10 seg_kernel_uncdata_base = 0x80080000;   /* system uncacheable data */
    11 seg_kernel_init_base    = 0x80090000;   /* system page table */
    12 seg_mapping_base            = 0xBFC0C000;       /* boot mapping_info */
     6INCLUDE giet_vsegs.ld
    137
    14 
    15 /* The peripherals base addresses are referenced by the software drivers and    \
    16    must be defined, even if the peripherals are not used in the architecture */
    17 
    18 seg_tty_base                = 0x90000000;   /* TTY device */
    19 seg_timer_base              = 0x91000000;   /* Timer device */
    20 seg_ioc_base                = 0x92000000;   /* Block device */
    21 seg_dma_base                = 0x93000000;   /* DMA device */
    22 seg_gcd_base                = 0x95000000;   /* GCD device */
    23 seg_fb_base                 = 0x96000000;   /* FrameBuffer device */
    24 seg_iob_base                = 0x9E000000;   /* IOB device */
    25 seg_icu_base                = 0x9F000000;   /* ICU or XICU device */
    26 
    27 /*
    28  * Grouping sections into segments for system code and data
    29  */
     8/******************************************************************************/
     9/* Grouping sections into virtual segments for system code and data           */
     10/******************************************************************************/
    3011
    3112SECTIONS
     
    3718        *(.text)
    3819    }
     20
    3921    . = seg_kernel_data_base;
    4022    seg_kernel_data :
     
    5335        *(.scommon)
    5436    }
     37
    5538    . = seg_kernel_uncdata_base;
    5639    seg_kernel_uncdata :
  • soft/giet_vm/sys/sys_handler.c

    r199 r203  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The sys_handler.c and sys_handler.h files are part of the GIET nano-kernel.
     7// The sys_handler.c and sys_handler.h files are part of the GIET-VM nano-kernel.
    88// It define the syscall_vector[] (at the end of this file), as well as the
    99// associated syscall handlers that are not related to peripherals.
     
    2626    &_tty_write,        /* 0x02 */
    2727    &_tty_read,         /* 0x03 */
    28     &_timer_write,      /* 0x04 */
    29     &_timer_read,       /* 0x05 */
     28    &_timer_start,      /* 0x04 */
     29    &_timer_stop,       /* 0x05 */
    3030    &_gcd_write,        /* 0x06 */
    3131    &_gcd_read,         /* 0x07 */
Note: See TracChangeset for help on using the changeset viewer.