kernel/arch/riscv64/trap/
exception.rs

1use core::arch::asm;
2use core::panic;
3
4use crate::abi::syscall_dispatcher;
5use crate::arch::trap::print_traplog;
6use crate::arch::Trapframe;
7use crate::println;
8use crate::sched::scheduler::get_scheduler;
9use crate::task::mytask;
10
11pub fn arch_exception_handler(trapframe: &mut Trapframe, cause: usize) {
12    match cause {
13        /* Environment call from U-mode */
14        8 => {
15            /* Execute SystemCall */
16            match syscall_dispatcher(trapframe) {
17                Ok(ret) => {
18                    trapframe.set_return_value(ret);
19                }
20                Err(msg) => {
21                    // panic!("Syscall error: {}", msg);
22                    println!("Syscall error: {}", msg);
23                    trapframe.set_return_value(usize::MAX); // Set error code: -1
24                    trapframe.increment_pc_next(mytask().unwrap());
25                }
26            }
27        }
28        /* Instruction page fault */
29        12 => {
30            let mut vaddr = trapframe.epc as usize;
31            let task = get_scheduler().get_current_task(trapframe.get_cpuid()).unwrap();
32            let manager = &task.vm_manager;
33            
34            loop {
35                match manager.search_memory_map(vaddr) {
36                    Some(mmap) => {
37                        match manager.get_root_page_table() {
38                            Some(root_page_table) => {
39                                let paddr = mmap.get_paddr(vaddr).unwrap();
40                                root_page_table.map(manager.get_asid(), vaddr, paddr, mmap.permissions);
41                            }
42                            None => {
43                                print_traplog(trapframe);
44                                panic!("Root page table is not found");
45                            }
46                        }
47                    }
48                    None => {
49                        print_traplog(trapframe);
50                        panic!("Not found memory map matched with vaddr: {:#x}", vaddr);
51                    }
52                }
53
54                if vaddr & 0b11 == 0 {
55                    // If the address is aligned, we can stop
56                    break;
57                }
58                vaddr = (vaddr + 4) & !0b11; // Align to the next 4-byte boundary
59            }
60            
61        }
62        /* Load/Store page fault */
63        13 | 15 => {
64            let mut vaddr;
65            unsafe {
66                asm!("csrr {}, stval", out(reg) vaddr);
67            }
68            let task = get_scheduler().get_current_task(trapframe.get_cpuid()).unwrap();
69            let manager = &task.vm_manager;
70            loop {
71                match manager.search_memory_map(vaddr) {
72                    Some(mmap) => {
73                        match manager.get_root_page_table() {
74                            Some(root_page_table) => {
75                                let paddr = mmap.get_paddr(vaddr).unwrap();
76                                root_page_table.map(manager.get_asid(), vaddr, paddr, mmap.permissions);
77                            }
78                            None => {
79                                print_traplog(trapframe);
80                                panic!("Root page table is not found");
81                            }
82                        }
83                    }
84                    None => {
85                        print_traplog(trapframe);
86                        panic!("Not found memory map matched with vaddr: {:#x}", vaddr);
87                    }
88                }
89
90                if vaddr & 0b11 == 0 {
91                    // If the address is aligned, we can stop
92                    break;
93                }
94                vaddr = (vaddr + 4) & !0b11; // Align to the next 4-byte boundary
95            }
96        },
97        _ => {
98            print_traplog(trapframe);
99            panic!("Unhandled exception: {}", cause);
100            
101        }
102    }
103}