From 86fb4208f26cc45e3c4ae8682e47ef6ff523d14b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 24 Jan 2024 21:31:15 +0100 Subject: [PATCH] Dedup some more code between x86 and x86_64 --- src/arch/x86/mod.rs | 7 +-- src/arch/x86_64/mod.rs | 7 +-- src/arch/x86_64/stop.rs | 91 ---------------------------- src/arch/x86_64/time.rs | 40 ------------ src/arch/x86_shared/mod.rs | 6 ++ src/arch/{x86 => x86_shared}/stop.rs | 0 src/arch/{x86 => x86_shared}/time.rs | 0 7 files changed, 10 insertions(+), 141 deletions(-) delete mode 100644 src/arch/x86_64/stop.rs delete mode 100644 src/arch/x86_64/time.rs rename src/arch/{x86 => x86_shared}/stop.rs (100%) rename src/arch/{x86 => x86_shared}/time.rs (100%) diff --git a/src/arch/x86/mod.rs b/src/arch/x86/mod.rs index 4528aa3272..f1917ac9e1 100644 --- a/src/arch/x86/mod.rs +++ b/src/arch/x86/mod.rs @@ -1,3 +1,5 @@ +pub use crate::arch::x86_shared::*; + #[macro_use] pub mod macros; @@ -37,11 +39,6 @@ pub mod rmm; /// Initialization and start function pub mod start; -/// Stop function -pub mod stop; - -pub mod time; - use crate::{memory::PAGE_SIZE, Bootstrap}; use ::rmm::Arch; pub use ::rmm::X86Arch as CurrentRmmArch; diff --git a/src/arch/x86_64/mod.rs b/src/arch/x86_64/mod.rs index f749e5a953..4bd78bd87b 100644 --- a/src/arch/x86_64/mod.rs +++ b/src/arch/x86_64/mod.rs @@ -2,6 +2,8 @@ use crate::Bootstrap; use self::paging::PAGE_SIZE; +pub use crate::arch::x86_shared::*; + pub mod alternative; #[macro_use] @@ -46,11 +48,6 @@ pub mod rmm; /// Initialization and start function pub mod start; -/// Stop function -pub mod stop; - -pub mod time; - use ::rmm::Arch; pub use ::rmm::X8664Arch as CurrentRmmArch; diff --git a/src/arch/x86_64/stop.rs b/src/arch/x86_64/stop.rs deleted file mode 100644 index 50ceab3ade..0000000000 --- a/src/arch/x86_64/stop.rs +++ /dev/null @@ -1,91 +0,0 @@ -#[cfg(feature = "acpi")] -use crate::{context, scheme::acpi, time}; - -use crate::syscall::io::{Io, Pio}; - -#[no_mangle] -pub unsafe extern "C" fn kreset() -> ! { - println!("kreset"); - - // 8042 reset - { - println!("Reset with 8042"); - let mut port = Pio::::new(0x64); - while port.readf(2) {} - port.write(0xFE); - } - - emergency_reset(); -} - -pub unsafe fn emergency_reset() -> ! { - // Use triple fault to guarantee reset - core::arch::asm!( - " - cli - lidt cs:0 - int $3 - ", - options(noreturn) - ); -} - -#[cfg(feature = "acpi")] -fn userspace_acpi_shutdown() { - log::info!("Notifying any potential ACPI driver"); - // Tell whatever driver that handles ACPI, that it should enter the S5 state (i.e. - // shutdown). - if !acpi::register_kstop() { - // There was no context to switch to. - log::info!("No ACPI driver was alive to handle shutdown."); - return; - } - log::info!("Waiting one second for ACPI driver to run the shutdown sequence."); - let initial = time::monotonic(); - - // Since this driver is a userspace process, and we do not use any magic like directly - // context switching, we have to wait for the userspace driver to complete, with a timeout. - // - // We switch context, and wait for one second. - loop { - // TODO: Switch directly to whichever process is handling the kstop pipe. We would add an - // event flag like EVENT_DIRECT, which has already been suggested for IRQs. - // TODO: Waitpid with timeout? Because, what if the ACPI driver would crash? - let _ = unsafe { context::switch() }; - - let current = time::monotonic(); - if current - initial > time::NANOS_PER_SEC { - log::info!("Timeout reached, thus falling back to other shutdown methods."); - return; - } - } -} - -#[no_mangle] -pub unsafe extern "C" fn kstop() -> ! { - log::info!("Running kstop()"); - - #[cfg(feature = "acpi")] - userspace_acpi_shutdown(); - - // Magic shutdown code for bochs and qemu (older versions). - for c in "Shutdown".bytes() { - let port = 0x8900; - println!("Shutdown with outb(0x{:X}, '{}')", port, c as char); - Pio::::new(port).write(c); - } - - // Magic shutdown using qemu default ACPI method - { - let port = 0x604; - let data = 0x2000; - println!("Shutdown with outb(0x{:X}, 0x{:X})", port, data); - Pio::::new(port).write(data); - } - - // Magic code for VMWare. Also a hard lock. - println!("Shutdown with cli hlt"); - loop { - core::arch::asm!("cli; hlt"); - } -} diff --git a/src/arch/x86_64/time.rs b/src/arch/x86_64/time.rs deleted file mode 100644 index d610050a09..0000000000 --- a/src/arch/x86_64/time.rs +++ /dev/null @@ -1,40 +0,0 @@ -#[cfg(feature = "acpi")] -use super::device::hpet; -use super::device::pit; - -pub fn counter() -> u128 { - #[cfg(feature = "acpi")] - if let Some(ref hpet) = *crate::acpi::ACPI_TABLE.hpet.read() { - //TODO: handle rollover? - //TODO: improve performance - - // Current count - let counter = unsafe { hpet.base_address.read_u64(hpet::MAIN_COUNTER_OFFSET) }; - // Comparator holds next interrupt count - let comparator = unsafe { hpet.base_address.read_u64(hpet::T0_COMPARATOR_OFFSET) }; - // Get period in femtoseconds - let capability = unsafe { hpet.base_address.read_u64(hpet::CAPABILITY_OFFSET) }; - - // There seems to be a bug in qemu on macos that causes the calculation to produce 0 for - // period_fs and hence a divide by zero calculating the divisor - workaround it while we - // try and get a fix from qemu: https://gitlab.com/qemu-project/qemu/-/issues/1570 - let mut period_fs = capability >> 32; - if period_fs == 0 { - period_fs = 10_000_000; - } - - // Calculate divisor - let divisor = (pit::RATE as u64 * 1_000_000) / period_fs; - // Calculate last interrupt - let last_interrupt = comparator.saturating_sub(divisor); - // Calculate ticks since last interrupt - let elapsed = counter.saturating_sub(last_interrupt); - // Calculate nanoseconds since last interrupt - return (elapsed as u128 * period_fs as u128) / 1_000_000; - } - - // Read ticks since last interrupt - let elapsed = unsafe { pit::read() }; - // Calculate nanoseconds since last interrupt - (elapsed as u128 * pit::PERIOD_FS) / 1_000_000 -} diff --git a/src/arch/x86_shared/mod.rs b/src/arch/x86_shared/mod.rs index 5458924147..b39dc88464 100644 --- a/src/arch/x86_shared/mod.rs +++ b/src/arch/x86_shared/mod.rs @@ -1 +1,7 @@ +/// Devices pub mod device; + +/// Stop function +pub mod stop; + +pub mod time; diff --git a/src/arch/x86/stop.rs b/src/arch/x86_shared/stop.rs similarity index 100% rename from src/arch/x86/stop.rs rename to src/arch/x86_shared/stop.rs diff --git a/src/arch/x86/time.rs b/src/arch/x86_shared/time.rs similarity index 100% rename from src/arch/x86/time.rs rename to src/arch/x86_shared/time.rs