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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.