mirror of
https://github.com/sgmarz/osblog.git
synced 2024-11-24 02:16:19 +04:00
Moved PC to trap frame so we don't restart the function
This commit is contained in:
parent
2984472493
commit
f2b1e2018a
@ -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
|
||||
|
@ -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
|
||||
|
@ -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, }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user