Ignore:
Timestamp:
Mar 26, 2014, 6:44:44 PM (10 years ago)
Author:
alain
Message:

Introducing a major release, to suppoort the tsar_generic_leti platform
and the various (external or internal) peripherals configurations.
The map.xml format has been modified, in order to support the new
vci_iopic componentand a new policy for peripherals initialisation.
The IRQs are nom described in the XICU and IOPIC components
(and not anymore in the processors).
To enforce this major change, the map.xml file signature changed:
The signature value must be: 0xDACE2014

This new release has been tested on the tsar_generic_leti platform
for the following mappings:

  • 4c_4p_sort_leti
  • 4c_4p_sort_leti_ext
  • 4c_4p_transpose_leti
  • 4c_4p_transpose_leti_ext
  • 4c_1p_four_leti_ext
File:
1 edited

Legend:

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

    r258 r295  
    88// This driver supports the SocLib vci_multi_tty component.
    99//
    10 // It can exist only one multi_tty controler in the architecture.
    11 //
    1210// The total number of TTY terminals must be defined by the configuration
    1311// parameter NB_TTY_CHANNELS in the hard_config.h file.
    14 //
    15 // The register offsets must be defined in the hwr_mapping.h file.
    1612//
    1713// The "system" terminal is TTY[0].
     
    1915// as defined in the mapping_info data structure. The corresponding tty_id must
    2016// be stored in the context of the task by the boot code.
    21 ///////////////////////////////////////////////////////////////////////////////////
    22 // The virtual base address of the segment associated to a channel is:
    2317//
    24 //                  seg_tty_base  + TTY_SPAN * channel_id
    25 //
    26 // The seg_tty_base virtual base addresses must be defined in giet_vsegs.ld file.
     18// The seg_tty_base must be defined in giet_vsegs.ld 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.
    2725///////////////////////////////////////////////////////////////////////////////////
    2826
    2927#include <giet_config.h>
    3028#include <tty_driver.h>
     29#include <xcu_driver.h>
    3130#include <ctx_handler.h>
    3231#include <utils.h>
     
    4241#define in_unckdata __attribute__((section (".unckdata")))
    4342
    44 /////////////////   TTY global variables
    45 in_unckdata volatile unsigned char _tty_get_buf[NB_TTY_CHANNELS];
    46 in_unckdata volatile unsigned char _tty_get_full[NB_TTY_CHANNELS]
     43//////////////////////////////////////////////////////////////////////////////
     44//   TTY global variables
     45//////////////////////////////////////////////////////////////////////////////
     46
     47in_unckdata volatile unsigned int _tty_rx_buf[NB_TTY_CHANNELS];
     48in_unckdata volatile unsigned int _tty_rx_full[NB_TTY_CHANNELS]
    4749                                     = { [0 ... NB_TTY_CHANNELS - 1] = 0 };
     50
     51//////////////////////////////////////////////////////////////////////////////
     52// This low level function returns the value of register (channel / index)
     53//////////////////////////////////////////////////////////////////////////////
     54unsigned int _tty_get_register( unsigned int channel,
     55                                unsigned int index )
     56{
     57    unsigned int* vaddr = (unsigned int*)&seg_tty_base + channel*TTY_SPAN + index;
     58    return _io_extended_read( vaddr );
     59}
     60
     61//////////////////////////////////////////////////////////////////////////////
     62// This low level function set a new value in register (channel / index) 
     63//////////////////////////////////////////////////////////////////////////////
     64void _tty_set_register( unsigned int channel,
     65                        unsigned int index,
     66                        unsigned int value )
     67{
     68    unsigned int* vaddr = (unsigned int*)&seg_tty_base + channel*TTY_SPAN + index;
     69    _io_extended_write( vaddr, value );
     70}
    4871
    4972/////////////////////////////////////////////////////////////////////////////////
    5073// This non-blocking function writes a character string from a fixed-length
    51 // buffer to the TTY_WRITE register of a TTY terminal identified by the
    52 // channel argument. If the channel argument is 0xFFFFFFFF, the channel
    53 // index is obtained from the current taxk context.
    54 // It doesn't use any interrupt.
     74// buffer to a TTY terminal identified by the channel argument.
     75// This function is intended to be used to handle a system call, and should
     76// not be used by the kernel for log messages on TTY 0.
     77// protecting exclusive access to the selected terminal.
     78// If channel argument is 0xFFFFFFFF, the TTY index is found in the task context.
    5579// This is a non blocking call: it tests the TTY_STATUS register, and stops
    5680// the transfer as soon as the TTY_STATUS[WRITE] bit is set.
     
    6286                         unsigned int channel)   // channel index
    6387{
    64     unsigned int nwritten;
    65     unsigned int tty_id;
    66     unsigned int* tty_address = (unsigned int *) &seg_tty_base;
    67 
    68     // compute tty channel
    69     if( channel == 0xFFFFFFFF )
    70     {
    71         tty_id = _get_context_slot(CTX_TTY_ID);
    72     }
    73     else
    74     {
    75         tty_id = (unsigned int)channel;
    76     }
     88    unsigned int  nwritten;
     89
     90    // compute and check tty channel
     91    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
     92    if( channel >= NB_TTY_CHANNELS ) return -1;
    7793
    7894    // write string to TTY channel
     
    8096    {
    8197        // check tty's status
    82         if ((tty_address[tty_id * TTY_SPAN + TTY_STATUS] & 0x2) == 0x2) break;
    83         _tty_write_data( tty_id, buffer[nwritten] );
    84     }
     98        if ( _tty_get_register( channel, TTY_STATUS ) & 0x2 )  break;
     99
     100        // write one byte
     101        _tty_set_register( channel, TTY_WRITE, (unsigned int)buffer[nwritten] );
     102    }
     103   
    85104    return nwritten;
    86105}
     
    92111// It uses the TTY_GET_IRQ[tty_id] interrupt and the buffer must have been
    93112// filled by the TTY_ISR.
    94 // It test the _tty_get_full[tty_id] register, read the _tty_get_buf[tty_id]
     113// It test the _tty_rx_full[tty_id] variable, read the _tty_rx_buf[tty_id]
    95114// buffer, writes this character to the target buffer, and resets the
    96 // _tty_get_full[tty_id] register.
     115// _tty_rx_full[tty_id] register.
    97116// The length argument is not used.
    98117//////////////////////////////////////////////////////////////////////////////
     
    103122                        unsigned int channel)   // channel index
    104123{
    105    
    106     unsigned int tty_id;
    107 
    108     // compute tty channel
    109     if( channel == 0xFFFFFFFF )
    110     {
    111         tty_id = _get_context_slot(CTX_TTY_ID);
    112     }
    113     else
    114     {
    115         tty_id = (unsigned int)channel;
    116     }
     124    // compute and check tty channel
     125    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
     126    if( channel >= NB_TTY_CHANNELS ) return -1;
    117127
    118128    // read one character from TTY channel
    119     if (_tty_get_full[tty_id] == 0)
     129    if (_tty_rx_full[channel] == 0)
    120130    {
    121131        return 0;
     
    123133    else
    124134    {
    125         *buffer = _tty_get_buf[tty_id];
    126         _tty_get_full[tty_id] = 0;
     135        *buffer = _tty_rx_buf[channel];
     136        _tty_rx_full[channel] = 0;
    127137        return 1;
    128138    }
    129139}
    130 //////////////////////////////////////////////////////////////////////////////
    131 
    132 //////////////////////////////////////////////////////////////////////////////
    133 // This function try to take the hardwired lock protecting exclusive access
    134 // to TTY terminal identified by the channel argument.
     140
     141//////////////////////////////////////////////////////////////////////////////
     142// This function try to take the hardwired lock protecting
     143// exclusive access to TTY terminal identified by the "channel" argument.
     144// It enters a critical section before taking the lock, and save the SR value
     145// at address defined by the "save_sr_ptr" argument.
    135146// It returns only when the lock has been successfully taken.
    136147//////////////////////////////////////////////////////////////////////////////
    137 void _tty_get_lock( unsigned int channel )
    138 {
    139     unsigned int* tty_address = (unsigned int *) &seg_tty_base;
    140 
    141     if( channel >= NB_TTY_CHANNELS )
    142     {
    143         _puts("[GIET ERROR] in _tty_get_lock() : illegal TTY index\n");
    144         _exit();       
    145     }
    146 
    147     while ( tty_address[channel * TTY_SPAN + TTY_CONFIG] );
    148 }
    149 
    150 //////////////////////////////////////////////////////////////////////////////
    151 // This function releases the hardwired lock protecting exclusive access
    152 // to TTY terminal identified by the channel argument.
    153 //////////////////////////////////////////////////////////////////////////////
    154 void _tty_release_lock( unsigned int channel )
    155 {
    156     unsigned int* tty_address = (unsigned int *) &seg_tty_base;
    157 
    158     if( channel >= NB_TTY_CHANNELS )
    159     {
    160         _puts("[GIET ERROR] in _tty_release_lock() : illegal TTY index\n");
    161         _exit();       
    162     }
    163 
    164     tty_address[channel * TTY_SPAN + TTY_CONFIG] = 0;
    165 }
    166 
    167 //////////////////////////////////////////////////////////////////////////////
    168 // This function returns the content of the TTY_READ register in the
    169 // TTY terminal identified by the channel argument.
    170 //////////////////////////////////////////////////////////////////////////////
    171 unsigned int _tty_read_data( unsigned int channel )
    172 {
    173     unsigned int* tty_address = (unsigned int *) &seg_tty_base;
    174 
    175     if( channel >= NB_TTY_CHANNELS )
    176     {
    177         _puts("[GIET ERROR] in _tty_read_data() : illegal TTY index\n");
    178         _exit();       
    179     }
    180 
    181     return tty_address[channel * TTY_SPAN + TTY_READ];
    182 }
    183 
    184 //////////////////////////////////////////////////////////////////////////////
    185 // This function returns the content of the TTY_STATUS register in the
    186 // TTY terminal identified by the channel argument.
    187 //////////////////////////////////////////////////////////////////////////////
    188 unsigned int _tty_get_status( unsigned int channel )
    189 {
    190     unsigned int* tty_address = (unsigned int *) &seg_tty_base;
    191 
    192     if( channel >= NB_TTY_CHANNELS )
    193     {
    194         _puts("[GIET ERROR] in _tty_get_status() : illegal TTY index\n");
    195         _exit();       
    196     }
    197 
    198     return tty_address[channel * TTY_SPAN + TTY_STATUS];
    199 }
    200 
    201 //////////////////////////////////////////////////////////////////////////////
    202 // This function writes one character in the TTY_WRITE register in the
    203 // TTY terminal identified by the channel argument.
    204 //////////////////////////////////////////////////////////////////////////////
    205 void _tty_write_data( unsigned int channel,
    206                       char         byte )
    207 {
    208     unsigned int* tty_address = (unsigned int *) &seg_tty_base;
    209 
    210     if( channel >= NB_TTY_CHANNELS )
    211     {
    212         _puts("[GIET ERROR] in _tty_write_data() : illegal TTY index\n");
    213         _exit();       
    214     }
    215 
    216     tty_address[channel * TTY_SPAN + TTY_WRITE] = (unsigned int) byte;
    217 }
    218 
     148void _tty_get_lock( unsigned int   channel,
     149                    unsigned int * save_sr_ptr )
     150{
     151    if( channel >= NB_TTY_CHANNELS ) _exit();
     152    _it_disable( save_sr_ptr );
     153    while ( _tty_get_register( channel, TTY_CONFIG ) ); // busy waiting
     154}
     155
     156//////////////////////////////////////////////////////////////////////////////
     157// This function releases the hardwired lock protecting
     158// exclusive access to TTY terminal identified by the channel argument.
     159// It exit the critical section after lock release, and restore SR value
     160// from address defined by the "save_sr_ptr" argument.
     161//////////////////////////////////////////////////////////////////////////////
     162void _tty_release_lock( unsigned int   channel,
     163                        unsigned int * save_sr_ptr )
     164{
     165    if( channel >= NB_TTY_CHANNELS ) _exit();
     166
     167    _tty_set_register( channel, TTY_CONFIG, 0 );
     168    _it_restore( save_sr_ptr );
     169}
     170
     171///////////////////////////////////////////////////////////////////////////////////
     172// This ISR handles the IRQ signaling that the RX buffer is full.
     173// IT can be an HWI or an SWI.
     174// There is one single multi_tty component controling all channels.
     175// There is one communication buffer _tty_rx_buf[i] and one synchronisation
     176// variable _tty_rx_full[i] per channel.
     177// A character is lost if the buffer is full when the ISR is executed.
     178///////////////////////////////////////////////////////////////////////////////////
     179void _tty_rx_isr( unsigned int irq_type,   // HWI / WTI
     180                  unsigned int irq_id,     // index returned by XCU
     181                  unsigned int channel )   // TTY channel
     182{
     183    unsigned int cluster_xy = _get_procid() / NB_PROCS_MAX;
     184
     185    if ( irq_type == IRQ_TYPE_WTI )   // reset SWI in XCU if required
     186    {
     187        unsigned int value;
     188        _xcu_get_wti_value( cluster_xy, irq_id, &value );
     189    }
     190     
     191    // get character and reset TTY IRQ
     192    _tty_rx_buf[channel] = _tty_get_register( channel, TTY_READ );
     193
     194#if GIET_DEBUG_IRQS  // we don't take the TTY lock to avoid deadlock
     195unsigned int x              = cluster_xy >> Y_WIDTH;
     196unsigned int y              = cluster_xy & ((1<<Y_WIDTH)-1);
     197unsigned int lpid           = _get_procid() % NB_PROCS_MAX;
     198_puts("\n[IRQS DEBUG] Processor[");
     199_putd(x );
     200_puts(",");
     201_putd(y );
     202_puts(",");
     203_putd(lpid );
     204_puts("] enters _tty_rx_isr() at cycle ");
     205_putd(_get_proctime() );
     206_puts("\n  read byte = ");
     207_putx(_tty_rx_buf[channel] );
     208_puts("\n");
     209#endif
     210
     211    // signals character available
     212    _tty_rx_full[channel] = 1;
     213}
     214
     215///////////////////////////////////////////////////////////////////////////////////
     216// This ISR handles the IRQ signaling that the TX buffer is empty.
     217// IT can be an HWI or an SWI.
     218// There is one single multi_tty component controling all channels.
     219// There is one communication buffer _tty_rx_buf[i] and one synchronisation
     220// variable _tty_rx_full[i] per channel.
     221// A character is lost if the buffer is full when the ISR is executed.
     222///////////////////////////////////////////////////////////////////////////////////
     223void _tty_tx_isr( unsigned int irq_type,   // HWI / WTI
     224                  unsigned int irq_id,     // index returned by XCU
     225                  unsigned int channel )   // TTY channel
     226{
     227    _puts("\n[GIET ERROR] the _tty_tx_isr() is not implemented\n");
     228    _exit();
     229}
    219230
    220231// Local Variables:
Note: See TracChangeset for help on using the changeset viewer.