feat: add trampoline definition

This commit is contained in:
Paul Pan 2023-09-23 20:30:01 +08:00
parent 2252edf228
commit f86b061470
10 changed files with 323 additions and 3 deletions

17
Cargo.lock generated
View File

@ -14,6 +14,15 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
dependencies = [
"spin",
]
[[package]]
name = "log"
version = "0.4.20"
@ -53,6 +62,12 @@ dependencies = [
"static_assertions",
]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "static_assertions"
version = "1.1.0"
@ -63,8 +78,10 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
name = "tiny_os"
version = "0.1.0"
dependencies = [
"lazy_static",
"log",
"sbi-rt",
"static_assertions",
"uart_16550",
]

View File

@ -8,6 +8,7 @@ edition = "2021"
[features]
default = ["arch_riscv64", "board_virt"]
arch_riscv64 = []
arch_riscv32 = []
arch_arm = []
arch_x86 = []
board_default = []
@ -21,6 +22,8 @@ panic = "abort"
panic = "abort"
[dependencies]
sbi-rt = { version = "0.0.2", features = ["legacy"] }
uart_16550 = "0.3"
lazy_static = { version = "1.4.0", features = ["spin_no_std"] }
log = "0.4"
sbi-rt = { version = "0.0.2", features = ["legacy"] }
static_assertions = "1.1.0"
uart_16550 = "0.3"

View File

@ -8,12 +8,13 @@ fn main() {
const TARGET_CONFIGURATIONS: &[TargetConfiguration] = &[TargetConfiguration {
target: "riscv64",
lds: "src/arch/riscv/boot/linker64.ld",
lds: "src/arch/riscv/linker64.ld",
}];
let target = std::env::var("TARGET").unwrap();
for cfg in TARGET_CONFIGURATIONS {
if target.starts_with(cfg.target) {
println!("cargo:rerun-if-changed={}", cfg.lds);
println!("cargo:rustc-link-arg=-T{}", cfg.lds);
return;
}

123
src/arch/riscv/asm/trap32.S Normal file
View File

@ -0,0 +1,123 @@
.section .trampoline_section
.global trampoline
trampoline:
.align 4
.global __user2kernel
__user2kernel:
# load trapframe
csrw sscratch, a0 # save a0, will be saved later
li a0, {TRAPFRAME} # TRAPFRAME will be mapped to the same virtual address
# save GPRs
sd ra, 0(a0)
sd sp, 4(a0)
sd gp, 8(a0)
sd tp, 12(a0)
sd t0, 16(a0)
sd t1, 20(a0)
sd t2, 24(a0)
sd s0, 28(a0)
sd s1, 32(a0)
#sd a0, 36(a0)
sd a1, 40(a0)
sd a2, 44(a0)
sd a3, 48(a0)
sd a4, 52(a0)
sd a5, 56(a0)
sd a6, 60(a0)
sd a7, 64(a0)
sd s2, 68(a0)
sd s3, 72(a0)
sd s4, 76(a0)
sd s5, 80(a0)
sd s6, 84(a0)
sd s7, 88(a0)
sd s8, 92(a0)
sd s9, 96(a0)
sd s10, 100(a0)
sd s11, 104(a0)
sd t3, 108(a0)
sd t4, 112(a0)
sd t5, 116(a0)
sd t6, 120(a0)
# save a0
csrr t0, sscratch
sd t0, 36(a0)
# save user epc / sstatus
csrr t0, sepc
csrr t1, sstatus
sd t0, 124(a0)
sd t1, 128(a0)
# restore kernel env
ld sp, 132(a0) # kernel sp
ld tp, 136(a0) # kernel tp
ld t0, 140(a0) # trap handler
ld t1, 144(a0) # page table
# load kernel page table
sfence.vma zero, zero
csrw satp, t1
sfence.vma zero, zero
# jump to trap handler
jr t0
.global __kernel2user
__kernel2user:
# restore user page table (a0)
sfence.vma zero, zero
csrw satp, a0
sfence.vma zero, zero
li a0, {TRAPFRAME}
# restore user epc / sstatus
ld t0, 124(a0)
ld t1, 128(a0)
csrw sepc, t0
csrw sstatus, t1
# restore GPRs
ld ra, 0(a0)
ld sp, 4(a0)
ld gp, 8(a0)
ld tp, 12(a0)
ld t0, 16(a0)
ld t1, 20(a0)
ld t2, 24(a0)
ld s0, 28(a0)
ld s1, 32(a0)
#ld a0, 36(a0)
ld a1, 40(a0)
ld a2, 44(a0)
ld a3, 48(a0)
ld a4, 52(a0)
ld a5, 56(a0)
ld a6, 60(a0)
ld a7, 64(a0)
ld s2, 68(a0)
ld s3, 72(a0)
ld s4, 76(a0)
ld s5, 80(a0)
ld s6, 84(a0)
ld s7, 88(a0)
ld s8, 92(a0)
ld s9, 96(a0)
ld s10, 100(a0)
ld s11, 104(a0)
ld t3, 108(a0)
ld t4, 112(a0)
ld t5, 116(a0)
ld t6, 120(a0)
ld a0, 36(a0)
# go back to usermode
sret
# vim:set ts=8 noexpandtab:

123
src/arch/riscv/asm/trap64.S Normal file
View File

@ -0,0 +1,123 @@
.section .trampoline_section
.global trampoline
trampoline:
.align 4
.global __user2kernel
__user2kernel:
# load trapframe
csrw sscratch, a0 # save a0, will be saved later
li a0, {TRAPFRAME} # TRAPFRAME will be mapped to the same virtual address
# save GPRs
sd ra, 0(a0)
sd sp, 8(a0)
sd gp, 16(a0)
sd tp, 24(a0)
sd t0, 32(a0)
sd t1, 40(a0)
sd t2, 48(a0)
sd s0, 56(a0)
sd s1, 64(a0)
#sd a0, 72(a0)
sd a1, 80(a0)
sd a2, 88(a0)
sd a3, 96(a0)
sd a4, 104(a0)
sd a5, 112(a0)
sd a6, 120(a0)
sd a7, 128(a0)
sd s2, 136(a0)
sd s3, 144(a0)
sd s4, 152(a0)
sd s5, 160(a0)
sd s6, 168(a0)
sd s7, 176(a0)
sd s8, 184(a0)
sd s9, 192(a0)
sd s10, 200(a0)
sd s11, 208(a0)
sd t3, 216(a0)
sd t4, 224(a0)
sd t5, 232(a0)
sd t6, 240(a0)
# save a0
csrr t0, sscratch
sd t0, 72(a0)
# save user epc / sstatus
csrr t0, sepc
csrr t1, sstatus
sd t0, 248(a0)
sd t1, 256(a0)
# restore kernel env
ld sp, 264(a0) # kernel sp
ld tp, 272(a0) # kernel tp
ld t0, 280(a0) # trap handler
ld t1, 288(a0) # page table
# load kernel page table
sfence.vma zero, zero
csrw satp, t1
sfence.vma zero, zero
# jump to trap handler
jr t0
.global __kernel2user
__kernel2user:
# restore user page table (a0)
sfence.vma zero, zero
csrw satp, a0
sfence.vma zero, zero
li a0, {TRAPFRAME}
# restore user epc / sstatus
ld t0, 248(a0)
ld t1, 256(a0)
csrw sepc, t0
csrw sstatus, t1
# restore GPRs
ld ra, 0(a0)
ld sp, 8(a0)
ld gp, 16(a0)
ld tp, 24(a0)
ld t0, 32(a0)
ld t1, 40(a0)
ld t2, 48(a0)
ld s0, 56(a0)
ld s1, 64(a0)
#ld a0, 72(a0)
ld a1, 80(a0)
ld a2, 88(a0)
ld a3, 96(a0)
ld a4, 104(a0)
ld a5, 112(a0)
ld a6, 120(a0)
ld a7, 128(a0)
ld s2, 136(a0)
ld s3, 144(a0)
ld s4, 152(a0)
ld s5, 160(a0)
ld s6, 168(a0)
ld s7, 176(a0)
ld s8, 184(a0)
ld s9, 192(a0)
ld s10, 200(a0)
ld s11, 208(a0)
ld t3, 216(a0)
ld t4, 224(a0)
ld t5, 232(a0)
ld t6, 240(a0)
ld a0, 72(a0)
# go back to usermode
sret
# vim:set ts=8 noexpandtab:

2
src/arch/riscv/layout.rs Normal file
View File

@ -0,0 +1,2 @@
// TODO: currently a dummy value, figure out our memory layout
pub const TRAPFRAME: usize = 0x8000_0000;

View File

@ -14,6 +14,15 @@ SECTIONS {
__text_start = .;
*(.text.entry)
*(.text .text.*)
. = ALIGN(0x1000);
__trampoline_start = .;
*(.trampoline_section)
. = ALIGN(0x1000);
__trampoline_end = .;
ASSERT(__trampoline_end - __trampoline_start == 0x1000, "trampoline larger than one page");
__text_end = .;
} > DRAM

View File

@ -2,6 +2,9 @@
#[path = "board/virt/mod.rs"]
mod board;
mod layout;
pub mod entry;
pub mod io;
pub mod lowlevel;
pub mod trap;

37
src/arch/riscv/trap.rs Normal file
View File

@ -0,0 +1,37 @@
use lazy_static::lazy_static;
#[cfg(feature = "arch_riscv64")]
core::arch::global_asm!(
include_str!("./asm/trap64.S"),
TRAPFRAME = const super::layout::TRAPFRAME
);
#[cfg(feature = "arch_riscv32")]
core::arch::global_asm!(
include_str!("./asm/trap32.S"),
TRAPFRAME = const super::layout::TRAPFRAME
);
extern "C" {
pub fn __user2kernel();
pub fn __kernel2user(ctx: *mut TrapContext);
}
// TODO: remove this when we have a real context switch
lazy_static! {
pub static ref __DUMMY: usize = unsafe {
__user2kernel();
__kernel2user(core::ptr::null_mut());
42
};
}
#[repr(C)]
pub struct TrapContext {
pub gprs: [usize; 31], // GPRs exclude zero
pub user_sepc: usize, // 248/124 user program counter
pub user_sstatus: usize, // 256/128 user status register
pub kernel_sp: usize, // 264/132 kernel stack pointer
pub kernel_tp: usize, // 272/136 kernel tp
pub kernel_trap: usize, // 280/140 kernel trap handler
pub kernel_satp: usize, // 288/144 kernel page table
}

View File

@ -5,6 +5,8 @@
#![feature(fmt_internals)]
#![feature(stmt_expr_attributes)]
extern crate static_assertions;
// arch
pub mod arch;