aboutsummaryrefslogtreecommitdiff
path: root/src/lib/instructions.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/instructions.zig')
-rw-r--r--src/lib/instructions.zig26
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;
+ };
}