diff --git a/build.zig b/build.zig index 58bf2c6..6794a81 100644 --- a/build.zig +++ b/build.zig @@ -7,7 +7,6 @@ pub fn build(b: *Builder) void { kernel.addPackagePath("x86", "src/arch/x86/index.zig"); kernel.setOutputDir("build"); - // kernel.addAssemblyFile("src/arch/x86/_start.s"); kernel.addAssemblyFile("src/arch/x86/gdt.s"); kernel.addAssemblyFile("src/arch/x86/isr.s"); kernel.addAssemblyFile("src/arch/x86/paging.s"); diff --git a/qemu.sh b/qemu.sh index 950dbb8..ee36123 100755 --- a/qemu.sh +++ b/qemu.sh @@ -12,8 +12,8 @@ start() { -m 1337M \ -curses \ -append "Hello" \ - -drive file=disk.img,if=virtio\ -kernel ${KERNEL} + # -drive file=disk.img,if=virtio\ # -no-reboot \ # -device virtio-net,netdev=network0 -netdev tap,id=network0,ifname=tap0,script=no,downscript=no \ # build/kernel.iso diff --git a/src/arch/x86/_start.s b/src/arch/x86/_start.s deleted file mode 100644 index db987e0..0000000 --- a/src/arch/x86/_start.s +++ /dev/null @@ -1,16 +0,0 @@ -.global __start -.type __start, @function - -// Entry point. It puts the machine into a consistent state, -// starts the kernel and then waits forever. -__start: - mov $0x80000, %esp // Setup the stack. - - push %ebx // Pass multiboot info structure. - push %eax // Pass multiboot magic code. - - call kmain // Call the kernel. - - // Halt the CPU. - cli - hlt diff --git a/src/arch/x86/idt.zig b/src/arch/x86/idt.zig index 443c383..32c29a7 100644 --- a/src/arch/x86/idt.zig +++ b/src/arch/x86/idt.zig @@ -1,18 +1,19 @@ // https://wiki.osdev.org/IDT -usingnamespace @import("kernel"); -usingnamespace @import("x86"); +// usingnamespace @import("kernel"); +// usingnamespace @import("x86"); +usingnamespace @import("index.zig"); // Types of gates. pub const INTERRUPT_GATE = 0x8E; pub const SYSCALL_GATE = 0xEE; // Interrupt Descriptor Table. -var idt: [256]IDTEntry = undefined; +var idt_table: [256]IDTEntry = undefined; // IDT descriptor register pointing at the IDT. const idtr = IDTRegister{ - .limit = u16(@sizeOf(@typeOf(idt))), - .base = &idt, + .limit = u16(@sizeOf(@typeOf(idt_table))), + .base = &idt_table, }; // Structure representing an entry in the IDT. @@ -40,11 +41,11 @@ const IDTRegister = packed struct { pub fn setGate(n: u8, flags: u8, offset: extern fn () void) void { const intOffset = @ptrToInt(offset); - idt[n].offset_low = @truncate(u16, intOffset); - idt[n].offset_high = @truncate(u16, intOffset >> 16); - idt[n].flags = flags; - idt[n].zero = 0; - idt[n].selector = gdt.KERNEL_CODE; + idt_table[n].offset_low = @truncate(u16, intOffset); + idt_table[n].offset_high = @truncate(u16, intOffset >> 16); + idt_table[n].flags = flags; + idt_table[n].zero = 0; + idt_table[n].selector = gdt.KERNEL_CODE; } // Initialize the Interrupt Descriptor Table. diff --git a/src/arch/x86/index.zig b/src/arch/x86/index.zig index fe3dc58..ea3be95 100644 --- a/src/arch/x86/index.zig +++ b/src/arch/x86/index.zig @@ -1,9 +1,15 @@ -usingnamespace @import("lib/io.zig"); -usingnamespace @import("lib/instructions.zig"); -usingnamespace @import("main.zig"); +pub usingnamespace @import("../../vga.zig"); +pub const multiboot = @import("../../multiboot.zig"); -const memory = @import("memory.zig"); -const paging = @import("paging.zig"); -const idt = @import("idt.zig"); -const gdt = @import("gdt.zig"); -const interrupt = @import("interrupt.zig"); +pub usingnamespace @import("lib/io.zig"); +pub usingnamespace @import("lib/instructions.zig"); +pub usingnamespace @import("main.zig"); + +pub const memory = @import("memory.zig"); +pub const paging = @import("paging.zig"); +pub const idt = @import("idt.zig"); +pub const isr = @import("isr.zig"); +pub const gdt = @import("gdt.zig"); +pub const interrupt = @import("interrupt.zig"); + +pub const assert = @import("std").debug.assert; diff --git a/src/arch/x86/interrupt.zig b/src/arch/x86/interrupt.zig index a4da053..5b991a4 100644 --- a/src/arch/x86/interrupt.zig +++ b/src/arch/x86/interrupt.zig @@ -1,6 +1,6 @@ -usingnamespace @import("kernel"); -const x86 = @import("x86"); -const isr = @import("isr.zig"); +usingnamespace @import("index.zig"); +// const x86 = @import("index.zig"); +// const isr = @import("isr.zig"); // PIC ports. const PIC1_CMD = 0x20; @@ -32,16 +32,17 @@ var handlers = [_]fn () void{unhandled} ** 48; fn unhandled() noreturn { const n = isr.context.interrupt_n; + print("unhandled interrupt number {d}", n); if (n < IRQ_0) { - println("unhandled exception number {d}", n); + println(" (exception)"); } else { - println("unhandled IRQ number {d} (intr {d})", n - IRQ_0, n); + println(" (IRQ number {d})", n - IRQ_0); } - x86.hang(); + hang(); } inline fn picwait() void { - x86.outb(WAIT_PORT, 0); + outb(WAIT_PORT, 0); } //// @@ -81,8 +82,8 @@ export fn interruptDispatch() void { // If no user thread is ready to run, halt here and wait for interrupts. // if (scheduler.current() == null) { - // x86.sti(); - // x86.hlt(); + // sti(); + // hlt(); // } } @@ -92,8 +93,8 @@ inline fn spuriousIRQ(irq: u8) bool { // TODO: handle spurious IRQ15. // Read the value of the In-Service Register. - x86.outb(PIC1_CMD, ISR_READ); - const in_service = x86.inb(PIC1_CMD); + outb(PIC1_CMD, ISR_READ); + const in_service = inb(PIC1_CMD); // Verify whether IRQ7 is set in the ISR. return (in_service & (1 << 7)) == 0; @@ -103,11 +104,11 @@ inline fn startOfInterrupt(irq: u8) void { // mask the irq and then ACK if (irq >= 8) { maskIRQ(irq, true); - x86.outb(PIC1_CMD, ACK); - x86.outb(PIC2_CMD, ACK); + outb(PIC1_CMD, ACK); + outb(PIC2_CMD, ACK); } else { maskIRQ(irq, true); - x86.outb(PIC1_CMD, ACK); + outb(PIC1_CMD, ACK); } } @@ -115,10 +116,10 @@ inline fn endOfInterrupt(irq: u8) void { // unmask the irq and then ACK if (irq >= 8) { maskIRQ(irq, false); - x86.outb(PIC2_CMD, ACK); + outb(PIC2_CMD, ACK); } else { maskIRQ(irq, false); - x86.outb(PIC1_CMD, ACK); + outb(PIC1_CMD, ACK); } } @@ -133,33 +134,33 @@ pub fn registerIRQ(irq: u8, handler: fn () void) void { fn remapPIC() void { // ICW1: start initialization sequence. - x86.outb(PIC1_CMD, ICW1_INIT | ICW1_ICW4); + outb(PIC1_CMD, ICW1_INIT | ICW1_ICW4); picwait(); - x86.outb(PIC2_CMD, ICW1_INIT | ICW1_ICW4); + outb(PIC2_CMD, ICW1_INIT | ICW1_ICW4); picwait(); // ICW2: Interrupt Vector offsets of IRQs. - x86.outb(PIC1_DATA, IRQ_0); // IRQ 0..7 -> Interrupt 32..39 + outb(PIC1_DATA, IRQ_0); // IRQ 0..7 -> Interrupt 32..39 picwait(); - x86.outb(PIC2_DATA, IRQ_0 + 8); // IRQ 8..15 -> Interrupt 40..47 + outb(PIC2_DATA, IRQ_0 + 8); // IRQ 8..15 -> Interrupt 40..47 picwait(); // ICW3: IRQ line 2 to connect master to slave PIC. - x86.outb(PIC1_DATA, 1 << 2); + outb(PIC1_DATA, 1 << 2); picwait(); - x86.outb(PIC2_DATA, 2); + outb(PIC2_DATA, 2); picwait(); // ICW4: 80x86 mode. - x86.outb(PIC1_DATA, ICW4_8086); + outb(PIC1_DATA, ICW4_8086); picwait(); - x86.outb(PIC2_DATA, ICW4_8086); + outb(PIC2_DATA, ICW4_8086); picwait(); // Mask all IRQs. - x86.outb(PIC1_DATA, 0xFF); + outb(PIC1_DATA, 0xFF); picwait(); - x86.outb(PIC2_DATA, 0xFF); + outb(PIC2_DATA, 0xFF); picwait(); } @@ -167,16 +168,16 @@ pub fn maskIRQ(irq: u8, mask: bool) void { if (irq > 15) return; // Figure out if master or slave PIC owns the IRQ. const port = if (irq < 8) u16(PIC1_DATA) else u16(PIC2_DATA); - const old = x86.inb(port); // Retrieve the current mask. + const old = inb(port); // Retrieve the current mask. // Mask or unmask the interrupt. const shift = @intCast(u3, irq % 8); if (mask) { - x86.outb(port, old | (u8(1) << shift)); + outb(port, old | (u8(1) << shift)); } else { - x86.outb(port, old & ~(u8(1) << shift)); + outb(port, old & ~(u8(1) << shift)); } - const new = x86.inb(port); // Retrieve the current mask. + const new = inb(port); // Retrieve the current mask. } //// diff --git a/src/arch/x86/isr.zig b/src/arch/x86/isr.zig index 47cf0a9..7a4fd05 100644 --- a/src/arch/x86/isr.zig +++ b/src/arch/x86/isr.zig @@ -1,4 +1,4 @@ -usingnamespace @import("x86"); +usingnamespace @import("index.zig"); // Interrupt Service Routines defined externally in assembly. extern fn isr0() void; diff --git a/src/arch/x86/main.zig b/src/arch/x86/main.zig index 5a3ce99..8b5eb77 100644 --- a/src/arch/x86/main.zig +++ b/src/arch/x86/main.zig @@ -1,13 +1,14 @@ -usingnamespace @import("kernel"); -usingnamespace @import("x86"); +// usingnamespace @import("kernel"); +usingnamespace @import("index.zig"); +// const multiboot = @import("../../multiboot.zig"); /// x86 specific intialization -pub fn x86_main(info: *const MultibootInfo) void { +pub fn x86_main(info: *const multiboot.MultibootInfo) void { gdt.initialize(); idt.initialize(); memory.initialize(info); paging.initialize(); // enable interrupts - x86.sti(); + sti(); } diff --git a/src/arch/x86/memory.zig b/src/arch/x86/memory.zig index bfe48cf..3c7335c 100644 --- a/src/arch/x86/memory.zig +++ b/src/arch/x86/memory.zig @@ -1,4 +1,4 @@ -usingnamespace @import("kernel"); +usingnamespace @import("index.zig"); var stack: [*]usize = undefined; // Stack of free physical page. var stack_index: usize = 0; // Index into the stack. @@ -51,10 +51,10 @@ pub fn free(address: usize) void { // Arguments: // info: Information structure from bootloader. // -pub fn initialize(info: *const MultibootInfo) void { +pub fn initialize(info: *const multiboot.MultibootInfo) void { // Ensure the bootloader has given us the memory map. - assert((info.flags & MULTIBOOT_INFO_MEMORY) != 0); - assert((info.flags & MULTIBOOT_INFO_MEM_MAP) != 0); + assert((info.flags & multiboot.MULTIBOOT_INFO_MEMORY) != 0); + assert((info.flags & multiboot.MULTIBOOT_INFO_MEM_MAP) != 0); // Place the stack of free pages after the last Multiboot module. stack = @intToPtr([*]usize, 0x200000); @@ -65,7 +65,7 @@ pub fn initialize(info: *const MultibootInfo) void { var map: usize = info.mmap_addr; while (map < info.mmap_addr + info.mmap_length) { - var entry = @intToPtr(*MultibootMMapEntry, map); + var entry = @intToPtr(*multiboot.MultibootMMapEntry, map); // Calculate the start and end of this memory area. var start = @truncate(usize, entry.addr); @@ -74,7 +74,7 @@ pub fn initialize(info: *const MultibootInfo) void { start = if (start >= stack_end) start else stack_end; // Flag all the pages in this memory area as free. - if (entry.type == MULTIBOOT_MEMORY_AVAILABLE) while (start < end) : (start += PAGE_SIZE) + if (entry.type == multiboot.MULTIBOOT_MEMORY_AVAILABLE) while (start < end) : (start += PAGE_SIZE) free(start); // Go to the next entry in the memory map. diff --git a/src/arch/x86/paging.zig b/src/arch/x86/paging.zig index cd93b3c..6a92188 100644 --- a/src/arch/x86/paging.zig +++ b/src/arch/x86/paging.zig @@ -1,5 +1,5 @@ -usingnamespace @import("kernel"); -usingnamespace @import("x86"); +usingnamespace @import("index.zig"); +// usingnamespace @import("x86"); extern fn setupPaging(phys_pd: usize) void; diff --git a/src/console.zig b/src/console.zig index 3c1d1b0..8cf854c 100644 --- a/src/console.zig +++ b/src/console.zig @@ -1,4 +1,4 @@ -usingnamespace @import("kernel"); +usingnamespace @import("index.zig"); var command: [10]u8 = undefined; var command_len: usize = 0; @@ -30,6 +30,6 @@ pub fn keypress(char: u8) void { } pub fn initialize() void { - @import("x86").interrupt.registerIRQ(1, ps2.keyboard_handler); + x86.interrupt.registerIRQ(1, ps2.keyboard_handler); print("> "); } diff --git a/src/index.zig b/src/index.zig index 89eed32..cce2ad0 100644 --- a/src/index.zig +++ b/src/index.zig @@ -1,8 +1,9 @@ +pub const assert = @import("std").debug.assert; +pub const std = @import("std"); + pub usingnamespace @import("vga.zig"); -pub const main = @import("main.zig"); pub const multiboot = @import("multiboot.zig"); pub const console = @import("console.zig"); -pub const pci = @import("pci.zig"); +pub const pci = @import("pci/pci.zig"); pub const ps2 = @import("ps2.zig"); - -pub const assert = @import("std").debug.assert; +pub const x86 = @import("arch/x86/index.zig"); diff --git a/src/main.zig b/src/main.zig index 741a87e..fff5250 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,29 +1,43 @@ usingnamespace @import("kernel"); +// const x86 = @import("x86"); -const x86 = @import("x86"); +// Place the header at the very beginning of the binary. +export const multiboot_header align(4) linksection(".multiboot") = multiboot: { + const MAGIC = u32(0x1BADB002); // multiboot magic + const ALIGN = u32(1 << 0); // Align loaded modules at 4k + const MEMINFO = u32(1 << 1); // Receive a memory map from the bootloader. + const ADDR = u32(1 << 16); // Load specific addr + const FLAGS = ALIGN | MEMINFO; // Combine the flags. + + break :multiboot multiboot.MultibootHeader{ + .magic = MAGIC, + .flags = FLAGS, + .checksum = ~(MAGIC +% FLAGS) +% 1, + }; +}; export var stack_bytes: [16 * 1024]u8 align(16) linksection(".bss") = undefined; const stack_bytes_slice = stack_bytes[0..]; // linker.ld entrypoint -export nakedcc fn _start() noreturn { - // ebx -> multiboot info - const info: u32 = asm volatile ("" - : [result] "={ebx}" (-> u32) - ); +export nakedcc fn __start() noreturn { // eax -> multiboot magic const magic: u32 = asm volatile ("" : [result] "={eax}" (-> u32) ); + // ebx -> multiboot info + const info: u32 = asm volatile ("" + : [result] "={ebx}" (-> u32) + ); @newStackCall(stack_bytes_slice, kmain, magic, @intToPtr(*const multiboot.MultibootInfo, info)); - while (true) {} + // @newStackCall(stack_bytes_slice, kmain); } // arch independant initialization fn kmain(magic: u32, info: *const multiboot.MultibootInfo) noreturn { - assert(magic == multiboot.MULTIBOOT_BOOTLOADER_MAGIC); - clear(); + println("--- {x} ---", magic); + // assert(magic == multiboot.MULTIBOOT_BOOTLOADER_MAGIC); println("--- x86 initialization ---"); x86.x86_main(info); println("--- core initialization ---"); diff --git a/src/multiboot.zig b/src/multiboot.zig index 936c59e..cdb38d1 100644 --- a/src/multiboot.zig +++ b/src/multiboot.zig @@ -124,7 +124,7 @@ pub const MultibootModule = packed struct { }; // Multiboot structure to be read by the bootloader. -const MultibootHeader = packed struct { +pub const MultibootHeader = packed struct { magic: u32, // Must be equal to header magic number. flags: u32, // Feature flags. checksum: u32, // Above fields plus this one must equal 0 mod 2^32. @@ -136,18 +136,3 @@ const MultibootHeader = packed struct { entry_addr: u32 = 0, }; // NOTE: this structure is incomplete. - -// Place the header at the very beginning of the binary. -export const multiboot_header align(4) linksection(".multiboot") = multiboot: { - const MAGIC = u32(0x1BADB002); // multiboot magic - const ALIGN = u32(1 << 0); // Align loaded modules at 4k - const MEMINFO = u32(1 << 1); // Receive a memory map from the bootloader. - const ADDR = u32(1 << 16); // Load specific addr - const FLAGS = ALIGN | MEMINFO; // Combine the flags. - - break :multiboot MultibootHeader{ - .magic = MAGIC, - .flags = FLAGS, - .checksum = ~(MAGIC +% FLAGS) +% 1, - }; -}; diff --git a/src/pci.zig b/src/pci.zig deleted file mode 100644 index 3ce4ae8..0000000 --- a/src/pci.zig +++ /dev/null @@ -1,157 +0,0 @@ -usingnamespace @import("kernel"); -const arch = @import("x86"); -const std = @import("std"); -const virtio = @import("virtio.zig"); - -const PCI_CONFIG_ADDRESS = 0xCF8; -const PCI_CONFIG_DATA = 0xCFC; - -// https://wiki.osdev.org/Pci -pub const PciAddress = packed struct { - offset: u8, - function: u3, - slot: u5, - bus: u8, - reserved: u7, - enable: u1, -}; - -pub const PciDevice = struct { - bus: u8, - slot: u5, - function: u3, - vendor: u16 = undefined, - - pub fn init(bus: u8, slot: u5, function: u3) ?PciDevice { - var dev = PciDevice{ .bus = bus, .slot = slot, .function = function }; - dev.vendor = dev.vendor(); - if (dev.vendor == 0xffff) return null; - return dev; - } - - pub fn address(self: PciDevice, offset: u8) u32 { - var addr = PciAddress{ - .enable = 1, - .reserved = 0, - .bus = self.bus, - .slot = self.slot, - .function = self.function, - .offset = offset, - }; - return @bitCast(u32, addr); - } - - pub fn format(self: PciDevice) void { - print("{}:{}.{}", self.bus, self.slot, self.function); - print(" {x},{x:2}", self.class(), self.subclass()); - print(" 0x{x},0x{x}", self.vendor, self.device()); - if (self.driver()) |d| - print(" {}", d.name); - println(""); - } - - pub fn driver(self: PciDevice) ?Driver { - var i: usize = 0; - while (i < Drivers.len) : (i += 1) { - var drv = Drivers[i]; - if (self.class() != drv.class or self.subclass() != drv.subclass) - continue; - if (drv.vendor) |v| if (self.vendor != v) - continue; - if (drv.subsystem) |ss| if (self.subsystem() != ss) - continue; - return drv; - } - return null; - } - - // 0 1 2 3 - // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | vendor ID | device ID | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | command | status | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | revision ID | prog IF | subclass | class | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // |cache line size| latency timer | header type | bist | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - pub fn vendor(self: PciDevice) u16 { - return self.config_read(u16, 0x0); - } - pub fn device(self: PciDevice) u16 { - return self.config_read(u16, 0x2); - } - pub fn subclass(self: PciDevice) u8 { - return self.config_read(u8, 0xa); - } - pub fn class(self: PciDevice) u8 { - return self.config_read(u8, 0xb); - } - pub fn header_type(self: PciDevice) u8 { - return self.config_read(u8, 0xe); - } - - // only for header_type == 0 - pub fn subsystem(self: PciDevice) u16 { - return self.config_read(u8, 0x2e); - } - - pub inline fn config_read(self: PciDevice, comptime size: type, comptime offset: u8) size { - // ask for access before reading config - arch.outl(PCI_CONFIG_ADDRESS, self.address(offset)); - switch (size) { - // read the correct size - u8 => return arch.inb(PCI_CONFIG_DATA), - u16 => return arch.inw(PCI_CONFIG_DATA), - u32 => return arch.inl(PCI_CONFIG_DATA), - else => @compileError("pci config space only supports reading u8, u16, u32."), - } - } -}; - -const Driver = struct { - name: [*]u8, - class: u8, - subclass: u8, - vendor: ?u16 = null, - subsystem: ?u16 = null, - init: fn (PciDevice) void, -}; - -const name = "virtio-blk"; -pub var Drivers: [1]Driver = [_]Driver{Driver{ .name = &name, .class = 0x1, .subclass = 0x0, .vendor = 0x1af4, .subsystem = 0x2, .init = virtio.init }}; - -// TODO: factor 2 functions when anonymous fn is released -pub fn scan() void { - var slot: u5 = 0; - // 0..31 - while (slot <= std.math.maxInt(u5)) : (slot += 1) { - if (PciDevice.init(0, slot, 0)) |dev| { - var function: u3 = 0; - // 0..7 - while (function <= std.math.maxInt(u3)) : (function += 1) { - if (PciDevice.init(0, slot, function)) |vf| { - if (vf.driver()) |d| d.init(vf); - } - } - } - } -} - -pub fn lspci() void { - var slot: u5 = 0; - println("b:s.f c,s v d drv"); - // 0..31 - while (slot <= std.math.maxInt(u5)) : (slot += 1) { - if (PciDevice.init(0, slot, 0)) |dev| { - var function: u3 = 0; - // 0..7 - while (function <= std.math.maxInt(u3)) : (function += 1) { - if (PciDevice.init(0, slot, function)) |vf| { - vf.format(); - } - } - } - } -} diff --git a/src/ps2.zig b/src/ps2.zig index 2b80d5b..d815698 100644 --- a/src/ps2.zig +++ b/src/ps2.zig @@ -1,5 +1,5 @@ -usingnamespace @import("kernel"); -const x86 = @import("x86"); +usingnamespace @import("index.zig"); +// const x86 = @import("x86"); const PS2_DATA = 0x60; const PS2_STATUS = 0x64; diff --git a/src/vga.zig b/src/vga.zig index c3f4d78..fa2d1c8 100644 --- a/src/vga.zig +++ b/src/vga.zig @@ -1,4 +1,4 @@ -const arch = @import("x86"); +const x86 = @import("arch/x86/index.zig"); const std = @import("std"); // Screen size. @@ -156,10 +156,10 @@ const VGA = struct { // Use the software cursor as the source of truth. // pub fn updateCursor(self: *const VGA) void { - arch.outb(0x3D4, 0x0F); - arch.outb(0x3D5, @truncate(u8, self.cursor)); - arch.outb(0x3D4, 0x0E); - arch.outb(0x3D5, @truncate(u8, self.cursor >> 8)); + x86.outb(0x3D4, 0x0F); + x86.outb(0x3D5, @truncate(u8, self.cursor)); + x86.outb(0x3D4, 0x0E); + x86.outb(0x3D5, @truncate(u8, self.cursor >> 8)); } //// @@ -169,11 +169,11 @@ const VGA = struct { pub fn fetchCursor(self: *VGA) void { var cursor: usize = 0; - arch.outb(0x3D4, 0x0E); - cursor |= usize(arch.inb(0x3D5)) << 8; + x86.outb(0x3D4, 0x0E); + cursor |= usize(x86.inb(0x3D5)) << 8; - arch.outb(0x3D4, 0x0F); - cursor |= arch.inb(0x3D5); + x86.outb(0x3D4, 0x0F); + cursor |= x86.inb(0x3D5); self.cursor = cursor; } diff --git a/src/virtio.zig b/src/virtio.zig deleted file mode 100644 index 8c82989..0000000 --- a/src/virtio.zig +++ /dev/null @@ -1,22 +0,0 @@ -usingnamespace @import("kernel"); - -pub fn init(pci: PciDevice) void { - println("-- virtio-block init --"); - pci.format(); - assert(pci.header_type() == 0x0); // mass storage device - assert(pci.subsystem() == 0x2); // virtio-block - const intr_line = pci.config_read(u8, 0x3c); - const intr_pin = pci.config_read(u8, 0x3d); - const min_grant = pci.config_read(u8, 0x3e); - const max_lat = pci.config_read(u8, 0x3f); - - println("{x} {} {} {}", intr_line, intr_pin, min_grant, max_lat); - println("dev features =0x{x}", pci.config_read(u32, 0x10)); - println("guest features=0x{x}", pci.config_read(u32, 0x14)); - println("queue addr =0x{x}", pci.config_read(u32, 0x18)); - println("queue size =0x{x}", pci.config_read(u16, 0x1c)); - println("queue select =0x{x}", pci.config_read(u16, 0x1e)); - println("queue notify =0x{x}", pci.config_read(u16, 0x20)); - println("device status =0x{x}", pci.config_read(u8, 0x22)); - println("isr status =0x{x}", pci.config_read(u8, 0x23)); -}