ide: cleanup, still PF at rep insw
This commit is contained in:
parent
2db4f9899a
commit
bc46a138ff
5 changed files with 50 additions and 60 deletions
|
|
@ -69,6 +69,7 @@ pub fn initialize() void {
|
||||||
|
|
||||||
fn general_protection_fault() void {
|
fn general_protection_fault() void {
|
||||||
kernel.println("general protection fault");
|
kernel.println("general protection fault");
|
||||||
|
hang();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_trap() void {
|
fn debug_trap() void {
|
||||||
|
|
@ -83,5 +84,5 @@ fn page_fault() void {
|
||||||
kernel.println("pde: 0x{x} ({})", paging.pde(vaddr), vaddr >> 22);
|
kernel.println("pde: 0x{x} ({})", paging.pde(vaddr), vaddr >> 22);
|
||||||
kernel.println("pte: 0x{x} ({})", paging.pte(vaddr), vaddr >> 12);
|
kernel.println("pte: 0x{x} ({})", paging.pte(vaddr), vaddr >> 12);
|
||||||
// paging.format();
|
// paging.format();
|
||||||
while (true) asm volatile ("hlt");
|
hang();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
src/bio.zig
10
src/bio.zig
|
|
@ -1,6 +1,10 @@
|
||||||
// Block Device
|
// Block Device
|
||||||
// Glue code between Driver and FS
|
// Glue code between Driver and FS
|
||||||
|
|
||||||
pub const BlockDev = struct {
|
pub fn BlockDev(comptime sector_size: usize) type {
|
||||||
read: fn (u64) void,
|
return struct {
|
||||||
};
|
const sector_size;
|
||||||
|
read: fn (u64, *[sector_size]u8) void, //TODO: inferred !void or var (issue 447)
|
||||||
|
write: ?fn (u64, *[sector_size]u8) void,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ const ATA_IDENT_MAX_LBA = 120;
|
||||||
const ATA_IDENT_COMMANDSETS = 164;
|
const ATA_IDENT_COMMANDSETS = 164;
|
||||||
const ATA_IDENT_MAX_LBA_EXT = 200;
|
const ATA_IDENT_MAX_LBA_EXT = 200;
|
||||||
|
|
||||||
const ide_buf: [2048]u8 = [1]u8{0} ** 2048;
|
var ide_buf: [2048]u8 = [1]u8{0} ** 2048;
|
||||||
const atapi_packet: [12]u8 = [1]u8{0xA8} ++ [1]u8{0} ** 11;
|
const atapi_packet: [12]u8 = [1]u8{0xA8} ++ [1]u8{0} ** 11;
|
||||||
var ide_irq_invoked = false;
|
var ide_irq_invoked = false;
|
||||||
|
|
||||||
|
|
@ -134,20 +134,21 @@ pub inline fn ide_write(channel: u8, comptime reg: u8, data: u8) void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fn ide_polling(channel: u8, comptime advanced_check: bool) ?u8 {
|
inline fn ide_poll(channel: u8) void {
|
||||||
// (I) Delay 400 nanosecond for BSY to be set:
|
|
||||||
for ([_]u8{ 0, 1, 2, 3 }) |_| _ = ide_read(channel, ATA_REG_ALTSTATUS); // wate 100ns per call
|
for ([_]u8{ 0, 1, 2, 3 }) |_| _ = ide_read(channel, ATA_REG_ALTSTATUS); // wate 100ns per call
|
||||||
while (ide_read(channel, ATA_REG_STATUS) & ATA_SR_BSY != 0) {} // Wait for BSY to be zero.
|
while (ide_read(channel, ATA_REG_STATUS) & ATA_SR_BSY != 0) {} // Wait for BSY to be zero.
|
||||||
if (advanced_check) {
|
|
||||||
const state = ide_read(channel, ATA_REG_STATUS); // Read Status Register.
|
|
||||||
if (state & ATA_SR_ERR != 0) return u8(2); // Error.
|
|
||||||
if (state & ATA_SR_DF != 0) return 1; // Device Fault.
|
|
||||||
if ((state & ATA_SR_DRQ) == 0) return 3; // DRQ should be set
|
|
||||||
}
|
|
||||||
return null; // No Error.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ide_ata_access(direction: u8, drive: u8, lba: u64, numsects: u8, selector: u16, edi: usize) u8 {
|
inline fn ide_poll_check(channel: u8) !void {
|
||||||
|
// (I) Delay 400 nanosecond for BSY to be set:
|
||||||
|
ide_poll(channel);
|
||||||
|
const state = ide_read(channel, ATA_REG_STATUS); // Read Status Register.
|
||||||
|
if (state & ATA_SR_ERR != 0) return error.ATAStatusReg; // Error.
|
||||||
|
if (state & ATA_SR_DF != 0) return error.ATADeviceFault; // Device Fault.
|
||||||
|
if ((state & ATA_SR_DRQ) == 0) return error.ATANoDRQ; // DRQ should be set
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ide_ata_access(direction: u8, drive: u8, lba: u64, numsects: u8, selector: u16, edi: usize) !void {
|
||||||
var dma = false; // 0: No DMA, 1: DMA
|
var dma = false; // 0: No DMA, 1: DMA
|
||||||
var cmd: u8 = 0;
|
var cmd: u8 = 0;
|
||||||
var lba_io = [1]u8{0} ** 8;
|
var lba_io = [1]u8{0} ** 8;
|
||||||
|
|
@ -189,7 +190,6 @@ fn ide_ata_access(direction: u8, drive: u8, lba: u64, numsects: u8, selector: u1
|
||||||
head = @intCast(u8, (lba + 1 - sect) % (16 * 63) / (63)); // Head number is written to HDDEVSEL lower 4-bits.
|
head = @intCast(u8, (lba + 1 - sect) % (16 * 63) / (63)); // Head number is written to HDDEVSEL lower 4-bits.
|
||||||
lba_mode = 0;
|
lba_mode = 0;
|
||||||
}
|
}
|
||||||
kernel.println("lba_mode {}", lba_mode);
|
|
||||||
|
|
||||||
// (III) Wait if the drive is busy;
|
// (III) Wait if the drive is busy;
|
||||||
while (ide_read(channel, ATA_REG_STATUS) & ATA_SR_BSY != 0) {} // Wait if busy.)
|
while (ide_read(channel, ATA_REG_STATUS) & ATA_SR_BSY != 0) {} // Wait if busy.)
|
||||||
|
|
@ -235,15 +235,14 @@ fn ide_ata_access(direction: u8, drive: u8, lba: u64, numsects: u8, selector: u1
|
||||||
if (!dma and direction == 0) {
|
if (!dma and direction == 0) {
|
||||||
// PIO Read.
|
// PIO Read.
|
||||||
var i: u8 = 0;
|
var i: u8 = 0;
|
||||||
var iedi = edi;
|
|
||||||
while (i < numsects) : (i = i + 1) {
|
while (i < numsects) : (i = i + 1) {
|
||||||
iedi = edi + i * (words * 2);
|
var iedi = edi + i * (words * 2);
|
||||||
if (ide_polling(channel, true)) |err| return err; // Polling, set error and exit if there is.
|
try ide_poll_check(channel); // Polling, set error and exit if there is.
|
||||||
asm volatile ("pushw %%es");
|
asm volatile ("pushw %%es");
|
||||||
asm volatile ("mov %[a], %%es"
|
// asm volatile ("mov %[a], %%es"
|
||||||
:
|
// :
|
||||||
: [a] "{eax}" (selector)
|
// : [a] "{eax}" (selector)
|
||||||
);
|
// );
|
||||||
asm volatile ("rep insw"
|
asm volatile ("rep insw"
|
||||||
:
|
:
|
||||||
: [words] "{ecx}" (words),
|
: [words] "{ecx}" (words),
|
||||||
|
|
@ -259,7 +258,7 @@ fn ide_ata_access(direction: u8, drive: u8, lba: u64, numsects: u8, selector: u1
|
||||||
var iedi = edi;
|
var iedi = edi;
|
||||||
while (i < numsects) : (i = i + 1) {
|
while (i < numsects) : (i = i + 1) {
|
||||||
iedi = edi + i * (words * 2);
|
iedi = edi + i * (words * 2);
|
||||||
_ = ide_polling(channel, false); // Polling.
|
ide_poll(channel); // Polling.
|
||||||
asm volatile ("pushw %%ds");
|
asm volatile ("pushw %%ds");
|
||||||
asm volatile ("mov %%ax, %%ds"
|
asm volatile ("mov %%ax, %%ds"
|
||||||
:
|
:
|
||||||
|
|
@ -275,39 +274,36 @@ fn ide_ata_access(direction: u8, drive: u8, lba: u64, numsects: u8, selector: u1
|
||||||
}
|
}
|
||||||
if (lba_mode == 2) ide_write(channel, ATA_REG_COMMAND, ATA_CMD_CACHE_FLUSH_EXT);
|
if (lba_mode == 2) ide_write(channel, ATA_REG_COMMAND, ATA_CMD_CACHE_FLUSH_EXT);
|
||||||
if (lba_mode != 2) ide_write(channel, ATA_REG_COMMAND, ATA_CMD_CACHE_FLUSH);
|
if (lba_mode != 2) ide_write(channel, ATA_REG_COMMAND, ATA_CMD_CACHE_FLUSH);
|
||||||
_ = ide_polling(channel, true); // Polling.
|
try ide_poll_check(channel); // Polling.
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const blockdev = kernel.bio.BlockDev{ .read = ide_block_read };
|
pub const blockdev = kernel.bio.BlockDev(512){
|
||||||
pub const sectorbuffer = [1]u8{0} ** 512;
|
.read = ide_block_read,
|
||||||
pub fn ide_block_read(lba: u64) void {
|
.write = null,
|
||||||
const a = ide_read_sectors(0, 1, lba, 0x8, @ptrToInt(§orbuffer[0]));
|
};
|
||||||
if (a != 0) kernel.println("ide_read_sectors failed {}", a);
|
pub fn ide_block_read(lba: u64, buf: *[512]u8) void {
|
||||||
|
return ide_read_sectors(0, 1, lba, 0x10, @ptrToInt(buf)) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ide_read_sectors(drive: u2, numsects: u8, lba: u64, es: u8, edi: usize) u8 {
|
pub fn ide_read_sectors(drive: u2, numsects: u8, lba: u64, es: u8, edi: usize) !void {
|
||||||
// 1: Check if the drive presents:
|
// 1: Check if the drive presents:
|
||||||
if (ide_devices[drive].reserved == 0) {
|
if (ide_devices[drive].reserved == 0) {
|
||||||
return 0x1; // Drive Not Found!
|
return error.DriveNotFound; // Drive Not Found!
|
||||||
} else if (ide_devices[drive].idetype == IDE_ATA and (lba + numsects) > ide_devices[drive].size) {
|
} else if (ide_devices[drive].idetype == IDE_ATA and (lba + numsects) > ide_devices[drive].size) {
|
||||||
// 2: Check if inputs are valid:
|
// 2: Check if inputs are valid:
|
||||||
return 0x2; // Seeking to invalid position.
|
return error.InvalidSeek; // Seeking to invalid position.
|
||||||
} else {
|
} else {
|
||||||
// 3: Read in PIO Mode through Polling & IRQs:
|
// 3: Read in PIO Mode through Polling & IRQs:
|
||||||
var err: u8 = 0;
|
|
||||||
if (ide_devices[drive].idetype == IDE_ATA) {
|
if (ide_devices[drive].idetype == IDE_ATA) {
|
||||||
err = ide_ata_access(ATA_READ, drive, lba, numsects, es, edi);
|
try ide_ata_access(ATA_READ, drive, lba, numsects, es, edi);
|
||||||
} else if (ide_devices[drive].idetype == IDE_ATAPI) {
|
} else if (ide_devices[drive].idetype == IDE_ATAPI) {
|
||||||
var i: u8 = 0;
|
return error.ATAPINotImplemented;
|
||||||
while (i < numsects) : (i = i + 1) {
|
// var i: u8 = 0;
|
||||||
// err = ide_atapi_read(drive, lba + i, 1, es, edi + (i * 2048));
|
// while (i < numsects) : (i = i + 1) {
|
||||||
}
|
// // err = ide_atapi_read(drive, lba + i, 1, es, edi + (i * 2048));
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
// ide_print_error(drive, err);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -402,13 +398,6 @@ pub fn init(dev: kernel.pci.PciDevice) void {
|
||||||
ide_devices[count].size = @ptrCast(*const usize, &ide_buf[ATA_IDENT_MAX_LBA]).*;
|
ide_devices[count].size = @ptrCast(*const usize, &ide_buf[ATA_IDENT_MAX_LBA]).*;
|
||||||
}
|
}
|
||||||
|
|
||||||
kernel.println("120 {x}", ide_buf[120..122]);
|
|
||||||
kernel.println("max_lba = {x}", ide_buf[ATA_IDENT_MAX_LBA .. ATA_IDENT_MAX_LBA + 4]);
|
|
||||||
kernel.println("max_lba = {x}", ide_buf[ATA_IDENT_MAX_LBA]);
|
|
||||||
kernel.println("max_lba = {x}", ide_buf[ATA_IDENT_MAX_LBA + 1]);
|
|
||||||
kernel.println("max_lba = {x}", ide_buf[ATA_IDENT_MAX_LBA + 2]);
|
|
||||||
kernel.println("max_lba = {x}", ide_buf[ATA_IDENT_MAX_LBA + 3]);
|
|
||||||
kernel.println("max_lba = {}", @ptrCast(*const u8, &ide_buf[ATA_IDENT_MAX_LBA]).*);
|
|
||||||
// (VIII) String indicates model of device (like Western Digital HDD and SONY DVD-RW...):
|
// (VIII) String indicates model of device (like Western Digital HDD and SONY DVD-RW...):
|
||||||
var k: u16 = 0;
|
var k: u16 = 0;
|
||||||
while (k < 40) : (k = k + 2) {
|
while (k < 40) : (k = k + 2) {
|
||||||
|
|
@ -424,10 +413,10 @@ pub fn init(dev: kernel.pci.PciDevice) void {
|
||||||
for ([_]u8{ 0, 1, 2, 3 }) |i| {
|
for ([_]u8{ 0, 1, 2, 3 }) |i| {
|
||||||
if (ide_devices[i].reserved == 1) {
|
if (ide_devices[i].reserved == 1) {
|
||||||
kernel.println(
|
kernel.println(
|
||||||
"[ide] drive {} {} ({}GB) - {}",
|
"[ide] drive {} {} ({}MB) - {}",
|
||||||
i,
|
i,
|
||||||
if (ide_devices[i].idetype == 0) "ATA" else "ATAPI",
|
if (ide_devices[i].idetype == 0) "ATA" else "ATAPI",
|
||||||
ide_devices[i].size,
|
ide_devices[i].size * 512 / 1024 / 1024,
|
||||||
ide_devices[i].model,
|
ide_devices[i].model,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
src/main.zig
10
src/main.zig
|
|
@ -30,13 +30,9 @@ export fn kmain(magic: u32, info: *const multiboot.MultibootInfo) noreturn {
|
||||||
_ = task.new(@ptrToInt(topbar)) catch unreachable;
|
_ = task.new(@ptrToInt(topbar)) catch unreachable;
|
||||||
_ = task.new(@ptrToInt(console.loop)) catch unreachable;
|
_ = task.new(@ptrToInt(console.loop)) catch unreachable;
|
||||||
|
|
||||||
var i: u16 = 0;
|
var buf = [1]u8{0} ** 512;
|
||||||
var sum: u64 = 0;
|
driver.ide.blockdev.read(1, &buf);
|
||||||
driver.ide.blockdev.read(2);
|
println("sblock: {x}", buf);
|
||||||
while (i < 512) : (i += 1) {
|
|
||||||
sum += driver.ide.sectorbuffer[i];
|
|
||||||
}
|
|
||||||
println("sum: {}", sum);
|
|
||||||
|
|
||||||
task.terminate();
|
task.terminate();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ const Drivers = [_]Driver{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: factor 2 functions when anonymous fn is released
|
// TODO: factor 2 functions with a closure or a generator when released
|
||||||
pub fn scan() void {
|
pub fn scan() void {
|
||||||
var slot: u5 = 0;
|
var slot: u5 = 0;
|
||||||
// 0..31
|
// 0..31
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue