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

@ -40,7 +40,7 @@ pub unsafe fn enable() {
pub unsafe fn disable_and_store() -> usize {
let e = cp0::status::read_u32() & 1;
interrupts::disable();
e
e as usize
}
/// Enable interrupt if `flags` != 0
@ -116,7 +116,7 @@ fn timer() {
fn syscall(tf: &mut TrapFrame) {
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;
}

@ -50,7 +50,7 @@ impl PageTableExt for ActivePageTable {}
/// The virtual address of root page table
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;
impl ActivePageTable {

Loading…
Cancel
Save