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/xcu_driver.c

    r281 r295  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The xcu_driver.c and xcu_driver.h files are part ot the GIET-VM nano-kernel.
    8 // This driver supports the SoCLib vci_xicu, that is a vectorised interrupt
    9 // controler supporting IPI (Inter Processor Interrupts) and integrated timers.
    10 //
    11 // It can exist several interrupt controller unit in the architecture
    12 // (one per cluster), and each one can contain several channels.
    13 // The number of XICU channels is equal to NB_PROCS_MAX, because there is
    14 // one private XICU channel per processor in a cluster.
    15 ////////////////////////////////////////////////////////////////////////////////
    16 // The virtual base address of the segment associated to the component is:
    17 //
    18 //      seg_xcu_base + cluster_xy * vseg_cluster_increment
    19 //
    20 // The seg_xcu_base and vseg_cluster_increment values must be defined
    21 // in giet_vsegs.ld file.
    22 ////////////////////////////////////////////////////////////////////////////////
    237
    248#include <giet_config.h>
     
    5236#endif
    5337
    54 ////////////////////////////////////////////////////////////////////////////////
    55 //     _xcu_set_mask()
    56 // This function set the mask register for the XICU channel identified by the
    57 // cluster index and the processor index multiplied by the number of IRQ per
    58 // processor.
     38
     39////////////////////////////////////////////////////////////////////////////////
     40// This function set the mask register for the IRQ type defined by "irq_type",
     41// and for the channel identified by the "cluster_xy" and "channel" arguments.
    5942// All '1' bits are set / all '0' bits are not modified.
    60 // Returns 0 if success, > 0 if error.
    61 ////////////////////////////////////////////////////////////////////////////////
    62 unsigned int _xcu_set_mask( unsigned int cluster_xy,
    63                             unsigned int irq_index,
    64                             unsigned int value,
    65                             unsigned int irq_type )
    66 {
    67     // parameters checking
    68     unsigned int x = cluster_xy >> Y_WIDTH;
    69     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    70     if (x >= X_SIZE)                                     return 1;
    71     if (y >= Y_SIZE)                                     return 1;
    72     if (irq_index >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) return 1;
    73 
    74 #if USE_XICU
     43////////////////////////////////////////////////////////////////////////////////
     44void _xcu_set_mask( unsigned int cluster_xy,
     45                    unsigned int channel, 
     46                    unsigned int value,
     47                    unsigned int irq_type )
     48{
     49#if USE_XICU
     50    // parameters checking
     51    unsigned int x = cluster_xy >> Y_WIDTH;
     52    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     53    if (x >= X_SIZE)                                   _exit();
     54    if (y >= Y_SIZE)                                   _exit();
     55    if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit();
     56
    7557    volatile unsigned int* xcu_address =
    7658        (unsigned int *) ((unsigned int)&seg_xcu_base +
     
    7961    unsigned int func;
    8062    if      (irq_type == IRQ_TYPE_PTI) func = XICU_MSK_PTI_ENABLE;
    81     else if (irq_type == IRQ_TYPE_SWI) func = XICU_MSK_WTI_ENABLE;
    82     else                               func = XICU_MSK_HWI_ENABLE;
    83     xcu_address[XICU_REG(func,irq_index)] = value;
    84     return 0;
    85 #else
    86     _tty_get_lock( 0 );
    87     _puts("[GIET ERROR] _xcu_set_mask should not be used if USE_XICU is not set\n");
    88     _tty_release_lock( 0 );
    89     return 1;
    90 #endif
    91 }
    92 
    93 ////////////////////////////////////////////////////////////////////////////////
    94 //     _xcu_get_index()
    95 // This function returns the index of the highest priority (smaller index)
    96 // - active HWI (Hardware Interrupt), or
    97 // - active PTI (Timer Interrupt), or
    98 // - active SWI (Software Interrupt).
    99 // The ICU channel is identified by the cluster index and the processor index
    100 // multiplied by the number of IRQ per processor.
    101 // Returns 0 if success, > 0 if error.
    102 ////////////////////////////////////////////////////////////////////////////////
    103 unsigned int _xcu_get_index( unsigned int cluster_xy,
    104                              unsigned int irq_index,
    105                              unsigned int * buffer)
    106 {
    107     // parameters checking
    108     unsigned int x = cluster_xy >> Y_WIDTH;
    109     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    110     if (x >= X_SIZE)                                     return 1;
    111     if (y >= Y_SIZE)                                     return 1;
    112     if (irq_index >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) return 1;
    113 
    114 #if USE_XICU
    115     volatile unsigned int* xcu_address =
    116         (unsigned int *) ((unsigned int)&seg_xcu_base +
    117         (cluster_xy * (unsigned int)&vseg_cluster_increment));
    118 
    119     unsigned int prio = xcu_address[XICU_REG(XICU_PRIO,irq_index)];
     63    else if (irq_type == IRQ_TYPE_WTI) func = XICU_MSK_WTI_ENABLE;
     64    else if (irq_type == IRQ_TYPE_HWI) func = XICU_MSK_HWI_ENABLE;
     65    else
     66    {
     67        _printf("[GIET ERROR] _xcu_set_mask() receives illegal IRQ type\n");
     68        _exit();
     69    }
     70
     71    xcu_address[XICU_REG(func,channel)] = value;
     72
     73#else
     74    _printf("[GIET ERROR] _xcu_set_mask() should not be used if USE_XICU not set\n");
     75    _exit();
     76#endif
     77}
     78
     79////////////////////////////////////////////////////////////////////////////////
     80// This function returns the index and the type of the highest priority
     81// - active PTI (Timer Interrupt), then
     82// - active HWI (Hardware Interrupt), then
     83// - active WTI (Software Interrupt)
     84// As the hardware can define more than one IRQ per processor, but the GIET
     85// use only one, channel = lpid * IRQ_PER_PROCESSOR.
     86////////////////////////////////////////////////////////////////////////////////
     87void _xcu_get_index( unsigned int cluster_xy,
     88                     unsigned int channel,   
     89                     unsigned int * index,
     90                     unsigned int * irq_type )
     91{
     92#if USE_XICU
     93    // parameters checking
     94    unsigned int x = cluster_xy >> Y_WIDTH;
     95    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     96    if (x >= X_SIZE)                                   _exit();
     97    if (y >= Y_SIZE)                                   _exit();
     98    if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit();
     99
     100    volatile unsigned int* xcu_address =
     101        (unsigned int *) ((unsigned int)&seg_xcu_base +
     102        (cluster_xy * (unsigned int)&vseg_cluster_increment));
     103
     104    unsigned int prio = xcu_address[XICU_REG(XICU_PRIO,channel)];
    120105    unsigned int pti_ok = (prio & 0x00000001);
    121106    unsigned int hwi_ok = (prio & 0x00000002);
    122     unsigned int swi_ok = (prio & 0x00000004);
     107    unsigned int wti_ok = (prio & 0x00000004);
    123108    unsigned int pti_id = (prio & 0x00001F00) >> 8;
    124109    unsigned int hwi_id = (prio & 0x001F0000) >> 16;
    125     unsigned int swi_id = (prio & 0x1F000000) >> 24;
    126     if      (pti_ok)  *buffer = pti_id;
    127     else if (hwi_ok)  *buffer = hwi_id;
    128     else if (swi_ok)  *buffer = swi_id;
    129     else              *buffer = 32;
    130     return 0;
    131 #else
    132     _tty_get_lock( 0 );
    133     _puts("[GIET ERROR] _xcu_get_index should not be used if USE_XICU is not set\n");
    134     _tty_release_lock( 0 );
    135     return 1;
    136 #endif
    137 }
    138 
    139 ////////////////////////////////////////////////////////////////////////////////
    140 //     _xcu_send_ipi()
    141 // This function can be used only in an architecture using  XICU components.
    142 // It writes the "wdata" value in the mailbox defined by the cluster index
    143 // and the processor index.
    144 // Giet-VM supports at most NB_PROCS_MAX mailboxes:
    145 // (0 <= wti_index <= NB_PROCS_MAX-1)
    146 // Returns 0 if success, > 0 if error.
    147 ////////////////////////////////////////////////////////////////////////////////
    148 unsigned int _xcu_send_ipi( unsigned int cluster_xy,
    149                             unsigned int wti_index,
    150                             unsigned int wdata )
     110    unsigned int wti_id = (prio & 0x1F000000) >> 24;
     111    if      (pti_ok)
     112    {
     113        *index    = pti_id;
     114        *irq_type = IRQ_TYPE_PTI;
     115    }
     116    else if (hwi_ok)
     117    {
     118        *index    = hwi_id;
     119        *irq_type = IRQ_TYPE_HWI;
     120    }
     121    else if (wti_ok)
     122    {
     123        *index    = wti_id;
     124        *irq_type = IRQ_TYPE_WTI;
     125    }
     126    else
     127    {
     128        *index = 32;
     129    }
     130 
     131#else
     132    _printf("[GIET ERROR] _xcu_get_index should not be used if USE_XICU is not set\n");
     133    _exit();
     134#endif
     135}
     136
     137////////////////////////////////////////////////////////////////////////////////
     138// This function writes the "wdata" value in the mailbox defined
     139// by the "cluster_xy" and "wti_index" arguments.
     140////////////////////////////////////////////////////////////////////////////////
     141void _xcu_send_wti( unsigned int cluster_xy,
     142                    unsigned int wti_index,
     143                    unsigned int wdata )
    151144{
    152     // parameters checking
    153     unsigned int x = cluster_xy >> Y_WIDTH;
    154     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    155     if (x >= X_SIZE)               return 1;
    156     if (y >= Y_SIZE)               return 1;
    157     if (wti_index >= NB_PROCS_MAX) return 1;
    158 
    159 #if USE_XICU
     145#if USE_XICU
     146    // parameters checking
     147    unsigned int x = cluster_xy >> Y_WIDTH;
     148    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     149    if (x >= X_SIZE)               _exit();
     150    if (y >= Y_SIZE)               _exit();
     151    if (wti_index >= 32)           _exit();
     152
    160153    volatile unsigned int* xcu_address =
    161154        (unsigned int *) ((unsigned int)&seg_xcu_base +
     
    163156
    164157    xcu_address[XICU_REG(XICU_WTI_REG,wti_index)] = wdata;
    165     return 0;
    166 #else
    167     _tty_get_lock( 0 );
    168     _puts("[GIET ERROR] _xcu_send_ipi should not be used if USE_XICU is not set\n");
    169     _tty_release_lock( 0 );
    170     return 1;
     158
     159#else
     160    _printf("[GIET ERROR] _xcu_send_ipi should not be used if USE_XICU is not set\n");
     161    _exit();
    171162#endif
    172163}
    173164
    174165////////////////////////////////////////////////////////////////////////////////
    175 //    _xcu_timer_start()
     166// This function returns the value contained in a WTI mailbox defined by
     167// the cluster_xy and "wti_index" arguments. This value is written in
     168// the "value" argument, and the corresponding WTI is acknowledged.
     169// returns 0 if success, > 0 if error.
     170////////////////////////////////////////////////////////////////////////////////
     171void _xcu_get_wti_value( unsigned int   cluster_xy,
     172                         unsigned int   wti_index,
     173                         unsigned int * value )
     174{
     175#if USE_XICU
     176    // parameters checking
     177    unsigned int x = cluster_xy >> Y_WIDTH;
     178    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     179    if (x >= X_SIZE)               _exit();
     180    if (y >= Y_SIZE)               _exit();
     181    if (wti_index >= 32)           _exit();
     182 
     183    volatile unsigned int* xcu_address =
     184        (unsigned int *) ((unsigned int)&seg_xcu_base +
     185        (cluster_xy * (unsigned int)&vseg_cluster_increment));
     186
     187    *value = xcu_address[XICU_REG(XICU_WTI_REG, wti_index)];
     188
     189#else
     190    _printf("[GIET ERROR] in _xcu_get_wti_value() USE_XICU is not set\n");
     191    _exit();
     192#endif
     193}
     194
     195////////////////////////////////////////////////////////////////////////////////
     196// This function returns the address of a WTI mailbox defined by
     197// the "wti_index" argument, in the unsigned int "address" argument.
     198// It is used by the GIET to configurate the IOPIC component.
     199// There is no access to a specific XCU component in a specific cluster.
     200// returns 0 if success, > 0 if error.
     201////////////////////////////////////////////////////////////////////////////////
     202void _xcu_get_wti_address( unsigned int   wti_index,
     203                           unsigned int * address )
     204{
     205#if USE_XICU
     206    if (wti_index >= 32)           _exit();
     207 
     208    unsigned int xcu_address = (unsigned int)&seg_xcu_base;
     209    *address = xcu_address + (XICU_REG(XICU_WTI_REG, wti_index)<<2);
     210
     211#else
     212    _printf("[GIET ERROR] in _xcu_get_wti_address() USE_XICU is not set\n");
     213    _exit();
     214#endif
     215}
     216
     217////////////////////////////////////////////////////////////////////////////////
    176218// This function activates a timer contained in XICU by writing in the
    177219// proper register the period value.
    178 // Returns 0 if success, > 0 if error.
    179 ////////////////////////////////////////////////////////////////////////////////
    180 unsigned int _xcu_timer_start( unsigned int cluster_xy,
    181                                unsigned int pti_index,
    182                                unsigned int period )
    183 {
    184     // parameters checking
    185     unsigned int x = cluster_xy >> Y_WIDTH;
    186     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    187     if (x >= X_SIZE)             return 1;
    188     if (y >= Y_SIZE)             return 1;
    189 
    190 #if USE_XICU
     220////////////////////////////////////////////////////////////////////////////////
     221void _xcu_timer_start( unsigned int cluster_xy,
     222                       unsigned int pti_index,
     223                       unsigned int period )
     224{
     225#if USE_XICU
     226    // parameters checking
     227    unsigned int x = cluster_xy >> Y_WIDTH;
     228    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     229    if (x >= X_SIZE)             _exit();
     230    if (y >= Y_SIZE)             _exit();
     231
    191232    volatile unsigned int* xcu_address =
    192233        (unsigned int *) ((unsigned int)&seg_xcu_base +
     
    194235
    195236    xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = period;
    196     return 0;
    197 #else
    198     _tty_get_lock( 0 );
    199     _puts("[GIET ERROR] _xcu_timer_start should not be used if USE_XICU is not set\n");
    200     _tty_release_lock( 0 );
    201     return 1;
    202 #endif
    203 }
    204 
    205 //////////////////////////////////////////////////////////////////////////////
    206 //     _xcu_timer_stop()
     237
     238#else
     239    _printf("[GIET ERROR] in _xcu_timer_start() USE_XICU is not set\n");
     240    _exit();
     241#endif
     242}
     243
     244//////////////////////////////////////////////////////////////////////////////
    207245// This function desactivates a timer in XICU component
    208246// by writing in the proper register.
    209 // Returns 0 if success, > 0 if error.
    210 //////////////////////////////////////////////////////////////////////////////
    211 unsigned int _xcu_timer_stop( unsigned int cluster_xy,
    212                               unsigned int pti_index)
    213 {
    214     // parameters checking
    215     unsigned int x = cluster_xy >> Y_WIDTH;
    216     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    217     if (x >= X_SIZE)             return 1;
    218     if (y >= Y_SIZE)             return 1;
    219 
    220 #if USE_XICU
     247//////////////////////////////////////////////////////////////////////////////
     248void _xcu_timer_stop( unsigned int cluster_xy,
     249                      unsigned int pti_index)
     250{
     251#if USE_XICU
     252    // parameters checking
     253    unsigned int x = cluster_xy >> Y_WIDTH;
     254    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     255    if (x >= X_SIZE)             _exit();
     256    if (y >= Y_SIZE)             _exit();
     257
    221258    volatile unsigned int * xcu_address =
    222259        (unsigned int *) ((unsigned int)&seg_xcu_base +
     
    224261
    225262    xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = 0;
    226     return 0;
    227 #else
    228     _tty_get_lock( 0 );
    229     _puts("[GIET ERROR] _xcu_timer_stop should not be used if USE_XICU is not set\n");
    230     _tty_release_lock( 0 );
    231     return 1;
    232 #endif
    233 }
    234 
    235 //////////////////////////////////////////////////////////////////////////////
    236 //     _xcu_timer_reset_irq()
     263
     264#else
     265    _printf("[GIET ERROR] in _xcu_timer_stop() USE_XICU is not set\n");
     266    _exit();
     267#endif
     268}
     269
     270//////////////////////////////////////////////////////////////////////////////
    237271// This function acknowlegge a timer interrupt in XICU
    238272// component by reading in the proper register.
    239273// It can be used by both the isr_switch() for a "system" timer,
    240274// or by the _isr_timer() for an "user" timer.
    241 // Returns 0 if success, > 0 if error.
    242 //////////////////////////////////////////////////////////////////////////////
    243 unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy,
    244                                    unsigned int pti_index )
    245 {
    246     // parameters checking
    247     unsigned int x = cluster_xy >> Y_WIDTH;
    248     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    249     if (x >= X_SIZE)             return 1;
    250     if (y >= Y_SIZE)             return 1;
    251 
    252 #if USE_XICU
     275//////////////////////////////////////////////////////////////////////////////
     276void _xcu_timer_reset_irq( unsigned int cluster_xy,
     277                           unsigned int pti_index )
     278{
     279#if USE_XICU
     280    // parameters checking
     281    unsigned int x = cluster_xy >> Y_WIDTH;
     282    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     283    if (x >= X_SIZE)             _exit();
     284    if (y >= Y_SIZE)             _exit();
     285
    253286    volatile unsigned int * xcu_address =
    254287        (unsigned int *) ((unsigned int)&seg_xcu_base +
     
    256289
    257290    xcu_address[XICU_REG(XICU_PTI_ACK, pti_index)];
    258     return 0;
    259 #else
    260     _tty_get_lock( 0 );
    261     _puts("[GIET ERROR] _xcu_timer_reset_irq should not be used if USE_XICU is not set\n");
    262     _tty_release_lock( 0 );
    263     return 1;
    264 #endif
    265 }
    266 
    267 //////////////////////////////////////////////////////////////////////////////
    268 //     _xcu_timer_reset_cpt()
     291
     292#else
     293    _printf("[GIET ERROR] in _xcu_timer_reset_irq() USE_XICU is not set\n");
     294    _exit();
     295#endif
     296}
     297
     298//////////////////////////////////////////////////////////////////////////////
    269299// This function resets a timer counter. To do so, we re-write the period
    270300// in the proper register, what causes the count to restart.
    271301// The period value is read from the same (TIMER_PERIOD) register,
    272302// this is why in appearance we do nothing useful (read a value
    273 // from a register and write this value in the same register)
     303// from a register and write this value in the same register).
    274304// This function is called during a context switch (user or preemptive)
    275305/////////////////////////////////////////////////////////////////////////////
    276 unsigned int _xcu_timer_reset_cpt( unsigned int cluster_xy,
    277                                    unsigned int pti_index )
    278 {
    279     // parameters checking
    280     unsigned int x = cluster_xy >> Y_WIDTH;
    281     unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    282     if (x >= X_SIZE)             return 1;
    283     if (y >= Y_SIZE)             return 1;
    284 
    285 #if USE_XICU
     306void _xcu_timer_reset_cpt( unsigned int cluster_xy,
     307                           unsigned int pti_index )
     308{
     309#if USE_XICU
     310    // parameters checking
     311    unsigned int x = cluster_xy >> Y_WIDTH;
     312    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     313    if (x >= X_SIZE)             _exit();
     314    if (y >= Y_SIZE)             _exit();
     315
    286316    volatile unsigned int * xcu_address =
    287317        (unsigned int *) ((unsigned int) &seg_xcu_base +
     
    294324    xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = 0;
    295325    xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = period;
    296     return 0;
    297 #else
    298     _tty_get_lock( 0 );
    299     _puts("[GIET ERROR] _xcu_timer_reset_irq should not be used if USE_XICU is not set\n");
    300     _tty_release_lock( 0 );
    301     return 1;
     326
     327#else
     328    _printf("[GIET ERROR] in _xcu_timer_reset_cpt() USE_XICU is not set\n");
     329    _exit();
    302330#endif
    303331}
Note: See TracChangeset for help on using the changeset viewer.