diff --git a/src/arch/mod.rs b/src/arch/mod.rs new file mode 100644 index 0000000..0bffdbe --- /dev/null +++ b/src/arch/mod.rs @@ -0,0 +1 @@ +pub mod x86_64; \ No newline at end of file diff --git a/src/device/cpu.rs b/src/arch/x86_64/device/cpu.rs similarity index 100% rename from src/device/cpu.rs rename to src/arch/x86_64/device/cpu.rs diff --git a/src/device/hpet.rs b/src/arch/x86_64/device/hpet.rs similarity index 100% rename from src/device/hpet.rs rename to src/arch/x86_64/device/hpet.rs diff --git a/src/device/local_apic.rs b/src/arch/x86_64/device/local_apic.rs similarity index 100% rename from src/device/local_apic.rs rename to src/arch/x86_64/device/local_apic.rs diff --git a/src/device/mod.rs b/src/arch/x86_64/device/mod.rs similarity index 100% rename from src/device/mod.rs rename to src/arch/x86_64/device/mod.rs diff --git a/src/device/pic.rs b/src/arch/x86_64/device/pic.rs similarity index 100% rename from src/device/pic.rs rename to src/arch/x86_64/device/pic.rs diff --git a/src/device/pit.rs b/src/arch/x86_64/device/pit.rs similarity index 100% rename from src/device/pit.rs rename to src/arch/x86_64/device/pit.rs diff --git a/src/device/rtc.rs b/src/arch/x86_64/device/rtc.rs similarity index 100% rename from src/device/rtc.rs rename to src/arch/x86_64/device/rtc.rs diff --git a/src/device/serial.rs b/src/arch/x86_64/device/serial.rs similarity index 100% rename from src/device/serial.rs rename to src/arch/x86_64/device/serial.rs diff --git a/src/gdt.rs b/src/arch/x86_64/gdt.rs similarity index 100% rename from src/gdt.rs rename to src/arch/x86_64/gdt.rs diff --git a/src/idt.rs b/src/arch/x86_64/idt.rs similarity index 100% rename from src/idt.rs rename to src/arch/x86_64/idt.rs diff --git a/src/interrupt/exception.rs b/src/arch/x86_64/interrupt/exception.rs similarity index 100% rename from src/interrupt/exception.rs rename to src/arch/x86_64/interrupt/exception.rs diff --git a/src/interrupt/ipi.rs b/src/arch/x86_64/interrupt/ipi.rs similarity index 100% rename from src/interrupt/ipi.rs rename to src/arch/x86_64/interrupt/ipi.rs diff --git a/src/interrupt/irq.rs b/src/arch/x86_64/interrupt/irq.rs similarity index 100% rename from src/interrupt/irq.rs rename to src/arch/x86_64/interrupt/irq.rs diff --git a/src/interrupt/mod.rs b/src/arch/x86_64/interrupt/mod.rs similarity index 100% rename from src/interrupt/mod.rs rename to src/arch/x86_64/interrupt/mod.rs diff --git a/src/interrupt/syscall.rs b/src/arch/x86_64/interrupt/syscall.rs similarity index 100% rename from src/interrupt/syscall.rs rename to src/arch/x86_64/interrupt/syscall.rs diff --git a/src/interrupt/trace.rs b/src/arch/x86_64/interrupt/trace.rs similarity index 100% rename from src/interrupt/trace.rs rename to src/arch/x86_64/interrupt/trace.rs diff --git a/src/arch/x86_64/macros.rs b/src/arch/x86_64/macros.rs new file mode 100644 index 0000000..ab75124 --- /dev/null +++ b/src/arch/x86_64/macros.rs @@ -0,0 +1,181 @@ +/// Create an interrupt function that can safely run rust code +#[macro_export] +macro_rules! interrupt { + ($name:ident, $func:block) => { + #[naked] + pub unsafe extern fn $name () { + #[inline(never)] + unsafe fn inner() { + $func + } + + // Push scratch registers + asm!("push rax + push rcx + push rdx + push rdi + push rsi + push r8 + push r9 + push r10 + push r11 + push fs + mov rax, 0x18 + mov fs, ax" + : : : : "intel", "volatile"); + + // Call inner rust function + inner(); + + // Pop scratch registers and return + asm!("pop fs + pop r11 + pop r10 + pop r9 + pop r8 + pop rsi + pop rdi + pop rdx + pop rcx + pop rax + iretq" + : : : : "intel", "volatile"); + } + }; +} + +#[allow(dead_code)] +#[repr(packed)] +pub struct InterruptStack { + pub fs: usize, + pub r11: usize, + pub r10: usize, + pub r9: usize, + pub r8: usize, + pub rsi: usize, + pub rdi: usize, + pub rdx: usize, + pub rcx: usize, + pub rax: usize, + pub rip: usize, + pub cs: usize, + pub rflags: usize, +} + +#[macro_export] +macro_rules! interrupt_stack { + ($name:ident, $stack: ident, $func:block) => { + #[naked] + pub unsafe extern fn $name () { + #[inline(never)] + unsafe fn inner($stack: &mut $crate::arch::x86_64::macros::InterruptStack) { + $func + } + + // Push scratch registers + asm!("push rax + push rcx + push rdx + push rdi + push rsi + push r8 + push r9 + push r10 + push r11 + push fs + mov rax, 0x18 + mov fs, ax" + : : : : "intel", "volatile"); + + // Get reference to stack variables + let rsp: usize; + asm!("" : "={rsp}"(rsp) : : : "intel", "volatile"); + + // Call inner rust function + inner(&mut *(rsp as *mut $crate::arch::x86_64::macros::InterruptStack)); + + // Pop scratch registers and return + asm!("pop fs + pop r11 + pop r10 + pop r9 + pop r8 + pop rsi + pop rdi + pop rdx + pop rcx + pop rax + iretq" + : : : : "intel", "volatile"); + } + }; +} + +#[allow(dead_code)] +#[repr(packed)] +pub struct InterruptErrorStack { + pub fs: usize, + pub r11: usize, + pub r10: usize, + pub r9: usize, + pub r8: usize, + pub rsi: usize, + pub rdi: usize, + pub rdx: usize, + pub rcx: usize, + pub rax: usize, + pub code: usize, + pub rip: usize, + pub cs: usize, + pub rflags: usize, +} + +#[macro_export] +macro_rules! interrupt_error { + ($name:ident, $stack:ident, $func:block) => { + #[naked] + pub unsafe extern fn $name () { + #[inline(never)] + unsafe fn inner($stack: &$crate::arch::x86_64::macros::InterruptErrorStack) { + $func + } + + // Push scratch registers + asm!("push rax + push rcx + push rdx + push rdi + push rsi + push r8 + push r9 + push r10 + push r11 + push fs + mov rax, 0x18 + mov fs, ax" + : : : : "intel", "volatile"); + + // Get reference to stack variables + let rsp: usize; + asm!("" : "={rsp}"(rsp) : : : "intel", "volatile"); + + // Call inner rust function + inner(&*(rsp as *const $crate::arch::x86_64::macros::InterruptErrorStack)); + + // Pop scratch registers, error code, and return + asm!("pop fs + pop r11 + pop r10 + pop r9 + pop r8 + pop rsi + pop rdi + pop rdx + pop rcx + pop rax + add rsp, 8 + iretq" + : : : : "intel", "volatile"); + } + }; +} diff --git a/src/arch/x86_64/mod.rs b/src/arch/x86_64/mod.rs new file mode 100644 index 0000000..7ae1a8e --- /dev/null +++ b/src/arch/x86_64/mod.rs @@ -0,0 +1,23 @@ +#[macro_use] +pub mod macros; + +/// Devices +pub mod device; + +/// Global descriptor table +pub mod gdt; + +/// Interrupt descriptor table +pub mod idt; + +/// Interrupt instructions +pub mod interrupt; + +/// Paging +pub mod paging; + +/// Initialization and start function +pub mod start; + +/// Stop function +pub mod stop; \ No newline at end of file diff --git a/src/paging/entry.rs b/src/arch/x86_64/paging/entry.rs similarity index 100% rename from src/paging/entry.rs rename to src/arch/x86_64/paging/entry.rs diff --git a/src/paging/mapper.rs b/src/arch/x86_64/paging/mapper.rs similarity index 100% rename from src/paging/mapper.rs rename to src/arch/x86_64/paging/mapper.rs diff --git a/src/paging/mod.rs b/src/arch/x86_64/paging/mod.rs similarity index 100% rename from src/paging/mod.rs rename to src/arch/x86_64/paging/mod.rs diff --git a/src/paging/table.rs b/src/arch/x86_64/paging/table.rs similarity index 100% rename from src/paging/table.rs rename to src/arch/x86_64/paging/table.rs diff --git a/src/paging/temporary_page.rs b/src/arch/x86_64/paging/temporary_page.rs similarity index 100% rename from src/paging/temporary_page.rs rename to src/arch/x86_64/paging/temporary_page.rs diff --git a/src/start.rs b/src/arch/x86_64/start.rs similarity index 100% rename from src/start.rs rename to src/arch/x86_64/start.rs diff --git a/src/stop.rs b/src/arch/x86_64/stop.rs similarity index 100% rename from src/stop.rs rename to src/arch/x86_64/stop.rs diff --git a/src/lib.rs b/src/lib.rs index 533b9e4..aaedb09 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,45 +52,29 @@ pub mod consts; /// ACPI table parsing mod acpi; +/// Architecture-dependent stuff +mod arch; +#[cfg(target_arch = "x86_64")] +pub use arch::x86_64::*; + /// Context management pub mod context; -/// Devices -pub mod device; - /// ELF file parsing pub mod elf; /// External functions pub mod externs; -/// Global descriptor table -pub mod gdt; - -/// Interrupt descriptor table -mod idt; - -/// Interrupt instructions -pub mod interrupt; - /// Memory management pub mod memory; -/// Paging -pub mod paging; - /// Panic pub mod panic; /// Schemes, filesystem handlers pub mod scheme; -/// Initialization and start function -pub mod start; - -/// Shutdown function -pub mod stop; - /// Synchronization primitives pub mod sync; diff --git a/src/macros.rs b/src/macros.rs index 2c8d133..beaef43 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -14,185 +14,3 @@ macro_rules! println { ($fmt:expr) => (print!(concat!($fmt, "\n"))); ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); } - -/// Create an interrupt function that can safely run rust code -#[macro_export] -macro_rules! interrupt { - ($name:ident, $func:block) => { - #[naked] - pub unsafe extern fn $name () { - #[inline(never)] - unsafe fn inner() { - $func - } - - // Push scratch registers - asm!("push rax - push rcx - push rdx - push rdi - push rsi - push r8 - push r9 - push r10 - push r11 - push fs - mov rax, 0x18 - mov fs, ax" - : : : : "intel", "volatile"); - - // Call inner rust function - inner(); - - // Pop scratch registers and return - asm!("pop fs - pop r11 - pop r10 - pop r9 - pop r8 - pop rsi - pop rdi - pop rdx - pop rcx - pop rax - iretq" - : : : : "intel", "volatile"); - } - }; -} - -#[allow(dead_code)] -#[repr(packed)] -pub struct InterruptStack { - pub fs: usize, - pub r11: usize, - pub r10: usize, - pub r9: usize, - pub r8: usize, - pub rsi: usize, - pub rdi: usize, - pub rdx: usize, - pub rcx: usize, - pub rax: usize, - pub rip: usize, - pub cs: usize, - pub rflags: usize, -} - -#[macro_export] -macro_rules! interrupt_stack { - ($name:ident, $stack: ident, $func:block) => { - #[naked] - pub unsafe extern fn $name () { - #[inline(never)] - unsafe fn inner($stack: &mut $crate::macros::InterruptStack) { - $func - } - - // Push scratch registers - asm!("push rax - push rcx - push rdx - push rdi - push rsi - push r8 - push r9 - push r10 - push r11 - push fs - mov rax, 0x18 - mov fs, ax" - : : : : "intel", "volatile"); - - // Get reference to stack variables - let rsp: usize; - asm!("" : "={rsp}"(rsp) : : : "intel", "volatile"); - - // Call inner rust function - inner(&mut *(rsp as *mut $crate::macros::InterruptStack)); - - // Pop scratch registers and return - asm!("pop fs - pop r11 - pop r10 - pop r9 - pop r8 - pop rsi - pop rdi - pop rdx - pop rcx - pop rax - iretq" - : : : : "intel", "volatile"); - } - }; -} - -#[allow(dead_code)] -#[repr(packed)] -pub struct InterruptErrorStack { - pub fs: usize, - pub r11: usize, - pub r10: usize, - pub r9: usize, - pub r8: usize, - pub rsi: usize, - pub rdi: usize, - pub rdx: usize, - pub rcx: usize, - pub rax: usize, - pub code: usize, - pub rip: usize, - pub cs: usize, - pub rflags: usize, -} - -#[macro_export] -macro_rules! interrupt_error { - ($name:ident, $stack:ident, $func:block) => { - #[naked] - pub unsafe extern fn $name () { - #[inline(never)] - unsafe fn inner($stack: &$crate::macros::InterruptErrorStack) { - $func - } - - // Push scratch registers - asm!("push rax - push rcx - push rdx - push rdi - push rsi - push r8 - push r9 - push r10 - push r11 - push fs - mov rax, 0x18 - mov fs, ax" - : : : : "intel", "volatile"); - - // Get reference to stack variables - let rsp: usize; - asm!("" : "={rsp}"(rsp) : : : "intel", "volatile"); - - // Call inner rust function - inner(&*(rsp as *const $crate::macros::InterruptErrorStack)); - - // Pop scratch registers, error code, and return - asm!("pop fs - pop r11 - pop r10 - pop r9 - pop r8 - pop rsi - pop rdi - pop rdx - pop rcx - pop rax - add rsp, 8 - iretq" - : : : : "intel", "volatile"); - } - }; -}