1
0
mirror of https://github.com/sgmarz/osblog.git synced 2024-11-24 02:16:19 +04:00

Split CTX switch time and frequency and also use build_satp for switching to user process

This commit is contained in:
Stephen Marz 2020-03-10 15:35:21 -04:00
parent f2b1e2018a
commit d44f729957
4 changed files with 22 additions and 13 deletions

View File

@ -30,7 +30,7 @@ _start:
# Any hardware threads (hart) that are not bootstrapping # Any hardware threads (hart) that are not bootstrapping
# need to wait for an IPI # need to wait for an IPI
csrr t0, mhartid csrr t0, mhartid
bnez t0, 4f bnez t0, 3f
# Set all bytes in the BSS section to zero. # Set all bytes in the BSS section to zero.
la a0, _bss_start la a0, _bss_start

View File

@ -4,8 +4,10 @@
// Stephen Marz // Stephen Marz
// 14 October 2019 // 14 October 2019
// Let's do this 3 times per second for switching // The frequency of QEMU is 10 MHz
pub const CONTEXT_SWITCH_TIME: u64 = 10_000_000 / 250; pub const FREQ: u64 = 10_000_000;
// Let's do this 250 times per second for switching
pub const CONTEXT_SWITCH_TIME: u64 = FREQ / 250;
/// In 64-bit mode, we're given three different modes for the MMU: /// 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 /// 0 - The MMU is off -- no protection and no translation PA = VA

View File

@ -145,7 +145,7 @@ extern "C" fn kinit() {
unsafe { unsafe {
let mtimecmp = 0x0200_4000 as *mut u64; let mtimecmp = 0x0200_4000 as *mut u64;
let mtime = 0x0200_bff8 as *const u64; let mtime = 0x0200_bff8 as *const u64;
mtimecmp.write_volatile(mtime.read_volatile().wrapping_add(10_000_000)); mtimecmp.write_volatile(mtime.read_volatile().wrapping_add(cpu::CONTEXT_SWITCH_TIME));
} }
let (frame, mepc, satp) = sched::schedule(); let (frame, mepc, satp) = sched::schedule();
unsafe { unsafe {

View File

@ -3,9 +3,10 @@
// Stephen Marz // Stephen Marz
// 27 Dec 2019 // 27 Dec 2019
use crate::{process::{ProcessState, PROCESS_LIST}}; use crate::{cpu::{build_satp, SatpMode},
process::{ProcessState, PROCESS_LIST}};
pub fn schedule() -> (usize, usize, usize) { pub fn schedule() -> (usize, usize, usize) {
unsafe { unsafe {
if let Some(mut pl) = PROCESS_LIST.take() { if let Some(mut pl) = PROCESS_LIST.take() {
pl.rotate_left(1); pl.rotate_left(1);
@ -19,12 +20,10 @@ pub fn schedule() -> (usize, usize, usize) {
frame_addr = frame_addr =
prc.get_frame_address(); prc.get_frame_address();
mepc = prc.get_program_counter(); mepc = prc.get_program_counter();
satp = prc.get_table_address() >> 12; satp = prc.get_table_address();
pid = prc.get_pid() as usize; pid = prc.get_pid() as usize;
}, },
ProcessState::Sleeping => { ProcessState::Sleeping => {},
},
_ => {}, _ => {},
} }
} }
@ -32,10 +31,18 @@ pub fn schedule() -> (usize, usize, usize) {
PROCESS_LIST.replace(pl); PROCESS_LIST.replace(pl);
if frame_addr != 0 { if frame_addr != 0 {
// MODE 8 is 39-bit virtual address MMU // MODE 8 is 39-bit virtual address MMU
// I'm using the PID as the address space identifier to hopefully // I'm using the PID as the address space
// help with (not?) flushing the TLB whenever we switch processes. // identifier to hopefully help with (not?)
// flushing the TLB whenever we switch
// processes.
if satp != 0 { if satp != 0 {
return (frame_addr, mepc, (8 << 60) | (pid << 44) | satp); return (frame_addr,
mepc,
build_satp(
SatpMode::Sv39,
pid,
satp,
));
} }
else { else {
return (frame_addr, mepc, 0); return (frame_addr, mepc, 0);