aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-06-13 22:33:52 +0200
committerHimbeer <himbeer@disroot.org>2024-06-13 22:33:52 +0200
commit235cff033077809565a89f77334866fddda899ad (patch)
tree6ae4f3f59d9691814529d7b3bae3f7efabd7182c /src
parentb53cb2af26b43db9c7daa06d9fa2770679de04c8 (diff)
process: Disable interrupts while switching to U-mode
Diffstat (limited to 'src')
-rw-r--r--src/lib/interrupts.zig4
-rw-r--r--src/lib/process.zig9
2 files changed, 10 insertions, 3 deletions
diff --git a/src/lib/interrupts.zig b/src/lib/interrupts.zig
index f9a9ca1..ebb6e9a 100644
--- a/src/lib/interrupts.zig
+++ b/src/lib/interrupts.zig
@@ -99,6 +99,10 @@ export fn handleTrap(epc: usize, tval: usize, cause_bits: usize, frame: *trap.Fr
switch (@as(AsyncCause, @enumFromInt(cause.num))) {
.supervisor_software => w.print("Hart {d}: Software interrupt\r\n", .{frame.hart_id}) catch unreachable,
.supervisor_timer => {
+ defer time.interruptInMillis(process.schedule_interval_millis) catch |err| {
+ std.debug.panic("Hart {d}: Unable to reset interrupt timer: {any}", .{ frame.hart_id, err });
+ };
+
if (status.previous_privilege == .user) {
// Trapped from U-mode, update pc for next time slice.
//
diff --git a/src/lib/process.zig b/src/lib/process.zig
index e07c6a4..c227fdb 100644
--- a/src/lib/process.zig
+++ b/src/lib/process.zig
@@ -93,12 +93,15 @@ pub fn next() ?*Info {
pub fn switchTo(proc: *Info) noreturn {
proc.state = .active;
- instructions.sscratch.write(@intFromPtr(&proc.trap_frame));
-
var sstatus = instructions.sstatus.read();
sstatus.previous_privilege = .user;
+ sstatus.user_interrupt_enable = 0;
+ sstatus.supervisor_interrupt_enable = 0;
+ sstatus.user_prior_interrupt_enable = 1;
+ sstatus.supervisor_prior_interrupt_enable = 1;
instructions.sstatus.write(sstatus);
+ instructions.sscratch.write(@intFromPtr(&proc.trap_frame));
instructions.sepc.write(proc.pc);
instructions.satp.write(proc.satp());
@@ -163,5 +166,5 @@ pub fn demo(allocator: std.mem.Allocator) !noreturn {
list.prepend(proc_node);
try time.interruptInMillis(schedule_interval_millis);
- try switchTo(&proc_node.data);
+ switchTo(&proc_node.data);
}