Changeset 437


Ignore:
Timestamp:
Nov 3, 2014, 10:53:00 AM (10 years ago)
Author:
alain
Message:

Introducing dynamic allocation of peripheral channel(TTY, NIC, TIM, CMA)
Removint the ICU driver : ICU component not supported anymore.
Removing the FBF driver.

Location:
soft/giet_vm/giet_drivers
Files:
4 deleted
31 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_drivers/bdv_driver.c

    r426 r437  
    66// Copyright (c) UPMC-LIP6
    77///////////////////////////////////////////////////////////////////////////////////
    8 // The bdv_driver.c and bdv_driver.h files are part ot the GIET-VM kernel.
    9 // This driver supports the SocLib vci_block_device component, that is
    10 // a single channel, block oriented, external storage contrÃŽler.
    11 //
    12 // The _bdv_read() and _bdv_write() functions are always blocking.
    13 // They can be called in 3 modes:
    14 //
    15 // - In BOOT mode, these functions use a polling policy on the BDV STATUS
    16 //   register to detect transfer completion, as interrupts are not activated.
    17 //   This mode is used by the boot code to load the map.bin file into memory
    18 //   (before MMU activation), or to load the .elf files (after MMU activation).
    19 //
    20 // - In KERNEL mode, these functions use a descheduling strategy:
    21 //   The ISR executed when transfer completes should restart the calling task.
    22 //   There is no checking of user access right to the memory buffer.
    23 //   This mode must be used, for an "open" system call.
    24 //
    25 // - In USER mode, these functions use a descheduling strategy:
    26 //   The ISR executed when transfer completes should restart the calling task,
    27 //   The user access right to the memory buffer must be checked.
    28 //   This mode must be used for a "read/write" system call.
    29 //
    30 // As the BDV component can be used by several programs running in parallel,
    31 // the _bdv_lock variable guaranties exclusive access to the device.  The
    32 // _bdv_read() and _bdv_write() functions use atomic LL/SC to get the lock.
    33 //
    34 // Finally, the memory buffer must fulfill the following conditions:
    35 // - The buffer must be word aligned,
    36 // - The buffer must be mapped in user space for an user access,
    37 // - The buffer must be writable in case of (to_mem) access,
    38 // - The total number of physical pages occupied by the user buffer cannot
    39 //   be larger than 512 pages if the IOMMU is activated,
    40 // - All physical pages occupied by the user buffer must be contiguous
    41 //   if the IOMMU is not activated.
    42 // An error code is returned if these conditions are not verified.
    43 //
    44 // The SEG_IOC_BASE address must be defined in the hard_config.h file.
    45 ///////////////////////////////////////////////////////////////////////////////////
    468// Implementation notes:
    47 //
    489// 1. In order to share code, the two _bdv_read() and _bdv_write() functions
    4910//    call the same _bdv_access() function.
    50 //
    5111// 2. All accesses to BDV registers are done by the two
    5212//    _bdv_set_register() and _bdv_get_register() low-level functions,
     
    12686
    12787#if GIET_DEBUG_IOC_DRIVER
    128 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] enters at cycle %d\n"
    129         " - to_mem  = %d\n"
    130         " - mode    = %d\n"
    131         " - paddr   = %l\n"
    132         " - sectors = %x\n"
    133         " - lba     = %x\n",
    134         x, y, p, _get_proctime(), to_mem, mode, buf_paddr, count, lba );
     88_puts("\n[BDV DEBUG] _bdv_access() : P[");
     89_putd( x );
     90_puts(",");
     91_putd( y );
     92_puts(",");
     93_putd( p );
     94_puts("] enters at cycle ");
     95_putd( _get_proctime() );
     96_puts("\n - to_mem  = ");
     97_putd( to_mem );
     98_puts("\n - mode    = ");
     99_putd( mode );
     100_puts("\n - paddr   = ");
     101_putl( buf_paddr );
     102_puts("\n - sectors = ");
     103_putd( count );
     104_puts("\n - lba     = ");
     105_putx( lba );
     106_puts("\n");
    135107#endif
    136108
     
    141113
    142114#if GIET_DEBUG_IOC_DRIVER
    143 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] get bdv_lock at cycle %d \n",
    144         x, y, p, _get_proctime() );
     115_puts("\n[BDV DEBUG] _bdv_access() : P[");
     116_putd( x );
     117_puts(",");
     118_putd( y );
     119_puts(",");
     120_putd( p );
     121_puts("] get bdv_lock at cycle ");
     122_pud( _get_proctime() );
     123_puts("\n");
    145124#endif
    146125
     
    160139
    161140#if GIET_DEBUG_IOC_DRIVER
    162 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] launch transfer in polling mode\n",
    163         x, y, p );
     141_puts("\n[BDV DEBUG] _bdv_access() : P[");
     142_putd( x );
     143_puts(",");
     144_putd( y );
     145_puts(",");
     146_putd( p );
     147_puts("] launch transfer in polling mode\n");
    164148#endif
    165149        unsigned int status;
     
    169153
    170154#if GIET_DEBUG_IOC_DRIVER
    171 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] wait on BDV_STATUS register ...\n",
    172         x, y, p );
     155_puts("\n[BDV DEBUG] _bdv_access() : P[");
     156_putd( x );
     157_puts(",");
     158_putd( y );
     159_puts(",");
     160_putd( p );
     161_puts("] wait on BDV_STATUS register ...\n");
    173162#endif
    174163        }
     
    214203
    215204#if GIET_DEBUG_IOC_DRIVER
    216 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] launch transfer in interrupt mode\n",
    217         x, y, p );
    218 #endif
     205_puts("\n[BDV DEBUG] _bdv_access() : P[");
     206_putd( x );
     207_puts(",");
     208_putd( y );
     209_puts(",");
     210_putd( p );
     211_puts("] launch transfer in nterrupt mode\n");
     212#endif
     213
    219214        // deschedule task
    220215        _ctx_switch();                     
    221216
    222217#if GIET_DEBUG_IOC_DRIVER
    223 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] resume execution after descheduling\n",
    224         x, y, p );
     218_puts("\n[BDV DEBUG] _bdv_access() : P[");
     219_putd( x );
     220_puts(",");
     221_putd( y );
     222_puts(",");
     223_putd( p );
     224_puts("] resume execution after descheduling\n");
    225225#endif
    226226        // restore SR
    227227        _it_restore( &save_sr );
    228228
    229 #if GIET_DEBUG_IOC_DRIVER
    230 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] returns from _it_restore()\n",
    231         x, y, p );
    232 #endif
    233229        // analyse status
    234230        error = ( (_bdv_status == BLOCK_DEVICE_READ_ERROR) ||
     
    241237
    242238#if GIET_DEBUG_IOC_DRIVER
    243 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] exit at cycle %d / error = %d\n",
    244         x, y, p, _get_proctime(), error );
     239_puts("\n[BDV DEBUG] _bdv_access() : P[");
     240_putd( x );
     241_puts(",");
     242_putd( y );
     243_puts(",");
     244_putd( p );
     245_puts("] exit at cycle ");
     246_putd( _get_proctime() );
     247_puts(" / error = ");
     248_putd( error )
     249_puts("\n");
    245250#endif
    246251
     
    249254
    250255///////////////////////////////////////////////////////////////////////////////
    251 // This function cheks block size, and desactivates the interrupts.
    252 // Return 0 for success, > 0 if error
    253 ///////////////////////////////////////////////////////////////////////////////
     256//      External functions
     257///////////////////////////////////////////////////////////////////////////////
     258
     259////////////////////////
    254260unsigned int _bdv_init()
    255261{
    256262    if ( _bdv_get_register( BLOCK_DEVICE_BLOCK_SIZE ) != 512 )
    257263    {
    258         _printf("\n[GIET ERROR] in _bdv_init() : block size must be 512 bytes\n");
     264        _puts("\n[GIET ERROR] in _bdv_init() : block size must be 512 bytes\n");
    259265        return 1;
    260266    }
     
    264270}
    265271
    266 ///////////////////////////////////////////////////////////////////////////////
    267 // Transfer data from the block device to a memory buffer.
    268 // - mode     : BOOT / KERNEL / USER
    269 // - lba      : first block index on the block device
    270 // - buffer   : base address of the memory buffer (must be word aligned)
    271 // - count    : number of blocks to be transfered.
    272 // Returns 0 if success, > 0 if error.
    273 ///////////////////////////////////////////////////////////////////////////////
     272////////////////////////////////////////////////
    274273unsigned int _bdv_read( unsigned int       mode, 
    275274                        unsigned int       lba,
     
    284283}
    285284
    286 ///////////////////////////////////////////////////////////////////////////////
    287 // Transfer data from a memory buffer to the block device.
    288 // - mode     : BOOT / KERNEL / USER
    289 // - lba      : first block index on the block device
    290 // - buffer   : base address of the memory buffer (must be word aligned)
    291 // - count    : number of blocks to be transfered.
    292 // Returns 0 if success, > 0 if error.
    293 ///////////////////////////////////////////////////////////////////////////////
     285/////////////////////////////////////////////////
    294286unsigned int _bdv_write( unsigned int       mode, 
    295287                         unsigned int       lba,
     
    304296}
    305297
    306 ///////////////////////////////////////////////////////////////////////////////
    307 // Returns device status.
    308 ///////////////////////////////////////////////////////////////////////////////
     298//////////////////////////////
    309299unsigned int _bdv_get_status()
    310300{
     
    312302}
    313303
    314 ///////////////////////////////////////////////////////////////////////////////
    315 // Returns block size.
    316 ///////////////////////////////////////////////////////////////////////////////
     304//////////////////////////////////
    317305unsigned int _bdv_get_block_size()
    318306{
     
    320308}
    321309
    322 ///////////////////////////////////////////////////////////////////////////////////
    323 // This ISR save the status, acknowledge the IRQ,
    324 // and activates the task waiting on IO transfer.
    325 // It can be an HWI or a SWI.
    326 //
    327 // TODO the _set_task_slot access should be replaced by an atomic LL/SC
    328 //      when the CTX_RUN bool will be replaced by a bit_vector.
    329 ///////////////////////////////////////////////////////////////////////////////////
     310/////////////////////////////////////
    330311void _bdv_isr( unsigned int irq_type,   // HWI / WTI
    331312               unsigned int irq_id,     // index returned by ICU
  • soft/giet_vm/giet_drivers/bdv_driver.h

    r350 r437  
    55// Maintainer: cesar fuguet
    66// Copyright (c) UPMC-LIP6
     7///////////////////////////////////////////////////////////////////////////////////
     8// The bdv_driver.c and bdv_driver.h files are part ot the GIET-VM kernel.
     9// This driver supports the SocLib vci_block_device component, that is
     10// a single channel, block oriented, external storage contrÃŽler.
     11//
     12// The _bdv_read() and _bdv_write() functions are always blocking.
     13// They can be called in 3 modes:
     14//
     15// - In BOOT mode, these functions use a polling policy on the BDV STATUS
     16//   register to detect transfer completion, as interrupts are not activated.
     17//   This mode is used by the boot code to load the map.bin file into memory
     18//   (before MMU activation), or to load the .elf files (after MMU activation).
     19//
     20// - In KERNEL mode, these functions use a descheduling strategy:
     21//   The ISR executed when transfer completes should restart the calling task.
     22//   There is no checking of user access right to the memory buffer.
     23//   This mode must be used, for an "open" system call.
     24//
     25// - In USER mode, these functions use a descheduling strategy:
     26//   The ISR executed when transfer completes should restart the calling task,
     27//   The user access right to the memory buffer must be checked.
     28//   This mode must be used for a "read/write" system call.
     29//
     30// As the BDV component can be used by several programs running in parallel,
     31// the _bdv_lock variable guaranties exclusive access to the device.  The
     32// _bdv_read() and _bdv_write() functions use atomic LL/SC to get the lock.
     33//
     34// Finally, the memory buffer must fulfill the following conditions:
     35// - The buffer must be word aligned,
     36// - The buffer must be mapped in user space for an user access,
     37// - The buffer must be writable in case of (to_mem) access,
     38// - The total number of physical pages occupied by the user buffer cannot
     39//   be larger than 512 pages if the IOMMU is activated,
     40// - All physical pages occupied by the user buffer must be contiguous
     41//   if the IOMMU is not activated.
     42// An error code is returned if these conditions are not verified.
     43//
     44// The SEG_IOC_BASE address must be defined in the hard_config.h file.
    745///////////////////////////////////////////////////////////////////////////////////
    846
     
    5694
    5795///////////////////////////////////////////////////////////////////////////////////
    58 // BDV access functions (vci_block_device)
     96//            Access functions
    5997///////////////////////////////////////////////////////////////////////////////////
    6098
     99///////////////////////////////////////////////////////////////////////////////////
     100// This function cheks block size == 512, and desactivates the interrupts.
     101// Return 0 for success, > 0 if error
     102///////////////////////////////////////////////////////////////////////////////////
    61103extern unsigned int _bdv_init();
    62104
     105///////////////////////////////////////////////////////////////////////////////////
     106// Transfer data from the block device to a memory buffer.
     107// - mode     : BOOT / KERNEL / USER
     108// - lba      : first block index on the block device
     109// - buffer   : base address of the memory buffer (must be word aligned)
     110// - count    : number of blocks to be transfered.
     111// Returns 0 if success, > 0 if error.
     112////////////////////////////////////////////////////////////////////////////////////
     113extern unsigned int _bdv_read(  unsigned int       mode,
     114                                unsigned int       lba,
     115                                unsigned long long buffer,
     116                                unsigned int       count );
     117
     118///////////////////////////////////////////////////////////////////////////////////
     119// Transfer data from a memory buffer to the block device.
     120// - mode     : BOOT / KERNEL / USER
     121// - lba      : first block index on the block device
     122// - buffer   : base address of the memory buffer (must be word aligned)
     123// - count    : number of blocks to be transfered.
     124// Returns 0 if success, > 0 if error.
     125///////////////////////////////////////////////////////////////////////////////////
    63126extern unsigned int _bdv_write( unsigned int       mode,
    64127                                unsigned int       lba,
     
    66129                                unsigned int       count );
    67130
    68 extern unsigned int _bdv_read(  unsigned int       mode,
    69                                 unsigned int       lba,
    70                                 unsigned long long buffer,
    71                                 unsigned int       count );
    72 
     131///////////////////////////////////////////////////////////////////////////////////
     132// Returns device status.
     133///////////////////////////////////////////////////////////////////////////////////
    73134extern unsigned int _bdv_get_status();
    74135
     136///////////////////////////////////////////////////////////////////////////////////
     137// Returns block size.
     138///////////////////////////////////////////////////////////////////////////////////
    75139extern unsigned int _bdv_get_block_size();
    76140
     141///////////////////////////////////////////////////////////////////////////////////
     142// This ISR save the status, acknowledge the IRQ, and activates the task
     143// waiting on IO transfer. It can be an HWI or a SWI.
     144//
     145// TODO the _set_task_slot access should be replaced by an atomic LL/SC
     146//      when the CTX_RUN bool will be replaced by a bit_vector.
     147///////////////////////////////////////////////////////////////////////////////////
    77148extern void _bdv_isr( unsigned irq_type,
    78149                      unsigned irq_id,
    79150                      unsigned channel );
    80151
    81 ///////////////////////////////////////////////////////////////////////////////////
    82152
    83153#endif
  • soft/giet_vm/giet_drivers/cma_driver.c

    r320 r437  
    44// Author    : alain greiner
    55// Copyright (c) UPMC-LIP6
    6 ///////////////////////////////////////////////////////////////////////////////////
    7 // The cma_driver.c and cma_driver.h files are part ot the GIET-VM kernel.
    8 // This driver supports the SocLib vci_chbuf_dma component, that is
    9 // a multi channels, chained buffer DMA controller.
    10 //
    11 // This component can be used in conjonction with the SocLib vci_frame_buffer
    12 // to display images, or with the SocLib vci_multi_nic controller to tranfer
    13 // both RX and TX packets between NIC and memory buffers.
    14 //
    15 // The SEG_DMA_BASE address must be defined in the hard_config.h file
    16 ////////////////////////////////////////////////////////////////////////////////////
    17 // Implementation notes:
    18 // 1. The higher level access functions can be found in the fbf_driver and
    19 //    nic_driver files.
    20 // 2. All accesses to CMA registers are done by the two
    21 //    _cma_set_register() and _cma_get_register() low-level functions,
    22 //    that are handling virtual / physical extended addressing.
    236///////////////////////////////////////////////////////////////////////////////////
    247
     
    3114#endif
    3215
    33 ///////////////////////////////////////////////////////////////////////////////
    34 // This low_level function returns the value contained in register (index).
    35 ///////////////////////////////////////////////////////////////////////////////
     16/////////////////////////////////////////////////////
    3617unsigned int _cma_get_register( unsigned int channel,
    3718                                unsigned int index )
     
    4223}
    4324
    44 ///////////////////////////////////////////////////////////////////////////////
    45 // This low-level function set a new value in register (index).
    46 ///////////////////////////////////////////////////////////////////////////////
     25/////////////////////////////////////////////
    4726void _cma_set_register( unsigned int channel,
    4827                        unsigned int index,
     
    5433}
    5534
    56 ///////////////////////////////////////////////////////////////////////////////
    57 // This ISR handles the IRQ generated by a CMA channel.
    58 ///////////////////////////////////////////////////////////////////////////////
     35////////////////////////////////////////////////////
     36void _cma_start_channel( unsigned int       channel,
     37                         unsigned long long src_paddr,
     38                         unsigned int       src_nbufs,
     39                         unsigned long long dst_paddr,
     40                         unsigned int       dst_nbufs,
     41                         unsigned int       buf_length )
     42{
     43    _cma_set_register( channel, CHBUF_SRC_DESC , (unsigned int)(src_paddr & 0xFFFFFFFF) );
     44    _cma_set_register( channel, CHBUF_SRC_EXT  , (unsigned int)(src_paddr >> 32) );
     45    _cma_set_register( channel, CHBUF_SRC_NBUFS, src_nbufs );
     46    _cma_set_register( channel, CHBUF_DST_DESC , (unsigned int)(dst_paddr & 0xFFFFFFFF) );
     47    _cma_set_register( channel, CHBUF_DST_EXT  , (unsigned int)(dst_paddr >> 32) );
     48    _cma_set_register( channel, CHBUF_DST_NBUFS, dst_nbufs );
     49    _cma_set_register( channel, CHBUF_BUF_SIZE , buf_length );
     50    _cma_set_register( channel, CHBUF_PERIOD   , 300 );
     51    _cma_set_register( channel, CHBUF_RUN      , 1 );
     52}
     53
     54//////////////////////////////////////////////
     55void _cma_stop_channel( unsigned int channel )
     56{
     57    _cma_set_register( channel, CHBUF_RUN      , 0 );
     58}
     59
     60//////////////////////////////////////
    5961void _cma_isr( unsigned int irq_type,
    6062               unsigned int irq_id,
    6163               unsigned int channel )
    6264{
    63     _printf("\n[GIET ERROR] _cma_isr() not implemented\n");
     65    _puts("\n[GIET ERROR] _cma_isr() not implemented\n");
    6466    _exit();
    6567}
  • soft/giet_vm/giet_drivers/cma_driver.h

    r295 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7// The cma_driver.c and cma_driver.h files are part ot the GIET-VM kernel.
     8// This driver supports the SocLib vci_chbuf_dma component, that is
     9// a multi channels, chained buffer DMA controller.
     10//
     11// This component can be used in conjonction with the SocLib vci_frame_buffer
     12// to display images, or with the SocLib vci_multi_nic controller to tranfer
     13// RX or TX packets between NIC and memory buffers.
     14//
     15// The SEG_CMA_BASE address must be defined in the hard_config.h file
     16//
     17// All accesses to CMA registers are done by the two _cma_set_register()
     18// and _cma_get_register() low-level functions, that are handling virtual
     19// to physical extended addressing.
     20//
     21// The higher level access functions are defined in the fbf_driver
     22// and nic_driver files.
     23///////////////////////////////////////////////////////////////////////////////////
    724
    825#ifndef _GIET_CMA_DRIVERS_H_
     
    1027
    1128///////////////////////////////////////////////////////////////////////////////////
    12 // CMA (vci_chbuf_dma) registers offsets
     29// registers offsets
    1330///////////////////////////////////////////////////////////////////////////////////
    1431
     
    3047
    3148///////////////////////////////////////////////////////////////////////////////////
    32 // CMA (vci_chbuf_dma) low-level access functions
     49//   access functions
    3350///////////////////////////////////////////////////////////////////////////////////
    3451
     52////////////////////////////////////////////////////////////
    3553extern unsigned int _cma_get_register( unsigned int channel,
    3654                                       unsigned int index );
    3755
     56///////////////////////////////////////////////////
    3857extern void _cma_set_register( unsigned int channel,
    3958                               unsigned int index,
    4059                               unsigned int value );
    4160
     61///////////////////////////////////////////////////
     62void _cma_start_channel( unsigned int       channel,
     63                         unsigned long long src_paddr,
     64                         unsigned int       src_nbufs,
     65                         unsigned long long dst_paddr,
     66                         unsigned int       dst_nbufs,
     67                         unsigned int       buf_length );
     68
     69//////////////////////////////////////////////
     70void _cma_stop_channel( unsigned int channel );
     71
     72////////////////////////////////////////////
    4273extern void _cma_isr( unsigned int irq_type,
    4374                      unsigned int irq_id,
    4475                      unsigned int channel );
    45 
    46 ///////////////////////////////////////////////////////////////////////////////////
    4776
    4877#endif
  • soft/giet_vm/giet_drivers/dma_driver.c

    r345 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The dma_driver.c and dma_driver.h files are part ot the GIET-VM nano-kernel.
    8 // This driver supports the SoCLib vci_multi_dma component.
    9 //
    10 // It can exist several DMA controlers in the architecture (one per cluster),
    11 // and each controller can contain several channels.
    12 //
    13 // There is  (NB_CLUSTERS * NB_DMA_CHANNELS) channels, indexed by a global index:
    14 //        dma_id = cluster_xy * NB_DMA_CHANNELS + loc_id
    15 //
    16 // A DMA channel is a private ressource allocated to a given processor.
    17 // It is exclusively used by the kernet to speedup data transfers, and
    18 // there is no lock protecting exclusive access to the channel.
    19 // As the kernel uses a polling policy on the DMA_STATUS register to detect
    20 // transfer completion, the DMA IRQ is not used.
    21 //
    22 // The virtual base address of the segment associated to a channel is:
    23 //    SEG_DMA_BASE + cluster_xy * PERI_CLUSTER_INCREMENT + DMA_SPAN * channel_id
    24 //
    25 // The SEG_DMA_BASE virtual address mus be defined in the hard_config.h file.
    26 ////////////////////////////////////////////////////////////////////////////////////
    277
    288#include <giet_config.h>
     
    10181}
    10282
    103 //////////////////////////////////////////////////////////////////////////////////
    104 // AS the GIET-VM uses a polling policy to detect transfer completion,
    105 // The DMA component initialisation must disable interrupts.
    106 // This function disables interrupts for one DMA channel in one cluster.
    107 // Returns 0 if success, returns > 0 if error.
    108 //////////////////////////////////////////////////////////////////////////////////
     83////////////////////////////////////////////////
    10984unsigned int _dma_init( unsigned int cluster_xy,
    11085                        unsigned int channel_id )
     
    127102}
    128103
    129 //////////////////////////////////////////////////////////////////////////////////
    130 // This function re-initialises one DMA channel in one cluster after a transfer
    131 // completion. It actually forces the channel to return in iDLE state.
    132 //////////////////////////////////////////////////////////////////////////////////
     104//////////////////////////////////////////////////
    133105unsigned int _dma_reset( unsigned int cluster_xy,
    134106                         unsigned int channel_id )
     
    151123}
    152124
    153 //////////////////////////////////////////////////////////////////////////////////
    154 // This function returns the status of a DMA channel in a given cluster
    155 //////////////////////////////////////////////////////////////////////////////////
     125//////////////////////////////////////////////////////
    156126unsigned int _dma_get_status( unsigned int cluster_xy,
    157127                              unsigned int channel_id )
     
    173143}
    174144
    175 //////////////////////////////////////////////////////////////////////////////////
    176 // This function sets the physical address (including 64 bits extension)
    177 // for the source and destination buffers in a DMA channel in a given cluster
    178 // and sets the transfer size to lauch the transfer.
    179 //////////////////////////////////////////////////////////////////////////////////
     145////////////////////////////////////////////////////////
    180146void _dma_start_transfer( unsigned int       cluster_xy,  // DMA cluster
    181147                          unsigned int       channel_id,  // DMA channel
     
    201167}
    202168
    203 ///////////////////////////////////////////////////////////////////////////////////
    204 // This function copies a source memory buffer to a destination memory buffer,
    205 // using directly physical addresses.
    206 // This blocking function is supposed to be used by the kernel only,
    207 // and uses a polling policy on DMA_STATUS register to detect completion.
    208 // Therefore, the DMA_IRQ is NOT used.
    209 // The source and destination buffers base addresses must be word aligned,
    210 // and the buffer's size must be multiple of 4.
    211 // In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error
    212 // message is displayed on TTY0, and the system crash.
    213 ///////////////////////////////////////////////////////////////////////////////////
     169///////////////////////////////////////////////////////
    214170void _dma_physical_copy( unsigned int       cluster_xy,  // DMA cluster
    215171                         unsigned int       channel_id,  // DMA channel
     
    225181    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (channel_id >= NB_DMA_CHANNELS) )
    226182    {
    227         _printf("\n[GIET ERROR] in _dma_physical_copy() : illegal DMA channel ");
     183        _puts("\n[DMA ERROR] in _dma_physical_copy() : illegal DMA channel ");
    228184        _exit();
    229185    }
     
    232188    if ( (dst_paddr & 0x3)   || (src_paddr & 0x3) || (size & 0x3) )
    233189    {
    234         _printf("\n[GIET ERROR] in _dma_physical_copy() : buffer unaligned\n");
    235         _exit();
    236     }
    237 
    238 #if GIET_DEBUG_DMA_DRIVER
    239 _printf("\n[DMA DEBUG] Start a dma_physical_copy on channel[%d,%d,%d] at cycle %d\n"
    240         " - src_paddr   = %l\n"
    241         " - dst_paddr   = %l\n"
    242         " - bytes       = %x\n",
    243         x, y, channel_id, _get_proctime(), src_paddr, dst_paddr, size );
     190        _puts("\n[DMA ERROR] in _dma_physical_copy() : buffer unaligned\n");
     191        _exit();
     192    }
     193
     194#if GIET_DEBUG_DMA_DRIVER
     195_puts("\n[DMA DEBUG] enter _dma_physical_copy() for channel[");
     196_putd( x );
     197_puts(",");
     198_putd( y );
     199_puts(",");
     200_putd( channel_id );
     201_puts("] at cycle ");
     202_putd( _get_proctime() );
     203_puts("\n - src_paddr   = ");
     204_putl( src_paddr );
     205_puts("\n - dst_paddr   = ");
     206_putl( dst_paddr );
     207_puts("\n - bytes       = ");
     208_putd( size );
     209_puts("\n");
    244210#endif
    245211
     
    256222
    257223#if GIET_DEBUG_DMA_DRIVER
    258 _printf("\n[DMA DEBUG] _dma_physical_copy() : ... waiting on DMA_STATUS register\n");
     224_puts("\n[DMA DEBUG] _dma_physical_copy() : ... waiting on DMA_STATUS register\n");
    259225#endif
    260226
     
    264230    if( status != DMA_SUCCESS )
    265231    {
    266         _printf("\n[GIET ERROR] in _dma_physical_copy() : DMA_STATUS = %x\n", status );
    267         _exit();
    268     }
     232        _puts("\n[DMA ERROR] in _dma_physical_copy() : bad DMA_STATUS");
     233        _exit();
     234    }
     235
    269236    // reset dma channel
    270237    _dma_reset( cluster_xy, channel_id );
    271238
    272239#if GIET_DEBUG_DMA_DRIVER
    273 _printf("\n[DMA DEBUG] _dma_physical_copy() completed at cycle %d\n", _get_proctime() );
     240_puts("\n[DMA DEBUG] exit _dma_physical_copy() at cycle ");
     241_putd( _get_proctime() );
     242_puts("\n");
    274243#endif
    275244
    276245#else // NB_DMA_CHANNELS == 0
    277     _printf("\n[GIET ERROR] in _dma_physical_copy() : NB_DMA_CHANNELS == 0 / cycle %d\n",
    278             _get_proctime );
     246
     247    _puts("\n[DMA ERROR] in _dma_physical_copy() : NB_DMA_CHANNELS == 0\n");
    279248    _exit();
    280 #endif
    281 }
    282 
    283 ///////////////////////////////////////////////////////////////////////////////////
    284 // This function copies a source memory buffer to a destination memory buffer,
    285 // making virtual to physical address translation: the MMU should be activated.
    286 // This blocking function is supposed to be used by the kernel only,
    287 // and uses a polling policy on DMA_STATUS register to detect completion.
    288 // Therefore, the DMA_IRQ is NOT used.
    289 // The source and destination buffers base addresses must be word aligned,
    290 // and the buffer's size must be multiple of 4.
    291 // In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error
    292 // message is displayed on TTY0, and the system crash.
    293 ///////////////////////////////////////////////////////////////////////////////////
     249
     250#endif
     251}
     252
     253
     254////////////////////////////////////////
    294255void  _dma_copy( unsigned int cluster_xy,    // DMA cluster
    295256                 unsigned int channel_id,    // DMA channel
     
    306267    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (channel_id >= NB_DMA_CHANNELS) )
    307268    {
    308         _printf("\n[GIET ERROR] in _dma_copy() : illegal DMA channel ");
     269        _puts("\n[DMA ERROR] in _dma_copy() : illegal DMA channel ");
    309270        _exit();
    310271    }
     
    313274    if ( (dst_vaddr & 0x3)   || (src_vaddr & 0x3) || (size & 0x3) )
    314275    {
    315         _printf("\n[GIET ERROR] in _dma_copy() : buffer unaligned\n");
     276        _puts("\n[DMA ERROR] in _dma_copy() : buffer unaligned\n");
    316277        _exit();
    317278    }
     
    322283
    323284#if GIET_DEBUG_DMA_DRIVER
    324 _printf("\n[DMA DEBUG] Start a dma_copy on channel[%d,%d,%d] at cycle %d\n"
    325         " - src_vaddr   = %x\n"
    326         " - dst_vaddr   = %x\n"
    327         " - bytes       = %x\n",
    328         x, y, channel_id, _get_proctime(), src_vaddr, dst_vaddr, size );
     285_puts("\n[DMA DEBUG] enter _dma_copy() for channel[");
     286_putd( x );
     287_puts(",");
     288_putd( y );
     289_puts(",");
     290_putd( channel_id );
     291_puts("] at cycle ");
     292_putd( _get_proctime() );
     293_puts("\n - src_vaddr   = ");
     294_putx( src_vaddr );
     295_puts("\n - dst_vaddr   = ");
     296_putx( dst_vaddr );
     297_puts("\n - bytes       = ");
     298_putd( size );
     299_puts("\n");
    329300#endif
    330301
     
    334305         (size & 0x3) )
    335306    {
    336         _printf("\n[GIET ERROR] in _dma_copy() : buffer unaligned\n");
     307        _puts("\n[DMA ERROR] in _dma_copy() : buffer unaligned\n");
    337308        _exit();
    338309    }
     
    348319    if ( ko )
    349320    {
    350         _printf("\n[GIET ERROR] in _dma_copy() : source buffer unmapped\n");
     321        _puts("\n[DMA ERROR] in _dma_copy() : source buffer unmapped\n");
    351322        _exit();
    352323    }
     
    361332    if ( ko )
    362333    {
    363         _printf("\n[GIET ERROR] in _dma_copy() : dest buffer unmapped\n");
     334        _puts("\n[DMA ERROR] in _dma_copy() : dest buffer unmapped\n");
    364335        _exit();
    365336    }
     
    368339
    369340#if GIET_DEBUG_DMA_DRIVER
    370 _printf(" - src_paddr   = %l\n"
    371         " - dst_paddr   = %l\n",
    372         src_paddr, dst_paddr );
     341_puts("\n - src_paddr   = ");
     342_putl( src_paddr );
     343_puts("\n - dst_paddr   = ");
     344_putl( dst_paddr );
     345_puts("\n");
    373346#endif
    374347
     
    385358
    386359#if GIET_DEBUG_DMA_DRIVER
    387 _printf("\n[DMA DEBUG] _dma_copy() : ... waiting on DMA_STATUS register\n");
     360_puts("\n[DMA DEBUG] _dma_copy() : ... waiting on DMA_STATUS register\n");
    388361#endif
    389362
     
    393366    if( status != DMA_SUCCESS )
    394367    {
    395         _printf("\n[GIET ERROR] in _dma_copy() : DMA_STATUS = %x\n", status );
     368        _puts("\n[DMA ERROR] in _dma_copy() : bad DMA_STATUS\n");
    396369        _exit();
    397370    }
     
    400373
    401374#if GIET_DEBUG_DMA_DRIVER
    402 _printf("\n[DMA DEBUG] _dma_copy() completed at cycle %d\n", _get_proctime() );
     375_puts("\n[DMA DEBUG] exit _dma_copy() at cycle ");
     376_putd( _get_proctime() );
     377_puts("\n");
    403378#endif
    404379
    405380#else // NB_DMA_CHANNELS == 0
    406     _printf("\n[GIET ERROR] in _dma_copy() : NB_DMA_CHANNELS == 0 / cycle %d\n",
    407             _get_proctime );
     381
     382    _puts("\n[DMA ERROR] in _dma_copy() : NB_DMA_CHANNELS == 0\n");
    408383    _exit();
     384
    409385#endif
    410386} // end _dma_copy
    411387
    412 ///////////////////////////////////////////////////////////////////////////////
    413 // This ISR handles the IRQ generated by a DMA channel.
    414 ///////////////////////////////////////////////////////////////////////////////
     388/////////////////////////////////////
    415389void _dma_isr( unsigned int irq_type,
    416390               unsigned int irq_id,
    417391               unsigned int channel )
    418392{
    419     _printf("\n[GIET ERROR] _dma_isr() not implemented / cycle %d\n",
    420             _get_proctime() );
     393    _puts("\n[DMA ERROR] _dma_isr() not implemented\n");
    421394    _exit();
    422395}
  • soft/giet_vm/giet_drivers/dma_driver.h

    r343 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7// The dma_driver.c and dma_driver.h files are part ot the GIET-VM nano-kernel.
     8// This driver supports the SoCLib vci_multi_dma component.
     9//
     10// It can exist several DMA controlers in the architecture (one per cluster),
     11// and each controller can contain several channels.
     12//
     13// There is  (NB_CLUSTERS * NB_DMA_CHANNELS) channels, indexed by a global index:
     14//        dma_id = cluster_xy * NB_DMA_CHANNELS + loc_id
     15//
     16// A DMA channel is a private ressource allocated to a given processor.
     17// It is exclusively used by the kernet to speedup data transfers, and
     18// there is no lock protecting exclusive access to the channel.
     19// As the kernel uses a polling policy on the DMA_STATUS register to detect
     20// transfer completion, the DMA IRQ is not used.
     21//
     22// The virtual base address of the segment associated to a channel is:
     23//    SEG_DMA_BASE + cluster_xy * PERI_CLUSTER_INCREMENT + DMA_SPAN * channel_id
     24//
     25// The SEG_DMA_BASE virtual address mus be defined in the hard_config.h file.
     26////////////////////////////////////////////////////////////////////////////////////
    727
    828#ifndef _GIET_DMA_DRIVER_H_
     
    3757
    3858
    39 ///////////////////////////////////////////////////////////////////////////////////
    40 // Multi DMA variables and access functions  (vci_multi_dma)
    41 ///////////////////////////////////////////////////////////////////////////////////
     59///////////////////////////////////////////////////////////////////////////////
     60//                  low-level access functions 
     61///////////////////////////////////////////////////////////////////////////////
    4262
    43 // low level access functions
     63//////////////////////////////////////////////////////////////////////////////////
     64// This function disables interrupts for one DMA channel in one cluster.
     65// AS the GIET-VM uses a polling policy to detect DMA transfer completion,
     66// the DMA component initialisation must disable interrupts.
     67// Returns 0 if success, returns > 0 if error.
     68//////////////////////////////////////////////////////////////////////////////////
    4469extern unsigned int _dma_init( unsigned int cluster_xy,
    4570                               unsigned int channel_id );
    4671
     72//////////////////////////////////////////////////////////////////////////////////
     73// This function re-initialises one DMA channel in one cluster after transfer
     74// completion. It actually forces the channel to return in IDLE state.
     75//////////////////////////////////////////////////////////////////////////////////
    4776extern unsigned int _dma_reset( unsigned int  cluster_xy,
    4877                                unsigned int  channel_id );
    4978
     79//////////////////////////////////////////////////////////////////////////////////
     80// This function returns the status of a DMA channel in a given cluster
     81//////////////////////////////////////////////////////////////////////////////////
    5082extern unsigned int _dma_get_status( unsigned int  cluster_xy,
    5183                                     unsigned int  channel_id );
    5284
     85//////////////////////////////////////////////////////////////////////////////////
     86// This function sets the physical address (including 64 bits extension)
     87// for the source and destination buffers in a DMA channel in a given cluster
     88// and sets the transfer size to lauch the transfer.
     89//////////////////////////////////////////////////////////////////////////////////
    5390extern void _dma_start_transfer( unsigned int       cluster_xy,
    5491                                 unsigned int       channel_id,
     
    5794                                 unsigned int       size );
    5895
    59 // higher level access function
     96//////////////////////////////////////////////////////////////////////////////////
     97//                     higher level access function
     98//////////////////////////////////////////////////////////////////////////////////
     99
     100///////////////////////////////////////////////////////////////////////////////////
     101// This function copies a source memory buffer to a destination memory buffer,
     102// using directly physical addresses.
     103// This blocking function is supposed to be used by the kernel only,
     104// and uses a polling policy on DMA_STATUS register to detect completion.
     105// Therefore, the DMA_IRQ is NOT used.
     106// The source and destination buffers base addresses must be word aligned,
     107// and the buffer's size must be multiple of 4.
     108// In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error
     109// message is displayed on TTY0, and system crash.
     110///////////////////////////////////////////////////////////////////////////////////
    60111extern void _dma_physical_copy( unsigned int       cluster_xy,
    61112                                unsigned int       channel_id,
     
    64115                                unsigned int       size );
    65116
     117///////////////////////////////////////////////////////////////////////////////////
     118// This function copies a source memory buffer to a destination memory buffer,
     119// making virtual to physical address translation: the MMU should be activated.
     120// This blocking function is supposed to be used by the kernel only,
     121// and uses a polling policy on DMA_STATUS register to detect completion.
     122// Therefore, the DMA_IRQ is NOT used.
     123// The source and destination buffers base addresses must be word aligned,
     124// and the buffer's size must be multiple of 4.
     125// In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error
     126// message is displayed on TTY0, and system crash.
     127///////////////////////////////////////////////////////////////////////////////////
    66128extern void _dma_copy(  unsigned int cluster_xy,
    67129                        unsigned int channel_id,
     
    71133                        unsigned int size );
    72134
     135///////////////////////////////////////////////////////////////////////////////
     136// This ISR should not be used by the GIET_VM, because the DMA is only
     137// used by the kernel in the boot phase, with a polling strategy.
     138///////////////////////////////////////////////////////////////////////////////
    73139extern void _dma_isr( unsigned int irq_type,
    74140                      unsigned int irq_id,
    75141                      unsigned int channel );
    76142
    77 ///////////////////////////////////////////////////////////////////////////////////
    78143
    79144#endif
  • soft/giet_vm/giet_drivers/hba_driver.c

    r320 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The hba_driver.c and hba_driver.h files are part ot the GIET-VM kernel.
    8 // This driver supports the SocLib VciMultiAhci component, that is a multi-channels,
    9 // block oriented, external storage contrÃŽler, respecting the AHCI standard.
    10 //
    11 // The SEG_IOC_BASE virtual address must be defined in the hard_config.h file.
    12 //////////////////////////////////////////////////////////////////////////////////
    137// Implementation notes:
    14 //
    158// 1. In order to share code, the two _hba_read() and _hba_write() functions
    169//    call the same _hba_set_cmd() function.
    17 //
    1810// 2. All accesses to HBA registers are done by the two
    1911//    _hba_set_register() and _hba_get_register() low-level functions,
     
    4234
    4335//////////////////////////////////////////////////////////////////
    44 //  Global variables
     36//               Global variables
    4537//////////////////////////////////////////////////////////////////
    4638
     
    8981// buffer must be an integer number of blocks entirely contained in a single
    9082// page frame.
    91 // return 0 if success, > 0 if error
     83// return 0 if success, -1 if error
    9284///////////////////////////////////////////////////////////////////////////////
    9385unsigned int _hba_cmd_set( unsigned int  channel,     // channel index
     
    109101    if( buffer & (block_size-1) )
    110102    {
    111         _printf("\n[GIET ERROR] in _hba_set_cmd() : user buffer not block aligned\n");
    112         return 1;
     103        _puts("\n[GIET ERROR] in _hba_set_cmd() : user buffer not block aligned\n");
     104        return -1;
    113105    }
    114106
     
    120112    if( pxci & (1<<cmd_id ) )
    121113    {
    122         _printf("\n[GIET ERROR] in _hba_set_cmd() : command list full for channel %d\n",
    123                 channel );
    124         return 1;
     114        _puts("\n[GIET ERROR] in _hba_set_cmd() : command list full for channel ");
     115        _putd( channel );
     116        _puts("\n");
     117        return -1;
    125118    }
    126119
     
    188181        if ( ko )
    189182        {
    190             _printf("[GIET ERROR] in _hba_set_cmd() : user buffer unmapped\n");
    191             return 1;
     183            _puts("[GIET ERROR] in _hba_set_cmd() : user buffer unmapped\n");
     184            return -1;
    192185        }
    193186        if ((flags & PTE_U) == 0)
    194187        {
    195             _printf("[GIET ERROR] in _hba_set_cmd() : user buffer not in user space\n");
    196             return 1;
     188            _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not in user space\n");
     189            return -1;
    197190        }
    198191        if (((flags & PTE_W) == 0 ) && (is_read == 0) )
    199192        {
    200             _printf("[GIET ERROR] in _hba_set_cmd() : user buffer not writable\n");
    201             return 1;
     193            _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not writable\n");
     194            return -1;
    202195        }
    203196
     
    205198        if( buf_id > 245 )
    206199        {
    207             _printf("[GIET ERROR] in _hba_set_cmd() : max number of buffers is 248\n");
    208             return 1;
     200            _puts("[GIET ERROR] in _hba_set_cmd() : max number of buffers is 248\n");
     201            return -1;   
    209202        }
    210203
     
    218211            cmd_table->entry[buf_id].dbc  = count;
    219212
    220 #if GIET_DEBUG_HBA_DRIVER
    221 _printf("\n- buf_index = ");
    222 _putd( buf_id );
    223 _printf(" / paddr = ");
    224 _putl( paddr );
    225 _printf(" / count = ");
    226 _putd( count );
    227 _printf("\n");
    228 #endif
    229213            buf_id++;
    230214        }
     
    237221            cmd_table->entry[buf_id].dbc  = count;
    238222
    239 #if GIET_DEBUG_HBA_DRIVER
    240 _printf("\n- buf_index = ");
    241 _putd( buf_id );
    242 _printf(" / paddr = ");
    243 _putl( paddr );
    244 _printf(" / count = ");
    245 _putd( count );
    246 _printf("\n");
    247 #endif
    248223            buf_id++;
    249224        }
     
    257232            cmd_table->entry[buf_id].dbc  = count;
    258233
    259 #if GIET_DEBUG_HBA_DRIVER
    260 _printf("\n- buf_index = ");
    261 _putd( buf_id );
    262 _printf(" / paddr = ");
    263 _putl( paddr );
    264 _printf(" / count = ");
    265 _putd( count );
    266 _printf("\n");
    267 #endif
    268234            buf_id++;
    269235
     
    274240            cmd_table->entry[buf_id].dbc  = count;
    275241
    276 #if GIET_DEBUG_HBA_DRIVER
    277 _printf("\n- buf_index = ");
    278 _putd( buf_id );
    279 _printf(" / paddr = ");
    280 _putl( paddr );
    281 _printf(" / count = ");
    282 _putd( count );
    283 _printf("\n");
    284 #endif
    285242            buf_id++;
    286243        }
     
    293250            cmd_table->entry[buf_id].dbc  = count;
    294251
    295 #if GIET_DEBUG_HBA_DRIVER
    296 _printf("\n- buf_index = ");
    297 _putd( buf_id );
    298 _printf(" / paddr = ");
    299 _putl( paddr );
    300 _printf(" / count = ");
    301 _putd( count );
    302 _printf("\n");
    303 #endif
    304252            buf_id++;
    305253        }
     
    308256
    309257
    310 ///////////////////////////////////////////////////////////////////
    311 // Register a write command in Command List and Command Table
    312 // for a single physical buffer.
    313 // Returns 0 if success, > 0 if error.
    314 ///////////////////////////////////////////////////////////////////
    315 unsigned int _hba_write( unsigned int  channel,
    316                          unsigned int  mode,
    317                          unsigned int  lba,
    318                          paddr_t       buffer,
    319                          unsigned int  count )
    320 {
    321     return _hba_cmd_set( channel,
    322                          0,         // write
    323                          lba,
    324                          buffer,
    325                          count );
    326 }
    327 
    328 ///////////////////////////////////////////////////////////////////
    329 // Register a read command in Command List and Command Table
    330 // for a single physical buffer.
    331 // Returns 0 if success, > 0 if error.
    332 ///////////////////////////////////////////////////////////////////
    333 unsigned int _hba_read( unsigned int  channel,
    334                         unsigned int  mode,
    335                         unsigned int  lba,
    336                         paddr_t       buffer,
    337                         unsigned int  count )
    338 {
    339     return _hba_cmd_set( channel,
    340                          1,          // read
    341                          lba,
    342                          buffer,
    343                          count );
    344 }
    345 
    346 //////////////////////////////////////////////////////////////////
    347 // This function initializes for a given channel
    348 // - the HBA hardware registers,
    349 // - the command list pointer,
    350 // - the command lists physical addresse,
    351 // - the command tables physical addresses array,
    352 //////////////////////////////////////////////////////////////////
     258//////////////////////////////////////////////
    353259unsigned int _hba_init( unsigned int channel )
    354260{
     
    381287    if ( fail )
    382288    {
    383         _printf("[GIET ERROR] in _hba_init() : command list unmapped\n");
    384         return 1;
     289        _puts("[GIET ERROR] in _hba_init() : command list unmapped\n");
     290        return -1;
    385291    }
    386292    hba_cmd_list_paddr[channel] = ((paddr_t)ppn) | (vbase & 0xFFF);
     
    396302        if ( fail )
    397303        {
    398             _printf("[GIET ERROR] in _hba_init() : command table unmapped\n");
    399             return 1;
     304            _puts("[GIET ERROR] in _hba_init() : command table unmapped\n");
     305            return -1;
    400306        }
    401307        hba_cmd_table_paddr[channel][c] = ((paddr_t)ppn) | (vbase & 0xFFF);
     
    405311}
    406312
    407 ///////////////////////////////////////////////////////////////////////////////
    408 //     _hba_get_block_size()
    409 // This function returns the block_size of HBA controller
    410 ///////////////////////////////////////////////////////////////////////////////
     313///////////////////////////////////////////////
     314unsigned int _hba_write( unsigned int  channel,
     315                         unsigned int  mode,
     316                         unsigned int  lba,
     317                         paddr_t       buffer,
     318                         unsigned int  count )
     319{
     320    return _hba_cmd_set( channel,
     321                         0,         // write
     322                         lba,
     323                         buffer,
     324                         count );
     325}
     326
     327//////////////////////////////////////////////
     328unsigned int _hba_read( unsigned int  channel,
     329                        unsigned int  mode,
     330                        unsigned int  lba,
     331                        paddr_t       buffer,
     332                        unsigned int  count )
     333{
     334    return _hba_cmd_set( channel,
     335                         1,          // read
     336                         lba,
     337                         buffer,
     338                         count );
     339}
     340
     341//////////////////////////////////
    411342unsigned int _hba_get_block_size()
    412343{
     
    415346}
    416347
    417 /////////////////////////////////////////////////////////////////////////////////////
    418 // This function returns the content of the HBA_PXIS register for a given channel,
    419 // and reset this register to acknoledge IRQ.
    420 // return 0 if success, > 0 if error
    421 /////////////////////////////////////////////////////////////////////////////////////
     348////////////////////////////////////////////////////
    422349unsigned int _hba_get_status( unsigned int channel )
    423350{
     
    425352    if( channel >= NB_IOC_CHANNELS )
    426353    {
    427         _printf("\n[GIET ERROR] in _hba_get_status() : illegal channel\n");
     354        _puts("\n[GIET ERROR] in _hba_get_status() : illegal channel\n");
    428355        _exit();
    429356    }
  • soft/giet_vm/giet_drivers/hba_driver.h

    r295 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7// The hba_driver.c and hba_driver.h files are part ot the GIET-VM kernel.
     8// This driver supports the SocLib VciMultiAhci component, that is a multi-channels,
     9// block oriented, external storage contrÃŽler, respecting the AHCI standard.
     10//
     11// The SEG_IOC_BASE virtual address must be defined in the hard_config.h file.
     12//////////////////////////////////////////////////////////////////////////////////
    713
    814#ifndef _GIET_HBA_DRIVERS_H_
     
    94100
    95101///////////////////////////////////////////////////////////////////////////////////
    96 // HBA device access functions  (vci_hba)
     102//              access functions 
    97103///////////////////////////////////////////////////////////////////////////////////
    98104
     105///////////////////////////////////////////////////////////////////////////////////
     106// This function initializes for a given channel
     107// - the HBA hardware registers,
     108// - the command list pointer,
     109// - the command lists physical addresse,
     110// - the command tables physical addresses array,
     111///////////////////////////////////////////////////////////////////////////////////
    99112extern unsigned int _hba_init ( unsigned int channel );
    100113
     114///////////////////////////////////////////////////////////////////////////////////
     115// This function register a write command in Command List and Command Table
     116// for a single physical buffer, and updates the HBA_PXCI register.
     117// Returns 0 if success, > 0 if error.
     118///////////////////////////////////////////////////////////////////////////////////
    101119extern unsigned int _hba_write( unsigned int channel,     // channel index
    102120                                unsigned int mode,        // BOOT / KERNEL / USER
     
    105123                                unsigned int count );     // number of blocs
    106124
     125//////////////////////////////////////////////////////////////////////////////////
     126// This function register a read command in Command List and Command Table
     127// for a single physical buffer, and updates the HBA_PXCI register.
     128// Returns 0 if success, > 0 if error.
     129//////////////////////////////////////////////////////////////////////////////////
    107130extern unsigned int _hba_read ( unsigned int channel,     // channel index
    108131                                unsigned int mode,        // BOOT / KERNEL / USER
     
    111134                                unsigned int count );     // number of blocks
    112135
     136/////////////////////////////////////////////////////////////////////////////////
     137// This function returns the block_size of HBA controller
     138/////////////////////////////////////////////////////////////////////////////////
     139extern unsigned int _hba_get_block_size ();
     140
     141/////////////////////////////////////////////////////////////////////////////////////
     142// This function returns the content of the HBA_PXIS register for a given channel,
     143// and reset this register to acknoledge IRQ.
     144// return 0 if success, > 0 if error
     145/////////////////////////////////////////////////////////////////////////////////////
    113146extern unsigned int _hba_get_status( unsigned int   channel );
    114 
    115 extern unsigned int _hba_get_block_size ();
    116147
    117148
  • soft/giet_vm/giet_drivers/iob_driver.c

    r340 r437  
    44// Author   : alain greiner
    55// Copyright (c) UPMC-LIP6
    6 ///////////////////////////////////////////////////////////////////////////////////
    7 // The iob_driver.c and iob_driver.h files are part ot the GIET-VM kernel.
    8 // This driver supports the TSAR vci_io_bridge, that is a bridge to access
    9 // The external peripherals, implementing an IO_MMU.
    10 // This component can be instanciated in more than one cluster.
    11 ///////////////////////////////////////////////////////////////////////////////////
    12 // The SEG_IOB_BASE virtual addresses must be defined in hard_config.h file.
    13 // The physical base address is supposed to be (cluster_xy << 32) | SEG_IOB_BASE.
    146///////////////////////////////////////////////////////////////////////////////////
    157
     
    6153
    6254
    63 ///////////////////////////////////////////////////////////////////////////////
    64 // This function invalidates a TLB entry identified by a virtual address.
    65 ///////////////////////////////////////////////////////////////////////////////
     55
     56///////////////////////////////////////////////////
    6657void _iob_inval_tlb_entry( unsigned int cluster_xy,
    6758                           unsigned int vaddr )
     
    7263}
    7364
    74 ///////////////////////////////////////////////////////////////////////////////
    75 // This function sets a new value in IOB_IOMMU_PTPR register.
    76 ///////////////////////////////////////////////////////////////////////////////
     65//////////////////////////////////////////////////
    7766void _iob_set_iommu_ptpr( unsigned int cluster_xy,
    7867                          unsigned int value )
  • soft/giet_vm/giet_drivers/iob_driver.h

    r340 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7// The iob_driver.c and iob_driver.h files are part ot the GIET-VM kernel.
     8// This driver supports the TSAR vci_io_bridge, that is a bridge to access
     9// The external peripherals, implementing an IO_MMU.
     10// The SEG_IOB_BASE virtual addresses must be defined in hard_config.h file.
     11// The physical base address is (cluster_io << 32) | SEG_IOB_BASE.
     12///////////////////////////////////////////////////////////////////////////////////
    713
    814#ifndef _GIET_IOB_DRIVER_H_
     
    1016
    1117///////////////////////////////////////////////////////////////////////////////////
    12 // vci_io_bridge : registers offsets and iommu error codes
     18//               registers offsets and iommu error codes
    1319///////////////////////////////////////////////////////////////////////////////////
    1420
     
    4046
    4147///////////////////////////////////////////////////////////////////////////////////
    42 // TSAR IOB access functions
     48//                       access functions
    4349///////////////////////////////////////////////////////////////////////////////////
    4450
     51///////////////////////////////////////////////////////////////////////////////
     52// This function invalidates a TLB entry identified by a virtual address.
     53///////////////////////////////////////////////////////////////////////////////
    4554extern void _iob_inval_tlb_entry( unsigned int cluster_xy,
    4655                                  unsigned int vaddr );
    4756
     57///////////////////////////////////////////////////////////////////////////////
     58// This function sets a new value in IOB_IOMMU_PTPR register.
     59///////////////////////////////////////////////////////////////////////////////
    4860extern void _iob_set_iommu_ptpr(  unsigned int cluster_xy,
    4961                                  unsigned int value );
    5062
    51 ///////////////////////////////////////////////////////////////////////////////////
     63
    5264
    5365#endif
  • soft/giet_vm/giet_drivers/ioc_driver.c

    r426 r437  
    66// Copyright (c) UPMC-LIP6
    77///////////////////////////////////////////////////////////////////////////////////
    8 // Implementation note:
    9 //
     8// Implementation notes:
    109// 1) In order to share the code, the two _ioc_read() and _ioc_write() functions
    11 // call the same _ioc_access() function.
    12 //
     10// call the same _ioc_access() function, and this function call the selected
     11// physical driver (BDV / HBA / SPI / RDK).
    1312// 2) The IOMMU is not supported yet, but the method is the following:
    1413// A fixed size 2 Mbytes vseg is allocated to the IOC peripheral, in the I/O
     
    9796unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
    9897unsigned int p       = procid & ((1<<P_WIDTH)-1);
    99 _printf("\n[IOC DEBUG] _ioc_access() : P[%d,%d,%d] enters at cycle %d\n"
    100         " - channel  = %d\n"
    101         " - mode     = %d\n"
    102         " - vaddr    = %x\n"
    103         " - sectors  = %d\n"
    104         " - lba      = %x\n",
    105         x, y, p, _get_proctime(), channel, mode, buf_vaddr, count, lba );
     98_puts("\n[IOC DEBUG] _ioc_access() : P[");
     99_putd( x );
     100_puts(",");
     101_putd( y );
     102_puts(",");
     103_putd( p );
     104_puts("] enters at cycle ");
     105_putd( _get_proctime() );
     106_puts("\n - channel  = ");
     107_putd( channel );
     108_puts("\n - mode     = ");
     109_putd( mode );
     110_puts("\n - vaddr    = ");
     111_putx( buf_vaddr );
     112_puts("\n - sectors  = ");
     113_putd( count );
     114_puts("\n - lba      = ");
     115_putx( lba );
     116_puts("\n");
    106117#endif
    107118
     
    115126    if ((unsigned int) buf_vaddr & 0x3)
    116127    {
    117         _printf("\n[IOC ERROR] in _ioc_access() : buffer not word aligned\n");
     128        _puts("\n[IOC ERROR] in _ioc_access() : buffer not word aligned\n");
    118129        _exit();
    119130    }
     
    122133    if ( (USE_IOC_HBA == 0) && (channel > 0) )
    123134    {
    124         _printf("\n[IOC ERROR] in _ioc_access() : channel must be 0 when HBA not used\n");
     135        _puts("\n[IOC ERROR] in _ioc_access() : channel must be 0 when HBA not used\n");
    125136        _exit();
    126137    }
     
    146157        if ( ko )
    147158        {
    148             _printf("\n[IOC ERROR] in _ioc_access() : buffer unmapped\n");
     159            _puts("\n[IOC ERROR] in _ioc_access() : buffer unmapped\n");
    149160            _exit();
    150161        }
     
    152163        if ( (mode == IOC_USER_MODE) && ((flags & PTE_U) == 0) )
    153164        {
    154             _printf("\n[IOC ERROR] in _ioc_access() : buffer not user accessible\n");
     165            _puts("\n[IOC ERROR] in _ioc_access() : buffer not user accessible\n");
    155166            _exit();
    156167        }
     
    158169        if ( ((flags & PTE_W) == 0 ) && to_mem )
    159170        {
    160             _printf("\n[IOC ERROR] in _ioc_access() : buffer not writable\n");
     171            _puts("\n[IOC ERROR] in _ioc_access() : buffer not writable\n");
    161172            _exit();
    162173        }
     
    274285#elif ( USE_IOC_RDK )
    275286
    276     _printf("[GIET ERROR] _ioc_get_status() should not be called");
    277     _printf(" when RAMDISK  is used...\n");
    278     _exit();
    279 
    280     return 0;
     287    return rdk_get_status();
    281288
    282289#endif
  • soft/giet_vm/giet_drivers/ioc_driver.h

    r413 r437  
    1818// USE_IOC_BDV, USE_IOC_SDC, USE_IOC_HBA, USE_IOC_RDK.
    1919//
    20 // Any physical block device driver xxx must provide the following API:
    21 // - _xxx_init()
    22 // - _xxx_read()
    23 // - _xxx_write()
    24 // - _xxx_get_status()
    25 // - _xxx_get_block_size()
    26 // The "channel" parameter is no transmited to single channel devices.
     20// Any physical block device driver must provide the 5 five functions defined
     21// by this generic driver.
    2722//
    2823// The _ioc_read() and _ioc_write() functions are always blocking for
     
    6762// If the RAMDISK is used, an extra memory segment with virtual base address
    6863// SEG_RDK_BASE, used by RDK driver, must be defined in hard_config.h.
    69 ///////////////////////////////////////////////////////////////////////////////////
    70 // Implementation note:
    7164//
    72 // 1) In order to share the code, the two _ioc_read() and _ioc_write() functions
    73 // call the same _ioc_access() function.
    74 //
    75 // 2) The IOMMU is not supported yet, but the method is the following:
     65// The IOMMU is not supported yet, but the method is the following:
    7666// A fixed size 2 Mbytes vseg is allocated to the IOC peripheral, in the I/O
    7767// virtual space, and the user buffer is dynamically remapped to one single
     
    10393
    10494///////////////////////////////////////////////////////////////////////////////////
    105 // IOC access functions  (generic disk controller)
     95//      External functions                           
    10696///////////////////////////////////////////////////////////////////////////////////
    10797
    10898///////////////////////////////////////////////////////////////////////////////
    109 // This function cheks block size, and desactivates the IOC interrupts.
     99// This function cheks block size, and desactivates interrupts.
    110100// Return 0 for success, non zero if error.
    111101///////////////////////////////////////////////////////////////////////////////
     
    113103
    114104///////////////////////////////////////////////////////////////////////////////
    115 // Transfer data from a memory buffer to the block device.
    116 // - mode     : BOOT_PA / BOOT_VA / KERNEL / USER
     105// Transfer data from a memory buffer to the disk.
     106// - mode     : BOOT / KERNEL / USER
    117107// - lba      : first block index on the block device
    118108// - buffer   : base address of the memory buffer (must be word aligned)
     
    127117
    128118///////////////////////////////////////////////////////////////////////////////
    129 // Transfer data from the block device to a memory buffer.
    130 // - mode     : BOOT_PA / BOOT_VA / KERNEL / USER
     119// Transfer data from the disk to a memory buffer.
     120// - mode     : BOOT / KERNEL / USER
    131121// - lba      : first block index on the block device
    132122// - buffer   : base address of the memory buffer (must be word aligned)
     
    142132///////////////////////////////////////////////////////////////////////////////
    143133// This function returns in the status variable, the transfert status, and
    144 // acknowledge the IRQ if the IOC controler is not busy.
     134// acknowledge the IRQ if required.
    145135// Returns 0 if success, > 0 if error
    146136///////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/giet_drivers/mmc_driver.c

    r426 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The mmc_driver.c and mmc_driver.h files are part ot the GIET-VM nano-kernel.
    8 // This driver supports the vci_mem_cache component used in the TSAR architecture.
    9 //
    10 // This component is replicated in all clusters, and can be accessed through
    11 // a configuration interface as a set of uncached, memory mapped registers.
    12 //
    13 // The (virtual) base address of the associated segment is:
    14 //       SEG_MMC_BASE + cluster_id * PERI_CLUSTER_INCREMENT
    15 //
    16 // SEG_MMC_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h.
    17 ////////////////////////////////////////////////////////////////////////////////
    187
    198#include <giet_config.h>
     
    8271}
    8372
    84 ///////////////////////////////////////////////////////////////////////////////////
    85 // This function invalidates all cache lines covering a memory buffer defined
    86 // by the physical base address, and the length.
    87 // The buffer address MSB are used to compute the cluster index.
    88 ///////////////////////////////////////////////////////////////////////////////////
     73/////////////////////////////////////////
    8974void _mmc_inval( paddr_t      buf_paddr,
    9075                 unsigned int buf_length )
     
    9883    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
    9984    {
    100         _printf("\n[GIET ERROR] in _memc_inval() : illegal cluster_xy for paddr %l\n",
    101                  buf_paddr );
     85        _puts("\n[GIET ERROR] in _memc_inval() : illegal cluster coordinates\n");
    10286        _exit();
    10387    }
     
    11599    _mmc_set_register(cluster_xy, 0, MEMC_LOCK, 0);
    116100}
    117 ///////////////////////////////////////////////////////////////////////////////////
    118 // This function copies to external RAM all cache lines covering a memory buffer
    119 // defined by the physical base address, and the length, if they are dirty.
    120 // The buffer address MSB are used to compute the cluster index.
    121 ///////////////////////////////////////////////////////////////////////////////////
     101
     102///////////////////////////////////////
    122103void _mmc_sync( paddr_t      buf_paddr,
    123104                unsigned int buf_length )
     
    131112    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
    132113    {
    133         _printf( "\n[GIET ERROR] in _memc_sync() : illegal cluster_xy for paddr %l\n",
    134                  buf_paddr );
     114        _puts( "\n[GIET ERROR] in _memc_sync() : illegal cluster coordinates");
    135115        _exit();
    136116    }
     
    149129}
    150130
    151 //////////////////////////////////////////////////////////////////////////////////
    152 // This ISR access the vci_mem_cache component to get the faulty physical
    153 // address and the associated SRCID. It must also acknowledge the IRQ.
    154 //
    155 // TODO implement...
    156 //////////////////////////////////////////////////////////////////////////////////
     131///////////////////////////////////////////////////////
    157132void _mmc_isr( unsigned int irq_type,  // should be HWI
    158133               unsigned int irq_id,    // index returned by ICU
     
    163138    unsigned int x          = cluster_xy >> Y_WIDTH;
    164139    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    165     unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
     140    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
    166141
    167     _printf("[GIET ERROR] MMC IRQ received by processor[%d,%d,%d]"
    168             " but _mmc_isr() not implemented...\n", x, y, lpid );
     142    _puts("[GIET ERROR] MMC IRQ received by processor[");
     143    _putd( x );
     144    _puts(",");
     145    _putd( y );
     146    _puts(",");
     147    _putd( p );
     148    _puts("] but _mmc_isr() not implemented\n");
    169149}
    170150
  • soft/giet_vm/giet_drivers/mwr_driver.c

    r333 r437  
    6363                           paddr_t                channel_pbase )
    6464{
    65     _printf(" [GIET_ERROR] _mwr_hw_init() function not supported yet\n");
     65    _puts(" [GIET_ERROR] _mwr_hw_init() function not supported yet\n");
    6666    _exit();
    6767
  • soft/giet_vm/giet_drivers/nic_driver.c

    r333 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The nic_driver.c and nic_driver.h files are part ot the GIET-VM nano-kernel.
    8 // This driver supports the vci_multi_nic component.
    9 //
    10 // It can exist only one network controller in the architecture, but this
    11 // component supports several channels.
    12 //
    13 // It can be accessed directly by software with memcpy(),
    14 // or it can be accessed through the vci_chbuf_dma component:
    15 // 
    16 // The '_nic_sync_write' and '_nic_sync_read' functions use a memcpy strategy to
    17 // implement the transfer between a data buffer (user space) and the NIC
    18 // buffer (kernel space). They are blocking until completion of the transfer.
    19 //
    20 // The _nic_cma_*_init() and _nic_cma_stop() functions use the VciChbufDma component
    21 // to transfer a flow of packets from the NIC RX hard chbuf (two containers)
    22 // to an user RX chbuf (two containers), and to transfer another flow of packets
    23 // from an user TX chbuf (two containers) to the NIC TX chbuf (two containers).
    24 // One NIC channel and two CMA channels must be allocated to the task
    25 // in the mapping_info data structure.
    26 //
    27 // The SEG_NIC_BASE address must be defined in the hard_config.h file.
    28 //////////////////////////////////////////////////////////////////////////////////
    297
    308#include <giet_config.h>
    319#include <nic_driver.h>
     10#include <cma_driver.h>
    3211#include <utils.h>
     12#include <ctx_handler.h>
     13#include <vmem.h>
    3314
    3415#if !defined(GIET_USE_IOMMU)
     
    4425#endif
    4526
     27#if !defined(X_IO)
     28# error: You must define X_IO in the hard_config.h file
     29#endif
     30
     31#if !defined(Y_IO)
     32# error: You must define Y_IO in the hard_config.h file
     33#endif
     34
    4635#if ( NB_NIC_CHANNELS > 8 )
    4736# error: NB_NIC_CHANNELS cannot be larger than 8
     
    6049#endif
    6150
     51#if !defined( GIET_CHBUF_NBUFS )
     52# error: You must define GIET_CHBUF_NBUFS in the giet_config.h file
     53#endif
     54
    6255#define in_unckdata __attribute__((section (".unckdata")))
    6356
    6457///////////////////////////////////////////////////////////////////////////////
    65 // This low_level function returns the value contained in register (index).
    66 ///////////////////////////////////////////////////////////////////////////////
    67 unsigned int _nic_get_register( unsigned int channel,
    68                                 unsigned int index )
     58// This low_level function returns the value contained in a channel register.
     59///////////////////////////////////////////////////////////////////////////////
     60unsigned int _nic_get_channel_register( unsigned int channel,
     61                                        unsigned int index )
    6962{
    7063    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE +
     
    7467
    7568///////////////////////////////////////////////////////////////////////////////
    76 // This low-level function set a new value in register (index).
    77 ///////////////////////////////////////////////////////////////////////////////
    78 void _nic_set_register( unsigned int channel,
    79                         unsigned int index,
    80                         unsigned int value )
     69// This low-level function set a new value in a channel register.
     70///////////////////////////////////////////////////////////////////////////////
     71void _nic_set_channel_register( unsigned int channel,
     72                                unsigned int index,
     73                                unsigned int value )
    8174{
    8275    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE +
     
    8578}
    8679
    87 //////////////////////////////////////////////////////////////////////////////////
    88 // Transfer data from an memory buffer to the NIC device using a memcpy.
    89 // - buffer : base address of the memory buffer.
    90 // - length : number of bytes to be transfered.
    91 //////////////////////////////////////////////////////////////////////////////////
    92 unsigned int _nic_sync_write( const void*    buffer,
    93                               unsigned int   length )
    94 {
    95     _printf("[GIET ERROR] _nic_sync_write function not implemented / cycle %d\n",
    96             _get_proctime() );
    97     _exit();
    98 
    99     return 0;
    100 }
    101 //////////////////////////////////////////////////////////////////////////////////
    102 // Transfer data from the NIC device to a memory buffer using a memcpy.
    103 // - buffer : base address of the memory buffer.
    104 // - length : number of bytes to be transfered.
    105 //////////////////////////////////////////////////////////////////////////////////
    106 unsigned int _nic_sync_read( const void*    buffer,
    107                              unsigned int   length )
    108 {
    109     _printf("[GIET ERROR] _nic_sync_read function not implemented / cycle %d\n",
    110             _get_proctime() );
    111     _exit();
    112 
    113     return 0;
    114 }
    115 //////////////////////////////////////////////////////////////////////////////////
    116 // Returns 0 if success, > 0 if error.
    117 //////////////////////////////////////////////////////////////////////////////////
    118 unsigned int _nic_cma_start( )
    119 {
    120     _printf("[GIET ERROR] _nic_cma_start() not implemented / cycle %d\n",
    121             _get_proctime() );
    122     _exit();
    123 
    124     return 0;
    125 }
    126 //////////////////////////////////////////////////////////////////////////////////
    127 // Returns 0 if success, > 0 if error.
    128 //////////////////////////////////////////////////////////////////////////////////
    129 unsigned int _nic_cma_stop()
    130 {
    131     _printf("[GIET ERROR] _nic_cma_stop() not implemented / cycle %d\n",
    132             _get_proctime() );
    133     _exit();
    134 
    135     return 0;
    136 }
    137 
    138 //////////////////////////////////////////////////////////////////////////////////
    139 // This ISR handles IRQx from a NIC RX channeL
    140 //////////////////////////////////////////////////////////////////////////////////
     80///////////////////////////////////////////////////////////////////////////////
     81// This low_level function returns the value contained in a global register.
     82///////////////////////////////////////////////////////////////////////////////
     83unsigned int _nic_get_global_register( unsigned int index )
     84{
     85    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE +
     86                           NIC_CHANNEL_SPAN * NB_NIC_CHANNELS + index;
     87    return _io_extended_read( vaddr );
     88}
     89
     90///////////////////////////////////////////////////////////////////////////////
     91// This low-level function set a new value in a global register.
     92///////////////////////////////////////////////////////////////////////////////
     93void _nic_set_global_register( unsigned int index,
     94                               unsigned int value )
     95{
     96    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE +
     97                           NIC_CHANNEL_SPAN * NB_NIC_CHANNELS + index;
     98    _io_extended_write( vaddr, value );
     99}
     100
     101////////////////////////////////////////////
     102int _nic_global_init( unsigned int channels,
     103                      unsigned int vis,
     104                      unsigned int bc_enable,
     105                      unsigned int bypass_enable )
     106{
     107    _nic_set_global_register( NIC_G_VIS          , vis );
     108    _nic_set_global_register( NIC_G_NB_CHAN      , channels );
     109    _nic_set_global_register( NIC_G_BC_ENABLE    , bc_enable );
     110    _nic_set_global_register( NIC_G_BYPASS_ENABLE, bypass_enable );
     111    _nic_set_global_register( NIC_G_ON           , 1 );
     112
     113    return 0;
     114}
     115
     116////////////////////////////////////////////
     117int _nic_channel_init( unsigned int index,
     118                       unsigned int mac4,
     119                       unsigned int mac2 )
     120{
     121    unsigned int base     = SEG_NIC_BASE;
     122    unsigned int extend   = (X_IO << Y_WIDTH) + Y_IO;
     123
     124    _nic_set_channel_register( index, NIC_RX_DESC_LO_0 + 4096, base );
     125    _nic_set_channel_register( index, NIC_RX_DESC_LO_1 + 4096, base + 0x1000 );
     126    _nic_set_channel_register( index, NIC_TX_DESC_LO_0 + 4096, base + 0x2000 );
     127    _nic_set_channel_register( index, NIC_TX_DESC_LO_1 + 4096, base + 0x3000 );
     128
     129    _nic_set_channel_register( index, NIC_RX_DESC_HI_0       , extend );
     130    _nic_set_channel_register( index, NIC_RX_DESC_HI_1       , extend );
     131    _nic_set_channel_register( index, NIC_TX_DESC_HI_0       , extend );
     132    _nic_set_channel_register( index, NIC_TX_DESC_HI_1       , extend );
     133
     134    _nic_set_channel_register( index, NIC_MAC_4              , mac4 );
     135    _nic_set_channel_register( index, NIC_MAC_2              , mac2 );
     136   
     137    _nic_set_channel_register( index, NIC_RX_RUN             , 1 );
     138    _nic_set_channel_register( index, NIC_TX_RUN             , 1 );
     139
     140    return 0;
     141}
     142
     143/////////////////////////////////////////////////////////////////////////////////////
     144//             Synchronous access functions
     145/////////////////////////////////////////////////////////////////////////////////////
     146
     147///////////////////////////////////////////////
     148int _nic_sync_send( unsigned int        channel,
     149                    unsigned long long  user_paddr )
     150{
     151    unsigned long long nic_paddr;   // nic buffer physical address
     152    unsigned int       done = 0;
     153    unsigned int       lsb;
     154    unsigned int       msb;
     155
     156    if ( channel >= NB_NIC_CHANNELS )
     157    {
     158        _puts("[GIET ERROR] in _timer_sync_send()\n");
     159        return -1;
     160    }
     161
     162    // poll the NIC buffers
     163    while ( done == 0 )
     164    {
     165        // test availability of NIC TX buffer 0
     166        lsb  = _nic_get_channel_register( channel, NIC_TX_DESC_LO_0 );
     167        msb  = _nic_get_channel_register( channel, NIC_TX_DESC_HI_0 );
     168        if ( (msb & 0x80000000) == 0 )
     169        {
     170            msb  = msb & 0x0000FFFF;
     171            done = 1;
     172            continue;
     173        }
     174
     175        // test availability of NIC TX buffer 1
     176        lsb  = _nic_get_channel_register( channel, NIC_TX_DESC_LO_1 );
     177        msb  = _nic_get_channel_register( channel, NIC_TX_DESC_HI_1 );
     178        if ( (msb & 0x80000000) == 0 )
     179        {
     180            msb  = msb & 0x0000FFFF;
     181            done = 1;
     182            continue;
     183        }
     184
     185        // random delay (average value: 380 cycle)
     186        _random_wait( 8 );
     187    }
     188
     189    // make the transfer
     190    nic_paddr = (unsigned long long)lsb + (((unsigned long long)msb) << 32);
     191
     192    _physical_memcpy( nic_paddr , user_paddr, 4096 );
     193
     194    return 0;
     195}
     196
     197///////////////////////////////////////////////////
     198int _nic_sync_receive( unsigned int        channel,
     199                       unsigned long long  user_paddr )
     200{
     201    unsigned long long nic_paddr;   // nic  buffer physical address
     202    unsigned int       done = 0;
     203    unsigned int       lsb;
     204    unsigned int       msb;
     205
     206    if ( channel >= NB_NIC_CHANNELS )
     207    {
     208        _puts("[GIET ERROR] in _timer_sync_receive()\n");
     209        return -1;
     210    }
     211
     212    // polling the NIC buffers
     213    while ( done == 0 )
     214    {
     215        // test availability of NIC RX buffer 0
     216        lsb  = _nic_get_channel_register( channel, NIC_RX_DESC_LO_0 );
     217        msb  = _nic_get_channel_register( channel, NIC_RX_DESC_HI_0 );
     218        if ( (msb & 0x80000000) == 1 )
     219        {
     220            msb  = msb & 0x0000FFFF;
     221            done = 1;
     222            continue;
     223        }
     224
     225        // test availability of NIC RX buffer 1
     226        lsb  = _nic_get_channel_register( channel, NIC_RX_DESC_LO_1 );
     227        msb  = _nic_get_channel_register( channel, NIC_RX_DESC_HI_1 );
     228        if ( (msb & 0x80000000) == 1 )
     229        {
     230            msb  = msb & 0x0000FFFF;
     231            done = 1;
     232            continue;
     233        }
     234
     235        // random delay (average value: 380 cycle)
     236        _random_wait( 8 );
     237    }
     238
     239    // make the transfer
     240    nic_paddr = (unsigned long long)lsb + (((unsigned long long)msb) << 32);
     241
     242    _physical_memcpy( user_paddr, nic_paddr , 4096 );
     243
     244    return 0;
     245}
     246
     247/////////////////////////////////////////////////////////////////////////////////////
     248//             CMA access functions
     249/////////////////////////////////////////////////////////////////////////////////////
     250
     251//////////////////////////////////////////////////////////////
     252int _nic_cma_receive( unsigned int  nic_channel,
     253                      unsigned int  cma_channel,
     254                      nic_chbuf_t*  kernel_chbuf )
     255                             
     256{
     257    unsigned int nic_chbuf_lsb;     // 32 LSB bits of the NIC chbuf physical address
     258    unsigned int nic_chbuf_msb;     // 16 MSB bits of the NIC chbuf physical address
     259    unsigned int mem_chbuf_lsb;     // 32 LSB bits of the kernel chbuf physical address
     260    unsigned int mem_chbuf_msb;     // 16 MSB bits of the kernel chbuf physical address
     261
     262    unsigned int ppn;
     263    unsigned int flags;
     264
     265    // checking parameters
     266    if ( nic_channel >= NB_NIC_CHANNELS )
     267    {
     268        _puts("[GIET ERROR] in _nic_cma_start_receive() : nic_channel index too large\n");
     269        return -1;
     270    }
     271    if ( cma_channel >= NB_CMA_CHANNELS )
     272    {
     273        _puts("[GIET ERROR] in _nic_cma_start_receive() : cma_channel index too large\n");
     274        return -1;
     275    }
     276
     277    // get the NIC_RX chbuf descriptor physical address
     278    nic_chbuf_lsb = SEG_NIC_BASE + (nic_channel * NIC_CHANNEL_SPAN) + 0x1000;
     279    nic_chbuf_msb = (X_IO << Y_WIDTH) + Y_IO;
     280
     281    // compute the kernel chbuf physical address
     282    unsigned int ptab  = _get_context_slot(CTX_PTAB_ID);
     283    unsigned int vaddr = (unsigned int)kernel_chbuf;
     284    unsigned int ko    = _v2p_translate( (page_table_t*)ptab,
     285                                          vaddr,
     286                                          &ppn,
     287                                          &flags );
     288    if ( ko )
     289    {
     290        _puts("\n[GIET ERROR] in _nic_cma_start_receive() : kernel buffer unmapped\n");
     291        return -1;
     292    }
     293
     294    mem_chbuf_lsb = (ppn << 12) | (vaddr & 0x00000FFF);
     295    mem_chbuf_msb = ppn >> 20;
     296
     297    // initializes CMA registers defining the source chbuf (NIC_RX)
     298    _cma_set_register( cma_channel, CHBUF_SRC_DESC , nic_chbuf_lsb );
     299    _cma_set_register( cma_channel, CHBUF_DST_EXT  , nic_chbuf_msb );
     300    _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, 2 );
     301
     302    // initializes CMA registers defining the destination chbuf (kernel memory)
     303    _cma_set_register( cma_channel, CHBUF_DST_DESC , mem_chbuf_lsb );
     304    _cma_set_register( cma_channel, CHBUF_DST_EXT  , mem_chbuf_msb );
     305    _cma_set_register( cma_channel, CHBUF_DST_NBUFS, GIET_CHBUF_NBUFS );
     306
     307    // set buffer size, polling period, and start
     308    _cma_set_register( cma_channel, CHBUF_BUF_SIZE , 4096 );
     309    _cma_set_register( cma_channel, CHBUF_PERIOD   , 300 );
     310    _cma_set_register( cma_channel, CHBUF_RUN      , 1 );
     311
     312    return 0;
     313}
     314
     315//////////////////////////////////////////////////////////
     316int _nic_cma_send( unsigned int  nic_channel,
     317                   unsigned int  cma_channel,
     318                   nic_chbuf_t*  kernel_chbuf )
     319{
     320    unsigned int nic_chbuf_lsb;     // 32 LSB bits of the NIC chbuf physical address
     321    unsigned int nic_chbuf_msb;     // 16 MSB bits of the NIC chbuf physical address
     322    unsigned int mem_chbuf_lsb;     // 32 LSB bits of the kernel chbuf physical address
     323    unsigned int mem_chbuf_msb;     // 16 MSB bits of the kernel chbuf physical address
     324
     325    unsigned int ppn;
     326    unsigned int flags;
     327
     328    // checking parameters
     329    if ( nic_channel >= NB_NIC_CHANNELS )
     330    {
     331        _puts("[GIET ERROR] in _nic_cma_start_send() : nic_channel index too large\n");
     332        return -1;
     333    }
     334    if ( cma_channel >= NB_CMA_CHANNELS )
     335    {
     336        _puts("[GIET ERROR] in _nic_cma_start_send() : cma_channel index too large\n");
     337        return -1;
     338    }
     339
     340    // get the NIC_TX chbuf descriptor physical address
     341    nic_chbuf_lsb = SEG_NIC_BASE + (nic_channel * NIC_CHANNEL_SPAN) + 0x1010;
     342    nic_chbuf_msb = (X_IO << Y_WIDTH) + Y_IO;
     343
     344    // compute the kernel chbuf physical address
     345    unsigned int ptab  = _get_context_slot(CTX_PTAB_ID);
     346    unsigned int vaddr = (unsigned int)kernel_chbuf;
     347    unsigned int ko    = _v2p_translate( (page_table_t*)ptab,
     348                                          vaddr,
     349                                          &ppn,
     350                                          &flags );
     351    if ( ko )
     352    {
     353        _puts("\n[GIET ERROR] in _nic_cma_start_send() : kernel buffer unmapped\n");
     354        return -1;
     355    }
     356
     357    mem_chbuf_lsb = (ppn << 12) | (vaddr & 0x00000FFF);
     358    mem_chbuf_msb = ppn >> 20;
     359
     360    // initializes CMA registers defining the source chbuf (kernel memory)
     361    _cma_set_register( cma_channel, CHBUF_SRC_DESC , mem_chbuf_lsb );
     362    _cma_set_register( cma_channel, CHBUF_DST_EXT  , mem_chbuf_msb );
     363    _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, GIET_CHBUF_NBUFS );
     364
     365    // initializes CMA registers defining the destination chbuf (NIC_TX)
     366    _cma_set_register( cma_channel, CHBUF_DST_DESC , nic_chbuf_lsb );
     367    _cma_set_register( cma_channel, CHBUF_DST_EXT  , nic_chbuf_msb );
     368    _cma_set_register( cma_channel, CHBUF_DST_NBUFS, 2 );
     369
     370    // set buffer size, polling period, and start
     371    _cma_set_register( cma_channel, CHBUF_BUF_SIZE , 4096 );
     372    _cma_set_register( cma_channel, CHBUF_PERIOD   , 300 );
     373    _cma_set_register( cma_channel, CHBUF_RUN      , 1 );
     374
     375    return 0;
     376}
     377
     378////////////////////////////////////////////////////////////////////////////////////////////
     379//            Interrupt Service Routines
     380////////////////////////////////////////////////////////////////////////////////////////////
     381
     382////////////////////////////////////////
    141383void _nic_rx_isr( unsigned int irq_type,
    142384                  unsigned int irq_id,
    143385                  unsigned int channel )
    144386{
    145     _printf("[GIET ERROR] _nic_rx_isr() not implemented / cycle %d\n",
    146             _get_proctime() );
    147     _exit();
    148 }
    149 
    150 //////////////////////////////////////////////////////////////////////////////////
    151 // This ISR handles IRQx from a NIC RX channeL
    152 //////////////////////////////////////////////////////////////////////////////////
     387    _puts("[NIC WARNING] RX buffers are full for NIC channel ");
     388    _putd( channel );
     389    _puts("\n");
     390}
     391
     392////////////////////////////////////////
    153393void _nic_tx_isr( unsigned int irq_type,
    154394                  unsigned int irq_id,
    155395                  unsigned int channel )
    156396{
    157     _printf("[GIET ERROR] _nic_tx_isr() not implemented / cycle %d\n",
    158             _get_proctime() );
    159     _exit();
     397    _puts("[NIC WARNING] TX buffers are full for NIC channel ");
     398    _putd( channel );
     399    _puts("\n");
    160400}
    161401
  • soft/giet_vm/giet_drivers/nic_driver.h

    r295 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7// The nic_driver.c and nic_driver.h files are part ot the GIET-VM nano-kernel.
     8// This driver supports the vci_multi_nic component.
     9//
     10// It can exist only one network controller in the architecture, but this
     11// component supports several channels.
     12//
     13// It can be accessed directly by software with memcpy(),
     14// or it can be accessed through the vci_chbuf_dma component:
     15// 
     16// The '_nic_sync_write' and '_nic_sync_read' functions use a memcpy strategy to
     17// implement the transfer between a data buffer (user space) and the NIC
     18// buffer (kernel space). They are blocking until completion of the transfer.
     19//
     20// The _nic_cma_start() and _nic_cma_stop() functions use the VciChbufDma component
     21// to transfer a flow of packets from the NIC RX hard chbuf (two containers)
     22// to an user RX chbuf (two containers), and to transfer another flow of packets
     23// from an user TX chbuf (two containers) to the NIC TX chbuf (two containers).
     24// One NIC channel and two CMA channels must be allocated to the task
     25// in the mapping_info data structure.
     26//
     27// All these access functions return -1 in case of error.
     28//
     29// The SEG_NIC_BASE address must be defined in the hard_config.h file.
     30//////////////////////////////////////////////////////////////////////////////////
    731
    832#ifndef _GIET_NIC_DRIVERS_H_
    933#define _GIET_NIC_DRIVERS_H_
    1034
     35#include <giet_config.h>
     36
    1137///////////////////////////////////////////////////////////////////////////////////
    12 // NIC Registers  (vci_multi_nic)
     38//           Global Addressable Registers
    1339///////////////////////////////////////////////////////////////////////////////////
    1440
     
    5076};
    5177
    52 /////////////////////////////////////////////////////////////////////
     78/////////////////////////////////////////////////////////////////////////////////////
     79//            Channel Addressable Registers
    5380// A container descriptor has the following form:
    54 // LOW WORD : Container LSB base address     
    55 // HIGH WORD: Container status (leftmost bit), '1' means full
    56 //            Base address MSB extension, if needed (right aligned)
    57 //////////////////////////////////////////////////////////////////////
     81// LOW WORD  : 32 LSB bits of the container physical base address     
     82// HIGH WORD : 16 MSB bits of the container physical base address + status (bit 31) 
     83/////////////////////////////////////////////////////////////////////////////////////
    5884enum SoclibMultiNicChannelRegisters
    5985{
     
    7298};
    7399
     100
     101////////////////////////////////////////////////////////////////////////////////////
     102//              Chained Buffer Descriptor Structure
     103////////////////////////////////////////////////////////////////////////////////////
     104typedef struct nic_chbuf_s
     105{
     106    unsigned long long buf[GIET_CHBUF_NBUFS]; // array of buffer descriptors
     107    unsigned int       buf_length;            // buffer length (bytes)
     108    unsigned int       nb_buffers;            // actual number of buffers
     109} nic_chbuf_t;
     110
    74111///////////////////////////////////////////////////////////////////////////////////
    75 // NIC device access functions  (vci_multi_nic)
     112//              Initialization functions
    76113///////////////////////////////////////////////////////////////////////////////////
    77114
    78 extern unsigned int _nic_sync_write( const void*  buffer,
    79                                      unsigned int length );
     115extern int _nic_global_init( unsigned int channels,
     116                             unsigned int vis,
     117                             unsigned int bc_enable,
     118                             unsigned int bypass_enable );
    80119
    81 extern unsigned int _nic_sync_read(  const void*  buffer,
    82                                      unsigned int length );
     120extern int _nic_channel_init( unsigned int index,
     121                              unsigned int mac4,
     122                              unsigned int mac2 );
    83123
    84 extern unsigned int _nic_cma_start();
     124///////////////////////////////////////////////////////////////////////////////////
     125//              Blocking functions using a physical_memcpy()
     126///////////////////////////////////////////////////////////////////////////////////
    85127
    86 extern unsigned int _nic_cma_stop();
     128extern int _nic_sync_receive( unsigned int       channel,
     129                              unsigned long long user_paddr );
     130
     131extern int _nic_sync_send( unsigned int       channel,
     132                           unsigned long long user_paddr );
     133
     134///////////////////////////////////////////////////////////////////////////////////
     135//              Non blocking functions using the chained buffer DMA
     136///////////////////////////////////////////////////////////////////////////////////
     137
     138extern int _nic_cma_receive( unsigned int  nic_channel,
     139                             unsigned int  cma_channel,
     140                             nic_chbuf_t*  kernel_chbuf );
     141
     142extern int _nic_cma_send( unsigned int  nic_channel,
     143                          unsigned int  cma_channel,
     144                          nic_chbuf_t*  kernel_chbuf );
     145
     146///////////////////////////////////////////////////////////////////////////////////
     147//              Interrupt Service Routines
     148///////////////////////////////////////////////////////////////////////////////////
    87149
    88150extern void _nic_rx_isr( unsigned int irq_type,
     
    94156                         unsigned int channel );
    95157
    96 ///////////////////////////////////////////////////////////////////////////////////
    97158
    98159
  • soft/giet_vm/giet_drivers/pic_driver.c

    r413 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // Implementation note:
    8 // All physical accesses to device registers are done by the two
    9 // _pic_get_register(), _pic_set_register() low-level functions,
    10 // that are handling virtual / physical addressing.
    11 ///////////////////////////////////////////////////////////////////////////////////
    127
    138#include <pic_driver.h>
     9#include <giet_config.h>
     10#include <hard_config.h>
    1411#include <utils.h>
    1512
     
    1815#endif
    1916
    20 /////////////////////////////////////////////////////////////////////////////////
     17/////////////////////////////////////////////////////
    2118unsigned int _pic_get_register( unsigned int channel,
    2219                                unsigned int index )
     
    2623}
    2724
    28 /////////////////////////////////////////////////////////////////////////////////
     25/////////////////////////////////////////////
    2926void _pic_set_register( unsigned int channel,
    3027                        unsigned int index,
     
    3633
    3734
    38 /////////////////////////////////////////////////////////////////////////////////
     35/////////////////////////////////////
    3936void _pic_init( unsigned int channel,      // source PIC HWI channel
    4037                unsigned int vaddr,        // dest XCU WTI address
     
    4643}
    4744
    48 /////////////////////////////////////////////////////////////////////////////////
     45////////////////////////////////////////////////////
    4946unsigned int _pic_get_status( unsigned int channel )
    5047{
  • soft/giet_vm/giet_drivers/pic_driver.h

    r413 r437  
    1515
    1616///////////////////////////////////////////////////////////////////////////////////
    17 // PIC (vci_iopic) registers offsets
     17//                     registers offsets
    1818///////////////////////////////////////////////////////////////////////////////////
    1919
     
    2929
    3030//////////////////////////////////////////////////////////////////////////////////
    31 // PIC access functions
     31//                     access functions
    3232//////////////////////////////////////////////////////////////////////////////////
    3333
  • soft/giet_vm/giet_drivers/rdk_driver.c

    r405 r437  
    66// Copyright (c) UPMC-LIP6
    77///////////////////////////////////////////////////////////////////////////////////
    8 // The rdk_driver.c and rdk_driver.h files are part ot the GIET-VM kernel.
    9 //
    10 // This driver supports a virtual disk implemented as a memory segment,
    11 // in the address space.
    12 //
    13 // The _rdk_read() and _rdk_write() blocking functions use a software memcpy,
    14 // whatever the selected mode. They return only when the transfer is completed.
    15 // As the number of concurrent accesses is not bounded, these functions
    16 // don't use the _ioc_lock variable.
    17 //
    18 // The SEG_RDK_BASE virtual address must be defined in the hard_config.h
    19 // file when the USE_RAMDISK flag is set.
    20 ///////////////////////////////////////////////////////////////////////////////////
    218
    229#include <giet_config.h>
     
    2411#include <rdk_driver.h>
    2512#include <utils.h>
    26 #include <tty_driver.h>
    27 #include <ctx_handler.h>
    2813
    2914#if !defined(SEG_RDK_BASE)
     
    3116#endif
    3217
    33 ///////////////////////////////////////////////////////////////////////////////
    34 //       _rdk_init()
    35 // This function does nothing, and return 0 for success.
    36 ///////////////////////////////////////////////////////////////////////////////
     18//////////////////////////////////////////////
    3719unsigned int _rdk_init( unsigned int channel )
    3820{
     
    4022}
    4123
    42 ///////////////////////////////////////////////////////////////////////////////
    43 //     _rdk_read()
    44 // Transfer data from the RAMDISK to a memory buffer.
    45 // - mode     : BOOT / KERNEL / USER
    46 // - lba      : first block index on the block device
    47 // - buffer   : virtual base address of the memory buffer
    48 // - count    : number of blocks to be transfered.
    49 // Returns 0 if success, > 0 if error.
    50 ///////////////////////////////////////////////////////////////////////////////
     24//////////////////////////////////////////
    5125unsigned int _rdk_read( unsigned int lba,
    5226                        unsigned int buffer,
    5327                        unsigned int count)
    5428{
     29#if USE_IOC_RDK
    5530
    5631#if GIET_DEBUG_IOC_DRIVER
    57 _printf("\n[IOC DEBUG] Enter _rdk_read() at cycle %d"
    58         "\n - vaddr   = %x"
    59         "\n - sectors = %d"
    60         "\n - lba     = %x",
    61         _get_proctime(), buffer, count, lba );
     32_puts("\n[IOC DEBUG] Enter _rdk_read() at cycle ");
     33_putd( _get_proctime() );
     34_puts("\n - vaddr   = ");
     35_putx( buffer );
     36-puts("\n - sectors = ");
     37_putd( count );
     38-puts("\n - lba     = ");
     39_putx( lba );
     40_puts("\n");
    6241#endif
    6342
    64 #if USE_IOC_RDK
    6543    char* src = (char*)SEG_RDK_BASE + (512*lba);
    6644    char* dst = (char*)buffer;
    6745    memcpy( dst, src, count*512 );
    6846    return 0;
     47
    6948#else
    70     _printf("[GIET ERROR] _rdk_read() should not be used if USE_IOC_RDK not set\n");
     49
     50    _puts("[GIET ERROR] _rdk_read() should not be used if USE_IOC_RDK not set\n");
    7151    return 1;
     52
    7253#endif
    7354}
    7455
    75 ///////////////////////////////////////////////////////////////////////////////
    76 //     _rdk_write()
    77 // Transfer data from a memory buffer to the block device.
    78 // - mode     : BOOT / KERNEL / USER
    79 // - lba      : first block index on the block device
    80 // - buffer   : virtual base address of the memory buffer
    81 // - count    : number of blocks to be transfered.
    82 // Returns 0 if success, > 0 if error.
    83 ///////////////////////////////////////////////////////////////////////////////
     56//////////////////////////////////////////
    8457unsigned int _rdk_write( unsigned int lba,
    8558                         unsigned int buffer,
    8659                         unsigned int count )
    8760{
     61#if USE_IOC_RDK
    8862
    8963#if GIET_DEBUG_IOC_DRIVER
    90 _printf("\n[IOC DEBUG] Enter _rdk_write() at cycle %d"
    91         "\n - vaddr   = %x"
    92         "\n - sectors = %d"
    93         "\n - lba     = %x",
    94         _get_proctime(), buffer, count, lba );
     64_puts("\n[IOC DEBUG] Enter _rdk_write() at cycle ");
     65_putd( _get_proctime() );
     66_puts("\n - vaddr   = ");
     67_putx( buffer );
     68-puts("\n - sectors = ");
     69_putd( count );
     70-puts("\n - lba     = ");
     71_putx( lba );
     72_puts("\n");
    9573#endif
    9674
    97 #if USE_IOC_RDK
    9875    char* dst = (char*)SEG_RDK_BASE + (512*lba);
    9976    char* src = (char*)buffer;
    10077    memcpy( dst, src, count*512 );
    10178    return 0;
     79
    10280#else
    103     _printf("[GIET ERROR] _rdk_write() should not be used if USE_IOC_RDK not set\n");
     81
     82    _puts("[GIET ERROR] _rdk_write() should not be used if USE_IOC_RDK not set\n");
    10483    return 1;
     84
    10585#endif
    10686}
    10787
    108 ///////////////////////////////////////////////////////////////////////////////
    109 //     _rdk_get_block_size()
    110 // This function returns the block_size.
    111 ///////////////////////////////////////////////////////////////////////////////
     88//////////////////////////////////
    11289unsigned int _rdk_get_block_size()
    11390{
    11491    return 512;
     92}
     93
     94//////////////////////////////
     95unsigned int _rdk_get_status()
     96{
     97    return 0;
    11598}
    11699
  • soft/giet_vm/giet_drivers/rdk_driver.h

    r298 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7// The rdk_driver.c and rdk_driver.h files are part ot the GIET-VM kernel.
     8//
     9// This driver supports a virtual disk implemented as a memory segment,
     10// in the physical address space.
     11//
     12// The _rdk_read() and _rdk_write() blocking functions use a software memcpy,
     13// whatever the selected mode. They return only when the transfer is completed.
     14// As the number of concurrent accesses is not bounded, these functions
     15// don't use the _ioc_lock variable.
     16//
     17// The SEG_RDK_BASE virtual address must be defined in the hard_config.h
     18// file when the USE_RAMDISK flag is set.
     19///////////////////////////////////////////////////////////////////////////////////
    720
    821#ifndef _GIET_RDK_DRIVERS_H_
    922#define _GIET_RDK_DRIVERS_H_
    10 
    11 #include <mapping_info.h>
    1223
    1324///////////////////////////////////////////////////////////////////////////////////
     
    1526///////////////////////////////////////////////////////////////////////////////////
    1627
     28///////////////////////////////////////////////////////////////////////////////
     29// This function does nothing, but is required by the IOC API.
     30///////////////////////////////////////////////////////////////////////////////
    1731extern unsigned int _rdk_init();
    1832
     33///////////////////////////////////////////////////////////////////////////////
     34// Transfer data from a memory buffer to the RAMDISK.
     35// - mode     : BOOT / KERNEL / USER (unused)
     36// - lba      : first block index on the block device
     37// - buffer   : virtual base address of the memory buffer
     38// - count    : number of blocks to be transfered.
     39// Returns 0 if success, > 0 if error.
     40///////////////////////////////////////////////////////////////////////////////
    1941extern unsigned int _rdk_write( unsigned int lba,
    2042                                unsigned int buffer,
    2143                                unsigned int count );
    2244
     45///////////////////////////////////////////////////////////////////////////////
     46// Transfer data from the RAMDISK to a memory buffer.
     47// - mode     : BOOT / KERNEL / USER (unused)
     48// - lba      : first block index on the block device
     49// - buffer   : virtual base address of the memory buffer
     50// - count    : number of blocks to be transfered.
     51// Returns 0 if success, > 0 if error.
     52///////////////////////////////////////////////////////////////////////////////
    2353extern unsigned int _rdk_read(  unsigned int lba,
    2454                                unsigned int buffer,
    2555                                unsigned int count );
    2656
     57///////////////////////////////////////////////////////////////////////////////
     58// This function returns the block size.
     59///////////////////////////////////////////////////////////////////////////////
    2760extern unsigned int _rdk_get_block_size();
    2861
    2962///////////////////////////////////////////////////////////////////////////////////
     63// This function returns always 0, but is required by the IOC API.
     64///////////////////////////////////////////////////////////////////////////////
     65extern unsigned int _rdk_get_status();
    3066
    3167#endif
  • soft/giet_vm/giet_drivers/sdc_driver.c

    r320 r437  
    1818
    1919///////////////////////////////////////////////////////////////////////////////
    20 //      _sdc_enable()
    2120// This function enables SD Card select signal
    2221///////////////////////////////////////////////////////////////////////////////
     
    2726
    2827///////////////////////////////////////////////////////////////////////////////
    29 //      _sdc_enable()
    3028// This function disables SD Card select signal
    3129///////////////////////////////////////////////////////////////////////////////
     
    3634
    3735///////////////////////////////////////////////////////////////////////////////
    38 //      _sdc_gen_tick()
    3936// This function writes on the SPI tx register to generate SD card clock ticks
    4037// - tick_count: number of ticks to generate (1 tick -> 8 clocks)
     
    4744
    4845///////////////////////////////////////////////////////////////////////////////
    49 //      _sdc_lseek()
    5046// This function changes the SD card access pointer position in terms of
    5147// blocks
     
    5854
    5955///////////////////////////////////////////////////////////////////////////////
    60 //      _sdc_receive_char()
    6156// This function gets a byte from the SD card
    6257///////////////////////////////////////////////////////////////////////////////
     
    6964
    7065///////////////////////////////////////////////////////////////////////////////
    71 //      _sdc_wait_response()
    7266// This function returns when a valid response from the SD card is received or
    7367// a timeout has been triggered
     
    9488
    9589///////////////////////////////////////////////////////////////////////////////
    96 //      _sdc_wait_data_block()
    9790// This function returns when a data block from the SD card is received (data
    9891// block start marker received).
     
    10598
    10699///////////////////////////////////////////////////////////////////////////////
    107 //      _sdc_send_command()
    108100// This function sends a command to the SD card
    109101// - index: CMD index
     
    153145
    154146///////////////////////////////////////////////////////////////////////////////
    155 //      _sdc_open()
    156147// This function initializes the SD card (reset procedure)
    157148// - channel: channel index (only channel 0 is supported)
     
    182173        if ( sdcard_rsp != 0x01 )
    183174        {
    184                 _printf("[SDC ERROR] card CMD0 failed\n");
     175                _puts("[SDC ERROR] card CMD0 failed\n");
    185176                return sdcard_rsp;
    186177        }
     
    198189        if (!SDCARD_CHECK_R1_VALID(sdcard_rsp))
    199190    {
    200                 _printf("[SDC ERROR] card CMD8 failed\n");
     191                _puts("[SDC ERROR] card CMD8 failed\n");
    201192                return sdcard_rsp;
    202193        }
     
    211202        {
    212203                        // voltage mismatch
    213                         _printf("[SDC ERROR] card CMD8 mismatch : ersp = %x\n");
     204                        _puts("[SDC ERROR] card CMD8 mismatch : ersp = %x\n");
    214205                        return sdcard_rsp;
    215206                }
    216                 _printf("[SDC WARNING] v2 or later ");
     207                _puts("[SDC WARNING] v2 or later ");
    217208                sdcard.sdhc = 1;
    218209        }
     
    220211    {
    221212                // other error
    222                 _printf("[SDC ERROR] card CMD8 error\n");
     213                _puts("[SDC ERROR] card CMD8 error\n");
    223214                return sdcard_rsp;
    224215        }
     
    251242        if (sdcard_rsp)
    252243    {
    253                 _printf("[SDC ERROR] ACMD41 failed\n");
     244                _puts("[SDC ERROR] ACMD41 failed\n");
    254245                return sdcard_rsp;
    255246        }
     
    265256                if (sdcard_rsp)
    266257        {
    267                         _printf("[SDC ERROR] CMD58 failed\n");
     258                        _puts("[SDC ERROR] CMD58 failed\n");
    268259                        return sdcard_rsp;
    269260                }
     
    274265                if (ersp & 0x40000000)
    275266        {
    276                         _printf(" SDHC ");
     267                        _puts(" SDHC ");
    277268                }
    278269        else
     
    282273                _sdc_disable();
    283274        }
    284         _printf("card detected\n");
     275        _puts("card detected\n");
    285276        return 0;
    286277}
    287278
    288279///////////////////////////////////////////////////////////////////////////////
    289 //      _sdc_set_block_size()
    290 // This function sets the block size in bytes of the SD card
     280// This function sets the block size in the SD card.
    291281// - len: block size in bytes (only 512 bytes supported)
    292282// Returns 0 if success, other value if failure
     
    330320}
    331321
    332 ///////////////////////////////////////////////////////////////////////////////
    333 //      _sdc_init()
    334 // This function initializes the SPI controller and call sdc_open to
    335 // initializes SD card
    336 // - channel: channel to initialize (only channel 0 supported)
    337 // Returns 0 if success, other value if failure
    338 ///////////////////////////////////////////////////////////////////////////////
     322/////////////////////////////////////////////////////////////////////////////////
     323//           Extern functions
     324/////////////////////////////////////////////////////////////////////////////////
     325
     326////////////////////////
    339327unsigned int _sdc_init()
    340328{
     
    358346    while(1)
    359347    {
    360         _printf("[SDC WARNING] Trying to initialize SD card...\n");
     348        _puts("[SDC WARNING] Trying to initialize SD card...\n");
    361349
    362350        sdcard_rsp = _sdc_open( 0 );  // only channel 0
    363351        if (sdcard_rsp == 0)
    364352        {
    365             _printf("OK\n");
     353            _puts("OK\n");
    366354            break;
    367355        }
    368356
    369         _printf("KO\n");
     357        _puts("KO\n");
    370358
    371359        for (i = 0; i < 1000; i++);
     
    373361        if (++iter >= SDCARD_RESET_ITER_MAX)
    374362        {
    375             _printf("\n[SDC ERROR] During SD card reset to IDLE state "
    376                     "/ card response = %x\n", sdcard_rsp );
     363            _puts("\n[SDC ERROR] During SD card reset / card response = ");
     364            _putx( sdcard_rsp );
     365            _puts("\n");
    377366            _exit();
    378367        }
     
    383372    if (sdcard_rsp)
    384373    {
    385         _printf("[SDC ERROR] During SD card blocklen initialization\n");
     374        _puts("[SDC ERROR] During SD card blocklen initialization\n");
    386375        _exit();
    387376    }
     
    397386    );
    398387
    399     _printf("[SDC WARNING] Finish SD card initialization\n\r");
     388    _puts("[SDC WARNING] Finish SD card initialization\n\r");
    400389
    401390    return 0;
     
    403392
    404393
    405 ///////////////////////////////////////////////////////////////////////////////
    406 //     _sdc_read()
    407 // Transfer data from the block device to a memory buffer.
    408 // - mode     : BOOT / KERNEL / USER
    409 // - lba      : first block index on the block device
    410 // - buffer   : base address of the memory buffer (must be word aligned)
    411 // - count    : number of blocks to be transfered.
    412 // Returns 0 if success, > 0 if error.
    413 ///////////////////////////////////////////////////////////////////////////////
     394//////////////////////////////////////////
    414395unsigned int _sdc_read( unsigned int mode,
    415396                        unsigned int lba,
     
    461442}
    462443
    463 ///////////////////////////////////////////////////////////////////////////////
    464 //     _sdc_write() (not supported for now)
    465 // Transfer data from memory buffer to SD card device.
    466 // - mode     : BOOT / KERNEL / USER
    467 // - lba      : destination first block index on the SD card
    468 // - buffer   : base address of the memory buffer (must be word aligned)
    469 // - count    : number of blocks to be transfered.
    470 // Returns 0 if success, > 0 if error.
    471 ///////////////////////////////////////////////////////////////////////////////
     444///////////////////////////////////////////
    472445unsigned int _sdc_write( unsigned int mode,
    473446                         unsigned int lba,
     
    475448                         unsigned int count )
    476449{
    477         return 0;
    478 }
    479 
    480 ///////////////////////////////////////////////////////////////////////////////
    481 // Transfer data from memory buffer to SD card device.
    482 // - channel: channel index
    483 // - status: this pointer is used to transmit the status value to caller.
    484 // Returns 0 if success, > 0 if error.
    485 ///////////////////////////////////////////////////////////////////////////////
     450    _puts("[SDC ERROR] function _sdc_write() not iplemented yet\n");
     451    _exit();
     452
     453    return 0;  // to avoid a warning
     454}
     455
     456//////////////////////////////
    486457unsigned int _sdc_get_status()
    487458{
    488     _printf("[SDC ERROR] function _sdc_get_status() should not be called\n");
     459    _puts("[SDC ERROR] function _sdc_get_status() should not be called\n");
    489460    _exit();
    490461
     
    492463}
    493464
    494 ///////////////////////////////////////////////////////////////////////////////
    495 // Returns the block size in bytes of the SD card
    496 ///////////////////////////////////////////////////////////////////////////////
     465//////////////////////////////////
    497466unsigned int _sdc_get_block_size()
    498467{
  • soft/giet_vm/giet_drivers/sdc_driver.h

    r295 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7
    78#ifndef _GIET_SDC_DRIVER_H_
    89#define _GIET_SDC_DRIVER_H_
     
    3637};
    3738
     39///////////////////////////////////////////////////////////////////////////////
     40// This function initializes the SPI controller and call sdc_open to
     41// initialize  the SD card
     42// - channel: channel to initialize (only channel 0 supported)
     43// Returns 0 if success, other value if failure
     44///////////////////////////////////////////////////////////////////////////////
    3845unsigned int _sdc_init();
    3946
     47///////////////////////////////////////////////////////////////////////////////
     48// Transfer data from the block device to a memory buffer.
     49// - mode     : BOOT / KERNEL / USER
     50// - lba      : first block index on the block device
     51// - buffer   : base address of the memory buffer (must be word aligned)
     52// - count    : number of blocks to be transfered.
     53// Returns 0 if success, > 0 if error.
     54///////////////////////////////////////////////////////////////////////////////
    4055unsigned int _sdc_read( unsigned int mode,
    4156                        unsigned int lba,
     
    4459
    4560
     61///////////////////////////////////////////////////////////////////////////////
     62// Transfer data from memory buffer to SD card device.
     63// - mode     : BOOT / KERNEL / USER
     64// - lba      : destination first block index on the SD card
     65// - buffer   : base address of the memory buffer (must be word aligned)
     66// - count    : number of blocks to be transfered.
     67// Returns 0 if success, > 0 if error.
     68// WARNING: The _sdc_write() is not implemented yet.
     69///////////////////////////////////////////////////////////////////////////////
    4670unsigned int _sdc_write( unsigned int mode,
    4771                         unsigned int lba,
     
    4973                         unsigned int count);
    5074
     75///////////////////////////////////////////////////////////////////////////////
     76// This function should not be called for the SDC card.
     77///////////////////////////////////////////////////////////////////////////////
    5178unsigned int _sdc_get_status();
    5279
     80///////////////////////////////////////////////////////////////////////////////
     81// Returns the block size in bytes of the SD card.
     82///////////////////////////////////////////////////////////////////////////////
    5383unsigned int _sdc_get_block_size();
    5484
  • soft/giet_vm/giet_drivers/sim_driver.c

    r345 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The sim_driver.c and sim_driver.h files are part ot the GIET-VM nano-kernel.
    8 // This driver supports the vci_sim_helper component.
    9 // There is at most one such component in the architecture.
    10 //
    11 // The SEG_SIM_BASE address must be defined in the hard_config.h file.
    12 ////////////////////////////////////////////////////////////////////////////////
    137
    148#include <hard_config.h>
     
    2014#endif
    2115
    22 ////////////////////////////////////////////////////////////////////////////////
    23 // _sim_helper_access()
    24 // Accesses the Simulation Helper Component.
    25 //
    26 // If the access is on a writable register (except SIMHELPER_PAUSE_SIM),
    27 // the simulation will stop.
    28 // If the access is on a readable register, value is written in retval buffer.
    29 // Returns 0 on success, 1 on failure.
    30 ////////////////////////////////////////////////////////////////////////////////
    31 unsigned int _sim_helper_access( unsigned int register_index,
    32                                  unsigned int value,
    33                                  unsigned int * retval)
     16/////////////////////////////////////////////////////
     17void _sim_helper_access( unsigned int register_index,
     18                         unsigned int value,
     19                         unsigned int * retval )
    3420{
    3521    volatile unsigned int* sim_helper_address = (unsigned int*)&seg_sim_base;
    3622   
    37     if (register_index == SIMHELPER_SC_STOP         ||
    38         register_index == SIMHELPER_END_WITH_RETVAL ||
    39         register_index == SIMHELPER_EXCEPT_WITH_VAL ||
    40         register_index == SIMHELPER_PAUSE_SIM       ||
    41         register_index == SIMHELPER_SIGINT)
     23    if (register_index == SIMHELPER_SC_STOP)
    4224    {
    4325        sim_helper_address[register_index] = value;
    44         return 0;
    4526    }
    4627    else if (register_index == SIMHELPER_CYCLES)
    4728    {
    4829        *retval = sim_helper_address[register_index];
    49         return 0;
    5030    }
    5131    else
    5232    {
    5333        _tty_get_lock( 0 );
    54         _puts("\n[GIET ERROR] in _sim_helper_access() : access to unmapped register\n");
     34        _puts("\n[GIET ERROR] in _sim_helper_access() : undefined register\n");
    5535        _tty_release_lock( 0 );
    56         return 1;
     36        _exit();
    5737    }
    5838}
  • soft/giet_vm/giet_drivers/sim_driver.h

    r258 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7// The sim_driver.c and sim_driver.h files are part ot the GIET-VM nano-kernel.
     8//
     9// This driver supports the vci_sim_helper component, that is a pseudo hardware
     10// component available in the SoCLib library, and providing a monitoring service
     11// in a virtual prototyping environment.
     12//
     13// There is at most one such component in the architecture.
     14//
     15// The SEG_SIM_BASE address must be defined in the hard_config.h file.
     16////////////////////////////////////////////////////////////////////////////////
    717
    818#ifndef _GIET_SIM_DRIVERS_H_
     
    1525enum SoclibSimhelperRegisters
    1626{
    17     SIMHELPER_SC_STOP,
    18     SIMHELPER_END_WITH_RETVAL,
    19     SIMHELPER_EXCEPT_WITH_VAL,
    20     SIMHELPER_PAUSE_SIM,
    21     SIMHELPER_CYCLES,
    22     SIMHELPER_SIGINT,
     27    SIMHELPER_SC_STOP,                 // stop simulation
     28    SIMHELPER_END_WITH_RETVAL,         // Not supported
     29    SIMHELPER_EXCEPT_WITH_VAL,         // Not supported
     30    SIMHELPER_PAUSE_SIM,               // Not supported
     31    SIMHELPER_CYCLES,                  // Return number of cycles
     32    SIMHELPER_SIGINT,                  // Not supported
    2333};
    2434
    25 ///////////////////////////////////////////////////////////////////////////////////
    26 // SIM_HELPER access functions
    27 ///////////////////////////////////////////////////////////////////////////////////
     35////////////////////////////////////////////////////////////////////////////////
     36// Accesses the Simulation Helper Component.
     37// - If the access is on a write register, the simulation will stop.
     38// - If the access is on a read register, value is written in retval buffer.
     39////////////////////////////////////////////////////////////////////////////////
     40extern void _sim_helper_access( unsigned int  register_index,
     41                                unsigned int  value,
     42                                unsigned int* retval );
    2843
    29 extern unsigned int _sim_helper_access( unsigned int  register_index,
    30                                         unsigned int  value,
    31                                         unsigned int* retval );
    32 
    33 ///////////////////////////////////////////////////////////////////////////////////
    3444
    3545#endif
  • soft/giet_vm/giet_drivers/spi_driver.c

    r320 r437  
    258258               unsigned int channel )
    259259{
    260     _printf("\n[GIET ERROR] _spi_isr() not implemented\n");
     260    _puts("\n[GIET ERROR] _spi_isr() not implemented\n");
    261261    _exit();
    262262}
  • soft/giet_vm/giet_drivers/tim_driver.c

    r426 r437  
    11//////////////////////////////////////////////////////////////////////////////////////
    2 // File     : timer_driver.c
     2// File     : tim_driver.c
    33// Date     : 23/05/2013
    44// Author   : alain greiner
    55// Copyright (c) UPMC-LIP6
    66//////////////////////////////////////////////////////////////////////////////////////
    7 // The timer_driver.c and timer_driver.h files are part ot the GIET-VM nano-kernel.
    8 // This driver supports the SoCLib vci_multi_timer component.
    9 //
    10 // It can exist several multi_timers in the architecture (at most one per cluster),
    11 // and each one can contain several timers (called channels).
    12 //
    13 // There is two types of timers:
    14 // - "system" timers : one per processor, used for context switch.
    15 //   local_id in [0, NB_PROCS_MAX-1],
    16 // - "user" timers : requested by the task in the mapping_info data structure.
    17 //   For each user timer, the timer_id is stored in the context of the task.
    18 // The global index is cluster_xy * (NB_PROCS_MAX + NB_TIM_CHANNELS) + local_id
    19 //
    20 // The NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in hard_config.h file.
    21 //
    22 // The virtual base address of the segment associated to a channel is:
    23 //     SEG_TIM_BASE + cluster_xy * PERI_CLUSTER_INCREMENT + TIMER_SPAN * timer_id
    24 //
    25 // The SEG_TIM_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h.
    26 /////////////////////////////////////////////////////////////////////////////////////
    277
    288#include <giet_config.h>
     9#include <hard_config.h>
    2910#include <tim_driver.h>
    30 #include <xcu_driver.h>
    31 #include <tty_driver.h>
    3211#include <utils.h>
    3312
     
    6847#endif
    6948
    70 ///////////////////  Timer global variables ////////////////////////////////////////
     49/////////////////////////////////////////////////////////////////////////////////
     50//                      global variables
     51/////////////////////////////////////////////////////////////////////////////////
    7152
    7253#define in_unckdata __attribute__((section (".unckdata")))
    7354
    7455#if (NB_TIM_CHANNELS > 0)
    75 in_unckdata volatile unsigned char _user_timer_event[(1<<X_WIDTH)*(1<<Y_WIDTH)*NB_TIM_CHANNELS]
    76                         = { [0 ... (((1<<X_WIDTH)*(1<<Y_WIDTH)*NB_TIM_CHANNELS) - 1)] = 0 };
     56in_unckdata volatile unsigned char _user_timer_event[NB_TIM_CHANNELS]
     57                        = { [0 ... ((1<<NB_TIM_CHANNELS) - 1)] = 0 };
    7758#endif
    7859
    79 ////////////////////////////////////////////////////////////////////////////////////
    80 // This function activates a timer in the vci_timer component
    81 // by writing in the proper register the period value.
    82 // It can be used by both the kernel to initialise a "system" timer,
    83 // or by a task (through a system call) to configure an "user" timer.
    84 ///////////////////////////////////////////////////////////////////////////////////
    85 void _timer_start( unsigned int cluster_xy,
    86                    unsigned int local_id,
    87                    unsigned int period)
     60/////////////////////////////////////////////////////////////////////////////////
     61//                      access functions
     62/////////////////////////////////////////////////////////////////////////////////
     63
     64//////////////////////////////////////////////////////////////
     65unsigned int _timer_get_register( unsigned int channel,
     66                                  unsigned int index )
     67{
     68    unsigned int* vaddr = (unsigned int*)SEG_TIM_BASE + channel*TIMER_SPAN + index;
     69    return _io_extended_read( vaddr );
     70}
     71
     72//////////////////////////////////////////////////////
     73void _timer_set_register( unsigned int channel,
     74                          unsigned int index,
     75                          unsigned int value )
     76{
     77    unsigned int* vaddr = (unsigned int*)SEG_TIM_BASE + channel*TIMER_SPAN + index;
     78    _io_extended_write( vaddr, value );
     79}
     80
     81///////////////////////////////////////
     82int _timer_start( unsigned int channel,
     83                  unsigned int period )
    8884{
    8985#if NB_TIM_CHANNELS
    9086
    91     // parameters checking
    92     unsigned int x = cluster_xy >> Y_WIDTH;
    93     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    94     if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
     87    if ( channel >= NB_TIM_CHANNELS )
    9588    {
    96         _printf("[GIET ERROR] in _timer_start()\n");
    97         _exit();
     89        _puts("[GIET ERROR] in _timer_start()\n");
     90        return -1;
    9891    }
    9992
    100     unsigned int* timer_address = (unsigned int *) ( SEG_TIM_BASE +
    101                                   (cluster_xy * PERI_CLUSTER_INCREMENT) );
    102 
    103     timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
    104     timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0x3;
     93    _timer_set_register( channel, TIMER_PERIOD, period );
     94    _timer_set_register( channel, TIMER_MODE  , 0x3 );
     95   
     96    return 0;
    10597
    10698#else
    107     _printf("[GIET ERROR] _timer_start() should not be called when NB_TIM_CHANNELS is 0\n");
    108     _exit();
     99
     100    _puts("[GIET ERROR] _timer_start() should not be called when NB_TIM_CHANNELS is 0\n");
     101    return -1;
     102
    109103#endif
    110104}
    111105
    112 //////////////////////////////////////////////////////////////////////////////
    113 // This function desactivates a timer in the vci_timer component
    114 // by writing in the proper register.
    115 // Returns 0 if success, > 0 if error.
    116 //////////////////////////////////////////////////////////////////////////////
    117 void _timer_stop( unsigned int cluster_xy,
    118                   unsigned int local_id)
     106///////////////////////////////////////
     107int _timer_stop( unsigned int channel )
    119108{
    120109#if NB_TIM_CHANNELS
    121110
    122     // parameters checking
    123     unsigned int x = cluster_xy >> Y_WIDTH;
    124     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    125     if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
     111    if ( channel >= NB_TIM_CHANNELS )
    126112    {
    127         _printf("[GIET ERROR] in _timer_stop()\n");
    128         _exit();
     113        _puts("[GIET ERROR] in _timer_stop()\n");
     114        return -1;
    129115    }
    130116
    131     unsigned int* timer_address = (unsigned int *) ( SEG_TIM_BASE +
    132                                   (cluster_xy * PERI_CLUSTER_INCREMENT) );
     117    _timer_set_register( channel, TIMER_MODE  , 0 );
    133118
    134     timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0;
     119    return 0;
    135120
    136121#else
    137     _printf("[GIET ERROR] _timer_stop() should not be called when NB_TIM_CHANNELS is 0\n");
    138     _exit();
     122
     123    _puts("[GIET ERROR] _timer_stop() should not be called when NB_TIM_CHANNELS is 0\n");
     124    return -1;
     125
    139126#endif
    140127}
    141128
    142 //////////////////////////////////////////////////////////////////////////////
    143 // This function acknowlegge a timer interrupt in the vci_timer 
    144 // component by writing in the proper register.
    145 // It can be used by both the isr_switch() for a "system" timer,
    146 // or by the _isr_timer() for an "user" timer.
    147 // Returns 0 if success, > 0 if error.
    148 //////////////////////////////////////////////////////////////////////////////
    149 void _timer_reset_irq( unsigned int cluster_xy,
    150                        unsigned int local_id )
     129////////////////////////////////////////////
     130int _timer_reset_cpt( unsigned int channel )
    151131{
    152132#if NB_TIM_CHANNELS
    153133
    154     // parameters checking
    155     unsigned int x = cluster_xy >> Y_WIDTH;
    156     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    157     if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
     134    if ( channel >= NB_TIM_CHANNELS )
    158135    {
    159         _printf("[GIET ERROR] in _timer_reset_irq()\n");
    160         _exit();
     136        _puts("[GIET ERROR in _timer_reset_cpt()\n");
     137        return -1;
    161138    }
    162139
    163     unsigned int* timer_address = (unsigned int *) ( SEG_TIM_BASE +
    164                                   (cluster_xy * PERI_CLUSTER_INCREMENT) );
     140    unsigned int period = _timer_get_register( channel, TIMER_PERIOD );
     141    _timer_set_register( channel, TIMER_PERIOD, period );
    165142
    166     timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0;
     143    return 0;
    167144
    168145#else
    169     _printf("[GIET ERROR] _timer_reset_irq() should not be called when NB_TIM_CHANNELS is 0\n");
    170     _exit();
     146
     147    _puts("[GIET ERROR] _timer_reset_cpt should not be called when NB_TIM_CHANNELS is 0\n");
     148    return -1;
     149
    171150#endif
    172151}
    173152
    174 /////////////////////////////////////////////////////////////////////////////
    175 // This function resets the timer counter. To do so, we re-write the period
    176 // in the proper register, what causes the count to restart.
    177 // The period value is read from the same (TIMER_PERIOD) register,
    178 // this is why in appearance we do nothing useful (read a value
    179 // from a register and write this value in the same register)
    180 // This function is called during a context switch (user or preemptive)
    181 //////////////////////////////////////////////////////////////////////i//////
    182 void _timer_reset_cpt( unsigned int cluster_xy,
    183                        unsigned int local_id)
    184 {
    185 #if NB_TIM_CHANNELS
    186 
    187     // parameters checking
    188     unsigned int x = cluster_xy >> Y_WIDTH;
    189     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    190     if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
    191     {
    192         _printf("[GIET ERROR in _timer_reset_cpt()\n");
    193         _exit();
    194     }
    195 
    196     // We suppose that the TIMER_MODE register value is 0x3
    197     unsigned int* timer_address = (unsigned int *) ( SEG_TIM_BASE +
    198                                   (cluster_xy * PERI_CLUSTER_INCREMENT) );
    199 
    200     unsigned int period = timer_address[local_id * TIMER_SPAN + TIMER_PERIOD];
    201     timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
    202 
    203 #else
    204     _printf("[GIET ERROR] _timer_reset_cpt should not be called when NB_TIM_CHANNELS is 0\n");
    205     _exit();
    206 #endif
    207 }
    208 
    209 ///////////////////////////////////////////////////////////////////////////////////
    210 // This ISR handles the IRQs generated by the "user" timers that are
    211 // replicated in all clusters.
    212 // The IRQs generated by the "system" timers should be handled by _isr_switch().
    213 // It can be a HWI or a PTI.
    214 // The channel argument is the user timer local index.
    215 //     timer_global_id = cluster_id*(NB_TIM_CHANNELS) + channel
    216 // The ISR acknowledges the IRQ and registers the event in the proper entry
    217 // of the _user_timer_event[] array, and a log message is displayed on TTY0.
    218 ///////////////////////////////////////////////////////////////////////////////////
     153///////////////////////////////////////
    219154void _timer_isr( unsigned int irq_type,   // HWI / PTI
    220155                 unsigned int irq_id,     // index returned by XCU
     
    223158#if NB_TIM_CHANNELS
    224159
    225     unsigned int cluster_xy = _get_procid() >> P_WIDTH;
    226 
    227     // acknowledge IRQ depending on type
    228     if   ( irq_type == IRQ_TYPE_HWI )  _timer_reset_irq( cluster_xy, channel );
    229     else                               _xcu_timer_reset_irq( cluster_xy, irq_id );
     160    // acknowledge IRQ
     161    _timer_set_register( channel, TIMER_RESETIRQ, 0 );
    230162
    231163    // register the event
    232     _user_timer_event[cluster_xy * NB_TIM_CHANNELS + channel] = 1;
     164    _user_timer_event[channel] = 1;
    233165
    234166    // display a message on TTY 0
    235     _printf("\n[GIET WARNING] User Timer IRQ at cycle %d / cluster = %x / channel = %d\n",
    236             _get_proctime(), cluster_xy, channel );
     167    _puts("\n[GIET WARNING] User Timer IRQ at cycle %d for channel = %d\n",
     168            _get_proctime(), channel );
    237169
    238170#else
    239     _printf("[GIET ERROR] _timer_isr() should not be called when NB_TIM_CHANNELS == 0\n");
     171
     172    _puts("[GIET ERROR] _timer_isr() should not be called when NB_TIM_CHANNELS == 0\n");
    240173    _exit();
     174
    241175#endif
    242176}
  • soft/giet_vm/giet_drivers/tim_driver.h

    r295 r437  
    1 ///////////////////////////////////////////////////////////////////////////////////
     1//////////////////////////////////////////////////////////////////////////////////////
    22// File     : tim_driver.h
    33// Date     : 01/11/2013
     
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7// The tim_driver.c and tim_driver.h files are part ot the GIET-VM nano-kernel.
     8// This driver supports the SoCLib vci_multi_timer component.
     9//
     10// It can exist several multi_timers in the architecture (at most one per cluster),
     11// and each one can contain several timers (called channels).
     12//
     13// There is two types of timers:
     14// - "system" timers : one per processor, used for context switch.
     15//   local_id in [0, NB_PROCS_MAX-1],
     16// - "user" timers : requested by the task in the mapping_info data structure.
     17//   For each user timer, the timer_id is stored in the context of the task.
     18// The global index is cluster_xy * (NB_PROCS_MAX + NB_TIM_CHANNELS) + local_id
     19//
     20// The NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in hard_config.h file.
     21//
     22// The virtual base address of the segment associated to a channel is:
     23//     SEG_TIM_BASE + cluster_xy * PERI_CLUSTER_INCREMENT + TIMER_SPAN * timer_id
     24//
     25// The SEG_TIM_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h.
     26/////////////////////////////////////////////////////////////////////////////////////
    727
    828#ifndef _GIET_TIM_DRIVER_H_
     
    1030
    1131///////////////////////////////////////////////////////////////////////////////////
    12 // TIMER (vci_multi_timer) registers offsets
     32//                   registers offsets
    1333///////////////////////////////////////////////////////////////////////////////////
    1434
     
    2444
    2545///////////////////////////////////////////////////////////////////////////////////
    26 // Timer access functions and global variables
     46//                   access functions
    2747///////////////////////////////////////////////////////////////////////////////////
    2848
    29 extern void _timer_start( unsigned int cluster_xy,
    30                           unsigned int local_id,
    31                           unsigned int period );
     49///////////////////////////////////////////////////////////////////////////////////
     50// This function activates a timer in the vci_timer external peripheral.
     51// - channel : Timer channel global index
     52// - period  : interrupt period (cycles)
     53///////////////////////////////////////////////////////////////////////////////////
     54extern int _timer_start( unsigned int channel,
     55                         unsigned int period );
    3256
    33 extern void _timer_stop( unsigned int cluster_xy,
    34                          unsigned int local_id );
     57///////////////////////////////////////////////////////////////////////////////////
     58// This function desactivates a timer in the vci_timer external component.
     59///////////////////////////////////////////////////////////////////////////////////
     60extern int _timer_stop( unsigned int channel );
    3561
    36 extern void _timer_reset_irq( unsigned int cluster_xy,
    37                               unsigned int local_id );
     62///////////////////////////////////////////////////////////////////////////////////
     63// This function resets the timer counter. To do so, it read the period,
     64// and re-write it in the timer register, what causes the count to restart.
     65///////////////////////////////////////////////////////////////////////////////////
     66extern int _timer_reset_cpt( unsigned int channel );
    3867
    39 extern void _timer_reset_cpt( unsigned int cluster_xy,
    40                               unsigned int local_id);
    41 
     68///////////////////////////////////////////////////////////////////////////////////
     69// This Interrupt Service Routine handles the IRQs generated by the "user" timers.
     70// It can be a HWI or a PTI.
     71// The channel argument is the user timer global index.
     72// The ISR acknowledges the IRQ, registers the event in the proper entry
     73// of the _user_timer_event[] array, and a log message is displayed on TTY0.
     74///////////////////////////////////////////////////////////////////////////////////
    4275extern void _timer_isr( unsigned int irq_type,
    4376                        unsigned int irq_id,
    4477                        unsigned int channel );
    4578
    46 ///////////////////////////////////////////////////////////////////////////////////
    4779
    4880#endif
  • soft/giet_vm/giet_drivers/tty_driver.c

    r426 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The tty_driver.c and tty_drivers.h files are part ot the GIET-VM kernel.
    8 // This driver supports the SocLib vci_multi_tty component.
    9 //
    10 // The total number of TTY terminals must be defined by the configuration
    11 // parameter NB_TTY_CHANNELS in the hard_config.h file.
    12 //
    13 // The "system" terminal is TTY[0].
    14 // The "user" TTYs are allocated to applications by the GIET in the boot phase,
    15 // as defined in the mapping_info data structure. The corresponding tty_id must
    16 // be stored in the context of the task by the boot code.
    17 //
    18 // The SEG_TTY_BASE address must be defined in the hard_config.h file.
    19 ///////////////////////////////////////////////////////////////////////////////////
    20 // Implementation note:
    21 //
    22 // All physical accesses to device registers are done by the two
    23 // _tty_get_register(), _tty_set_register() low-level functions,
    24 // that are handling virtual / physical addressing.
    25 ///////////////////////////////////////////////////////////////////////////////////
    267
    278#include <giet_config.h>
     9#include <hard_config.h>
    2810#include <tty_driver.h>
    2911#include <xcu_driver.h>
     
    4830
    4931//////////////////////////////////////////////////////////////////////////////
    50 //   TTY global variables
     32//               global variables
    5133//////////////////////////////////////////////////////////////////////////////
    5234
     
    6547
    6648//////////////////////////////////////////////////////////////////////////////
    67 // This low level function returns the value of register (channel / index)
     49//               access functions
    6850//////////////////////////////////////////////////////////////////////////////
     51
     52/////////////////////////////////////////////////////
    6953unsigned int _tty_get_register( unsigned int channel,
    7054                                unsigned int index )
     
    7458}
    7559
    76 //////////////////////////////////////////////////////////////////////////////
    77 // This low level function set a new value in register (channel / index) 
    78 //////////////////////////////////////////////////////////////////////////////
     60/////////////////////////////////////////////
    7961void _tty_set_register( unsigned int channel,
    8062                        unsigned int index,
     
    8567}
    8668
    87 /////////////////////////////////////////////////////////////////////////////////
    88 // This non-blocking function writes a character string from a fixed-length
    89 // buffer to a TTY terminal identified by the channel argument.
    90 // This function is intended to be used to handle a system call, and should
    91 // not be used by the kernel for log messages on TTY 0.
    92 // protecting exclusive access to the selected terminal.
    93 // If channel argument is 0xFFFFFFFF, the TTY index is found in the task context.
    94 // This is a non blocking call: it tests the TTY_STATUS register, and stops
    95 // the transfer as soon as the TTY_STATUS[WRITE] bit is set.
    96 /////////////////////////////////////////////////////////////////////////////////
    97 // Returns  the number of characters that have been written.
    98 /////////////////////////////////////////////////////////////////////////////////
    99 unsigned int _tty_write( const char*  buffer,   
    100                          unsigned int length,    // number of characters
    101                          unsigned int channel)   // channel index
    102 {
    103     unsigned int  nwritten;
    10469
    105     // compute and check tty channel
    106     if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
    107     if( channel >= NB_TTY_CHANNELS ) return -1;
    108 
    109     // write string to TTY channel
    110     for (nwritten = 0; nwritten < length; nwritten++)
    111     {
    112         // check tty's status
    113         if ( _tty_get_register( channel, TTY_STATUS ) & 0x2 )  break;
    114 
    115         // write one byte
    116         if (buffer[nwritten] == '\n') {
    117             _tty_set_register( channel, TTY_WRITE, (unsigned int)'\r' );
    118         }
    119         _tty_set_register( channel, TTY_WRITE, (unsigned int)buffer[nwritten] );
    120     }
    121    
    122     return nwritten;
    123 }
    124 
    125 //////////////////////////////////////////////////////////////////////////////
    126 // This non-blocking function fetches one character from the
    127 // terminal identified by the channel argument. If the channel argument
    128 // is 0xFFFFFFFF, the channel index is obtained from the current task context.
    129 // It uses the TTY_GET_IRQ[tty_id] interrupt and the buffer must have been
    130 // filled by the TTY_ISR.
    131 // It test the _tty_rx_full[tty_id] variable, read the _tty_rx_buf[tty_id]
    132 // buffer, writes this character to the target buffer, and resets the
    133 // _tty_rx_full[tty_id] register.
    134 // The length argument is not used.
    135 //////////////////////////////////////////////////////////////////////////////
    136 // Returns  the number of characters that have been read (0/1).
    137 //////////////////////////////////////////////////////////////////////////////
    138 unsigned int _tty_read( char*        buffer,
    139                         unsigned int length,    // unused
    140                         unsigned int channel)   // channel index
    141 {
    142     // compute and check tty channel
    143     if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
    144     if( channel >= NB_TTY_CHANNELS ) return -1;
    145 
    146     // read one character from TTY channel
    147     if (_tty_rx_full[channel] == 0)
    148     {
    149         return 0;
    150     }
    151     else
    152     {
    153         *buffer = _tty_rx_buf[channel];
    154         _tty_rx_full[channel] = 0;
    155         return 1;
    156     }
    157 }
    158 
    159 //////////////////////////////////////////////////////////////////////////////
    160 // This function try to take the lock protecting
    161 // exclusive access to TTY terminal identified by the "channel" argument.
    162 // It enters a critical section before taking the lock, and save the SR value
    163 // at address defined by the "save_sr_ptr" argument.
    164 // It returns only when the lock has been successfully taken.
    165 //////////////////////////////////////////////////////////////////////////////
    166 void _tty_get_lock( unsigned int   channel,
    167                     unsigned int * save_sr_ptr )
    168 {
    169     if( channel >= NB_TTY_CHANNELS ) _exit();
    170     _it_disable( save_sr_ptr );
    171     _get_lock( &_tty_lock[channel] );
    172 }
    173 
    174 //////////////////////////////////////////////////////////////////////////////
    175 // This function releases the hardwired lock protecting
    176 // exclusive access to TTY terminal identified by the channel argument.
    177 // It exit the critical section after lock release, and restore SR value
    178 // from address defined by the "save_sr_ptr" argument.
    179 //////////////////////////////////////////////////////////////////////////////
    180 void _tty_release_lock( unsigned int   channel,
    181                         unsigned int * save_sr_ptr )
    182 {
    183     if( channel >= NB_TTY_CHANNELS ) _exit();
    184     _release_lock( &_tty_lock[channel] );
    185     _it_restore( save_sr_ptr );
    186 }
    187 
    188 ///////////////////////////////////////////////////////////////////////////////////
    189 // This ISR handles the IRQ signaling that the RX buffer is not empty.
    190 // IT can be an HWI or an SWI.
    191 // There is one communication buffer _tty_rx_buf[i] and one synchronisation
    192 // variable _tty_rx_full[i] per channel.
    193 // Does nothing if the TTY_RX buffer is empty, or if the kernel buffer is full
    194 // when the ISR is called.
    195 ///////////////////////////////////////////////////////////////////////////////////
     70////////////////////////////////////////
    19671void _tty_rx_isr( unsigned int irq_type,   // HWI / WTI
    19772                  unsigned int irq_id,     // index returned by XCU
     
    242117}
    243118
    244 ///////////////////////////////////////////////////////////////////////////////////
    245 // This ISR handles the IRQ signaling that the TX buffer is empty.
    246 // IT can be an HWI or an SWI.
    247 // There is one single multi_tty component controling all channels.
    248 // There is one communication buffer _tty_rx_buf[i] and one synchronisation
    249 // variable _tty_rx_full[i] per channel.
    250 // A character is lost if the buffer is full when the ISR is executed.
    251 ///////////////////////////////////////////////////////////////////////////////////
     119/////////////////////////////////////////
    252120void _tty_tx_isr( unsigned int irq_type,   // HWI / WTI
    253121                  unsigned int irq_id,     // index returned by XCU
  • soft/giet_vm/giet_drivers/tty_driver.h

    r350 r437  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7// The tty_driver.c and tty_drivers.h files are part ot the GIET-VM kernel.
     8// This driver supports the SocLib vci_multi_tty component.
     9//
     10// The total number of TTY terminals must be defined by the configuration
     11// parameter NB_TTY_CHANNELS in the hard_config.h file.
     12//
     13// The "system" terminal is TTY[0].
     14// The "user" TTYs are allocated to applications requesting it.
     15//
     16// The SEG_TTY_BASE address must be defined in the hard_config.h file.
     17//
     18// All physical accesses to device registers are done by the two
     19// _tty_get_register(), _tty_set_register() low-level functions,
     20// that are handling virtual / physical addressing.
     21///////////////////////////////////////////////////////////////////////////////////
    722
    823#ifndef _GIET_TTY_DRIVERS_H_
    924#define _GIET_TTY_DRIVERS_H_
    1025
    11 #include "utils.h"
     26#include <utils.h>
    1227
    1328///////////////////////////////////////////////////////////////////////////////////
    14 // TTY (vci_multi_tty) registers offsets
     29//                     registers offsets
    1530///////////////////////////////////////////////////////////////////////////////////
    1631
     
    2641
    2742///////////////////////////////////////////////////////////////////////////////////
    28 // TTY variables
     43//                   external variables
    2944///////////////////////////////////////////////////////////////////////////////////
    3045
     
    3651
    3752//////////////////////////////////////////////////////////////////////////////////
    38 // TTY access functions
     53//                   access functions
    3954//////////////////////////////////////////////////////////////////////////////////
    4055
    41 extern unsigned int _tty_write( const char*  buffer,
    42                                 unsigned int length,     
    43                                 unsigned int channel ); 
     56extern unsigned int _tty_get_register( unsigned int channel,
     57                                       unsigned int index );
    4458
    45 extern unsigned int _tty_read(  char*        buffer,
    46                                 unsigned int length, 
    47                                 unsigned int channel );
     59extern void _tty_set_register( unsigned int channel,
     60                               unsigned int index,
     61                               unsigned int value );
    4862
    49 extern void _tty_get_lock( unsigned int  channel,
    50                            unsigned int* save_sr_ptr );
    51 
    52 extern void _tty_release_lock( unsigned int  channel,
    53                                unsigned int* save_sr_ptr );
     63///////////////////////////////////////////////////////////////////////////////////
     64//                 Interrupt Service Routine
     65///////////////////////////////////////////////////////////////////////////////////
    5466
    5567extern void _tty_rx_isr( unsigned int irq_type,
     
    6173                         unsigned int channel );
    6274
    63 ///////////////////////////////////////////////////////////////////////////////////
    64 // low-level access functions
    65 ///////////////////////////////////////////////////////////////////////////////////
    66 
    67 extern unsigned int _tty_get_register( unsigned int channel,
    68                                        unsigned int index );
    69 
    70 extern void _tty_set_register( unsigned int channel,
    71                                unsigned int index,
    72                                unsigned int value );
    7375
    7476#endif
  • soft/giet_vm/giet_drivers/xcu_driver.c

    r395 r437  
    44// Author   : alain greiner
    55// Copyright (c) UPMC-LIP6
    6 ///////////////////////////////////////////////////////////////////////////////////
    7 // This peripheral is replicated in all clusters containing processors.
    8 //
    9 // SEG_XCU_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h file.
    106///////////////////////////////////////////////////////////////////////////////////
    117
     
    8581}
    8682
    87 ////////////////////////////////////////////////////////////////////////////////
    88 // This function set the mask register for the IRQ type defined by "irq_type",
    89 // and for the channel identified by the "cluster_xy" and "channel" arguments.
    90 // All '1' bits are set / all '0' bits are not modified.
    91 ////////////////////////////////////////////////////////////////////////////////
     83////////////////////////////////////////////
    9284void _xcu_set_mask( unsigned int cluster_xy,
    9385                    unsigned int channel, 
     
    109101    else
    110102    {
    111         _printf("[GIET ERROR] _xcu_set_mask() receives illegal IRQ type\n");
     103        _puts("[GIET ERROR] _xcu_set_mask() receives illegal IRQ type\n");
    112104        _exit();
    113105    }
     
    116108
    117109#else
    118     _printf("[GIET ERROR] _xcu_set_mask() should not be used if USE_XCU not set\n");
    119     _exit();
    120 #endif
    121 }
    122 
    123 ////////////////////////////////////////////////////////////////////////////////
    124 // This function returns the index and the type of the highest priority
    125 // - active PTI (Timer Interrupt), then
    126 // - active HWI (Hardware Interrupt), then
    127 // - active WTI (Software Interrupt)
    128 // As the hardware can define more than one IRQ per processor, but the GIET
    129 // use only one, channel = lpid * IRQ_PER_PROCESSOR.
    130 ////////////////////////////////////////////////////////////////////////////////
     110    _puts("[GIET ERROR] _xcu_set_mask() should not be used if USE_XCU not set\n");
     111    _exit();
     112#endif
     113}
     114
     115/////////////////////////////////////////////
    131116void _xcu_get_index( unsigned int cluster_xy,
    132117                     unsigned int channel,   
     
    170155 
    171156#else
    172     _printf("[GIET ERROR] _xcu_get_index should not be used if USE_XCU is not set\n");
    173     _exit();
    174 #endif
    175 }
    176 
    177 ////////////////////////////////////////////////////////////////////////////////
    178 // This function writes the "wdata" value in the mailbox defined
    179 // by the "cluster_xy" and "wti_index" arguments.
    180 ////////////////////////////////////////////////////////////////////////////////
     157    _puts("[GIET ERROR] _xcu_get_index should not be used if USE_XCU is not set\n");
     158    _exit();
     159#endif
     160}
     161
     162////////////////////////////////////////////
    181163void _xcu_send_wti( unsigned int cluster_xy,
    182164                    unsigned int wti_index,
     
    194176
    195177#else
    196     _printf("[GIET ERROR] _xcu_send_wti() should not be used if USE_XCU is not set\n");
     178    _puts("[GIET ERROR] _xcu_send_wti() should not be used if USE_XCU is not set\n");
    197179    _exit();
    198180#endif
    199181}
    200182
    201 ////////////////////////////////////////////////////////////////////////////////
    202 // This function returns the value contained in a WTI mailbox defined by
    203 // the cluster_xy and "wti_index" arguments. This value is written in
    204 // the "value" argument, and the corresponding WTI is acknowledged.
    205 // returns 0 if success, > 0 if error.
    206 ////////////////////////////////////////////////////////////////////////////////
     183///////////////////////////////////////////////////
    207184void _xcu_get_wti_value( unsigned int   cluster_xy,
    208185                         unsigned int   wti_index,
     
    220197
    221198#else
    222     _printf("[GIET ERROR] in _xcu_get_wti_value() USE_XCU is not set\n");
    223     _exit();
    224 #endif
    225 }
    226 
    227 ////////////////////////////////////////////////////////////////////////////////
    228 // This function returns the address of a WTI mailbox defined by
    229 // the "wti_index" argument, in the unsigned int "address" argument.
    230 // It is used by the GIET to configurate the IOPIC component.
    231 // There is no access to a specific XCU component in a specific cluster.
    232 // returns 0 if success, > 0 if error.
    233 ////////////////////////////////////////////////////////////////////////////////
     199    _puts("[GIET ERROR] in _xcu_get_wti_value() USE_XCU is not set\n");
     200    _exit();
     201#endif
     202}
     203
     204////////////////////////////////////////////////////
    234205void _xcu_get_wti_address( unsigned int   wti_index,
    235206                           unsigned int * address )
     
    241212
    242213#else
    243     _printf("[GIET ERROR] in _xcu_get_wti_address() USE_XCU is not set\n");
    244     _exit();
    245 #endif
    246 }
    247 
    248 ////////////////////////////////////////////////////////////////////////////////
    249 // This function activates a timer contained in XCU by writing in the
    250 // proper register the period value.
    251 ////////////////////////////////////////////////////////////////////////////////
     214    _puts("[GIET ERROR] in _xcu_get_wti_address() USE_XCU is not set\n");
     215    _exit();
     216#endif
     217}
     218
     219///////////////////////////////////////////////
    252220void _xcu_timer_start( unsigned int cluster_xy,
    253221                       unsigned int pti_index,
     
    264232
    265233#else
    266     _printf("[GIET ERROR] in _xcu_timer_start() USE_XCU is not set\n");
    267     _exit();
    268 #endif
    269 }
    270 
    271 //////////////////////////////////////////////////////////////////////////////
    272 // This function desactivates a timer in XCU component
    273 // by writing in the proper register.
    274 //////////////////////////////////////////////////////////////////////////////
     234    _puts("[GIET ERROR] in _xcu_timer_start() USE_XCU is not set\n");
     235    _exit();
     236#endif
     237}
     238
     239//////////////////////////////////////////////
    275240void _xcu_timer_stop( unsigned int cluster_xy,
    276241                      unsigned int pti_index)
     
    286251
    287252#else
    288     _printf("[GIET ERROR] in _xcu_timer_stop() USE_XCU is not set\n");
    289     _exit();
    290 #endif
    291 }
    292 
    293 //////////////////////////////////////////////////////////////////////////////
    294 // This function acknowlegge a timer interrupt in XCU
    295 // component by reading in the proper XCU register.
    296 // It can be used by both the isr_switch() for a "system" timer,
    297 // or by the _isr_timer() for an "user" timer.
    298 //////////////////////////////////////////////////////////////////////////////
     253    _puts("[GIET ERROR] in _xcu_timer_stop() USE_XCU is not set\n");
     254    _exit();
     255#endif
     256}
     257
     258///////////////////////////////////////////////////////////
    299259unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy,
    300260                                   unsigned int pti_index )
     
    311271
    312272#else
    313     _printf("[GIET ERROR] in _xcu_timer_reset_irq() USE_XCU is not set\n");
     273    _puts("[GIET ERROR] in _xcu_timer_reset_irq() USE_XCU is not set\n");
    314274    _exit();
    315275    return 0;
     
    317277}
    318278
    319 //////////////////////////////////////////////////////////////////////////////
    320 // This function resets a timer counter. To do so, we re-write the period
    321 // in the proper register, what causes the count to restart.
    322 // The period value is read from the same (TIMER_PERIOD) register,
    323 // this is why in appearance we do nothing useful (read a value
    324 // from a register and write this value in the same register).
    325 // This function is called during a context switch (user or preemptive)
    326 /////////////////////////////////////////////////////////////////////////////
     279///////////////////////////////////////////////////
    327280void _xcu_timer_reset_cpt( unsigned int cluster_xy,
    328281                           unsigned int pti_index )
     
    343296
    344297#else
    345     _printf("[GIET ERROR] in _xcu_timer_reset_cpt() USE_XCU is not set\n");
     298    _puts("[GIET ERROR] in _xcu_timer_reset_cpt() USE_XCU is not set\n");
    346299    _exit();
    347300#endif
  • soft/giet_vm/giet_drivers/xcu_driver.h

    r320 r437  
    77// The xcu_driver.c and xcu_driver.h files are part ot the GIET-VM nano-kernel.
    88// This driver supports the SoCLib vci_xicu, that is a vectorised interrupt
    9 // controler supporting IPI (Inter Processor Interrupts) and integrated timers.
     9// controler supporting three types of interrupts:
     10//
     11// - HWI : HardWare Interrupts (from hardware peripherals)
     12// - PTI : Programmable Timer Interrupts (contained in the XCU component)
     13// - WTI : Write Trigered Interrupts (from software, or from a PIC controller)
    1014//
    1115// It can exist several interrupt controller unit in the architecture
    12 // (one per cluster), and each one can contain several channels.
     16// (one per cluster), and each one can contain several channels:
    1317// The number of XICU channels is equal to NB_PROCS_MAX, because there is
    1418// one private XICU channel per processor in a cluster.
    15 ////////////////////////////////////////////////////////////////////////////////
     19//
    1620// The virtual base address of the segment associated to the component is:
    1721//
    18 //      seg_xcu_base + cluster_xy * vseg_cluster_increment
     22//      vbase = SEG_XCU_BASE + cluster_xy * PERI_CLUSTER_INCREMENT
    1923//
    20 // The seg_xcu_base and vseg_cluster_increment values must be defined
    21 // in giet_vsegs.ld file.
     24// The SEG_XCU_BSE  and PERI_CLUSTER_INCREMENT values must be defined
     25// in the hard_config.h file.
    2226////////////////////////////////////////////////////////////////////////////////
    2327
     
    5660#define XCU_REG(func, index) (((func)<<5)|(index))
    5761 
    58 ///////////////////////////////////////////////////////////////////////////////////
    59 // XICU access functions
    60 ///////////////////////////////////////////////////////////////////////////////////
     62////////////////////////////////////////////////////////////////////////////////
     63//                           access functions
     64////////////////////////////////////////////////////////////////////////////////
    6165
     66////////////////////////////////////////////////////////////////////////////////
     67// This function set the mask register for the IRQ type defined by "irq_type",
     68// and for the channel identified by the "cluster_xy" and "channel" arguments.
     69// All '1' bits are set / all '0' bits are not modified.
     70////////////////////////////////////////////////////////////////////////////////
    6271extern void _xcu_set_mask( unsigned int cluster_xy,
    6372                           unsigned int channel, 
     
    6574                           unsigned int irq_type );
    6675
     76////////////////////////////////////////////////////////////////////////////////
     77// This function returns the index and the type of the highest priority
     78// - active PTI (Timer Interrupt), then
     79// - active HWI (Hardware Interrupt), then
     80// - active WTI (Software Interrupt)
     81////////////////////////////////////////////////////////////////////////////////
    6782extern void _xcu_get_index( unsigned int   cluster_xy,
    6883                            unsigned int   channel,   
     
    7085                            unsigned int * irq_type );
    7186
     87////////////////////////////////////////////////////////////////////////////////
     88// This function writes the "wdata" value in the mailbox defined
     89// by the "cluster_xy" and "wti_index" arguments.
     90////////////////////////////////////////////////////////////////////////////////
    7291extern void _xcu_send_wti( unsigned int cluster_xy,
    7392                           unsigned int wti_index,
    7493                           unsigned int wdata );
    7594
     95////////////////////////////////////////////////////////////////////////////////
     96// This function returns the value contained in a WTI mailbox defined by
     97// the cluster_xy and "wti_index" arguments. This value is written in
     98// the "value" argument, and the corresponding WTI is acknowledged.
     99////////////////////////////////////////////////////////////////////////////////
    76100extern void _xcu_get_wti_value( unsigned int   cluster_xy,
    77101                                unsigned int   wti_index,
    78102                                unsigned int * value );
    79103
     104////////////////////////////////////////////////////////////////////////////////
     105// This function returns the address of a WTI mailbox defined by
     106// the "wti_index" argument, in the unsigned int "address" argument.
     107// It is used by the GIET to configurate the IOPIC component.
     108// There is no access to a specific XCU component in a specific cluster.
     109////////////////////////////////////////////////////////////////////////////////
    80110extern void _xcu_get_wti_address( unsigned int   wti_index,
    81111                                  unsigned int * address );
    82112
     113////////////////////////////////////////////////////////////////////////////////
     114// This function activates a timer contained in XCU by writing in the
     115// proper register the period value.
     116////////////////////////////////////////////////////////////////////////////////
    83117extern void _xcu_timer_start( unsigned int cluster_xy,
    84118                              unsigned int pti_index,
    85119                              unsigned int period );
    86120
     121//////////////////////////////////////////////////////////////////////////////
     122// This function desactivates a timer in XCU component
     123// by writing in the proper register.
     124//////////////////////////////////////////////////////////////////////////////
    87125extern void _xcu_timer_stop( unsigned int cluster_xy,
    88126                             unsigned int pti_index );
    89127
     128//////////////////////////////////////////////////////////////////////////////
     129// This function acknowlegge a timer interrupt in XCU
     130// component by reading in the proper XCU register.
     131// It can be used by both the isr_switch() for a "system" timer,
     132// or by the _isr_timer() for an "user" timer.
     133//////////////////////////////////////////////////////////////////////////////
    90134extern unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy,
    91135                                          unsigned int pti_index );
    92136
     137//////////////////////////////////////////////////////////////////////////////
     138// This function resets a timer counter. To do so, we re-write the period
     139// in the proper register, what causes the count to restart.
     140// The period value is read from the same (TIMER_PERIOD) register,
     141// this is why in appearance we do nothing useful (read a value
     142// from a register and write this value in the same register).
     143// This function is called during a context switch (user or preemptive)
     144/////////////////////////////////////////////////////////////////////////////
    93145extern void _xcu_timer_reset_cpt( unsigned int cluster_xy,
    94146                                  unsigned int pti_index );
    95 
    96 ///////////////////////////////////////////////////////////////////////////////////
    97147
    98148#endif
Note: See TracChangeset for help on using the changeset viewer.