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
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
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
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
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
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;
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 
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);
Основные определения ядра
struct registers __attribute__((packed))
Структура данных пакета от мыши
Definition: psf.h:19