1 | /////////////////////////////////////////////////////////////////////////////////// |
---|
2 | // File : boot_hba_driver.h |
---|
3 | // Date : 01/11/2013 |
---|
4 | // Authors : Alain Greiner / Vu Son |
---|
5 | // Copyright (c) UPMC-LIP6 |
---|
6 | /////////////////////////////////////////////////////////////////////////////////// |
---|
7 | // This file defines a simplified driver for SocLib vci_multi_ahci, |
---|
8 | // a multi-channel, block-oriented, external mass storage peripheral |
---|
9 | // respecting the AHCI standard. The driver is used by the ALMOS-MKH |
---|
10 | // boot-loader when the USE_IOC_HBA flag is set in the hard_config.h file. |
---|
11 | // Each channel can access a different physical disk, modeled by a file |
---|
12 | // belonging to the operating system, and containing a complete disk image. |
---|
13 | // However, this driver implementation only supports one channel, since the |
---|
14 | // ALMOS-MKH boot-loader only uses one physical hard drive. |
---|
15 | // The driver uses a software FIFO to register a command defined by a |
---|
16 | // Command Descriptor. A 32-entry Command Descriptor array forms the |
---|
17 | // Command List. Each Command Descriptor is associated with a Command Table |
---|
18 | // describing one given command. |
---|
19 | // All accesses to the device registers are performed via 2 low-level |
---|
20 | // functions boot_hba_get_register() and boot_hba_set_register(). |
---|
21 | // Since the driver is used by the boot-loader, it implements synchronous |
---|
22 | // accesses to block device by polling the HBA_PXCI register to detect the |
---|
23 | // transfer completion, as interrupts are not activated. |
---|
24 | /////////////////////////////////////////////////////////////////////////////////// |
---|
25 | |
---|
26 | #ifndef BOOT_HBA_DRIVER_H |
---|
27 | #define BOOT_HBA_DRIVER_H |
---|
28 | |
---|
29 | #include <hal_kernel_types.h> |
---|
30 | |
---|
31 | /**************************************************************************** |
---|
32 | * Driver register map. * |
---|
33 | ****************************************************************************/ |
---|
34 | |
---|
35 | enum HBA_registers |
---|
36 | { |
---|
37 | HBA_PXCLB = 0, /* 32 LSB of the Command List address */ |
---|
38 | HBA_PXCLBU = 1, /* 32 MSB of the Command List address */ |
---|
39 | HBA_PXIS = 2, /* Channel status, for error reporting */ |
---|
40 | HBA_PXIE = 3, /* Enabling / disabling the IRQ line */ |
---|
41 | HBA_PXCMD = 4, /* Activate Command List polling */ |
---|
42 | HBA_PXCI = 5, /* Command status bit-vector. */ |
---|
43 | |
---|
44 | HBA_SPAN = 0x400, /* HBA channel segment size (32 bits words) */ |
---|
45 | }; |
---|
46 | |
---|
47 | /**************************************************************************** |
---|
48 | * This structure defines the Command Descriptor. * |
---|
49 | ****************************************************************************/ |
---|
50 | |
---|
51 | typedef struct hba_cmd_desc_s |
---|
52 | { |
---|
53 | unsigned char flag[2]; /* WRITE when bit 6 of flag[0] is set. */ |
---|
54 | unsigned char prdtl[2]; /* Number of buffers. */ |
---|
55 | uint32_t prdbc; /* Number of bytes transfered. */ |
---|
56 | uint32_t ctba; /* 32 LSB of Command Table address. */ |
---|
57 | uint32_t ctbau; /* 32 MSB of Command Table address. */ |
---|
58 | |
---|
59 | } |
---|
60 | hba_cmd_desc_t; |
---|
61 | |
---|
62 | /**************************************************************************** |
---|
63 | * These structures define the Command Table associated with each Command * |
---|
64 | * Descriptor. * |
---|
65 | * * |
---|
66 | * For a given command, there is only one LBA coded in 48 bits to identify * |
---|
67 | * the block(s) on the device to be transfered. Yet the memory buffer can * |
---|
68 | * be splitted in a variable number of contiguous buffers. The Command * |
---|
69 | * Table thus contains 2 data structures: * |
---|
70 | * - 'hba_cmd_header_t' structure: fixed-size header (16 bytes) defining * |
---|
71 | * the LBA. * |
---|
72 | * - 'hba_cmd_buffer_t' structure: variable-sized array of fixed-size (16 * |
---|
73 | * bytes) buffer descriptors. * |
---|
74 | ****************************************************************************/ |
---|
75 | typedef struct hba_cmd_header_s |
---|
76 | { |
---|
77 | /* Word 1. */ |
---|
78 | uint32_t res0; /* Reserved. */ |
---|
79 | |
---|
80 | /* Word 2. */ |
---|
81 | unsigned char lba0; /* LBA 7:0. */ |
---|
82 | unsigned char lba1; /* LBA 15:8. */ |
---|
83 | unsigned char lba2; /* LBA 23:16. */ |
---|
84 | unsigned char res1; /* Reserved. */ |
---|
85 | |
---|
86 | /* Word 3. */ |
---|
87 | unsigned char lba3; /* LBA 31:24. */ |
---|
88 | unsigned char lba4; /* LBA 39:32. */ |
---|
89 | unsigned char lba5; /* LBA 47:40. */ |
---|
90 | unsigned char res2; /* Reserved. */ |
---|
91 | |
---|
92 | /* Word 4. */ |
---|
93 | uint32_t res3; /* Reserved. */ |
---|
94 | } |
---|
95 | hba_cmd_header_t; |
---|
96 | |
---|
97 | typedef struct hba_cmd_buffer_s |
---|
98 | { |
---|
99 | uint32_t dba; /* 32 LSB buffer base address. */ |
---|
100 | uint32_t dbau; /* 32 MSB buffer base address. */ |
---|
101 | uint32_t res; /* Reserved. */ |
---|
102 | uint32_t dbc; /* Buffer bytes count. */ |
---|
103 | } |
---|
104 | hba_cmd_buffer_t; |
---|
105 | |
---|
106 | typedef struct hba_cmd_table_s |
---|
107 | { |
---|
108 | hba_cmd_header_t header; |
---|
109 | hba_cmd_buffer_t buffer; |
---|
110 | } |
---|
111 | hba_cmd_table_t; |
---|
112 | |
---|
113 | /**************************************************************************** |
---|
114 | * Driver API functions. * |
---|
115 | ****************************************************************************/ |
---|
116 | |
---|
117 | /**************************************************************************** |
---|
118 | * This function initializes the HBA hardware registers and Command List. * |
---|
119 | * @ returns 0 on success, -1 on error. * |
---|
120 | ****************************************************************************/ |
---|
121 | int boot_hba_init(); |
---|
122 | |
---|
123 | /**************************************************************************** |
---|
124 | * This function registers a command in the Command List and Command Table. * |
---|
125 | * @ lba : LBA of the first block on the block device. * |
---|
126 | * @ buff_addr : memory buffer physical address. * |
---|
127 | * @ count : number of blocks to be transfered. * |
---|
128 | * @ returns 0 on success, -1 on error. * |
---|
129 | ****************************************************************************/ |
---|
130 | int boot_hba_access( uint32_t lba, |
---|
131 | uint64_t buf_paddr, |
---|
132 | uint32_t count ); |
---|
133 | |
---|
134 | #endif // BOOT_HBA_DRIVER_H |
---|