|  |  |  | @ -28,6 +28,7 @@ use riscv::register::{ | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | global_asm!(include_str!("trap.S")); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /// initialize CSR `stvec` as the entry of `__alltraps`
 | 
			
		
	
		
			
				
					|  |  |  |  | pub fn init() { | 
			
		
	
		
			
				
					|  |  |  |  |     set_kernel_trap_entry(); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
	
		
			
				
					|  |  |  | @ -44,6 +45,7 @@ fn set_user_trap_entry() { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /// enable timer interrupt in sie CSR
 | 
			
		
	
		
			
				
					|  |  |  |  | pub fn enable_timer_interrupt() { | 
			
		
	
		
			
				
					|  |  |  |  |     unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |         sie::set_stimer(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -51,6 +53,7 @@ pub fn enable_timer_interrupt() { | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #[no_mangle] | 
			
		
	
		
			
				
					|  |  |  |  | /// handle an interrupt, exception, or system call from user space
 | 
			
		
	
		
			
				
					|  |  |  |  | pub fn trap_handler() -> ! { | 
			
		
	
		
			
				
					|  |  |  |  |     set_kernel_trap_entry(); | 
			
		
	
		
			
				
					|  |  |  |  |     let cx = current_trap_cx(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -86,6 +89,9 @@ pub fn trap_handler() -> ! { | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #[no_mangle] | 
			
		
	
		
			
				
					|  |  |  |  | /// set the new addr of __restore asm function in TRAMPOLINE page,
 | 
			
		
	
		
			
				
					|  |  |  |  | /// set the reg a0 = trap_cx_ptr, reg a1 = phy addr of usr page table,
 | 
			
		
	
		
			
				
					|  |  |  |  | /// finally, jump to new addr of __restore asm function
 | 
			
		
	
		
			
				
					|  |  |  |  | pub fn trap_return() -> ! { | 
			
		
	
		
			
				
					|  |  |  |  |     set_user_trap_entry(); | 
			
		
	
		
			
				
					|  |  |  |  |     let trap_cx_ptr = TRAP_CONTEXT; | 
			
		
	
	
		
			
				
					|  |  |  | @ -98,16 +104,18 @@ pub fn trap_return() -> ! { | 
			
		
	
		
			
				
					|  |  |  |  |     unsafe { | 
			
		
	
		
			
				
					|  |  |  |  |         asm!( | 
			
		
	
		
			
				
					|  |  |  |  |             "fence.i", | 
			
		
	
		
			
				
					|  |  |  |  |             "jr {restore_va}", | 
			
		
	
		
			
				
					|  |  |  |  |             "jr {restore_va}",             // jump to new addr of __restore asm function
 | 
			
		
	
		
			
				
					|  |  |  |  |             restore_va = in(reg) restore_va, | 
			
		
	
		
			
				
					|  |  |  |  |             in("a0") trap_cx_ptr, | 
			
		
	
		
			
				
					|  |  |  |  |             in("a1") user_satp, | 
			
		
	
		
			
				
					|  |  |  |  |             in("a0") trap_cx_ptr,      // a0 = virt addr of Trap Context
 | 
			
		
	
		
			
				
					|  |  |  |  |             in("a1") user_satp,        // a1 = phy addr of usr page table
 | 
			
		
	
		
			
				
					|  |  |  |  |             options(noreturn) | 
			
		
	
		
			
				
					|  |  |  |  |         ); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #[no_mangle] | 
			
		
	
		
			
				
					|  |  |  |  | /// Unimplement: traps/interrupts/exceptions from kernel mode
 | 
			
		
	
		
			
				
					|  |  |  |  | /// Todo: Chapter 9: I/O device 
 | 
			
		
	
		
			
				
					|  |  |  |  | pub fn trap_from_kernel() -> ! { | 
			
		
	
		
			
				
					|  |  |  |  |     panic!("a trap from kernel!"); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
	
		
			
				
					|  |  |  | 
 |