|
12 | 12 | #define AHCI_H |
13 | 13 |
|
14 | 14 | #include <basics.h> |
| 15 | +#include <graphics.h> |
15 | 16 |
|
16 | | -/** |
17 | | - * @brief Base memory address for AHCI ports. |
18 | | - */ |
19 | | -#define AHCI_PORT_BASE 0x400 |
20 | | - |
21 | | -/** |
22 | | - * @brief AHCI port command flags. |
23 | | - */ |
24 | | -#define AHCI_PORT_CMD_ST 0x1 /**< Start command. */ |
25 | | -#define AHCI_PORT_CMD_FRE 0x10 /**< FIS receive enable. */ |
26 | | -#define AHCI_PORT_CMD_FR 0x400 /**< FIS receive running. */ |
| 17 | +#define AHCI_PORT_DET_PRESENT 3 |
| 18 | +#define AHCI_PORT_IPM_ACTIVE 1 |
| 19 | +#define AHCI_PORT_CMD_ST (1 << 0) |
| 20 | +#define AHCI_PORT_CMD_FRE (1 << 4) |
| 21 | +#define AHCI_PORT_CMD_FR (1 << 14) |
| 22 | +#define AHCI_PORT_CMD_CR (1 << 15) |
| 23 | +#define READ_DMA_EXT 0x25 |
| 24 | +#define SECTOR_SIZE 512 |
27 | 25 |
|
28 | 26 | /** |
29 | 27 | * @brief AHCI device signatures. |
|
33 | 31 | #define semb_disk 0xC33C0101 |
34 | 32 | #define port_multiplier 0x96690101 |
35 | 33 |
|
36 | | -/** |
37 | | - * @brief Standard sector size in bytes. |
38 | | - */ |
39 | | -#define SECTOR_SIZE 512 |
40 | | - |
41 | 34 | /** |
42 | 35 | * @brief AHCI command header structure. |
43 | 36 | * |
44 | 37 | * Represents the command header for a single AHCI port. |
45 | 38 | */ |
46 | | -typedef struct { |
47 | | - uint16_t cfl:5; /**< Command FIS length in DWORDS */ |
48 | | - uint16_t a:1; /**< ATAPI flag */ |
49 | | - uint16_t w:1; /**< Write flag (1 = Host to Device, 0 = Device to Host) */ |
50 | | - uint16_t p:1; /**< Prefetchable */ |
51 | | - uint16_t r:1; /**< Reset */ |
52 | | - uint16_t b:1; /**< BIST flag */ |
53 | | - uint16_t c:1; /**< Clear busy upon R_OK */ |
54 | | - uint16_t rsv0:1; /**< Reserved */ |
55 | | - uint16_t pmp:4; /**< Port multiplier port */ |
56 | | - uint16_t prdtl; /**< Number of PRDT entries */ |
57 | | - uint32_t prdbc; /**< Physical Region Descriptor byte count transferred */ |
58 | | - uint32_t ctba; /**< Command table base address (lower 32 bits) */ |
59 | | - uint32_t ctbau; /**< Command table base address upper 32 bits */ |
60 | | - uint32_t rsv1[4]; /**< Reserved */ |
61 | | -} __attribute__((packed)) ahci_command_header_t; |
| 39 | +typedef struct __attribute__((packed)) { |
| 40 | + /* first 16-bit flags */ |
| 41 | + uint16_t flags; /* contains CFL(5), A, W, P, R, B, C, rsv0, PMP(4) */ |
| 42 | + uint16_t prdtl; /* PRDT length (entries) */ |
| 43 | + uint32_t prdbc; /* PRDT byte count transferred (updated by HBA) */ |
| 44 | + uint32_t ctba; /* Command table descriptor base address (lower 32) */ |
| 45 | + uint32_t ctbau; /* Command table descriptor base address upper 32 */ |
| 46 | + uint32_t rsv[4]; |
| 47 | +} ahci_cmd_header_t; |
| 48 | + |
| 49 | +#define AHCI_CMD_HDR_CFL_MASK 0x001F /* bits 0-4 */ |
| 50 | +#define AHCI_CMD_HDR_A_BIT 0x0020 |
| 51 | +#define AHCI_CMD_HDR_W_BIT 0x0040 |
| 52 | +#define AHCI_CMD_HDR_P_BIT 0x0080 |
| 53 | +#define AHCI_CMD_HDR_R_BIT 0x0100 |
| 54 | +#define AHCI_CMD_HDR_B_BIT 0x0200 |
| 55 | +#define AHCI_CMD_HDR_C_BIT 0x0400 |
| 56 | +#define AHCI_CMD_HDR_PMP_MASK 0xF000 /* bits 12-15 */ |
62 | 57 |
|
63 | 58 | /** |
64 | 59 | * @brief Physical Region Descriptor Table (PRDT) entry. |
65 | 60 | */ |
66 | | -typedef struct { |
67 | | - uint32_t dba; /**< Data base address */ |
68 | | - uint32_t dbau; /**< Data base address upper 32 bits */ |
69 | | - uint32_t rsv0; /**< Reserved */ |
70 | | - uint32_t dbc:22; /**< Byte count (maximum 4M) */ |
71 | | - uint32_t rsv1:9; |
72 | | - uint32_t i:1; /**< Interrupt on completion */ |
73 | | -} __attribute__((packed)) prdt_entry_t; |
| 61 | + typedef struct __attribute__((packed)) { |
| 62 | + uint32_t dba; /* Data base address (lower 32) */ |
| 63 | + uint32_t dbau; /* Data base address upper 32 (if S64A supported) */ |
| 64 | + uint32_t reserved; |
| 65 | + uint32_t dbc; /* DW3: byte count and flags (use macros) */ |
| 66 | +} prdt_entry_t; |
| 67 | + |
74 | 68 |
|
75 | 69 | /** |
76 | 70 | * @brief AHCI command table structure. |
77 | 71 | */ |
78 | | -typedef struct { |
79 | | - uint8_t cfis[64]; /**< Command FIS */ |
80 | | - uint8_t acmd[16]; /**< ATAPI command (optional) */ |
81 | | - uint8_t rsv[48]; /**< Reserved */ |
82 | | - prdt_entry_t prdt_entry[1]; /**< PRDT entries (can allocate more as needed) */ |
83 | | -} __attribute__((packed)) ahci_command_table_t; |
| 72 | + typedef struct __attribute__((packed)) { |
| 73 | + uint8_t cfis[64]; |
| 74 | + uint8_t acmd[16]; |
| 75 | + uint8_t reserved[48]; |
| 76 | + prdt_entry_t prdt[1]; /* flexible / variable sized in allocation */ |
| 77 | +} ahci_cmd_table_t; |
84 | 78 |
|
85 | 79 | /** |
86 | 80 | * @brief AHCI port registers and command header pointer. |
87 | 81 | */ |
88 | | -typedef volatile struct { |
89 | | - int32 clb; /**< Command list base address (1KB aligned) */ |
90 | | - int32 clbu; /**< Command list base address upper 32 bits */ |
91 | | - int32 fb; /**< FIS base address (256-byte aligned) */ |
92 | | - int32 fbu; /**< FIS base address upper 32 bits */ |
93 | | - int32 is; /**< Interrupt status */ |
94 | | - int32 ie; /**< Interrupt enable */ |
95 | | - int32 cmd; /**< Command and status */ |
96 | | - int32 rsv0; /**< Reserved */ |
97 | | - int32 tfd; /**< Task file data */ |
98 | | - int32 sig; /**< Signature */ |
99 | | - int32 ssts; /**< SATA status (SCR0: SStatus) */ |
100 | | - int32 sctl; /**< SATA control (SCR2: SControl) */ |
101 | | - int32 serr; /**< SATA error (SCR1: SError) */ |
102 | | - int32 sact; /**< SATA active (SCR3: SActive) */ |
103 | | - int32 ci; /**< Command issue */ |
104 | | - int32 sntf; /**< SATA notification (SCR4: SNotification) */ |
105 | | - int32 fbs; /**< FIS-based switch control */ |
106 | | - int32 rsv1[11]; /**< Reserved */ |
107 | | - int32 vendor[4]; /**< Vendor specific */ |
108 | | - ahci_command_header_t* cmd_list; /**< Pointer to command header array */ |
109 | | -} ahci_port; |
| 82 | + typedef volatile struct { |
| 83 | + uint32_t clb; /* 0x00 Command list base address (lower 32) */ |
| 84 | + uint32_t clbu; /* 0x04 Command list base address upper 32 */ |
| 85 | + uint32_t fb; /* 0x08 FIS base address (lower 32) */ |
| 86 | + uint32_t fbu; /* 0x0C FIS base address upper 32 */ |
| 87 | + uint32_t is; /* 0x10 Interrupt status */ |
| 88 | + uint32_t ie; /* 0x14 Interrupt enable */ |
| 89 | + uint32_t cmd; /* 0x18 Command and status */ |
| 90 | + uint32_t rsv0; /* 0x1C Reserved */ |
| 91 | + uint32_t tfd; /* 0x20 Task file data */ |
| 92 | + uint32_t sig; /* 0x24 Signature */ |
| 93 | + uint32_t ssts; /* 0x28 SATA status (SStatus) */ |
| 94 | + uint32_t sctl; /* 0x2C SATA control (SControl) */ |
| 95 | + uint32_t serr; /* 0x30 SATA error (SError) */ |
| 96 | + uint32_t sact; /* 0x34 SATA active (SActive) */ |
| 97 | + uint32_t ci; /* 0x38 Command issue */ |
| 98 | + uint32_t sntf; /* 0x3C SATA notification (SNotification) */ |
| 99 | + uint32_t fbs; /* 0x40 FIS-based switching */ |
| 100 | + uint32_t rsv1[11]; /* 0x44 - 0x6F reserved */ |
| 101 | + uint32_t vendor[4]; /* 0x70 - 0x7F vendor specific */ |
| 102 | +} ahci_port_t; |
110 | 103 |
|
111 | | -/** |
112 | | - * @brief AHCI controller registers. |
113 | | - */ |
114 | 104 | typedef volatile struct { |
115 | | - int32 cap; /**< Host Capabilities */ |
116 | | - int32 ghc; /**< Global Host Control */ |
117 | | - int32 is; /**< Interrupt Status */ |
118 | | - int32 pi; /**< Port Implemented */ |
119 | | - int32 vs; /**< Version */ |
120 | | - int32 ccc_ctl; /**< Command Completion Coalescing Control */ |
121 | | - int32 ccc_pts; /**< Command Completion Coalescing Ports */ |
122 | | - int32 em_loc; /**< Enclosure Management Location */ |
123 | | - int32 em_ctl; /**< Enclosure Management Control */ |
124 | | - int32 cap2; /**< Host Capabilities Extended */ |
125 | | - int32 bohc; /**< BIOS/OS Handoff Control and Status */ |
126 | | - int8 rsv[0xA0-0x2C]; /**< Reserved */ |
127 | | - int8 vendor[0x100-0xA0]; /**< Vendor specific */ |
128 | | - ahci_port ports[32]; /**< AHCI port control registers */ |
129 | | -} ahci_controller; |
| 105 | + uint32_t cap; /* 0x00 Host capabilities (CAP) */ |
| 106 | + uint32_t ghc; /* 0x04 Global host control (GHC) */ |
| 107 | + uint32_t is; /* 0x08 Interrupt status */ |
| 108 | + uint32_t pi; /* 0x0C Ports implemented */ |
| 109 | + uint32_t vs; /* 0x10 Version */ |
| 110 | + uint32_t ccc_ctl; /* 0x14 Command completion coalescing control */ |
| 111 | + uint32_t ccc_pts; /* 0x18 Command completion ports */ |
| 112 | + uint32_t em_loc; /* 0x1C Enclosure management location */ |
| 113 | + uint32_t em_ctl; /* 0x20 Enclosure management control */ |
| 114 | + uint32_t cap2; /* 0x24 Host capabilities extended */ |
| 115 | + uint32_t bohc; /* 0x28 BIOS/OS handoff control and status */ |
| 116 | + uint8_t rsv[0xA0 - 0x2C]; /* reserved bytes up to vendor area */ |
| 117 | + uint8_t vendor[0x100 - 0xA0];/* vendor specific area */ |
| 118 | + /* 0x100 - start of port control registers (ports[0] starts here) */ |
| 119 | + ahci_port_t ports[32]; /* array of port structures (0x100.. ) */ |
| 120 | +} ahci_hba_mem_t; |
| 121 | + |
130 | 122 |
|
131 | 123 | /** |
132 | 124 | * @brief Global AHCI controller pointer. |
133 | 125 | */ |
134 | | -extern ahci_controller* global_ahci_ctrl; |
| 126 | +extern ahci_hba_mem_t* global_ahci_ctrl; |
135 | 127 |
|
136 | 128 | /** |
137 | 129 | * @brief Probes and detects all AHCI devices connected to the controller. |
138 | 130 | * |
139 | 131 | * @param ahci_ctrl Pointer to the AHCI controller structure. |
140 | 132 | */ |
141 | | -void detect_ahci_devices(ahci_controller* ahci_ctrl); |
142 | | - |
143 | | -/** |
144 | | - * @brief Reads sectors from a port using polling mode. |
145 | | - * |
146 | | - * @param port_number The AHCI port number to read from. |
147 | | - * @param lba Logical block address to start reading. |
148 | | - * @param sector_count Number of sectors to read. |
149 | | - * @param buffer Pointer to the buffer to store data. |
150 | | - * @return int 0 on success, negative on failure. |
151 | | - */ |
152 | | -int ahci_read_sectors_polling(int port_number, uint64_t lba, uint32_t sector_count, void* buffer); |
153 | | - |
| 133 | +void detect_ahci_devices(ahci_hba_mem_t* ahci_ctrl); |
154 | 134 | #endif // AHCI_H |
0 commit comments