Index: /trunk/softs/tsar_boot/drivers/reset_hba.c
===================================================================
--- /trunk/softs/tsar_boot/drivers/reset_hba.c	(revision 964)
+++ /trunk/softs/tsar_boot/drivers/reset_hba.c	(revision 964)
@@ -0,0 +1,154 @@
+/**
+ * \File     : reset_hba.c
+ * \Date     : 23/11/2013
+ * \Author   : alain greiner
+ * \Copyright (c) UPMC-LIP6
+ */
+
+#include <reset_hba.h>
+#include <reset_tty.h>
+#include <reset_inval.h>
+#include <io.h>
+#include <defs.h>
+
+///////////////////////////////////////////////////////////////////////////////
+//               Global variables
+///////////////////////////////////////////////////////////////////////////////
+
+// command descriptor (one single command)
+static hba_cmd_desc_t  hba_cmd_desc  __attribute__((aligned(64)));
+
+// command table (one single command)
+static hba_cmd_table_t  hba_cmd_table __attribute__((aligned(64)));
+
+// IOC/HBA device base address
+static int* const ioc_address = (int* const)SEG_IOC_BASE;
+
+///////////////////////////////////////////////////////////////////////////////
+//      Extern functions
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+// This function register one command in both the command descriptor
+// and the command data, and updates the HBA_PXCI register.
+// The all addresses are supposed to be identity mapping (vaddr == paddr).
+// return 0 if success, -1 if error
+///////////////////////////////////////////////////////////////////////////////
+int reset_hba_read( unsigned int lba,  
+                    void*        buffer,
+                    unsigned int count )   
+{
+    unsigned int       pxci;           // HBA_PXCI register value
+    unsigned int       pxis;           // HBA_PXIS register value
+
+    // check buffer alignment
+    if( (unsigned int)buffer & 0x3F )
+    {
+        reset_puts("\n[RESET ERROR] in reset_hba_read() ");
+        reset_puts("buffer not aligned on 64 bytes: base = "); 
+        reset_putx( (unsigned int)buffer );
+        reset_puts("\n"); 
+        return -1;
+    }
+
+    // set command data header: lba value
+    hba_cmd_table.header.lba0 = (char)lba;
+    hba_cmd_table.header.lba1 = (char)(lba>>8);
+    hba_cmd_table.header.lba2 = (char)(lba>>16);
+    hba_cmd_table.header.lba3 = (char)(lba>>24);
+    hba_cmd_table.header.lba4 = 0;
+    hba_cmd_table.header.lba5 = 0;
+
+    // set command data buffer: address and size)
+    hba_cmd_table.buffer.dba  = (unsigned int)(buffer);
+    hba_cmd_table.buffer.dbau = 0;
+    hba_cmd_table.buffer.dbc  = count*512;
+
+    // set command descriptor: one single buffer / read access
+    hba_cmd_desc.prdtl[0] = 1;
+    hba_cmd_desc.prdtl[1] = 0;
+    hba_cmd_desc.flag[0]  = 0;  // read
+   
+#if USE_IOB
+    // update external memory for command table
+    reset_L2_sync( &hba_cmd_table , 32 );
+
+    // update external memory for command descriptor
+    reset_L2_sync( &hba_cmd_desc , 16 );
+#endif
+
+    // start transfer
+    iowrite32( &ioc_address[HBA_PXCI] , 1 );
+
+#if (RESET_HARD_CC == 0) || USE_IOB
+    // inval buffer in L1 cache
+    reset_L1_inval( buffer , count * 512 );
+#endif
+
+#if USE_IOB
+    // inval buffer in  L2 cache
+    reset_L2_inval( buffer , count * 512 );
+#endif
+
+    // poll PXCI until command completed by HBA
+    do
+    {
+        pxci = ioread32( &ioc_address[HBA_PXCI] );
+    }
+    while( pxci ); 
+             
+    // get PXIS register
+    pxis = ioread32( &ioc_address[HBA_PXIS] );
+
+    // reset PXIS register
+    iowrite32( &ioc_address[HBA_PXIS] , 0 );
+
+    // reset PXCI register : we use only command slot[0] in PXCI
+    iowrite32( &ioc_address[HBA_PXCI] , 0 );
+
+    // check error status 
+    if ( pxis & 0x40000000 ) 
+    {
+        reset_puts("[RESET ERROR] in reset_hba_read() : "
+                   " status error returned by HBA\n");
+        return 1;
+    }
+
+    return 0;
+} // end reset_hba_read()
+
+
+///////////////////////////////////////////////////////////////////////////////
+// This function initialises both the HBA registers and the 
+// memory structures used by the AHCI peripheral (one single command).
+///////////////////////////////////////////////////////////////////////////////
+int reset_hba_init()
+{
+    // initialise the command descriptor
+    hba_cmd_desc.ctba  = (unsigned int)&hba_cmd_table;
+    hba_cmd_desc.ctbau = 0;
+
+#if USE_IOB
+    // update external memory for the commande descriptor
+    reset_L2_sync( &hba_cmd_desc , sizeof( hba_cmd_desc_t ) );
+#endif
+    // initialise HBA registers 
+    iowrite32( &ioc_address[HBA_PXCLB]  , (unsigned int)&hba_cmd_desc );
+    iowrite32( &ioc_address[HBA_PXCLBU] , 0 );
+    iowrite32( &ioc_address[HBA_PXIE]   , 0 );
+    iowrite32( &ioc_address[HBA_PXIS]   , 0 );
+    iowrite32( &ioc_address[HBA_PXCI]   , 0 );
+    iowrite32( &ioc_address[HBA_PXCMD]  , 1 );
+
+    return 0;
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /trunk/softs/tsar_boot/drivers/reset_hba.h
===================================================================
--- /trunk/softs/tsar_boot/drivers/reset_hba.h	(revision 964)
+++ /trunk/softs/tsar_boot/drivers/reset_hba.h	(revision 964)
@@ -0,0 +1,106 @@
+/**
+ * \File     : reset_hba.h
+ * \Date     : 01/04/2015
+ * \Author   : alain greiner
+ * \Copyright (c) UPMC-LIP6
+ */
+
+#ifndef _RESET_HBA_H
+#define _RESET_HBA_H
+
+///////////////////////////////////////////////////////////////////////////////////
+// HBA component registers offsets
+///////////////////////////////////////////////////////////////////////////////////
+
+enum SoclibMultiAhciRegisters 
+{
+  HBA_PXCLB            = 0,         // command list base address 32 LSB bits
+  HBA_PXCLBU           = 1,         // command list base address 32 MSB bits
+  HBA_PXIS             = 4,         // interrupt status
+  HBA_PXIE             = 5,         // interrupt enable
+  HBA_PXCMD            = 6,         // run
+  HBA_PXCI             = 14,        // command bit-vector     
+  HBA_SPAN             = 0x400,     // 4 Kbytes per channel => 1024 slots
+};
+
+///////////////////////////////////////////////////////////////////////////////////
+// structures for one AHCI command table
+///////////////////////////////////////////////////////////////////////////////////
+
+typedef struct hba_cmd_header_s // size = 16 bytes
+{
+    // WORD 0
+    unsigned int        res0;       // reserved	
+  
+    // WORD 1
+    unsigned char	    lba0;	    // LBA 7:0
+    unsigned char	    lba1;	    // LBA 15:8
+    unsigned char	    lba2;	    // LBA 23:16
+    unsigned char	    res1;	    // reserved
+  
+    // WORD 2
+    unsigned char	    lba3;	    // LBA 31:24
+    unsigned char	    lba4;	    // LBA 39:32
+    unsigned char	    lba5;	    // LBA 47:40
+    unsigned char	    res2;	    // reserved
+  
+    // WORD 3 to 31
+    unsigned int        res3;       // reserved	
+
+} hba_cmd_header_t;
+
+typedef struct hba_cmd_buffer_s // size = 16 bytes
+{
+    unsigned int        dba;	    // Buffer base address 32 LSB bits
+    unsigned int        dbau;	    // Buffer base address 32 MSB bits
+    unsigned int        res0;	    // reserved
+    unsigned int        dbc;	    // Buffer byte count
+
+} hba_cmd_buffer_t;
+
+typedef struct hba_cmd_table_s  // one command = header + one buffer
+{
+
+    hba_cmd_header_t   header;      // contains lba value
+    hba_cmd_buffer_t   buffer;      // contains buffer address & size
+
+} hba_cmd_table_t;
+
+///////////////////////////////////////////////////////////////////////////////////
+// structure for one AHCI command descriptor
+///////////////////////////////////////////////////////////////////////////////////
+
+typedef struct hba_cmd_desc_s  // size = 16 bytes
+{
+	// WORD 0
+    unsigned char       flag[2];    // W in bit 6 of flag[0]
+    unsigned char       prdtl[2];	// Number of buffers
+
+    // WORD 1
+    unsigned int        prdbc;		// Number of bytes actually transfered
+
+    // WORD 2, WORD 3
+    unsigned int        ctba;		// Command data base address 32 LSB bits
+    unsigned int        ctbau;		// Command data base address 32 MSB bits
+
+} hba_cmd_desc_t;
+
+///////////////////////////////////////////////////////////////////////////////////
+//              access functions  
+///////////////////////////////////////////////////////////////////////////////////
+
+int reset_hba_init (); 
+
+int reset_hba_read( unsigned int lba, 
+                    void*        buffer, 
+                    unsigned int count );
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
