Add context.

master
Yuhao Zhou 6 years ago
parent 1fba79d26a
commit 53317e84c4

@ -1,52 +1,53 @@
use mips::registers; use mips::registers::cp0;
use crate::arch::paging::root_page_table_ptr;
/// Saved registers on a trap. /// Saved registers on a trap.
#[derive(Clone)] #[derive(Clone)]
#[repr(C)] #[repr(C)]
pub struct TrapFrame { pub struct TrapFrame {
/// CP0 status register /// CP0 status register
pub status: u32, pub status: cp0::status::Status,
/// CP0 cause register /// CP0 cause register
pub cause: u32, pub cause: cp0::cause::Cause,
/// CP0 EPC register /// CP0 EPC register
pub epc: u32, pub epc: usize,
/// CP0 vaddr register /// CP0 vaddr register
pub vaddr: u32, pub vaddr: usize,
/// HI/LO registers /// HI/LO registers
pub hi: u32, pub hi: usize,
pub lo: u32, pub lo: usize,
/// General registers /// General registers
pub at: u32, pub at: usize,
pub v0: u32, pub v0: usize,
pub v1: u32, pub v1: usize,
pub a0: u32, pub a0: usize,
pub a1: u32, pub a1: usize,
pub a2: u32, pub a2: usize,
pub a3: u32, pub a3: usize,
pub t0: u32, pub t0: usize,
pub t1: u32, pub t1: usize,
pub t2: u32, pub t2: usize,
pub t3: u32, pub t3: usize,
pub t4: u32, pub t4: usize,
pub t5: u32, pub t5: usize,
pub t6: u32, pub t6: usize,
pub t7: u32, pub t7: usize,
pub s0: u32, pub s0: usize,
pub s1: u32, pub s1: usize,
pub s2: u32, pub s2: usize,
pub s3: u32, pub s3: usize,
pub s4: u32, pub s4: usize,
pub s5: u32, pub s5: usize,
pub s6: u32, pub s6: usize,
pub s7: u32, pub s7: usize,
pub t8: u32, pub t8: usize,
pub t9: u32, pub t9: usize,
pub k0: u32, pub k0: usize,
pub k1: u32, pub k1: usize,
pub gp: u32, pub gp: usize,
pub sp: u32, pub sp: usize,
pub fp: u32, pub fp: usize,
pub ra: u32, pub ra: usize,
/// Reserve space for hartid /// Reserve space for hartid
pub _hartid: usize, pub _hartid: usize,
} }
@ -59,13 +60,13 @@ impl TrapFrame {
fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, sp: usize) -> Self { fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, sp: usize) -> Self {
use core::mem::zeroed; use core::mem::zeroed;
let mut tf: Self = unsafe { zeroed() }; let mut tf: Self = unsafe { zeroed() };
tf.x[10] = arg; // a0 tf.a0 = arg;
tf.x[2] = sp; tf.sp = sp;
tf.sepc = entry as usize; tf.epc = entry as usize;
tf.sstatus = sstatus::read(); tf.status = cp0::status::read();
tf.sstatus.set_spie(true); tf.status.set_kernel_mode();
tf.sstatus.set_sie(false); tf.status.set_ie();
tf.sstatus.set_spp(sstatus::SPP::Supervisor); tf.status.set_exl();
tf tf
} }
@ -76,12 +77,12 @@ impl TrapFrame {
fn new_user_thread(entry_addr: usize, sp: usize) -> Self { fn new_user_thread(entry_addr: usize, sp: usize) -> Self {
use core::mem::zeroed; use core::mem::zeroed;
let mut tf: Self = unsafe { zeroed() }; let mut tf: Self = unsafe { zeroed() };
tf.x[2] = sp; tf.sp = sp;
tf.sepc = entry_addr; tf.epc = entry_addr;
tf.sstatus = sstatus::read(); tf.status = cp0::status::read();
tf.sstatus.set_spie(true); tf.status.set_user_mode();
tf.sstatus.set_sie(false); tf.status.set_ie();
tf.sstatus.set_spp(sstatus::SPP::User); tf.status.set_exl();
tf tf
} }
} }
@ -89,23 +90,11 @@ impl TrapFrame {
use core::fmt::{Debug, Formatter, Error}; use core::fmt::{Debug, Formatter, Error};
impl Debug for TrapFrame { impl Debug for TrapFrame {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
struct Regs<'a>(&'a [usize; 32]);
impl<'a> Debug for Regs<'a> {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
const REG_NAME: [&str; 32] = [
"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2",
"s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
"s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
"t3", "t4", "t5", "t6"];
f.debug_map().entries(REG_NAME.iter().zip(self.0)).finish()
}
}
f.debug_struct("TrapFrame") f.debug_struct("TrapFrame")
.field("regs", &Regs(&self.x)) .field("status", &self.status.bits)
.field("sstatus", &self.sstatus) .field("epc", &self.epc.bits)
.field("sepc", &self.sepc) .field("cause", &self.cause.bits)
.field("stval", &self.stval) .field("vaddr", &self.vaddr.bits)
.field("scause", &self.scause.cause())
.finish() .finish()
} }
} }
@ -167,7 +156,6 @@ impl Context {
#[naked] #[naked]
#[inline(never)] #[inline(never)]
pub unsafe extern fn switch(&mut self, _target: &mut Self) { pub unsafe extern fn switch(&mut self, _target: &mut Self) {
#[cfg(target_arch = "riscv32")]
asm!(r" asm!(r"
.equ XLENB, 4 .equ XLENB, 4
.macro Load reg, mem .macro Load reg, mem
@ -176,15 +164,6 @@ impl Context {
.macro Store reg, mem .macro Store reg, mem
sw \reg, \mem sw \reg, \mem
.endm"); .endm");
#[cfg(target_arch = "riscv64")]
asm!(r"
.equ XLENB, 8
.macro Load reg, mem
ld \reg, \mem
.endm
.macro Store reg, mem
sd \reg, \mem
.endm");
asm!(" asm!("
// save from's registers // save from's registers
addi sp, sp, (-XLENB*14) addi sp, sp, (-XLENB*14)
@ -199,16 +178,16 @@ impl Context {
Store s6, 8*XLENB(sp) Store s6, 8*XLENB(sp)
Store s7, 9*XLENB(sp) Store s7, 9*XLENB(sp)
Store s8, 10*XLENB(sp) Store s8, 10*XLENB(sp)
Store s9, 11*XLENB(sp) Store gp, 11*XLENB(sp)
Store s10, 12*XLENB(sp) Store ra, 12*XLENB(sp)
Store s11, 13*XLENB(sp) Store sp, 13*XLENB(sp)
csrr s11, satp
Store s11, 1*XLENB(sp) Store $1, 1*XLENB(sp)
// restore to's registers // restore to's registers
Load sp, 0(a1) Load sp, 0(a1)
Load s11, 1*XLENB(sp) Load $0, 1*XLENB(sp)
csrw satp, s11
Load ra, 0*XLENB(sp) Load ra, 0*XLENB(sp)
Load s0, 2*XLENB(sp) Load s0, 2*XLENB(sp)
Load s1, 3*XLENB(sp) Load s1, 3*XLENB(sp)
@ -219,14 +198,15 @@ impl Context {
Load s6, 8*XLENB(sp) Load s6, 8*XLENB(sp)
Load s7, 9*XLENB(sp) Load s7, 9*XLENB(sp)
Load s8, 10*XLENB(sp) Load s8, 10*XLENB(sp)
Load s9, 11*XLENB(sp) Load gp, 11*XLENB(sp)
Load s10, 12*XLENB(sp) Load ra, 12*XLENB(sp)
Load s11, 13*XLENB(sp) Load sp, 13*XLENB(sp)
addi sp, sp, (XLENB*14) addi sp, sp, (XLENB*14)
Store zero, 0(a1) Store zero, 0(a1)
ret" jr ra
: : : : "volatile" ) nop"
:"=r"(root_page_table_ptr) :"r"(root_page_table_ptr) : : "volatile" )
} }
/// Constructs a null Context for the current running thread. /// Constructs a null Context for the current running thread.
@ -269,7 +249,7 @@ impl Context {
tf: { tf: {
let mut tf = tf.clone(); let mut tf = tf.clone();
// fork function's ret value, the new process is 0 // fork function's ret value, the new process is 0
tf.x[10] = 0; // a0 tf.a0 = 0;
tf tf
}, },
}.push_at(kstack_top) }.push_at(kstack_top)
@ -287,9 +267,9 @@ impl Context {
context: ContextData::new(satp), context: ContextData::new(satp),
tf: { tf: {
let mut tf = tf.clone(); let mut tf = tf.clone();
tf.x[2] = ustack_top; // sp tf.sp = ustack_top; // sp
tf.x[4] = tls; // tp tf.v1 = tls; // tp
tf.x[10] = 0; // a0 tf.a0 = 0; // a0
tf tf
}, },
}.push_at(kstack_top) }.push_at(kstack_top)

@ -40,7 +40,7 @@ pub unsafe fn enable() {
pub unsafe fn disable_and_store() -> usize { pub unsafe fn disable_and_store() -> usize {
let e = cp0::status::read_u32() & 1; let e = cp0::status::read_u32() & 1;
interrupts::disable(); interrupts::disable();
e e as usize
} }
/// Enable interrupt if `flags` != 0 /// Enable interrupt if `flags` != 0
@ -116,7 +116,7 @@ fn timer() {
fn syscall(tf: &mut TrapFrame) { fn syscall(tf: &mut TrapFrame) {
tf.sepc += 4; // Must before syscall, because of fork. tf.sepc += 4; // Must before syscall, because of fork.
let ret = crate::syscall::syscall(tf.t0, [tf.x0, tf.x1, tf.x2, tf.x3, tf.s0, tf.s1], tf); let ret = crate::syscall::syscall(tf.t0, [tf.t0, tf.t1, tf.t2, tf.t3, tf.s0, tf.s1], tf);
tf.v0 = ret as usize; tf.v0 = ret as usize;
} }

@ -50,7 +50,7 @@ impl PageTableExt for ActivePageTable {}
/// The virtual address of root page table /// The virtual address of root page table
static ROOT_PAGE_TABLE_BUFFER: MIPSPageTable = ::core::mem::uninitialized(); static ROOT_PAGE_TABLE_BUFFER: MIPSPageTable = ::core::mem::uninitialized();
static mut root_page_table_ptr: usize = pub static mut root_page_table_ptr: usize =
&ROOT_PAGE_TABLE_BUFFER as *const MIPSPageTable as usize; &ROOT_PAGE_TABLE_BUFFER as *const MIPSPageTable as usize;
impl ActivePageTable { impl ActivePageTable {

Loading…
Cancel
Save