-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrap.c
95 lines (84 loc) · 1.79 KB
/
trap.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "os.h"
extern void trap_vector(void);
extern void uart_isr(void);
extern void timer_handler(void);
extern void schedule(void);
extern void do_syscall(struct context *cxt);
void trap_init()
{
/*
* set the trap-vector base-address for machine-mode
*/
w_mtvec((reg_t)trap_vector);
}
void external_interrupt_handler()
{
int irq = plic_claim();
if (irq == UART0_IRQ){
uart_isr();
} else if (irq) {
printf("unexpected interrupt irq = %d\n", irq);
}
if (irq) {
plic_complete(irq);
}
}
reg_t trap_handler(reg_t epc, reg_t cause, struct context *ctx)
{
reg_t return_pc = epc;
reg_t cause_code = cause & MCAUSE_MASK_ECODE;
if (cause & MCAUSE_MASK_INTERRUPT)
{
/* Asynchronous trap - interrupt */
switch (cause_code)
{
case 3:
uart_puts("software interruption!\n");
int id = r_mhartid();
*(uint32_t*)CLINT_MSIP(id) = 0;
schedule();
break;
case 7:
uart_puts("timer interruption!\n");
timer_handler();
break;
case 11:
uart_puts("external interruption!\n");
external_interrupt_handler();
break;
default:
printf("Unknown async exception! Code = %ld\n", cause_code);
break;
}
}
else
{
/* Synchronous trap - exception */
printf("Sync exceptions! Code = %ld\n", cause_code);
switch (cause_code) {
case 8:
uart_puts("System call from U-mode!\n");
do_syscall(ctx);
return_pc += 4;
break;
default:
panic("OOPS! What can I do!");
//return_pc += 4;
}
}
return return_pc;
}
void trap_test1()
{
/*
* Synchronous exception code = 7
* Store/AMO access fault
*/
*(int *)0x00000000 = 100;
/*
* Synchronous exception code = 5
* Load access fault
*/
// int a = *(int *)0x00000000;
uart_puts("Yeah! I'm return back from trap!\n");
}