possibly ata pio
This commit is contained in:
parent
986077435f
commit
90f1b3fdc5
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue