From f2b1e2018a7d071fff7e41ac41abe8225eef97b8 Mon Sep 17 00:00:00 2001 From: Stephen Marz Date: Tue, 10 Mar 2020 14:55:26 -0400 Subject: [PATCH] Moved PC to trap frame so we don't restart the function --- risc_v/ch9/src/asm/boot.S | 2 +- risc_v/ch9/src/asm/trap.S | 5 +++-- risc_v/ch9/src/cpu.rs | 9 +++++---- risc_v/ch9/src/lib.rs | 4 +--- risc_v/ch9/src/process.rs | 13 ++++++------- risc_v/ch9/src/sched.rs | 2 +- risc_v/ch9/src/trap.rs | 10 +++------- 7 files changed, 20 insertions(+), 25 deletions(-) diff --git a/risc_v/ch9/src/asm/boot.S b/risc_v/ch9/src/asm/boot.S index f910dcd..8abe463 100644 --- a/risc_v/ch9/src/asm/boot.S +++ b/risc_v/ch9/src/asm/boot.S @@ -30,7 +30,7 @@ _start: # Any hardware threads (hart) that are not bootstrapping # need to wait for an IPI csrr t0, mhartid - bnez t0, 3f + bnez t0, 4f # Set all bytes in the BSS section to zero. la a0, _bss_start diff --git a/risc_v/ch9/src/asm/trap.S b/risc_v/ch9/src/asm/trap.S index 88eee16..2afd566 100644 --- a/risc_v/ch9/src/asm/trap.S +++ b/risc_v/ch9/src/asm/trap.S @@ -57,12 +57,13 @@ m_trap_vector: # Restore the kernel trap frame into mscratch csrw mscratch, t5 - + # csrw mie, zero # Get ready to go into Rust (trap.rs) # We don't want to write into the user's stack or whomever # messed with us here. # csrw mie, zero csrr a0, mepc + sd a0, 520(t5) csrr a1, mtval csrr a2, mcause csrr a3, mhartid @@ -113,7 +114,7 @@ switch_to_user: # we're using the PID as the address space identifier, we might # only need this when we create a process. Right now, this ensures # correctness, however it isn't the most efficient. - sfence.vma + # sfence.vma # A0 is the context frame, so we need to reload it back # and mret so we can start running the program. mv t6, a0 diff --git a/risc_v/ch9/src/cpu.rs b/risc_v/ch9/src/cpu.rs index 31d2a62..55a676f 100755 --- a/risc_v/ch9/src/cpu.rs +++ b/risc_v/ch9/src/cpu.rs @@ -4,7 +4,8 @@ // Stephen Marz // 14 October 2019 -use core::ptr::null_mut; +// Let's do this 3 times per second for switching +pub const CONTEXT_SWITCH_TIME: u64 = 10_000_000 / 250; /// In 64-bit mode, we're given three different modes for the MMU: /// 0 - The MMU is off -- no protection and no translation PA = VA @@ -27,7 +28,7 @@ pub struct TrapFrame { pub regs: [usize; 32], // 0 - 255 pub fregs: [usize; 32], // 256 - 511 pub satp: usize, // 512 - 519 - pub trap_stack: *mut u8, // 520 + pub pc: usize, // 520 pub hartid: usize, // 528 } @@ -44,8 +45,8 @@ impl TrapFrame { TrapFrame { regs: [0; 32], fregs: [0; 32], satp: 0, - trap_stack: null_mut(), - hartid: 0, } + pc: 0, + hartid: 0, } } } diff --git a/risc_v/ch9/src/lib.rs b/risc_v/ch9/src/lib.rs index e691d5e..2b7672b 100755 --- a/risc_v/ch9/src/lib.rs +++ b/risc_v/ch9/src/lib.rs @@ -145,9 +145,7 @@ extern "C" fn kinit() { unsafe { 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 - // the next interrupt to fire one second from now. - mtimecmp.write_volatile(mtime.read_volatile() + 1_000_000); + mtimecmp.write_volatile(mtime.read_volatile().wrapping_add(10_000_000)); } let (frame, mepc, satp) = sched::schedule(); unsafe { diff --git a/risc_v/ch9/src/process.rs b/risc_v/ch9/src/process.rs index c91322a..fbd6f07 100644 --- a/risc_v/ch9/src/process.rs +++ b/risc_v/ch9/src/process.rs @@ -3,7 +3,7 @@ // Stephen Marz // 27 Nov 2019 -use crate::{cpu::TrapFrame, +use crate::{cpu::{TrapFrame, satp_fence_asid}, page::{alloc, dealloc, map, @@ -49,7 +49,7 @@ fn init_process() { let mut i: usize = 0; loop { i += 1; - if i > 70_000_000 { + if i > 100_000_000 { unsafe { make_syscall(1); } @@ -102,14 +102,13 @@ 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; println!("Init's frame is at 0x{:08x}", frame); // Put the process list back in the global. PROCESS_LIST.replace(pl); // Return the first instruction's address to execute. // Since we use the MMU, all start here. - func_vaddr + (*p).pc } } @@ -136,7 +135,6 @@ pub enum ProcessState { pub struct Process { frame: *mut TrapFrame, stack: *mut u8, - program_counter: usize, pid: u16, root: *mut Table, state: ProcessState, @@ -149,7 +147,7 @@ impl Process { self.frame as usize } pub fn get_program_counter(&self) -> usize { - self.program_counter + unsafe { (*self.frame).pc } } pub fn get_table_address(&self) -> usize { self.root as usize @@ -173,7 +171,6 @@ impl Process { let mut ret_proc = Process { frame: zalloc(1) as *mut TrapFrame, stack: alloc(STACK_PAGES), - program_counter: func_vaddr, pid: unsafe { NEXT_PID }, root: zalloc(1) as *mut Table, state: ProcessState::Running, @@ -181,6 +178,7 @@ impl Process { sleep_until: 0 }; unsafe { + satp_fence_asid(NEXT_PID as usize); NEXT_PID += 1; } // Now we move the stack pointer to the bottom of the @@ -193,6 +191,7 @@ impl Process { // bottom of the memory and far away from heap allocations. let saddr = ret_proc.stack as usize; unsafe { + (*ret_proc.frame).pc = func_vaddr; (*ret_proc.frame).regs[2] = STACK_ADDR + PAGE_SIZE * STACK_PAGES; } // Map the stack on the MMU diff --git a/risc_v/ch9/src/sched.rs b/risc_v/ch9/src/sched.rs index d0b3bbf..c53aa25 100755 --- a/risc_v/ch9/src/sched.rs +++ b/risc_v/ch9/src/sched.rs @@ -28,7 +28,7 @@ pub fn schedule() -> (usize, usize, usize) { _ => {}, } } - println!("Scheduling {}", pid); + // println!("Scheduling {}", pid); PROCESS_LIST.replace(pl); if frame_addr != 0 { // MODE 8 is 39-bit virtual address MMU diff --git a/risc_v/ch9/src/trap.rs b/risc_v/ch9/src/trap.rs index 5a3cd85..28110cb 100755 --- a/risc_v/ch9/src/trap.rs +++ b/risc_v/ch9/src/trap.rs @@ -3,7 +3,7 @@ // Stephen Marz // 10 October 2019 -use crate::cpu::TrapFrame; +use crate::cpu::{CONTEXT_SWITCH_TIME, TrapFrame}; use crate::{plic, uart}; use crate::syscall::do_syscall; use crate::sched::schedule; @@ -56,14 +56,10 @@ extern "C" fn m_trap(epc: usize, let (frame, mepc, satp) = schedule(); 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 - // the next interrupt to fire one second from now. // This is much too slow for normal operations, but it gives us // a visual of what's happening behind the scenes. - mtimecmp.write_volatile(mtime.read_volatile() + 10_000_000); - unsafe { - switch_to_user(frame, mepc, satp); - } + mtimecmp.write_volatile(mtime.read_volatile().wrapping_add(CONTEXT_SWITCH_TIME)); + switch_to_user(frame, mepc, satp); }, 11 => { // Machine external (interrupt from Platform Interrupt Controller (PLIC))