SayoriOS 0.3.3

ahci.h
1 #pragma once
2
3 #include "common.h"
4
5 #define AHCI_SIGNATURE_SATAPI 0xEB140101
6 #define AHCI_SIGNATURE_SATA 0x00000101
7
8 #define AHCI_HBA_ST 0x0001
9 #define AHCI_HBA_FRE 0x0010
10 #define AHCI_HBA_FR 0x4000
11 #define AHCI_HBA_CR 0x8000
12
13 #define AHCI_HBA_TFES (1 << 30)
14
15 typedef volatile struct {
16 uint32_t command_list_base_address_low; // 1K-byte aligned
17 uint32_t command_list_base_address_high;
18 uint32_t fis_base_address_low; // 256-byte aligned
19 uint32_t fis_base_address_high;
20 uint32_t interrupt_status;
21 uint32_t interrupt_enable;
22 uint32_t command_and_status;
23 uint32_t reserved;
24 uint32_t task_file_data;
25 uint32_t signature;
26 uint32_t sata_status;
27 uint32_t sata_control;
28 uint32_t sata_error;
29 uint32_t sata_active;
30 uint32_t command_issue;
31 uint32_t sata_notification;
32 uint32_t fis_based_switch_control;
33
34 uint32_t reserved1[11];
35 uint32_t vendor[4];
36 } __attribute__((packed)) AHCI_HBA_PORT;
37
38 typedef volatile struct {
39 uint32_t capability;
40 uint32_t global_host_control;
41 uint32_t interrupt_status;
42 uint32_t port_implemented;
43 uint32_t version;
44 uint32_t command_completion_coalescing_control;
45 uint32_t command_completion_coalescing_ports;
46 uint32_t enclosure_management_location;
47 uint32_t enclosure_management_control;
48 uint32_t host_capabilities_extended;
49 uint32_t handoff_control_and_status;
50
51 char reserved[0xA0 - 0x2C];
52 char vendor[0x100 - 0xA0];
53
54 AHCI_HBA_PORT ports[0];
55 } __attribute__((packed)) AHCI_HBA_MEM;
56
57 typedef enum {
58 FIS_TYPE_REG_HOST_TO_DEVICE = 0x27, // Register FIS - host to device
59 FIS_TYPE_REG_DEVICE_TO_HOST = 0x34, // Register FIS - device to host
60 FIS_TYPE_DMA_ACTIVATE = 0x39, // DMA activate FIS - device to host
61 FIS_TYPE_DMA_SETUP = 0x41, // DMA setup FIS - bidirectional
62 FIS_TYPE_DATA = 0x46, // Data FIS - bidirectional
63 FIS_TYPE_BIST = 0x58, // BIST activate FIS - bidirectional
64 FIS_TYPE_PIO_SETUP = 0x5F, // PIO setup FIS - device to host
65 FIS_TYPE_DEV_BITS = 0xA1, // Set device bits FIS - device to host
66 } AHCI_FIS_TYPE;
67
68 typedef struct {
69 // 0
70 uint8_t fis_type; // FIS_TYPE_REG_H2D
71
72 // 1
73 uint8_t pmport:4; // Port multiplier
74 uint8_t rsv0:3; // Reserved
75 uint8_t c:1; // 1: Command, 0: Control
76
77 // 2
78 uint8_t command; // Command register
79
80 // 3
81 uint8_t featurel; // Feature register, 7:0
82
83 // 4 - 8
84 uint8_t lba0; // LBA low register, 7:0
85 uint8_t lba1; // LBA mid register, 15:8
86 uint8_t lba2; // LBA high register, 23:16
87 uint8_t device; // Device register
88
89 uint8_t lba3; // LBA register, 31:24
90 uint8_t lba4; // LBA register, 39:32
91 uint8_t lba5; // LBA register, 47:40
92 uint8_t featureh; // Feature register, 15:8
93
94 uint8_t countl; // Count register, 7:0
95 uint8_t counth; // Count register, 15:8
96 uint8_t icc; // Isochronous command completion
97 uint8_t control; // Control register
98
99 uint8_t rsv1[4]; // Reserved
100 } AHCI_FIS_REG_HOST_TO_DEVICE;
101
102 typedef struct {
103 uint8_t fis_type; // FIS_TYPE_REG_D2H
104
105 uint8_t pmport:4; // Port multiplier
106 uint8_t rsv0:2; // Reserved
107 uint8_t i:1; // Interrupt bit
108 uint8_t rsv1:1; // Reserved
109
110 uint8_t status; // Status register
111 uint8_t error; // Error register
112
113 uint8_t lba0; // LBA low register, 7:0
114 uint8_t lba1; // LBA mid register, 15:8
115 uint8_t lba2; // LBA high register, 23:16
116 uint8_t device; // Device register
117
118 uint8_t lba3; // LBA register, 31:24
119 uint8_t lba4; // LBA register, 39:32
120 uint8_t lba5; // LBA register, 47:40
121 uint8_t rsv2; // Reserved
122
123 uint8_t countl; // Count register, 7:0
124 uint8_t counth; // Count register, 15:8
125 uint8_t rsv3[2]; // Reserved
126
127 uint8_t rsv4[4]; // Reserved
128 } AHCI_FIS_REG_DEVICE_TO_HOST;
129
130 typedef struct {
131 // DWORD 0
132 uint8_t fis_type; // FIS_TYPE_DATA
133
134 uint8_t pmport:4; // Port multiplier
135 uint8_t rsv0:4; // Reserved
136
137 uint8_t rsv1[2]; // Reserved
138
139 // DWORD 1 ~ N
140 uint32_t data[1]; // Payload
141 } AHCI_FIS_DATA;
142
143 typedef struct tagFIS_DMA_SETUP
144 {
145 uint8_t fis_type; // FIS_TYPE_DMA_SETUP
146
147 uint8_t pmport:4; // Port multiplier
148 uint8_t rsv0:1; // Reserved
149 uint8_t d:1; // Data transfer direction, 1 - device to host
150 uint8_t i:1; // Interrupt bit
151 uint8_t a:1; // Auto-activate. Specifies if DMA Activate FIS is needed
152
153 uint8_t rsved[2]; // Reserved
154
155 uint32_t DMAbufferID_low; // DMA Buffer Identifier. Used to Identify DMA buffer in host memory.
156 uint32_t DMAbufferID_high; // DMA Buffer Identifier. Used to Identify DMA buffer in host memory.
157
158 uint32_t rsvd; //More reserved
159
160 uint32_t DMAbufOffset; //Byte offset into buffer. First 2 bits must be 0
161 uint32_t TransferCount; //Number of bytes to transfer. Bit 0 must be 0
162
163 uint32_t resvd; //Reserved
164 } AHCI_FIS_DMA_SETUP;
165
166 typedef struct {
167 uint8_t fis_type; // FIS_TYPE_PIO_SETUP
168
169 uint8_t pmport:4; // Port multiplier
170 uint8_t rsv0:1; // Reserved
171 uint8_t d:1; // Data transfer direction, 1 - device to host
172 uint8_t i:1; // Interrupt bit
173 uint8_t rsv1:1;
174
175 uint8_t status; // Status register
176 uint8_t error; // Error register
177
178 uint8_t lba0; // LBA low register, 7:0
179 uint8_t lba1; // LBA mid register, 15:8
180 uint8_t lba2; // LBA high register, 23:16
181 uint8_t device; // Device register
182
183 uint8_t lba3; // LBA register, 31:24
184 uint8_t lba4; // LBA register, 39:32
185 uint8_t lba5; // LBA register, 47:40
186 uint8_t rsv2; // Reserved
187
188 uint8_t countl; // Count register, 7:0
189 uint8_t counth; // Count register, 15:8
190 uint8_t rsv3; // Reserved
191 uint8_t e_status; // New value of status register
192
193 uint16_t tc; // Transfer count
194 uint8_t rsv4[2]; // Reserved
195 } AHCI_FIS_PIO_SETUP;
196
197 typedef struct {
198 // 0
199 uint8_t cfl:5; // Command FIS length in DWORDS, 2 ~ 16
200 uint8_t a:1; // ATAPI
201 uint8_t w:1; // Write, 1: H2D, 0: D2H
202 uint8_t p:1; // Prefetchable
203
204 // 1
205 uint8_t r:1; // Reset
206 uint8_t b:1; // BIST
207 uint8_t c:1; // Clear busy upon R_OK
208 uint8_t rsv0:1; // Reserved
209 uint8_t pmp:4; // Port multiplier port
210
211 // 2
212 uint16_t prdtl; // Physical region descriptor table length in entries
213
214 // 4
215 volatile uint32_t prdbc; // Physical region descriptor byte count transferred
216
217 // 8
218 uint32_t ctba; // Command table descriptor base address
219 uint32_t ctbau; // Command table descriptor base address upper 32 bits
220
221 // 16
222 uint32_t rsv1[4]; // Reserved
223 } AHCI_HBA_CMD_HEADER;
224
225 typedef struct {
226 uint8_t fis_type;
227 uint8_t pmport:4;
228 uint8_t rsvd:2;
229 uint8_t i:1;
230 uint8_t n:1;
231 uint8_t statusl:3;
232 uint8_t rsvd2:1;
233 uint8_t statush:3;
234 uint8_t rsvd3:1;
235 uint8_t error;
236 uint32_t protocol;
237 } AHCI_FIS_DEV_BITS;
238
239
240 typedef volatile struct {
241 AHCI_FIS_DMA_SETUP dsfis; // DMA Setup FIS
242 uint8_t pad0[4];
243
244 AHCI_FIS_PIO_SETUP psfis; // PIO Setup FIS
245 uint8_t pad1[12];
246
247 AHCI_FIS_REG_DEVICE_TO_HOST rfis; // Register – Device to Host FIS
248 uint8_t pad2[4];
249
250 AHCI_FIS_DEV_BITS sdbfis; // Set Device Bit FIS
251
252 uint8_t ufis[64];
253
254 uint8_t rsv[0x100-0xA0];
255 } AHCI_HBA_FIS;
256
257 typedef struct {
258 uint32_t dba; // Data base address
259 uint32_t dbau; // Data base address upper 32 bits
260 uint32_t rsv0; // Reserved
261
262 uint32_t dbc:22; // Byte count, 4M max
263 uint32_t rsv1:9; // Reserved
264 uint32_t i:1; // Interrupt on completion
265 } __attribute__((packed)) AHCI_HBA_PRDT_ENTRY;
266
267 #define COMMAND_TABLE_PRDT_ENTRY_COUNT 8
268
269 typedef struct {
270 uint8_t cfis[64]; // Command FIS
271 uint8_t acmd[16]; // ATAPI command, 12 or 16 bytes
272 uint8_t rsv[48]; // Reserved
273 AHCI_HBA_PRDT_ENTRY prdt_entry[COMMAND_TABLE_PRDT_ENTRY_COUNT]; // Physical region descriptor table entries, 0 ~ 65535
274 } HBA_CMD_TBL;
275
276 #define COMMAND_LIST_ENTRY_COUNT 32
277 #define COMMAND_LIST_ENTRY_SIZE sizeof(AHCI_HBA_CMD_HEADER)
278 #define COMMAND_LIST_SIZE (COMMAND_LIST_ENTRY_COUNT * COMMAND_LIST_ENTRY_SIZE)
279
280 #define FIS_SIZE sizeof(AHCI_HBA_FIS)
281
282 #define COMMAND_TABLE_ENTRY_SIZE sizeof(HBA_CMD_TBL)
283 #define COMMAND_TABLE_SIZE (COMMAND_TABLE_ENTRY_SIZE * COMMAND_LIST_ENTRY_COUNT)
284
285 #define MEMORY_PER_AHCI_PORT (COMMAND_LIST_SIZE + FIS_SIZE + COMMAND_TABLE_SIZE)
286
287 // Here we using port_num = 0 because we using new memory layout.
288 #define AHCI_COMMAND_LIST(mem, port_num) (((size_t)mem) + (MEMORY_PER_AHCI_PORT * port_num))
289 #define AHCI_FIS(mem, port_num) (AHCI_COMMAND_LIST(mem, port_num) + COMMAND_LIST_SIZE)
290 #define AHCI_COMMAND_TABLE(mem, port_num) (AHCI_FIS(mem, port_num) + FIS_SIZE)
291 #define AHCI_COMMAND_TABLE_ENTRY(mem, port_num, i) (AHCI_COMMAND_TABLE(mem, port_num) + (i * COMMAND_TABLE_ENTRY_SIZE))
292
293 struct ahci_port_descriptor {
294 AHCI_HBA_CMD_HEADER* command_list_addr_virt;
295 size_t command_list_addr_phys;
296
297 size_t fis_virt;
298 size_t fis_phys;
299
300 bool is_atapi;
301 };
302
303 void ahci_init();
304 bool ahci_is_drive_attached(size_t port_num);
305 int ahci_free_cmd_slot(size_t port_num);
306 void ahci_start_cmd(size_t port_num);
307 void ahci_stop_cmd(size_t port_num);
308 void ahci_rebase_memory_for(size_t port_num);
309 void ahci_eject_cdrom(size_t port_num);
310 void ahci_read_sectors(size_t port_num, uint64_t location, size_t sector_count, void* buffer);
311 void ahci_write_sectors(size_t port_num, size_t location, size_t sector_count, void* buffer);
312 void ahci_identify(size_t port_num, bool is_atapi);
common.h
Основные определения ядра
__attribute__
struct registers __attribute__((packed))
Структура данных пакета от мыши
Definition: psf.h:19
AHCI_FIS_DATA
Definition: ahci.h:130
AHCI_FIS_DEV_BITS
Definition: ahci.h:225
AHCI_FIS_PIO_SETUP
Definition: ahci.h:166
AHCI_FIS_REG_DEVICE_TO_HOST
Definition: ahci.h:102
AHCI_FIS_REG_HOST_TO_DEVICE
Definition: ahci.h:68
AHCI_HBA_CMD_HEADER
Definition: ahci.h:197
AHCI_HBA_FIS
Definition: ahci.h:240
HBA_CMD_TBL
Definition: ahci.h:269
ahci_port_descriptor
Definition: ahci.h:293
tagFIS_DMA_SETUP
Definition: ahci.h:144