Ignore:
Timestamp:
May 18, 2015, 6:45:58 PM (9 years ago)
Author:
alain
Message:

1) Introduce a new driver "sdc_driver" for SD Card uding directly the 4 bits SD bus.
2) Improve the debug for all IOC drivers (debug activated only if _get_time() > GIET_DEBUG_IOC_DRIVER).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_drivers/sdc_driver.c

    r545 r563  
    11///////////////////////////////////////////////////////////////////////////////////
    22// File     : sdc_driver.c
    3 // Date     : 31/08/2012
    4 // Author   : cesar fuguet
     3// Date     : 31/04/2015
     4// Author   : Alain Greiner
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    77
    8 #include <hard_config.h>
    9 #include <sdc_driver.h>
    10 #include <tty0.h>
    11 #include <utils.h>
    12 
    13 #define SYSCLK_FREQ           50000000
    14 #define SDCARD_RESET_ITER_MAX 4
    15 
    16 ///////////////////////////////////////////////////////////////////////////////
    17 //   Global variables
    18 ///////////////////////////////////////////////////////////////////////////////
    19 
    20 __attribute__((section(".kdata")))
    21 static struct sdcard_dev sdcard;
    22 
    23 __attribute__((section(".kdata")))
    24 static struct spi_dev*   spi;
    25 
    26 ///////////////////////////////////////////////////////////////////////////////
    27 // This function enables SD Card select signal
    28 ///////////////////////////////////////////////////////////////////////////////
    29 static void _sdc_enable()
     8#include "hard_config.h"
     9#include "giet_config.h"
     10#include "sdc_driver.h"
     11#include "tty0.h"
     12#include "utils.h"
     13#include "vmem.h"
     14#include "kernel_locks.h"
     15#include "mmc_driver.h"
     16#include "xcu_driver.h"
     17#include "ctx_handler.h"
     18
     19#define  SDC_RSP_TIMEOUT      100       // number of retries for a config RSP
     20
     21#define  SDC_POLLING_TIMEOUT  1000000   // number of retries for polling PXCI
     22
     23///////////////////////////////////////////////////////////////////////////////////
     24//          AHCI related global variables
     25///////////////////////////////////////////////////////////////////////////////////
     26
     27// global index ot the task, for each entry in the command list
     28__attribute__((section(".kdata")))
     29unsigned int     _ahci_gtid[32];
     30
     31// status of the command, for each entry in the command list
     32__attribute__((section(".kdata")))
     33unsigned int     _ahci_status[32];
     34
     35// command list : up to 32 commands
     36__attribute__((section(".kdata")))
     37ahci_cmd_desc_t  _ahci_cmd_list[32] __attribute__((aligned(0x40)));   
     38
     39// command tables array : one command table per entry in command list
     40__attribute__((section(".kdata")))
     41ahci_cmd_table_t _ahci_cmd_table[32] __attribute__((aligned(0x40)));
     42
     43// command list write index : next slot to register a command
     44__attribute__((section(".kdata")))
     45unsigned int     _ahci_cmd_ptw;
     46
     47// command list read index : next slot to poll a completed command
     48__attribute__((section(".kdata")))
     49unsigned int     _ahci_cmd_ptr;
     50
     51
     52///////////////////////////////////////////////////////////////////////////////////
     53//          SD Card related global variables
     54///////////////////////////////////////////////////////////////////////////////////
     55
     56// SD card relative address
     57__attribute__((section(".kdata")))
     58unsigned int     _sdc_rca;
     59
     60// SD Card Hih Capacity Support when non zero
     61__attribute__((section(".kdata")))
     62unsigned int     _sdc_sdhc;
     63
     64
     65///////////////////////////////////////////////////////////////////////////////
     66// This low_level function returns the value contained in register (index).
     67///////////////////////////////////////////////////////////////////////////////
     68static unsigned int _sdc_get_register( unsigned int index )
    3069{
    31     spi_ss_assert(sdcard.spi, sdcard.slave_id);
     70    unsigned int* vaddr = (unsigned int*)SEG_IOC_BASE + index;
     71    return _io_extended_read( vaddr );
    3272}
    3373
    3474///////////////////////////////////////////////////////////////////////////////
    35 // This function disables SD Card select signal
    36 ///////////////////////////////////////////////////////////////////////////////
    37 static void _sdc_disable()
     75// This low-level function set a new value in register (index).
     76///////////////////////////////////////////////////////////////////////////////
     77static void _sdc_set_register( unsigned int index,
     78                               unsigned int value )
    3879{
    39     spi_ss_deassert(sdcard.spi, sdcard.slave_id);
     80    unsigned int* vaddr = (unsigned int*)SEG_IOC_BASE + index;
     81    _io_extended_write( vaddr, value );
    4082}
    4183
    4284///////////////////////////////////////////////////////////////////////////////
    43 // This function writes on the SPI tx register to generate SD card clock ticks
    44 // - tick_count: number of ticks to generate (1 tick -> 8 clocks)
    45 ///////////////////////////////////////////////////////////////////////////////
    46 static void _sdc_gen_tick(unsigned int tick_count)
     85// This function sends a command to the SD card and returns the response.
     86// - index      : CMD index
     87// - arg        : CMD argument
     88// - return Card response
     89///////////////////////////////////////////////////////////////////////////////
     90static unsigned int _sdc_send_cmd ( unsigned int   index,
     91                                    unsigned int   arg )
    4792{
    48     register int i = 0;
    49     while(i++ < tick_count) spi_put_tx(sdcard.spi, 0xFF, 0);
    50 }
    51 
    52 ///////////////////////////////////////////////////////////////////////////////
    53 // This function changes the SD card access pointer position in terms of
    54 // blocks
    55 // - lba: number of logical block to move the pointer
    56 ///////////////////////////////////////////////////////////////////////////////
    57 void _sdc_lseek(unsigned int lba)
    58 {
    59     sdcard.access_pointer = sdcard.block_length * lba;
    60 }
    61 
    62 ///////////////////////////////////////////////////////////////////////////////
    63 // This function gets a byte from the SD card
    64 ///////////////////////////////////////////////////////////////////////////////
    65 static unsigned char _sdc_receive_char()
    66 {
    67     _sdc_gen_tick(1);
    68 
    69     return spi_get_rx(sdcard.spi, 0);
    70 }
    71 
    72 ///////////////////////////////////////////////////////////////////////////////
    73 // This function returns when a valid response from the SD card is received or
    74 // a timeout has been triggered
    75 // Returns the SD card response value
    76 ///////////////////////////////////////////////////////////////////////////////
    77 static unsigned char _sdc_wait_response()
    78 {
    79     unsigned char sdcard_rsp;
    80     register int  iter;
    81 
    82     iter       = 0;
    83     sdcard_rsp = _sdc_receive_char();
    84     while (
    85             (iter < SDCARD_COMMAND_TIMEOUT) &&
    86             !SDCARD_CHECK_R1_VALID(sdcard_rsp)
    87           )
    88     {
    89         sdcard_rsp = _sdc_receive_char();
     93    unsigned int  sdc_rsp;
     94    register int  iter = 0;
     95
     96    // load argument
     97    _sdc_set_register( SDC_CMD_ARG, arg );
     98
     99    // lauch command
     100    _sdc_set_register( SDC_CMD_ID , index );
     101
     102    // get response
     103    do
     104    {
     105        sdc_rsp = _sdc_get_register( SDC_RSP_STS );
    90106        iter++;
    91107    }
    92 
    93     return sdcard_rsp;
    94 }
    95 
    96 ///////////////////////////////////////////////////////////////////////////////
    97 // This function returns when a data block from the SD card is received (data
    98 // block start marker received).
    99 // It must be called after a read command
    100 ///////////////////////////////////////////////////////////////////////////////
    101 static void _sdc_wait_data_block()
    102 {
    103         while (_sdc_receive_char() != 0xFE);
    104 }
    105 
    106 ///////////////////////////////////////////////////////////////////////////////
    107 // This function sends a command to the SD card
    108 // - index: CMD index
    109 // - app: type of command
    110 // - args: CMD arguments vector
    111 // - crc7: CRC (7 bits) to send
    112 ///////////////////////////////////////////////////////////////////////////////
    113 static int _sdc_send_command ( int      index,
    114                                int      app  ,
    115                                void *   args ,
    116                                unsigned crc7 )
    117 {
    118     unsigned char sdcard_rsp;
    119     unsigned char * _args;
    120 
    121     _sdc_gen_tick(5); 
    122 
    123     if (app == SDCARD_ACMD)
    124     {
    125         spi_put_tx(sdcard.spi, 0x40 | 55         , 0 );// CMD and START bit
    126         spi_put_tx(sdcard.spi, 0x00              , 0 );// Argument[0]
    127         spi_put_tx(sdcard.spi, 0x00              , 0 );// Argument[1]
    128         spi_put_tx(sdcard.spi, 0x00              , 0 );// Argument[2]
    129         spi_put_tx(sdcard.spi, 0x00              , 0 );// Argument[3]
    130         spi_put_tx(sdcard.spi, 0x01 | (crc7 << 1), 0 );// END bit
    131 
    132         sdcard_rsp = _sdc_wait_response();
    133         if (SDCARD_CHECK_R1_ERROR(sdcard_rsp))
    134         {
    135             return sdcard_rsp;       
    136         }
    137     }
    138 
    139     _args = (unsigned char *) args;
    140 
    141     _sdc_gen_tick(1); 
    142 
    143     spi_put_tx(sdcard.spi, 0x40 | index      , 0 );
    144     spi_put_tx(sdcard.spi, _args[0]          , 0 );
    145     spi_put_tx(sdcard.spi, _args[1]          , 0 );
    146     spi_put_tx(sdcard.spi, _args[2]          , 0 );
    147     spi_put_tx(sdcard.spi, _args[3]          , 0 );
    148     spi_put_tx(sdcard.spi, 0x01 | (crc7 << 1), 0 );
    149 
    150     return _sdc_wait_response();
    151 }
    152 
    153 ///////////////////////////////////////////////////////////////////////////////
    154 // This function initializes the SD card (reset procedure)
    155 // - channel: channel index (only channel 0 is supported)
    156 // Returns 0 if success, other value if failure
    157 ///////////////////////////////////////////////////////////////////////////////
    158 static int _sdc_open( unsigned int channel )
    159 {
    160         unsigned char args[4];
    161         unsigned char sdcard_rsp;
    162         unsigned int  iter, ersp;
    163 
    164         sdcard.spi      = spi;
    165         sdcard.slave_id = channel;
    166 
    167         // supply SD card ramp up time (min 74 cycles)
    168         _sdc_gen_tick(10);
    169 
    170         // Assert slave select signal
    171         // Send CMD0 (Reset Command)
    172         // Deassert slave select signal
    173         _sdc_enable();
    174 
    175         args[0] = 0;
    176         args[1] = 0;
    177         args[2] = 0;
    178         args[3] = 0;
    179         sdcard_rsp = _sdc_send_command(0, SDCARD_CMD, args, 0x4A);
    180         if ( sdcard_rsp != 0x01 )
    181         {
    182                 _puts("[SDC ERROR] card CMD0 failed\n");
    183                 return sdcard_rsp;
    184         }
    185 
    186         _sdc_disable();
    187 
    188         // send CMD8. If card is pre-v2, It will reply with illegal command.
    189         // Otherwise we announce sdhc support.
    190         _sdc_enable();
    191         args[0] = 0;
    192         args[1] = 0;
    193         args[2] = 0x01;
    194         args[3] = 0x01;
    195         sdcard_rsp = _sdc_send_command(8, SDCARD_CMD, args, 0x63);
    196         if (!SDCARD_CHECK_R1_VALID(sdcard_rsp))
    197     {
    198                 _puts("[SDC ERROR] card CMD8 failed\n");
    199                 return sdcard_rsp;
    200         }
    201         if (!SDCARD_CHECK_R1_ERROR(sdcard_rsp))
    202     {
    203                 // no error, command accepted. get whole reply
    204                 ersp = _sdc_receive_char();
    205                 ersp = (ersp << 8) | _sdc_receive_char();
    206                 ersp = (ersp << 8) | _sdc_receive_char();
    207                 ersp = (ersp << 8) | _sdc_receive_char();
    208                 if ((ersp & 0xffff) != 0x0101)
    209         {
    210                         // voltage mismatch
    211                         _puts("[SDC ERROR] card CMD8 mismatch : ersp = %x\n");
    212                         return sdcard_rsp;
    213                 }
    214                 _puts("[SDC WARNING] v2 or later ");
    215                 sdcard.sdhc = 1;
    216         }
    217     else if ((sdcard_rsp & SDCARD_R1_ILLEGAL_CMD) == 0)
    218     {
    219                 // other error
    220                 _puts("[SDC ERROR] card CMD8 error\n");
    221                 return sdcard_rsp;
    222         }
    223     else
    224     {
    225                 sdcard.sdhc = 0;
    226         }
    227         _sdc_disable();
    228 
    229         // send CMD41, enabling the card
    230         _sdc_enable();
    231         args[0] = sdcard.sdhc ? 0x40: 0;
    232         args[1] = 0;
    233         args[2] = 0;
    234         args[3] = 0;
    235 
    236         iter = 0;
    237         while( iter++ < SDCARD_COMMAND_TIMEOUT )
    238         {
    239                 sdcard_rsp = _sdc_send_command(41, SDCARD_ACMD, args, 0x00);
    240                 if( sdcard_rsp == 0x01 )
    241                 {
    242                         continue;
    243                 }
    244 
    245                 break;
    246         }
    247 
    248         _sdc_disable();
    249         if (sdcard_rsp)
    250     {
    251                 _puts("[SDC ERROR] ACMD41 failed\n");
    252                 return sdcard_rsp;
    253         }
    254         if (sdcard.sdhc != 0)
    255     {
    256                 // get the card capacity to see if it's really HC
    257                 _sdc_enable();
    258                 args[0] = sdcard.sdhc ? 0x40: 0;
    259                 args[1] = 0;
    260                 args[2] = 0;
    261                 args[3] = 0;
    262         sdcard_rsp = _sdc_send_command(58, SDCARD_CMD, args, 0x00);
    263                 if (sdcard_rsp)
    264         {
    265                         _puts("[SDC ERROR] CMD58 failed\n");
    266                         return sdcard_rsp;
    267                 }
    268                 ersp = _sdc_receive_char();
    269                 ersp = (ersp << 8) | _sdc_receive_char();
    270                 ersp = (ersp << 8) | _sdc_receive_char();
    271                 ersp = (ersp << 8) | _sdc_receive_char();
    272                 if (ersp & 0x40000000)
    273         {
    274                         _puts(" SDHC ");
    275                 }
    276         else
    277         {
    278                         sdcard.sdhc = 0;
    279                 }
    280                 _sdc_disable();
    281         }
    282         _puts("card detected\n");
    283         return 0;
    284 }
    285 
    286 ///////////////////////////////////////////////////////////////////////////////
    287 // This function sets the block size in the SD card.
    288 // - len: block size in bytes (only 512 bytes supported)
    289 // Returns 0 if success, other value if failure
    290 ///////////////////////////////////////////////////////////////////////////////
    291 static unsigned int _sdc_set_block_size(unsigned int len)
    292 {
    293     unsigned char args[4];
    294     unsigned char sdcard_rsp;
    295     register int i;
    296 
    297     // For now, supported block size is 512 bytes
    298     if (len != 512) return 1;
    299 
    300     // When using high capacity SDCARD, the block_length is not a number of bytes
    301     // but a number of blocks (transfer unit)
    302     if (sdcard.sdhc)
    303     {
    304         sdcard.block_length = len / 512;
    305         return 0;
    306     }
    307 
    308     for (i = 0; i < 4; i++)
    309     {
    310         args[i] = (len >> (32 - (i+1)*8)) & 0xFF;
    311     }
    312 
    313     _sdc_enable();
    314 
    315     sdcard_rsp = _sdc_send_command(16, SDCARD_CMD, args, 0x00);
    316     if ( SDCARD_CHECK_R1_ERROR(sdcard_rsp) )
    317     {
    318         _sdc_disable();
    319         return sdcard_rsp;
    320     }
    321 
    322     _sdc_disable();
    323 
    324     sdcard.block_length = len;
    325 
    326         return 0;
     108    while ( (sdc_rsp == 0xFFFFFFFF) && (iter < SDC_RSP_TIMEOUT) );
     109
     110    return sdc_rsp;
    327111}
    328112
     
    334118unsigned int _sdc_init()
    335119{
    336     spi = (struct spi_dev*)SEG_IOC_BASE;
    337 
    338     // initializing the SPI controller
    339     _spi_init (
    340         spi           ,
    341         200000        , /**< SPI_clk: 200 Khz */
    342         SYSCLK_FREQ   , /**< Sys_clk          */
    343         8             , /**< Charlen: 8       */
    344         SPI_TX_NEGEDGE,
    345         SPI_RX_POSEDGE
    346     );
    347 
    348     // initializing the SD Card
    349     unsigned int iter = 0;
    350     unsigned char sdcard_rsp;
    351     unsigned int i;
    352 
    353     while(1)
    354     {
    355         _puts("[SDC WARNING] Trying to initialize SD card...\n");
    356 
    357         sdcard_rsp = _sdc_open( 0 );  // only channel 0
    358         if (sdcard_rsp == 0)
    359         {
    360             _puts("OK\n");
    361             break;
    362         }
    363 
    364         _puts("KO\n");
    365 
    366         for (i = 0; i < 1000; i++);
    367 
    368         if (++iter >= SDCARD_RESET_ITER_MAX)
    369         {
    370             _puts("\n[SDC ERROR] During SD card reset / card response = ");
    371             _putx( sdcard_rsp );
    372             _puts("\n");
    373             _exit();
    374         }
    375     }
    376 
    377     // set the block length of the SD Card
    378     sdcard_rsp = _sdc_set_block_size(512);
    379     if (sdcard_rsp)
    380     {
    381         _puts("[SDC ERROR] During SD card block size initialization\n");
    382         _exit();
    383     }
    384 
    385     // incrementing SDCARD clock frequency for normal function
    386     _spi_init (
    387         spi         ,
    388         10000000    , // SPI_clk 10 Mhz
    389         SYSCLK_FREQ , // Sys_clk
    390         -1          , // Charlen: 8
    391         -1          ,
    392         -1
    393     );
    394 
    395     _puts("[SDC WARNING] Finish SD card initialization\n\r");
    396 
    397     return 0;
     120    //////////// SD Card initialisation //////////
     121 
     122    unsigned int rsp;
     123
     124    // define the SD card clock period
     125    _sdc_set_register( SDC_PERIOD , GIET_SDC_PERIOD );
     126
     127    // send CMD0 (soft reset / no argument)
     128    rsp = _sdc_send_cmd( SDC_CMD0 , 0 );
     129    if ( rsp == 0xFFFFFFFF )
     130    {
     131        _printf("\n[SDC ERROR] in _sdc_init() : no acknowledge to CMD0\n");
     132        return 1;
     133    }
     134
     135#if GIET_DEBUG_IOC_DRIVER
     136if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
     137_printf("\n[DEBUG SDC] _sdc_init() : SDC_CMD0 done at cycle %d\n", _get_proctime() );
     138#endif
     139
     140    // send CMD8 command
     141    rsp = _sdc_send_cmd( SDC_CMD8 , SDC_CMD8_ARGUMENT );
     142    if ( rsp == 0xFFFFFFFF )
     143    {
     144        _printf("\n[SDC ERROR] in _sdc_init() : no response to CMD8\n");
     145        return 1;
     146    }
     147    else if ( rsp != SDC_CMD8_ARGUMENT )
     148    {
     149        _printf("\n[SDC ERROR] in _sdc_init() : response to CMD8 = %x / expected = %x\n",
     150                rsp , SDC_CMD8_ARGUMENT );
     151        return 1;
     152    }
     153
     154#if GIET_DEBUG_IOC_DRIVER
     155if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
     156_printf("\n[DEBUG SDC] _sdc_init() : SDC_CMD8 done at cycle %d\n", _get_proctime() );
     157#endif
     158
     159    // send CMD41 to get SDHC
     160    if ( rsp == 0xFFFFFFFF )
     161    {
     162        _printf("\n[SDC ERROR] in _sdc_init() : no response to CMD41\n");
     163        return 1;
     164    }
     165    _sdc_sdhc = ( (rsp & SDC_CMD41_RSP_CCS) != 0 );
     166
     167#if GIET_DEBUG_IOC_DRIVER
     168if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
     169_printf("\n[DEBUG SDC] _sdc_init() : SDC_CMD41 done at cycle %d\n", _get_proctime() );
     170#endif
     171
     172    // send CMD3 to get RCA
     173    rsp = _sdc_send_cmd( SDC_CMD3 , 0 );
     174    if ( rsp == 0xFFFFFFFF )
     175    {
     176        _printf("\n[SDC ERROR] in _sdc_init() : no response to CMD3\n");
     177        return 1;
     178    }
     179    _sdc_rca = rsp;
     180
     181#if GIET_DEBUG_IOC_DRIVER
     182if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
     183_printf("\n[DEBUG SDC] _sdc_init() : SDC_CMD3 done at cycle %d\n", _get_proctime() );
     184#endif
     185
     186    // send CMD7
     187    rsp = _sdc_send_cmd( SDC_CMD7 , _sdc_rca );
     188    if ( rsp == 0xFFFFFFFF )
     189    {
     190        _printf("\n[SDC ERROR] in _sdc_init() : no response to CMD7\n");
     191        return 1;
     192    }
     193
     194#if GIET_DEBUG_IOC_DRIVER
     195if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
     196_printf("\n[DEBUG SDC] _sdc_init() : SDC_CMD7 done at cycle %d\n", _get_proctime() );
     197#endif
     198
     199    //////////// AHCI interface initialisation  ///////
     200
     201    unsigned int       cmd_list_vaddr;
     202    unsigned int       cmd_table_vaddr;
     203    unsigned long long cmd_list_paddr;
     204    unsigned long long cmd_table_paddr;
     205    unsigned int       flags;                 // unused
     206
     207    // compute Command list & command table physical addresses
     208    cmd_list_vaddr  = (unsigned int)(&_ahci_cmd_list[0]);
     209    cmd_table_vaddr = (unsigned int)(&_ahci_cmd_table[0]);
     210    if ( _get_mmu_mode() & 0x4 )
     211    {
     212        cmd_list_paddr  = _v2p_translate( cmd_list_vaddr  , &flags );
     213        cmd_table_paddr = _v2p_translate( cmd_table_vaddr , &flags );
     214    }
     215    else
     216    {
     217        cmd_list_paddr  = (unsigned long long)cmd_list_vaddr;
     218        cmd_table_paddr = (unsigned long long)cmd_table_vaddr;
     219    }
     220
     221    // initialise Command List pointers
     222    _ahci_cmd_ptw = 0;
     223    _ahci_cmd_ptr = 0;
     224
     225    // initialise Command Descriptors in Command List
     226    unsigned int         c;     
     227    unsigned long long   paddr;
     228    for( c=0 ; c<32 ; c++ )
     229    {
     230        paddr = cmd_table_paddr + c * sizeof(ahci_cmd_table_t);
     231        _ahci_cmd_list[c].ctba  = (unsigned int)(paddr);
     232        _ahci_cmd_list[c].ctbau = (unsigned int)(paddr>>32);
     233    }
     234
     235    // initialise AHCI registers
     236    _sdc_set_register( AHCI_PXCLB  , (unsigned int)(cmd_list_paddr) );
     237    _sdc_set_register( AHCI_PXCLBU , (unsigned int)(cmd_list_paddr>>32) );
     238    _sdc_set_register( AHCI_PXIE   , 0 );
     239    _sdc_set_register( AHCI_PXIS   , 0 );
     240    _sdc_set_register( AHCI_PXCI   , 0 );
     241    _sdc_set_register( AHCI_PXCMD  , 1 );
     242
     243#if GIET_DEBUG_IOC_DRIVER
     244if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
     245_printf("\n[DEBUG SDC] _sdc_init() : AHCI init done at cycle %d\n", _get_proctime() );
     246#endif
     247
    398248} // end _sdc_init()
    399249
    400250
    401251/////////////////////////////////////////////////////
    402 unsigned int _sdc_access( unsigned int       use_irq,  // unused
     252unsigned int _sdc_access( unsigned int       use_irq,
    403253                          unsigned int       to_mem,
    404254                          unsigned int       lba,
     
    406256                          unsigned int       count )
    407257{
    408     unsigned char args[4];
    409     unsigned char sdcard_rsp;
    410     unsigned int i;
    411     unsigned int curr = lba;
    412     unsigned int last = lba + count;
    413 
    414     if ( to_mem )  // read access
    415     {
    416         for ( ; curr < last ; curr++ )
     258    unsigned int procid  = _get_procid();
     259    unsigned int x       = procid >> (Y_WIDTH + P_WIDTH);
     260    unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH) - 1);
     261    unsigned int p       = procid & ((1<<P_WIDTH)-1);
     262    unsigned int iter;
     263
     264#if GIET_DEBUG_IOC_DRIVER
     265if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
     266_printf("\n[DEBUG SDC] _sdc_access() : P[%d,%d,%d] enters at cycle %d\n"
     267        "  use_irq = %d / to_mem = %d / lba = %x / paddr = %l / count = %d\n",
     268        x , y , p , _get_proctime() , use_irq , to_mem , lba , buf_paddr, count );
     269#endif
     270
     271    unsigned int       pxci;              // AHCI_PXCI register value
     272    unsigned int       ptw;               // command list write pointer
     273    unsigned int       pxis;              // AHCI_PXIS register value
     274    ahci_cmd_desc_t*   cmd_desc;          // command descriptor pointer   
     275    ahci_cmd_table_t*  cmd_table;         // command table pointer
     276
     277    // check buffer alignment
     278    if( buf_paddr & 0x3F )
     279    {
     280        _printf("\n[SDC ERROR] in _sdc_access() : buffer not 64 bytes aligned\n");
     281        return 1;
     282    }
     283
     284    // get one entry in Command List, using an
     285    // atomic increment on the _ahci_cmd_ptw allocator
     286    // only the 5 LSB bits are used to index the Command List
     287    ptw = _atomic_increment( &_ahci_cmd_ptw , 1 ) & 0x1F;
     288
     289    // blocked until allocated entry in Command List is empty
     290    iter = SDC_POLLING_TIMEOUT;
     291    do
     292    {
     293        // get PXCI register
     294        pxci = _sdc_get_register( AHCI_PXCI );
     295
     296        // check livelock
     297        iter--;
     298        if ( iter == 0 )
    417299        {
    418             _sdc_lseek(curr);
    419 
    420             for (i = 0; i < 4; i++)
     300            _printf("\n[SDC ERROR] in _sdc_access() : cannot get PXCI slot\n");
     301            return 1;
     302        }
     303    }
     304    while ( pxci & (1<<ptw) );
     305
     306    // compute pointers on command descriptor and command table   
     307    cmd_desc  = &_ahci_cmd_list[ptw];
     308    cmd_table = &_ahci_cmd_table[ptw];
     309
     310    // set  buffer descriptor in command table
     311    cmd_table->buffer.dba  = (unsigned int)(buf_paddr);
     312    cmd_table->buffer.dbau = (unsigned int)(buf_paddr >> 32);
     313    cmd_table->buffer.dbc  = count * 512;
     314
     315    // initialize command table header
     316    cmd_table->header.lba0 = (char)lba;
     317    cmd_table->header.lba1 = (char)(lba>>8);
     318    cmd_table->header.lba2 = (char)(lba>>16);
     319    cmd_table->header.lba3 = (char)(lba>>24);
     320    cmd_table->header.lba4 = 0;
     321    cmd_table->header.lba5 = 0;
     322
     323    // initialise command descriptor
     324    cmd_desc->prdtl[0] = 1;
     325    cmd_desc->prdtl[1] = 0;
     326    if( to_mem ) cmd_desc->flag[0] = 0x00;
     327    else         cmd_desc->flag[0] = 0x40;     
     328
     329#if USE_IOB    // software L2/L3 cache coherence
     330
     331    // compute physical addresses
     332    unsigned long long cmd_desc_paddr;    // command descriptor physical address
     333    unsigned long long cmd_table_paddr;   // command table header physical address
     334    unsigned int       flags;             // unused
     335
     336    if ( _get_mmu_mode() & 0x4 )
     337    {
     338        cmd_desc_paddr  = _v2p_translate( (unsigned int)cmd_desc  , &flags );
     339        cmd_table_paddr = _v2p_translate( (unsigned int)cmd_table , &flags );
     340    }
     341    else
     342    {
     343        cmd_desc_paddr  = (unsigned int)cmd_desc;
     344        cmd_table_paddr = (unsigned int)cmd_table;
     345    }
     346
     347    // update external memory for command table
     348    _mmc_sync( cmd_table_paddr & (~0x3F) , sizeof(ahci_cmd_table_t) );
     349
     350    // update external memory for command descriptor
     351    _mmc_sync( cmd_desc_paddr & (~0x3F) , sizeof(ahci_cmd_desc_t) );
     352
     353    // inval or synchronize memory buffer
     354    if ( to_mem )  _mmc_inval( buf_paddr, count<<9 );
     355    else           _mmc_sync( buf_paddr, count<<9 );
     356
     357#endif     // end software L2/L3 cache coherence
     358
     359    /////////////////////////////////////////////////////////////////////
     360    // In synchronous mode, we poll the PXCI register until completion
     361    /////////////////////////////////////////////////////////////////////
     362    if ( use_irq == 0 )
     363    {
     364        // start transfer
     365        _sdc_set_register( AHCI_PXCI, (1<<ptw) );
     366
     367#if GIET_DEBUG_IOC_DRIVER
     368if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
     369_printf("\n[DEBUG SDC] _sdc_access() : command %d for P[%d,%d,%d]"
     370        " at cycle %d / polling\n",
     371        ptw , x , y , p , _get_proctime() );
     372#endif
     373        // disable IRQs in PXIE register
     374        _sdc_set_register( AHCI_PXIE , 0 );
     375
     376        // poll PXCI[ptw] until command completed
     377        iter = SDC_POLLING_TIMEOUT;
     378        do
     379        {
     380            pxci = _sdc_get_register( AHCI_PXCI );
     381
     382            // check livelock
     383            iter--;
     384            if ( iter == 0 )
    421385            {
    422                 args[i] = (sdcard.access_pointer >> (32 - (i+1)*8)) & 0xFF;
    423             }
    424 
    425             _sdc_enable();
    426 
    427             sdcard_rsp = _sdc_send_command(17, SDCARD_CMD, args, 0x00);
    428             if ( SDCARD_CHECK_R1_ERROR(sdcard_rsp) )
    429             {
    430                 _sdc_disable();
    431                 return sdcard_rsp;
    432             }
    433 
    434             _sdc_wait_data_block();
    435 
    436             if (spi_get_data(sdcard.spi, buf_paddr, 512 ))
    437             {
    438                 _sdc_disable();
     386                _printf("\n[SDC ERROR] in _sdc_access() : polling PXCI timeout\n");
    439387                return 1;
    440388            }
    441 
    442             // Get the CRC16 (comes at the end of the data block)
    443             _sdc_receive_char(); // first byte
    444             _sdc_receive_char(); // second byte
    445 
    446             _sdc_disable();
    447 
    448             buf_paddr += 512;
    449389        }
    450     }
    451     else            // write access
    452     {
    453         _printf("[SDC ERROR] function _sdc_write() not iplemented yet\n");
    454         _exit();
    455     }
    456 
    457     return 0;
    458 }  // _end sdc_access()
    459 
    460 ///////////////////////////////////////////////////////////////////////////////
    461 // This ISR handles the IRQ generated by a SDC controler
     390        while( pxci & (1<<ptw) );
     391             
     392        // get PXIS register
     393        pxis = _sdc_get_register( AHCI_PXIS );
     394
     395        // reset PXIS register
     396        _sdc_set_register( AHCI_PXIS , 0 );
     397    }
     398
     399    /////////////////////////////////////////////////////////////////
     400    // in descheduling mode, we deschedule the task
     401    // and use an interrupt to reschedule the task.
     402    // We need a critical section, because we must reset the RUN bit
     403        // before to launch the transfer, and we don't want to be
     404    // descheduled between these two operations.
     405    /////////////////////////////////////////////////////////////////
     406    else
     407    {
     408
     409#if GIET_DEBUG_IOC_DRIVER
     410if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
     411_printf("\n[DEBUG SDC] _sdc_access() : command %d for P[%d,%d,%d] "
     412        "at cycle %d / descheduling\n",
     413        ptw , x , y , p , _get_proctime() );
     414#endif
     415        unsigned int save_sr;
     416        unsigned int ltid = _get_current_task_id();
     417
     418        // activates interrupt
     419        _sdc_set_register( AHCI_PXIE , 0x00000001 );
     420
     421        // set _ahci_gtid[ptw]
     422        _ahci_gtid[ptw] = (procid<<16) + ltid;
     423
     424        // enters critical section
     425        _it_disable( &save_sr );
     426
     427        // reset runnable
     428        _set_task_slot( x, y, p, ltid, CTX_RUN_ID, 0 ); 
     429
     430        // start transfer
     431        _sdc_set_register( AHCI_PXCI, (1<<ptw) );
     432
     433        // deschedule task
     434        _ctx_switch();                     
     435
     436#if GIET_DEBUG_IOC_DRIVER
     437if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
     438_printf("\n[DEBUG SDC] _sdc_access() : task %d on P[%d,%d,%d] resume at cycle %d\n",
     439        ltid , x , y , p , _get_proctime() );
     440#endif
     441
     442        // restore SR
     443        _it_restore( &save_sr );
     444
     445        // get command status
     446        pxis = _ahci_status[ptw];
     447    }   
     448
     449#if GIET_DEBUG_IOC_DRIVER
     450if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
     451_printf("\n[DEBUG SDC] _sdc_access() : P[%d,%d,%d] exit at cycle %d\n",
     452        x , y , p , _get_proctime() );
     453#endif
     454
     455    if ( pxis & 0x40000000 ) return pxis;
     456    else                     return 0;
     457
     458} // end _sdc_access()
     459
     460
     461///////////////////////////////////////////////////////////////////////////////
     462// This ISR handles the IRQ generated by the AHCI_SDC controler
    462463///////////////////////////////////////////////////////////////////////////////
    463464void _sdc_isr( unsigned int irq_type,
     
    465466               unsigned int channel )
    466467{
    467     _puts("\n[GIET ERROR] _sdc_isr() not implemented\n");
    468     _exit();
    469 }
     468    // get AHCI_PXCI containing commands status
     469    unsigned int pxci = _sdc_get_register( AHCI_PXCI );
     470
     471    // we must handle all completed commands
     472    // active commands are between  (_ahci_cmd_ptr) and (_ahci_cmd_ptw-1)
     473    unsigned int current;
     474    for ( current = _ahci_cmd_ptr ; current != _ahci_cmd_ptw ; current++ )
     475    {
     476        unsigned int ptr = current & 0x1F;
     477       
     478        if ( (pxci & (1<<ptr)) == 0 )    // command completed
     479        {
     480            // increment the 32 bits variable _ahci_cmd_ptr
     481            _ahci_cmd_ptr++;
     482
     483            // save AHCI_PXIS register
     484            _ahci_status[ptr] = _sdc_get_register( AHCI_PXIS );
     485
     486            // reset AHCI_PXIS register
     487            _sdc_set_register( AHCI_PXIS , 0 );
     488 
     489            // identify waiting task
     490            unsigned int remote_procid  = _ahci_gtid[ptr]>>16;
     491            unsigned int ltid           = _ahci_gtid[ptr] & 0xFFFF;
     492            unsigned int remote_cluster = remote_procid >> P_WIDTH;
     493            unsigned int remote_x       = remote_cluster >> Y_WIDTH;
     494            unsigned int remote_y       = remote_cluster & ((1<<Y_WIDTH)-1);
     495            unsigned int remote_p       = remote_procid & ((1<<P_WIDTH)-1);
     496 
     497            // re-activates waiting task
     498            _set_task_slot( remote_x,
     499                            remote_y,
     500                            remote_p,
     501                            ltid,
     502                            CTX_RUN_ID,
     503                            1 );
     504
     505            // send a WAKUP WTI to processor running the waiting task
     506            _xcu_send_wti( remote_cluster ,
     507                           remote_p ,
     508                           0 );          // don't force context switch
     509
     510#if GIET_DEBUG_IOC_DRIVER 
     511if (_get_proctime() > GIET_DEBUG_IOC_DRIVER)
     512_printf("\n[DEBUG SDC] _sdc_isr() : command %d completed at cycle %d\n"
     513        "  resume task %d running on P[%d,%d,%d] / status = %x\n",
     514        ptr , _get_proctime() ,
     515        ltid , remote_x , remote_y , remote_p , _ahci_status[ptr] );
     516#endif
     517        }
     518        else                         // command non completed
     519        {
     520            break;
     521        }
     522    }
     523}  // end _sdc_isr()
    470524
    471525// Local Variables:
Note: See TracChangeset for help on using the changeset viewer.