/////////////////////////////////////////////////////////////////////////////////// // File : boot_hba_driver.h // Date : 01/11/2013 // Authors : Alain Greiner / Vu Son // Copyright (c) UPMC-LIP6 /////////////////////////////////////////////////////////////////////////////////// // This file defines a simplified driver for SocLib vci_multi_ahci, // a multi-channel, block-oriented, external mass storage peripheral // respecting the AHCI standard. The driver is used by the ALMOS-MKH // boot-loader when the USE_IOC_HBA flag is set in the hard_config.h file. // Each channel can access a different physical disk, modeled by a file // belonging to the operating system, and containing a complete disk image. // However, this driver implementation only supports one channel, since the // ALMOS-MKH boot-loader only uses one physical hard drive. // The driver uses a software FIFO to register a command defined by a // Command Descriptor. A 32-entry Command Descriptor array forms the // Command List. Each Command Descriptor is associated with a Command Table // describing one given command. // All accesses to the device registers are performed via 2 low-level // functions boot_hba_get_register() and boot_hba_set_register(). // Since the driver is used by the boot-loader, it implements synchronous // accesses to block device by polling the HBA_PXCI register to detect the // transfer completion, as interrupts are not activated. /////////////////////////////////////////////////////////////////////////////////// #ifndef BOOT_HBA_DRIVER_H #define BOOT_HBA_DRIVER_H #include /**************************************************************************** * Driver register map. * ****************************************************************************/ enum HBA_registers { HBA_PXCLB = 0, /* 32 LSB of the Command List address */ HBA_PXCLBU = 1, /* 32 MSB of the Command List address */ HBA_PXIS = 2, /* Channel status, for error reporting */ HBA_PXIE = 3, /* Enabling / disabling the IRQ line */ HBA_PXCMD = 4, /* Activate Command List polling */ HBA_PXCI = 5, /* Command status bit-vector. */ HBA_SPAN = 0x400, /* HBA channel segment size (32 bits words) */ }; /**************************************************************************** * This structure defines the Command Descriptor. * ****************************************************************************/ typedef struct hba_cmd_desc_s { unsigned char flag[2]; /* WRITE when bit 6 of flag[0] is set. */ unsigned char prdtl[2]; /* Number of buffers. */ uint32_t prdbc; /* Number of bytes transfered. */ uint32_t ctba; /* 32 LSB of Command Table address. */ uint32_t ctbau; /* 32 MSB of Command Table address. */ } hba_cmd_desc_t; /**************************************************************************** * These structures define the Command Table associated with each Command * * Descriptor. * * * * For a given command, there is only one LBA coded in 48 bits to identify * * the block(s) on the device to be transfered. Yet the memory buffer can * * be splitted in a variable number of contiguous buffers. The Command * * Table thus contains 2 data structures: * * - 'hba_cmd_header_t' structure: fixed-size header (16 bytes) defining * * the LBA. * * - 'hba_cmd_buffer_t' structure: variable-sized array of fixed-size (16 * * bytes) buffer descriptors. * ****************************************************************************/ typedef struct hba_cmd_header_s { /* Word 1. */ uint32_t res0; /* Reserved. */ /* Word 2. */ unsigned char lba0; /* LBA 7:0. */ unsigned char lba1; /* LBA 15:8. */ unsigned char lba2; /* LBA 23:16. */ unsigned char res1; /* Reserved. */ /* Word 3. */ unsigned char lba3; /* LBA 31:24. */ unsigned char lba4; /* LBA 39:32. */ unsigned char lba5; /* LBA 47:40. */ unsigned char res2; /* Reserved. */ /* Word 4. */ uint32_t res3; /* Reserved. */ } hba_cmd_header_t; typedef struct hba_cmd_buffer_s { uint32_t dba; /* 32 LSB buffer base address. */ uint32_t dbau; /* 32 MSB buffer base address. */ uint32_t res; /* Reserved. */ uint32_t dbc; /* Buffer bytes count. */ } hba_cmd_buffer_t; typedef struct hba_cmd_table_s { hba_cmd_header_t header; hba_cmd_buffer_t buffer; } hba_cmd_table_t; /**************************************************************************** * Driver API functions. * ****************************************************************************/ /**************************************************************************** * This function initializes the HBA hardware registers and Command List. * * @ returns 0 on success, -1 on error. * ****************************************************************************/ int boot_hba_init(); /**************************************************************************** * This function registers a command in the Command List and Command Table. * * @ lba : LBA of the first block on the block device. * * @ buff_addr : memory buffer physical address. * * @ count : number of blocks to be transfered. * * @ returns 0 on success, -1 on error. * ****************************************************************************/ int boot_hba_access( uint32_t lba, uint64_t buf_paddr, uint32_t count ); #endif // BOOT_HBA_DRIVER_H