From 5a9d3606568a3a3c2b9b0772a9e5f252bb019759 Mon Sep 17 00:00:00 2001 From: Bob Date: Sat, 17 Jan 2026 18:04:36 -0500 Subject: [PATCH 1/3] Set machine mode bit in startup logic. --- port/wch/ch32v/src/cpus/main.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/port/wch/ch32v/src/cpus/main.zig b/port/wch/ch32v/src/cpus/main.zig index 593ac98d2..99ef1ca78 100644 --- a/port/wch/ch32v/src/cpus/main.zig +++ b/port/wch/ch32v/src/cpus/main.zig @@ -259,6 +259,7 @@ pub const startup_logic = struct { .mie = 1, .mpie = 1, .fs = if (cpu_name == .@"qingkev4-rv32imafc") .dirty else .off, + .mpp = 0x3, }); // Initialize the system. From af3d885bfc6a70b819cc6a8e6d3a6d0c7cfaea0b Mon Sep 17 00:00:00 2001 From: Copper280z Date: Mon, 19 Jan 2026 18:56:34 -0500 Subject: [PATCH 2/3] Add comments for machine mode Added comments explaining the machine mode setting for interrupts. --- port/wch/ch32v/src/cpus/main.zig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/port/wch/ch32v/src/cpus/main.zig b/port/wch/ch32v/src/cpus/main.zig index 99ef1ca78..aa3165423 100644 --- a/port/wch/ch32v/src/cpus/main.zig +++ b/port/wch/ch32v/src/cpus/main.zig @@ -255,6 +255,10 @@ pub const startup_logic = struct { // Enable interrupts. csr.mtvec.write(.{ .mode0 = 1, .mode1 = 1, .base = 0 }); + + // We set machine mode (0x3) so the user can enable/disable interrupts + // or manage machine/user mode themselves. + // With this at 0 the users main function is forced to run at user level. csr.mstatus.write(.{ .mie = 1, .mpie = 1, From 0326a39f1e45f83ffac6832e9fb05de8d87ba001 Mon Sep 17 00:00:00 2001 From: Bob Date: Wed, 21 Jan 2026 21:05:13 -0500 Subject: [PATCH 3/3] Edit comment on mstatus --- port/wch/ch32v/src/cpus/main.zig | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/port/wch/ch32v/src/cpus/main.zig b/port/wch/ch32v/src/cpus/main.zig index 32a6bf4d0..db931efbf 100644 --- a/port/wch/ch32v/src/cpus/main.zig +++ b/port/wch/ch32v/src/cpus/main.zig @@ -263,10 +263,11 @@ pub const startup_logic = struct { .base = @intCast((vtable_addr - 4) >> 2), }); - // We set machine mode (0x3) so the user can enable/disable interrupts - // or manage machine/user mode themselves. - // With mpp at 0 the users main function is forced to run at user level. - // Also enable interrupts. + // mstatus.mpp determines the privilege level restored by mret. + // Set to 0x3 (Machine) so mret returns to Machine mode, allowing the + // firmware to manage interrupts and change privilege as needed. + // To change execution to User mode set mpp to 0x0 and execute mret. + // Enable machine-level interrupts (mie) and set floating-point status (fs) if applicable. csr.mstatus.write(.{ .mie = 1, .mpie = 1,