commit e4da15d83536bd4dcdb42b5887e3597f0eeb55a4
parent 24ec31ddc58641b24fa39c1f8ce6400a3beef671
Author: erai <erai@omiltem.net>
Date: Thu, 2 May 2024 22:21:26 -0400
ahci read+write
Diffstat:
M | kernel.c | | | 144 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
1 file changed, 115 insertions(+), 29 deletions(-)
diff --git a/kernel.c b/kernel.c
@@ -1544,9 +1544,32 @@ init_ahci_port(ahci: *byte, i: int) {
ahci_port.bufp = alloc_page();
ahci_port.buf = ptov(ahci_port.bufp);
- // Set command list header
+ bzero(ahci_port.buf, 4096);
+
+ fill_fis_h2d(ahci_port, ATA_READ, 0, 1);
+
+ // Set AHCI Doorbell
+ _w32(&ahci_port.port[0x38], 1);
+
+ ahci_port.next = global.ahci_port;
+ global.ahci_port = ahci_port;
+}
+
+enum {
+ ATA_IDENTIFY = 0xec,
+ ATA_READ = 0x25,
+ ATA_WRITE = 0x35,
+}
+
+fill_fis_h2d(ahci_port: *ahci_port, cmd: int, lba: int, count: int) {
+ var w: int;
+
bzero(ahci_port.cmd, 4096);
- _w32(&ahci_port.cmd[0x00], (1 << 16) + (1 << 10) + 5);
+
+ w = (cmd == ATA_WRITE);
+
+ // Set command list header
+ _w32(&ahci_port.cmd[0x00], (1 << 16) + (1 << 10) + (w << 6) + 5);
_w32(&ahci_port.cmd[0x04], 0);
_w32(&ahci_port.cmd[0x08], ahci_port.ctabp);
_w32(&ahci_port.cmd[0x0c], ahci_port.ctabp >> 32);
@@ -1554,37 +1577,36 @@ init_ahci_port(ahci: *byte, i: int) {
bzero(ahci_port.ctab, 4096);
// Fill command FIS
- ahci_port.ctab[0x00] = 0x27:byte;
- ahci_port.ctab[0x01] = 0x80:byte;
- ahci_port.ctab[0x02] = 0xec:byte;
+ ahci_port.ctab[0] = 0x27:byte;
+ ahci_port.ctab[1] = 0x80:byte;
+ ahci_port.ctab[2] = cmd:byte;
+ ahci_port.ctab[3] = 0:byte;
+
+ ahci_port.ctab[4] = lba:byte;
+ ahci_port.ctab[5] = (lba >> 8):byte;
+ ahci_port.ctab[6] = (lba >> 16):byte;
+ ahci_port.ctab[7] = (1 << 6):byte;
+
+ ahci_port.ctab[8] = (lba >> 24):byte;
+ ahci_port.ctab[9] = (lba >> 32):byte;
+ ahci_port.ctab[10] = (lba >> 40):byte;
+ ahci_port.ctab[11] = 0:byte;
+
+ ahci_port.ctab[12] = count:byte;
+ ahci_port.ctab[13] = (count >> 8):byte;
+ ahci_port.ctab[14] = 0:byte;
+ ahci_port.ctab[15] = 0:byte;
+
+ ahci_port.ctab[16] = 0:byte;
+ ahci_port.ctab[17] = 0:byte;
+ ahci_port.ctab[18] = 0:byte;
+ ahci_port.ctab[19] = 0:byte;
// Fill PRDT
_w32(&ahci_port.ctab[0x80], ahci_port.bufp);
_w32(&ahci_port.ctab[0x84], ahci_port.bufp >> 32);
_w32(&ahci_port.ctab[0x88], 0);
_w32(&ahci_port.ctab[0x8c], (1 << 31) + 511);
-
- // Set AHCI Doorbell
- _w32(&ahci_port.port[0x38], 1);
-
- //loop {
- // _w32(&port[0x30], -1);
- // if _r32(&ahci_port.port[0x38]) & 1 == 0 {
- // break;
- // }
- //}
-
- //if _r32(&port[0x30]) != 0 {
- // kputs("got error");
- // return;
- //}
-
- //kputs("Found ");
- //kputd((512 * (&ahci_port.buf[200]):*int[0]) / 1000000000);
- //kputs("GB\n");
-
- ahci_port.next = global.ahci_port;
- global.ahci_port = ahci_port;
}
isr_ahci() {
@@ -1600,6 +1622,8 @@ isr_ahci() {
break;
}
+ xxd(ahci_port.buf, 512);
+
_w32(&ahci_port.port[0x10], -1);
ahci_port = ahci_port.next;
@@ -1645,6 +1669,68 @@ sleep(ms: int) {
}
}
+xxd(data: *byte, len: int) {
+ var i: int;
+ var j: int;
+ loop {
+ if i >= len {
+ break;
+ }
+
+ kputh32(i);
+
+ kputc(':');
+ kputc(' ');
+
+ j = 0;
+
+ loop {
+ if j == 16 {
+ break;
+ }
+
+ if i + j < len {
+ kputh8(data[i + j]: int);
+ } else {
+ kputc(' ');
+ kputc(' ');
+ }
+
+ if i + j + 1 < len {
+ kputh8(data[i + j + 1]: int);
+ } else {
+ kputc(' ');
+ kputc(' ');
+ }
+
+ kputc(' ');
+
+ j = j + 2;
+ }
+
+ kputc(' ');
+
+ j = 0;
+ loop {
+ if j == 16 || i + j >= len {
+ break;
+ }
+
+ if data[i + j]:int >= 0x20 && data[i + j]:int < 0x80 {
+ kputc(data[i + j]: int);
+ } else {
+ kputc('.');
+ }
+
+ j = j + 1;
+ }
+
+ kputc('\n');
+
+ i = i + 16;
+ }
+}
+
_kstart(mb: int) {
var global: global;
var brk: int;
@@ -1812,12 +1898,12 @@ _kstart(mb: int) {
xsdt = find_xsdt();
mcfg = find_acpi(xsdt, "MCFG");
if !mcfg {
- kputs("No mcfg?\n");
+ kdie("No mcfg?\n");
}
pcip = (ptov(mcfg + 44):*int)[0];
if !pcip {
- kputs("No pci?\n");
+ kdie("No pci?\n");
}
// Enable the local apic