aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-06-04 11:48:43 +0200
committerHimbeer <himbeer@disroot.org>2024-06-04 11:48:43 +0200
commit4a633fe9613349d0ad6138b3a1c3d7745b1cafa0 (patch)
tree94ebfbd5c86e9937a7c06c3d12c5c7e88edf9173 /src
parentebb035f0d8a25bfc6a89cfadd06b0d65ccc7e332 (diff)
instructions: Represent sstatus CSR in the type system
Diffstat (limited to 'src')
-rw-r--r--src/lib/instructions.zig39
-rw-r--r--src/lib/process.zig14
2 files changed, 43 insertions, 10 deletions
diff --git a/src/lib/instructions.zig b/src/lib/instructions.zig
index 81775b2..d072113 100644
--- a/src/lib/instructions.zig
+++ b/src/lib/instructions.zig
@@ -7,6 +7,44 @@ const std = @import("std");
const interrupts = @import("interrupts.zig");
const paging = @import("paging.zig");
+pub const Privilege = enum(u1) {
+ user = 0,
+ supervisor = 1,
+};
+
+pub const ExtensionState = enum(u2) {
+ off = 0,
+ initial = 1,
+ clean = 2,
+ dirty = 3,
+};
+
+pub const Xlen = enum(u2) {
+ rv32 = 1,
+ rv64 = 2,
+ rv128 = 3,
+};
+
+pub const Sstatus = packed struct(usize) {
+ user_interrupt_enable: u1,
+ supervisor_interrupt_enable: u1,
+ reserved0: u2,
+ user_prior_interrupt_enable: u1,
+ supervisor_prior_interrupt_enable: u1,
+ reserved1: u2,
+ previous_privilege: Privilege,
+ reserved2: u4,
+ floating_point_state: ExtensionState,
+ user_extension_state: ExtensionState,
+ reserved3: u1,
+ supervisor_user_memory_access: u1,
+ make_executable_readable: u1,
+ reserved4: u12,
+ user_xlen: Xlen,
+ reserved5: u29,
+ need_state_saving: u1, // Read-only.
+};
+
pub const SbiRet = struct {
err: isize,
val: isize,
@@ -46,6 +84,7 @@ pub fn stackPointer() usize {
}
pub const satp = Csr(paging.Satp, "satp");
+pub const sstatus = Csr(Sstatus, "sstatus");
pub const sie = Csr(interrupts.Enable, "sie");
pub const sscratch = Csr(usize, "sscratch");
pub const sepc = Csr(usize, "sepc");
diff --git a/src/lib/process.zig b/src/lib/process.zig
index 05c6773..5392229 100644
--- a/src/lib/process.zig
+++ b/src/lib/process.zig
@@ -95,13 +95,9 @@ pub fn switchTo(proc: *Info) noreturn {
instructions.sscratch.write(@intFromPtr(&proc.trap_frame));
- asm volatile (
- \\ csrr t0, sstatus
- \\ li t1, 0x100
- \\ not t1, t1
- \\ and t0, t0, t1
- \\ csrw sstatus, t0
- ::: "t0", "t1");
+ var sstatus = instructions.sstatus.read();
+ sstatus.previous_privilege = .user;
+ instructions.sstatus.write(sstatus);
instructions.sepc.write(proc.pc);
instructions.satp.write(proc.satp());
@@ -152,7 +148,7 @@ pub fn switchTo(proc: *Info) noreturn {
unreachable;
}
-pub fn demo(allocator: std.mem.Allocator) !void {
+pub fn demo(allocator: std.mem.Allocator) !noreturn {
const entry: [*]u8 = @alignCast(@ptrCast(try paging.zeroedAlloc(1)));
defer paging.free(@ptrCast(entry)) catch {};
@@ -168,6 +164,4 @@ pub fn demo(allocator: std.mem.Allocator) !void {
try time.interruptInMillis(schedule_interval_millis);
try switchTo(&proc_node.data);
-
- while (true) asm volatile ("wfi");
}