Voxia OS v0.0.1
Hobby Project Operating System Targeting x86-64
Loading...
Searching...
No Matches
ahci.cpp
Go to the documentation of this file.
1#include "ahci/ahci.hpp"
2#include "ahci/ahci_reg.hpp"
3#include "ioforge/ioforge.h"
4#include "ioforge/ioforge.hpp"
7#include "memory/kalloc.h"
8#include <type.h>
9#include <str.h>
10
11// assume max port is 32
13
14static bool is_device_present(ahci_port_t* port) {
15 uint32_t ssts = port->ssts;
16 uint8_t det = ssts & HBA_PxSSTS_DET_MASK;
17
18 return (det == HBA_PxSSTS_DET_ESTABLISHED);
19}
20
22
23 if (!is_device_present(port)) {
24 return AHCI_DEV_NULL;
25 }
26 uint32_t sig = port->sig;
27
28 switch (sig) {
29 case AHCI_SIG_ATA:
30 return AHCI_DEV_SATA;
31 case AHCI_SIG_ATAPI:
32 return AHCI_DEV_SATAPI;
33 case AHCI_SIG_SEMB:
34 return AHCI_DEV_SEMB;
35 case AHCI_SIG_PM:
36 return AHCI_DEV_PM;
37 default:
38 return AHCI_DEV_NULL;
39 }
40}
41
43 // Clear ST (bit 0) dulu
44 port->cmd &= ~(1UL << 0);
45
46 // Tunggu CR (bit 15) clear
47 int timeout = 500;
48 while (timeout-- > 0) {
50 if (!(port->cmd & (1UL << 15)))
51 break;
52 }
53 if (timeout <= 0)
54 log(mod, "Warning: CR not cleared");
55
56 // Baru clear FRE (bit 4)
57 port->cmd &= ~(1UL << 4);
58
59 // Tunggu FR (bit 14) clear
60 timeout = 500;
61 while (timeout-- > 0) {
63 if (!(port->cmd & (1UL << 14)))
64 break;
65 }
66 if (timeout <= 0)
67 log(mod, "Warning: FR not cleared");
68}
69
71 // Tunggu CR clear sebelum set ST
72 int timeout = 500;
73 while (timeout-- > 0) {
74 if (!(port->cmd & (1UL << 15)))
75 break;
77 }
78
79 // Set FRE dulu, baru ST
80 port->cmd |= (1UL << 4); // FRE
82 port->cmd |= (1UL << 0); // ST
83}
84
85static int find_cmdslot(ahci_port_t* port) {
86 // If not set in SACT and CI, the slot is free
87 uint32_t slots = (port->sact | port->ci);
88 for (int i = 0; i < 32; i++) {
89 if ((slots & 1) == 0)
90 return i;
91 slots >>= 1;
92 }
93 log("AHCI", "Cannot find free command list entry\n");
94 return -1;
95}
96
99 uint32_t spin = 0;
100 while ((p->tfd & (ATA_DEV_BUSY | ATA_DEV_DRQ)) && spin < timeout_ms) {
101 spin++;
102 ioforge_sleep(1); // 1ms per tick
103 }
104 if (spin >= timeout_ms) {
105 log("AHCI", "Port is hung (pre-issue timeout)");
106 return false;
107 }
108
109 p->ci = 1 << slot;
110
111 // Timeout untuk menunggu command selesai
112 spin = 0;
113 while (spin < timeout_ms) {
114 if ((p->ci & (1UL << slot)) == 0)
115 break;
116 if (p->is & (1UL << 30)) {
117 log("AHCI",
118 "Task file error: TFD=0x%x SERR=0x%x IS=0x%x",
119 p->tfd, p->serr, p->is);
120 return false;
121 }
122
123 // Small delay initially, then sleep
124 if (spin < 10) {
125 for (int i = 0; i < 1000; i++)
126 __asm__ volatile("pause");
127 } else {
128 ioforge_sleep(1);
129 }
130 spin++;
131 }
132
133 if (spin >= timeout_ms) {
134 log("AHCI",
135 "Command timeout after %dms (CI=0x%x IS=0x%x TFD=0x%x)",
136 timeout_ms, p->ci, p->is, p->tfd);
137
138 // To correctly cancel a command, the port must be stopped
140 port_power_on(p);
141 return false;
142 }
143
144 if (p->is & (1UL << 30)) {
145 log("AHCI", "Read disk error after completion");
146 return false;
147 }
148
149 return true;
150}
151
152#define ATA_CMD_IDENTIFY_PACKET 0xA1
153#define ATA_CMD_IDENTIFY 0xEC
154#define ATA_CMD_WRITE_DMA_EXT 0x35
155#define ATA_CMD_READ_DMA_EXT 0x25
156#define ATA_CMD_PACKET 0xA0
157#define ATA_CMD_FLUSH_CACHE_EXT 0xEA
158
159void AHCIModule::build_prdt(ahci_cmd_t* cmd, ahci_cmd_tbl_t* cmdtbl,
160 void* buffer, size_t size) {
161 if (!buffer || size == 0) {
162 cmd->prdtl = 0;
163 return;
164 }
165
167 uint16_t idx = 0;
168
169 while (size > 0 && idx < 8) {
170 size_t bytes = (size > 0x400000) ? 0x400000 : size;
171
172 cmdtbl->prdt[idx].dba = (uint32_t) (addr & 0xFFFFFFFF);
173 cmdtbl->prdt[idx].dbau = (uint32_t) (addr >> 32);
174 cmdtbl->prdt[idx].dbc = (uint32_t) (bytes - 1);
175 cmdtbl->prdt[idx].i = 1;
176
177 size -= bytes;
178 addr += bytes;
179 idx++;
180 }
181
182 cmd->prdtl = idx;
183}
184
186 struct ioforge_block_request* req) {
187 p->is = (uint32_t) -1;
188
189 int freeslot = find_cmdslot(p);
190 // log("AHCI", "found free slot at %d", freeslot);
191
192 if (freeslot == -1)
193 return false;
194
195 ahci_cmd_t* cmd = (ahci_cmd_t*) vaddr->clb + freeslot;
196 cmd->cfl =
197 sizeof(ahci_fis_h2d_t) / sizeof(uint32_t); // Command FIS size
198 cmd->w = (req->op == IOFORGE_BLOCK_OP_WRITE) ? 1 : 0;
199 cmd->a = 0; // bukan atapi
200 cmd->c = 1; // command
201
202 ahci_cmd_tbl_t* cmdtbl = (ahci_cmd_tbl_t*) (vaddr->cmd[freeslot]);
203 memset(cmdtbl, 0,
204 sizeof(ahci_cmd_tbl_t) + (8 - 1) * sizeof(ahci_prdt_t));
205
206 build_prdt(cmd, cmdtbl, req->buffer, (size_t) req->block_count * 512);
207
208 ahci_fis_h2d_t* cmdfis = (ahci_fis_h2d_t*) (&cmdtbl->cfis);
209 memset(cmdfis, 0, sizeof(ahci_fis_h2d_t));
210
211 cmdfis->fis_type = FIS_TYPE_REG_H2D;
212 cmdfis->c = 1; // Command
213 cmdfis->command = (req->op == IOFORGE_BLOCK_OP_WRITE)
216 cmdfis->featureh = 0;
217 cmdfis->featurel = 0;
218
219 cmdfis->lba0 = (uint8_t) (req->lba >> 0) & 0xFF;
220 cmdfis->lba1 = (uint8_t) (req->lba >> 8) & 0xFF;
221 cmdfis->lba2 = (uint8_t) (req->lba >> 16) & 0xFF;
222 cmdfis->device = 1 << 6; // LBA mode
223
224 cmdfis->lba3 = (uint8_t) (req->lba >> 24) & 0xFF;
225 cmdfis->lba4 = (uint8_t) (req->lba >> 32) & 0xFF;
226 cmdfis->lba5 = (uint8_t) (req->lba >> 40) & 0xFF;
227
228 cmdfis->countl = req->block_count & 0xFF;
229 cmdfis->counth = (req->block_count >> 8) & 0xFF;
230
231 return issue_and_wait(p, freeslot,
232 req->timeout_ms ? req->timeout_ms : 30000);
233}
234
236 struct ioforge_block_request* req) {
237 if (!req->packet_cmd || !req->packet_cmd_len
238 || req->packet_cmd_len > 16)
239 return -1;
240
241 p->is = (uint32_t) -1;
242 p->serr = p->serr;
243
244 int freeslot = find_cmdslot(p);
245 if (freeslot == -1)
246 return 0;
247
248 bool is_dma = req->flags & IOFORGE_FLAG_DMA;
249 bool is_write = req->flags & IOFORGE_FLAG_WRITE;
250
251 ahci_cmd_t* cmd = (ahci_cmd_t*) vaddr->clb + freeslot;
252 cmd->cfl = sizeof(ahci_fis_h2d_t) / sizeof(uint32_t);
253 cmd->w = is_write ? 1 : 0;
254 cmd->a = 1;
255 cmd->c = 1;
256
257 ahci_cmd_tbl_t* cmdtbl = (ahci_cmd_tbl_t*) (vaddr->cmd[freeslot]);
258 memset(cmdtbl, 0,
259 sizeof(ahci_cmd_tbl_t) + (8 - 1) * sizeof(ahci_prdt_t));
260
261 build_prdt(cmd, cmdtbl, req->buffer, req->buffer_size);
262
263 memcopy((void*) cmdtbl->acmd, req->packet_cmd, req->packet_cmd_len);
264
265 ahci_fis_h2d_t* cmdfis = (ahci_fis_h2d_t*) (&cmdtbl->cfis);
266 memset(cmdfis, 0, sizeof(ahci_fis_h2d_t));
267
268 cmdfis->fis_type = FIS_TYPE_REG_H2D;
269 cmdfis->c = 1;
270 cmdfis->command = ATA_CMD_PACKET;
271 cmdfis->featureh = 0;
272
273 if (is_dma) {
274 cmdfis->featurel = 0x01; // DMA bit
275 cmdfis->lba1 = 0;
276 cmdfis->lba2 = 0;
277 } else {
278 cmdfis->featurel = 0x00;
279 uint16_t byte_count =
280 req->buffer_size
281 ? (uint16_t) (req->buffer_size & 0xFFFE)
282 : 0xFFFE;
283 cmdfis->lba1 = (uint8_t) (byte_count & 0xFF); // byte count LOW
284 cmdfis->lba2 =
285 (uint8_t) ((byte_count >> 8) & 0xFF); // byte count HIGH
286 }
287 // lba0, lba3, lba4, lba5 = 0 — jangan di-set apapun
288 cmdfis->device = 0;
289
290 int r = issue_and_wait(p, freeslot,
291 req->timeout_ms ? req->timeout_ms : 30000);
292
293 return r;
294}
295
297 struct ioforge_block_request* req, bool is_atapi) {
298 p->is = (uint32_t) -1;
299
300 int freeslot = find_cmdslot(p);
301
302 if (freeslot == -1)
303 return false;
304
305 ahci_cmd_t* cmd = (ahci_cmd_t*) vaddr->clb + freeslot;
306 cmd->cfl = sizeof(ahci_fis_h2d_t) / sizeof(uint32_t);
307 cmd->w = 0;
308 cmd->a = 0; // not atapi packet (it's a reg command)
309 cmd->c = 1; // command
310
311 ahci_cmd_tbl_t* cmdtbl = (ahci_cmd_tbl_t*) (vaddr->cmd[freeslot]);
312 memset(cmdtbl, 0,
313 sizeof(ahci_cmd_tbl_t) + (8 - 1) * sizeof(ahci_prdt_t));
314
315 build_prdt(cmd, cmdtbl, req->buffer, 512);
316
317 ahci_fis_h2d_t* cmdfis = (ahci_fis_h2d_t*) (&cmdtbl->cfis);
318 memset(cmdfis, 0, sizeof(ahci_fis_h2d_t));
319
320 cmdfis->fis_type = FIS_TYPE_REG_H2D;
321 cmdfis->c = 1; // Command
322 cmdfis->command = is_atapi ? ATA_CMD_IDENTIFY_PACKET : ATA_CMD_IDENTIFY;
323 cmdfis->device = 0;
324
325 // IDENTIFY commands don't use LBA
326 cmdfis->lba0 = 0;
327 cmdfis->lba1 = 0;
328 cmdfis->lba2 = 0;
329 cmdfis->lba3 = 0;
330 cmdfis->lba4 = 0;
331 cmdfis->lba5 = 0;
332
333 cmdfis->countl = 0;
334 cmdfis->counth = 0;
335
336 return issue_and_wait(p, freeslot,
337 req->timeout_ms ? req->timeout_ms : 30000);
338}
339
341 struct ioforge_block_request* req) {
342
343 if (!req->packet_cmd || !req->packet_cmd_len
344 || req->packet_cmd_len > 16)
345 return -1;
346
347 int freeslot = find_cmdslot(p);
348 // log("AHCI", "found free slot at %d", freeslot);
349
350 if (freeslot == -1)
351 return false;
352
353 ahci_cmd_t* cmd = (ahci_cmd_t*) vaddr->clb + freeslot;
354
355 cmd->cfl = sizeof(ahci_fis_h2d_t) / 4;
356 cmd->w = 0;
357 cmd->a = 0;
358 cmd->c = 1;
359 cmd->prdtl = 0; // tidak ada data transfer
360
361 ahci_cmd_tbl_t* cmdtbl = (ahci_cmd_tbl_t*) (vaddr->cmd[freeslot]);
362 memset(cmdtbl, 0,
363 sizeof(ahci_cmd_tbl_t) + (cmd->prdtl - 1) * sizeof(ahci_prdt_t));
364
365 ahci_fis_h2d_t* cmdfis = (ahci_fis_h2d_t*) (&cmdtbl->cfis);
366 memset(cmdfis, 0, sizeof(ahci_fis_h2d_t));
367
368 cmdfis->fis_type = FIS_TYPE_REG_H2D;
369 cmdfis->c = 1;
370 cmdfis->command = 0xEA; // FLUSH CACHE EXT
371
372 // Flush bisa lambat (beberapa detik pada HDD besar)
373 // timeout lebih panjang dari read/write biasa
374 return issue_and_wait(p, freeslot,
375 req->timeout_ms ? req->timeout_ms : 30000);
376}
377
379 struct ioforge_block_request* req) {
380
381 // TODO: wait until ready
382
383 ahci_port_t* p = &op->ports[dev->port];
384 p->is = (uint32_t) -1;
385
386 switch (req->op) {
389 return ata_rw(p, &port_vaddr[dev->port], req);
390 break;
391 }
393 log(mod, "request packet found type");
394 return atapi_packet(p, &port_vaddr[dev->port], req);
395 break;
396 }
398 return ata_identify(p, &port_vaddr[dev->port], req,
400 break;
401 }
403 break;
404 }
405 default:
406 return -1;
407 }
408
409 return 1;
410}
411
412extern "C" int
415 return instance->submit_impl(dev, req);
416}
417
419 struct ahci_internal_vaddr* vaddr) {
420 port_power_off(port);
421
422 // setupping command list base address (1kb aligne)
423 uintptr_t clb_phys_addr = 0;
424 auto clb = (uintptr_t) IOForge::IOUtils::DMAAlloc(1024, &clb_phys_addr);
425 IOForge::IOUtils::memset((void*) clb, 0, 1024);
426 auto aligned_clb_paddr = (clb_phys_addr + 1024 - 1) & (uintptr_t)~(1024 - 1);
427
428 port->clbu = (aligned_clb_paddr >> 32) & 0xFFFFFFFF;
429 port->clb = aligned_clb_paddr & 0xFFFFFFFF;
430 vaddr->clb = clb;
431
432 // setupping FIS base address (256 byte alligned)
433 uintptr_t fb_paddr = 0;
434 auto fb = (uintptr_t) IOForge::IOUtils::DMAAlloc(256, &fb_paddr);
435 auto aligned_fb_paddr = (fb_paddr + 256 - 1) & (uintptr_t)~(256 - 1);
436
437 port->fb = aligned_fb_paddr & 0xFFFFFFFF;
438 port->fbu = (aligned_fb_paddr >> 32) & 0xFFFFFFFF;
439 IOForge::IOUtils::memset((void*) fb, 0, 256);
440 vaddr->fb = fb;
441
442 ahci_cmd_t* cmd = (ahci_cmd_t*) clb;
443 for (int j = 0; j < 32; j++) {
444 cmd[j].prdtl = 8;
445
446 uintptr_t ctba_paddr = 0;
447 auto ctba = (uintptr_t) IOForge::IOUtils::DMAAlloc(256,
448 &ctba_paddr);
449 vaddr->cmd[j] = ctba;
450 auto aligned_ctba_paddr = (ctba_paddr + 128 - 1) & (uintptr_t)~(128 - 1);
451 cmd[j].ctba = aligned_ctba_paddr & 0xFFFFFFFF;
452 cmd[j].ctbau = (aligned_ctba_paddr >> 32) & 0xFFFFFFFF;
453 IOForge::IOUtils::memset((void*) ctba, 0, 256);
454 }
455
456 port_power_on(port);
457}
458
460 // Check Ports Implemented (PI) register
461 uint32_t ports_implemented = op->pi;
462
463 for (uint8_t i = 0; i < 32; i++) {
464 if (ports_implemented & (1UL << i)) {
465 log(mod, "Port %d implemented", i);
466
467 // Port i is implemented
468 ahci_port_t* port = &op->ports[i];
469
470 port_power_on(port);
471
472 auto vaddr = &port_vaddr[i];
473
474 {
475 boolean_t present = false;
476 int spin = 0;
477 while (spin++ < 50 && !present) {
478 if (is_device_present(port)) {
479 present = true;
480 break;
481 }
482 IOUtils::sleep(10);
483 }
484 if (!present) {
485 log(mod, "No device on port %d", i);
486 continue;
487 }
488 }
489
490 port_configure(port, vaddr);
491
492 auto type = get_device_type(port);
493
494 switch (type) {
495 case AHCI_DEV_SATA:
496 log(mod, "SATA device found on port %d", i);
497 break;
498 case AHCI_DEV_SATAPI: {
499 log(mod, "SATAPI device found on port %d", i);
500 break;
501 }
502 case AHCI_DEV_SEMB:
503 log(mod, "SEMB device found on port %d", i);
504 break;
505 case AHCI_DEV_PM:
506 log(mod, "PM device found on port %d", i);
507 break;
508 case AHCI_DEV_NULL:
509 default:
510 break;
511 }
512
513 if (!type)
514 continue;
515
516 // registering block
517 {
518 struct ioforge_block_device* dev =
520 sizeof(struct
522 memset(dev, 0,
523 sizeof(struct ioforge_block_device));
524
525 dev->port = i;
526 dev->ops.submit = submit;
527
528 switch (type) {
529 case AHCI_DEV_SATA: {
530 strcpy((char*) dev->base.name, "SATA");
531 dev->base.name[4] = '\0';
533 break;
534 }
535
536 case AHCI_DEV_SATAPI: {
537 strcpy((char*) dev->base.name,
538 "SATAPI");
539 dev->base.name[6] = '\0';
541 break;
542 }
543
544 case AHCI_DEV_SEMB: {
545 strcpy((char*) dev->base.name, "SEMB");
546 break;
547 }
548
549 case AHCI_DEV_PM: {
550 strcpy((char*) dev->base.name, "PM");
551 break;
552 }
553
554 case AHCI_DEV_NULL:
555 default:
556 break;
557 }
558
559 dev->base.type = IOFORGE_BLOCK;
560
562 &dev->base);
563 }
564 }
565 }
566}
567
569 if (!dev_ || !dev_->bar[5].address) {
570 log(mod, "Device BAR not found");
571 return;
572 }
573
574 op = (ahci_op_t*) dev_->bar[5].address;
575
576 // Enable AHCI mode dulu
577 op->ghc |= (1UL << 31);
578
579 // Reset HBA
580 op->ghc |= (1UL << 0);
581
582 // Tunggu reset selesai (bit 0 harus clear sendiri)
583 int timeout = 1000;
584 while ((op->ghc & (1UL << 0)) && timeout-- > 0) {
585 IOUtils::sleep(1);
586 }
587 if (timeout <= 0) {
588 log(mod, "HBA reset timeout");
589 return;
590 }
591
592 // Enable AHCI + interrupt setelah reset
593 op->ghc |= (1UL << 31) | (1UL << 1);
594
595 log(mod, "AHCI reset ghc done");
596
597 if (op->cap & (1UL << 31)) {
598 log(mod, "Support 64bit");
599 }
600
601 probe();
602}
static AHCIModule instance
Definition init.cpp:5
static bool is_device_present(ahci_port_t *port)
Definition ahci.cpp:14
#define ATA_CMD_WRITE_DMA_EXT
Definition ahci.cpp:154
#define ATA_CMD_READ_DMA_EXT
Definition ahci.cpp:155
#define ATA_CMD_IDENTIFY
Definition ahci.cpp:153
static ahci_device_type_t get_device_type(ahci_port_t *port)
Definition ahci.cpp:21
static int find_cmdslot(ahci_port_t *port)
Definition ahci.cpp:85
#define ATA_CMD_IDENTIFY_PACKET
Definition ahci.cpp:152
int submit(struct ioforge_block_device *dev, struct ioforge_block_request *req)
Definition ahci.cpp:413
static struct ahci_internal_vaddr port_vaddr[32]
Definition ahci.cpp:12
#define ATA_CMD_PACKET
Definition ahci.cpp:156
int submit(struct ioforge_block_device *dev, struct ioforge_block_request *req)
Definition ahci.cpp:413
#define HBA_PxSSTS_DET_MASK
Definition ahci_reg.hpp:66
#define AHCI_SIG_ATAPI
Definition ahci_reg.hpp:61
#define AHCI_SIG_SEMB
Definition ahci_reg.hpp:62
#define ATA_DEV_BUSY
Definition ahci_reg.hpp:84
ahci_device_type_t
Definition ahci_reg.hpp:99
@ AHCI_DEV_SEMB
Definition ahci_reg.hpp:102
@ AHCI_DEV_NULL
Definition ahci_reg.hpp:99
@ AHCI_DEV_SATA
Definition ahci_reg.hpp:100
@ AHCI_DEV_SATAPI
Definition ahci_reg.hpp:101
@ AHCI_DEV_PM
Definition ahci_reg.hpp:103
#define AHCI_SIG_ATA
Definition ahci_reg.hpp:60
#define HBA_PxSSTS_DET_ESTABLISHED
Definition ahci_reg.hpp:69
@ FIS_TYPE_REG_H2D
Definition ahci_reg.hpp:88
#define AHCI_SIG_PM
Definition ahci_reg.hpp:63
#define ATA_DEV_DRQ
Definition ahci_reg.hpp:85
struct ioforge_pci_device * dev_
Definition ahci.hpp:46
int ata_flush(ahci_port_t *p, struct ahci_internal_vaddr *vaddr, struct ioforge_block_request *req)
Definition ahci.cpp:340
void port_power_on(ahci_port_t *port)
Definition ahci.cpp:70
void port_power_off(ahci_port_t *port)
Definition ahci.cpp:42
ahci_op_t * op
Definition ahci.hpp:47
void port_configure(ahci_port_t *port, struct ahci_internal_vaddr *vaddr)
Definition ahci.cpp:418
int submit_impl(struct ioforge_block_device *dev, struct ioforge_block_request *req)
Definition ahci.cpp:378
void build_prdt(ahci_cmd_t *cmd, ahci_cmd_tbl_t *cmdtbl, void *buffer, size_t size)
Definition ahci.cpp:159
int atapi_packet(ahci_port_t *p, struct ahci_internal_vaddr *vaddr, struct ioforge_block_request *req)
Definition ahci.cpp:235
int ata_identify(ahci_port_t *p, struct ahci_internal_vaddr *vaddr, struct ioforge_block_request *req, bool is_atapi)
Definition ahci.cpp:296
void probe()
Definition ahci.cpp:459
void setup()
Definition ahci.cpp:568
static AHCIModule * getInstance()
Definition init.cpp:10
bool ata_rw(ahci_port_t *p, struct ahci_internal_vaddr *vaddr, struct ioforge_block_request *req)
Definition ahci.cpp:185
boolean_t issue_and_wait(ahci_port_t *p, int slot, uint32_t timeout)
Definition ahci.cpp:98
static void * DMAAlloc(size_t size, uintptr_t *paddr)
Definition ioforge.hpp:23
static void sleep(uint32_t us)
Definition ioforge.hpp:26
static void memset(void *ptr, uint8_t value, size_t num)
Definition ioforge.hpp:49
const char * mod
Definition ioforge.hpp:65
volatile uint64_t addr
Definition e1000.hpp:0
volatile uint8_t cmd
Definition e1000.hpp:3
volatile uint32_t buffer[5]
Definition ehci.hpp:8
void ioforge_attach(struct ioforge_device *parent, struct ioforge_device *child)
void ioforge_sleep(uint32_t time)
struct ioforge_device * ioforge_get_block_devices_root()
@ IOFORGE_BLOCK
Definition ioforge.h:19
#define log(mod, fmt,...)
Definition ioforge.hpp:12
@ IOFORGE_BLOCK_TYPE_SATA
@ IOFORGE_BLOCK_TYPE_SATAPI
@ IOFORGE_FLAG_WRITE
@ IOFORGE_FLAG_DMA
@ IOFORGE_BLOCK_OP_PACKET
@ IOFORGE_BLOCK_OP_FLUSH
@ IOFORGE_BLOCK_OP_IDENTIFY
@ IOFORGE_BLOCK_OP_WRITE
@ IOFORGE_BLOCK_OP_READ
void * kalloc(size_t size)
void strcpy(char *dest, const char *src)
void memset(void *ptr, int value, size_t num)
void memcopy(void *dest, void *src, size_t size)
uint8_t fis_type
Definition ahci_reg.hpp:153
uint8_t featurel
Definition ahci_reg.hpp:160
uint8_t command
Definition ahci_reg.hpp:159
uint8_t featureh
Definition ahci_reg.hpp:172
uintptr_t fb
Definition ahci.hpp:11
uintptr_t clb
Definition ahci.hpp:10
uintptr_t cmd[32]
Definition ahci.hpp:12
uint32_t is
Definition ahci_reg.hpp:11
uint32_t sact
Definition ahci_reg.hpp:20
uint32_t cmd
Definition ahci_reg.hpp:13
uint32_t fb
Definition ahci_reg.hpp:9
uint32_t ci
Definition ahci_reg.hpp:21
uint32_t clbu
Definition ahci_reg.hpp:8
uint32_t ssts
Definition ahci_reg.hpp:17
uint32_t clb
Definition ahci_reg.hpp:7
uint32_t serr
Definition ahci_reg.hpp:19
uint32_t fbu
Definition ahci_reg.hpp:10
uint32_t tfd
Definition ahci_reg.hpp:15
uint32_t sig
Definition ahci_reg.hpp:16
struct ioforge_device base
struct ioforge_block_op ops
int(* submit)(struct ioforge_block_device *dev, struct ioforge_block_request *req)
char name[64]
Definition ioforge.h:30
IoForgeType type
Definition ioforge.h:31
unsigned short uint16_t
Definition type.h:13
unsigned int uint32_t
Definition type.h:19
uint8_t boolean_t
Definition type.h:89
unsigned long uintptr_t
Definition type.h:73
unsigned char uint8_t
Definition type.h:7
uint16_t idx
Definition virtio-gpu.hpp:1
uint8_t type
Definition vnode.h:2
size_t size
Definition vnode.h:3
struct xhci_slot_ctx slot
Definition xhci.hpp:0