refactoring pci
This commit is contained in:
parent
07089c2ea1
commit
4c9f4b54d8
7 changed files with 77 additions and 67 deletions
10
build.zig
10
build.zig
|
|
@ -4,13 +4,13 @@ const builtin = @import("builtin");
|
||||||
pub fn build(b: *Builder) void {
|
pub fn build(b: *Builder) void {
|
||||||
const kernel = b.addExecutable("kernel", "src/arch/x86/main.zig");
|
const kernel = b.addExecutable("kernel", "src/arch/x86/main.zig");
|
||||||
kernel.addPackagePath("kernel", "src/index.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.setOutputDir("build");
|
||||||
|
|
||||||
kernel.addAssemblyFile("src/arch/x86/_start.s");
|
// kernel.addAssemblyFile("src/arch/x86/_start.s");
|
||||||
kernel.addAssemblyFile("src/arch/x86/gdt.s");
|
// kernel.addAssemblyFile("src/arch/x86/gdt.s");
|
||||||
kernel.addAssemblyFile("src/arch/x86/isr.s");
|
// kernel.addAssemblyFile("src/arch/x86/isr.s");
|
||||||
kernel.addAssemblyFile("src/arch/x86/paging.s");
|
// kernel.addAssemblyFile("src/arch/x86/paging.s");
|
||||||
|
|
||||||
kernel.setBuildMode(b.standardReleaseOptions());
|
kernel.setBuildMode(b.standardReleaseOptions());
|
||||||
kernel.setTarget(builtin.Arch.i386, builtin.Os.freestanding, builtin.Abi.none);
|
kernel.setTarget(builtin.Arch.i386, builtin.Os.freestanding, builtin.Abi.none);
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
use @import("io.zig");
|
usingnamespace @import("io.zig");
|
||||||
use @import("instructions.zig");
|
usingnamespace @import("instructions.zig");
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ const gdt = @import("gdt.zig");
|
||||||
const x86 = @import("lib/index.zig");
|
const x86 = @import("lib/index.zig");
|
||||||
|
|
||||||
/// x86 specific intialization
|
/// x86 specific intialization
|
||||||
/// first entry point (see linker.ld)
|
|
||||||
pub fn x86_main(info: *const MultibootInfo) void {
|
pub fn x86_main(info: *const MultibootInfo) void {
|
||||||
gdt.initialize();
|
gdt.initialize();
|
||||||
idt.initialize();
|
idt.initialize();
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,5 @@ pub fn initialize() void {
|
||||||
|
|
||||||
interrupt.register(14, pageFault);
|
interrupt.register(14, pageFault);
|
||||||
setupPaging(@ptrToInt(&pageDirectory[0]));
|
setupPaging(@ptrToInt(&pageDirectory[0]));
|
||||||
|
|
||||||
addrspace();
|
|
||||||
// const addr = mapper.translate(0xfffff000);
|
// const addr = mapper.translate(0xfffff000);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
const interrupt = @import("arch/x86/interrupt.zig");
|
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 ps2 = @import("ps2.zig");
|
||||||
const pci = @import("pci.zig");
|
// const pci = @import("pci.zig");
|
||||||
const std = @import("std");
|
const mem = @import("std").mem;
|
||||||
const mem = std.mem;
|
|
||||||
usingnamespace @import("vga.zig");
|
usingnamespace @import("vga.zig");
|
||||||
|
|
||||||
var command: [10]u8 = undefined;
|
var command: [10]u8 = undefined;
|
||||||
var command_len: usize = 0;
|
var command_len: usize = 0;
|
||||||
|
|
||||||
fn execute(com: []u8) void {
|
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 {
|
pub fn keypress(char: u8) void {
|
||||||
|
|
@ -41,5 +41,5 @@ pub fn keypress(char: u8) void {
|
||||||
|
|
||||||
pub fn initialize() void {
|
pub fn initialize() void {
|
||||||
interrupt.registerIRQ(1, ps2.keyboard_handler);
|
interrupt.registerIRQ(1, ps2.keyboard_handler);
|
||||||
vga.writeString("> ");
|
print("> ");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
src/main.zig
15
src/main.zig
|
|
@ -10,27 +10,14 @@ const assert = @import("std").debug.assert;
|
||||||
export fn kmain(magic: u32, info: *const MultibootInfo) noreturn {
|
export fn kmain(magic: u32, info: *const MultibootInfo) noreturn {
|
||||||
clear();
|
clear();
|
||||||
assert(magic == MULTIBOOT_BOOTLOADER_MAGIC);
|
assert(magic == MULTIBOOT_BOOTLOADER_MAGIC);
|
||||||
|
|
||||||
println("--- x86 initialization ---");
|
println("--- x86 initialization ---");
|
||||||
|
|
||||||
x86.x86_main(info);
|
x86.x86_main(info);
|
||||||
|
|
||||||
// pagefault_test(0xfeffc000);
|
|
||||||
|
|
||||||
println("--- core initialization ---");
|
println("--- core initialization ---");
|
||||||
|
pci.scan();
|
||||||
console.initialize();
|
console.initialize();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
asm volatile ("hlt");
|
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.*);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
100
src/pci.zig
100
src/pci.zig
|
|
@ -3,6 +3,7 @@ const arch = @import("arch/x86/lib/index.zig");
|
||||||
const PCI_CONFIG_ADDRESS = 0xCF8;
|
const PCI_CONFIG_ADDRESS = 0xCF8;
|
||||||
const PCI_CONFIG_DATA = 0xCFC;
|
const PCI_CONFIG_DATA = 0xCFC;
|
||||||
usingnamespace @import("vga.zig");
|
usingnamespace @import("vga.zig");
|
||||||
|
const virtio = @import("virtio.zig");
|
||||||
|
|
||||||
pub const PciAddress = packed struct {
|
pub const PciAddress = packed struct {
|
||||||
offset: u8,
|
offset: u8,
|
||||||
|
|
@ -17,12 +18,7 @@ pub const PciDevice = struct {
|
||||||
bus: u8,
|
bus: u8,
|
||||||
slot: u5,
|
slot: u5,
|
||||||
function: u3,
|
function: u3,
|
||||||
device: u16 = undefined,
|
|
||||||
vendor: 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 {
|
pub fn init(bus: u8, slot: u5, function: u3) ?PciDevice {
|
||||||
var dev = PciDevice{
|
var dev = PciDevice{
|
||||||
|
|
@ -30,15 +26,9 @@ pub const PciDevice = struct {
|
||||||
.slot = slot,
|
.slot = slot,
|
||||||
.function = function,
|
.function = function,
|
||||||
};
|
};
|
||||||
dev.vendor = dev.pci_config_read_word(0);
|
dev.vendor = dev.config_read_word(0);
|
||||||
if (dev.vendor == 0xffff)
|
if (dev.vendor == 0xffff) return null;
|
||||||
return null;
|
return dev;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn address(self: PciDevice, offset: u8) u32 {
|
pub fn address(self: PciDevice, offset: u8) u32 {
|
||||||
|
|
@ -50,46 +40,66 @@ pub const PciDevice = struct {
|
||||||
.function = self.function,
|
.function = self.function,
|
||||||
.offset = offset,
|
.offset = offset,
|
||||||
};
|
};
|
||||||
return (@bitCast(u32, addr));
|
return @bitCast(u32, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format(self: PciDevice) void {
|
pub fn format(self: PciDevice) void {
|
||||||
print("{}:{}.{}", self.bus, self.slot, self.function);
|
print("{}:{}.{}", self.bus, self.slot, self.function);
|
||||||
print(" {x},{x}: {x} {x}", self.class, self.subclass, self.vendor, self.device);
|
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|
|
if (self.driver()) |d|
|
||||||
print(" {}", d.name);
|
print(" {}", d.name);
|
||||||
println("");
|
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 {
|
pub fn access(self: PciDevice, offset: u8) void {
|
||||||
arch.outl(PCI_CONFIG_ADDRESS, self.address(offset));
|
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);
|
self.access(offset);
|
||||||
return (arch.inb(PCI_CONFIG_DATA));
|
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);
|
self.access(offset);
|
||||||
return (arch.inw(PCI_CONFIG_DATA));
|
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);
|
self.access(offset);
|
||||||
return (arch.inl(PCI_CONFIG_DATA));
|
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 {
|
const Driver = struct {
|
||||||
|
|
@ -97,22 +107,38 @@ const Driver = struct {
|
||||||
class: u8,
|
class: u8,
|
||||||
subclass: u8,
|
subclass: u8,
|
||||||
vendor: ?u16 = null,
|
vendor: ?u16 = null,
|
||||||
|
subsystem: ?u16 = null,
|
||||||
|
init: fn (PciDevice) void,
|
||||||
};
|
};
|
||||||
|
|
||||||
const name = "virtio-blk";
|
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 {
|
pub fn lspci() void {
|
||||||
var slot: u5 = 0;
|
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| {
|
if (PciDevice.init(0, slot, 0)) |device| {
|
||||||
var function: u3 = 0;
|
var function: u3 = 0;
|
||||||
while (true) {
|
while (function < 8) : (function += 1) {
|
||||||
if (PciDevice.init(0, slot, function)) |vf|
|
if (PciDevice.init(0, slot, function)) |vf| {
|
||||||
vf.format();
|
vf.format();
|
||||||
if (function == 7) break else function += 1;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (slot == 31) break else slot += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue