From 635ed1be4216f7de8fb98c0827c8ba5fe13a031e Mon Sep 17 00:00:00 2001 From: Able Date: Wed, 4 Dec 2024 04:21:24 -0600 Subject: [PATCH] theoretically works but is broken in practice :( --- repbuild/src/main.rs | 3 +- sysdata/programs/diskio_driver/src/main.hb | 126 +++++++++++---------- sysdata/programs/diskio_driver/src/regs.hb | 23 ++++ 3 files changed, 93 insertions(+), 59 deletions(-) create mode 100644 sysdata/programs/diskio_driver/src/regs.hb diff --git a/repbuild/src/main.rs b/repbuild/src/main.rs index d361cbc1..31600c43 100644 --- a/repbuild/src/main.rs +++ b/repbuild/src/main.rs @@ -90,7 +90,7 @@ fn main() -> Result<(), Error> { } else if arg == "avx2" { target = Target::X86_64Avx2; } else if arg == "--ktest" { - tests = true; + tests = true; } else { return Err(report!(Error::InvalidSubCom)); } @@ -510,7 +510,6 @@ fn run(release: bool, target: Target, do_accel: bool) -> Result<(), Error> { } } - fn fetch_ovmf(target: Target) -> Result { let (ovmf_url, ovmf_path) = match target { Target::X86_64 | Target::X86_64Avx2 => ( diff --git a/sysdata/programs/diskio_driver/src/main.hb b/sysdata/programs/diskio_driver/src/main.hb index 9311c2fb..844bf53d 100644 --- a/sysdata/programs/diskio_driver/src/main.hb +++ b/sysdata/programs/diskio_driver/src/main.hb @@ -1,67 +1,79 @@ -.{memory, buffer, log} := @use("../../../libraries/stn/src/lib.hb") +.{memory, buffer, log} := @use("../../../libraries/stn/src/lib.hb"); +.{inb, outb} := memory -// Influenced by https://github.com/levex/osdev/blob/master/drivers/ata.c +regs := @use("regs.hb"); +.{ATA_PRIMARY_COMM_REGSTAT, ATA_PRIMARY_DRIVE_HEAD, ATA_PRIMARY_SECCOUNT, ATA_PRIMARY_LBA_LO, ATA_PRIMARY_LBA_MID, ATA_PRIMARY_LBA_HI, STAT_BSY} := regs -main := fn(): int { - // shuts down ableOS - // memory.outb(0xF400, 0) +sloop := fn(): void { + idx := 0xFFFFFFF + loop { + if idx == 0 { + break + } else { + idx -= 1 + } + } +} - a := memory.inb(0x4600) - b := memory.inb(0x4700) +identify := fn(): u8 { + a := inb(ATA_PRIMARY_COMM_REGSTAT) + outb(ATA_PRIMARY_DRIVE_HEAD, 0xA0) + log.info("Primary drive head set.\0") + + a = inb(ATA_PRIMARY_COMM_REGSTAT) + outb(ATA_PRIMARY_SECCOUNT, 0) + a = inb(ATA_PRIMARY_COMM_REGSTAT) + outb(ATA_PRIMARY_LBA_LO, 0) + a = inb(ATA_PRIMARY_COMM_REGSTAT) + outb(ATA_PRIMARY_LBA_MID, 0) + a = inb(ATA_PRIMARY_COMM_REGSTAT) + outb(ATA_PRIMARY_LBA_HI, 0) + a = inb(ATA_PRIMARY_COMM_REGSTAT) + outb(ATA_PRIMARY_COMM_REGSTAT, 0xEC) + outb(ATA_PRIMARY_COMM_REGSTAT, 0xE7) + + status := inb(ATA_PRIMARY_COMM_REGSTAT) + log.info("Waiting for status.\0") + loop { + if (status & STAT_BSY) == 0 { + break + } else { + sloop() + } + status = inb(ATA_PRIMARY_COMM_REGSTAT) + } + log.info("Status got\0") + if status == 0 return 0 + + log.info("Status indicates presence of a drive. Polling while STAT_BSY... \0") + loop { + if (status & STAT_BSY) == 0 { + break + } else { + sloop() + } + status = inb(ATA_PRIMARY_COMM_REGSTAT) + } + + mid := inb(ATA_PRIMARY_LBA_MID) + hi := inb(ATA_PRIMARY_LBA_HI) + + if (mid | hi) == 0 { + log.error("The drive is not ATA. (Who knows what it is.)\0") + return 0 + } - // c := buffer.search("XNumber\0") - ata := ATA.new() return 0 } +main := fn(): int { + // shuts down ableOS + // outb(0xF400, 0) -ATA_PRIMARY := @as(u8, @intcast(0x0)) -ATA_PRIMARY_IO := @as(u8, @intcast(0x1F0)) + a := inb(0x4600) + b := inb(0x4700) -ATA_SECONDARY := @as(u8, @intcast(0x1)) -ATA_SECONDARY_IO := @as(u8, @intcast(0x170)) + // c := buffer.search("XNumber\0") + c := identify() -ATA_REG_HDDEVSEL := @as(u8, @intcast(0x6)) - -ATA_MASTER := @as(u8, @intcast(0x0)) -IDE := struct {} - -ide_select_drive := fn(bus: u8, i: u8): void { - if bus == ATA_PRIMARY { - if i == ATA_MASTER { - log.info("Primary ATA selected\0") - memory.outb(ATA_PRIMARY_IO + ATA_REG_HDDEVSEL, 0xA0) - } else { - memory.outb(ATA_PRIMARY_IO + ATA_REG_HDDEVSEL, 0xB0) - } - } else { - if i == ATA_MASTER { - memory.outb(ATA_SECONDARY_IO + ATA_REG_HDDEVSEL, 0xA0) - } else { - memory.outb(ATA_SECONDARY_IO + ATA_REG_HDDEVSEL, 0xB0) - } - } -} - -identify := fn(bus: u8, drive: u8): bool { - io := 0 - - // BUG: Causes qemu to crash - ide_select_drive(bus, drive) - if bus == ATA_PRIMARY { - io = ATA_PRIMARY_IO - } - - return true -} - -ata_probe := fn(): void { - if identify(ATA_PRIMARY, ATA_MASTER) { - } -} - -ATA := struct { - new := fn(): void { - log.info("Checking for ATA Drives.\0") - // ata_probe() - } + return 0 } \ No newline at end of file diff --git a/sysdata/programs/diskio_driver/src/regs.hb b/sysdata/programs/diskio_driver/src/regs.hb new file mode 100644 index 00000000..5562d1b2 --- /dev/null +++ b/sysdata/programs/diskio_driver/src/regs.hb @@ -0,0 +1,23 @@ +$ATA_PRIMARY_DATA := @intcast(0x1F0) +$ATA_PRIMARY_ERR := @intcast(0x1F1) +$ATA_PRIMARY_SECCOUNT := @intcast(0x1F2) +$ATA_PRIMARY_LBA_LO := @intcast(0x1F3) +$ATA_PRIMARY_LBA_MID := @intcast(0x1F4) +$ATA_PRIMARY_LBA_HI := @intcast(0x1F5) +$ATA_PRIMARY_DRIVE_HEAD := @intcast(0x1F6) +$ATA_PRIMARY_COMM_REGSTAT := @intcast(0x1F7) +$ATA_PRIMARY_ALTSTAT_DCR := @intcast(0x3F6) + +// Indicates an error occurred. Send a new command to clear it +STAT_ERR := 1 << 0 +// Set when the drive has PIO data to transfer, or is ready to accept PIO data. +STAT_DRQ := 1 << 3 +// Overlapped Mode Service Request. +STAT_SRV := 1 << 4 +// Drive Fault Error (does not set ERR). +STAT_DF := 1 << 5 +// Bit is clear when drive is spun down, or after an error. Set otherwise. +STAT_RDY := 1 << 6 +// Indicates the drive is preparing to send/receive data (wait for it to clear). +// In case of 'hang' (it never clears), do a software reset. +STAT_BSY := 1 << 7 \ No newline at end of file