Ignore:
Timestamp:
Feb 12, 2013, 6:33:31 PM (12 years ago)
Author:
meunier
Message:

Added support for memspaces and const.
Added an interrupt masking to the "giet_context_switch" syscall
Corrected two bugs in boot/boot_init.c (one minor and one regarding barriers initialization)
Reformatted the code in all files.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/libs/mwmr_channel.c

    r207 r228  
    1919// can be used to get the virtual base address of the channel from it's name.
    2020//
    21 // An MWMR transaction transfer an integer number of items, and an item is
     21// An MWMR transaction transfer    an integer number of items, and an item is
    2222// an integer number of unsigned int (32 bits words).
    2323// The max number of words that can be stored in a MWMR channel is defined by the
     
    3939// If the lock is already taken a fixed delay is introduced before retry.
    4040//////////////////////////////////////////////////////////////////////////////
    41 void mwmr_lock_acquire(unsigned int* lock_address)
    42 {
    43     register unsigned int*      plock = lock_address;
    44     register unsigned int       delay = 100;
     41void mwmr_lock_acquire(unsigned int * lock_address) {
     42    register unsigned int * plock = lock_address;
     43    register unsigned int delay = 100;
    4544    asm volatile (
    46             "mwmr_lock_try:                                     \n"
    47             "ll   $2,    0(%0)                          \n" /* $2 <= lock current value */
    48             "bnez $2,    mwmr_lock_delay        \n" /* retry after delay if lock busy */
    49             "li   $3,    1                                      \n" /* $3 <= argument for sc */
    50             "sc   $3,    0(%0)                          \n" /* try to get lock */
    51             "bnez $3,    mwmr_lock_ok           \n" /* exit if atomic */
    52             "mwmr_lock_delay:                           \n"
     45            "mwmr_lock_try:                    \n"
     46            "ll   $2,    0(%0)                \n" /* $2 <= lock current value */
     47            "bnez $2,    mwmr_lock_delay    \n" /* retry after delay if lock busy */
     48            "li   $3,    1                    \n" /* $3 <= argument for sc */
     49            "sc   $3,    0(%0)                \n" /* try to get lock */
     50            "bnez $3,    mwmr_lock_ok        \n" /* exit if atomic */
     51            "mwmr_lock_delay:                \n"
    5352            "move $4,    %1                 \n" /* $4 <= delay */
    5453            "mwmr_lock_loop:                \n"
    55             "beqz $4,    mwmr_lock_loop         \n" /* test end delay */
    56             "addi $4,    $4,  -1                        \n" /* $4 <= $4 - 1 */
    57             "j           mwmr_lock_try          \n" /* retry ll */
    58             "nop                                                        \n"
    59             "mwmr_lock_ok:                                      \n"
     54            "beqz $4,    mwmr_lock_loop        \n" /* test end delay */
     55            "addi $4,    $4,  -1            \n" /* $4 <= $4 - 1 */
     56            "j           mwmr_lock_try        \n" /* retry ll */
     57            "nop                            \n"
     58            "mwmr_lock_ok:                    \n"
    6059            :
    6160            :"r"(plock), "r"(delay)
    6261            :"$2", "$3", "$4");
    6362}
    64 //////////////////////////////////////////////////////////////////////////////
    65 //         nb_mwmr_write()
     63
     64
     65//////////////////////////////////////////////////////////////////////////////
     66//       nb_mwmr_write()
    6667// This is a non-blocking function.
    6768// The nitems parameter is the number of items to be transfered.
     
    7273// the number of read items (it can be 0).
    7374//////////////////////////////////////////////////////////////////////////////
    74 unsigned int nb_mwmr_write( mwmr_channel_t*     mwmr,
    75                             unsigned int*               buffer,
    76                             unsigned int                nitems )
    77 {
    78     unsigned int        x;
    79     unsigned int        spaces;         // number of empty slots (in words)
    80     unsigned int        nwords;         // requested transfer length (in words)
    81     unsigned int    depth;              // channel depth (in words)
    82     unsigned int    width;              // channel width (in words)
    83     unsigned int    sts;        // channel sts
    84     unsigned int    ptw;        // channel ptw
    85 
    86     if(nitems == 0) return 0;
     75unsigned int nb_mwmr_write(mwmr_channel_t * mwmr, unsigned int * buffer, unsigned int nitems) {
     76    unsigned int x;
     77    unsigned int spaces; // number of empty slots (in words)
     78    unsigned int nwords; // requested transfer length (in words)
     79    unsigned int depth;  // channel depth (in words)
     80    unsigned int width;  // channel width (in words)
     81    unsigned int sts;    // channel sts
     82    unsigned int ptw;    // channel ptw
     83
     84    if (nitems == 0) {
     85        return 0;
     86    }
    8787
    8888    // get the lock
    89     mwmr_lock_acquire( &mwmr->lock );
     89    mwmr_lock_acquire(&mwmr->lock);
    9090
    9191    // access fifo status
    92     depth  = mwmr->depth;
    93     width  = mwmr->width;
    94     sts    = mwmr->sts;
    95     ptw    = mwmr->ptw;
     92    depth = mwmr->depth;
     93    width = mwmr->width;
     94    sts = mwmr->sts;
     95    ptw = mwmr->ptw;
    9696    spaces = depth - sts;
    9797    nwords = width * nitems;
    9898
    99     if( spaces >= nwords )      // transfer nitems, release lock and return
    100     {
    101         for ( x = 0 ; x < nwords ; x++ ) 
    102         {
     99    if (spaces >= nwords) { // transfer nitems, release lock and return
     100        for (x = 0; x < nwords; x++) {
    103101            mwmr->data[ptw] = buffer[x];
    104             if ( (ptw + 1) == depth ) ptw = 0;
    105             else                      ptw = ptw + 1;
    106         }
    107         mwmr->sts  = mwmr->sts + nwords;
    108         mwmr->ptw  = ptw;
     102            if ((ptw + 1) == depth) {
     103                ptw = 0;
     104            }
     105            else {
     106                ptw = ptw + 1;
     107            }
     108        }
     109        mwmr->sts = mwmr->sts + nwords;
     110        mwmr->ptw = ptw;
    109111        mwmr->lock = 0;
    110112        return nitems;
    111113    }
    112    
    113     else if ( spaces < width )  // release lock and return
    114     {
     114    else if (spaces < width) {
     115        // release lock and return
    115116        mwmr->lock = 0;
    116117        return 0;
    117118    }
    118     else        // transfer as many items as possible, release lock and return
    119     {
    120         nwords = (spaces/width) * width;        // integer number of items
    121         for ( x = 0 ; x < nwords ; x++ ) 
    122         {
     119    else {
     120        // transfer as many items as possible, release lock and return
     121        nwords = (spaces / width) * width;    // integer number of items
     122        for (x = 0; x < nwords; x++) {
    123123            mwmr->data[ptw] = buffer[x];
    124             if ( (ptw + 1) == depth ) ptw = 0;
    125             else                      ptw = ptw + 1;
    126         }
    127         mwmr->sts  = sts + nwords;
    128         mwmr->ptw  = ptw;
    129         mwmr->lock = 0;
    130         return (nwords/width);
     124            if ((ptw + 1) == depth) {
     125                ptw = 0;
     126            }
     127            else {
     128                ptw = ptw + 1;
     129            }
     130        }
     131        mwmr->sts = sts + nwords;
     132        mwmr->ptw = ptw;
     133        mwmr->lock = 0;
     134        return (nwords / width);
    131135    }
    132136} // end nb_mwmr_write()
    133137
    134 //////////////////////////////////////////////////////////////////////////////
    135 //      mwmr_write()
     138
     139//////////////////////////////////////////////////////////////////////////////
     140//    mwmr_write()
    136141// This blocking function returns only when the transfer is completed.
    137142// The nitems parameter is the number of items to be transfered.
     
    142147// after a random delay.
    143148//////////////////////////////////////////////////////////////////////////////
    144 void mwmr_write( mwmr_channel_t*        mwmr,
    145                  unsigned int*          buffer,
    146                  unsigned int           nitems )
    147 {
    148     unsigned int        x;
    149     unsigned int        spaces;         // number of empty slots (in words)
    150     unsigned int        nwords;         // requested transfer length (in words)
    151     unsigned int    depth;              // channel depth (in words)
    152     unsigned int    width;              // channel width (in words)
    153     unsigned int    sts;        // channel sts
    154     unsigned int    ptw;        // channel ptw
    155 
    156     if(nitems == 0) return;
    157 
    158     while(1)
    159     {
     149void mwmr_write(mwmr_channel_t * mwmr, unsigned int * buffer, unsigned int nitems) {
     150    unsigned int x;
     151    unsigned int spaces; // number of empty slots (in words)
     152    unsigned int nwords; // requested transfer length (in words)
     153    unsigned int depth;  // channel depth (in words)
     154    unsigned int width;  // channel width (in words)
     155    unsigned int sts;    // channel sts
     156    unsigned int ptw;    // channel ptw
     157
     158    if (nitems == 0) {
     159        return;
     160    }
     161
     162    while (1) {
    160163        // get the lock
    161164        mwmr_lock_acquire(&mwmr->lock);
    162165
    163166        // compute spaces and nwords
    164         depth  = mwmr->depth;
    165         width  = mwmr->width;
    166         sts    = mwmr->sts;
    167         ptw    = mwmr->ptw;
     167        depth = mwmr->depth;
     168        width = mwmr->width;
     169        sts  = mwmr->sts;
     170        ptw  = mwmr->ptw;
    168171        spaces = depth - sts;
    169172        nwords = width * nitems;
    170173
    171         if( spaces >= nwords )  // write nwords, release lock and return
    172         {
    173             for ( x = 0 ; x < nwords ; x++ ) 
    174             {
     174        if (spaces >= nwords) {
     175            // write nwords, release lock and return
     176            for (x = 0; x < nwords; x++) {
    175177                mwmr->data[ptw] = buffer[x];
    176                 if ( (ptw + 1) == depth ) ptw = 0;
    177                 else                      ptw = ptw + 1;
    178             }
    179             mwmr->ptw  = ptw;
    180             mwmr->sts  = sts + nwords;
     178                if ((ptw + 1) == depth) {
     179                    ptw = 0;
     180                }
     181                else {
     182                    ptw = ptw + 1;
     183                }
     184            }
     185            mwmr->ptw = ptw;
     186            mwmr->sts = sts + nwords;
    181187            mwmr->lock = 0;
    182188            return;
    183189        }
    184         else if ( spaces < width )      // release lock and retry after delay
    185         {
    186             mwmr->lock = 0;
    187             for ( x = giet_rand()>>8 ; x > 0 ; x-- ) asm volatile ( "nop" );
    188         }
    189         else    // write as many items as possible, release lock and retry after delay
    190         {
    191             nwords = (spaces/width) * width;  // integer number of items
    192             for ( x = 0 ; x < nwords ; x++ ) 
    193             {
     190        else if (spaces < width) {
     191            // release lock and retry after delay
     192            mwmr->lock = 0;
     193        }
     194        else {
     195            // write as many items as possible, release lock and retry after delay
     196            nwords = (spaces / width) * width;  // integer number of items
     197            for (x = 0; x < nwords; x++) {
    194198                mwmr->data[ptw] = buffer[x];
    195                 if ( (ptw + 1) == depth ) ptw = 0;
    196                 else                      ptw = ptw + 1;
    197             }
    198             mwmr->sts  = sts + nwords;
    199             mwmr->ptw  = ptw;
    200             buffer     = buffer + nwords;
    201             nitems     = nitems - (nwords/width);
    202             mwmr->lock = 0;
    203         }
    204         // random delay before retry
    205         for ( x = giet_rand()>>6 ; x > 0 ; x-- ) asm volatile ( "nop" );
     199                if ((ptw + 1) == depth) {
     200                    ptw = 0;
     201                }
     202                else {
     203                    ptw = ptw + 1;
     204                }
     205            }
     206            mwmr->sts = sts + nwords;
     207            mwmr->ptw = ptw;
     208            buffer = buffer + nwords;
     209            nitems = nitems - (nwords/width);
     210            mwmr->lock = 0;
     211        }
     212        giet_context_switch();
    206213    }
    207214} // end mwmr_write()
    208215
    209 //////////////////////////////////////////////////////////////////////////////
    210 //         nb_mwmr_read()
     216
     217//////////////////////////////////////////////////////////////////////////////
     218//       nb_mwmr_read()
    211219// This is a non-blocking function.
    212220// The nitems parameter is the number of items to be transfered.
     
    217225// the number of read items (it can be 0).
    218226//////////////////////////////////////////////////////////////////////////////
    219 unsigned int nb_mwmr_read( mwmr_channel_t*      mwmr,
    220                            unsigned int*                buffer,
    221                            unsigned int                 nitems )
    222 {
    223     unsigned int        x;
    224     unsigned int        nwords;         // requested transfer length (in words)
    225     unsigned int    depth;              // channel depth (in words)
    226     unsigned int    width;              // channel width (in words)
    227     unsigned int    sts;        // channel sts
    228     unsigned int    ptr;        // channel ptr
    229 
    230     if(nitems == 0) return 0;
     227unsigned int nb_mwmr_read(mwmr_channel_t * mwmr, unsigned int * buffer, unsigned int nitems) {
     228    unsigned int x;
     229    unsigned int nwords; // requested transfer length (in words)
     230    unsigned int depth;  // channel depth (in words)
     231    unsigned int width;  // channel width (in words)
     232    unsigned int sts;    // channel sts
     233    unsigned int ptr;    // channel ptr
     234
     235    if (nitems == 0) {
     236        return 0;
     237    }
    231238
    232239    // get the lock
    233     mwmr_lock_acquire( &mwmr->lock );
     240    mwmr_lock_acquire(&mwmr->lock);
    234241
    235242    // access fifo status
    236     depth  = mwmr->depth;
    237     width  = mwmr->width;
    238     sts    = mwmr->sts;
    239     ptr    = mwmr->ptr;
     243    depth = mwmr->depth;
     244    width = mwmr->width;
     245    sts = mwmr->sts;
     246    ptr = mwmr->ptr;
    240247    nwords = width * nitems;
    241248
    242     if( sts >= nwords )         // transfer nitems, release lock and return
    243     {
    244         for ( x = 0 ; x < nwords ; x++ ) 
    245         {
     249    if (sts >= nwords) {
     250        // transfer nitems, release lock and return
     251        for (x = 0; x < nwords; x++) {
    246252            buffer[x] = mwmr->data[ptr];
    247             if ( (ptr + 1) == depth ) ptr = 0;
    248             else                      ptr = ptr + 1;
    249         }
    250         mwmr->sts  = mwmr->sts - nwords;
    251         mwmr->ptr  = ptr;
     253            if ((ptr + 1) == depth) {
     254                ptr = 0;
     255            }
     256            else {
     257                ptr = ptr + 1;
     258            }
     259        }
     260        mwmr->sts = mwmr->sts - nwords;
     261        mwmr->ptr = ptr;
    252262        mwmr->lock = 0;
    253263        return nitems;
    254264    }
    255    
    256     else if ( sts < width )     // release lock and return
    257     {
     265    else if (sts < width) {
     266        // release lock and return
    258267        mwmr->lock = 0;
    259268        return 0;
    260269    }
    261     else        // transfer as many items as possible, release lock and return
    262     {
    263         nwords = (sts/width) * width;   // integer number of items
    264         for ( x = 0 ; x < nwords ; x++ ) 
    265         {
     270    else {
     271        // transfer as many items as possible, release lock and return
     272        nwords = (sts / width) * width; // integer number of items
     273        for (x = 0 ; x < nwords ; x++) {
    266274            buffer[x] = mwmr->data[ptr];
    267             if ( (ptr + 1) == depth ) ptr = 0;
    268             else                      ptr = ptr + 1;
    269         }
    270         mwmr->sts  = sts - nwords;
    271         mwmr->ptr  = ptr;
    272         mwmr->lock = 0;
    273         return (nwords/width);
    274     }
    275 } // nb_mwmr_read()
    276 
    277 //////////////////////////////////////////////////////////////////////////////
    278 //      mwmr_read()
     275            if ((ptr + 1) == depth) {
     276                ptr = 0;
     277            }
     278            else {
     279                ptr = ptr + 1;
     280            }
     281        }
     282        mwmr->sts = sts - nwords;
     283        mwmr->ptr = ptr;
     284        mwmr->lock = 0;
     285        return (nwords / width);
     286    }
     287} // nb_mwmr_read()
     288
     289
     290//////////////////////////////////////////////////////////////////////////////
     291//    mwmr_read()
    279292// This blocking function returns only when the transfer is completed.
    280293// The nitems parameter is the number of items to be transfered.
     
    285298// after a random delay.
    286299//////////////////////////////////////////////////////////////////////////////
    287 void mwmr_read( mwmr_channel_t*         mwmr,
    288                 unsigned int*           buffer,
    289                 unsigned int            nitems )
    290 {
    291     unsigned int        x;
    292     unsigned int        nwords;         // requested transfer length (in words)
    293     unsigned int    depth;              // channel depth (in words)
    294     unsigned int    width;              // channel width (in words)
    295     unsigned int    sts;        // channel sts
    296     unsigned int    ptr;        // channel ptr
    297 
    298     if(nitems == 0) return;
    299 
    300     while(1)
    301     {
     300void mwmr_read( mwmr_channel_t * mwmr, unsigned int * buffer, unsigned int nitems) {
     301    unsigned int x;
     302    unsigned int nwords; // requested transfer length (in words)
     303    unsigned int depth;  // channel depth (in words)
     304    unsigned int width;  // channel width (in words)
     305    unsigned int sts;    // channel sts
     306    unsigned int ptr;    // channel ptr
     307
     308    if (nitems == 0) {
     309        return;
     310    }
     311
     312    while (1) {
    302313        // get the lock
    303         mwmr_lock_acquire( &mwmr->lock );
     314        mwmr_lock_acquire(&mwmr->lock);
    304315
    305316        // compute nwords
    306         depth  = mwmr->depth;
    307         width  = mwmr->width;
    308         sts    = mwmr->sts;
    309         ptr    = mwmr->ptr;
     317        depth = mwmr->depth;
     318        width = mwmr->width;
     319        sts = mwmr->sts;
     320        ptr = mwmr->ptr;
    310321        nwords = width * nitems;
    311322
    312         if( sts >= nwords )     // read nwords, release lock and return
    313         {
    314             for ( x = 0 ; x < nwords ; x++ ) 
    315             {
     323        if (sts >= nwords) {
     324            // read nwords, release lock and return
     325            for (x = 0; x < nwords; x++) {
    316326                buffer[x] = mwmr->data[ptr];
    317                 if ( (ptr + 1) == depth ) ptr = 0;
    318                 else                      ptr = ptr + 1;
    319             }
    320             mwmr->sts  = mwmr->sts - nwords;
    321             mwmr->ptr  = ptr;
     327                if ((ptr + 1) == depth) {
     328                    ptr = 0;
     329                }
     330                else {
     331                    ptr = ptr + 1;
     332                }
     333            }
     334            mwmr->sts = mwmr->sts - nwords;
     335            mwmr->ptr = ptr;
    322336            mwmr->lock = 0;
    323337            return;
    324338        }
    325         else if ( sts < width ) // release lock and retry after delay
    326         {
    327             mwmr->lock = 0;
    328             for ( x = giet_rand()>>8 ; x > 0 ; x-- ) asm volatile ( "nop" );
    329         }
    330         else    // read as many items as possible, release lock and retry after delay
    331         {
    332             nwords = (sts/width) * width;       // integer number of items
    333             for ( x = 0 ; x < nwords ; x++ ) 
    334             {
     339        else if (sts < width) {
     340            // release lock and retry after delay
     341            mwmr->lock = 0;
     342        }
     343        else {   // read as many items as possible, release lock and retry after delay
     344            nwords = (sts / width) * width; // integer number of items
     345            for (x = 0; x < nwords; x++) {
    335346                buffer[x] = mwmr->data[ptr];
    336                 if ( (ptr + 1) == depth ) ptr = 0;
    337                 else                      ptr = ptr + 1;
    338             }
    339             mwmr->sts  = sts - nwords;
    340             mwmr->ptr  = ptr;
    341             buffer     = buffer + nwords;
    342             nitems     = nitems - (nwords/width);
    343             mwmr->lock = 0;
    344         }
    345         // random delay before retry
    346         for ( x = giet_rand()>>6 ; x > 0 ; x-- ) asm volatile ( "nop" );
     347                if ((ptr + 1) == depth) {
     348                    ptr = 0;
     349                }
     350                else {
     351                    ptr = ptr + 1;
     352                }
     353            }
     354            mwmr->sts = sts - nwords;
     355            mwmr->ptr = ptr;
     356            buffer = buffer + nwords;
     357            nitems = nitems - (nwords/width);
     358            mwmr->lock = 0;
     359        }
     360        giet_context_switch();
    347361    }
    348362} // end mwmr_read()
    349363
    350364
     365// Local Variables:
     366// tab-width: 4
     367// c-basic-offset: 4
     368// c-file-offsets:((innamespace . 0)(inline-open . 0))
     369// indent-tabs-mode: nil
     370// End:
     371// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
     372
Note: See TracChangeset for help on using the changeset viewer.