fix riscv syscall ABI. fix store user tp and kernel hartid

master
WangRunji 6 years ago
parent a4c1d1231b
commit b8460e20d8

@ -15,18 +15,18 @@
# the kernel stack pointer. If we came from the kernel, sscratch # the kernel stack pointer. If we came from the kernel, sscratch
# will contain 0, and we should continue on the current stack. # will contain 0, and we should continue on the current stack.
csrrw sp, (xscratch), sp csrrw sp, (xscratch), sp
bnez sp, _save_context bnez sp, trap_from_user
_restore_kernel_sp: trap_from_kernel:
csrr sp, (xscratch) csrr sp, (xscratch)
STORE gp, 0
# sscratch = previous-sp, sp = kernel-sp # sscratch = previous-sp, sp = kernel-sp
_save_context: trap_from_user:
# provide room for trap frame # provide room for trap frame
addi sp, sp, -36 * XLENB addi sp, sp, -36 * XLENB
# save x registers except x2 (sp) # save x registers except x2 (sp)
STORE x1, 1 STORE x1, 1
STORE x3, 3 STORE x3, 3
# tp(x4) = hartid. DON'T change. STORE x4, 4
# STORE x4, 4
STORE x5, 5 STORE x5, 5
STORE x6, 6 STORE x6, 6
STORE x7, 7 STORE x7, 7
@ -55,6 +55,9 @@ _save_context:
STORE x30, 30 STORE x30, 30
STORE x31, 31 STORE x31, 31
# load hartid to gp from sp[36]
LOAD gp, 36
# get sp, sstatus, sepc, stval, scause # get sp, sstatus, sepc, stval, scause
# set sscratch = 0 # set sscratch = 0
csrrw s0, (xscratch), x0 csrrw s0, (xscratch), x0
@ -74,11 +77,12 @@ _save_context:
LOAD s1, 32 # s1 = sstatus LOAD s1, 32 # s1 = sstatus
LOAD s2, 33 # s2 = sepc LOAD s2, 33 # s2 = sepc
TEST_BACK_TO_KERNEL TEST_BACK_TO_KERNEL
bnez s0, _restore_context # s0 = back to kernel? bnez s0, _to_kernel # s0 = back to kernel?
_save_kernel_sp: _to_user:
addi s0, sp, 36*XLENB addi s0, sp, 36*XLENB
csrw (xscratch), s0 # sscratch = kernel-sp csrw (xscratch), s0 # sscratch = kernel-sp
_restore_context: STORE gp, 36 # store hartid from gp to sp[36]
_to_kernel:
# restore sstatus, sepc # restore sstatus, sepc
csrw (xstatus), s1 csrw (xstatus), s1
csrw (xepc), s2 csrw (xepc), s2
@ -86,7 +90,7 @@ _restore_context:
# restore x registers except x2 (sp) # restore x registers except x2 (sp)
LOAD x1, 1 LOAD x1, 1
LOAD x3, 3 LOAD x3, 3
# LOAD x4, 4 LOAD x4, 4
LOAD x5, 5 LOAD x5, 5
LOAD x6, 6 LOAD x6, 6
LOAD x7, 7 LOAD x7, 7
@ -119,13 +123,13 @@ _restore_context:
.endm .endm
.section .text .section .text
.globl __alltraps .globl trap_entry
__alltraps: trap_entry:
SAVE_ALL SAVE_ALL
mv a0, sp mv a0, sp
jal rust_trap jal rust_trap
.globl __trapret .globl trap_return
__trapret: trap_return:
RESTORE_ALL RESTORE_ALL
# return from supervisor call # return from supervisor call
XRET XRET

@ -19,6 +19,7 @@ pub struct TrapFrame {
pub sepc: usize, // Supervisor exception program counter, save the trap virtual address (here is used to save the process program entry addr?) pub sepc: usize, // Supervisor exception program counter, save the trap virtual address (here is used to save the process program entry addr?)
pub stval: usize, // Supervisor trap value pub stval: usize, // Supervisor trap value
pub scause: Mcause, // scause register: record the cause of exception/interrupt/trap pub scause: Mcause, // scause register: record the cause of exception/interrupt/trap
pub _hartid: usize, // reserve space
} }
/// Generate the trapframe for building new thread in kernel /// Generate the trapframe for building new thread in kernel
@ -123,7 +124,7 @@ impl InitStack {
} }
extern { extern {
fn __trapret(); fn trap_return();
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -137,7 +138,7 @@ struct ContextData {
impl ContextData { impl ContextData {
fn new(satp: usize) -> Self { fn new(satp: usize) -> Self {
// satp(asid) just like cr3, save the physical address for Page directory? // satp(asid) just like cr3, save the physical address for Page directory?
ContextData { ra: __trapret as usize, satp, ..ContextData::default() } ContextData { ra: trap_return as usize, satp, ..ContextData::default() }
} }
} }

@ -4,13 +4,13 @@ use core::ptr::{read_volatile, write_volatile};
static mut STARTED: [bool; MAX_CPU_NUM] = [false; MAX_CPU_NUM]; static mut STARTED: [bool; MAX_CPU_NUM] = [false; MAX_CPU_NUM];
pub unsafe fn set_cpu_id(cpu_id: usize) { pub unsafe fn set_cpu_id(cpu_id: usize) {
asm!("mv tp, $0" : : "r"(cpu_id)); asm!("mv gp, $0" : : "r"(cpu_id));
} }
pub fn id() -> usize { pub fn id() -> usize {
let cpu_id; let cpu_id;
#[cfg(not(feature = "m_mode"))] #[cfg(not(feature = "m_mode"))]
unsafe { asm!("mv $0, tp" : "=r"(cpu_id)); } unsafe { asm!("mv $0, gp" : "=r"(cpu_id)); }
#[cfg(feature = "m_mode")] #[cfg(feature = "m_mode")]
unsafe { asm!("csrr $0, mhartid" : "=r"(cpu_id)); } unsafe { asm!("csrr $0, mhartid" : "=r"(cpu_id)); }
cpu_id cpu_id

@ -24,14 +24,14 @@ mod context;
*/ */
pub fn init() { pub fn init() {
extern { extern {
fn __alltraps(); fn trap_entry();
} }
unsafe { unsafe {
// Set sscratch register to 0, indicating to exception vector that we are // Set sscratch register to 0, indicating to exception vector that we are
// presently executing in the kernel // presently executing in the kernel
xscratch::write(0); xscratch::write(0);
// Set the exception vector address // Set the exception vector address
xtvec::write(__alltraps as usize, xtvec::TrapMode::Direct); xtvec::write(trap_entry as usize, xtvec::TrapMode::Direct);
// Enable IPI // Enable IPI
sie::set_ssoft(); sie::set_ssoft();
// Enable serial interrupt // Enable serial interrupt
@ -168,7 +168,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.x[10], [tf.x[11], tf.x[12], tf.x[13], tf.x[14], tf.x[15], tf.x[16]], tf); let ret = crate::syscall::syscall(tf.x[17], [tf.x[10], tf.x[11], tf.x[12], tf.x[13], tf.x[14], tf.x[15]], tf);
tf.x[10] = ret as usize; tf.x[10] = ret as usize;
} }

@ -1 +1 @@
Subproject commit f0441d1fe30022acfadced2224b00ed9a29db455 Subproject commit 5ce1d2f7887b026ab5c5eb60f5aa4fb57390d349
Loading…
Cancel
Save