changes imports again...
This commit is contained in:
parent
bdc3b2939b
commit
bd12f0495f
8 changed files with 223 additions and 18 deletions
|
|
@ -7,6 +7,7 @@ pub fn build(b: *Builder) void {
|
||||||
kernel.addPackagePath("x86", "src/arch/x86/index.zig");
|
kernel.addPackagePath("x86", "src/arch/x86/index.zig");
|
||||||
kernel.setOutputDir("build");
|
kernel.setOutputDir("build");
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
|
||||||
2
qemu.sh
2
qemu.sh
|
|
@ -12,8 +12,8 @@ start() {
|
||||||
-m 1337M \
|
-m 1337M \
|
||||||
-curses \
|
-curses \
|
||||||
-append "Hello" \
|
-append "Hello" \
|
||||||
|
-drive file=disk.img,if=virtio\
|
||||||
-kernel ${KERNEL}
|
-kernel ${KERNEL}
|
||||||
# -drive file=disk.img,if=virtio\
|
|
||||||
# -no-reboot \
|
# -no-reboot \
|
||||||
# -device virtio-net,netdev=network0 -netdev tap,id=network0,ifname=tap0,script=no,downscript=no \
|
# -device virtio-net,netdev=network0 -netdev tap,id=network0,ifname=tap0,script=no,downscript=no \
|
||||||
# build/kernel.iso
|
# build/kernel.iso
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,14 @@ pub inline fn inb(port: u16) u8 {
|
||||||
: [port] "N{dx}" (port)
|
: [port] "N{dx}" (port)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn inw(port: u16) u16 {
|
pub inline fn inw(port: u16) u16 {
|
||||||
return asm volatile ("inw %[port], %[result]"
|
return asm volatile ("inw %[port], %[result]"
|
||||||
: [result] "={ax}" (-> u16)
|
: [result] "={ax}" (-> u16)
|
||||||
: [port] "N{dx}" (port)
|
: [port] "N{dx}" (port)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn inl(port: u16) u32 {
|
pub inline fn inl(port: u16) u32 {
|
||||||
return asm volatile ("inl %[port], %[result]"
|
return asm volatile ("inl %[port], %[result]"
|
||||||
: [result] "={eax}" (-> u32)
|
: [result] "={eax}" (-> u32)
|
||||||
|
|
@ -24,6 +26,7 @@ pub inline fn outb(port: u16, value: u8) void {
|
||||||
[port] "N{dx}" (port)
|
[port] "N{dx}" (port)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn outw(port: u16, value: u16) void {
|
pub inline fn outw(port: u16, value: u16) void {
|
||||||
asm volatile ("outw %[value], %[port]"
|
asm volatile ("outw %[value], %[port]"
|
||||||
:
|
:
|
||||||
|
|
@ -31,6 +34,7 @@ pub inline fn outw(port: u16, value: u16) void {
|
||||||
[port] "N{dx}" (port)
|
[port] "N{dx}" (port)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn outl(port: u16, value: u32) void {
|
pub inline fn outl(port: u16, value: u32) void {
|
||||||
asm volatile ("outl %[value], %[port]"
|
asm volatile ("outl %[value], %[port]"
|
||||||
:
|
:
|
||||||
|
|
|
||||||
16
src/arch/x86/start.s
Normal file
16
src/arch/x86/start.s
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
.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
|
||||||
4
src/base.zig
Normal file
4
src/base.zig
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
pub const assert = @import("std").debug.assert;
|
||||||
|
pub const std = @import("std");
|
||||||
|
|
||||||
|
pub usingnamespace @import("vga.zig");
|
||||||
37
src/main.zig
37
src/main.zig
|
|
@ -16,28 +16,31 @@ export const multiboot_header align(4) linksection(".multiboot") = multiboot: {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export var stack_bytes: [16 * 1024]u8 align(16) linksection(".bss") = undefined;
|
// export var stack_bytes: [16 * 1024]u8 align(16) linksection(".bss") = undefined;
|
||||||
const stack_bytes_slice = stack_bytes[0..];
|
// const stack_bytes_slice = stack_bytes[0..];
|
||||||
|
|
||||||
// linker.ld entrypoint
|
// linker.ld entrypoint
|
||||||
export nakedcc fn __start() noreturn {
|
// export nakedcc fn __start() noreturn {
|
||||||
// eax -> multiboot magic
|
// // eax -> multiboot magic
|
||||||
const magic: u32 = asm volatile (""
|
// // ebx -> multiboot info
|
||||||
: [result] "={eax}" (-> u32)
|
// const magic = asm volatile ("mov %[ret], %eax"
|
||||||
);
|
// : [ret] "=" (-> u32)
|
||||||
// ebx -> multiboot info
|
// );
|
||||||
const info: u32 = asm volatile (""
|
// const info = asm volatile (""
|
||||||
: [result] "={ebx}" (-> u32)
|
// : [ret] "=" (-> u32)
|
||||||
);
|
// );
|
||||||
@newStackCall(stack_bytes_slice, kmain, magic, @intToPtr(*const multiboot.MultibootInfo, info));
|
// clear();
|
||||||
// @newStackCall(stack_bytes_slice, kmain);
|
// println("--- {x} ---", magic);
|
||||||
}
|
// println("--- {x} ---", info);
|
||||||
|
// // @newStackCall(stack_bytes_slice, kmain, magic, @intToPtr(*const multiboot.MultibootInfo, info));
|
||||||
|
// @newStackCall(stack_bytes_slice, kmain, magic);
|
||||||
|
// // @newStackCall(stack_bytes_slice, kmain);
|
||||||
|
// }
|
||||||
|
|
||||||
// arch independant initialization
|
// arch independant initialization
|
||||||
fn kmain(magic: u32, info: *const multiboot.MultibootInfo) noreturn {
|
export fn kmain(magic: u32, info: *const multiboot.MultibootInfo) noreturn {
|
||||||
|
assert(magic == multiboot.MULTIBOOT_BOOTLOADER_MAGIC);
|
||||||
clear();
|
clear();
|
||||||
println("--- {x} ---", magic);
|
|
||||||
// assert(magic == multiboot.MULTIBOOT_BOOTLOADER_MAGIC);
|
|
||||||
println("--- x86 initialization ---");
|
println("--- x86 initialization ---");
|
||||||
x86.x86_main(info);
|
x86.x86_main(info);
|
||||||
println("--- core initialization ---");
|
println("--- core initialization ---");
|
||||||
|
|
|
||||||
154
src/pci/pci.zig
Normal file
154
src/pci/pci.zig
Normal file
|
|
@ -0,0 +1,154 @@
|
||||||
|
pub usingnamespace @import("../index.zig");
|
||||||
|
pub 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_id();
|
||||||
|
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_id(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
|
||||||
|
x86.outl(PCI_CONFIG_ADDRESS, self.address(offset));
|
||||||
|
switch (size) {
|
||||||
|
// read the correct size
|
||||||
|
u8 => return x86.inb(PCI_CONFIG_DATA),
|
||||||
|
u16 => return x86.inw(PCI_CONFIG_DATA),
|
||||||
|
u32 => return x86.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 < 31) : (slot += 1) {
|
||||||
|
if (PciDevice.init(0, slot, 0)) |dev| {
|
||||||
|
var function: u3 = 0;
|
||||||
|
// 0..7
|
||||||
|
while (function < 7) : (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");
|
||||||
|
while (slot < 31) : (slot += 1) {
|
||||||
|
if (PciDevice.init(0, slot, 0)) |dev| {
|
||||||
|
var function: u3 = 0;
|
||||||
|
// 0..7
|
||||||
|
while (function < 7) : (function += 1) {
|
||||||
|
if (PciDevice.init(0, slot, function)) |vf| {
|
||||||
|
vf.format();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/pci/virtio.zig
Normal file
23
src/pci/virtio.zig
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
usingnamespace @import("pci.zig");
|
||||||
|
|
||||||
|
pub fn init(dev: PciDevice) void {
|
||||||
|
println("-- virtio-block init --");
|
||||||
|
dev.format();
|
||||||
|
assert(dev.header_type() == 0x0); // mass storage device
|
||||||
|
assert(dev.subsystem() == 0x2); // virtio-block
|
||||||
|
|
||||||
|
const intr_line = dev.config_read(u8, 0x3c);
|
||||||
|
const intr_pin = dev.config_read(u8, 0x3d);
|
||||||
|
const min_grant = dev.config_read(u8, 0x3e);
|
||||||
|
const max_lat = dev.config_read(u8, 0x3f);
|
||||||
|
println("{x} {} {} {}", intr_line, intr_pin, min_grant, max_lat);
|
||||||
|
|
||||||
|
println("dev features =0x{x}", dev.config_read(u32, 0x10));
|
||||||
|
println("guest features=0x{x}", dev.config_read(u32, 0x14));
|
||||||
|
println("queue addr =0x{x}", dev.config_read(u32, 0x18));
|
||||||
|
println("queue size =0x{x}", dev.config_read(u16, 0x1c));
|
||||||
|
println("queue select =0x{x}", dev.config_read(u16, 0x1e));
|
||||||
|
println("queue notify =0x{x}", dev.config_read(u16, 0x20));
|
||||||
|
println("device status =0x{x}", dev.config_read(u8, 0x22));
|
||||||
|
println("isr status =0x{x}", dev.config_read(u8, 0x23));
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue