Ignore:
Timestamp:
Jul 10, 2014, 11:42:14 AM (10 years ago)
Author:
cfuguet
Message:

Merge 'trunk' new modifications into 'fault_tolerance'

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/fault_tolerance/softs/giet_tsar/stdio.c

    r724 r745  
    11////////////////////////////////////////////////////////////////////////////////////////
    22// File : stdio.c
    3 // Written by Alain Greiner 
    4 // Date : janvier 2014 
     3// Written by Alain Greiner
     4// Date : janvier 2014
    55//
    66// This file defines various functions that can be used by applications to access
     
    2222// - NB_PROCS_MAX    : max number of processor per cluster
    2323// - NB_TTY_CHANNELS : max number of TTY channels
    24 // - USE_EXT_IO      : use external peripherals if not zero
    2524//
    2625// The follobing base addresses must be defined in the ldscript
     
    3635#endif
    3736
    38 #if !defined(USE_EXT_IO)
    39 #error: you must define USE_EXT_IO in the hard_config.h file
     37#if !defined(X_IO) || !defined(Y_IO)
     38#error: you must define X_IO and Y_IO in the hard_config.h file
    4039#endif
    4140
     
    6867#endif
    6968
    70 
    71 
    72 
    7369#define NB_LOCKS      256
    7470#define NB_BARRIERS   16
     
    8278
    8379struct plouf;
    84 
    85 extern struct plouf seg_tty_base;
    86 extern struct plouf seg_fbf_base;
    87 extern struct plouf seg_ioc_base;
    88 extern struct plouf seg_mmc_base;
    89 extern struct plouf seg_ramdisk_base;
     80extern volatile struct plouf seg_tty_base;
     81extern volatile struct plouf seg_fbf_base;
     82extern volatile struct plouf seg_ioc_base;
     83extern volatile struct plouf seg_mmc_base;
     84extern volatile struct plouf seg_ramdisk_base;
    9085
    9186////////////////////////////////////////////////////////////////////////////////////////
     
    9388////////////////////////////////////////////////////////////////////////////////////////
    9489
    95 in_unckdata int volatile    _ioc_lock    = 0;
    96 in_unckdata int volatile    _ioc_done    = 0;
    97 in_unckdata int volatile    _ioc_status;
    98 
    99 in_unckdata char volatile  _tty_get_buf[NB_TTY_CHANNELS];
    100 in_unckdata int volatile    _tty_get_full[NB_TTY_CHANNELS] = { [0 ... NB_TTY_CHANNELS-1] = 0 };
     90static in_unckdata int volatile  _ioc_lock    = 0;
     91static in_unckdata int volatile  _ioc_done    = 0;
     92static in_unckdata int volatile  _ioc_status;
     93
     94static in_unckdata char volatile _tty_get_buf[NB_TTY_CHANNELS];
     95static in_unckdata int volatile  _tty_get_full[NB_TTY_CHANNELS] = { [0 ... NB_TTY_CHANNELS-1] = 0 };
    10196
    10297////////////////////////////////////////////////////////////////////////////////////////
     
    10499////////////////////////////////////////////////////////////////////////////////////////
    105100
    106 in_unckdata int volatile    _barrier_value[NB_BARRIERS] = { [0 ... NB_BARRIERS-1] = 0 };
    107 in_unckdata int volatile    _barrier_count[NB_BARRIERS] = { [0 ... NB_BARRIERS-1] = 0 };
    108 in_unckdata int volatile    _barrier_lock[NB_BARRIERS]   = { [0 ... NB_BARRIERS-1] = 0 };
     101static in_unckdata int volatile  _barrier_value[NB_BARRIERS] = { [0 ... NB_BARRIERS-1] = 0 };
     102static in_unckdata int volatile  _barrier_count[NB_BARRIERS] = { [0 ... NB_BARRIERS-1] = 0 };
     103static in_unckdata int volatile  _barrier_lock[NB_BARRIERS]  = { [0 ... NB_BARRIERS-1] = 0 };
    109104
    110105////////////////////////////////////////////////////////////////////////////////////////
     
    112107////////////////////////////////////////////////////////////////////////////////////////
    113108
    114 in_unckdata int volatile    _spin_lock[NB_LOCKS] =    { [0 ... NB_LOCKS-1] = 0 };
     109static in_unckdata int volatile  _spin_lock[NB_LOCKS] = { [0 ... NB_LOCKS-1] = 0 };
    115110
    116111////////////////////////////////////////////////////////////////////////////////////////
    117112// Memcopy taken from MutekH.
    118113////////////////////////////////////////////////////////////////////////////////////////
    119 in_drivers void* _memcpy( void*        _dst, 
    120                           const void*  _src, 
     114in_drivers void* _memcpy( void*        _dst,
     115                          const void*  _src,
    121116                          unsigned int size )
    122117{
     
    125120    if ( ! ((unsigned int)dst & 3) && ! ((unsigned int)src & 3) )
    126121    {
    127         while (size > 3) 
     122        while (size > 3)
    128123        {
    129124            *dst++ = *src++;
     
    135130    unsigned char *csrc = (unsigned char*)src;
    136131
    137     while (size--) 
     132    while (size--)
    138133    {
    139134        *cdst++ = *csrc++;
     
    146141in_drivers void  _extended_memcpy( unsigned int dst_cluster,
    147142                                   unsigned int dst_address,
    148                                    unsigned int src_cluster,
    149143                                   unsigned int src_address,
    150144                                   unsigned int length )
     
    189183// Returns the number of processsors controled by the GIET
    190184////////////////////////////////////////////////////////////////////////////////////////
    191 in_drivers unsigned int _procnumber()
     185in_drivers inline unsigned int _procnumber()
    192186{
    193187    return (unsigned int)(NB_PROCS_MAX * X_SIZE * Y_SIZE);
     
    205199}
    206200////////////////////////////////////////////////////////////////////////////////////////
     201// Access CP0 and enable IRQs
     202////////////////////////////////////////////////////////////////////////////////////////
     203in_drivers inline void _it_enable()
     204{
     205    asm volatile(
     206            "mfc0   $8,     $12         \n"
     207            "ori    $8,     $8,     1   \n"
     208            "mtc0   $8,     $12         \n"
     209            ::: "$8");
     210}
     211////////////////////////////////////////////////////////////////////////////////////////
    207212// Access CP0 and mask IRQs
    208213////////////////////////////////////////////////////////////////////////////////////////
    209 in_drivers void _it_mask()
    210 {
    211     int tmp;
    212     asm volatile("mfc0  %0, $12"    : "=r" (tmp) );
    213     asm volatile("ori   %0, %0, 1"  : "=r" (tmp) );
    214     asm volatile("mtc0  %0, $12"    : "=r" (tmp) );
    215 }
    216 ////////////////////////////////////////////////////////////////////////////////////////
    217 // Access CP0 and enable IRQs
    218 ////////////////////////////////////////////////////////////////////////////////////////
    219 in_drivers void _it_enable()
    220 {
    221     int tmp;
    222     asm volatile("mfc0  %0, $12"    : "=r" (tmp) );
    223     asm volatile("addi  %0, %0, -1" : "=r" (tmp) );
    224     asm volatile("mtc0  %0, $12"    : "=r" (tmp) );
    225 }
     214in_drivers inline void _it_disable()
     215{
     216    asm volatile(
     217            "li     $9,     0xFFFFFFFE  \n"
     218            "mfc0   $8,     $12         \n"
     219            "and    $8,     $8,     $9  \n"
     220            "mtc0   $8,     $12         \n"
     221            ::: "$8","$9");
     222}
     223
     224////////////////////////////////////////////////////////////////////////////////////////
     225// Access CP0 and mask IRQs
     226////////////////////////////////////////////////////////////////////////////////////////
     227in_drivers inline void _sr_write(int sr)
     228{
     229    asm volatile("mtc0  %0, $12        \n" : /* no outputs */ : "r" (sr));
     230}
     231
     232in_drivers inline int _sr_read()
     233{
     234    int ret;
     235    asm volatile("mfc0  %0, $12        \n" : "=r" (ret));
     236    return ret;
     237}
     238
    226239//////////////////////////////////////////////////////////////////////
    227240// Invalidate all cache lines corresponding to a memory buffer.
     
    246259
    247260////////////////////////////////////////////////////////////////////////////
    248 // This function makes a physical read access to a 32 bits word in memory, 
     261// This function makes a physical read access to a 32 bits word in memory,
    249262// after a temporary paddr extension.
    250263////////////////////////////////////////////////////////////////////////////
    251 in_drivers unsigned int _word_extended_read( unsigned int  cluster,
    252                                              unsigned int  address )
    253 {
    254     unsigned int value;
     264in_drivers volatile unsigned int _word_extended_read( unsigned int cluster,
     265                                                      unsigned int address )
     266{
     267    int sr = _sr_read();
     268    volatile unsigned int value;
    255269    asm volatile(
    256270            "li      $3,        0xFFFFFFFE    \n"
    257             "mfc0    $2,        $12           \n"
    258             "and     $3,        $2, $3        \n"
     271            "and     $3,        %3,     $3    \n"
    259272            "mtc0    $3,        $12           \n"     /* IRQ disabled     */
    260273
    261             "mtc2    %2,        $24           \n"     /* PADDR_EXT <= msb */   
     274            "mtc2    %2,        $24           \n"     /* PADDR_EXT <= msb */
    262275            "lw      %0,        0(%1)         \n"     /* value <= *paddr  */
    263276            "mtc2    $0,        $24           \n"     /* PADDR_EXT <= 0   */
    264277
    265             "li      $3,        0x00000001    \n"
    266             "mfc0    $2,        $12           \n"
    267             "or      $3,        $3, $2        \n"
    268             "mtc0    $3,        $12           \n"     /* IRQ enabled      */
    269278            : "=r" (value)
    270             : "r" (address), "r" (cluster)
    271             : "$2", "$3" );
     279            : "r" (address), "r" (cluster), "r" (sr)
     280            : "$2", "$3", "memory" );
     281
     282    _sr_write(sr);
    272283    return value;
    273284}
    274285////////////////////////////////////////////////////////////////////////////
    275 // This function makes a physical read access to a single byte in memory, 
     286// This function makes a physical read access to a single byte in memory,
    276287// after a temporary paddr extension.
    277288////////////////////////////////////////////////////////////////////////////
    278 in_drivers unsigned char _byte_extended_read( unsigned int  cluster,
    279                                               unsigned int  address )
    280 {
    281     unsigned int value;
     289in_drivers volatile unsigned char _byte_extended_read( unsigned int  cluster,
     290                                                       unsigned int  address )
     291{
     292    int sr = _sr_read();
     293    volatile unsigned char value;
    282294    asm volatile(
    283295            "li      $3,        0xFFFFFFFE    \n"
    284             "mfc0    $2,        $12           \n"
    285             "and     $3,        $2, $3        \n"
     296            "and     $3,        %3,     $3    \n"
    286297            "mtc0    $3,        $12           \n"     /* IRQ disabled     */
    287298
    288             "mtc2    %2,        $24           \n"     /* PADDR_EXT <= msb */   
     299            "mtc2    %2,        $24           \n"     /* PADDR_EXT <= msb */
    289300            "lb      %0,        0(%1)         \n"     /* value <= *paddr  */
    290301            "mtc2    $0,        $24           \n"     /* PADDR_EXT <= 0   */
    291302
    292             "li      $3,        0x00000001    \n"
    293             "mfc0    $2,        $12           \n"
    294             "or      $3,        $3, $2        \n"
    295             "mtc0    $3,        $12           \n"     /* IRQ enabled      */
    296303            : "=r" (value)
    297             : "r" (address), "r" (cluster)
    298             : "$2", "$3" );
    299     return (unsigned char)value;
     304            : "r" (address), "r" (cluster), "r" (sr)
     305            : "$2", "$3", "memory" );
     306
     307    _sr_write(sr);
     308    return value;
    300309}
    301310////////////////////////////////////////////////////////////////////////////
    302 // This function makes a physical write access to a 32 bits word in memory, 
     311// This function makes a physical write access to a 32 bits word in memory,
    303312// after a temporary DTLB address extension.
    304313////////////////////////////////////////////////////////////////////////////
    305 in_drivers void _word_extended_write( unsigned int  cluster, 
     314in_drivers void _word_extended_write( unsigned int  cluster,
    306315                                      unsigned int  address,
    307                                       unsigned int  word )
    308 {
     316                                      unsigned int  word )
     317{
     318    int sr = _sr_read();
    309319    asm volatile(
    310320            "li      $3,        0xFFFFFFFE    \n"
    311             "mfc0    $2,        $12           \n"
    312             "and     $3,        $2, $3        \n"
     321            "and     $3,        %3,     $3    \n"
    313322            "mtc0    $3,        $12           \n"     /* IRQ disabled     */
    314323
    315             "mtc2    %2,        $24           \n"     /* PADDR_EXT <= msb */   
     324            "mtc2    %2,        $24           \n"     /* PADDR_EXT <= msb */
    316325            "sw      %0,        0(%1)         \n"     /* *paddr <= value  */
    317             "mtc2    $0,        $24           \n"     /* PADDR_EXT <= 0   */   
    318 
    319             "li      $3,        0x00000001    \n"
    320             "mfc0    $2,        $12           \n"
    321             "or      $3,        $2, $3        \n"
    322             "mtc0    $3,        $12           \n"     /* IRQ enabled      */
     326            "mtc2    $0,        $24           \n"     /* PADDR_EXT <= 0   */
     327
     328            "sync                             \n"
    323329            :
    324             : "r" (word), "r" (address), "r" (cluster)
    325             : "$2", "$3");
     330            : "r" (word), "r" (address), "r" (cluster), "r" (sr)
     331            : "$2", "$3", "memory");
     332
     333    _sr_write(sr);
    326334}
    327335////////////////////////////////////////////////////////////////////////////
    328 // This function makes a physical write access to single byte in memory, 
     336// This function makes a physical write access to single byte in memory,
    329337// after a temporary DTLB de-activation and address extension.
    330338////////////////////////////////////////////////////////////////////////////
    331 in_drivers void _byte_extended_write( unsigned int  cluster, 
     339in_drivers void _byte_extended_write( unsigned int  cluster,
    332340                                      unsigned int  address,
    333                                       unsigned char byte )
    334 {
     341                                      unsigned char byte )
     342{
     343    int sr = _sr_read();
    335344    asm volatile(
    336345            "li      $3,        0xFFFFFFFE    \n"
    337             "mfc0    $2,        $12           \n"
    338             "and     $3,        $2, $3        \n"
     346            "and     $3,        %3,     $3    \n"
    339347            "mtc0    $3,        $12           \n"     /* IRQ disabled     */
    340348
    341             "mtc2    %2,        $24           \n"     /* PADDR_EXT <= msb */   
     349            "mtc2    %2,        $24           \n"     /* PADDR_EXT <= msb */
    342350            "sb      %0,        0(%1)         \n"     /* *paddr <= value  */
    343             "mtc2    $0,        $24           \n"     /* PADDR_EXT <= 0   */   
    344 
    345             "li      $3,        0x00000001    \n"
    346             "mfc0    $2,        $12           \n"
    347             "or      $3,        $2, $3        \n"
    348             "mtc0    $3,        $12           \n"     /* IRQ enabled      */
     351            "mtc2    $0,        $24           \n"     /* PADDR_EXT <= 0   */
     352
     353            "sync                             \n"
    349354            :
    350             : "r" (byte), "r" (address), "r" (cluster)
    351             : "$2", "$3");
    352 }
    353 
    354 ///////////////////////////////////////////////////////////////////////////////////////
    355 // Exit (suicide) after printing message on TTY0
     355            : "r" (byte), "r" (address), "r" (cluster), "r" (sr)
     356            : "$2", "$3", "memory");
     357
     358    _sr_write(sr);
     359}
     360
     361///////////////////////////////////////////////////////////////////////////////////////
     362// Exit (suicide) after printing message on TTY0
    356363///////////////////////////////////////////////////////////////////////////////////////
    357364in_drivers void _exit()
     
    410417//  - If there is only one terminal, it is supposed to be shared, and used by
    411418//    all processors: a lock must be taken before display.
    412 //  - If there is several terminals, and the number of processors is smaller 
    413 //    than the number of terminals, there is one terminal per processor, but 
     419//  - If there is several terminals, and the number of processors is smaller
     420//    than the number of terminals, there is one terminal per processor, but
    414421//    the TTY index is not equal to the proc_id, due to cluster indexing policy:
    415422//    proc_id = cluster_xy * NB_PROCS_MAX + local_id (with cluster_xy = x << Y_WIDTH + y)
    416423//    tty_id  = cluster_id * NB_PROCS_MAX + local_id (with cluster_id = x * Y_SIZE + y)
    417424//  - If the computed tty_id is larger than NB_TTY_CHANNELS, an error is returned.
    418 ///////////////////////////////////////////////////////////////////////////////////////
    419 //  If USE_EXT_IO is set, we use the TTY controler implemented in cluster_io
    420 //  (x = X_SIZE-1 / y = Y_SIZE), which requires and extended address access.
    421 //  If USE_EXT_IO not set, we use the single channel TTY contrÃŽler in cluster (0,0).
    422425///////////////////////////////////////////////////////////////////////////////////////
    423426
     
    430433// returns  the number of characters that have been actually written.
    431434///////////////////////////////////////////////////////////////////////////////////////
    432 in_drivers int _tty_write( char*           buffer, 
    433                            unsigned int    length, 
     435in_drivers int _tty_write( char*           buffer,
     436                           unsigned int    length,
    434437                           unsigned int    channel )
    435438{
    436     unsigned int    base       = (unsigned int)&seg_tty_base + channel*TTY_SPAN*4;
    437     unsigned int    nwritten   = 0;
    438     unsigned int    cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
     439    unsigned int    base     = (unsigned int)&seg_tty_base + channel*TTY_SPAN*4;
     440    unsigned int    nwritten = 0;
    439441    unsigned int    status;
    440     unsigned int        i;
     442    unsigned int    i;
    441443
    442444    for ( i=0 ; i < length ; i++ )
    443445    {
    444         if( USE_EXT_IO )    // extended addressing to reach cluster_io
     446        status = _word_extended_read( CLUSTER_IO, base + TTY_STATUS*4 );
     447        if ( (status & 0x2) == 0x2 ) break;
     448        else
    445449        {
    446             status = _word_extended_read( cluster_io, base + TTY_STATUS*4 );
    447             if ( (status & 0x2) == 0x2 ) break;
    448             else
    449             {
    450                 _byte_extended_write( cluster_io, base + TTY_WRITE*4 , buffer[i] );
    451                 nwritten++;
    452             }
    453         }
    454         else                // direct addressing to cluster(0,0)
    455         {
    456             char* tty = (char*)base;
    457             if ( (tty[TTY_STATUS*4] & 0x2) == 0x2 )  break;
    458             else
    459             {
    460                 tty[TTY_WRITE*4] = buffer[i]; // write character
    461                 nwritten++;
    462             }
     450            _byte_extended_write( CLUSTER_IO, base + TTY_WRITE*4 , buffer[i] );
     451            nwritten++;
    463452        }
    464453    }
     
    474463// and returns 1 if the register is full.
    475464///////////////////////////////////////////////////////////////////////////////////////
    476 in_drivers int _tty_read( char*          buffer, 
     465in_drivers int _tty_read( char*          buffer,
    477466                          unsigned int   channel )
    478467{
    479     unsigned int    base       = (unsigned int)&seg_tty_base + channel*TTY_SPAN*4;
    480     unsigned int    cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
    481     unsigned int    status;
    482 
    483     if( USE_EXT_IO )
    484     {
    485         status = _word_extended_read( cluster_io, base + TTY_STATUS*4 );
    486         if ( (status & 0x1) == 0x1 )
    487         {
    488             buffer[0] = (char)_word_extended_read( cluster_io, base + TTY_READ*4 );
    489             return 1;
    490         }
    491         else
    492         {
    493             return 0;
    494         }
    495     }
    496     else
    497     {
    498         char* tty = (char*)base;
    499 
    500         if((tty[TTY_STATUS*4] & 0x1) == 0x1)
    501         {
    502             buffer[0] = tty[TTY_READ*4];
    503             return 1;
    504         }
    505         else
    506         {
    507             return 0;
    508         }
    509     }
     468    unsigned int base    = (unsigned int)&seg_tty_base + channel*TTY_SPAN*4;
     469    unsigned int status;
     470
     471    status = _word_extended_read( CLUSTER_IO, base + TTY_STATUS*4 );
     472    if ( (status & 0x1) == 0x1 )
     473    {
     474        buffer[0] = (char)_word_extended_read( CLUSTER_IO, base + TTY_READ*4 );
     475        return 1;
     476    }
     477    return 0;
    510478}
    511479
     
    524492// This function displays a 32 bits unsigned int as an hexa string on TTY0.
    525493///////////////////////////////////////////////////////////////////////////////
    526 in_drivers void _tty_putx(unsigned int val) 
     494in_drivers void _tty_putx(unsigned int val)
    527495{
    528496    static const char HexaTab[] = "0123456789ABCDEF";
     
    534502    buf[10] = 0;
    535503
    536     for (c = 0; c < 8; c++) 
    537     { 
     504    for (c = 0; c < 8; c++)
     505    {
    538506        buf[9 - c] = HexaTab[val & 0xF];
    539507        val = val >> 4;
     
    545513// This function displays a 32 bits unsigned int as a decimal string on TTY0.
    546514///////////////////////////////////////////////////////////////////////////////
    547 in_drivers void _tty_putd( unsigned int val ) 
     515in_drivers void _tty_putd( unsigned int val )
    548516{
    549517    static const char DecTab[] = "0123456789";
    550518    char buf[11];
    551519    unsigned int i;
    552     unsigned int first;
     520    unsigned int first = 0;
    553521
    554522    buf[10] = 0;
    555523
    556     for (i = 0; i < 10; i++) 
    557     {
    558         if ((val != 0) || (i == 0)) 
     524    for (i = 0; i < 10; i++)
     525    {
     526        if ((val != 0) || (i == 0))
    559527        {
    560528            buf[9 - i] = DecTab[val % 10];
    561529            first = 9 - i;
    562530        }
    563         else 
     531        else
    564532        {
    565533            break;
     
    571539
    572540//////////////////////////////////////////////////////////////////////////////
    573 // This function try to take the hardwired lock protecting exclusive access 
     541// This function try to take the hardwired lock protecting exclusive access
    574542// to TTY terminal identified by the channel argument.
    575543// It returns only when the lock has been successfully taken.
     
    577545in_drivers void _tty_get_lock( unsigned int channel )
    578546{
    579     if ( USE_EXT_IO )  // extended addressing to cluster_io
    580     {
    581         unsigned int    cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
    582         unsigned int    address    = (unsigned int)&seg_tty_base
    583                                      + ((TTY_CONFIG + channel*TTY_SPAN)*4);
    584         while ( _word_extended_read( cluster_io, address ) ) asm volatile("nop");
    585     }
    586     else               // direct addressing to cluster(0,0)
    587     {
    588         unsigned int* tty = (unsigned int *) &seg_tty_base;
    589         while ( tty[channel * TTY_SPAN + TTY_CONFIG] ) asm volatile("nop");
    590     }
     547    unsigned int base = (unsigned int)&seg_tty_base;
     548    unsigned int offset = (TTY_CONFIG + channel*TTY_SPAN) << 2;
     549    while ( _word_extended_read( CLUSTER_IO, base + offset ) );
    591550}
    592551
    593552//////////////////////////////////////////////////////////////////////////////
    594 // This function releases the hardwired lock protecting exclusive access 
     553// This function releases the hardwired lock protecting exclusive access
    595554// to TTY terminal identified by the channel argument.
    596555//////////////////////////////////////////////////////////////////////////////
    597556in_drivers void _tty_release_lock( unsigned int channel )
    598557{
    599     if ( USE_EXT_IO )  // extended addressing to cluster_io
    600     {
    601         unsigned int    cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
    602         unsigned int    address    = (unsigned int)&seg_tty_base
    603                                      + ((TTY_CONFIG + channel*TTY_SPAN)*4);
    604         _word_extended_write( cluster_io, address, 0 );
    605     }
    606     else               // direct addressing to cluster(0,0)
    607     {
    608         unsigned int* tty_address = (unsigned int *) &seg_tty_base;
    609         tty_address[channel * TTY_SPAN + TTY_CONFIG] = 0;
    610     }
     558    unsigned int base    = (unsigned int)&seg_tty_base;
     559    unsigned int offset  = (TTY_CONFIG + channel*TTY_SPAN) << 2;
     560    _word_extended_write( CLUSTER_IO, base + offset, 0 );
    611561}
    612562
     
    626576    // check TTY channel
    627577    l           = (proc_id % NB_PROCS_MAX);
    628     x           = (proc_id / NB_PROCS_MAX) >> Y_WIDTH; 
     578    x           = (proc_id / NB_PROCS_MAX) >> Y_WIDTH;
    629579    y           = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1);
    630580    channel = (x * Y_SIZE + y) * NB_PROCS_MAX + l;
     
    649599//  The <DEL> character is interpreted, and previous characters can be
    650600//  cancelled. All others characters are ignored.
    651 //  When the <LF> or <CR> character is received, the string is converted 
     601//  When the <LF> or <CR> character is received, the string is converted
    652602//  to an unsigned int value. If the number of decimal digit is too large
    653603//  for the 32 bits range, the zero value is returned.
     
    673623    // check TTY channel
    674624    l           = (proc_id % NB_PROCS_MAX);
    675     x           = (proc_id / NB_PROCS_MAX) >> Y_WIDTH; 
     625    x           = (proc_id / NB_PROCS_MAX) >> Y_WIDTH;
    676626    y           = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1);
    677627    channel = (x * Y_SIZE + y) * NB_PROCS_MAX + l;
     
    751701
    752702    // compute TTY channel :
    753     // if the number of TTY channels is smaller 
     703    // if the number of TTY channels is smaller
    754704    // than the number of clusters, use TTY_0_0
    755705    // else, TTY channel <= cluster index
     
    760710    else
    761711    {
    762         x           = (proc_id / NB_PROCS_MAX) >> Y_WIDTH; 
     712        x           = (proc_id / NB_PROCS_MAX) >> Y_WIDTH;
    763713        y           = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1);
    764714        channel     = (x * Y_SIZE + y);
    765715    }
    766716
    767     // take the TTY lock 
     717    // take the TTY lock
    768718    _tty_get_lock( channel );
    769719
    770720printf_text:
    771721
    772     while (*format) 
     722    while (*format)
    773723    {
    774724        unsigned int i;
    775725        for (i = 0; format[i] && format[i] != '%'; i++)
    776726            ;
    777         if (i) 
     727        if (i)
    778728        {
    779729            _tty_write( format, i, channel );
    780730            format += i;
    781731        }
    782         if (*format == '%') 
     732        if (*format == '%')
    783733        {
    784734            format++;
     
    811761                break;
    812762            case ('d'):             // decimal signed integer
    813                 if (val < 0) 
     763                if (val < 0)
    814764                {
    815765                    val = -val;
     
    817767                }
    818768            case ('u'):             // decimal unsigned integer
    819                 for( i=0 ; i<10 ; i++) 
     769                for( i=0 ; i<10 ; i++)
    820770                {
    821771                    buf[9-i] = HexaTab[val % 10];
     
    827777            case ('x'):             // hexadecimal integer
    828778                _tty_write( "0x", 2, channel );
    829                 for( i=0 ; i<8 ; i++) 
     779                for( i=0 ; i<8 ; i++)
    830780                {
    831781                    buf[7-i] = HexaTab[val % 16U];
     
    860810in_drivers void _tty_isr_indexed(size_t index)
    861811{
    862     if ( USE_EXT_IO )   // extended addressing to TTY in cluster_io
    863     {
    864         unsigned int  cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
    865         unsigned int  base    = (unsigned int)&seg_tty_base +
    866                                 ((index*TTY_SPAN + TTY_READ)*4);
    867 
    868         _tty_get_buf[index] = (char)_word_extended_read( cluster, base );
    869     }
    870     else                // direct addressing to TTY in cluster(0,0)
    871     {
    872         char* tty = (char*)&seg_tty_base + index*TTY_SPAN*4;
    873 
    874         _tty_get_buf[index] = tty[TTY_READ*4];  // save character and reset IRQ
    875     }
     812    unsigned int base = (unsigned int)&seg_tty_base;
     813    unsigned int offset = (index*TTY_SPAN + TTY_READ) << 2;
     814
     815    _tty_get_buf[index] = _byte_extended_read(CLUSTER_IO, base + offset);
    876816    _tty_get_full[index] = 1;               // signals character available
    877817}
     
    917857//////////////////////////////////////////////////////////////////////////////////////////
    918858// The block size is 512 bytes.
    919 // The functions below use the three variables _ioc_lock _ioc_done, 
     859// The functions below use the three variables _ioc_lock _ioc_done,
    920860// and _ioc_status for synchronisation.
    921861// - As the IOC component can be used by several programs running in parallel,
    922862// the _ioc_lock variable guaranties exclusive access to the device.
    923863// The _ioc_read() and _ioc_write() functions use atomic LL/SC to get the lock.
    924 // and set _ioc_lock to a non zero value. 
     864// and set _ioc_lock to a non zero value.
    925865// The _ioc_write() and _ioc_read() functions are blocking, polling the _ioc_lock
    926866// variable until the device is available.
     
    932872// reset the _ioc_done variable to zero, and releases the _ioc_lock variable.
    933873///////////////////////////////////////////////////////////////////////////////////////
    934 //  If USE_EXT_IO is set, we use the IOC controler implemented in cluster_io
    935 //  (x = X_SIZE-1 / y = Y_SIZE), which requires and extended address access.
    936 //  If USE_EXT_IO not set, we use the IOC contrÃŽler in cluster (0,0).
    937 //
    938 //  If USE_RAMDISK is set, we access a "virtual" block device controler  implemented
     874//  If USE_RAMDISK is set, we access a "virtual" block device controler  implemented
    939875//  as a memory-mapped segment in cluster [0,0] at address seg_ramdisk_base.
    940876//  The tranfer being fully synchronous, the IOC interrupt is not activated.
     
    942878
    943879///////////////////////////////////////////////////////////////////////////////////////
    944 // This blocking function is used by the _ioc_read() and _ioc_write() functions 
     880// This blocking function is used by the _ioc_read() and _ioc_write() functions
    945881// to get _ioc_lock using LL/SC.
    946882///////////////////////////////////////////////////////////////////////////////////////
    947883in_drivers void _ioc_get_lock()
    948884{
    949     register unsigned int*      plock = (unsigned int*)&_ioc_lock;                     
    950 
    951     asm volatile ("_ioc_llsc:                       \n"
    952                   "ll   $2,    0(%0)                \n" // $2 <= _ioc_lock
    953                   "bnez $2,    _ioc_llsc            \n" // retry  if busy
    954                   "li   $3,    1                    \n" // prepare argument for sc 
    955                   "sc   $3,    0(%0)                \n" // try to set _ioc_busy
    956                   "beqz $3,    _ioc_llsc            \n" // retry if not atomic
    957                   ::"r"(plock):"$2","$3");
     885    register unsigned int*  plock = (unsigned int*)&_ioc_lock;
     886
     887    asm volatile (
     888            "1:                         \n"
     889            "ll     $2,     0(%0)       \n" // $2 <= _ioc_lock
     890            "bnez   $2,     1b          \n" // retry  if busy
     891            "li     $3,     1           \n" // prepare argument for sc
     892            "sc     $3,     0(%0)       \n" // try to set _ioc_busy
     893            "beqz   $3,     1b          \n" // retry if not atomic
     894            ::"r"(plock) :"$2","$3");
    958895}
    959896
     
    965902// - ext    : cluster index for the memory buffer
    966903///////////////////////////////////////////////////////////////////////////////////////
    967 in_drivers void _ioc_write( size_t   lba, 
    968                             void*    buffer, 
     904in_drivers void _ioc_write( size_t   lba,
     905                            void*    buffer,
    969906                            size_t   count,
    970907                            size_t   ext )
     
    985922                          src_address,
    986923                          count*512 );
    987        
     924
    988925        _ioc_status = BLOCK_DEVICE_WRITE_SUCCESS;
    989926        _ioc_done   = 1;
    990     }
    991     else if ( USE_EXT_IO )   // extended addressing to cluster_io
    992     {
    993         unsigned int    cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
    994         unsigned int    base    = (unsigned int)&seg_ioc_base;
    995 
    996         _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER*4,     (unsigned int)buffer );
    997         _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER_EXT*4, ext );
    998         _word_extended_write( cluster, base + BLOCK_DEVICE_COUNT*4,      count );
    999         _word_extended_write( cluster, base + BLOCK_DEVICE_LBA*4,        lba );
    1000         _word_extended_write( cluster, base + BLOCK_DEVICE_IRQ_ENABLE*4, 1 );
    1001         _word_extended_write( cluster, base + BLOCK_DEVICE_OP*4,         BLOCK_DEVICE_WRITE );
    1002     }
    1003     else                // direct addressing to cluster(0,0)
    1004     {
    1005         unsigned int* ioc = (unsigned int*)&seg_ioc_base;
    1006 
    1007         ioc[BLOCK_DEVICE_BUFFER]     = (unsigned int)buffer;
    1008         ioc[BLOCK_DEVICE_BUFFER_EXT] = ext;
    1009         ioc[BLOCK_DEVICE_COUNT]      = count;
    1010         ioc[BLOCK_DEVICE_LBA]        = lba;
    1011         ioc[BLOCK_DEVICE_IRQ_ENABLE] = 1;
    1012         ioc[BLOCK_DEVICE_OP]         = BLOCK_DEVICE_WRITE;
    1013     }
     927
     928        return;
     929    }
     930
     931    unsigned int base = (unsigned int)&seg_ioc_base;
     932    _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_BUFFER*4,     (unsigned int)buffer );
     933    _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_BUFFER_EXT*4, ext );
     934    _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_COUNT*4,      count );
     935    _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_LBA*4,        lba );
     936    _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_IRQ_ENABLE*4, 1 );
     937    _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_OP*4,         BLOCK_DEVICE_WRITE );
    1014938}
    1015939
     
    1021945// - ext    : cluster index for the memory buffer
    1022946///////////////////////////////////////////////////////////////////////////////////////
    1023 in_drivers void _ioc_read( size_t   lba, 
    1024                            void*    buffer, 
     947in_drivers void _ioc_read( size_t   lba,
     948                           void*    buffer,
    1025949                           size_t   count,
    1026950                           size_t   ext )
     
    1044968        _ioc_status = BLOCK_DEVICE_READ_SUCCESS;
    1045969        _ioc_done   = 1;
    1046     }
    1047     else if ( USE_EXT_IO )   // extended addressing to cluster_io
    1048     {
    1049         unsigned int    cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
    1050         unsigned int    base    = (unsigned int)&seg_ioc_base;
    1051 
    1052         _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER*4,     (unsigned int)buffer );
    1053         _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER_EXT*4, ext );
    1054         _word_extended_write( cluster, base + BLOCK_DEVICE_COUNT*4,      count );
    1055         _word_extended_write( cluster, base + BLOCK_DEVICE_LBA*4,        lba );
    1056         _word_extended_write( cluster, base + BLOCK_DEVICE_IRQ_ENABLE*4, 1 );
    1057         _word_extended_write( cluster, base + BLOCK_DEVICE_OP*4,         BLOCK_DEVICE_READ );
    1058     }
    1059     else                // direct addressing to cluster(0,0)
    1060     {
    1061         unsigned int* ioc = (unsigned int*)&seg_ioc_base;
    1062 
    1063         ioc[BLOCK_DEVICE_BUFFER]     = (unsigned int)buffer;
    1064         ioc[BLOCK_DEVICE_BUFFER_EXT] = ext;
    1065         ioc[BLOCK_DEVICE_COUNT]      = count;
    1066         ioc[BLOCK_DEVICE_LBA]        = lba;
    1067         ioc[BLOCK_DEVICE_IRQ_ENABLE] = 1;
    1068         ioc[BLOCK_DEVICE_OP]         = BLOCK_DEVICE_READ;
    1069     }
     970
     971        return;
     972    }
     973
     974    const unsigned int base = (unsigned int)&seg_ioc_base;
     975    _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_BUFFER*4,     (unsigned int)buffer );
     976    _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_BUFFER_EXT*4, ext );
     977    _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_COUNT*4,      count );
     978    _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_LBA*4,        lba );
     979    _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_IRQ_ENABLE*4, 1 );
     980    _word_extended_write( CLUSTER_IO, base + BLOCK_DEVICE_OP*4,         BLOCK_DEVICE_READ );
     981}
     982
     983in_drivers inline unsigned int _ioc_get_blocksize() {
     984    const unsigned int base = (unsigned int)&seg_ioc_base;
     985    return _word_extended_read( CLUSTER_IO, base + BLOCK_DEVICE_BLOCK_SIZE*4 );
    1070986}
    1071987
     
    1078994{
    1079995    // waiting for completion
    1080     while (_ioc_done == 0)  asm volatile("nop"); 
    1081    
     996    while (_ioc_done == 0)  asm volatile("nop");
     997
    1082998    // reset synchronisation variables
    1083999    _ioc_done = 0;
     
    11021018in_drivers void _ioc_isr()
    11031019{
    1104     if ( USE_EXT_IO )  // extended addressing to cluster_io
    1105     {
    1106         unsigned int    cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
    1107         unsigned int    base    = (unsigned int)&seg_ioc_base;
    1108 
    1109         _ioc_status = _word_extended_read( cluster, base + BLOCK_DEVICE_STATUS*4 );
    1110     }
    1111     else               // direct addressing to cluster(à,0)
    1112     {
    1113         unsigned int* ioc = (unsigned int*)&seg_ioc_base;
    1114    
    1115         _ioc_status = ioc[BLOCK_DEVICE_STATUS]; // save status & reset IRQ
    1116     }
    1117     _ioc_done   = 1;       // signals completion
     1020    unsigned int base = (unsigned int)&seg_ioc_base;
     1021
     1022    _ioc_status = _word_extended_read( CLUSTER_IO, base + BLOCK_DEVICE_STATUS*4 );
     1023    _ioc_done   = 1;       // signals completion
    11181024}
    11191025
     
    11211027//  FRAME_BUFFER
    11221028//////////////////////////////////////////////////////////////////////////////////////
    1123 // The _fb_sync_write & _fb_sync_read functions use a memcpy strategy to implement 
     1029// The _fb_sync_write & _fb_sync_read functions use a memcpy strategy to implement
    11241030// the transfer between a data buffer and the frame buffer.
    11251031// They are blocking until completion of the transfer.
     
    11341040// - ext    : cluster_xy for the user buffer
    11351041//////////////////////////////////////////////////////////////////////////////////////
    1136 in_drivers void _fb_sync_write( unsigned int  offset, 
    1137                                 unsigned int  buffer, 
     1042in_drivers void _fb_sync_write( unsigned int  offset,
     1043                                unsigned int  buffer,
    11381044                                unsigned int  length,
    11391045                                unsigned int  ext )
     
    11421048    unsigned int  src_cluster = ext;
    11431049    unsigned int  dst_address = (unsigned int)&seg_fbf_base + offset;
    1144     unsigned int  dst_cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;  // cluster_xy for I/O
    1145 
    1146     _extended_memcpy( dst_cluster,
     1050
     1051    _extended_memcpy( CLUSTER_IO,
    11471052                      dst_address,
    11481053                      src_cluster,
     
    11591064// - ext    : cluster_xy for the user buffer
    11601065//////////////////////////////////////////////////////////////////////////////////////
    1161 in_drivers void  _fb_sync_read( unsigned int  offset, 
    1162                                 unsigned int  buffer, 
     1066in_drivers void  _fb_sync_read( unsigned int  offset,
     1067                                unsigned int  buffer,
    11631068                                unsigned int  length,
    11641069                                unsigned int  ext )
     
    11671072    unsigned int  dst_cluster = ext;
    11681073    unsigned int  src_address = (unsigned int)&seg_fbf_base + offset;
    1169     unsigned int  src_cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;  // cluster_xy for I/O
    11701074
    11711075    _extended_memcpy( dst_cluster,
    11721076                      dst_address,
    1173                       src_cluster,
     1077                      CLUSTER_IO,
    11741078                      src_address,
    11751079                      length );
     
    11841088in_drivers void _mmc_isr()
    11851089{
    1186     int*         mmc_address = (int*)&seg_mmc_base;
     1090    //int*         mmc_address = (int*)&seg_mmc_base;
    11871091    unsigned int cluster_xy  = _procid() / NB_PROCS_MAX;
    1188    
     1092
    11891093    _tty_printf( "WRITE ERROR signaled by Memory Cache in cluster %x\n", cluster_xy );
    11901094}
    11911095
    11921096///////////////////////////////////////////////////////////////////////////////////////
    1193 // Release a software spin-lock 
     1097// Release a software spin-lock
    11941098///////////////////////////////////////////////////////////////////////////////////////
    11951099in_drivers void _release_lock(size_t index)
    11961100
    11971101{
    1198     if( index >= NB_LOCKS ) 
     1102    if( index >= NB_LOCKS )
    11991103    {
    12001104        _tty_get_lock( 0 );
     
    12031107        _exit();
    12041108    }
    1205    
     1109
    12061110    _spin_lock[index] = 0;
    12071111}
     
    12251129
    12261130    register int   delay = ((_proctime() +_procid()) & 0xF) << 4;
    1227     register int * plock = (int *) &_spin_lock[index];                 
    1228 
    1229     asm volatile ("_locks_llsc:                 \n"
    1230                   "ll   $2,    0(%0)            \n"     // $2 <= _locks_lock
    1231                   "bnez $2,    _locks_delay     \n"     // random delay if busy
    1232                   "li   $3,    1            \n"     // prepare argument for sc 
    1233                   "sc   $3,    0(%0)            \n"     // try to set _locks_busy
    1234                   "bnez $3,    _locks_ok    \n"     // exit if atomic 
     1131    register int * plock = (int *) &_spin_lock[index];
     1132
     1133    asm volatile ("_locks_llsc:             \n"
     1134                  "ll   $2,    0(%0)        \n"     // $2 <= _locks_lock
     1135                  "bnez $2,    _locks_delay \n"     // random delay if busy
     1136                  "li   $3,    1            \n"     // prepare argument for sc
     1137                  "sc   $3,    0(%0)        \n"     // try to set _locks_busy
     1138                  "bnez $3,    _locks_ok    \n"     // exit if atomic
    12351139                  "_locks_delay:            \n"
    12361140                  "move $4,    %1           \n"     // $4 <= delay
     
    12391143                  "beqz $4,    _locks_loop  \n"     // test end delay
    12401144                  "j           _locks_llsc  \n"     // retry
    1241                   "_locks_ok:                   \n"
     1145                  "_locks_ok:           \n"
    12421146                  ::"r"(plock),"r"(delay):"$2","$3","$4");
    12431147}
     
    12481152// - barrier_count[index] <= N
    12491153// - barrier_lock[index]  <= 0
    1250 // All tasks try to initialize the barrier, but the initialisation 
     1154// All tasks try to initialize the barrier, but the initialisation
    12511155// is done by only one task, using LL/SC instructions.
    1252 // This cooperative initialisation is questionnable, 
     1156// This cooperative initialisation is questionnable,
    12531157// because the barrier can ony be initialised once...
    12541158//////////////////////////////////////////////////////////////////////////////////////
    12551159in_drivers void _barrier_init(unsigned int index, unsigned int value)
    12561160{
    1257 
    1258     register int* pinit         = (int*)&_barrier_value[index];
    1259     register int* pcount        = (int*)&_barrier_count[index];
    1260     register int* plock         = (int*)&_barrier_lock[index];
     1161    register int* pinit     = (int*)&_barrier_value[index];
     1162    register int* pcount    = (int*)&_barrier_count[index];
     1163    register int* plock     = (int*)&_barrier_lock[index];
    12611164
    12621165    if ( index >= NB_BARRIERS )
     
    12691172
    12701173    // parallel initialisation using atomic instructions LL/SC
    1271     asm volatile ("_barrier_init_test:                  \n"
    1272                   "ll   $2,     0(%0)                   \n"     // read barrier_value
    1273                   "bnez $2,     _barrier_init_done      \n"
    1274                   "move $3,     %3                              \n"
    1275                   "sc   $3,     0(%0)                   \n"     // try to write barrier_value
    1276                   "beqz $3,     _barrier_init_test      \n"
    1277                   "move $3,     %3                                  \n"
    1278                   "sw   $3,     0(%1)                           \n"     // barrier_count <= barrier_value
    1279                   "move $3, $0                      \n" // 
    1280                   "sw   $3,     0(%2)                           \n"     // barrier_lock <= 0
    1281                   "_barrier_init_done:                  \n"
     1174    asm volatile ("_barrier_init_test:              \n"
     1175                  "ll   $2,     0(%0)               \n" // read barrier_value
     1176                  "bnez $2,     _barrier_init_done  \n"
     1177                  "move $3,     %3                  \n"
     1178                  "sc   $3,     0(%0)               \n" // try to write barrier_value
     1179                  "beqz $3,     _barrier_init_test  \n"
     1180                  "move $3, %3                      \n"
     1181                  "sw   $3, 0(%1)                   \n" // barrier_count <= barrier_value
     1182                  "move $3, $0                      \n" //
     1183                  "sw   $3, 0(%2)                   \n" // barrier_lock <= 0
     1184                  "_barrier_init_done:          \n"
    12821185                  ::"r"(pinit),"r"(pcount),"r"(plock),"r"(value):"$2","$3");
    12831186}
    12841187
    12851188//////////////////////////////////////////////////////////////////////////////////////
    1286 // This blocking function uses a busy_wait technics (on the barrier_lock value), 
    1287 // because the GIET does not support dynamic scheduling/descheduling of tasks. 
     1189// This blocking function uses a busy_wait technics (on the barrier_lock value),
     1190// because the GIET does not support dynamic scheduling/descheduling of tasks.
    12881191// The barrier state is actually defined by two variables:
    12891192// _barrier_count[index] define the number of particpants that are waiting
    1290 // _barrier_lock[index] define the bool variable whose value is polled 
     1193// _barrier_lock[index] define the bool variable whose value is polled
    12911194// The last participant change the value of _barrier_lock[index] to release the barrier...
    12921195// There is at most 16 independant barriers, and an error is returned
     
    12951198in_drivers void _barrier_wait(unsigned int index)
    12961199{
    1297     register int*       pcount          = (int*)&_barrier_count[index];         
    1298     register int        count;
    1299 
    1300     int                lock             = _barrier_lock[index];         
     1200    register int*   pcount      = (int*)&_barrier_count[index];
     1201    register int    count;
     1202    int             lock        = _barrier_lock[index];
    13011203
    13021204    if ( index >= NB_BARRIERS )
     
    13071209        _exit();
    13081210    }
    1309    
     1211
    13101212    // parallel decrement _barrier_count[index] using atomic instructions LL/SC
    13111213    // input : pointer on _barrier_count[index]
    13121214    // output : count = _barrier_count[index] (before decrementation)
    1313     asm volatile ("_barrier_decrement:                          \n"
    1314                   "ll   %0,     0(%1)                           \n"
    1315                   "addi $3,     %0,     -1                      \n"
    1316                   "sc   $3,     0(%1)                           \n"
    1317                   "beqz $3,     _barrier_decrement              \n"
     1215    asm volatile ("_barrier_decrement:                  \n"
     1216                  "ll   %0,     0(%1)                   \n"
     1217                  "addi $3,     %0,     -1              \n"
     1218                  "sc   $3,     0(%1)                   \n"
     1219                  "beqz $3,     _barrier_decrement      \n"
    13181220                  :"=&r"(count)
    13191221                  :"r"(pcount)
     
    13231225    // and the barrier_lock variable, waking up all other waiting tasks
    13241226
    1325     if ( count == 1 )   // last task
     1227    if ( count == 1 )   // last task
    13261228    {
    13271229        _barrier_count[index] = _barrier_value[index];
     
    13291231        _barrier_lock[index]   = (lock == 0) ? 1 : 0;
    13301232    }
    1331     else                // other tasks
    1332     {
    1333         while ( lock == _barrier_lock[index] )  asm volatile("nop");
    1334     }
    1335 } 
     1233    else        // other tasks
     1234    {
     1235        while ( lock == _barrier_lock[index] );
     1236    }
     1237}
    13361238
    13371239
Note: See TracChangeset for help on using the changeset viewer.