possibly ata pio

This commit is contained in:
koniifer 2024-12-26 02:00:51 +00:00
parent 986077435f
commit 90f1b3fdc5
4 changed files with 120 additions and 121 deletions

View file

@ -130,15 +130,27 @@ fmt_container := fn(v: @Any(), str: []u8, opts: FormatOptions): uint {
*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(".(".ptr)
len += 2
}
if kind == .Slice {
loop {
len += @inline(format, v[i], str[len..], opts)
i += 1
if i == v.len break else {
*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(", ".ptr)
len += 2
}
}
} else {
$loop {
v_sub := v[i]
len += @inline(format, v_sub, str[len..], opts)
len += @inline(format, v[i], str[len..], opts)
i += 1
if i == @lenof(T2) break else {
*@as(^[2]u8, @bitcast(str.ptr + len)) = *@bitcast(", ".ptr)
len += 2
}
}
}
if kind == .Struct | kind == .Tuple {
*@as(^[1]u8, @bitcast(str.ptr + len)) = *@bitcast(")".ptr)
len += 1

View file

@ -69,6 +69,16 @@ $inl := fn(addr: u16): u32 {
return @eca(3, 3, &InlMsg.(0, 2, addr), @sizeof(InlMsg))
}
OutsMsg := packed struct {a: u8, b: u8, addr: u16, value: u16}
$outs := fn(addr: u16, value: u32): void {
return @eca(3, 3, &OutsMsg.(1, 1, addr, value), @sizeof(OutsMsg))
}
InsMsg := packed struct {a: u8, b: u8, addr: u16}
$ins := fn(addr: u16): u16 {
return @eca(3, 3, &InsMsg.(0, 1, addr), @sizeof(InsMsg))
}
CopyMsg := packed struct {a: u8, count: uint, src: ^u8, dest: ^u8}
$copy := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
return @eca(3, 2, &CopyMsg.(4, count * @sizeof(Expr), @bitcast(src), @bitcast(dest)), @sizeof(CopyMsg))

View file

@ -1,134 +1,111 @@
.{memory, buffer, log} := @use("stn");
.{inb, outb} := memory
.{memory: .{inb, outb, ins, alloc}, log} := @use("stn")
regs := @use("regs.hb");
.{ATA_PRIMARY_IO, ATA_PRIMARY_DEVCTL, ATA_SECONDARY_DEVCTL, ATA_REG_STAT, ATA_SR_ERR, ATA_SR_BSY, ATA_SR_DF, ATA_SR_DRQ} := regs
$ATA_PRIMARY_DATA := 0x1F0
$ATA_PRIMARY_ERR := 0x1F1
$ATA_PRIMARY_SECCOUNT := 0x1F2
$ATA_PRIMARY_LBA_LO := 0x1F3
$ATA_PRIMARY_LBA_MID := 0x1F4
$ATA_PRIMARY_LBA_HI := 0x1F5
$ATA_PRIMARY_DRIVE_HEAD := 0x1F6
$ATA_PRIMARY_COMM_REGSTAT := 0x1F7
$ATA_PRIMARY_ALTSTAT_DCR := 0x3F6
sloop := fn(i: u8): void {
// idx := 0xFFFFFFF
// loop {
// if idx == 0 {
// break
// } else {
// idx -= 1
// }
// }
$STAT_ERR := 1 << 0
$STAT_DRQ := 1 << 3
$STAT_SRV := 1 << 4
$STAT_DF := 1 << 5
$STAT_RDY := 1 << 6
$STAT_BSY := 1 << 7
loop {
if i == 0 {
break
} else {
a := inb(ATA_SECONDARY_DEVCTL)
Drive := enum {Master, Slave}
i -= 1
}
select_drive := fn(drive: Drive): void {
match drive {
.Master => outb(ATA_PRIMARY_DRIVE_HEAD, 0xA0),
.Slave => outb(ATA_PRIMARY_DRIVE_HEAD, 0xB0),
}
}
// identify := fn(): u8 {
// a := inb(ATA_PRIMARY_COMM_REGSTAT)
// outb(ATA_PRIMARY_DRIVE_HEAD, 0xA0)
// log.info("Primary drive head set.")
// 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.")
// loop {
// if (status & STAT_BSY) == 0 {
// log.info("Status got.")
// break
// } else {
// sloop()
// }
// status = inb(ATA_PRIMARY_COMM_REGSTAT)
// }
// if status == 0 {
// log.error("No drive detected.")
// return 0
// }
// log.info("Status indicates presence of a drive. Polling while STAT_BSY... ")
// loop {
// if (status & STAT_BSY) == 0 {
// log.info("Status got.")
// 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.)")
// return 0
// }
// return 0
// }
drive_reset := fn(): void {
log.warn("Drive resetting.")
outb(ATA_PRIMARY_DEVCTL, 0x4)
sloop(4)
outb(ATA_PRIMARY_DEVCTL, 0x0)
}
poll := fn(): u8 {
sloop(4)
status := 0
// busy loop waiting for status
loop {
status = inb(ATA_PRIMARY_IO + ATA_REG_STAT)
if (status & ATA_SR_BSY) == 0 {
break
}
identify := fn(drive: Drive): u8 {
if inb(ATA_PRIMARY_COMM_REGSTAT) == 0xFF {
log.error("(ata: drive not present) status=0xFF")
return 0
}
status = inb(ATA_PRIMARY_IO + ATA_REG_STAT)
if (status & ATA_SR_DF) == 0 {
log.error("ATA PRIMARY DRIVE FAULT")
return 1
select_drive(drive)
inb(ATA_PRIMARY_COMM_REGSTAT)
outb(ATA_PRIMARY_SECCOUNT, 0)
inb(ATA_PRIMARY_COMM_REGSTAT)
outb(ATA_PRIMARY_LBA_LO, 0)
inb(ATA_PRIMARY_COMM_REGSTAT)
outb(ATA_PRIMARY_LBA_MID, 0)
inb(ATA_PRIMARY_COMM_REGSTAT)
outb(ATA_PRIMARY_LBA_HI, 0)
inb(ATA_PRIMARY_COMM_REGSTAT)
outb(ATA_PRIMARY_COMM_REGSTAT, 0xEC)
outb(ATA_PRIMARY_COMM_REGSTAT, 0xE7)
status := inb(ATA_PRIMARY_COMM_REGSTAT)
loop if (status & STAT_BSY) == 0 break else {
// if DEBUG_PRINT log.printf("(ata: waiting for status) status={}", .(status), .{radix: 16, log: .Warn})
status = inb(ATA_PRIMARY_COMM_REGSTAT)
}
if (status & ATA_SR_ERR) == 0 {
log.error("ATA PRIMARY ERR")
return 2
if status == 0 {
log.error("(ata: drive not present) status=0")
return 0
}
if (status & ATA_SR_DRQ) == 0 {
log.error("ATA PRIMARY DRQ")
return 3
loop if (status & STAT_BSY) == 0 break else {
if DEBUG_PRINT log.printf("(ata: waiting for busy to end) status={}", .(status), .{radix: 16, log: .Warn})
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...?")
return 0
}
loop if (status & (STAT_ERR | STAT_DRQ)) != 0 break else {
if DEBUG_PRINT log.printf("(ata: waiting for ERR or DRQ) status={}", .(status), .{radix: 16, log: .Warn})
status = inb(ATA_PRIMARY_COMM_REGSTAT)
}
if (status & STAT_ERR) != 0 {
if DEBUG_PRINT log.printf("(ata: drive error) status={}", .(status), .{radix: 16, log: .Error})
return 0
}
if DEBUG_PRINT log.printf("status={}", .(status), .{radix: 16})
buffer := alloc(u16, 255)[0..255]
read(buffer)
if DEBUG_PRINT {
if (buffer[83] & 1 << 10) != 0 {
log.info("LBA48 mode supported")
log.printf("{} 48 bit addressable sectors", *@as(^uint, @bitcast(buffer[100..].ptr)), .{})
}
log.print(buffer, .{})
}
return 0
}
main := fn(): int {
// shuts down ableOS
// outb(0xF400, 0)
a := inb(0x4600)
b := inb(0x4700)
// c := buffer.search("XNumber")
// c := identify()
d := drive_reset()
e := poll()
return 0
read := fn(buffer: []u16): void {
i := 0
loop if i == buffer.len break else {
buffer[i] = ins(ATA_PRIMARY_DATA)
i += 1
}
}
// inflates asm a lot
$DEBUG_PRINT := true
main := fn(): void {
identify(.Master)
}

View file

@ -44,8 +44,8 @@ resolution = "1024x768x24"
# [boot.limine.ableos.modules.ablefetch]
# path = "boot:///ablefetch.hbf"
# [boot.limine.ableos.modules.diskio_driver]
# path = "boot:///diskio_driver.hbf"
[boot.limine.ableos.modules.diskio_driver]
path = "boot:///diskio_driver.hbf"
# [boot.limine.ableos.modules.angels_halo]
# path = "boot:///angels_halo.hbf"
@ -53,5 +53,5 @@ resolution = "1024x768x24"
# [boot.limine.ableos.modules.test]
# path = "boot:///test.hbf"
[boot.limine.ableos.modules.vfsaur]
path = "boot:///vfsaur.hbf"
# [boot.limine.ableos.modules.vfsaur]
# path = "boot:///vfsaur.hbf"