source: trunk/softs/tsar_boot/drivers/reset_hba.c @ 976

Last change on this file since 976 was 968, checked in by cfuguet, 10 years ago

bugfix:tsar_boot: cache aligned structures should use the
CACHE_LINE_SIZE constant

  • Define a macro for the cache aligned attribute.
File size: 4.7 KB
Line 
1/**
2 * \File     : reset_hba.c
3 * \Date     : 23/11/2013
4 * \Author   : alain greiner
5 * \Copyright (c) UPMC-LIP6
6 */
7
8#include <reset_hba.h>
9#include <reset_tty.h>
10#include <reset_inval.h>
11#include <reset_utils.h>
12#include <io.h>
13#include <defs.h>
14
15///////////////////////////////////////////////////////////////////////////////
16//               Global variables
17///////////////////////////////////////////////////////////////////////////////
18
19// command descriptor (one single command)
20static hba_cmd_desc_t hba_cmd_desc __cache_aligned__;
21
22// command table (one single command)
23static hba_cmd_table_t hba_cmd_table __cache_aligned__;
24
25// IOC/HBA device base address
26static int* const ioc_address = (int* const)SEG_IOC_BASE;
27
28///////////////////////////////////////////////////////////////////////////////
29//      Extern functions
30///////////////////////////////////////////////////////////////////////////////
31
32///////////////////////////////////////////////////////////////////////////////
33// This function register one command in both the command descriptor
34// and the command data, and updates the HBA_PXCI register.
35// The all addresses are supposed to be identity mapping (vaddr == paddr).
36// return 0 if success, -1 if error
37///////////////////////////////////////////////////////////////////////////////
38int reset_hba_read( unsigned int lba,
39                    void*        buffer,
40                    unsigned int count )
41{
42    unsigned int       pxci;           // HBA_PXCI register value
43    unsigned int       pxis;           // HBA_PXIS register value
44
45    // check buffer alignment
46    if( (unsigned int)buffer & 0x3F )
47    {
48        reset_puts("\n[RESET ERROR] in reset_hba_read() ");
49        reset_puts("buffer not aligned on 64 bytes: base = ");
50        reset_putx( (unsigned int)buffer );
51        reset_puts("\n");
52        return -1;
53    }
54
55    // set command data header: lba value
56    hba_cmd_table.header.lba0 = (char)lba;
57    hba_cmd_table.header.lba1 = (char)(lba>>8);
58    hba_cmd_table.header.lba2 = (char)(lba>>16);
59    hba_cmd_table.header.lba3 = (char)(lba>>24);
60    hba_cmd_table.header.lba4 = 0;
61    hba_cmd_table.header.lba5 = 0;
62
63    // set command data buffer: address and size)
64    hba_cmd_table.buffer.dba  = (unsigned int)(buffer);
65    hba_cmd_table.buffer.dbau = 0;
66    hba_cmd_table.buffer.dbc  = count*512;
67
68    // set command descriptor: one single buffer / read access
69    hba_cmd_desc.prdtl[0] = 1;
70    hba_cmd_desc.prdtl[1] = 0;
71    hba_cmd_desc.flag[0]  = 0;  // read
72
73#if USE_IOB
74    // update external memory for command table
75    reset_L2_sync( &hba_cmd_table , 32 );
76
77    // update external memory for command descriptor
78    reset_L2_sync( &hba_cmd_desc , 16 );
79#endif
80
81    // start transfer
82    iowrite32( &ioc_address[HBA_PXCI] , 1 );
83
84#if (RESET_HARD_CC == 0) || USE_IOB
85    // inval buffer in L1 cache
86    reset_L1_inval( buffer , count * 512 );
87#endif
88
89#if USE_IOB
90    // inval buffer in  L2 cache
91    reset_L2_inval( buffer , count * 512 );
92#endif
93
94    // poll PXCI until command completed by HBA
95    do
96    {
97        pxci = ioread32( &ioc_address[HBA_PXCI] );
98    }
99    while( pxci );
100
101    // get PXIS register
102    pxis = ioread32( &ioc_address[HBA_PXIS] );
103
104    // reset PXIS register
105    iowrite32( &ioc_address[HBA_PXIS] , 0 );
106
107    // reset PXCI register : we use only command slot[0] in PXCI
108    iowrite32( &ioc_address[HBA_PXCI] , 0 );
109
110    // check error status
111    if ( pxis & 0x40000000 )
112    {
113        reset_puts("[RESET ERROR] in reset_hba_read() : "
114                   " status error returned by HBA\n");
115        return 1;
116    }
117
118    return 0;
119} // end reset_hba_read()
120
121
122///////////////////////////////////////////////////////////////////////////////
123// This function initialises both the HBA registers and the
124// memory structures used by the AHCI peripheral (one single command).
125///////////////////////////////////////////////////////////////////////////////
126int reset_hba_init()
127{
128    // initialise the command descriptor
129    hba_cmd_desc.ctba = (unsigned int)&hba_cmd_table;
130    hba_cmd_desc.ctbau = 0;
131
132#if USE_IOB
133    // update external memory for the commande descriptor
134    reset_L2_sync(&hba_cmd_desc , sizeof( hba_cmd_desc_t ) );
135#endif
136    // initialise HBA registers
137    iowrite32(&ioc_address[HBA_PXCLB], (unsigned int)&hba_cmd_desc );
138    iowrite32(&ioc_address[HBA_PXCLBU], 0 );
139    iowrite32(&ioc_address[HBA_PXIE], 0 );
140    iowrite32(&ioc_address[HBA_PXIS], 0 );
141    iowrite32(&ioc_address[HBA_PXCI], 0 );
142    iowrite32(&ioc_address[HBA_PXCMD], 1 );
143
144    return 0;
145}
146
147// Local Variables:
148// tab-width: 4
149// c-basic-offset: 4
150// c-file-offsets:((innamespace . 0)(inline-open . 0))
151// indent-tabs-mode: nil
152// End:
153// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
154
Note: See TracBrowser for help on using the repository browser.