Ignore:
Timestamp:
Feb 12, 2014, 9:51:23 AM (10 years ago)
Author:
alain
Message:
  • Updatre the gier_tsar to support the vci_iopic component in the tsar_generic_leti plat-form.
  • Modify the soft_transpose_giet application to make optional the graphic display on frame buffer and to introduce a systematic auto-check
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/softs/giet_tsar/stdio.c

    r626 r629  
    44// Date : janvier 2014
    55//
    6 // This file define varions functions that can be used by applications to access
     6// This file defines various functions that can be used by applications to access
    77// peripherals, for the TSAR multi-processors multi_clusters architecture.
    88// There is NO separation between application code and system code, as the
     
    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
    2425//
    2526// The follobing base addresses must be defined in the ldscript
     
    3132#include "stdio.h"
    3233
     34#if !defined(NB_PROCS_MAX)
     35#error: you must define NB_PROCS_MAX in the hard_config.h file
     36#endif
     37
     38#if !defined(USE_EXT_IO)
     39#error: you must define USE_EXT_IO in the hard_config.h file
     40#endif
     41
     42#if !defined(X_SIZE)
     43#error: you must define X_SIZE in the hard_config.h file
     44#endif
     45
     46#if !defined(Y_SIZE)
     47#error: you must define Y_SIZE in the hard_config.h file
     48#endif
     49
     50#if !defined(X_WIDTH)
     51#error: you must define X_WIDTH in the hard_config.h file
     52#endif
     53
     54#if (X_WIDTH != 4)
     55#error: The X_WIDTH parameter must be equal to 4
     56#endif
     57
     58#if !defined(Y_WIDTH)
     59#error: you must define X_WIDTH in the hard_config.h file
     60#endif
     61
     62#if (X_WIDTH != 4)
     63#error: The Y_WIDTH parameter must be equal to 4
     64#endif
     65
     66#if !defined(NB_TTY_CHANNELS)
     67#error: you must define NB_TTY_CHANNELS in the hard_config.h file
     68#endif
     69
     70
     71
     72
    3373#define NB_LOCKS      256
    3474#define NB_BARRIERS   16
     
    74114
    75115////////////////////////////////////////////////////////////////////////////////////////
    76 // Taken from MutekH.
     116// Memcopy taken from MutekH.
    77117////////////////////////////////////////////////////////////////////////////////////////
    78118in_drivers void* _memcpy( void*        _dst,
     
    100140    return _dst;
    101141}
    102 
     142////////////////////////////////////////////////////////////////////////////////////////
     143// Memcopy using extended addresses
     144////////////////////////////////////////////////////////////////////////////////////////
     145in_drivers void  _extended_memcpy( unsigned int dst_cluster,
     146                                   unsigned int dst_address,
     147                                   unsigned int src_cluster,
     148                                   unsigned int src_address,
     149                                   unsigned int length )
     150{
     151    if ( (dst_address & 0x3) || (src_address & 0x3) || (length & 0x3) )
     152    {
     153        _tty_get_lock( 0 );
     154        _tty_puts( "ERROR in _extended_memcpy()" );
     155        _tty_release_lock( 0 );
     156        _exit();
     157    }
     158
     159    unsigned int i;
     160    unsigned int word;
     161
     162    for ( i = 0 ; i < length ; i = i+4 )
     163    {
     164        word = _word_extended_read( src_cluster, (src_address + i) );
     165        _word_extended_write( dst_cluster, (dst_address + i), word );
     166    }
     167}
    103168////////////////////////////////////////////////////////////////////////////////////////
    104169// Access CP0 and returns processor ident
     
    179244}
    180245
    181 ///////////////////////////////////////////////////////////////////////////////////////
    182 // Exit (suicide) after printing message on  a TTY terminal.
     246////////////////////////////////////////////////////////////////////////////
     247// This function makes a physical read access to a 32 bits word in memory,
     248// after a temporary paddr extension.
     249////////////////////////////////////////////////////////////////////////////
     250in_drivers unsigned int _word_extended_read( unsigned int  cluster,
     251                                             unsigned int  address )
     252{
     253    unsigned int value;
     254    asm volatile(
     255            "li      $3,        0xFFFFFFFE    \n"
     256            "mfc0    $2,        $12           \n"
     257            "and     $3,        $2, $3        \n"
     258            "mtc0    $3,        $12           \n"     /* IRQ disabled     */
     259
     260            "mtc2    %2,        $24           \n"     /* PADDR_EXT <= msb */   
     261            "lw      %0,        0(%1)         \n"     /* value <= *paddr  */
     262            "mtc2    $0,        $24           \n"     /* PADDR_EXT <= 0   */
     263
     264            "li      $3,        0x00000001    \n"
     265            "mfc0    $2,        $12           \n"
     266            "or      $3,        $3, $2        \n"
     267            "mtc0    $3,        $12           \n"     /* IRQ enabled      */
     268            : "=r" (value)
     269            : "r" (address), "r" (cluster)
     270            : "$2", "$3" );
     271    return value;
     272}
     273////////////////////////////////////////////////////////////////////////////
     274// This function makes a physical read access to a single byte in memory,
     275// after a temporary paddr extension.
     276////////////////////////////////////////////////////////////////////////////
     277in_drivers unsigned char _byte_extended_read( unsigned int  cluster,
     278                                              unsigned int  address )
     279{
     280    unsigned int value;
     281    asm volatile(
     282            "li      $3,        0xFFFFFFFE    \n"
     283            "mfc0    $2,        $12           \n"
     284            "and     $3,        $2, $3        \n"
     285            "mtc0    $3,        $12           \n"     /* IRQ disabled     */
     286
     287            "mtc2    %2,        $24           \n"     /* PADDR_EXT <= msb */   
     288            "lb      %0,        0(%1)         \n"     /* value <= *paddr  */
     289            "mtc2    $0,        $24           \n"     /* PADDR_EXT <= 0   */
     290
     291            "li      $3,        0x00000001    \n"
     292            "mfc0    $2,        $12           \n"
     293            "or      $3,        $3, $2        \n"
     294            "mtc0    $3,        $12           \n"     /* IRQ enabled      */
     295            : "=r" (value)
     296            : "r" (address), "r" (cluster)
     297            : "$2", "$3" );
     298    return (unsigned char)value;
     299}
     300////////////////////////////////////////////////////////////////////////////
     301// This function makes a physical write access to a 32 bits word in memory,
     302// after a temporary DTLB address extension.
     303////////////////////////////////////////////////////////////////////////////
     304in_drivers void _word_extended_write( unsigned int  cluster,
     305                                      unsigned int  address,
     306                                      unsigned int  word )
     307{
     308    asm volatile(
     309            "li      $3,        0xFFFFFFFE    \n"
     310            "mfc0    $2,        $12           \n"
     311            "and     $3,        $2, $3        \n"
     312            "mtc0    $3,        $12           \n"     /* IRQ disabled     */
     313
     314            "mtc2    %2,        $24           \n"     /* PADDR_EXT <= msb */   
     315            "sw      %0,        0(%1)         \n"     /* *paddr <= value  */
     316            "mtc2    $0,        $24           \n"     /* PADDR_EXT <= 0   */   
     317
     318            "li      $3,        0x00000001    \n"
     319            "mfc0    $2,        $12           \n"
     320            "or      $3,        $2, $3        \n"
     321            "mtc0    $3,        $12           \n"     /* IRQ enabled      */
     322            :
     323            : "r" (word), "r" (address), "r" (cluster)
     324            : "$2", "$3");
     325}
     326////////////////////////////////////////////////////////////////////////////
     327// This function makes a physical write access to single byte in memory,
     328// after a temporary DTLB de-activation and address extension.
     329////////////////////////////////////////////////////////////////////////////
     330in_drivers void _byte_extended_write( unsigned int  cluster,
     331                                      unsigned int  address,
     332                                      unsigned char byte )
     333{
     334    asm volatile(
     335            "li      $3,        0xFFFFFFFE    \n"
     336            "mfc0    $2,        $12           \n"
     337            "and     $3,        $2, $3        \n"
     338            "mtc0    $3,        $12           \n"     /* IRQ disabled     */
     339
     340            "mtc2    %2,        $24           \n"     /* PADDR_EXT <= msb */   
     341            "sb      %0,        0(%1)         \n"     /* *paddr <= value  */
     342            "mtc2    $0,        $24           \n"     /* PADDR_EXT <= 0   */   
     343
     344            "li      $3,        0x00000001    \n"
     345            "mfc0    $2,        $12           \n"
     346            "or      $3,        $2, $3        \n"
     347            "mtc0    $3,        $12           \n"     /* IRQ enabled      */
     348            :
     349            : "r" (byte), "r" (address), "r" (cluster)
     350            : "$2", "$3");
     351}
     352
     353///////////////////////////////////////////////////////////////////////////////////////
     354// Exit (suicide) after printing message on TTY0
    183355///////////////////////////////////////////////////////////////////////////////////////
    184356in_drivers void _exit()
     
    189361    unsigned int y       = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1);
    190362
    191     _tty_printf("\n\n!!!  Exit  Processor (%d,%d,%d)  !!!\n", x, y, l );
     363    _tty_get_lock( 0 );
     364    _tty_puts("\n !!! exit proc[");
     365    _tty_putd( x );
     366    _tty_puts(",");
     367    _tty_putd( y );
     368    _tty_puts(",");
     369    _tty_putd( l );
     370    _tty_puts("]  !!!\n");
     371    _tty_release_lock( 0 );
    192372
    193373    while(1) asm volatile("nop");   // infinite loop...
     
    227407///////////////////////////////////////////////////////////////////////////////////////
    228408//  The total number of TTY terminals is defined by NB_TTY_CHANNELS.
    229 //  1. If there is only one terminal, it is supposed to be shared, and used by
    230 //     all processors: a lock must be taken before display.
    231 //  2. If there is several terminals, and the number of processors is smaller
    232 //     than the number of terminals, there is one terminal per processor, but
    233 //     the TTY index is not equal to the proc_id, due to cluster indexing policy:
    234 //     - proc_id = cluster_xy * NB_PROCS_MAX + local_id (with cluster_xy = x << Y_WIDTH + y)
    235 //     - tty_id  = cluster_id * NB_PROCS_MAX + local_id (with cluster_id = x * Y_SIZE + y)
    236 //  3. If the computed tty_id is larger than NB_TTY_CHANNELS, an error is returned.
     409//  - If there is only one terminal, it is supposed to be shared, and used by
     410//    all processors: a lock must be taken before display.
     411//  - If there is several terminals, and the number of processors is smaller
     412//    than the number of terminals, there is one terminal per processor, but
     413//    the TTY index is not equal to the proc_id, due to cluster indexing policy:
     414//    proc_id = cluster_xy * NB_PROCS_MAX + local_id (with cluster_xy = x << Y_WIDTH + y)
     415//    tty_id  = cluster_id * NB_PROCS_MAX + local_id (with cluster_id = x * Y_SIZE + y)
     416//  - If the computed tty_id is larger than NB_TTY_CHANNELS, an error is returned.
     417///////////////////////////////////////////////////////////////////////////////////////
     418//  If USE_EXT_IO is set, we use the TTY controler implemented in cluster_io
     419//  (x = X_SIZE-1 / y = Y_SIZE), which requires and extended address access.
     420//  If USE_EXT_IO not set, we use the single channel TTY contrÃŽler in cluster (0,0).
     421///////////////////////////////////////////////////////////////////////////////////////
     422
    237423///////////////////////////////////////////////////////////////////////////////////////
    238424// Write one or several characters directly from a fixed length user buffer
    239425// to the TTY_WRITE register of the TTY controler.
     426// The channel index must be checked by the calling function.
    240427// This is a non blocking call : it test the TTY_STATUS register.
    241428// If the TTY_STATUS_WRITE bit is set, the transfer stops and the function
     
    246433                           unsigned int    channel )
    247434{
    248     char*           tty_address;
    249     unsigned int    base                = (unsigned int)&seg_tty_base;
    250     unsigned int    nwritten    = 0;
    251     int i;
    252 
    253     tty_address = (char*)(base + channel*TTY_SPAN*4);
     435    unsigned int    base       = (unsigned int)&seg_tty_base + channel*TTY_SPAN*4;
     436    unsigned int    nwritten   = 0;
     437    unsigned int    cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
     438    unsigned int    status;
     439    unsigned int        i;
    254440
    255441    for ( i=0 ; i < length ; i++ )
    256442    {
    257         if((tty_address[TTY_STATUS*4] & 0x2) == 0x2)  break;
    258         else
    259         {
    260             tty_address[TTY_WRITE*4] = buffer[i]; // write character
    261             nwritten++;
     443        if( USE_EXT_IO )    // extended addressing to reach cluster_io
     444        {
     445            status = _word_extended_read( cluster_io, base + TTY_STATUS*4 );
     446            if ( (status & 0x2) == 0x2 ) break;
     447            else
     448            {
     449                _byte_extended_write( cluster_io, base + TTY_WRITE*4 , buffer[i] );
     450                nwritten++;
     451            }
     452        }
     453        else                // direct addressing to cluster(0,0)
     454        {
     455            char* tty = (char*)base;
     456            if ( (tty[TTY_STATUS*4] & 0x2) == 0x2 )  break;
     457            else
     458            {
     459                tty[TTY_WRITE*4] = buffer[i]; // write character
     460                nwritten++;
     461            }
    262462        }
    263463    }
     
    265465    return nwritten;
    266466}
     467
    267468///////////////////////////////////////////////////////////////////////////////////////
    268469// Fetch one character directly from the TTY_READ register of the TTY controler,
    269470// and writes this character to the user buffer.
     471// The channel index must be checked by the calling function.
    270472// This is a non blocking call : it returns 0 if the register is empty,
    271473// and returns 1 if the register is full.
     
    274476                          unsigned int   channel )
    275477{
    276     char*           tty_address;
    277     unsigned int    base                = (unsigned int)&seg_tty_base;
    278 
    279     tty_address = (char*)(base + channel*TTY_SPAN*4);
    280 
    281     if((tty_address[TTY_STATUS*4] & 0x1) == 0x1)
    282     {
    283         buffer[0] = tty_address[TTY_READ*4];
    284         return 1;
     478    unsigned int    base       = (unsigned int)&seg_tty_base + channel*TTY_SPAN*4;
     479    unsigned int    cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
     480    unsigned int    status;
     481
     482    if( USE_EXT_IO )
     483    {
     484        status = _word_extended_read( cluster_io, base + TTY_STATUS*4 );
     485        if ( (status & 0x1) == 0x1 )
     486        {
     487            buffer[0] = (char)_word_extended_read( cluster_io, base + TTY_READ*4 );
     488            return 1;
     489        }
     490        else
     491        {
     492            return 0;
     493        }
    285494    }
    286495    else
    287496    {
    288         return 0;
    289     }
    290 }
     497        char* tty = (char*)base;
     498
     499        if((tty[TTY_STATUS*4] & 0x1) == 0x1)
     500        {
     501            buffer[0] = tty[TTY_READ*4];
     502            return 1;
     503        }
     504        else
     505        {
     506            return 0;
     507        }
     508    }
     509}
     510
    291511//////////////////////////////////////////////////////////////////////////////
    292512// This function displays a string on TTY0.
     
    356576in_drivers void _tty_get_lock( unsigned int channel )
    357577{
    358     unsigned int* tty_address = (unsigned int *) &seg_tty_base;
    359     while ( tty_address[channel * TTY_SPAN + TTY_CONFIG] ) asm volatile("nop");
     578    if ( USE_EXT_IO )  // extended addressing to cluster_io
     579    {
     580        unsigned int    cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
     581        unsigned int    address    = (unsigned int)&seg_tty_base
     582                                     + ((TTY_CONFIG + channel*TTY_SPAN)*4);
     583        while ( _word_extended_read( cluster_io, address ) ) asm volatile("nop");
     584    }
     585    else               // direct addressing to cluster(0,0)
     586    {
     587        unsigned int* tty = (unsigned int *) &seg_tty_base;
     588        while ( tty[channel * TTY_SPAN + TTY_CONFIG] ) asm volatile("nop");
     589    }
    360590}
    361591
     
    366596in_drivers void _tty_release_lock( unsigned int channel )
    367597{
    368     unsigned int* tty_address = (unsigned int *) &seg_tty_base;
    369     tty_address[channel * TTY_SPAN + TTY_CONFIG] = 0;
     598    if ( USE_EXT_IO )  // extended addressing to cluster_io
     599    {
     600        unsigned int    cluster_io = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
     601        unsigned int    address    = (unsigned int)&seg_tty_base
     602                                     + ((TTY_CONFIG + channel*TTY_SPAN)*4);
     603        _word_extended_write( cluster_io, address, 0 );
     604    }
     605    else               // direct addressing to cluster(0,0)
     606    {
     607        unsigned int* tty_address = (unsigned int *) &seg_tty_base;
     608        tty_address[channel * TTY_SPAN + TTY_CONFIG] = 0;
     609    }
    370610}
    371611
     
    383623    unsigned int y;
    384624
    385     // compute TTY terminal index
    386     if ( NB_TTY_CHANNELS == 1 )
    387     {
    388         channel = 0;
    389     }
    390     else
    391     {
    392         l           = (proc_id % NB_PROCS_MAX);
    393         x           = (proc_id / NB_PROCS_MAX) >> Y_WIDTH;
    394         y           = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1);
    395         channel = (x * Y_SIZE + y) * NB_PROCS_MAX + l;
    396         if (channel >= NB_TTY_CHANNELS )
    397         {
    398             _tty_get_lock( 0 );
    399             _tty_puts( "ERROR in _tty_getc()\n" );
    400             _tty_release_lock( 0 );
    401             _exit();
    402         }
     625    // check TTY channel
     626    l           = (proc_id % NB_PROCS_MAX);
     627    x           = (proc_id / NB_PROCS_MAX) >> Y_WIDTH;
     628    y           = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1);
     629    channel = (x * Y_SIZE + y) * NB_PROCS_MAX + l;
     630    if (channel >= NB_TTY_CHANNELS )
     631    {
     632        _tty_get_lock( 0 );
     633        _tty_puts( "ERROR in _tty_getc(): TTY index too large\n" );
     634        _tty_release_lock( 0 );
     635        _exit();
    403636    }
    404637
     
    433666    unsigned int  i;
    434667    unsigned int  channel;
    435     unsigned int  l;
    436668    unsigned int  x;
    437669    unsigned int  y;
    438 
    439     // compute TTY terminal index
    440     if ( NB_TTY_CHANNELS == 1 )
    441     {
    442         channel = 0;
    443     }
    444     else
    445     {
    446         l           = (proc_id % NB_PROCS_MAX);
    447         x           = (proc_id / NB_PROCS_MAX) >> Y_WIDTH;
    448         y           = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1);
    449         channel = (x * Y_SIZE + y) * NB_PROCS_MAX + l;
    450         if (channel >= NB_TTY_CHANNELS )   
    451         {
    452             _tty_get_lock( 0 );
    453             _tty_puts( "ERROR in _tty_getw()\n" );
    454             _tty_release_lock( 0 );
    455             _exit();
    456         }
     670    unsigned int  l;
     671
     672    // check TTY channel
     673    l           = (proc_id % NB_PROCS_MAX);
     674    x           = (proc_id / NB_PROCS_MAX) >> Y_WIDTH;
     675    y           = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1);
     676    channel = (x * Y_SIZE + y) * NB_PROCS_MAX + l;
     677    if (channel >= NB_TTY_CHANNELS )
     678    {
     679        _tty_get_lock( 0 );
     680        _tty_puts( "ERROR in _tty_getw(): TTY index too large\n" );
     681        _tty_release_lock( 0 );
     682        _exit();
    457683    }
    458684
     
    519745
    520746    unsigned int channel;
    521     unsigned int l;
    522747    unsigned int x;
    523748    unsigned int y;
    524749    unsigned int proc_id = _procid();
    525750
    526     // compute TTY channel
    527     if ( NB_TTY_CHANNELS == 1 )
     751    // compute TTY channel :
     752    // if the number of TTY channels is smaller
     753    // than the number of clusters, use TTY_0_0
     754    // else, TTY channel <= cluster index
     755    if ( NB_TTY_CHANNELS < (X_SIZE * Y_SIZE) )
    528756    {
    529757        channel = 0;
     
    531759    else
    532760    {
    533         l           = (proc_id % NB_PROCS_MAX);
    534761        x           = (proc_id / NB_PROCS_MAX) >> Y_WIDTH;
    535762        y           = (proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1);
    536         channel = (x * Y_SIZE + y) * NB_PROCS_MAX + l;
    537         if (channel >= NB_TTY_CHANNELS )
    538         {
    539             _tty_get_lock( 0 );
    540             _tty_puts("ERROR in _tty_printf() for proc[" );
    541             _tty_putd( x );
    542             _tty_puts(",");
    543             _tty_putd( y );
    544             _tty_puts(",");
    545             _tty_putd( l );
    546             _tty_puts("] / TTY channel too large = ");
    547             _tty_putd( channel );
    548             _tty_puts("\n");
    549             _tty_release_lock( 0 );
    550             _exit();
    551         }
     763        channel     = (x * Y_SIZE + y);
    552764    }
    553765
     
    640852//////////////////////////////////////////////////////////////////////////////////////
    641853//  These functions are the ISRs that must be executed when an IRQ is activated
    642 //  by the TTY: _tty_isr_X is associated to channel [X].
    643 //  It save the character in the communication buffer _tty_get_buf[X],
    644 //  and set the set/reset variable _tty_get_full[X].
     854//  by the TTY: _tty_isr_XX is associated to TTY channel [XX].
     855//  It save the character in the communication buffer _tty_get_buf[XX],
     856//  and set the set/reset variable _tty_get_full[XX].
    645857//  A character is lost if the buffer is full when the ISR is executed.
    646858//////////////////////////////////////////////////////////////////////////////////////
    647859in_drivers void _tty_isr_indexed(size_t index)
    648860{
    649     char*   base = (char*)&seg_tty_base;
    650     char*   tty_address = (char*)(base + index*TTY_SPAN*4);
    651 
    652     _tty_get_buf[index]  = tty_address[TTY_READ*4];     // save character and reset IRQ
    653     _tty_get_full[index] = 1;                       // signals character available
    654 }
     861    if ( USE_EXT_IO )   // extended addressing to TTY in cluster_io
     862    {
     863        unsigned int  cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
     864        unsigned int  base    = (unsigned int)&seg_tty_base +
     865                                ((index*TTY_SPAN + TTY_READ)*4);
     866
     867        _tty_get_buf[index] = (char)_word_extended_read( cluster, base );
     868    }
     869    else                // direct addressing to TTY in cluster(0,0)
     870    {
     871        char* tty = (char*)&seg_tty_base + index*TTY_SPAN*4;
     872
     873        _tty_get_buf[index] = tty[TTY_READ*4];  // save character and reset IRQ
     874    }
     875    _tty_get_full[index] = 1;               // signals character available
     876}
     877
     878in_drivers void _tty_isr()    { _tty_isr_indexed(0); }
    655879
    656880in_drivers void _tty_isr_00() { _tty_isr_indexed(0); }
     
    689913
    690914//////////////////////////////////////////////////////////////////////////////////////////
    691 //  I/O BLOCK_DEVICE
    692 // The three functions below use the three variables _ioc_lock _ioc_done,
     915//   BLOCK_DEVICE (IOC)
     916//////////////////////////////////////////////////////////////////////////////////////////
     917// The functions below use the three variables _ioc_lock _ioc_done,
    693918// and _ioc_status for synchronisation.
    694919// - As the IOC component can be used by several programs running in parallel,
     
    705930// reset the _ioc_done variable to zero, and releases the _ioc_lock variable.
    706931///////////////////////////////////////////////////////////////////////////////////////
     932//  If USE_EXT_IO is set, we use the IOC controler implemented in cluster_io
     933//  (x = X_SIZE-1 / y = Y_SIZE), which requires and extended address access.
     934//  If USE_EXT_IO not set, we use the IOC contrÃŽler in cluster (0,0).
     935///////////////////////////////////////////////////////////////////////////////////////
     936
     937///////////////////////////////////////////////////////////////////////////////////////
    707938// This blocking function is used by the _ioc_read() and _ioc_write() functions
    708939// to get _ioc_lock using LL/SC.
     
    720951                  ::"r"(plock):"$2","$3");
    721952}
     953
    722954//////////////////////////////////////////////////////////////////////////////////////
    723955// Transfer data from a memory buffer to the block_device.
     
    725957// - buffer : base address of the memory buffer
    726958// - count  : number of blocks to be transfered
    727 // The source buffer must be in user address space.
     959// - ext    : cluster index for the memory buffer
    728960///////////////////////////////////////////////////////////////////////////////////////
    729961in_drivers void _ioc_write( size_t   lba,
     
    732964                            size_t   ext )
    733965{
    734     volatile unsigned int*      ioc_address = (unsigned int*)&seg_ioc_base;
    735 
    736966    // get the lock
    737967    _ioc_get_lock();
    738968
    739     // block_device configuration
    740     ioc_address[BLOCK_DEVICE_BUFFER]     = (unsigned int)buffer;
    741     ioc_address[BLOCK_DEVICE_BUFFER_EXT] = ext;
    742     ioc_address[BLOCK_DEVICE_COUNT]      = count;
    743     ioc_address[BLOCK_DEVICE_LBA]        = lba;
    744     ioc_address[BLOCK_DEVICE_IRQ_ENABLE] = 1;
    745     ioc_address[BLOCK_DEVICE_OP]         = BLOCK_DEVICE_WRITE;
    746 }
     969    if ( USE_EXT_IO )   // extended addressing to cluster_io
     970    {
     971        unsigned int    cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
     972        unsigned int    base    = (unsigned int)&seg_ioc_base;
     973
     974        _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER*4,     (unsigned int)buffer );
     975        _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER_EXT*4, ext );
     976        _word_extended_write( cluster, base + BLOCK_DEVICE_COUNT*4,      count );
     977        _word_extended_write( cluster, base + BLOCK_DEVICE_LBA*4,        lba );
     978        _word_extended_write( cluster, base + BLOCK_DEVICE_IRQ_ENABLE*4, 1 );
     979        _word_extended_write( cluster, base + BLOCK_DEVICE_OP*4,         BLOCK_DEVICE_WRITE );
     980    }
     981    else                // direct addressing to cluster(0,0)
     982    {
     983        unsigned int* ioc = (unsigned int*)&seg_ioc_base;
     984
     985        ioc[BLOCK_DEVICE_BUFFER]     = (unsigned int)buffer;
     986        ioc[BLOCK_DEVICE_BUFFER_EXT] = ext;
     987        ioc[BLOCK_DEVICE_COUNT]      = count;
     988        ioc[BLOCK_DEVICE_LBA]        = lba;
     989        ioc[BLOCK_DEVICE_IRQ_ENABLE] = 1;
     990        ioc[BLOCK_DEVICE_OP]         = BLOCK_DEVICE_WRITE;
     991    }
     992}
     993
    747994///////////////////////////////////////////////////////////////////////////////////////
    748995// Transfer data from a file on the block device to a memory buffer.
     
    750997// - buffer : base address of the memory buffer
    751998// - count  : number of blocks to be transfered
    752 // The destination buffer must be in user address space.
    753 // All cache lines corresponding to the the target buffer must be invalidated
    754 // for cache coherence.
     999// - ext    : cluster index for the memory buffer
    7551000///////////////////////////////////////////////////////////////////////////////////////
    7561001in_drivers void _ioc_read( size_t   lba,
     
    7591004                           size_t   ext )
    7601005{
    761     volatile unsigned int*      ioc_address = (unsigned int*)&seg_ioc_base;
    762 
    7631006    // get the lock
    7641007    _ioc_get_lock();
    7651008
    766     // block_device configuration
    767     ioc_address[BLOCK_DEVICE_BUFFER]     = (unsigned int)buffer;
    768     ioc_address[BLOCK_DEVICE_BUFFER_EXT] = ext;
    769     ioc_address[BLOCK_DEVICE_COUNT]      = count;
    770     ioc_address[BLOCK_DEVICE_LBA]        = lba;
    771     ioc_address[BLOCK_DEVICE_IRQ_ENABLE] = 1;
    772     ioc_address[BLOCK_DEVICE_OP]         = BLOCK_DEVICE_READ;
    773 }
     1009    if ( USE_EXT_IO )   // extended addressing to cluster_io
     1010    {
     1011        unsigned int    cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
     1012        unsigned int    base    = (unsigned int)&seg_ioc_base;
     1013
     1014        _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER*4,     (unsigned int)buffer );
     1015        _word_extended_write( cluster, base + BLOCK_DEVICE_BUFFER_EXT*4, ext );
     1016        _word_extended_write( cluster, base + BLOCK_DEVICE_COUNT*4,      count );
     1017        _word_extended_write( cluster, base + BLOCK_DEVICE_LBA*4,        lba );
     1018        _word_extended_write( cluster, base + BLOCK_DEVICE_IRQ_ENABLE*4, 1 );
     1019        _word_extended_write( cluster, base + BLOCK_DEVICE_OP*4,         BLOCK_DEVICE_READ );
     1020    }
     1021    else                // direct addressing to cluster(0,0)
     1022    {
     1023        unsigned int* ioc = (unsigned int*)&seg_ioc_base;
     1024
     1025        ioc[BLOCK_DEVICE_BUFFER]     = (unsigned int)buffer;
     1026        ioc[BLOCK_DEVICE_BUFFER_EXT] = ext;
     1027        ioc[BLOCK_DEVICE_COUNT]      = count;
     1028        ioc[BLOCK_DEVICE_LBA]        = lba;
     1029        ioc[BLOCK_DEVICE_IRQ_ENABLE] = 1;
     1030        ioc[BLOCK_DEVICE_OP]         = BLOCK_DEVICE_READ;
     1031    }
     1032}
     1033
    7741034///////////////////////////////////////////////////////////////////////////////////////
    7751035// This blocking function cheks completion of an I/O transfer and reports errors.
     
    7951055    }
    7961056}
     1057
    7971058//////////////////////////////////////////////////////////////////////////////////////
    7981059//  This ISR must be executed when an IRQ is activated by IOC to signal completion.
     
    8031064in_drivers void _ioc_isr()
    8041065{
    805     int* ioc_address = (int*)&seg_ioc_base;
     1066    if ( USE_EXT_IO )  // extended addressing to cluster_io
     1067    {
     1068        unsigned int    cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;
     1069        unsigned int    base    = (unsigned int)&seg_ioc_base;
     1070
     1071        _ioc_status = _word_extended_read( cluster, base + BLOCK_DEVICE_STATUS*4 );
     1072    }
     1073    else               // direct addressing to cluster(à,0)
     1074    {
     1075        unsigned int* ioc = (unsigned int*)&seg_ioc_base;
    8061076   
    807     _ioc_status = ioc_address[BLOCK_DEVICE_STATUS];     // save status & reset IRQ
    808     _ioc_done   = 1;                                                // signals completion
     1077        _ioc_status = ioc[BLOCK_DEVICE_STATUS]; // save status & reset IRQ
     1078    }
     1079    _ioc_done   = 1;       // signals completion
    8091080}
    8101081
     
    8251096//////////////////////////////////////////////////////////////////////////////////////
    8261097//  FRAME_BUFFER
     1098//////////////////////////////////////////////////////////////////////////////////////
    8271099// The _fb_sync_write & _fb_sync_read functions use a memcpy strategy to implement
    8281100// the transfer between a data buffer and the frame buffer.
    8291101// They are blocking until completion of the transfer.
    8301102//////////////////////////////////////////////////////////////////////////////////////
     1103
     1104//////////////////////////////////////////////////////////////////////////////////////
    8311105//  _fb_sync_write()
    8321106// Transfer data from an user buffer to the frame_buffer device with a memcpy.
    833 // - offset     : offset (in bytes) in the frame buffer
     1107// - offset : offset (in bytes) in the frame buffer
    8341108// - buffer : base address of the memory buffer
    8351109// - length : number of bytes to be transfered
    836 //////////////////////////////////////////////////////////////////////////////////////
    837 in_drivers void _fb_sync_write( size_t  offset,
    838                                 void*   buffer,
    839                                 size_t  length,
    840                                 size_t  ext )
    841 {
    842     volatile char*  fb = (char*)(void*)&seg_fbf_base + offset;
    843     char*       ub = buffer;
    844 
    845     _memcpy( (void*)fb, (void*)ub, length );
    846 }
     1110// - ext    : cluster_xy for the user buffer
     1111//////////////////////////////////////////////////////////////////////////////////////
     1112in_drivers void _fb_sync_write( unsigned int  offset,
     1113                                unsigned int  buffer,
     1114                                unsigned int  length,
     1115                                unsigned int  ext )
     1116{
     1117    unsigned int  src_address = buffer;
     1118    unsigned int  src_cluster = ext;
     1119    unsigned int  dst_address = (unsigned int)&seg_fbf_base + offset;
     1120    unsigned int  dst_cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;  // cluster_xy for I/O
     1121
     1122    _extended_memcpy( dst_cluster,
     1123                      dst_address,
     1124                      src_cluster,
     1125                      src_address,
     1126                      length );
     1127}
     1128
    8471129///////////////////////////////////////////////////////////////////////////////////////
    8481130//  _fb_sync_read()
    8491131// Transfer data from the frame_buffer device to an user buffer with a memcpy.
    850 // - offset     : offset (in bytes) in the frame buffer
     1132// - offset : offset (in bytes) in the frame buffer
    8511133// - buffer : base address of the memory buffer
    8521134// - length : number of bytes to be transfered
    853 //////////////////////////////////////////////////////////////////////////////////////
    854 in_drivers void  _fb_sync_read( size_t  offset,
    855                                 void*   buffer,
    856                                 size_t  length,
    857                                 size_t  ext )
    858 {
    859     volatile char*  fb = (char*)(void*)&seg_fbf_base + offset;
    860     char*       ub = buffer;
    861 
    862     _memcpy( (void*)ub, (void*)fb, length );
     1135// - ext    : cluster_xy for the user buffer
     1136//////////////////////////////////////////////////////////////////////////////////////
     1137in_drivers void  _fb_sync_read( unsigned int  offset,
     1138                                unsigned int  buffer,
     1139                                unsigned int  length,
     1140                                unsigned int  ext )
     1141{
     1142    unsigned int  dst_address = buffer;
     1143    unsigned int  dst_cluster = ext;
     1144    unsigned int  src_address = (unsigned int)&seg_fbf_base + offset;
     1145    unsigned int  src_cluster = ((X_SIZE-1)<<Y_WIDTH) + Y_SIZE;  // cluster_xy for I/O
     1146
     1147    _extended_memcpy( dst_cluster,
     1148                      dst_address,
     1149                      src_cluster,
     1150                      src_address,
     1151                      length );
    8631152}
    8641153
     
    8791168    _spin_lock[index] = 0;
    8801169}
     1170
    8811171///////////////////////////////////////////////////////////////////////////////////////
    8821172// Try to take a software spin-lock.
     
    9541244                  ::"r"(pinit),"r"(pcount),"r"(plock),"r"(value):"$2","$3");
    9551245}
     1246
    9561247//////////////////////////////////////////////////////////////////////////////////////
    9571248// This blocking function uses a busy_wait technics (on the barrier_lock value),
Note: See TracChangeset for help on using the changeset viewer.