Changeset 204 for soft/giet_vm/sys


Ignore:
Timestamp:
Aug 14, 2012, 8:14:55 PM (12 years ago)
Author:
alain
Message:

mproving support for multi-clusters architectures (CLUSTER_SIZE & CLUSTER_IO_ID parameters)

Location:
soft/giet_vm/sys
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/sys/drivers.c

    r203 r204  
    1717//
    1818// The following global parameters must be defined in the giet_config.h file:
     19// - CLUSTER_IO_ID
     20// - CLUSTER_SIZE
    1921// - NB_CLUSTERS   
    2022// - NB_PROCS_MAX 
     
    2325// - NB_TTYS   
    2426//
    25 // The following virtual base addresses must be defined in the sys.ld file:
     27// The following virtual base addresses must be defined in the giet.ld file:
    2628// - seg_icu_base
    2729// - seg_tim_base
     
    3133// - seg_fbf_base
    3234// - seg_ioc_base
     35// As some peripherals can be replicated in the clusters (ICU, TIMER, DMA)
     36// These addresses must be completed by an offset depending on the cluster index
     37//    full_base_address = seg_***_base + cluster_id * CLUSTER_SIZE
    3338///////////////////////////////////////////////////////////////////////////////////
    3439
     
    5459#endif
    5560
    56 #if !defined(CLUSTER_SPAN)
    57 # error: You must define CLUSTER_SPAN in 'giet_config.h' file
     61#if !defined(CLUSTER_SIZE)
     62# error: You must define CLUSTER_SIZE in 'giet_config.h' file
    5863#endif
    5964
     
    132137
    133138#if GIET_USE_XICU
    134     unsigned int* timer_address = (unsigned int*)&seg_icu_base +
    135                                   (cluster_id * CLUSTER_SPAN);
     139    unsigned int* timer_address = (unsigned int*)((char*)&seg_icu_base +
     140                                  (cluster_id * CLUSTER_SIZE) );
    136141
    137142    timer_address[XICU_REG(XICU_PTI_PER, local_id)] = period;
    138143#else
    139     unsigned int* timer_address = (unsigned int*)&seg_tim_base +
    140                                   (cluster_id * CLUSTER_SPAN);
     144    unsigned int* timer_address = (unsigned int*)((char*)&seg_tim_base +
     145                                  (cluster_id * CLUSTER_SIZE) );
    141146
    142147    timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
     
    160165
    161166#if GIET_USE_XICU
    162     unsigned int* timer_address = (unsigned int*)&seg_icu_base +
    163                                   (cluster_id * CLUSTER_SPAN);
     167    unsigned int* timer_address = (unsigned int*)((char*)&seg_icu_base +
     168                                  (cluster_id * CLUSTER_SIZE) );
    164169
    165170    timer_address[XICU_REG(XICU_PTI_PER, local_id)] = 0;
    166171#else
    167     unsigned int* timer_address = (unsigned int*)&seg_tim_base +
    168                                   (cluster_id * CLUSTER_SPAN);
     172    unsigned int* timer_address = (unsigned int*)((char*)&seg_tim_base +
     173                                  (cluster_id * CLUSTER_SIZE) );
    169174
    170175    timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0;
     
    176181//     _timer_reset_irq()
    177182// This function acknowlegge a timer interrupt in the vci_timer (or vci_xicu)
    178 // component by writing in the proper register the period value.
     183// component by reading/writing in the proper register.
    179184// It can be used by both the isr_switch() for a "system" timer,
    180185// or by the _isr_timer() for an "user" timer.
     
    189194
    190195#if GIET_USE_XICU
    191     unsigned int* timer_address = (unsigned int*)&seg_icu_base +
    192                                   (cluster_id * CLUSTER_SPAN);
     196    unsigned int* timer_address = (unsigned int*)((char*)&seg_icu_base +
     197                                  (cluster_id * (unsigned)CLUSTER_SIZE) );
    193198
    194199    unsigned int bloup = timer_address[XICU_REG(XICU_PTI_ACK, local_id)];
     200    bloup++;    // to avoid a warning
    195201#else
    196     unsigned int* timer_address = (unsigned int*)&seg_tim_base +
    197                                   (cluster_id * CLUSTER_SPAN);
     202    unsigned int* timer_address = (unsigned int*)((char*)&seg_tim_base +
     203                                  (cluster_id * CLUSTER_SIZE) );
    198204
    199205    timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0;
     
    258264    }
    259265
    260     unsigned int*       tty_address = (unsigned int*)&seg_tty_base + tty_id*TTY_SPAN;
     266    unsigned int*       tty_address = (unsigned int*)( (char*)&seg_tty_base +
     267                                  (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
    261268
    262269    for (nwritten = 0; nwritten < length; nwritten++)
    263270    {
    264271        // check tty's status
    265         if ((tty_address[TTY_STATUS] & 0x2) == 0x2)
     272        if ((tty_address[tty_id*TTY_SPAN + TTY_STATUS] & 0x2) == 0x2)
    266273            break;
    267274        else
    268275            // write character
    269             tty_address[TTY_WRITE] = (unsigned int)buffer[nwritten];
     276            tty_address[tty_id*TTY_SPAN + TTY_WRITE] = (unsigned int)buffer[nwritten];
    270277    }
    271278    return nwritten;
    272279}
    273280//////////////////////////////////////////////////////////////////////////////
    274 //      _tty_read_irq()
     281//      _tty_read()
    275282// This non-blocking function uses the TTY_GET_IRQ[tty_id] interrupt and
    276283// the associated kernel buffer, that has been written by the ISR.
     284// It get the TTY terminal index from the context of the current task.
    277285// It fetches one single character from the _tty_get_buf[tty_id] kernel
    278286// buffer, writes this character to the user buffer, and resets the
    279287// _tty_get_full[tty_id] buffer.
     288// The length argument is not used.
    280289// Returns 0 if the kernel buffer is empty, 1 if the buffer is full.
    281290//////////////////////////////////////////////////////////////////////////////
    282 unsigned int _tty_read_irq( char                        *buffer,
    283                             unsigned int        length)
     291unsigned int _tty_read( char                    *buffer,
     292                        unsigned int    length)
    284293{
    285294    unsigned int task_id  = _get_current_task_id();
     
    304313}
    305314////////////////////////////////////////////////////////////////////////////////
    306 //     _tty_read()
    307 // This non-blocking function fetches one character directly from the TTY_READ
    308 // register of the TTY controler, and writes this character to the user buffer.
    309 // It doesn't use the TTY_GET_IRQ interrupt and the associated kernel buffer.
    310 // Returns 0 if the register is empty, 1 if the register is full.
    311 ////////////////////////////////////////////////////////////////////////////////
    312 unsigned int _tty_read( char                    *buffer,
    313                         unsigned int    length)
    314 {
    315     unsigned int task_id  = _get_current_task_id();
    316     unsigned int tty_id   = _get_context_slot(task_id, CTX_TTY_ID);
    317 
    318     if ( tty_id >= NB_TTYS )
    319     {
    320         _tty_error( task_id );
    321         return 0;
    322     }
    323 
    324     unsigned int*       tty_address = (unsigned int*)&seg_tty_base + tty_id*TTY_SPAN;
    325 
    326     if ((tty_address[TTY_STATUS] & 0x1) != 0x1)
    327     {
    328         return 0;
    329     }
    330     else
    331     {
    332         *buffer = (char)tty_address[TTY_READ];
    333         return 1;
    334     }
     315//     _tty_get_char()
     316// This function is used by the _isr_tty to read a character in the TTY
     317// terminal defined by the tty_id argument. The character is stored
     318// in requested buffer, and the IRQ is acknowledged.
     319// Returns 0 if success, 1 if tty_id too large.
     320////////////////////////////////////////////////////////////////////////////////
     321unsigned int _tty_get_char( unsigned int        tty_id,
     322                            char*           buffer )
     323{
     324    // checking argument
     325    if ( tty_id >= NB_TTYS ) return 1;
     326
     327    // compute terminal base address
     328    unsigned int *tty_address = (unsigned int*)( (char*)&seg_tty_base +
     329                                (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
     330
     331    *buffer = (unsigned char)tty_address[tty_id*TTY_SPAN + TTY_READ];
     332    return 0;
    335333}
    336334
     
    359357    if ( proc_id    >= NB_PROCS_MAX )   return 1;
    360358
    361     unsigned int* icu_address = (unsigned int*)&seg_icu_base +
    362                                 (cluster_id * CLUSTER_SPAN);
     359    unsigned int* icu_address = (unsigned int*)( (char*)&seg_icu_base +
     360                                (cluster_id * (unsigned)CLUSTER_SIZE) );
    363361#if GIET_USE_XICU
    364362    if ( is_timer ) icu_address[XICU_REG(XICU_MSK_PTI_ENABLE, proc_id)] = value;
     
    385383    if ( proc_id    >= NB_PROCS_MAX )   return 1;
    386384
    387     unsigned int* icu_address = (unsigned int*)&seg_icu_base +
    388                                 (cluster_id * CLUSTER_SPAN);
     385    unsigned int* icu_address = (unsigned int*)( (char*)&seg_icu_base +
     386                                (cluster_id * (unsigned)CLUSTER_SIZE) );
    389387#if GIET_USE_XICU
    390388    unsigned int prio   = icu_address[XICU_REG(XICU_PRIO, proc_id)];
     
    422420                         unsigned int value)
    423421{
    424     volatile unsigned int *gcd_address;
    425 
    426422    // parameters checking
    427423    if (register_index >= GCD_END)
    428424        return 1;
    429425
    430     gcd_address = (unsigned int*)&seg_gcd_base;
     426    unsigned int* gcd_address = (unsigned int*)( (char*)&seg_gcd_base +
     427                                (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
    431428
    432429    gcd_address[register_index] = value; // write word
     
    441438                        unsigned int *buffer)
    442439{
    443     volatile unsigned int *gcd_address;
    444 
    445440    // parameters checking
    446441    if (register_index >= GCD_END)
    447442        return 1;
    448443
    449     gcd_address = (unsigned int*)&seg_gcd_base;
     444    unsigned int* gcd_address = (unsigned int*)( (char*)&seg_gcd_base +
     445                                (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
    450446
    451447    *buffer = gcd_address[register_index]; // read word
     
    538534    if ( (unsigned int)user_vaddr & 0x3 ) return 1;
    539535
    540     unsigned int*       ioc_address = (unsigned int*)&seg_ioc_base;
     536    unsigned int*       ioc_address = (unsigned int*)( (char*)&seg_ioc_base +
     537                                  (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
     538
    541539    unsigned int        block_size   = ioc_address[BLOCK_DEVICE_BLOCK_SIZE];
    542540    unsigned int        length       = count*block_size;
     
    630628    if ( GIET_IOMMU_ACTIVE )
    631629    {
    632         unsigned int* iob_address = (unsigned int*)&seg_iob_base;
     630        unsigned int* iob_address = (unsigned int*)( (char*)&seg_iob_base +
     631                                    (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
    633632
    634633        for ( ix2 = 0 ; ix2 < _ioc_iommu_npages ; ix2++ )
     
    687686                        (unsigned int)buffer,
    688687                        count );
     688}
     689///////////////////////////////////////////////////////////////////////////////
     690//     _ioc_get_status()
     691// This function returns the transfert status, and acknowledge the IRQ.
     692// Returns 0 if success, > 0 if error.
     693///////////////////////////////////////////////////////////////////////////////
     694unsigned int _ioc_get_status(unsigned int* status)
     695{
     696    // get IOC base address
     697    unsigned int* ioc_address = (unsigned int*)( (char*)&seg_ioc_base +
     698                                (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
     699
     700    *status = ioc_address[BLOCK_DEVICE_STATUS]; // read status & reset IRQ
     701    return 0;
    689702}
    690703
     
    718731in_unckdata unsigned int            _dma_iommu_npages[NB_DMAS_MAX * NB_CLUSTERS];
    719732#endif
     733
     734//////////////////////////////////////////////////////////////////////////////////
     735// _dma_reset_irq()
     736//////////////////////////////////////////////////////////////////////////////////
     737unsigned int _dma_reset_irq( unsigned int       cluster_id,
     738                             unsigned int       local_id )
     739{
     740    // parameters checking
     741    if ( cluster_id >= NB_CLUSTERS ) return 1;
     742    if ( local_id >= NB_DMAS_MAX )   return 1;
     743
     744    // compute DMA base address
     745    unsigned int*       dma_address = (unsigned int*)( (char*)&seg_dma_base +
     746                                  (cluster_id * (unsigned)CLUSTER_SIZE) );
     747
     748    dma_address[local_id*DMA_SPAN + DMA_RESET] = 0;                     
     749    return 0;
     750}
     751//////////////////////////////////////////////////////////////////////////////////
     752// _dma_get_status()
     753//////////////////////////////////////////////////////////////////////////////////
     754unsigned int _dma_get_status( unsigned int      cluster_id,
     755                              unsigned int      local_id,
     756                              unsigned int* status )
     757{
     758    // parameters checking
     759    if ( cluster_id >= NB_CLUSTERS ) return 1;
     760    if ( local_id >= NB_DMAS_MAX )   return 1;
     761
     762    // compute DMA base address
     763    unsigned int*       dma_address = (unsigned int*)( (char*)&seg_dma_base +
     764                                  (cluster_id * (unsigned)CLUSTER_SIZE) );
     765   
     766    *status = dma_address[local_id*DMA_SPAN + DMA_LEN];
     767    return 0;
     768}
    720769
    721770//////////////////////////////////////////////////////////////////////////////////
     
    819868    unsigned int    cluster_id = dma_id / NB_DMAS_MAX;
    820869    unsigned int    loc_id     = dma_id % NB_DMAS_MAX;
    821     unsigned int*       dma_base   = (unsigned int*)&seg_dma_base +
    822                                  (cluster_id * CLUSTER_SPAN) +
    823                                  (loc_id * DMA_SPAN);
    824 
     870
     871    unsigned int*       dma_base   = (unsigned int*)( (char*)&seg_dma_base +
     872                                 (cluster_id * (unsigned)CLUSTER_SIZE) );
     873 
    825874    // check user buffer address and length alignment
    826875    if ( (user_vaddr & 0x3) || (length & 0x3) )
     
    930979
    931980*/
     981
    932982    // invalidate data cache in case of memory write
    933983    if ( to_user ) _dcache_buf_invalidate( (void*)user_vaddr, length );
     
    939989    if ( to_user )
    940990    {
    941         dma_base[DMA_SRC] = (unsigned int)fb_pbase;
    942         dma_base[DMA_DST] = (unsigned int)user_pbase;
     991        dma_base[loc_id*DMA_SPAN + DMA_SRC] = (unsigned int)fb_pbase;
     992        dma_base[loc_id*DMA_SPAN + DMA_DST] = (unsigned int)user_pbase;
    943993    }
    944994    else
    945995    {
    946         dma_base[DMA_SRC] = (unsigned int)user_pbase;
    947         dma_base[DMA_DST] = (unsigned int)fb_pbase;
    948     }
    949     dma_base[DMA_LEN] = (unsigned int)length;
     996        dma_base[loc_id*DMA_SPAN + DMA_SRC] = (unsigned int)user_pbase;
     997        dma_base[loc_id*DMA_SPAN + DMA_DST] = (unsigned int)fb_pbase;
     998    }
     999    dma_base[loc_id*DMA_SPAN + DMA_LEN] = (unsigned int)length;
    9501000   
    9511001    return 0;
     
    10111061    if ( GIET_IOMMU_ACTIVE )
    10121062    {
    1013         unsigned int* iob_address = (unsigned int*)&seg_iob_base;
     1063        unsigned int* iob_address = (unsigned int*)( (char*)&seg_iob_base +
     1064                                    (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
     1065
    10141066        unsigned int  ix1         = _dma_iommu_ix1 + dma_id;
    10151067        unsigned int  ix2;
  • soft/giet_vm/sys/drivers.h

    r203 r204  
    4040                            unsigned int        length);
    4141
    42 unsigned int _tty_read_irq( char*                       buffer,
    43                             unsigned int        length);
     42unsigned int _tty_get_char( unsigned int        tty_id,
     43                            char*                       buffer);
    4444
    4545///////////////////////////////////////////////////////////////////////////////////
     
    7777unsigned int _ioc_completed();
    7878
     79unsigned int _ioc_get_status( unsigned int* status);
     80
    7981///////////////////////////////////////////////////////////////////////////////////
    8082// Multi DMA variables                  (vci_multi_dma)
     
    8688extern unsigned int                             _dma_iommu_ix1;
    8789extern unsigned int                             _dma_iommu_npages[];
     90
     91unsigned int _dma_reset_irq( unsigned int       cluster_id,
     92                             unsigned int       local_id );
     93
     94unsigned int _dma_get_status( unsigned int      cluster_id,
     95                              unsigned int      local_id,
     96                              unsigned int*     status );
    8897
    8998///////////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/sys/irq_handler.c

    r203 r204  
    9292    // compute cluster_id and loc_id
    9393    unsigned int cluster_id = channel_id / NB_DMAS_MAX;
    94     unsigned int loc_id     = channel_id % NB_DMAS_MAX;
    95 
    96     // compute DMA channel address
    97     unsigned int*       dma_address = (unsigned int*)&seg_dma_base +
    98                                   (loc_id * DMA_SPAN) +
    99                                   (cluster_id * CLUSTER_SPAN);
     94    unsigned int local_id   = channel_id % NB_DMAS_MAX;
    10095
    10196    // save DMA channel status 
    102     _dma_status[channel_id] = dma_address[DMA_LEN];
    103 
    104     // reset DMA channel
    105     dma_address[DMA_RESET] = 0;                 
     97    if ( _dma_get_status(cluster_id, local_id, &_dma_status[channel_id]) )
     98    {
     99        _get_lock(&_tty_put_lock);
     100        _puts("[GIET ERROR] illegal DMA channel detected by _isr_dma\n");
     101        _release_lock(&_tty_put_lock);
     102        return;
     103    }
     104
     105    // reset DMA channel irq
     106    if ( _dma_reset_irq(cluster_id, local_id) )
     107    {
     108        _get_lock(&_tty_put_lock);
     109        _puts("[GIET ERROR] illegal DMA channel detected by _isr_dma\n");
     110        _release_lock(&_tty_put_lock);
     111        return;
     112    }
    106113
    107114    // release DMA channel
     
    117124void _isr_ioc()
    118125{
    119     unsigned int* ioc_address = (unsigned int*)&seg_ioc_base;
    120 
    121     _ioc_status = ioc_address[BLOCK_DEVICE_STATUS]; // save status & reset IRQ
    122     _ioc_done   = 1;                                // signals completion
     126     // save status & reset IRQ
     127    if ( _ioc_get_status( &_ioc_status ) )
     128    {
     129        _get_lock(&_tty_put_lock);
     130        _puts("[GIET ERROR] bad access to IOC status detected by _isr_ioc\n");
     131        _release_lock(&_tty_put_lock);
     132        return;
     133    }
     134
     135    // signals completion
     136    _ioc_done   = 1;
    123137}
    124138
     
    148162        _puts("[GIET ERROR] Strange... User timer ISR for a system timer\n");
    149163        _release_lock(&_tty_put_lock);
     164        return;
    150165    }
    151166
    152167    // aknowledge IRQ
    153     _timer_reset_irq( cluster_id, local_id );
     168    if ( _timer_reset_irq( cluster_id, local_id ) )
     169    {
     170        _get_lock(&_tty_put_lock);
     171        _puts("[GIET ERROR] illegal timer index detected by _isr_timer\n");
     172        _release_lock(&_tty_put_lock);
     173        return;
     174    }
    154175
    155176#if NB_TIMERS_MAX
     
    172193// This ISR handles the IRQs generated by the multi_tty controler,
    173194// signaling that a character is available.
    174 // There is one single multi_tty component controling all TTYs, and the tty_id
    175 // argument is the global TTY index.
     195// There is one single multi_tty component controling all TTYs,
     196// and the tty_id // argument is the global TTY index.
    176197// There is one communication buffer _tty_buf[tty_id] per terminal.
    177198// The sychronisation variable _tty_full[tty_id], is set by the ISR,
     
    181202void _isr_tty(unsigned int tty_id)
    182203{
    183     // compute terminal base address
    184     unsigned int *tty_address = (unsigned int*)&seg_tty_base + (tty_id * TTY_SPAN);
    185 
    186204    // save character and reset IRQ
    187     _tty_get_buf[tty_id] = (unsigned char)tty_address[TTY_READ];
     205    if ( _tty_get_char( tty_id, &_tty_get_buf[tty_id] ) )
     206    {
     207        _get_lock(&_tty_put_lock);
     208        _puts("[GIET ERROR] illegal tty index detected by _isr_tty\n");
     209        _release_lock(&_tty_put_lock);
     210        return;
     211    }
    188212
    189213    // signals character available
     
    207231
    208232    // acknowledge IRQ
    209     _timer_reset_irq( cluster_id, local_id );
     233    if ( _timer_reset_irq( cluster_id, local_id ) )
     234    {
     235        _get_lock(&_tty_put_lock);
     236        _puts("[GIET ERROR] illegal proc index detected by _isr_switch\n");
     237        _release_lock(&_tty_put_lock);
     238        return;
     239    }
    210240
    211241    // performs the context switch
  • soft/giet_vm/sys/sys_handler.c

    r203 r204  
    3232    &_sys_ukn,          /* 0x08 */
    3333    &_sys_ukn,          /* 0x09 */
    34     &_tty_read_irq,     /* 0x0A */
     34    &_sys_ukn,          /* 0x0A */
    3535    &_sys_ukn,          /* 0x0B */
    3636    &_sys_ukn,          /* 0x0C */
Note: See TracChangeset for help on using the changeset viewer.