mirror of
https://github.com/obhq/obliteration.git
synced 2024-10-07 00:13:24 +00:00
Initializes trap handler (#1013)
This commit is contained in:
parent
40dd689596
commit
b41b214c60
@ -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"));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -22,6 +22,7 @@ mod malloc;
|
||||
mod panic;
|
||||
mod proc;
|
||||
mod sched;
|
||||
mod trap;
|
||||
mod uma;
|
||||
|
||||
extern crate alloc;
|
||||
|
10
kernel/src/trap/aarch64.rs
Normal file
10
kernel/src/trap/aarch64.rs
Normal 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
6
kernel/src/trap/mod.rs
Normal 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
14
kernel/src/trap/vm.rs
Normal 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
46
kernel/src/trap/x86_64.rs
Normal 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
|
||||
}
|
@ -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.
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user