mirror of
https://github.com/cccriscv/mini-riscv-os.git
synced 2025-11-16 04:24:33 +00:00
fix 10-SystemCall trap bug
This commit is contained in:
@@ -72,6 +72,7 @@
|
||||
sw t3, 108(\base)
|
||||
sw t4, 112(\base)
|
||||
sw t5, 116(\base)
|
||||
sw t6, 120(\base)
|
||||
.endm
|
||||
|
||||
.macro reg_load base
|
||||
@@ -142,12 +143,12 @@ trap_vector:
|
||||
# save context(registers).
|
||||
csrrw t6, mscratch, t6 # swap t6 and mscratch
|
||||
reg_save t6
|
||||
csrw mscratch, t6
|
||||
|
||||
# save mepc to context of current task
|
||||
csrr a0, mepc
|
||||
sw a0, 124(t6)
|
||||
sw a0, 128(t6)
|
||||
|
||||
csrrw t6, mscratch, t6
|
||||
# call the C trap handler in trap.c
|
||||
csrr a0, mepc
|
||||
csrr a1, mcause
|
||||
@@ -158,28 +159,9 @@ trap_vector:
|
||||
csrw mepc, a0
|
||||
|
||||
# load context(registers).
|
||||
csrr t6, mscratch
|
||||
csrrw t6, mscratch, t6
|
||||
reg_load t6
|
||||
mret
|
||||
|
||||
# void switch_to(struct context *next);
|
||||
# a0: pointer to the context of the next task
|
||||
.globl switch_to
|
||||
.align 4
|
||||
switch_to:
|
||||
# switch mscratch to point to the context of the next task
|
||||
csrw mscratch, a0
|
||||
# set mepc to the pc of the next task
|
||||
lw a1, 124(a0)
|
||||
csrw mepc, a1
|
||||
|
||||
# Restore all GP registers
|
||||
# Use t6 to point to the context of the new task
|
||||
mv t6, a0
|
||||
reg_load t6
|
||||
|
||||
# Do actual context switching.
|
||||
# Notice this will enable global interrupt
|
||||
csrrw t6, mscratch, t6
|
||||
mret
|
||||
|
||||
.end
|
||||
|
||||
@@ -12,7 +12,6 @@ int task_create(void (*task)(void))
|
||||
{
|
||||
int i = taskTop++;
|
||||
ctx_tasks[i].ra = (reg_t)task;
|
||||
// ctx_tasks[i].pc = (reg_t)task;
|
||||
ctx_tasks[i].sp = (reg_t)&task_stack[i][STACK_SIZE - 1];
|
||||
return i;
|
||||
}
|
||||
@@ -21,7 +20,6 @@ int task_create(void (*task)(void))
|
||||
void task_go(int i)
|
||||
{
|
||||
ctx_now = &ctx_tasks[i];
|
||||
// switch_to(ctx_now);
|
||||
sys_switch(&ctx_os, &ctx_tasks[i]);
|
||||
}
|
||||
|
||||
@@ -30,6 +28,5 @@ void task_os()
|
||||
{
|
||||
struct context *ctx = ctx_now;
|
||||
ctx_now = &ctx_os;
|
||||
// switch_to(&ctx_os);
|
||||
sys_switch(ctx, &ctx_os);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "timer.h"
|
||||
|
||||
// a scratch area per CPU for machine-mode timer interrupts.
|
||||
reg_t timer_scratch[NCPU][5];
|
||||
|
||||
#define interval 20000000 // cycles; about 2 second in qemu.
|
||||
|
||||
@@ -9,23 +8,7 @@ void timer_init()
|
||||
{
|
||||
// each CPU has a separate source of timer interrupts.
|
||||
int id = r_mhartid();
|
||||
|
||||
// ask the CLINT for a timer interrupt.
|
||||
// int interval = 1000000; // cycles; about 1/10th second in qemu.
|
||||
|
||||
*(reg_t *)CLINT_MTIMECMP(id) = *(reg_t *)CLINT_MTIME + interval;
|
||||
|
||||
// prepare information in scratch[] for timervec.
|
||||
// scratch[0..2] : space for timervec to save registers.
|
||||
// scratch[3] : address of CLINT MTIMECMP register.
|
||||
// scratch[4] : desired interval (in cycles) between timer interrupts.
|
||||
reg_t *scratch = &timer_scratch[id][0];
|
||||
scratch[3] = CLINT_MTIMECMP(id);
|
||||
scratch[4] = interval;
|
||||
w_mscratch((reg_t)scratch);
|
||||
|
||||
// enable machine-mode timer interrupts.
|
||||
w_mie(r_mie() | MIE_MTIE);
|
||||
}
|
||||
|
||||
static int timer_count = 0;
|
||||
|
||||
@@ -4,10 +4,16 @@ extern void trap_vector();
|
||||
extern void virtio_disk_isr();
|
||||
extern void do_syscall(struct context *ctx);
|
||||
|
||||
// a scratch area per CPU for machine-mode interrupt.
|
||||
reg_t trap_scratch[NCPU][32+1]; // R0-R31 + mepc
|
||||
|
||||
void trap_init()
|
||||
{
|
||||
// set the machine-mode trap handler.
|
||||
w_mtvec((reg_t)trap_vector);
|
||||
int id = r_mhartid();
|
||||
reg_t *scratch = &trap_scratch[id][0];
|
||||
w_mscratch((reg_t)scratch); // set scratch area for this core
|
||||
w_mtvec((reg_t)trap_vector); // set the machine-mode trap handler.
|
||||
w_mie(r_mie() | MIE_MTIE); // enable machine-mode timer interrupts.
|
||||
}
|
||||
|
||||
void external_handler()
|
||||
|
||||
Reference in New Issue
Block a user