From 4c9f4b54d85a8fded8c4ea98a1ea8de2a2f2bd3a Mon Sep 17 00:00:00 2001 From: Jack Halford Date: Sat, 17 Aug 2019 22:37:37 +0200 Subject: [PATCH] refactoring pci --- build.zig | 10 ++-- src/arch/x86/lib/index.zig | 4 +- src/arch/x86/main.zig | 1 - src/arch/x86/paging.zig | 2 - src/console.zig | 12 ++--- src/main.zig | 15 +----- src/pci.zig | 100 +++++++++++++++++++++++-------------- 7 files changed, 77 insertions(+), 67 deletions(-) diff --git a/build.zig b/build.zig index f13c969..4fb3409 100644 --- a/build.zig +++ b/build.zig @@ -4,13 +4,13 @@ const builtin = @import("builtin"); pub fn build(b: *Builder) void { const kernel = b.addExecutable("kernel", "src/arch/x86/main.zig"); kernel.addPackagePath("kernel", "src/index.zig"); - kernel.addPackagePath("arch", "src/arch/x86/lib/index.zig"); + // kernel.addPackagePath("arch", "src/arch/x86/lib/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"); + // 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"); kernel.setBuildMode(b.standardReleaseOptions()); kernel.setTarget(builtin.Arch.i386, builtin.Os.freestanding, builtin.Abi.none); diff --git a/src/arch/x86/lib/index.zig b/src/arch/x86/lib/index.zig index 808dc73..14b9bcb 100644 --- a/src/arch/x86/lib/index.zig +++ b/src/arch/x86/lib/index.zig @@ -1,2 +1,2 @@ -use @import("io.zig"); -use @import("instructions.zig"); +usingnamespace @import("io.zig"); +usingnamespace @import("instructions.zig"); diff --git a/src/arch/x86/main.zig b/src/arch/x86/main.zig index 31ff80c..6f02fd3 100644 --- a/src/arch/x86/main.zig +++ b/src/arch/x86/main.zig @@ -10,7 +10,6 @@ const gdt = @import("gdt.zig"); const x86 = @import("lib/index.zig"); /// x86 specific intialization -/// first entry point (see linker.ld) pub fn x86_main(info: *const MultibootInfo) void { gdt.initialize(); idt.initialize(); diff --git a/src/arch/x86/paging.zig b/src/arch/x86/paging.zig index 1c89696..4d1307d 100644 --- a/src/arch/x86/paging.zig +++ b/src/arch/x86/paging.zig @@ -96,7 +96,5 @@ pub fn initialize() void { interrupt.register(14, pageFault); setupPaging(@ptrToInt(&pageDirectory[0])); - - addrspace(); // const addr = mapper.translate(0xfffff000); } diff --git a/src/console.zig b/src/console.zig index 21d24aa..3af594a 100644 --- a/src/console.zig +++ b/src/console.zig @@ -1,16 +1,16 @@ const interrupt = @import("arch/x86/interrupt.zig"); -const x86 = @import("arch/x86/lib/index.zig"); +const paging = @import("arch/x86/paging.zig"); const ps2 = @import("ps2.zig"); -const pci = @import("pci.zig"); -const std = @import("std"); -const mem = std.mem; +// const pci = @import("pci.zig"); +const mem = @import("std").mem; usingnamespace @import("vga.zig"); var command: [10]u8 = undefined; var command_len: usize = 0; fn execute(com: []u8) void { - if (mem.eql(u8, com, "lspci")) pci.lspci(); + // if (mem.eql(u8, com, "lspci")) pci.lspci(); + if (mem.eql(u8, com, "paging")) paging.addrspace(); } pub fn keypress(char: u8) void { @@ -41,5 +41,5 @@ pub fn keypress(char: u8) void { pub fn initialize() void { interrupt.registerIRQ(1, ps2.keyboard_handler); - vga.writeString("> "); + print("> "); } diff --git a/src/main.zig b/src/main.zig index 61f9b16..f2c8116 100644 --- a/src/main.zig +++ b/src/main.zig @@ -10,27 +10,14 @@ const assert = @import("std").debug.assert; export fn kmain(magic: u32, info: *const MultibootInfo) noreturn { clear(); assert(magic == MULTIBOOT_BOOTLOADER_MAGIC); - println("--- x86 initialization ---"); x86.x86_main(info); - // pagefault_test(0xfeffc000); - println("--- core initialization ---"); + pci.scan(); console.initialize(); - while (true) { asm volatile ("hlt"); } } - -fn pagefault_test(addr: u32) void { - const ptr = @intToPtr(*volatile u8, addr); - var a: u8 = ptr.*; - printf("a = {}\n", a); - - ptr.* += 1; - - printf("a = {}\n", ptr.*); -} diff --git a/src/pci.zig b/src/pci.zig index e77c689..9ba38b6 100644 --- a/src/pci.zig +++ b/src/pci.zig @@ -3,6 +3,7 @@ const arch = @import("arch/x86/lib/index.zig"); const PCI_CONFIG_ADDRESS = 0xCF8; const PCI_CONFIG_DATA = 0xCFC; usingnamespace @import("vga.zig"); +const virtio = @import("virtio.zig"); pub const PciAddress = packed struct { offset: u8, @@ -17,12 +18,7 @@ pub const PciDevice = struct { bus: u8, slot: u5, function: u3, - device: u16 = undefined, vendor: u16 = undefined, - class: u8 = undefined, - subclass: u8 = undefined, - header_type: u8 = undefined, - driver: ?Driver = null, pub fn init(bus: u8, slot: u5, function: u3) ?PciDevice { var dev = PciDevice{ @@ -30,15 +26,9 @@ pub const PciDevice = struct { .slot = slot, .function = function, }; - dev.vendor = dev.pci_config_read_word(0); - if (dev.vendor == 0xffff) - return null; - dev.device = dev.pci_config_read_word(2); - dev.subclass = dev.pci_config_read_byte(10); - dev.class = dev.pci_config_read_byte(11); - dev.header_type = dev.pci_config_read_byte(14); - dev.driver = dev.get_driver(); - return (dev); + dev.vendor = dev.config_read_word(0); + if (dev.vendor == 0xffff) return null; + return dev; } pub fn address(self: PciDevice, offset: u8) u32 { @@ -50,46 +40,66 @@ pub const PciDevice = struct { .function = self.function, .offset = offset, }; - return (@bitCast(u32, addr)); + return @bitCast(u32, addr); } pub fn format(self: PciDevice) void { print("{}:{}.{}", self.bus, self.slot, self.function); - print(" {x},{x}: {x} {x}", self.class, self.subclass, self.vendor, self.device); - if (self.driver) |d| + print(" {x},{x:2}(0x{x:4}): 0x{x} 0x{x}", self.class(), self.subclass(), self.subsystem(), 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() == drv.subsystem.?) + continue; + return drv; + } + return null; + } + + pub fn device(self: PciDevice) u16 { + return self.config_read_word(2); + } + pub fn subclass(self: PciDevice) u16 { + return self.config_read_byte(10); + } + pub fn class(self: PciDevice) u16 { + return self.config_read_byte(11); + } + pub fn header_type(self: PciDevice) u16 { + return self.config_read_byte(14); + } + pub fn subsystem(self: PciDevice) u16 { + return self.config_read_word(0x2e); + } + pub fn access(self: PciDevice, offset: u8) void { arch.outl(PCI_CONFIG_ADDRESS, self.address(offset)); } - pub fn pci_config_read_byte(self: PciDevice, offset: u8) u8 { + pub fn config_read_byte(self: PciDevice, offset: u8) u8 { self.access(offset); return (arch.inb(PCI_CONFIG_DATA)); } - pub fn pci_config_read_word(self: PciDevice, offset: u8) u16 { + pub fn config_read_word(self: PciDevice, offset: u8) u16 { self.access(offset); return (arch.inw(PCI_CONFIG_DATA)); } - pub fn pci_config_read_long(self: PciDevice, offset: u8) u32 { + pub fn config_read_long(self: PciDevice, offset: u8) u32 { self.access(offset); return (arch.inl(PCI_CONFIG_DATA)); } - - pub fn get_driver(self: PciDevice) ?Driver { - var i: usize = 0; - while (i < Drivers.len) : (i += 1) { - var driver = Drivers[i]; - if (self.class == driver.class and self.subclass == driver.subclass and (driver.vendor == null or self.vendor == driver.vendor.?)) { - return driver; - } - } - return null; - } }; const Driver = struct { @@ -97,22 +107,38 @@ const Driver = struct { 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 }}; +pub var Drivers: [1]Driver = [_]Driver{Driver{ .name = &name, .class = 0x1, .subclass = 0x0, .vendor = 0x1af4, .subsystem = 0x2, .init = virtio.init }}; + +pub fn scan() void { + var slot: u5 = 0; + while (slot < 31) : (slot += 1) { + if (PciDevice.init(0, slot, 0)) |device| { + var function: u3 = 0; + while (function < 8) : (function += 1) { + if (PciDevice.init(0, slot, function)) |vf| { + if (vf.driver()) |d| d.init(vf); + } + } + } + } +} pub fn lspci() void { var slot: u5 = 0; - while (true) { + println("b:s.f c,s (ss) v d drv"); + while (slot < 31) : (slot += 1) { if (PciDevice.init(0, slot, 0)) |device| { var function: u3 = 0; - while (true) { - if (PciDevice.init(0, slot, function)) |vf| + while (function < 8) : (function += 1) { + if (PciDevice.init(0, slot, function)) |vf| { vf.format(); - if (function == 7) break else function += 1; + } } } - if (slot == 31) break else slot += 1; } }