1
0
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:
Stephen Marz 2020-03-10 14:55:26 -04:00
parent 2984472493
commit f2b1e2018a
7 changed files with 20 additions and 25 deletions

View File

@ -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

View File

@ -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

View File

@ -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,7 +45,7 @@ impl TrapFrame {
TrapFrame { regs: [0; 32],
fregs: [0; 32],
satp: 0,
trap_stack: null_mut(),
pc: 0,
hartid: 0, }
}
}

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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 {
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))