Makes scheduler works at the end of the interruption

This commit is contained in:
2026-02-11 16:39:36 +01:00
parent 6fc08b5dbb
commit 8a5c17482c
5 changed files with 139 additions and 204 deletions

View File

@@ -1,16 +1,10 @@
use core::{
arch::{naked_asm, riscv64::wfi},
array,
cell::LazyCell,
time::Duration,
};
use core::{arch::riscv64::wfi, array, cell::LazyCell, time::Duration};
use alloc::string::String;
use log::info;
use crate::{
process::{create_processus, ExecutionContext, Process, ProcessState},
riscv::enable_supervisor_interrupt,
time,
};
@@ -31,7 +25,7 @@ pub static mut PROCESS_TABLE: LazyCell<[Process; PROCESSUS_COUNT]> = LazyCell::n
a: [0; _],
t: [0; _],
s: [0; _],
mepc: 0,
mepc: core::ptr::null(),
mstatus: 0,
},
entry_point: None,
@@ -41,7 +35,7 @@ pub static mut PROCESS_TABLE: LazyCell<[Process; PROCESSUS_COUNT]> = LazyCell::n
pub extern "C" fn idle() {
loop {
enable_supervisor_interrupt();
// enable_supervisor_interrupt();
unsafe {
wfi();
}
@@ -62,13 +56,14 @@ pub fn scheduler_init() {
}
}
pub fn scheduler(interrupt_state: ExecutionContext) -> usize {
pub fn scheduler(interrupt_state: ExecutionContext) -> *const ExecutionContext {
// info!("scheduler");
unsafe {
let prev_pid = ACTIVE_PID;
PROCESS_TABLE[prev_pid].ctx = interrupt_state;
if PROCESS_TABLE[ACTIVE_PID].state == ProcessState::Active {
PROCESS_TABLE[ACTIVE_PID].state = ProcessState::Activable;
if PROCESS_TABLE[prev_pid].state == ProcessState::Active {
PROCESS_TABLE[prev_pid].state = ProcessState::Activable;
}
loop {
@@ -84,90 +79,6 @@ pub fn scheduler(interrupt_state: ExecutionContext) -> usize {
}
PROCESS_TABLE[ACTIVE_PID].state = ProcessState::Active;
PROCESS_TABLE[prev_pid].ctx = interrupt_state;
// PROCESS_TABLE[prev_pid].ctx.t = interrupt_state.t;
// PROCESS_TABLE[prev_pid].ctx.ra = interrupt_state.ra;
context_switch(
PROCESS_TABLE[ACTIVE_PID].entry_point.unwrap(),
&raw mut PROCESS_TABLE[prev_pid].ctx,
&raw mut PROCESS_TABLE[ACTIVE_PID].ctx,
);
prev_pid
&raw const PROCESS_TABLE[ACTIVE_PID].ctx
}
}
#[unsafe(naked)]
pub extern "C" fn context_switch(
code: extern "C" fn(),
current: *mut ExecutionContext,
next: *mut ExecutionContext,
) {
naked_asm!(
"
// sd ra, 0(a1)
// sd sp, 8(a1)
// sd gp, 16(a1)
// sd tp, 24(a1)
// sd s0, 152(a1)
// sd s1, 160(a1)
// sd s2, 168(a1)
// sd s3, 176(a1)
// sd s4, 184(a1)
// sd s5, 192(a1)
// sd s6, 200(a1)
// sd s7, 208(a1)
// sd s8, 216(a1)
// sd s9, 224(a1)
// sd s10, 232(a1)
// sd s11, 240(a1)
// csrr t0, sepc
// sd t0, 248(a1)
// csrr t0, sstatus
// sd t0, 256(a1)
# Load next execution context
ld t0, 248(a2)
csrw sepc, t0
ld t0, 256(a2)
csrw sstatus, t0
ld ra, 0(a2)
ld sp, 8(a2)
ld gp, 16(a2)
ld tp, 24(a2)
ld a0, 32(a2)
ld a1, 40(a2)
// Skip a2 since it used as a pointer
ld a3, 56(a2)
ld a4, 64(a2)
ld a5, 72(a2)
ld a6, 80(a2)
ld a7, 88(a2)
ld t0, 96(a2)
ld t1, 104(a2)
ld t2, 112(a2)
ld t3, 120(a2)
ld t4, 128(a2)
ld t5, 136(a2)
ld t6, 144(a2)
ld s0, 152(a2)
ld s1, 160(a2)
ld s2, 168(a2)
ld s3, 176(a2)
ld s4, 184(a2)
ld s5, 192(a2)
ld s6, 200(a2)
ld s7, 208(a2)
ld s8, 216(a2)
ld s9, 224(a2)
ld s10, 232(a2)
ld s11, 240(a2)
// Restore a2 at the end
ld a2, 48(a2)
addi sp, sp, 264
sret"
);
}