diff --git a/risc_v/ch8/src/asm/trap.S b/risc_v/ch8/src/asm/trap.S index 80cbded..3c6e1ba 100644 --- a/risc_v/ch8/src/asm/trap.S +++ b/risc_v/ch8/src/asm/trap.S @@ -24,7 +24,6 @@ fld f\i, ((NUM_GP_REGS+(\i))*REG_SIZE)(\basereg) .endm - .section .text .global m_trap_vector # This must be aligned by 4 since the last two bits @@ -69,8 +68,8 @@ m_trap_vector: csrr a2, mcause csrr a3, mhartid csrr a4, mstatus - mv a5, t5 - ld sp, 520(a5) + la t0, KERNEL_STACK_END + ld sp, 0(t0) call m_trap # When we get here, we've returned from m_trap, restore registers @@ -109,6 +108,8 @@ switch_to_user: csrw mstatus, t0 csrw mepc, a1 csrw satp, a2 + li t1, 0xaaa + csrw mie, t1 # This fence forces the MMU to flush the TLB. However, since # we're using the PID as the address space identifier, we might # only need this when we create a process. Right now, this ensures diff --git a/risc_v/ch8/src/lib.rs b/risc_v/ch8/src/lib.rs index 9cf219e..df21ec1 100755 --- a/risc_v/ch8/src/lib.rs +++ b/risc_v/ch8/src/lib.rs @@ -140,6 +140,12 @@ extern "C" fn kinit() -> usize { println!("Getting ready for first process."); println!("Issuing the first context-switch timer."); unsafe { + cpu::mscratch_write( + (&mut cpu::KERNEL_TRAP_FRAME[0] + as *mut cpu::TrapFrame) + as usize, + ); + cpu::KERNEL_TRAP_FRAME[0].hartid = 0; let mtimecmp = 0x0200_4000 as *mut u64; let mtime = 0x0200_bff8 as *const u64; // The frequency given by QEMU is 10_000_000 Hz, so this sets diff --git a/risc_v/ch8/src/process.rs b/risc_v/ch8/src/process.rs index d0d5adf..c747c4f 100644 --- a/risc_v/ch8/src/process.rs +++ b/risc_v/ch8/src/process.rs @@ -26,7 +26,7 @@ const STACK_PAGES: usize = 2; // regardless of where it is on the kernel heap. const STACK_ADDR: usize = 0xf_0000_0000; // All processes will have a defined starting point in virtual memory. -const PROCESS_STARTING_ADDR: usize = 0x2000_0000; +const PROCESS_STARTING_ADDR: usize = 0x8000_0000; // Here, we store a process list. It uses the global allocator // that we made before and its job is to store all processes. @@ -94,6 +94,7 @@ pub fn init() -> usize { // the address, and then move it right back in. let pl = PROCESS_LIST.take().unwrap(); let p = pl.front().unwrap().frame; + let func_vaddr = pl.front().unwrap().program_counter; let frame = &p as *const TrapFrame as usize; mscratch_write(frame); satp_write(build_satp( @@ -107,7 +108,7 @@ pub fn init() -> usize { PROCESS_LIST.replace(pl); // Return the first instruction's address to execute. // Since we use the MMU, all start here. - PROCESS_STARTING_ADDR + func_vaddr } } @@ -163,13 +164,15 @@ impl Process { } pub fn new_default(func: fn()) -> Self { let func_addr = func as usize; + let func_vaddr = func_addr; //- 0x6000_0000; + // println!("func_addr = {:x} -> {:x}", func_addr, func_vaddr); // We will convert NEXT_PID below into an atomic increment when // we start getting into multi-hart processing. For now, we want // a process. Get it to work, then improve it! let mut ret_proc = Process { frame: TrapFrame::zero(), stack: alloc(STACK_PAGES), - program_counter: PROCESS_STARTING_ADDR, + program_counter: func_vaddr, pid: unsafe { NEXT_PID }, root: zalloc(1) as *mut Table, state: ProcessState::Waiting, @@ -207,21 +210,17 @@ impl Process { 0, ); } - // Map the program counter on the MMU - map( - pt, - PROCESS_STARTING_ADDR, - func_addr, - EntryBits::UserReadExecute.val(), - 0, - ); - map( - pt, - PROCESS_STARTING_ADDR + 0x1001, - func_addr + 0x1001, - EntryBits::UserReadExecute.val(), - 0, - ); + // Map the program counter on the MMU and other bits + for i in 0..=100 { + let modifier = i * 0x1000; + map( + pt, + func_vaddr + modifier, + func_addr + modifier, + EntryBits::UserReadWriteExecute.val(), + 0, + ); + } ret_proc } } diff --git a/risc_v/ch8/src/trap.rs b/risc_v/ch8/src/trap.rs index 4c083a7..a74c9cc 100755 --- a/risc_v/ch8/src/trap.rs +++ b/risc_v/ch8/src/trap.rs @@ -118,6 +118,7 @@ extern "C" fn m_trap(epc: usize, 2 => { // Illegal instruction panic!("Illegal instruction CPU#{} -> 0x{:08x}: 0x{:08x}\n", hart, epc, tval); + while true {} }, 8 => { // Environment (system) call from User mode @@ -137,16 +138,19 @@ extern "C" fn m_trap(epc: usize, 12 => { // Instruction page fault println!("Instruction page fault CPU#{} -> 0x{:08x}: 0x{:08x}", hart, epc, tval); + while true {} return_pc += 4; }, 13 => { // Load page fault println!("Load page fault CPU#{} -> 0x{:08x}: 0x{:08x}", hart, epc, tval); + while true {} return_pc += 4; }, 15 => { // Store page fault println!("Store page fault CPU#{} -> 0x{:08x}: 0x{:08x}", hart, epc, tval); + while true {} return_pc += 4; }, _ => {