Ignore:
Timestamp:
Jul 4, 2012, 2:51:18 PM (12 years ago)
Author:
alain
Message:

Introducing various modifications in kernel initialisation

File:
1 edited

Legend:

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

    r160 r165  
    1616//
    1717// The following global parameters must be defined in the giet_config.h file:
    18 // - NB_PROCS  : number of PROCS per cluster (if not zero)
    19 // - NB_DMAS   : number of DMA channels per cluster (if not zero)
    20 // - NB_TIMERS : number of TIMERS per cluster (if not zero)
    21 // - NB_TTYS   : number of TTY terminals per cluster (if not zero)
     18// - NB_CLUSTERS  : number of clusters
     19// - NB_PROCS     : number of PROCS per cluster
     20// - NB_TIMERS    : number of TIMERS per cluster
     21// - NB_DMAS      : number of DMA channels
     22// - NB_TTYS      : number of TTY terminals
     23// - NB_TIMERS    : number of TIMERS per cluster
     24// - CLUSTER_SPAN : address increment between clusters
    2225//
    2326// The following base addresses must be defined in the sys.ld file:
     
    5861#endif
    5962
     63#if (NB_TTYS < 1)
     64# error: NB_TTYS cannot be smaller than 1!
     65#endif
     66
     67#if (NB_TIMERS < NB_PROCS)
     68# error: NB_TIMERS must be larger or equal to NB_PROCS!
     69#endif
     70
     71#if (NB_PROCS > 8)
     72# error: NB_PROCS cannot be larger than 8!
     73#endif
     74
     75#if (NB_DMAS < 1)
     76# error: NB_DMAS cannot be 0!
     77#endif
     78
     79
    6080/////////////////////////////////////////////////////////////////////////////
    6181//      Global (uncachable) variables
     
    7191in_unckdata volatile unsigned int  _ioc_lock = 0;
    7292
    73 in_unckdata volatile unsigned int  _tty_lock[NB_TTYS] = { [0 ... NB_TTYS-1] = 0 };
    7493in_unckdata volatile unsigned char _tty_get_buf[NB_TTYS];
    7594in_unckdata volatile unsigned char _tty_get_full[NB_TTYS] = { [0 ... NB_TTYS-1] = 0 };
     95in_unckdata unsigned int           _tty_put_lock;
    7696
    7797//////////////////////////////////////////////////////////////////////////////
    7898//      VciMultiTimer driver
    7999//////////////////////////////////////////////////////////////////////////////
    80 // The number of independant timers per cluster is defined by the
    81 // configuration parameter NB_TIMERS.
     100// There is one MULTI-TIMER component per cluster.
     101// The number of timers per cluster must be larger or equal to the number
     102// processors (NB_TIMERS >= NB_PROCS), because each processor uses a private
     103// yimer for context switch.
    82104// The total number of timers is NB_CLUSTERS * NB_TIMERS
    83 // The global timer index = cluster_id*NB_TIMER + timer_id
     105// The global timer index = cluster_id*NB_TIMERS + timer_id
    84106//////////////////////////////////////////////////////////////////////////////
    85107
     
    87109// _timer_write()
    88110//
    89 // Write a 32-bit word in a memory mapped register of a timer device.
    90 // Returns 0 if success, > 0 if error.
    91 //////////////////////////////////////////////////////////////////////////////
    92 unsigned int _timer_write( unsigned int global_timer_index,
     111// Write a 32-bit word in a memory mapped register of a timer device,
     112// identified by the cluster index and the local timer index.
     113// Returns 0 if success, > 0 if error.
     114//////////////////////////////////////////////////////////////////////////////
     115unsigned int _timer_write( unsigned int cluster_index,
     116                           unsigned int timer_index,
    93117                           unsigned int register_index,
    94118                           unsigned int value )
    95119{
    96     volatile unsigned int *timer_address;
    97 
    98     unsigned int        cluster_id = global_timer_index / NB_TIMERS;
    99     unsigned int        timer_id   = global_timer_index % NB_TIMERS;
    100 
    101     /* parameters checking */
    102     if ( register_index >= TIMER_SPAN)                  return 1;
    103     if ( global_timer_index >= NB_CLUSTERS*NB_TIMERS )  return 1;
     120    unsigned int*       timer_address;
     121
     122    // parameters checking
     123    if ( register_index >= TIMER_SPAN)          return 1;
     124    if ( cluster_index >= NB_CLUSTERS)          return 1;
     125    if ( timer_index >= NB_TIMERS )         return 1;
    104126
    105127    timer_address = (unsigned int*)&seg_timer_base +
    106                     ( cluster_id * CLUSTER_SPAN )  +
    107                     ( timer_id * TIMER_SPAN );
    108 
    109     timer_address[register_index] = value; /* write word */
     128                    ( cluster_index * CLUSTER_SPAN )  +
     129                    ( timer_index * TIMER_SPAN );
     130
     131    timer_address[register_index] = value; // write word
    110132
    111133    return 0;
     
    115137// _timer_read()
    116138//
    117 // Read a 32-bit word in a memory mapped register of a timer device.
    118 // Returns 0 if success, > 0 if error.
    119 //////////////////////////////////////////////////////////////////////////////
    120 unsigned int _timer_read(unsigned int global_timer_index,
     139// Read a 32-bit word in a memory mapped register of a timer device,
     140// identified by the cluster index and the local timer index.
     141// Returns 0 if success, > 0 if error.
     142//////////////////////////////////////////////////////////////////////////////
     143unsigned int _timer_read(unsigned int cluster_index,
     144                         unsigned int timer_index,
    121145                         unsigned int register_index,
    122146                         unsigned int *buffer)
    123147{
    124     volatile unsigned int *timer_address;
    125 
    126     unsigned int        cluster_id = global_timer_index / NB_TIMERS;
    127     unsigned int        timer_id   = global_timer_index % NB_TIMERS;
    128 
    129     /* parameters checking */
    130     if ( register_index >= TIMER_SPAN)                  return 1;
    131     if ( global_timer_index >= NB_CLUSTERS*NB_TIMERS )  return 1;
     148    unsigned int *timer_address;
     149
     150    // parameters checking
     151    if ( register_index >= TIMER_SPAN)          return 1;
     152    if ( cluster_index >= NB_CLUSTERS)          return 1;
     153    if ( timer_index >= NB_TIMERS )         return 1;
    132154
    133155    timer_address = (unsigned int*)&seg_timer_base +
    134                     ( cluster_id * CLUSTER_SPAN )  +
    135                     ( timer_id * TIMER_SPAN );
    136 
    137     *buffer = timer_address[register_index]; /* read word */
     156                    ( cluster_index * CLUSTER_SPAN )  +
     157                    ( timer_index * TIMER_SPAN );
     158
     159    *buffer = timer_address[register_index]; // read word
    138160
    139161    return 0;
     
    146168// The system terminal is TTY[0].
    147169// The TTYs are allocated to applications by the GIET in the boot phase.
    148 // The nummber of TTYs allocated to each application, and the TTY used by each
     170// The nummber of TTYs allocated to each application, and used by each
    149171// task can be defined in the mapping_info data structure.
    150172// For each user task, the tty_id is stored in the context of the task (slot 34),
     
    152174// The TTY address is always computed as : seg_tty_base + tty_id*TTY_SPAN
    153175///////////////////////////////////////////////////////////////////////////////////
    154 
    155 ///////////////////////////////////////////////////////////////////////////////////
    156 // tty_get_lock()
    157 //
    158 // This blocking function is intended to be used by the _tty_write() function
    159 // to provide exclusive access to the TTY. It is not used yet, because it appears
    160 // that it creates livelock situations...
    161 ///////////////////////////////////////////////////////////////////////////////////
    162 static inline void _tty_get_lock( unsigned int tty_id )
    163 {
    164     register unsigned int delay = (_proctime() & 0xF) << 4;
    165     register unsigned int *plock = (unsigned int*)&_tty_lock[tty_id];
    166 
    167     asm volatile (
    168             "_tty_llsc:             \n"
    169             "ll   $2,    0(%0)      \n" /* $2 <= _tty_lock current value */
    170             "bnez $2,    _tty_delay \n" /* delay if _tty_lock already taken */
    171             "li   $3,    1          \n" /* $3 <= argument for sc */
    172             "sc   $3,    0(%0)      \n" /* try to set _tty_lock */
    173             "bnez $3,    _tty_ok    \n" /* exit if atomic */
    174             "_tty_delay:            \n"
    175             "move $4,    %1         \n" /* $4 <= delay */
    176             "_tty_loop:             \n"
    177             "addi $4,    $4,    -1  \n" /* $4 <= $4 - 1 */
    178             "beqz $4,    _tty_loop  \n" /* test end delay */
    179             "j           _tty_llsc  \n" /* retry */
    180             "_tty_ok:               \n"
    181             :
    182             :"r"(plock), "r"(delay)
    183             :"$2", "$3", "$4");
    184 }
    185176
    186177//////////////////////////////////////////////////////////////////////////////
     
    194185// The function returns  the number of characters that have been written.
    195186//////////////////////////////////////////////////////////////////////////////
    196 unsigned int _tty_write(const char *buffer, unsigned int length)
     187unsigned int _tty_write( const char             *buffer,
     188                         unsigned int   length)
    197189{
    198190    volatile unsigned int *tty_address;
     
    212204    for (nwritten = 0; nwritten < length; nwritten++)
    213205    {
    214         /* check tty's status */
     206        // check tty's status
    215207        if ((tty_address[TTY_STATUS] & 0x2) == 0x2)
    216208            break;
    217209        else
    218             /* write character */
     210            // write character
    219211            tty_address[TTY_WRITE] = (unsigned int)buffer[nwritten];
    220212    }
     
    226218//
    227219// This non-blocking function uses the TTY_GET_IRQ[tty_id] interrupt and
    228 // the associated // kernel buffer, that has been written by the ISR.
     220// the associated kernel buffer, that has been written by the ISR.
    229221// It fetches one single character from the _tty_get_buf[tty_id] kernel
    230222// buffer, writes this character to the user buffer, and resets the
     
    232224// Returns 0 if the kernel buffer is empty, 1 if the buffer is full.
    233225//////////////////////////////////////////////////////////////////////////////
    234 unsigned int _tty_read_irq(char *buffer, unsigned int length)
     226unsigned int _tty_read_irq( char                        *buffer,
     227                            unsigned int        length)
    235228{
    236229    unsigned int proc_id;
     
    262255// register of the TTY controler, and writes this character to the user buffer.
    263256// It doesn't use the TTY_GET_IRQ interrupt and the associated kernel buffer.
    264 // It doesn't take the lock protecting exclusive access...
    265257// Returns 0 if the register is empty, 1 if the register is full.
    266258////////////////////////////////////////////////////////////////////////////////
    267 unsigned int _tty_read(char *buffer, unsigned int length)
     259unsigned int _tty_read( char                    *buffer,
     260                        unsigned int    length)
    268261{
    269262    volatile unsigned int *tty_address;
     
    296289// _icu_write()
    297290//
    298 // Write a 32-bit word in a memory mapped register of the ICU device. The
    299 // base address is deduced by the proc_id.
    300 // Returns 0 if success, > 0 if error.
    301 ////////////////////////////////////////////////////////////////////////////////
    302 unsigned int _icu_write(unsigned int register_index, unsigned int value)
    303 {
    304     volatile unsigned int *icu_address;
    305     unsigned int proc_id;
    306 
    307     /* parameters checking */
    308     if (register_index >= ICU_END)
    309         return 1;
    310 
    311     proc_id = _procid();
    312     icu_address = (unsigned int*)&seg_icu_base + (proc_id * ICU_SPAN);
    313     icu_address[register_index] = value;   /* write word */
     291// Write a 32-bit word in a memory mapped register of the MULTI_ICU device,
     292// identified by the cluster index, and a processor local index.
     293// Returns 0 if success, > 0 if error.
     294////////////////////////////////////////////////////////////////////////////////
     295unsigned int _icu_write( unsigned int cluster_index,
     296                         unsigned int proc_index,
     297                         unsigned int register_index,
     298                         unsigned int value )
     299{
     300    unsigned int *icu_address;
     301
     302    // parameters checking
     303    if ( register_index >= ICU_SPAN)            return 1;
     304    if ( cluster_index >= NB_CLUSTERS)          return 1;
     305    if ( proc_index >= NB_PROCS )           return 1;
     306
     307    icu_address = (unsigned int*)&seg_icu_base +
     308                  ( cluster_index * CLUSTER_SPAN )  +
     309                  ( proc_index * ICU_SPAN );
     310
     311    icu_address[register_index] = value;   // write word
    314312    return 0;
    315313}
     
    318316// _icu_read()
    319317//
    320 // Read a 32-bit word in a memory mapped register of the ICU device. The
    321 // ICU base address is deduced by the proc_id.
    322 // Returns 0 if success, > 0 if error.
    323 ////////////////////////////////////////////////////////////////////////////////
    324 unsigned int _icu_read(unsigned int register_index, unsigned int *buffer)
    325 {
    326     volatile unsigned int *icu_address;
    327     unsigned int proc_id;
    328 
    329     /* parameters checking */
    330     if (register_index >= ICU_END)
    331         return 1;
    332 
    333     proc_id = _procid();
    334     icu_address = (unsigned int*)&seg_icu_base + (proc_id * ICU_SPAN);
    335     *buffer = icu_address[register_index]; /* read word */
     318// Read a 32-bit word in a memory mapped register of the MULTI_ICU device,
     319// identified by the cluster index and a processor local index.
     320// Returns 0 if success, > 0 if error.
     321////////////////////////////////////////////////////////////////////////////////
     322unsigned int _icu_read(  unsigned int cluster_index,
     323                         unsigned int proc_index,
     324                         unsigned int register_index,
     325                         unsigned int* buffer )
     326{
     327    unsigned int *icu_address;
     328
     329    // parameters checking
     330    if ( register_index >= ICU_SPAN)            return 1;
     331    if ( cluster_index >= NB_CLUSTERS)          return 1;
     332    if ( proc_index >= NB_PROCS )           return 1;
     333
     334    icu_address = (unsigned int*)&seg_icu_base +
     335                  ( cluster_index * CLUSTER_SPAN )  +
     336                  ( proc_index * ICU_SPAN );
     337
     338    *buffer = icu_address[register_index]; // read word
    336339    return 0;
    337340}
     
    341344////////////////////////////////////////////////////////////////////////////////
    342345// The Greater Dommon Divider is a -very- simple hardware coprocessor
    343 // performing the computation of a GCD of two 32 bits integers.
     346// performing the computation of the GCD of two 32 bits integers.
    344347// It has no DMA capability.
    345348////////////////////////////////////////////////////////////////////////////////
     
    351354// Returns 0 if success, > 0 if error.
    352355////////////////////////////////////////////////////////////////////////////////
    353 unsigned int _gcd_write(unsigned int register_index, unsigned int value)
     356unsigned int _gcd_write( unsigned int register_index,
     357                         unsigned int value)
    354358{
    355359    volatile unsigned int *gcd_address;
    356360
    357     /* parameters checking */
     361    // parameters checking
    358362    if (register_index >= GCD_END)
    359363        return 1;
    360364
    361365    gcd_address = (unsigned int*)&seg_gcd_base;
    362     gcd_address[register_index] = value; /* write word */
     366
     367    gcd_address[register_index] = value; // write word
    363368    return 0;
    364369}
     
    370375// Returns 0 if success, > 0 if error.
    371376////////////////////////////////////////////////////////////////////////////////
    372 unsigned int _gcd_read(unsigned int register_index, unsigned int *buffer)
     377unsigned int _gcd_read( unsigned int register_index,
     378                        unsigned int *buffer)
    373379{
    374380    volatile unsigned int *gcd_address;
    375381
    376     /* parameters checking */
     382    // parameters checking
    377383    if (register_index >= GCD_END)
    378384        return 1;
    379385
    380386    gcd_address = (unsigned int*)&seg_gcd_base;
    381     *buffer = gcd_address[register_index]; /* read word */
     387
     388    *buffer = gcd_address[register_index]; // read word
    382389    return 0;
    383390}
     
    386393// VciBlockDevice driver
    387394////////////////////////////////////////////////////////////////////////////////
    388 // The VciBlockDevice is a simple external storage contrÃŽler.
     395// The VciBlockDevice is a single channel external storage contrÃŽler.
    389396// The three functions below use the three variables _ioc_lock _ioc_done,  and
    390 // _ioc_status for synchronsation.
     397// _ioc_status for synchronisation.
    391398// As the IOC component can be used by several programs running in parallel,
    392399// the _ioc_lock variable guaranties exclusive access to the device.  The
     
    429436            "move $4,    %1         \n" /* $4 <= delay */
    430437            "_ioc_loop:             \n"
     438            "beqz $4,    _ioc_loop  \n" /* test end delay */
    431439            "addi $4,    $4,    -1  \n" /* $4 <= $4 - 1 */
    432             "beqz $4,    _ioc_loop  \n" /* test end delay */
    433             "j           _ioc_llsc  \n" /* retry */
     440            "j           _ioc_llsc  \n" /* retry ll */
     441            "nop                    \n"
    434442            "_ioc_ok:               \n"
    435443            :
Note: See TracChangeset for help on using the changeset viewer.