1
+ use alloc:: boxed:: Box ;
2
+ use alloc:: vec:: Vec ;
1
3
use riscv:: register:: {
2
- scause:: {
3
- self ,
4
- Trap ,
5
- Exception ,
6
- Interrupt ,
7
- } ,
8
4
satp,
9
- sie,
10
- stval,
11
- sstatus,
5
+ scause:: { self , Exception , Interrupt , Trap } ,
6
+ sie, sstatus, stval,
12
7
} ;
13
- use trapframe:: { TrapFrame , UserContext } ;
14
- use alloc:: boxed:: Box ;
15
- use alloc:: vec:: Vec ;
16
8
use spin:: Mutex ;
9
+ use trapframe:: { TrapFrame , UserContext } ;
17
10
18
11
/*
19
12
use crate::timer::{
20
- TICKS,
21
- clock_set_next_event,
13
+ TICKS,
14
+ clock_set_next_event,
22
15
clock_close,
23
16
};
24
17
*/
25
18
26
19
//use crate::context::TrapFrame;
27
- use super :: sbi;
28
20
use super :: plic;
21
+ use super :: sbi;
29
22
use super :: uart;
30
23
31
- use crate :: { putfmt, map_range, phys_to_virt} ;
32
24
use super :: consts:: PHYSICAL_MEMORY_OFFSET ;
33
25
use super :: timer_set_next;
26
+ use crate :: { map_range, phys_to_virt, putfmt} ;
34
27
35
28
//global_asm!(include_str!("trap.asm"));
36
29
37
30
/*
38
31
#[repr(C)]
39
32
pub struct TrapFrame{
40
- pub x: [usize; 32], //General registers
41
- pub sstatus: Sstatus,
42
- pub sepc: usize,
43
- pub stval: usize,
44
- pub scause: Scause,
33
+ pub x: [usize; 32], //General registers
34
+ pub sstatus: Sstatus,
35
+ pub sepc: usize,
36
+ pub stval: usize,
37
+ pub scause: Scause,
45
38
}
46
39
*/
47
40
@@ -52,27 +45,25 @@ lazy_static! {
52
45
}
53
46
54
47
fn init_irq ( ) {
55
-
56
48
init_irq_table ( ) ;
57
49
irq_add_handle ( Timer , Box :: new ( super_timer) ) ; //模拟参照了x86_64,把timer处理函数也放进去了
58
- //irq_add_handle(Keyboard, Box::new(keyboard));
50
+ //irq_add_handle(Keyboard, Box::new(keyboard));
59
51
irq_add_handle ( S_PLIC , Box :: new ( plic:: handle_interrupt) ) ;
60
52
}
61
53
62
- pub fn init ( ) {
63
- unsafe {
64
-
65
- sstatus:: set_sie ( ) ;
54
+ pub fn init ( ) {
55
+ unsafe {
56
+ sstatus:: set_sie ( ) ;
66
57
67
58
init_uart ( ) ;
68
59
69
60
sie:: set_sext ( ) ;
70
61
init_ext ( ) ;
71
- }
62
+ }
72
63
73
64
init_irq ( ) ;
74
65
75
- bare_println ! ( "+++ setup interrupt +++" ) ;
66
+ bare_println ! ( "+++ setup interrupt +++" ) ;
76
67
}
77
68
78
69
#[ no_mangle]
@@ -83,20 +74,26 @@ pub extern "C" fn trap_handler(tf: &mut TrapFrame) {
83
74
let is_int = scause. bits ( ) >> 63 ;
84
75
let code = scause. bits ( ) & !( 1 << 63 ) ;
85
76
86
- match scause. cause ( ) {
87
- Trap :: Exception ( Exception :: Breakpoint ) => breakpoint ( & mut tf. sepc ) ,
88
- Trap :: Exception ( Exception :: IllegalInstruction ) => panic ! ( "IllegalInstruction: {:#x}->{:#x}" , sepc, stval) ,
89
- Trap :: Exception ( Exception :: LoadFault ) => panic ! ( "Load access fault: {:#x}->{:#x}" , sepc, stval) ,
90
- Trap :: Exception ( Exception :: StoreFault ) => panic ! ( "Store access fault: {:#x}->{:#x}" , sepc, stval) ,
77
+ match scause. cause ( ) {
78
+ Trap :: Exception ( Exception :: Breakpoint ) => breakpoint ( & mut tf. sepc ) ,
79
+ Trap :: Exception ( Exception :: IllegalInstruction ) => {
80
+ panic ! ( "IllegalInstruction: {:#x}->{:#x}" , sepc, stval)
81
+ }
82
+ Trap :: Exception ( Exception :: LoadFault ) => {
83
+ panic ! ( "Load access fault: {:#x}->{:#x}" , sepc, stval)
84
+ }
85
+ Trap :: Exception ( Exception :: StoreFault ) => {
86
+ panic ! ( "Store access fault: {:#x}->{:#x}" , sepc, stval)
87
+ }
91
88
Trap :: Exception ( Exception :: LoadPageFault ) => page_fault ( stval, tf) ,
92
89
Trap :: Exception ( Exception :: StorePageFault ) => page_fault ( stval, tf) ,
93
90
Trap :: Exception ( Exception :: InstructionPageFault ) => page_fault ( stval, tf) ,
94
- Trap :: Interrupt ( Interrupt :: SupervisorTimer ) => super_timer ( ) ,
95
- Trap :: Interrupt ( Interrupt :: SupervisorSoft ) => super_soft ( ) ,
91
+ Trap :: Interrupt ( Interrupt :: SupervisorTimer ) => super_timer ( ) ,
92
+ Trap :: Interrupt ( Interrupt :: SupervisorSoft ) => super_soft ( ) ,
96
93
Trap :: Interrupt ( Interrupt :: SupervisorExternal ) => plic:: handle_interrupt ( ) ,
97
- //Trap::Interrupt(Interrupt::SupervisorExternal) => irq_handle(code as u8),
98
- _ => panic ! ( "Undefined Trap: {:#x} {:#x}" , is_int, code)
99
- }
94
+ //Trap::Interrupt(Interrupt::SupervisorExternal) => irq_handle(code as u8),
95
+ _ => panic ! ( "Undefined Trap: {:#x} {:#x}" , is_int, code) ,
96
+ }
100
97
}
101
98
102
99
fn init_irq_table ( ) {
@@ -202,44 +199,47 @@ pub fn overwrite_handler(msi_id: u32, handle: Box<dyn Fn() + Send + Sync>) -> bo
202
199
set
203
200
}
204
201
205
- fn breakpoint ( sepc : & mut usize ) {
206
- bare_println ! ( "Exception::Breakpoint: A breakpoint set @0x{:x} " , sepc) ;
202
+ fn breakpoint ( sepc : & mut usize ) {
203
+ bare_println ! ( "Exception::Breakpoint: A breakpoint set @0x{:x} " , sepc) ;
207
204
208
- //sepc为触发中断指令ebreak的地址
209
- //防止无限循环中断,让sret返回时跳转到sepc的下一条指令地址
210
- * sepc +=2
205
+ //sepc为触发中断指令ebreak的地址
206
+ //防止无限循环中断,让sret返回时跳转到sepc的下一条指令地址
207
+ * sepc += 2
211
208
}
212
209
213
- fn page_fault ( stval : usize , tf : & mut TrapFrame ) {
210
+ fn page_fault ( stval : usize , tf : & mut TrapFrame ) {
214
211
let this_scause = scause:: read ( ) ;
215
- info ! ( "EXCEPTION Page Fault: {:?} @ {:#x}->{:#x}" , this_scause. cause( ) , tf. sepc, stval) ;
212
+ info ! (
213
+ "EXCEPTION Page Fault: {:?} @ {:#x}->{:#x}" ,
214
+ this_scause. cause( ) ,
215
+ tf. sepc,
216
+ stval
217
+ ) ;
216
218
let vaddr = stval;
217
219
218
- use riscv:: paging:: { Rv39PageTable , PageTableFlags as PTF , * } ;
219
- use riscv:: addr:: { Page , PhysAddr , VirtAddr } ;
220
220
use crate :: PageTableImpl ;
221
- use kernel_hal:: { PageTableTrait , MMUFlags } ;
221
+ use kernel_hal:: { MMUFlags , PageTableTrait } ;
222
+ use riscv:: addr:: { Page , PhysAddr , VirtAddr } ;
223
+ use riscv:: paging:: { PageTableFlags as PTF , Rv39PageTable , * } ;
222
224
223
225
//let mut flags = PTF::VALID;
224
226
let code = this_scause. code ( ) ;
225
- let mut flags =
226
- if code == 15 {
227
- //MMUFlags::WRITE ???
228
- MMUFlags :: READ | MMUFlags :: WRITE
229
- } else if code == 12 {
230
- MMUFlags :: EXECUTE
231
- } else {
232
- MMUFlags :: READ
233
- } ;
234
-
235
- let linear_offset =
236
- if stval >= PHYSICAL_MEMORY_OFFSET {
237
- // Kernel
238
- PHYSICAL_MEMORY_OFFSET
239
- } else {
240
- // User
241
- 0
242
- } ;
227
+ let mut flags = if code == 15 {
228
+ //MMUFlags::WRITE ???
229
+ MMUFlags :: READ | MMUFlags :: WRITE
230
+ } else if code == 12 {
231
+ MMUFlags :: EXECUTE
232
+ } else {
233
+ MMUFlags :: READ
234
+ } ;
235
+
236
+ let linear_offset = if stval >= PHYSICAL_MEMORY_OFFSET {
237
+ // Kernel
238
+ PHYSICAL_MEMORY_OFFSET
239
+ } else {
240
+ // User
241
+ 0
242
+ } ;
243
243
244
244
/*
245
245
let current =
@@ -248,16 +248,19 @@ fn page_fault(stval: usize, tf: &mut TrapFrame){
248
248
map_range(&mut pt, vaddr, vaddr, linear_offset, flags);
249
249
*/
250
250
251
- let mut pti =
252
- PageTableImpl {
253
- root_paddr : satp:: read ( ) . frame ( ) . start_address ( ) . as_usize ( ) ,
254
- } ;
251
+ let mut pti = PageTableImpl {
252
+ root_paddr : satp:: read ( ) . frame ( ) . start_address ( ) . as_usize ( ) ,
253
+ } ;
255
254
256
255
let page = Page :: of_addr ( VirtAddr :: new ( vaddr) ) ;
257
256
if let Ok ( pte) = pti. get ( ) . ref_entry ( page) {
258
257
let pte = unsafe { & mut * ( pte as * mut PageTableEntry ) } ;
259
258
if !pte. is_unused ( ) {
260
- debug ! ( "PageAlreadyMapped -> {:#x?}, {:?}" , pte. addr( ) . as_usize( ) , pte. flags( ) ) ;
259
+ debug ! (
260
+ "PageAlreadyMapped -> {:#x?}, {:?}" ,
261
+ pte. addr( ) . as_usize( ) ,
262
+ pte. flags( )
263
+ ) ;
261
264
//TODO update flags
262
265
263
266
pti. unmap ( vaddr) . unwrap ( ) ;
@@ -266,16 +269,16 @@ fn page_fault(stval: usize, tf: &mut TrapFrame){
266
269
pti. map ( vaddr, vaddr - linear_offset, flags) . unwrap ( ) ;
267
270
}
268
271
269
- fn super_timer ( ) {
272
+ fn super_timer ( ) {
270
273
timer_set_next ( ) ;
271
274
super :: timer_tick ( ) ;
272
275
273
276
//bare_print!(".");
274
277
275
- //发生外界中断时,epc的指令还没有执行,故无需修改epc到下一条
278
+ //发生外界中断时,epc的指令还没有执行,故无需修改epc到下一条
276
279
}
277
280
278
- fn init_uart ( ) {
281
+ fn init_uart ( ) {
279
282
uart:: Uart :: new ( 0x1000_0000 + PHYSICAL_MEMORY_OFFSET ) . simple_init ( ) ;
280
283
281
284
//但当没有SBI_CONSOLE_PUTCHAR时,却为什么不行?
@@ -295,7 +298,7 @@ pub fn try_process_serial() -> bool {
295
298
}
296
299
}
297
300
298
- pub fn init_ext ( ) {
301
+ pub fn init_ext ( ) {
299
302
// Qemu virt
300
303
// UART0 = 10
301
304
plic:: set_priority ( 10 , 7 ) ;
@@ -305,24 +308,23 @@ pub fn init_ext(){
305
308
bare_println ! ( "+++ Setting up PLIC +++" ) ;
306
309
}
307
310
308
- fn super_soft ( ) {
311
+ fn super_soft ( ) {
309
312
sbi:: clear_ipi ( ) ;
310
313
bare_println ! ( "Interrupt::SupervisorSoft!" ) ;
311
314
}
312
315
313
- pub fn init_soft ( ) {
316
+ pub fn init_soft ( ) {
314
317
unsafe {
315
318
sie:: set_ssoft ( ) ;
316
319
}
317
- bare_println ! ( "+++ setup soft int! +++" ) ;
320
+ bare_println ! ( "+++ setup soft int! +++" ) ;
318
321
}
319
322
320
323
#[ export_name = "fetch_trap_num" ]
321
324
pub fn fetch_trap_num ( _context : & UserContext ) -> usize {
322
325
scause:: read ( ) . bits ( )
323
326
}
324
327
325
-
326
328
pub fn wait_for_interrupt ( ) {
327
329
unsafe {
328
330
// enable interrupt and disable
0 commit comments