diff --git a/src/arch.zig b/src/arch.zig index e7d7a5d..b5bdae1 100644 --- a/src/arch.zig +++ b/src/arch.zig @@ -3,7 +3,7 @@ pub fn arch() type { switch (comptime builtin.cpu.arch) { .riscv64 => { - return @import("arch/riscv64.zig").arch(); + return @import("arch/riscv64.zig"); }, else => { @panic("Architecture is not supported"); diff --git a/src/arch/riscv64.zig b/src/arch/riscv64.zig index 39296fd..643de87 100644 --- a/src/arch/riscv64.zig +++ b/src/arch/riscv64.zig @@ -8,113 +8,111 @@ const Arena = @import("../arena.zig").Arena; export const _ = boot.rv64BspLowerEntry; -extern fn __rv64_enter_task(cx: *arch().Context) callconv(.C) noreturn; -extern fn __rv64_switch_task(dcx: *arch().Context, scx: *arch().Context) callconv(.C) void; +extern fn __rv64_enter_task(cx: *Context) callconv(.C) noreturn; +extern fn __rv64_switch_task(dcx: *Context, scx: *Context) callconv(.C) void; extern fn __rv64_task_enter_kernel() callconv(.C) noreturn; fn idleFunction() callconv(.naked) noreturn { asm volatile ("j ."); } -pub fn arch() type { - return struct { - pub threadlocal var tHartId: u32 = 0; +pub threadlocal var tHartId: u32 = 0; - pub const Context = extern struct { - const STACK_SIZE: usize = 8192; +pub const Context = extern struct { + const STACK_SIZE: usize = 8192; - // Has to be exactly at offset 0x00, used in assembly - kstack: thread.KStack(STACK_SIZE), + // Has to be exactly at offset 0x00, used in assembly + kstack: thread.KStack(STACK_SIZE), - pub fn idle() @This() { - const entry = @intFromPtr(&idleFunction); - return Context.kernel(entry, 0); - } + pub fn idle() @This() { + const entry = @intFromPtr(&idleFunction); + return Context.kernel(entry, 0); + } - pub fn kernel(pc: usize, arg: usize) @This() { - var ks = thread.KStack(STACK_SIZE).create(); - const entry = @intFromPtr(&__rv64_task_enter_kernel); + pub fn kernel(pc: usize, arg: usize) @This() { + var ks = thread.KStack(STACK_SIZE).create(); + const entry = @intFromPtr(&__rv64_task_enter_kernel); - ks.push(pc); - ks.push(arg); + ks.push(pc); + ks.push(arg); - ks.push(0); // x8/s0/fp - ks.push(0); // x9/s1 - ks.push(0); // x18/s2 - ks.push(0); // x19/s3 - ks.push(0); // x20/s4 - ks.push(0); // x21/s5 - ks.push(0); // x22/s6 - ks.push(0); // x23/s7 - ks.push(0); // x24/s8 - ks.push(0); // x25/s9 - ks.push(0); // x26/s10 - ks.push(0); // x27/s11 - ks.push(0); // x4/gp - ks.push(entry); // x1/ra return address + ks.push(0); // x8/s0/fp + ks.push(0); // x9/s1 + ks.push(0); // x18/s2 + ks.push(0); // x19/s3 + ks.push(0); // x20/s4 + ks.push(0); // x21/s5 + ks.push(0); // x22/s6 + ks.push(0); // x23/s7 + ks.push(0); // x24/s8 + ks.push(0); // x25/s9 + ks.push(0); // x26/s10 + ks.push(0); // x27/s11 + ks.push(0); // x4/gp + ks.push(entry); // x1/ra return address - return .{ - .kstack = ks - }; - } + return .{ .kstack = ks }; + } - pub fn enter(self: *@This()) noreturn { - __rv64_enter_task(self); - } + pub fn enter(self: *@This()) noreturn { + __rv64_enter_task(self); + } - pub fn switchFrom(self: *@This(), from: *@This()) void { - __rv64_switch_task(self, from); - } - }; + pub fn switchFrom(self: *@This(), from: *@This()) void { + __rv64_switch_task(self, from); + } +}; - pub inline fn halt() noreturn { - while (true) { - _ = setInterruptMask(true); - waitForInterrupt(); - } - } - - pub inline fn setInterruptMask(mask: bool) bool { - const old = interruptMask(); - if (mask) { - regs.SSTATUS.modify(.{}, .{ .SIE = true }); - } else { - regs.SSTATUS.modify(.{ .SIE = true }, .{}); - } - return old; - } - - pub fn interruptMask() bool { - return regs.SSTATUS.read().SIE; - } - - pub inline fn waitForInterrupt() void { - asm volatile ("wfi"); - } - - pub inline fn spinHint() void { - // Don't want to explicitly enable Zihintpause ext, so just paste this as raw opcode - asm volatile (".word 0x0100000f"); - } - - pub inline fn barrier(comptime ordering: std.builtin.AtomicOrder) void { - switch (ordering) { - .acquire => { - asm volatile ("fence rw, w"); - }, - .release => { - asm volatile ("fence w, rw"); - }, - .acq_rel, .seq_cst => { - asm volatile ("fence rw, rw"); - }, - .unordered, .monotonic => {}, - } - asm volatile ("":::"memory"); - } - - pub inline fn setThreadPointer(tp: usize) void { - asm volatile ("mv tp, %[tp]"::[tp]"r"(tp):"memory"); - } - }; +pub inline fn halt() noreturn { + while (true) { + _ = setInterruptMask(true); + waitForInterrupt(); + } +} + +pub inline fn setInterruptMask(mask: bool) bool { + const old = interruptMask(); + if (mask) { + regs.SSTATUS.modify(.{}, .{ .SIE = true }); + } else { + regs.SSTATUS.modify(.{ .SIE = true }, .{}); + } + return old; +} + +pub fn interruptMask() bool { + return regs.SSTATUS.read().SIE; +} + +pub inline fn waitForInterrupt() void { + asm volatile ("wfi"); +} + +pub inline fn spinHint() void { + // Don't want to explicitly enable Zihintpause ext, so just paste this as raw opcode + asm volatile (".word 0x0100000f"); +} + +pub inline fn barrier(comptime ordering: std.builtin.AtomicOrder) void { + switch (ordering) { + .acquire => { + asm volatile ("fence rw, w"); + }, + .release => { + asm volatile ("fence w, rw"); + }, + .acq_rel, .seq_cst => { + asm volatile ("fence rw, rw"); + }, + .unordered, .monotonic => {}, + } + asm volatile ("" ::: "memory"); +} + +pub inline fn setThreadPointer(tp: usize) void { + asm volatile ("mv tp, %[tp]" + : + : [tp] "r" (tp), + : "memory" + ); }