riscv-pke/kernel/process.c

54 lines
1.5 KiB
C

/*
* Utility functions for process management.
*
* Note: in Lab1, only one process (i.e., our user application) exists. Therefore,
* PKE OS at this stage will set "current" to the loaded user application, and also
* switch to the old "current" process after trap handling.
*/
#include "riscv.h"
#include "strap.h"
#include "config.h"
#include "process.h"
#include "elf.h"
#include "string.h"
#include "spike_interface/spike_utils.h"
//Two functions defined in kernel/usertrap.S
extern char smode_trap_vector[];
extern void return_to_user(trapframe*);
// current points to the currently running user-mode application.
process* current = NULL;
//
// switch to a user-mode process
//
void switch_to(process* proc) {
assert(proc);
current = proc;
write_csr(stvec, (uint64)smode_trap_vector);
// set up trapframe values that smode_trap_vector will need when
// the process next re-enters the kernel.
proc->trapframe->kernel_sp = proc->kstack; // process's kernel stack
proc->trapframe->kernel_trap = (uint64)smode_trap_handler;
// set up the registers that strap_vector.S's sret will use
// to get to user space.
// set S Previous Privilege mode to User.
unsigned long x = read_csr(sstatus);
x &= ~SSTATUS_SPP; // clear SPP to 0 for user mode
x |= SSTATUS_SPIE; // enable interrupts in user mode
write_csr(sstatus, x);
// set S Exception Program Counter to the saved user pc.
write_csr(sepc, proc->trapframe->epc);
// switch to user mode with sret.
return_to_user(proc->trapframe);
}