forked from peiyuanix/riscv-os
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrap_handler.c
71 lines (64 loc) · 2.06 KB
/
trap_handler.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include "riscv_cpu.h"
#include "uart.h"
#include "timer.h"
#include "proc.h"
#include "interrupts.h"
struct cpu trap_cpu;
u8 trap_stack[1 << 20];
void *trap_stack_top = &trap_stack[sizeof(trap_stack) - 1];
void trap_handler()
{
u64 mcause = csrr_mcause();
switch (mcause)
{
case MCAUSE_INTR_M_TIMER:
{
// there exists runnable processes
if (proc_list[0].state != PROC_STATE_NONE)
{
// assume proc-0 is the active process if there is no active process
if (active_pid < 0)
{
active_pid = 0;
trap_cpu = proc_list[0].cpu;
uart_printf("[Trap - M-mode Timer] Scheduler Init. Ticks: %ld\n", active_pid, mcause, mtime());
}
// save cpu state for the active process
proc_list[active_pid].cpu = trap_cpu;
// suspend the active process
proc_list[active_pid].state = PROC_STATE_READY;
// iterate the processes from the next process, ending with the active process
for (int ring_index = 1; ring_index <= PROC_TOTAL_COUNT; ring_index++)
{
int real_index = (active_pid + ring_index) % PROC_TOTAL_COUNT;
struct proc *proc = &proc_list[real_index];
// run this process if it is ready
if (proc->state == PROC_STATE_READY)
{
uart_printf("[Trap - M-mode Timer] Scheduler(Ticks = %ld): (PID = %d, PC = 0x%lx) => (PID = %d, PC = 0x%lx)\n", mtime(), active_pid, trap_cpu.pc, proc->pid, proc->cpu.pc);
trap_cpu = proc->cpu;
active_pid = proc->pid;
break;
}
}
}
set_timeout(10000000);
break;
}
case MCAUSE_INTR_M_EXTER:
{
uart_printf("[Trap - M-mode Exter] active_pid: %d, mcause: 0x%lX, current ticks: %d\n", active_pid, mcause, mtime());
break;
}
case MCAUSE_INNER_M_ILLEAGEL_INSTRUCTION:
{
uart_printf("[Trap - M-mode Illeagel Instruction] active_pid: %d, mcause: 0x%lX, mepc: %lx\n", active_pid, mcause, csrr_mepc());
break;
}
default:
{
uart_printf("[Trap - Default] active_pid: %d, mcause: 0x%lX, current ticks: %d\n", active_pid, mcause, mtime());
break;
}
}
}