zig: 0.5.0 -> 0.5.0+e6a812c82

This commit is contained in:
Jack Halford 2020-02-02 18:24:48 +01:00
parent 8380a657ac
commit 22f05324fa
18 changed files with 101 additions and 104 deletions

View file

@ -7,7 +7,7 @@ KERNEL=build/kernel
start() {
touch disk.img
sudo pkill -9 qemu-system-i386
# sudo pkill -9 qemu-system-i386
sudo qemu-system-i386 \
-gdb tcp::${QEMU_GDB_PORT} \
-monitor unix:${QEMU_SOCKET},server,nowait \

View file

@ -83,7 +83,7 @@ var gdt align(4) = [_]GDTEntry{
// GDT descriptor register pointing at the GDT.
var gdtr = GDTRegister{
.limit = u16(@sizeOf(@typeOf(gdt))),
.limit = @as(u16, @sizeOf(@TypeOf(gdt))),
.base = &gdt[0],
};

View file

@ -12,7 +12,7 @@ var idt_table: [256]IDTEntry = undefined;
// IDT descriptor register pointing at the IDT.
const idtr = IDTRegister{
.limit = u16(@sizeOf(@typeOf(idt_table))),
.limit = @as(u16, @sizeOf(@TypeOf(idt_table))),
.base = &idt_table,
};
@ -68,21 +68,21 @@ pub fn initialize() void {
}
fn general_protection_fault() void {
kernel.println("general protection fault");
kernel.println("general protection fault", .{});
hang();
}
fn debug_trap() void {
kernel.println("debug fault/trap");
kernel.println("dr7: 0b{b}", dr7());
kernel.println("debug fault/trap", .{});
kernel.println("dr7: 0b{b}", .{dr7()});
}
fn page_fault() void {
const vaddr = cr2();
kernel.println("cr2: 0x{x}", vaddr);
kernel.println("phy: 0x{x}", paging.translate(vaddr));
kernel.println("pde: 0x{x} ({})", paging.pde(vaddr), vaddr >> 22);
kernel.println("pte: 0x{x} ({})", paging.pte(vaddr), vaddr >> 12);
kernel.println("cr2: 0x{x}", .{vaddr});
kernel.println("phy: 0x{x}", .{paging.translate(vaddr)});
kernel.println("pde: 0x{x} ({})", .{ paging.pde(vaddr), vaddr >> 22 });
kernel.println("pte: 0x{x} ({})", .{ paging.pte(vaddr), vaddr >> 12 });
// paging.format();
hang();
}

View file

@ -35,12 +35,9 @@ var handlers = [_]fn () void{unhandled} ** 48;
fn unhandled() noreturn {
const n = isr.context.interrupt_n;
kernel.print("unhandled interrupt number {d}", n);
if (n < IRQ_0) {
kernel.println(" (exception)");
} else {
kernel.println(" (IRQ number {d})", n - IRQ_0);
}
kernel.print("unhandled interrupt number {d}", .{n});
if (n < IRQ_0) kernel.println(" (exception)", .{});
if (n >= IRQ_0) kernel.println(" (IRQ number {d})", .{n - IRQ_0});
hang();
}
@ -57,10 +54,11 @@ export fn interruptDispatch() void {
switch (n) {
// Exceptions.
EXCEPTION_0...EXCEPTION_31 => {
kernel.println("");
kernel.println("num: {}", isr.context.interrupt_n);
kernel.println("err: {}", isr.context.error_code);
kernel.println("ip: 0x{x}", isr.context.eip);
kernel.println("", .{});
kernel.println("num: {}", .{n});
kernel.println("err: {}", .{@truncate(u8, isr.context.error_code)});
kernel.println("ip: 0x{x}", .{@truncate(u16, isr.context.eip)});
kernel.println("ip: 0x{x}", .{@truncate(u16, isr.context.eip >> 16)});
return handlers[n]();
},
@ -171,16 +169,18 @@ pub fn remapPIC() void {
picwait();
}
pub fn maskIRQ(irq: u8, mask: bool) void {
pub fn maskIRQ(irq: u8, comptime 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 port = @as(u16, if (irq < 8) PIC1_DATA else PIC2_DATA);
const old = inb(port); // Retrieve the current mask.
// Mask or unmask the interrupt.
const shift = @intCast(u3, irq % 8);
if (mask) outb(port, old | (u8(1) << shift));
if (!mask) outb(port, old & ~(u8(1) << shift));
const shift = @truncate(u3, irq % 8);
// const shift = @truncate(u3, if (irq < 8) irq else irq - 8);
const bit = @as(u8, 1) << shift;
if (mask) outb(port, old | bit);
if (!mask) outb(port, old & ~bit);
const new = inb(port); // Retrieve the current mask.
}

View file

@ -66,7 +66,7 @@ pub const Context = packed struct {
ss: u32,
pub inline fn setReturnValue(self: *volatile Context, value: var) void {
self.registers.eax = if (@typeOf(value) == bool) @boolToInt(value) else @intCast(u32, value);
self.registers.eax = if (@TypeOf(value) == bool) @boolToInt(value) else @intCast(u32, value);
}
};

View file

@ -1,4 +1,3 @@
// usingnamespace @import("kernel");
usingnamespace @import("index.zig");
/// x86 specific intialization
@ -7,6 +6,5 @@ pub fn x86_main(info: *const kernel.multiboot.MultibootInfo) void {
idt.initialize();
pmem.initialize(info);
paging.initialize();
// enable interrupts
sti();
}

View file

@ -36,7 +36,7 @@ pub fn unmap(virt: usize) void {
if (translate(virt)) |phys| {
pmem.free(phys);
} else {
kernel.println("can't unmap 0x{x} because it is not mapped.", virt);
kernel.println("can't unmap 0x{x} because it is not mapped.", .{virt});
}
}
@ -67,12 +67,12 @@ pub fn format() void {
i = 0;
while (i < 1024) : (i += 1) {
if (PD[i] == 0) continue;
kernel.println("p2[{}] -> 0x{x}", i, PD[i]);
kernel.println("p2[{}] -> 0x{x}", .{ i, PD[i] });
if (PD[i] & HUGE != 0) continue;
var j: usize = 0;
while (j < 1024) : (j += 1) {
var entry: PageEntry = PT[i * 1024 + j];
if (entry != 0) kernel.println("p2[{}]p1[{}] -> 0x{x}", i, j, entry);
if (entry != 0) kernel.println("p2[{}]p1[{}] -> 0x{x}", .{ i, j, entry });
}
}
}

View file

@ -28,7 +28,7 @@ pub inline fn available_MiB() usize {
//
pub fn allocate() !usize {
if (available() == 0) {
kernel.println("out of memory");
kernel.println("out of memory", .{});
return error.OutOfMemory;
}
stack_index -= 1;
@ -82,12 +82,15 @@ pub fn initialize(info: *const kernel.multiboot.MultibootInfo) void {
free(start);
// Go to the next entry in the memory map.
map += entry.size + @sizeOf(@typeOf(entry.size));
map += entry.size + @sizeOf(@TypeOf(entry.size));
}
kernel.println("available memory: {d} MiB ", available() / 1024 / 1024);
const a = available();
kernel.println("available memory: {} MiB ", .{a});
// kernel.println("available memory: {d} MiB ", .{available() / 1024 / 1024});
hang();
}
pub fn format() void {
kernel.println("physframes left: {d} ({d} MiB)", stack_index, available_MiB());
kernel.println("physframes left: {d} ({d} MiB)", .{ stack_index, available_MiB() });
}

View file

@ -31,17 +31,17 @@ const commands = [_]Command{
fn execute(input: []u8) void {
for (commands) |c| if (std.mem.eql(u8, input, c.name)) return c.f();
println("{}: command not found, list of available commands:", input);
for (commands) |c| println("{}", c.name);
println("{}: command not found, list of available commands:", .{input});
for (commands) |c| println("{}", .{c.name});
}
pub fn keypress(char: u8) void {
// this is a custom "readline" capped at 10 characters
switch (char) {
'\n' => {
print("\n");
print("\n", .{});
if (command_len > 0) execute(command[0..command_len]);
print("> ");
print("> ", .{});
command_len = 0;
},
'\x00' => return,
@ -70,7 +70,7 @@ pub fn loop() void {
input_ring.init() catch unreachable;
input_ring.task = task.current_task;
ps2.keyboard_callback = keyboard_callback;
print("> ");
print("> ", .{});
while (true) {
while (input_ring.read()) |c| keypress(c);
task.block(.IOWait);

View file

@ -30,14 +30,14 @@ const ATA_CMD_IDENTIFY_PACKET = 0xA1;
const ATA_CMD_IDENTIFY = 0xEC;
// Status:
const ATA_SR_BSY = 0x80; // Busy
const ATA_SR_BUSY = 0x80;
const ATA_SR_DRDY = 0x40; // Drive ready
const ATA_SR_DF = 0x20; // Drive write fault
const ATA_SR_DSC = 0x10; // Drive seek complete
const ATA_SR_DRQ = 0x08; // Data request ready
const ATA_SR_CORR = 0x04; // Corrected data
const ATA_SR_IDX = 0x02; // Index
const ATA_SR_ERR = 0x01; // Error
const ATA_SR_IDX = 0x02;
const ATA_SR_ERR = 0x01;
// Registers:
const ATA_REG_DATA = 0x00;
@ -116,7 +116,7 @@ const IDEDevice = struct {
err = 1;
break;
} // If Err, Device is not ATA.
if ((status & ATA_SR_BSY == 0) and (status & ATA_SR_DRQ != 0)) break; // Everything is right.
if ((status & ATA_SR_BUSY == 0) and (status & ATA_SR_DRQ != 0)) break; // Everything is right.
}
// (IV) Probe for ATAPI Devices:)
@ -163,7 +163,7 @@ const IDEDevice = struct {
inline fn poll(self: IDEDevice) void {
for ([_]u8{ 0, 1, 2, 3 }) |_| _ = self.read(ATA_REG_ALTSTATUS); // wait 100ns per call
while (self.read(ATA_REG_STATUS) & ATA_SR_BSY != 0) {} // Wait for BSY to be zero.
while (self.read(ATA_REG_STATUS) & ATA_SR_BUSY != 0) {} // Wait for BSY to be zero.
}
inline fn poll_check(self: IDEDevice) !void {
// (I) Delay 400 nanosecond for BSY to be set:
@ -230,12 +230,11 @@ const IDEDevice = struct {
}
pub fn format(self: IDEDevice) void {
kernel.println(
"[ide] {} drive ({}MB) - {}",
if (self.idetype == 0) "ATA" else "ATAPI",
kernel.println("[ide] {} drive ({}MB) - {}", .{
if (self.idetype == 0) "ATA " else "ATAPI",
self.size * 512 / 1024 / 1024,
self.model,
);
});
}
fn ata_access(self: *IDEDevice, direction: u8, lba: u64, numsects: u8, selector: u16, buf: usize) !void {
@ -279,7 +278,7 @@ const IDEDevice = struct {
}
// (III) Wait if the drive is busy;
while (self.read(ATA_REG_STATUS) & ATA_SR_BSY != 0) {} // Wait if busy.)
while (self.read(ATA_REG_STATUS) & ATA_SR_BUSY != 0) {} // Wait if busy.)
// (IV) Select Drive from the controller;
if (lba_mode == 0) self.write(ATA_REG_HDDEVSEL, 0xA0 | (self.drive << 4) | head); // Drive & CHS.
@ -321,7 +320,6 @@ const IDEDevice = struct {
}
if (!dma and direction == 0) {
// PIO Read.
kernel.println("pio read");
var i: u8 = 0;
while (i < numsects) : (i = i + 1) {
var iedi = buf + i * (words * 2);
@ -393,16 +391,16 @@ pub fn ide_block_read(lba: u64, buf: *[512]u8) void {
}
pub fn init(dev: kernel.pci.PciDevice) void {
kernel.println("-- ide init --");
kernel.print("[ide] ");
kernel.println("-- ide init --", .{});
kernel.print("[ide] ", .{});
dev.format();
assert(dev.header_type() == 0x0); // mass storage device
dev.config_write(@intCast(u8, 0xfe), 0x3c);
if (dev.intr_line() == 0xfe) {
kernel.println("[ide] detected ATA device");
kernel.println("[ide] detected ATA device", .{});
} else {
kernel.println("[ide] Potential SATA device. Not implemented. Hanging");
kernel.println("[ide] Potential SATA device. Not implemented. Hanging", .{});
x86.hang();
}

View file

@ -1,7 +1,7 @@
usingnamespace @import("index.zig");
pub fn init(dev: kernel.pci.PciDevice) void {
kernel.println("-- virtio-block init --");
kernel.println("-- virtio-block init --", .{});
dev.format();
assert(dev.header_type() == 0x0); // mass storage device
assert(dev.subsystem() == 0x2); // virtio-block
@ -10,7 +10,7 @@ pub fn init(dev: kernel.pci.PciDevice) void {
const intr_pin = dev.config_read(u8, 0x3d);
const min_grant = dev.config_read(u8, 0x3e);
const max_lat = dev.config_read(u8, 0x3f);
kernel.println("{x} {} {} {}", intr_line, intr_pin, min_grant, max_lat);
kernel.println("{x} {} {} {}", .{ intr_line, intr_pin, min_grant, max_lat });
// all virtio
// 0 1 2 3

View file

@ -2,10 +2,10 @@ usingnamespace @import("kernel");
// 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 MAGIC = @as(u32, 0x1BADB002); // multiboot magic
const ALIGN = @as(u32, 1 << 0); // Align loaded modules at 4k
const MEMINFO = @as(u32, 1 << 1); // Receive a memory map from the bootloader.
const ADDR = @as(u32, 1 << 16); // Load specific addr
const FLAGS = ALIGN | MEMINFO; // Combine the flags.
break :multiboot multiboot.MultibootHeader{
@ -19,29 +19,30 @@ export const multiboot_header align(4) linksection(".multiboot") = multiboot: {
export fn kmain(magic: u32, info: *const multiboot.MultibootInfo) noreturn {
assert(magic == multiboot.MULTIBOOT_BOOTLOADER_MAGIC);
clear();
println("--- x86 initialization ---");
asm volatile ("movd %%edi, %%xmm0");
println("--- x86 initialization ---", .{});
x86.x86_main(info);
println("--- core initialization ---");
println("--- core initialization ---", .{});
vmem.init();
pci.scan();
println("--- finished booting --- ");
println("--- finished booting --- ", .{});
task.cleaner_task = task.new(@ptrToInt(task.cleaner_loop)) catch unreachable;
_ = task.new(@ptrToInt(topbar)) catch unreachable;
_ = task.new(@ptrToInt(console.loop)) catch unreachable;
var buf = vmem.create([512]u8) catch unreachable;
println("buf at 0x{x}", @ptrToInt(buf));
println("buf at 0x{x}", .{@ptrToInt(buf)});
driver.ide.first_ide_drive.read(2, buf);
const sig = buf[56..58];
println("sig: {x}", sig);
println("sig: {x}", .{sig});
task.terminate();
}
pub fn panic(a: []const u8, b: ?*builtin.StackTrace) noreturn {
println("{}", a);
println("{}", b);
println("{}", .{a});
println("{}", .{b});
while (true) asm volatile ("hlt");
}

View file

@ -41,15 +41,10 @@ pub const PciDevice = struct {
}
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);
} else {
print(" (none)");
}
println("");
print("{}:{}.{}", .{ self.bus, self.slot, self.function });
print(" {x},{x:2}", .{ self.class(), self.subclass() });
print(" 0x{x} 0x{x}", .{ self.vendor, self.device() });
println(" {}", .{if (self.driver()) |d| d.name else " (none)"});
}
pub fn driver(self: PciDevice) ?Driver {
@ -110,7 +105,7 @@ pub const PciDevice = struct {
pub inline fn config_write(self: PciDevice, value: var, comptime offset: u8) void {
// ask for access before writing config
x86.outl(PCI_CONFIG_ADDRESS, self.address(offset));
switch (@typeOf(value)) {
switch (@TypeOf(value)) {
// read the correct size
u8 => return x86.outb(PCI_CONFIG_DATA, value),
u16 => return x86.outw(PCI_CONFIG_DATA, value),
@ -177,7 +172,7 @@ pub fn scan() void {
pub fn lspci() void {
var slot: u5 = 0;
println("b:s.f c, s vendor device driver");
println("b:s.f c, s vendor device driver", .{});
while (slot < 31) : (slot += 1) {
if (PciDevice.init(0, slot, 0)) |dev| {
var function: u3 = 0;

View file

@ -3,8 +3,7 @@ usingnamespace @import("index.zig");
const PS2_DATA = 0x60;
const PS2_STATUS = 0x64;
const KEYMAP_MAX = 59;
const KEYMAP_US = [_][2]u8{
const KEYMAP_US = [_][]const u8{
"\x00\x00",
"\x00\x00", //escape
"1!",

View file

@ -12,7 +12,7 @@ pub fn Ring(comptime T: type) type {
//TODO: allocator argument and remove the namespace
pub fn init(ring: *Self) !void {
ring.buffer = try vmem.create(@typeOf(ring.buffer.*));
ring.buffer = try vmem.create(@TypeOf(ring.buffer.*));
}
pub fn write(ring: *Self, elem: T) void {

View file

@ -175,11 +175,11 @@ pub fn terminate() noreturn {
pub fn cleaner_loop() noreturn {
while (true) {
if (terminated_tasks.popFirst()) |n| {
notify("DESTROYING {}", n.data.tid);
notify("DESTROYING {}", .{n.data.tid});
n.data.destroy();
vmem.destroy(n);
} else {
notify("NOTHING TO CLEAN");
notify("NOTHING TO CLEAN", .{});
block(.Paused);
}
}
@ -201,7 +201,7 @@ fn unlock_scheduler() void {
postpone_task_switches_counter -= 1;
if (postpone_task_switches_flag == true and postpone_task_switches_counter == 0) {
postpone_task_switches_flag = false;
notify("AFTER POSTPONE");
notify("AFTER POSTPONE", .{});
schedule();
}
IRQ_disable_counter -= 1;
@ -215,7 +215,7 @@ pub fn preempt() void {
update_time_used();
if (ready_tasks.first == null) {
notify("NO PREEMPT SINGLE TASK");
notify("NO PREEMPT SINGLE TASK", .{});
time.task_slice_remaining = 0;
return;
}
@ -251,7 +251,11 @@ pub fn switch_to(chosen: *TaskNode) void {
}
// don't inline the asm function, it needs to ret
@noInlineCall(switch_tasks, chosen.data.esp, @ptrToInt(old_task_esp_addr));
@call(
.{ .modifier = .never_inline },
switch_tasks,
.{ chosen.data.esp, @ptrToInt(old_task_esp_addr) },
);
}
pub var CPU_idle_time: u64 = 0;
@ -267,7 +271,7 @@ pub fn schedule() void {
// postponed
if (postpone_task_switches_counter != 0 and current_task.data.state == .Running) {
postpone_task_switches_flag = true;
notify("POSTPONING SCHEDULE");
notify("POSTPONING SCHEDULE", .{});
return;
}
// next task
@ -284,7 +288,7 @@ pub fn schedule() void {
}
// single task
if (current_task.data.state == .Running) {
notify("SINGLE TASK");
notify("SINGLE TASK", .{});
time.task_slice_remaining = 0;
return;
}
@ -297,7 +301,7 @@ fn idle_mode() void {
assert(current_task.data.state != .Running);
assert(current_task.data.state != .ReadyToRun);
notify("IDLE");
notify("IDLE", .{});
// borrow the current task
const borrow = current_task;
@ -323,7 +327,7 @@ fn idle_mode() void {
}
}
pub fn notify(comptime message: []const u8, args: ...) void {
pub fn notify(comptime message: []const u8, args: var) void {
const bg = vga.background;
const fg = vga.foreground;
const cursor = vga.cursor;
@ -341,18 +345,18 @@ pub fn notify(comptime message: []const u8, args: ...) void {
}
pub fn format_short() void {
print("{}R {}B {}S", ready_tasks.len, blocked_tasks.len, sleeping_tasks.len);
print("{}R {}B {}S", .{ ready_tasks.len, blocked_tasks.len, sleeping_tasks.len });
}
pub fn format() void {
update_time_used();
println("{}", current_task.data);
println("{}", .{current_task.data});
var it = ready_tasks.first;
while (it) |node| : (it = node.next) println("{}", node.data);
while (it) |node| : (it = node.next) println("{}", .{node.data});
it = blocked_tasks.first;
while (it) |node| : (it = node.next) println("{}", node.data);
while (it) |node| : (it = node.next) println("{}", .{node.data});
var sit = sleeping_tasks.first;
while (sit) |node| : (sit = node.next) println("{} {}", node.data.data, node.counter);
while (sit) |node| : (sit = node.next) println("{} {}", .{ node.data.data, node.counter });
}

View file

@ -23,9 +23,9 @@ pub fn uptime() void {
const offset_s: u64 = offset_ms / 1000;
offset_ms = @mod(offset_ms / 100, 10);
print("{}.{:.3}", offset_s, offset_ms);
print("{}.{:.3}", .{ offset_s, offset_ms });
}
pub fn utilisation() void {
print("{}%", 100 * (offset_us - task.CPU_idle_time) / offset_us);
print("{}%", .{100 * (offset_us - task.CPU_idle_time) / offset_us});
}

View file

@ -53,10 +53,10 @@ pub fn disableCursor() void {
}
const Errors = error{};
pub fn print(comptime format: []const u8, args: ...) void {
pub fn print(comptime format: []const u8, args: var) void {
var a = std.fmt.format({}, Errors, printCallback, format, args);
}
pub fn println(comptime format: []const u8, args: ...) void {
pub fn println(comptime format: []const u8, args: var) void {
var a = print(format ++ "\n", args);
}
pub fn clear() void {
@ -74,12 +74,11 @@ pub fn topbar() void {
vga.cursor_enabled = false;
time.uptime();
print(" | ");
print(" | ", .{});
time.utilisation();
print(" | ");
print(" | ", .{});
task.format_short();
// print(" ({})", task.IRQ_disable_counter);
println("");
println("", .{});
vga.cursor_enabled = true;
vga.cursor = cursor;