diff options
Diffstat (limited to 'src/lib/instructions.zig')
-rw-r--r-- | src/lib/instructions.zig | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/src/lib/instructions.zig b/src/lib/instructions.zig index 2ae53ec..81775b2 100644 --- a/src/lib/instructions.zig +++ b/src/lib/instructions.zig @@ -4,6 +4,7 @@ const std = @import("std"); +const interrupts = @import("interrupts.zig"); const paging = @import("paging.zig"); pub const SbiRet = struct { @@ -44,15 +45,26 @@ pub fn stackPointer() usize { ); } -pub const setSatp = setCsrFn(paging.Satp, "satp").?; -pub const setSscratch = setCsrFn(usize, "sscratch").?; -pub const setSepc = setCsrFn(usize, "sepc").?; +pub const satp = Csr(paging.Satp, "satp"); +pub const sie = Csr(interrupts.Enable, "sie"); +pub const sscratch = Csr(usize, "sscratch"); +pub const sepc = Csr(usize, "sepc"); -pub fn setCsrFn(comptime T: type, csr: []const u8) ?fn (T) callconv(.Inline) void { - if (csr.len > 8) return null; +pub fn Csr(comptime T: type, csr: []const u8) type { + if (csr.len > 8) @compileError("CSR name length exceeds 8 characters"); return struct { - inline fn setCsr(value: T) void { + pub inline fn read() T { + comptime var buf = [_]u8{0} ** 23; + + const bits = asm volatile (std.fmt.bufPrint(buf[0..], "csrr %[bits], {s}", .{csr}) catch unreachable + : [bits] "=r" (-> usize), + ); + + return @bitCast(bits); + } + + pub inline fn write(value: T) void { const bits: usize = @bitCast(value); comptime var buf = [_]u8{0} ** 23; @@ -62,5 +74,5 @@ pub fn setCsrFn(comptime T: type, csr: []const u8) ?fn (T) callconv(.Inline) voi : [bits] "r" (bits), ); } - }.setCsr; + }; } |