Procházet zdrojové kódy

style: remove arch crate

greatbridf před 7 měsíci
rodič
revize
a0b22bb416
56 změnil soubory, kde provedl 352 přidání a 842 odebrání
  1. 0 53
      Cargo.lock
  2. 0 4
      Cargo.toml
  3. 0 191
      arch/Cargo.lock
  4. 0 16
      arch/Cargo.toml
  5. 0 9
      arch/arch_macros/Cargo.toml
  6. 0 2
      arch/arch_macros/src/lib.rs
  7. 0 1
      arch/arch_macros/src/riscv64/mod.rs
  8. 0 1
      arch/arch_macros/src/x86_64/mod.rs
  9. 0 14
      arch/src/lib.rs
  10. 0 54
      arch/src/riscv64/mod.rs
  11. 0 34
      arch/src/x86_64/fence.rs
  12. 0 76
      arch/src/x86_64/io.rs
  13. 0 119
      arch/src/x86_64/mod.rs
  14. 0 1
      crates/eonix_hal/Cargo.toml
  15. 5 1
      crates/eonix_hal/eonix_hal_traits/src/fault.rs
  16. 8 1
      crates/eonix_hal/src/arch/riscv64/cpu.rs
  17. 21 16
      crates/eonix_hal/src/arch/riscv64/fence.rs
  18. 0 0
      crates/eonix_hal/src/arch/riscv64/fpu.rs
  19. 27 1
      crates/eonix_hal/src/arch/riscv64/mm.rs
  20. 2 0
      crates/eonix_hal/src/arch/riscv64/mod.rs
  21. 8 9
      crates/eonix_hal/src/arch/riscv64/trap/trap_context.rs
  22. 2 15
      crates/eonix_hal/src/arch/x86_64/bootstrap/init.rs
  23. 36 98
      crates/eonix_hal/src/arch/x86_64/cpu.rs
  24. 46 0
      crates/eonix_hal/src/arch/x86_64/fence.rs
  25. 0 0
      crates/eonix_hal/src/arch/x86_64/fpu.rs
  26. 3 3
      crates/eonix_hal/src/arch/x86_64/interrupt.rs
  27. 36 0
      crates/eonix_hal/src/arch/x86_64/io.rs
  28. 48 1
      crates/eonix_hal/src/arch/x86_64/mm.rs
  29. 3 0
      crates/eonix_hal/src/arch/x86_64/mod.rs
  30. 19 1
      crates/eonix_hal/src/arch/x86_64/trap/trap_context.rs
  31. 0 7
      crates/eonix_hal/src/device.rs
  32. 31 2
      crates/eonix_hal/src/lib.rs
  33. 4 1
      crates/eonix_hal/src/mm.rs
  34. 0 1
      crates/eonix_hal/src/processor.rs
  35. 0 2
      crates/eonix_percpu/eonix_percpu_macros/Cargo.toml
  36. 9 16
      crates/eonix_percpu/eonix_percpu_macros/src/lib.rs
  37. 0 0
      crates/eonix_percpu/eonix_percpu_macros/src/riscv64.rs
  38. 0 0
      crates/eonix_percpu/eonix_percpu_macros/src/x86_64.rs
  39. 0 1
      crates/eonix_runtime/Cargo.toml
  40. 3 2
      crates/eonix_runtime/src/scheduler.rs
  41. 0 1
      crates/eonix_sync/eonix_sync_rt/Cargo.toml
  42. 0 20
      src/driver.rs
  43. 2 1
      src/driver/ahci/control.rs
  44. 1 1
      src/driver/ahci/register.rs
  45. 4 1
      src/driver/serial.rs
  46. 4 1
      src/driver/virtio.rs
  47. 5 3
      src/kernel/interrupt.rs
  48. 11 8
      src/kernel/mem/mm_list.rs
  49. 3 9
      src/kernel/mem/mm_list/page_fault.rs
  50. 2 1
      src/kernel/pcie/device.rs
  51. 1 1
      src/kernel/pcie/init.rs
  52. 1 1
      src/kernel/task/signal.rs
  53. 1 2
      src/kernel/task/signal/signal_action.rs
  54. 6 4
      src/kernel/task/thread.rs
  55. 0 1
      src/sync.rs
  56. 0 34
      src/sync/fence.rs

+ 0 - 53
Cargo.lock

@@ -19,29 +19,6 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c1c330e503236d0b06386ae6cc42a513ef1ccc23c52b603c1b52f018564faf44"
 
-[[package]]
-name = "arch"
-version = "0.1.0"
-dependencies = [
- "bitflags",
- "cfg-if",
- "eonix_hal_traits",
- "eonix_mm",
- "fdt",
- "riscv 0.13.0",
- "sbi",
- "spin",
-]
-
-[[package]]
-name = "arch_macros"
-version = "0.1.0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
 [[package]]
 name = "atomic_unique_refcell"
 version = "0.1.0"
@@ -118,7 +95,6 @@ name = "eonix_hal"
 version = "0.1.0"
 dependencies = [
  "acpi",
- "arch",
  "bitflags",
  "buddy_allocator",
  "cfg-if",
@@ -158,7 +134,6 @@ version = "0.1.0"
 dependencies = [
  "acpi",
  "align_ext",
- "arch",
  "atomic_unique_refcell",
  "bitflags",
  "buddy_allocator",
@@ -214,7 +189,6 @@ dependencies = [
 name = "eonix_percpu_macros"
 version = "0.1.0"
 dependencies = [
- "arch_macros",
  "proc-macro2",
  "quote",
  "syn",
@@ -231,7 +205,6 @@ dependencies = [
 name = "eonix_runtime"
 version = "0.1.0"
 dependencies = [
- "arch",
  "atomic_unique_refcell",
  "eonix_hal",
  "eonix_log",
@@ -267,7 +240,6 @@ version = "0.1.0"
 name = "eonix_sync_rt"
 version = "0.1.0"
 dependencies = [
- "arch",
  "eonix_hal",
  "eonix_preempt",
  "eonix_spin",
@@ -303,16 +275,6 @@ dependencies = [
  "either",
 ]
 
-[[package]]
-name = "lock_api"
-version = "0.4.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
-dependencies = [
- "autocfg",
- "scopeguard",
-]
-
 [[package]]
 name = "log"
 version = "0.4.27"
@@ -433,12 +395,6 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5c64a569a412de4ad7b123f429e434751d74dd7ed25654af962b93c4d1cd584e"
 
-[[package]]
-name = "scopeguard"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
-
 [[package]]
 name = "slab_allocator"
 version = "0.1.0"
@@ -448,15 +404,6 @@ dependencies = [
  "intrusive_list",
 ]
 
-[[package]]
-name = "spin"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591"
-dependencies = [
- "lock_api",
-]
-
 [[package]]
 name = "syn"
 version = "2.0.101"

+ 0 - 4
Cargo.toml

@@ -7,7 +7,6 @@ edition = "2021"
 crate-type = ["bin"]
 
 [dependencies]
-arch = { path = "./arch" }
 atomic_unique_refcell = { path = "./crates/atomic_unique_refcell", features = [
     "no_std",
 ] }
@@ -46,9 +45,6 @@ smp = []
 [profile.dev]
 panic = "abort"
 
-[profile.dev.package.arch]
-opt-level = 0
-
 [profile.dev.package.eonix_preempt]
 opt-level = 2
 

+ 0 - 191
arch/Cargo.lock

@@ -1,191 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 4
-
-[[package]]
-name = "arch"
-version = "0.1.0"
-dependencies = [
- "buddy_allocator",
- "cfg-if",
- "eonix_mm",
- "intrusive_list",
- "once_cell",
- "percpu-macros",
- "riscv",
- "sbi",
- "spin",
- "volatile",
-]
-
-[[package]]
-name = "autocfg"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
-
-[[package]]
-name = "bitflags"
-version = "2.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
-
-[[package]]
-name = "buddy_allocator"
-version = "0.1.0"
-dependencies = [
- "eonix_mm",
- "intrusive_list",
-]
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-
-[[package]]
-name = "critical-section"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
-
-[[package]]
-name = "embedded-hal"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
-
-[[package]]
-name = "eonix_mm"
-version = "0.1.0"
-dependencies = [
- "bitflags",
-]
-
-[[package]]
-name = "intrusive_list"
-version = "0.1.0"
-
-[[package]]
-name = "lock_api"
-version = "0.4.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
-dependencies = [
- "autocfg",
- "scopeguard",
-]
-
-[[package]]
-name = "once_cell"
-version = "1.21.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
-
-[[package]]
-name = "paste"
-version = "1.0.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
-
-[[package]]
-name = "percpu-macros"
-version = "0.1.0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.92"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.37"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "riscv"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afa3cdbeccae4359f6839a00e8b77e5736caa200ba216caf38d24e4c16e2b586"
-dependencies = [
- "critical-section",
- "embedded-hal",
- "paste",
- "riscv-macros",
- "riscv-pac",
-]
-
-[[package]]
-name = "riscv-macros"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8c4aa1ea1af6dcc83a61be12e8189f9b293c3ba5a487778a4cd89fb060fdbbc"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "riscv-pac"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8188909339ccc0c68cfb5a04648313f09621e8b87dc03095454f1a11f6c5d436"
-
-[[package]]
-name = "sbi"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c64a569a412de4ad7b123f429e434751d74dd7ed25654af962b93c4d1cd584e"
-
-[[package]]
-name = "scopeguard"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
-
-[[package]]
-name = "spin"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591"
-dependencies = [
- "lock_api",
-]
-
-[[package]]
-name = "syn"
-version = "2.0.89"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "unicode-ident"
-version = "1.0.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
-
-[[package]]
-name = "volatile"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af8ca9a5d4debca0633e697c88269395493cebf2e10db21ca2dbde37c1356452"

+ 0 - 16
arch/Cargo.toml

@@ -1,16 +0,0 @@
-[package]
-name = "arch"
-version = "0.1.0"
-edition = "2021"
-
-[dependencies]
-eonix_hal_traits = { path = "../crates/eonix_hal/eonix_hal_traits" }
-eonix_mm = { path = "../crates/eonix_mm" }
-cfg-if = "1.0"
-
-[target.'cfg(target_arch = "riscv64")'.dependencies]
-sbi = "0.3.0"
-riscv = { version = "0.13.0", features = ["s-mode"] }
-spin = "0.10.0"
-fdt = "0.1.5"
-bitflags = "2.6.0"

+ 0 - 9
arch/arch_macros/Cargo.toml

@@ -1,9 +0,0 @@
-[package]
-name = "arch_macros"
-version = "0.1.0"
-edition = "2024"
-
-[dependencies]
-proc-macro2 = "1.0"
-quote = "1.0"
-syn = { version = "2.0", features = ["full"] }

+ 0 - 2
arch/arch_macros/src/lib.rs

@@ -1,2 +0,0 @@
-pub mod x86_64;
-pub mod riscv64;

+ 0 - 1
arch/arch_macros/src/riscv64/mod.rs

@@ -1 +0,0 @@
-pub mod percpu;

+ 0 - 1
arch/arch_macros/src/x86_64/mod.rs

@@ -1 +0,0 @@
-pub mod percpu;

+ 0 - 14
arch/src/lib.rs

@@ -1,14 +0,0 @@
-#![no_std]
-
-
-cfg_if::cfg_if! {
-    if #[cfg(target_arch = "x86_64")] {
-        mod x86_64;
-        pub use self::x86_64::*;
-    } else if #[cfg(target_arch = "riscv64")] {
-        mod riscv64;
-        pub use self::riscv64::*;
-    } else if #[cfg(target_arch = "aarch64")]{
-        // TODO!!!
-    }
-}

+ 0 - 54
arch/src/riscv64/mod.rs

@@ -1,54 +0,0 @@
-use core::arch::asm;
-use eonix_mm::{address::VAddr, paging::PFN};
-use riscv::{
-    asm::{sfence_vma, sfence_vma_all},
-    register::{satp, stval},
-};
-
-mod fence;
-mod fpu;
-
-pub use fence::*;
-pub use fpu::*;
-
-#[inline(always)]
-pub fn flush_tlb(vaddr: usize) {
-    sfence_vma(0, vaddr);
-}
-
-#[inline(always)]
-pub fn flush_tlb_all() {
-    sfence_vma_all();
-}
-
-#[inline(always)]
-pub fn get_root_page_table_pfn() -> PFN {
-    let satp_val = satp::read();
-    let ppn = satp_val.ppn();
-    PFN::from(ppn)
-}
-
-#[inline(always)]
-pub fn set_root_page_table_pfn(pfn: PFN) {
-    unsafe { satp::set(satp::Mode::Sv48, 0, usize::from(pfn)) };
-    sfence_vma_all();
-}
-
-#[inline(always)]
-pub fn get_page_fault_address() -> VAddr {
-    VAddr::from(stval::read())
-}
-
-#[inline(always)]
-pub fn halt() {
-    unsafe {
-        asm!("wfi", options(nomem, nostack));
-    }
-}
-
-#[inline(always)]
-pub fn pause() {
-    unsafe {
-        asm!("nop", options(nomem, nostack));
-    }
-}

+ 0 - 34
arch/src/x86_64/fence.rs

@@ -1,34 +0,0 @@
-use core::arch::asm;
-
-#[doc(hidden)]
-/// Issues a full memory barrier.
-///
-/// Note that this acts as a low-level operation **ONLY** and should be used with caution.
-/// **NO COMPILER BARRIERS** are emitted by this function.
-pub fn memory_barrier() {
-    unsafe {
-        asm!("mfence", options(nostack, nomem, preserves_flags));
-    }
-}
-
-#[doc(hidden)]
-/// Issues a read memory barrier.
-///
-/// Note that this acts as a low-level operation **ONLY** and should be used with caution.
-/// **NO COMPILER BARRIERS** are emitted by this function.
-pub fn read_memory_barrier() {
-    unsafe {
-        asm!("lfence", options(nostack, nomem, preserves_flags));
-    }
-}
-
-#[doc(hidden)]
-/// Issues a write memory barrier.
-///
-/// Note that this acts as a low-level operation **ONLY** and should be used with caution.
-/// **NO COMPILER BARRIERS** are emitted by this function.
-pub fn write_memory_barrier() {
-    unsafe {
-        asm!("sfence", options(nostack, nomem, preserves_flags));
-    }
-}

+ 0 - 76
arch/src/x86_64/io.rs

@@ -1,76 +0,0 @@
-use core::arch::asm;
-
-pub fn inb(no: u16) -> u8 {
-    let data;
-    unsafe {
-        asm!(
-            "inb %dx, %al",
-            in("dx") no,
-            out("al") data,
-            options(att_syntax, nomem, nostack)
-        )
-    };
-
-    data
-}
-
-pub fn inw(no: u16) -> u16 {
-    let data;
-    unsafe {
-        asm!(
-            "inw %dx, %ax",
-            in("dx") no,
-            out("ax") data,
-            options(att_syntax, nomem, nostack)
-        )
-    };
-
-    data
-}
-
-pub fn inl(no: u16) -> u32 {
-    let data;
-    unsafe {
-        asm!(
-            "inl %dx, %eax",
-            in("dx") no,
-            out("eax") data,
-            options(att_syntax, nomem, nostack)
-        )
-    };
-
-    data
-}
-
-pub fn outb(no: u16, data: u8) {
-    unsafe {
-        asm!(
-            "outb %al, %dx",
-            in("al") data,
-            in("dx") no,
-            options(att_syntax, nomem, nostack)
-        )
-    };
-}
-
-pub fn outw(no: u16, data: u16) {
-    unsafe {
-        asm!(
-            "outw %ax, %dx",
-            in("ax") data,
-            in("dx") no,
-            options(att_syntax, nomem, nostack)
-        )
-    };
-}
-
-pub fn outl(no: u16, data: u32) {
-    unsafe {
-        asm!(
-            "outl %eax, %dx",
-            in("eax") data,
-            in("dx") no,
-            options(att_syntax, nomem, nostack)
-        )
-    };
-}

+ 0 - 119
arch/src/x86_64/mod.rs

@@ -1,119 +0,0 @@
-mod fence;
-mod fpu;
-mod io;
-
-use core::arch::asm;
-use eonix_mm::address::{Addr as _, PAddr, VAddr};
-use eonix_mm::paging::PFN;
-
-pub use self::io::*;
-pub use fence::*;
-pub use fpu::*;
-
-#[inline(always)]
-pub fn flush_tlb(vaddr: usize) {
-    unsafe {
-        asm!(
-            "invlpg ({})",
-            in(reg) vaddr,
-            options(att_syntax)
-        );
-    }
-}
-
-#[inline(always)]
-pub fn flush_tlb_all() {
-    unsafe {
-        asm!(
-            "mov %cr3, %rax",
-            "mov %rax, %cr3",
-            out("rax") _,
-            options(att_syntax)
-        );
-    }
-}
-
-#[inline(always)]
-pub fn get_root_page_table_pfn() -> PFN {
-    let cr3: usize;
-    unsafe {
-        asm!(
-            "mov %cr3, {0}",
-            out(reg) cr3,
-            options(att_syntax)
-        );
-    }
-    PFN::from(PAddr::from(cr3))
-}
-
-#[inline(always)]
-pub fn set_root_page_table_pfn(pfn: PFN) {
-    unsafe {
-        asm!(
-            "mov {0}, %cr3",
-            in(reg) PAddr::from(pfn).addr(),
-            options(att_syntax)
-        );
-    }
-}
-
-#[inline(always)]
-pub fn get_page_fault_address() -> VAddr {
-    let cr2: usize;
-    unsafe {
-        asm!(
-            "mov %cr2, {}",
-            out(reg) cr2,
-            options(att_syntax)
-        );
-    }
-    VAddr::from(cr2)
-}
-
-#[inline(always)]
-pub fn halt() {
-    unsafe {
-        asm!("hlt", options(att_syntax, nostack));
-    }
-}
-
-#[inline(always)]
-pub fn pause() {
-    unsafe {
-        asm!("pause", options(att_syntax, nostack));
-    }
-}
-
-#[inline(always)]
-pub fn rdmsr(msr: u32) -> u64 {
-    let edx: u32;
-    let eax: u32;
-
-    unsafe {
-        asm!(
-            "rdmsr",
-            in("ecx") msr,
-            out("eax") eax,
-            out("edx") edx,
-            options(att_syntax),
-        );
-    }
-
-    (edx as u64) << 32 | eax as u64
-}
-
-#[inline(always)]
-pub fn wrmsr(msr: u32, value: u64) {
-    let eax = value as u32;
-    let edx = (value >> 32) as u32;
-
-    unsafe {
-        asm!(
-            "wrmsr",
-            in("ecx") msr,
-            in("eax") eax,
-            in("edx") edx,
-            options(att_syntax),
-        );
-    }
-}

+ 0 - 1
crates/eonix_hal/Cargo.toml

@@ -8,7 +8,6 @@ links = "eonix_hal"
 eonix_hal_traits = { path = "./eonix_hal_traits" }
 eonix_hal_macros = { path = "./eonix_hal_macros" }
 
-arch = { path = "../../arch" }
 eonix_mm = { path = "../eonix_mm" }
 eonix_sync_base = { path = "../eonix_sync/eonix_sync_base" }
 eonix_percpu = { path = "../eonix_percpu" }

+ 5 - 1
crates/eonix_hal/eonix_hal_traits/src/fault.rs

@@ -1,4 +1,5 @@
 use bitflags::bitflags;
+use eonix_mm::address::VAddr;
 
 bitflags! {
     #[derive(Debug)]
@@ -14,6 +15,9 @@ bitflags! {
 pub enum Fault {
     InvalidOp,
     BadAccess,
-    PageFault(PageFaultErrorCode),
+    PageFault {
+        error_code: PageFaultErrorCode,
+        address: VAddr,
+    },
     Unknown(usize),
 }

+ 8 - 1
crates/eonix_hal/src/arch/riscv64/cpu.rs

@@ -3,7 +3,7 @@ use super::{
     trap::{setup_trap, TRAP_SCRATCH},
 };
 use crate::arch::fdt::{FdtExt, FDT};
-use core::{pin::Pin, ptr::NonNull};
+use core::{arch::asm, pin::Pin, ptr::NonNull};
 use eonix_preempt::PreemptGuard;
 use eonix_sync_base::LazyLock;
 use riscv::register::{
@@ -95,3 +95,10 @@ impl CPU {
         self.hart_id
     }
 }
+
+#[inline(always)]
+pub fn halt() {
+    unsafe {
+        asm!("wfi", options(nomem, nostack, preserves_flags));
+    }
+}

+ 21 - 16
arch/src/riscv64/fence.rs → crates/eonix_hal/src/arch/riscv64/fence.rs

@@ -1,16 +1,23 @@
-use core::arch::asm;
+use core::{
+    arch::asm,
+    sync::atomic::{compiler_fence, Ordering},
+};
 
 #[doc(hidden)]
 /// Issues a full memory barrier.
 ///
 /// Ensures all memory operations issued before the fence are globally
 /// visible before any memory operations issued after the fence.
-///
-/// **NO COMPILER BARRIERS** are emitted by this function.
 pub fn memory_barrier() {
     unsafe {
+        // A full memory barrier to prevent the compiler from reordering.
+        compiler_fence(Ordering::SeqCst);
+
         // rw for both predecessor and successor: read-write, read-write
         asm!("fence rw, rw", options(nostack, nomem, preserves_flags));
+
+        // A full memory barrier to prevent the compiler from reordering.
+        compiler_fence(Ordering::SeqCst);
     }
 }
 
@@ -19,12 +26,16 @@ pub fn memory_barrier() {
 ///
 /// Ensures all memory loads issued before the fence are globally
 /// visible before any memory loads issued after the fence.
-///
-/// **NO COMPILER BARRIERS** are emitted by this function.
 pub fn read_memory_barrier() {
     unsafe {
+        // A full memory barrier to prevent the compiler from reordering.
+        compiler_fence(Ordering::SeqCst);
+
         // r for both predecessor and successor: read, read
         asm!("fence r, r", options(nostack, nomem, preserves_flags));
+
+        // A full memory barrier to prevent the compiler from reordering.
+        compiler_fence(Ordering::SeqCst);
     }
 }
 
@@ -33,21 +44,15 @@ pub fn read_memory_barrier() {
 ///
 /// Ensures all memory stores issued before the fence are globally
 /// visible before any memory stores issued after the fence.
-///
-/// **NO COMPILER BARRIERS** are emitted by this function.
 pub fn write_memory_barrier() {
     unsafe {
+        // A full memory barrier to prevent the compiler from reordering.
+        compiler_fence(Ordering::SeqCst);
+
         // w for both predecessor and successor: write, write
         asm!("fence w, w", options(nostack, nomem, preserves_flags));
-    }
-}
 
-#[doc(hidden)]
-/// Issues a TLB invalidation memory barrier.
-///
-/// Typically used after modifying page tables.
-pub fn tlb_flush() {
-    unsafe {
-        asm!("sfence.vma zero, zero", options(nostack, nomem, preserves_flags));
+        // A full memory barrier to prevent the compiler from reordering.
+        compiler_fence(Ordering::SeqCst);
     }
 }

+ 0 - 0
arch/src/riscv64/fpu.rs → crates/eonix_hal/src/arch/riscv64/fpu.rs


+ 27 - 1
crates/eonix_hal/src/arch/riscv64/mm.rs

@@ -14,7 +14,10 @@ use eonix_mm::{
 };
 use eonix_sync_base::LazyLock;
 use fdt::Fdt;
-use riscv::{asm::sfence_vma_all, register::satp};
+use riscv::{
+    asm::{sfence_vma, sfence_vma_all},
+    register::satp,
+};
 
 pub const PAGE_TABLE_BASE: PFN = PFN::from_val(ROOT_PAGE_TABLE_PFN);
 pub static GLOBAL_PAGE_TABLE: LazyLock<PageTable<ArchPagingMode, NoAlloc, ArchPhysAccess>> =
@@ -318,3 +321,26 @@ where
         )
     }
 }
+
+#[inline(always)]
+pub fn flush_tlb(vaddr: usize) {
+    sfence_vma(0, vaddr);
+}
+
+#[inline(always)]
+pub fn flush_tlb_all() {
+    sfence_vma_all();
+}
+
+#[inline(always)]
+pub fn get_root_page_table_pfn() -> PFN {
+    let satp_val = satp::read();
+    let ppn = satp_val.ppn();
+    PFN::from(ppn)
+}
+
+#[inline(always)]
+pub fn set_root_page_table_pfn(pfn: PFN) {
+    unsafe { satp::set(satp::Mode::Sv48, 0, usize::from(pfn)) };
+    sfence_vma_all();
+}

+ 2 - 0
crates/eonix_hal/src/arch/riscv64/mod.rs

@@ -4,6 +4,8 @@ pub mod console;
 pub mod context;
 pub mod cpu;
 pub mod fdt;
+pub mod fence;
+pub mod fpu;
 pub mod interrupt;
 pub mod mm;
 pub mod trap;

+ 8 - 9
crates/eonix_hal/src/arch/riscv64/trap/trap_context.rs

@@ -14,14 +14,6 @@ use riscv::{
     ExceptionNumber, InterruptNumber,
 };
 
-/// Floating-point registers context.
-#[repr(C)]
-#[derive(Debug, Clone, Copy, Default)]
-pub struct FpuRegisters {
-    pub f: [u64; 32],
-    pub fcsr: u32,
-}
-
 #[repr(C)]
 #[derive(Default, Clone, Copy)]
 pub struct Registers {
@@ -142,7 +134,14 @@ impl RawTrapContext for TrapContext {
                     exception @ (Exception::InstructionPageFault
                     | Exception::LoadPageFault
                     | Exception::StorePageFault) => {
-                        TrapType::Fault(Fault::PageFault(self.get_page_fault_error_code(exception)))
+                        #[inline(always)]
+                        fn get_page_fault_address() -> VAddr {
+                            VAddr::from(stval::read())
+                        }
+                        TrapType::Fault(Fault::PageFault {
+                            error_code: self.get_page_fault_error_code(exception),
+                            address: get_page_fault_address(),
+                        })
                     }
                     // breakpoint and supervisor env call
                     _ => TrapType::Fault(Fault::Unknown(e)),

+ 2 - 15
crates/eonix_hal/src/arch/x86_64/bootstrap/init.rs

@@ -1,14 +1,14 @@
 use crate::{
     arch::{
         bootstrap::{EARLY_GDT_DESCRIPTOR, KERNEL_PML4},
-        cpu::CPU,
+        cpu::{wrmsr, CPU},
+        io::Port8,
         mm::{ArchPhysAccess, GLOBAL_PAGE_TABLE, V_KERNEL_BSS_START},
     },
     bootstrap::BootStrapData,
     mm::{ArchMemory, ArchPagingMode, BasicPageAlloc, BasicPageAllocRef, ScopedAllocator},
 };
 use acpi::{platform::ProcessorState, AcpiHandler, AcpiTables, PhysicalMapping, PlatformInfo};
-use arch::wrmsr;
 use core::{
     alloc::Allocator,
     arch::{asm, global_asm},
@@ -160,19 +160,6 @@ fn setup_cpu(alloc: impl PageAlloc) {
 
 fn setup_pic() {
     // TODO: Remove this when we have completely switched to APIC.
-    pub struct Port8 {
-        no: u16,
-    }
-
-    impl Port8 {
-        pub const fn new(no: u16) -> Self {
-            Self { no }
-        }
-
-        pub fn write(&self, data: u8) {
-            arch::outb(self.no, data)
-        }
-    }
 
     const PIC1_COMMAND: Port8 = Port8::new(0x20);
     const PIC1_DATA: Port8 = Port8::new(0x21);

+ 36 - 98
crates/eonix_hal/src/arch/x86_64/cpu.rs

@@ -1,6 +1,7 @@
 use super::gdt::{GDTEntry, GDT};
 use super::interrupt::InterruptControl;
 use super::trap::TrapContext;
+use core::arch::asm;
 use core::marker::PhantomPinned;
 use core::mem::size_of;
 use core::pin::Pin;
@@ -132,7 +133,7 @@ impl CPU {
         }
 
         const IA32_KERNEL_GS_BASE: u32 = 0xc0000102;
-        arch::wrmsr(IA32_KERNEL_GS_BASE, *base);
+        wrmsr(IA32_KERNEL_GS_BASE, *base);
     }
 
     pub fn cpuid(&self) -> usize {
@@ -182,106 +183,43 @@ impl TSS {
     }
 }
 
-#[macro_export]
-macro_rules! define_smp_bootstrap {
-    ($cpu_count:literal, $ap_entry:ident, $alloc_kstack:tt) => {
-        static BOOT_SEMAPHORE: core::sync::atomic::AtomicU64 =
-            core::sync::atomic::AtomicU64::new(0);
-        static BOOT_STACK: core::sync::atomic::AtomicU64 =
-            core::sync::atomic::AtomicU64::new(0);
-
-        static CPU_COUNT: core::sync::atomic::AtomicU64 =
-            core::sync::atomic::AtomicU64::new(1);
-
-        core::arch::global_asm!(
-            r#"
-        .pushsection .stage1.smp, "ax", @progbits
-        .code16
-        .globl ap_bootstrap
-        .type ap_bootstrap, @function
-        ap_bootstrap:
-            ljmp $0x0, $2f
-
-        2:
-            # we use the shared gdt for cpu bootstrapping
-            lgdt EARLY_GDT_DESCRIPTOR
-
-            # set msr
-            mov $0xc0000080, %ecx
-            rdmsr
-            or $0x901, %eax # set LME, NXE, SCE
-            wrmsr
-
-            # set cr4
-            mov %cr4, %eax
-            or $0xa0, %eax # set PAE, PGE
-            mov %eax, %cr4
-
-            # load new page table
-            mov ${KERNEL_PML4}, %eax
-            mov %eax, %cr3
-
-            mov %cr0, %eax
-            // SET PE, WP, PG
-            or $0x80010001, %eax
-            mov %eax, %cr0
-
-            ljmp $0x08, $2f
-
-        .code64
-        2:
-            mov $0x10, %ax
-            mov %ax, %ds
-            mov %ax, %es
-            mov %ax, %ss
-
-            xor %rsp, %rsp
-            xor %rax, %rax
-            inc %rax
-        2:
-            xchg %rax, {BOOT_SEMAPHORE}
-            cmp $0, %rax
-            je 2f
-            pause
-            jmp 2b
-
-        2:
-            mov {BOOT_STACK}, %rsp # Acquire
-            cmp $0, %rsp
-            jne 2f
-            pause
-            jmp 2b
+#[inline(always)]
+pub fn halt() {
+    unsafe {
+        asm!("hlt", options(att_syntax, nostack));
+    }
+}
 
-        2:
-            xor %rax, %rax
-            mov %rax, {BOOT_STACK} # Release
-            xchg %rax, {BOOT_SEMAPHORE}
+#[inline(always)]
+pub fn rdmsr(msr: u32) -> u64 {
+    let edx: u32;
+    let eax: u32;
+
+    unsafe {
+        asm!(
+            "rdmsr",
+            in("ecx") msr,
+            out("eax") eax,
+            out("edx") edx,
+            options(att_syntax),
+        );
+    }
 
-            lock incq {CPU_COUNT}
+    (edx as u64) << 32 | eax as u64
+}
 
-            xor %rbp, %rbp
-            push %rbp # NULL return address
-            mov ${AP_ENTRY}, %rax
-            jmp *%rax
-            .popsection
-            "#,
-            KERNEL_PML4 = const 0x1000,
-            BOOT_SEMAPHORE = sym BOOT_SEMAPHORE,
-            BOOT_STACK = sym BOOT_STACK,
-            CPU_COUNT = sym CPU_COUNT,
-            AP_ENTRY = sym $ap_entry,
+#[inline(always)]
+pub fn wrmsr(msr: u32, value: u64) {
+    let eax = value as u32;
+    let edx = (value >> 32) as u32;
+
+    unsafe {
+        asm!(
+            "wrmsr",
+            in("ecx") msr,
+            in("eax") eax,
+            in("edx") edx,
             options(att_syntax),
         );
-
-        pub unsafe fn wait_cpus_online() {
-            use core::sync::atomic::Ordering;
-            while CPU_COUNT.load(Ordering::Acquire) != $cpu_count {
-                if BOOT_STACK.load(Ordering::Acquire) == 0 {
-                    let stack_bottom = $alloc_kstack as u64;
-                    BOOT_STACK.store(stack_bottom, Ordering::Release);
-                }
-                $crate::pause();
-            }
-        }
-    };
+    }
 }

+ 46 - 0
crates/eonix_hal/src/arch/x86_64/fence.rs

@@ -0,0 +1,46 @@
+use core::{
+    arch::asm,
+    sync::atomic::{compiler_fence, Ordering},
+};
+
+#[doc(hidden)]
+/// Issues a full memory barrier.
+pub fn memory_barrier() {
+    unsafe {
+        // A full memory barrier to prevent the compiler from reordering.
+        compiler_fence(Ordering::SeqCst);
+
+        asm!("mfence", options(nostack, nomem, preserves_flags));
+
+        // A full memory barrier to prevent the compiler from reordering.
+        compiler_fence(Ordering::SeqCst);
+    }
+}
+
+#[doc(hidden)]
+/// Issues a read memory barrier.
+pub fn read_memory_barrier() {
+    unsafe {
+        // A full memory barrier to prevent the compiler from reordering.
+        compiler_fence(Ordering::SeqCst);
+
+        asm!("lfence", options(nostack, nomem, preserves_flags));
+
+        // A full memory barrier to prevent the compiler from reordering.
+        compiler_fence(Ordering::SeqCst);
+    }
+}
+
+#[doc(hidden)]
+/// Issues a write memory barrier.
+pub fn write_memory_barrier() {
+    unsafe {
+        // A full memory barrier to prevent the compiler from reordering.
+        compiler_fence(Ordering::SeqCst);
+
+        asm!("sfence", options(nostack, nomem, preserves_flags));
+
+        // A full memory barrier to prevent the compiler from reordering.
+        compiler_fence(Ordering::SeqCst);
+    }
+}

+ 0 - 0
arch/src/x86_64/fpu.rs → crates/eonix_hal/src/arch/x86_64/fpu.rs


+ 3 - 3
crates/eonix_hal/src/arch/x86_64/interrupt.rs

@@ -1,4 +1,4 @@
-use arch::{pause, rdmsr};
+use crate::arch::cpu::rdmsr;
 use core::{arch::asm, marker::PhantomPinned, pin::Pin, ptr::NonNull};
 
 #[repr(C)]
@@ -166,12 +166,12 @@ impl InterruptControl {
 
         icr.write(0xc4500);
         while icr.read() & 0x1000 != 0 {
-            pause();
+            core::hint::spin_loop();
         }
 
         icr.write(0xc4606);
         while icr.read() & 0x1000 != 0 {
-            pause();
+            core::hint::spin_loop();
         }
     }
 

+ 36 - 0
crates/eonix_hal/src/arch/x86_64/io.rs

@@ -0,0 +1,36 @@
+use core::arch::asm;
+
+pub struct Port8 {
+    no: u16,
+}
+
+impl Port8 {
+    pub const fn new(no: u16) -> Self {
+        Self { no }
+    }
+
+    pub fn read(&self) -> u8 {
+        let data;
+        unsafe {
+            asm!(
+                "inb %dx, %al",
+                in("dx") self.no,
+                out("al") data,
+                options(att_syntax, nomem, nostack)
+            )
+        };
+
+        data
+    }
+
+    pub fn write(&self, data: u8) {
+        unsafe {
+            asm!(
+                "outb %al, %dx",
+                in("al") data,
+                in("dx") self.no,
+                options(att_syntax, nomem, nostack)
+            )
+        };
+    }
+}

+ 48 - 1
crates/eonix_hal/src/arch/x86_64/mm.rs

@@ -1,5 +1,5 @@
 use crate::traits::mm::Memory;
-use core::{marker::PhantomData, ptr::NonNull};
+use core::{arch::asm, marker::PhantomData, ptr::NonNull};
 use eonix_mm::{
     address::{Addr as _, AddrOps as _, PAddr, PRange, PhysAccess, VAddr},
     page_table::{
@@ -373,3 +373,50 @@ impl Memory for ArchMemory {
         )
     }
 }
+
+#[inline(always)]
+pub fn flush_tlb(vaddr: usize) {
+    unsafe {
+        asm!(
+            "invlpg ({})",
+            in(reg) vaddr,
+            options(att_syntax)
+        );
+    }
+}
+
+#[inline(always)]
+pub fn flush_tlb_all() {
+    unsafe {
+        asm!(
+            "mov %cr3, %rax",
+            "mov %rax, %cr3",
+            out("rax") _,
+            options(att_syntax)
+        );
+    }
+}
+
+#[inline(always)]
+pub fn get_root_page_table_pfn() -> PFN {
+    let cr3: usize;
+    unsafe {
+        asm!(
+            "mov %cr3, {0}",
+            out(reg) cr3,
+            options(att_syntax)
+        );
+    }
+    PFN::from(PAddr::from(cr3))
+}
+
+#[inline(always)]
+pub fn set_root_page_table_pfn(pfn: PFN) {
+    unsafe {
+        asm!(
+            "mov {0}, %cr3",
+            in(reg) PAddr::from(pfn).addr(),
+            options(att_syntax)
+        );
+    }
+}

+ 3 - 0
crates/eonix_hal/src/arch/x86_64/mod.rs

@@ -1,7 +1,10 @@
 pub mod bootstrap;
 pub mod context;
 pub mod cpu;
+pub mod fence;
+pub mod fpu;
 pub mod gdt;
 pub mod interrupt;
+pub mod io;
 pub mod mm;
 pub mod trap;

+ 19 - 1
crates/eonix_hal/src/arch/x86_64/trap/trap_context.rs

@@ -1,7 +1,9 @@
+use core::arch::asm;
 use eonix_hal_traits::{
     fault::{Fault, PageFaultErrorCode},
     trap::{RawTrapContext, TrapType},
 };
+use eonix_mm::address::VAddr;
 
 #[derive(Clone, Copy, Default)]
 #[repr(C, align(16))]
@@ -50,7 +52,23 @@ impl TrapContext {
                     error_code |= PageFaultErrorCode::UserAccess;
                 }
 
-                Fault::PageFault(error_code)
+                #[inline(always)]
+                fn get_page_fault_address() -> VAddr {
+                    let cr2: usize;
+                    unsafe {
+                        asm!(
+                            "mov %cr2, {}",
+                            out(reg) cr2,
+                            options(att_syntax)
+                        );
+                    }
+                    VAddr::from(cr2)
+                }
+
+                Fault::PageFault {
+                    error_code,
+                    address: get_page_fault_address(),
+                }
             }
             code @ 0..0x20 => Fault::Unknown(code as usize),
             _ => unreachable!(),

+ 0 - 7
crates/eonix_hal/src/device.rs

@@ -1,7 +0,0 @@
-use cfg_if::cfg_if;
-
-cfg_if! {
-    if #[cfg(target_arch = "riscv64")] {
-        pub use crate::arch::fdt::FDT;
-    }
-}

+ 31 - 2
crates/eonix_hal/src/lib.rs

@@ -6,10 +6,39 @@ pub(crate) mod arch;
 
 pub mod bootstrap;
 pub mod context;
-pub mod device;
 pub mod mm;
-pub mod processor;
 pub mod trap;
 
+pub mod fence {
+    pub use crate::arch::fence::{memory_barrier, read_memory_barrier, write_memory_barrier};
+}
+
+pub mod fpu {
+    pub use crate::arch::fpu::FpuState;
+}
+
+pub mod processor {
+    pub use crate::arch::cpu::{halt, UserTLS, CPU};
+}
+
+/// Re-export the arch module for use in other crates
+///
+/// Use this to access architecture-specific functionality in cfg wrapped blocks.
+///
+/// # Example
+/// ``` no_run
+/// #[cfg(target_arch = "x86_64")]
+/// {
+///     use eonix_hal::arch_exported::io::Port8;
+///
+///     // We know that there will be a `Port8` type available for x86_64.
+///     let port = Port8::new(0x3f8);
+///     port.write(0x01);
+/// }
+/// ```
+pub mod arch_exported {
+    pub use crate::arch::*;
+}
+
 pub use eonix_hal_macros::{ap_main, default_trap_handler, main};
 pub use eonix_hal_traits as traits;

+ 4 - 1
crates/eonix_hal/src/mm.rs

@@ -8,7 +8,10 @@ use eonix_mm::{
     paging::{PageAlloc, UnmanagedRawPage, PAGE_SIZE, PFN},
 };
 
-pub use crate::arch::mm::{ArchMemory, ArchPagingMode, ArchPhysAccess, GLOBAL_PAGE_TABLE};
+pub use crate::arch::mm::{
+    flush_tlb, flush_tlb_all, get_root_page_table_pfn, set_root_page_table_pfn, ArchMemory,
+    ArchPagingMode, ArchPhysAccess, GLOBAL_PAGE_TABLE,
+};
 
 pub struct BasicPageAlloc {
     ranges: [Option<PRange>; Self::MAX],

+ 0 - 1
crates/eonix_hal/src/processor.rs

@@ -1 +0,0 @@
-pub use crate::arch::cpu::{UserTLS, CPU};

+ 0 - 2
crates/eonix_percpu/eonix_percpu_macros/Cargo.toml

@@ -7,8 +7,6 @@ edition = "2021"
 proc-macro = true
 
 [dependencies]
-arch_macros = { path = "../../../arch/arch_macros" }
-
 proc-macro2 = "1.0"
 quote = "1.0"
 syn = { version = "2.0", features = ["full"] }

+ 9 - 16
crates/eonix_percpu/eonix_percpu_macros/src/lib.rs

@@ -1,5 +1,8 @@
 extern crate proc_macro;
 
+mod riscv64;
+mod x86_64;
+
 use proc_macro2::TokenStream;
 use quote::{format_ident, quote};
 use syn::{parse2, Ident, ItemStatic, Type};
@@ -190,12 +193,7 @@ pub fn define_percpu_x86_64(
     attrs: proc_macro::TokenStream,
     item: proc_macro::TokenStream,
 ) -> proc_macro::TokenStream {
-    define_percpu_impl(
-        attrs.into(),
-        item.into(),
-        arch_macros::x86_64::percpu::get_percpu_pointer,
-    )
-    .into()
+    define_percpu_impl(attrs.into(), item.into(), x86_64::get_percpu_pointer).into()
 }
 
 #[proc_macro_attribute]
@@ -206,8 +204,8 @@ pub fn define_percpu_shared_x86_64(
     define_percpu_shared_impl(
         attrs.into(),
         item.into(),
-        arch_macros::x86_64::percpu::get_percpu_pointer,
-        arch_macros::x86_64::percpu::get_percpu_offset,
+        x86_64::get_percpu_pointer,
+        x86_64::get_percpu_offset,
     )
     .into()
 }
@@ -217,12 +215,7 @@ pub fn define_percpu_riscv64(
     attrs: proc_macro::TokenStream,
     item: proc_macro::TokenStream,
 ) -> proc_macro::TokenStream {
-    define_percpu_impl(
-        attrs.into(),
-        item.into(),
-        arch_macros::riscv64::percpu::get_percpu_pointer,
-    )
-    .into()
+    define_percpu_impl(attrs.into(), item.into(), riscv64::get_percpu_pointer).into()
 }
 
 #[proc_macro_attribute]
@@ -233,8 +226,8 @@ pub fn define_percpu_shared_riscv64(
     define_percpu_shared_impl(
         attrs.into(),
         item.into(),
-        arch_macros::riscv64::percpu::get_percpu_pointer,
-        arch_macros::riscv64::percpu::get_percpu_offset,
+        riscv64::get_percpu_pointer,
+        riscv64::get_percpu_offset,
     )
     .into()
 }

+ 0 - 0
arch/arch_macros/src/riscv64/percpu.rs → crates/eonix_percpu/eonix_percpu_macros/src/riscv64.rs


+ 0 - 0
arch/arch_macros/src/x86_64/percpu.rs → crates/eonix_percpu/eonix_percpu_macros/src/x86_64.rs


+ 0 - 1
crates/eonix_runtime/Cargo.toml

@@ -4,7 +4,6 @@ version = "0.1.0"
 edition = "2024"
 
 [dependencies]
-arch = { path = "../../arch" }
 atomic_unique_refcell = { path = "../atomic_unique_refcell" }
 eonix_hal = { path = "../eonix_hal" }
 eonix_log = { path = "../eonix_log" }

+ 3 - 2
crates/eonix_runtime/src/scheduler.rs

@@ -12,6 +12,7 @@ use core::{
     sync::atomic::{compiler_fence, Ordering},
     task::Waker,
 };
+use eonix_hal::processor::halt;
 use eonix_log::println_trace;
 use eonix_preempt::assert_preempt_count_eq;
 use eonix_sync::{LazyLock, Spin, SpinIrq as _};
@@ -219,7 +220,7 @@ extern "C" fn local_scheduler() -> ! {
             (None, None) => {
                 // Nothing to do, halt the cpu and rerun the loop.
                 drop(rq);
-                arch::halt();
+                halt();
                 continue;
             }
             (None, Some(next)) => {
@@ -238,7 +239,7 @@ extern "C" fn local_scheduler() -> ! {
                     // Nothing to do, halt the cpu and rerun the loop.
                     CURRENT_TASK.set(NonNull::new(Arc::into_raw(previous) as *mut _));
                     drop(rq);
-                    arch::halt();
+                    halt();
                     continue;
                 }
             }

+ 0 - 1
crates/eonix_sync/eonix_sync_rt/Cargo.toml

@@ -4,7 +4,6 @@ version = "0.1.0"
 edition = "2024"
 
 [dependencies]
-arch = { path = "../../../arch" }
 eonix_hal = { path = "../../eonix_hal" }
 eonix_preempt = { path = "../../eonix_preempt" }
 eonix_spin = { path = "../eonix_spin" }

+ 0 - 20
src/driver.rs

@@ -3,26 +3,6 @@ pub mod e1000e;
 #[cfg(target_arch = "x86_64")]
 pub mod serial;
 
-#[cfg(target_arch = "x86_64")]
-pub struct Port8 {
-    no: u16,
-}
-
-#[cfg(target_arch = "x86_64")]
-impl Port8 {
-    pub const fn new(no: u16) -> Self {
-        Self { no }
-    }
-
-    pub fn read(&self) -> u8 {
-        arch::inb(self.no)
-    }
-
-    pub fn write(&self, data: u8) {
-        arch::outb(self.no, data)
-    }
-}
-
 #[cfg(target_arch = "riscv64")]
 pub mod virtio;
 

+ 2 - 1
src/driver/ahci/control.rs

@@ -1,6 +1,7 @@
 use super::{BitsIterator, GHC_IE};
-use crate::{kernel::mem::PhysAccess as _, sync::fence::memory_barrier};
+use crate::kernel::mem::PhysAccess as _;
 use core::ptr::NonNull;
+use eonix_hal::fence::memory_barrier;
 use eonix_mm::address::PAddr;
 
 /// An `AdapterControl` is an HBA device Global Host Control block

+ 1 - 1
src/driver/ahci/register.rs

@@ -1,9 +1,9 @@
 use crate::{
     kernel::{constants::EIO, mem::PhysAccess as _},
-    sync::fence::memory_barrier,
     KResult,
 };
 use core::ptr::NonNull;
+use eonix_hal::fence::memory_barrier;
 use eonix_mm::address::PAddr;
 
 pub struct Register<T: Copy> {

+ 4 - 1
src/driver/serial.rs

@@ -1,4 +1,3 @@
-use super::Port8;
 use crate::{
     kernel::{
         block::make_device, console::set_console, constants::EIO, interrupt::register_irq_handler,
@@ -9,9 +8,13 @@ use crate::{
 use alloc::{collections::vec_deque::VecDeque, format, sync::Arc};
 use bitflags::bitflags;
 use core::pin::pin;
+use eonix_hal::arch_exported::io::Port8;
 use eonix_runtime::{run::FutureRun, scheduler::Scheduler};
 use eonix_sync::{SpinIrq as _, WaitList};
 
+#[cfg(not(target_arch = "x86_64"))]
+compile_error!("Serial driver is only supported on x86_64 architecture");
+
 bitflags! {
     struct LineStatus: u8 {
         const RX_READY = 0x01;

+ 4 - 1
src/driver/virtio.rs

@@ -1,12 +1,15 @@
 mod virtio_blk;
 
+#[cfg(not(target_arch = "riscv64"))]
+compile_error!("VirtIO drivers are only supported on RISC-V architecture");
+
 use crate::kernel::{
     block::{make_device, BlockDevice},
     mem::{AsMemoryBlock, MemoryBlock, Page},
 };
 use alloc::sync::Arc;
 use core::num::NonZero;
-use eonix_hal::{device::FDT, mm::ArchPhysAccess};
+use eonix_hal::{arch_exported::fdt::FDT, mm::ArchPhysAccess};
 use eonix_log::{println_info, println_warn};
 use eonix_mm::{
     address::{Addr, PAddr, PhysAccess},

+ 5 - 3
src/kernel/interrupt.rs

@@ -24,7 +24,7 @@ pub fn default_irq_handler(irqno: usize) {
 
     #[cfg(target_arch = "x86_64")]
     {
-        use crate::driver::Port8;
+        use eonix_hal::arch_exported::io::Port8;
 
         const PIC1_COMMAND: Port8 = Port8::new(0x20);
         const PIC2_COMMAND: Port8 = Port8::new(0xA0);
@@ -42,9 +42,11 @@ pub fn default_fault_handler(fault_type: Fault, trap_ctx: &mut TrapContext) {
     }
 
     match fault_type {
-        Fault::PageFault(error_code) => {
+        Fault::PageFault {
+            error_code,
+            address: vaddr,
+        } => {
             let fault_pc = VAddr::from(trap_ctx.get_program_counter());
-            let vaddr = arch::get_page_fault_address();
 
             if let Some(new_pc) = handle_kernel_page_fault(fault_pc, vaddr, error_code) {
                 trap_ctx.set_program_counter(new_pc.addr());

+ 11 - 8
src/kernel/mem/mm_list.rs

@@ -10,7 +10,10 @@ use crate::{prelude::*, sync::ArcSwap};
 use alloc::collections::btree_set::BTreeSet;
 use core::fmt;
 use core::sync::atomic::{AtomicUsize, Ordering};
-use eonix_hal::mm::{ArchPagingMode, ArchPhysAccess, GLOBAL_PAGE_TABLE};
+use eonix_hal::mm::{
+    flush_tlb_all, get_root_page_table_pfn, set_root_page_table_pfn, ArchPagingMode,
+    ArchPhysAccess, GLOBAL_PAGE_TABLE,
+};
 use eonix_mm::address::{Addr as _, PAddr};
 use eonix_mm::page_table::PageAttribute;
 use eonix_mm::paging::PFN;
@@ -289,12 +292,12 @@ impl MMList {
                 // If there are currently no users, we don't need to do anything.
             }
             1 => {
-                if PAddr::from(arch::get_root_page_table_pfn()).addr()
+                if PAddr::from(get_root_page_table_pfn()).addr()
                     == self.root_page_table.load(Ordering::Relaxed)
                 {
                     // If there is only one user and we are using the page table,
                     // flushing the TLB for the local cpu only is enough.
-                    arch::flush_tlb_all();
+                    flush_tlb_all();
                 } else {
                     // Send the TLB flush request to the core.
                     todo!();
@@ -360,11 +363,11 @@ impl MMList {
 
         let root_page_table = self.root_page_table.load(Ordering::Relaxed);
         assert_ne!(root_page_table, 0);
-        arch::set_root_page_table_pfn(PFN::from(PAddr::from(root_page_table)));
+        set_root_page_table_pfn(PFN::from(PAddr::from(root_page_table)));
     }
 
     pub fn deactivate(&self) {
-        arch::set_root_page_table_pfn(PFN::from(GLOBAL_PAGE_TABLE.addr()));
+        set_root_page_table_pfn(PFN::from(GLOBAL_PAGE_TABLE.addr()));
 
         let old_user_count = self.user_count.fetch_sub(1, Ordering::Release);
         assert_ne!(old_user_count, 0);
@@ -378,7 +381,7 @@ impl MMList {
 
         let root_page_table = self.root_page_table.load(Ordering::Relaxed);
         assert_ne!(root_page_table, 0);
-        arch::set_root_page_table_pfn(PFN::from(PAddr::from(root_page_table)));
+        set_root_page_table_pfn(PFN::from(PAddr::from(root_page_table)));
 
         let old_user_count = to.user_count.fetch_sub(1, Ordering::Release);
         assert_ne!(old_user_count, 0);
@@ -407,7 +410,7 @@ impl MMList {
         );
 
         let old_root_page_table = self.root_page_table.load(Ordering::Relaxed);
-        let current_root_page_table = arch::get_root_page_table_pfn();
+        let current_root_page_table = get_root_page_table_pfn();
         assert_eq!(
             PAddr::from(current_root_page_table).addr(),
             old_root_page_table,
@@ -419,7 +422,7 @@ impl MMList {
             None => GLOBAL_PAGE_TABLE.addr().addr(),
         };
 
-        arch::set_root_page_table_pfn(PFN::from(PAddr::from(new_root_page_table)));
+        set_root_page_table_pfn(PFN::from(PAddr::from(new_root_page_table)));
 
         self.root_page_table
             .store(new_root_page_table, Ordering::Relaxed);

+ 3 - 9
src/kernel/mem/mm_list/page_fault.rs

@@ -1,7 +1,8 @@
 use super::{MMList, VAddr};
 use crate::kernel::task::{Signal, Thread};
+use eonix_hal::mm::flush_tlb;
 use eonix_hal::traits::fault::PageFaultErrorCode;
-use eonix_mm::address::{AddrOps as _, VRange};
+use eonix_mm::address::{Addr as _, AddrOps as _, VRange};
 use eonix_mm::paging::PAGE_SIZE;
 use eonix_runtime::task::Task;
 
@@ -83,14 +84,7 @@ impl MMList {
         area.handle(pte, addr.floor() - area.range().start())
             .map_err(|_| Signal::SIGBUS)?;
 
-        #[cfg(not(target_arch = "x86_64"))]
-        {
-            use eonix_mm::address::Addr as _;
-            // Flush the TLB for the affected address range.
-            // x86 CPUs will try to retrieve the PTE again for non-present entries.
-            // So we don't need to flush TLB.
-            arch::flush_tlb(addr.floor().addr());
-        }
+        flush_tlb(addr.floor().addr());
 
         Ok(())
     }

+ 2 - 1
src/kernel/pcie/device.rs

@@ -1,7 +1,8 @@
 use super::{CommonHeader, Header};
-use crate::{kernel::mem::PhysAccess as _, sync::fence::memory_barrier};
+use crate::kernel::mem::PhysAccess as _;
 use alloc::sync::Arc;
 use core::{ops::RangeInclusive, sync::atomic::Ordering};
+use eonix_hal::fence::memory_barrier;
 use eonix_mm::address::PAddr;
 use eonix_sync::{LazyLock, Spin};
 use intrusive_collections::{intrusive_adapter, KeyAdapter, RBTree, RBTreeAtomicLink};

+ 1 - 1
src/kernel/pcie/init.rs

@@ -53,7 +53,7 @@ pub fn init_pcie() -> Result<(), PciError> {
     #[cfg(target_arch = "riscv64")]
     {
         use crate::kernel::constants::{EINVAL, ENOENT};
-        use eonix_hal::device::FDT;
+        use eonix_hal::arch_exported::fdt::FDT;
         use eonix_mm::address::PRange;
 
         let pcie_node = FDT.find_node("/soc/pci").ok_or(ENOENT)?;

+ 1 - 1
src/kernel/task/signal.rs

@@ -6,8 +6,8 @@ use super::{ProcessList, Thread, WaitObject, WaitType};
 use crate::kernel::constants::{EFAULT, EINVAL};
 use crate::{kernel::user::UserPointer, prelude::*};
 use alloc::collections::binary_heap::BinaryHeap;
-use arch::FpuState;
 use core::{cmp::Reverse, task::Waker};
+use eonix_hal::fpu::FpuState;
 use eonix_hal::traits::trap::RawTrapContext;
 use eonix_hal::trap::TrapContext;
 use eonix_runtime::task::Task;

+ 1 - 2
src/kernel/task/signal/signal_action.rs

@@ -8,9 +8,8 @@ use crate::{
     SIGNAL_NOW,
 };
 use alloc::collections::btree_map::BTreeMap;
-use arch::FpuState;
 use core::num::NonZero;
-use eonix_hal::{traits::trap::RawTrapContext, trap::TrapContext};
+use eonix_hal::{fpu::FpuState, traits::trap::RawTrapContext, trap::TrapContext};
 use eonix_mm::address::{Addr as _, AddrOps as _, VAddr};
 use posix_types::signal::{SigAction, TryFromSigAction};
 

+ 6 - 4
src/kernel/task/thread.rs

@@ -13,7 +13,6 @@ use crate::{
     prelude::*,
 };
 use alloc::sync::Arc;
-use arch::FpuState;
 use atomic_unique_refcell::AtomicUniqueRefCell;
 use core::{
     future::Future,
@@ -24,6 +23,7 @@ use core::{
 };
 use eonix_hal::{
     context::TaskContext,
+    fpu::FpuState,
     processor::{UserTLS, CPU},
     traits::{
         fault::Fault,
@@ -369,10 +369,12 @@ impl Thread {
 
             let trap_type = self.trap_ctx.borrow().trap_type();
             match trap_type {
-                TrapType::Fault(Fault::PageFault(err_code)) => {
-                    let addr = arch::get_page_fault_address();
+                TrapType::Fault(Fault::PageFault {
+                    error_code,
+                    address: addr,
+                }) => {
                     let mms = &self.process.mm_list;
-                    if let Err(signal) = mms.handle_user_page_fault(addr, err_code).await {
+                    if let Err(signal) = mms.handle_user_page_fault(addr, error_code).await {
                         self.signal_list.raise(signal);
                     }
                 }

+ 0 - 1
src/sync.rs

@@ -1,6 +1,5 @@
 mod arcswap;
 mod condvar;
-pub mod fence;
 
 pub use arcswap::ArcSwap;
 pub use eonix_sync::Spin;

+ 0 - 34
src/sync/fence.rs

@@ -1,34 +0,0 @@
-use core::sync::atomic::{compiler_fence, Ordering};
-
-/// A strong memory barrier that prevents reordering of memory operations.
-pub fn memory_barrier() {
-    // A full memory barrier to prevent the compiler from reordering.
-    compiler_fence(Ordering::SeqCst);
-
-    arch::memory_barrier();
-
-    // A full memory barrier to prevent the compiler from reordering.
-    compiler_fence(Ordering::SeqCst);
-}
-
-/// A read memory barrier that prevents reordering of read operations.
-pub fn read_memory_barrier() {
-    // A full memory barrier to prevent the compiler from reordering.
-    compiler_fence(Ordering::SeqCst);
-
-    arch::read_memory_barrier();
-
-    // A read memory barrier to prevent the compiler from reordering.
-    compiler_fence(Ordering::SeqCst);
-}
-
-/// A write memory barrier that prevents reordering of write operations.
-pub fn write_memory_barrier() {
-    // A full memory barrier to prevent the compiler from reordering.
-    compiler_fence(Ordering::SeqCst);
-
-    arch::write_memory_barrier();
-
-    // A write memory barrier to prevent the compiler from reordering.
-    compiler_fence(Ordering::SeqCst);
-}