Initializes trap handler (#1013)
Some checks are pending
Development Build / Build (push) Waiting to run
Development Build / Update PRs (push) Waiting to run

This commit is contained in:
Putta Khunchalee 2024-10-04 03:02:43 +07:00 committed by GitHub
parent 40dd689596
commit b41b214c60
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 93 additions and 9 deletions

View File

@ -8,8 +8,7 @@ const LINUX_INCLUDE: &str = r#"
"#;
fn main() {
let core = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
let root = core.parent().unwrap();
let root = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
let mut conf = Config::default();
let mut buf = String::new();
@ -47,9 +46,9 @@ fn main() {
.insert("target_os = macos".into(), "__APPLE__".into());
Builder::new()
.with_crate(&core)
.with_crate(&root)
.with_config(conf)
.generate()
.unwrap()
.write_to_file(root.join("src").join("core.h"));
.write_to_file(root.join("core.h"));
}

View File

@ -37,15 +37,15 @@ pub unsafe fn activate(cx: *mut Context) {
}
pub unsafe fn thread() -> *const Thread {
// SAFETY: "AtomicPtr<Thread>" is guarantee to have the same bit as "*mut Thread" and "mov" is
// atomic if the memory has correct alignment.
// SAFETY: "mov" is atomic if the memory has correct alignment. We can use "nomem" here since
// the value never changed.
let mut td;
asm!(
"mov {out}, gs:[{off}]",
off = in(reg) offset_of!(Context, thread), // TODO: Use const from Rust 1.82.
out = out(reg) td,
options(pure, readonly, preserves_flags, nostack)
options(pure, nomem, preserves_flags, nostack)
);
td

View File

@ -22,6 +22,7 @@ mod malloc;
mod panic;
mod proc;
mod sched;
mod trap;
mod uma;
extern crate alloc;

View File

@ -0,0 +1,10 @@
/// Main entry point for interrupt.
///
/// This will be called by an inline assembly.
pub extern "C" fn interrupt_handler(_: &mut TrapFrame) {
todo!()
}
/// Contains states of the interupted program.
#[repr(C)]
pub struct TrapFrame {}

6
kernel/src/trap/mod.rs Normal file
View File

@ -0,0 +1,6 @@
pub use self::arch::*;
#[cfg_attr(target_arch = "aarch64", path = "aarch64.rs")]
#[cfg_attr(target_arch = "x86_64", path = "x86_64.rs")]
mod arch;
mod vm;

14
kernel/src/trap/vm.rs Normal file
View File

@ -0,0 +1,14 @@
use super::TrapFrame;
use core::hint::unreachable_unchecked;
use core::ptr::{addr_of_mut, write_volatile};
use obconf::{KernelExit, Vm, VmmMemory};
/// # Interupt safety
/// This function can be called from interupt handler.
pub fn interrupt_handler(env: &Vm, _: &mut TrapFrame) {
// TODO: Implement a virtual device with GDB stub.
let vmm = env.vmm as *mut VmmMemory;
unsafe { write_volatile(addr_of_mut!((*vmm).shutdown), KernelExit::Panic) };
unsafe { unreachable_unchecked() };
}

46
kernel/src/trap/x86_64.rs Normal file
View File

@ -0,0 +1,46 @@
use crate::config::boot_env;
use obconf::BootEnv;
/// Main entry point for interrupt.
///
/// This will be called by an inline assembly.
///
/// See `trap` function on the PS4 for a reference.
pub extern "C" fn interrupt_handler(frame: &mut TrapFrame) {
match frame.num {
TrapNo::Breakpoint => match boot_env() {
BootEnv::Vm(vm) => super::vm::interrupt_handler(vm, frame),
},
}
}
/// Predefined interrupt vector number.
#[allow(dead_code)] // Used by inline assembly.
#[repr(u32)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum TrapNo {
Breakpoint = 3, // T_BPTFLT
}
/// Contains states of the interupted program.
#[repr(C)]
pub struct TrapFrame {
pub rdi: usize, // tf_rdi
pub rsi: usize, // tf_rsi
pub rdx: usize, // tf_rdx
pub rcx: usize, // tf_rcx
pub r8: usize, // tf_r8
pub r9: usize, // tf_r9
pub rax: usize, // tf_rax
pub rbx: usize, // tf_rbx
pub rbp: usize, // tf_rbp
pub r10: usize, // tf_r10
pub r11: usize, // tf_r11
pub r12: usize, // tf_r12
pub r13: usize, // tf_r13
pub r14: usize, // tf_r14
pub r15: usize, // tf_r15
pub num: TrapNo, // tf_trapno
pub fs: u16, // tf_fs
pub gs: u16, // tf_gs
}

View File

@ -1,3 +1,4 @@
use crate::trap::interrupt_handler;
use bitfield_struct::bitfield;
use core::arch::{asm, global_asm};
use core::mem::{transmute, zeroed};
@ -32,7 +33,7 @@ pub unsafe fn setup_main_cpu() {
static mut TSS_RSP0: [u8; 1024 * 128] = unsafe { zeroed() };
static mut TSS: Tss = unsafe { zeroed() };
TSS.rsp0 = TSS_RSP0.as_mut_ptr() as _;
TSS.rsp0 = TSS_RSP0.as_mut_ptr().add(TSS_RSP0.len()) as _; // Top-down.
// Setup TSS descriptor.
let tss: &'static mut TssDescriptor = transmute(&mut GDT[4]);
@ -120,7 +121,14 @@ global_asm!(
);
// See Xbpt on the PS4 for a reference.
global_asm!("Xbpt:", "ud2");
global_asm!(
"Xbpt:", // TODO: Check if coming from user-space.
"sub rsp, 0x80", // TODO: Use const from Rust 1.82.
"mov dword ptr [rsp+0x78], 3", // TODO: Use const from Rust 1.82.
"mov rdi, rsp",
"call {f}",
f = sym interrupt_handler
);
/// Raw value of a Global Descriptor-Table Register.
///