From f58d15a197f839ec45f02bbd41bf8b55298ec621 Mon Sep 17 00:00:00 2001 From: Mathieu Strypsteen Date: Wed, 30 Oct 2024 18:15:18 +0100 Subject: [PATCH] Add early_sleep --- kernel/src/sys/hpet.rs | 37 ++++++++++++++++++++++++--- kernel/src/sys/madt.rs | 6 +++-- lib/acpica | 2 +- lib/kernel-common/src/instructions.rs | 10 ++++++++ 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/kernel/src/sys/hpet.rs b/kernel/src/sys/hpet.rs index d597a68..2858d76 100644 --- a/kernel/src/sys/hpet.rs +++ b/kernel/src/sys/hpet.rs @@ -1,8 +1,11 @@ use core::{ ptr::null_mut, - sync::atomic::{AtomicPtr, AtomicU64, Ordering}, + sync::atomic::{AtomicBool, AtomicPtr, AtomicU64, Ordering}, }; +use kernel_common::instructions::pause; +use log::warn; + use crate::{ cpu::paging::map_physical, sys::{ @@ -20,11 +23,38 @@ const REGISTER_TIMER0_CONFIG: usize = 0x20; const REGISTER_TIMER0_COMPARATOR: usize = 0x21; const CONFIG_ENABLE: u64 = 1; const CONFIG_LEGACY_REPLACEMENT: u64 = 2; +const TIMER_CONFIG_ENABLE: u64 = 4; static ADDRESS: AtomicPtr = AtomicPtr::new(null_mut()); static PERIOD: AtomicU64 = AtomicU64::new(0); +static EARLY_SLEEP: AtomicBool = AtomicBool::new(false); -fn handler() {} +fn handler() { + if EARLY_SLEEP.load(Ordering::Relaxed) { + let address = ADDRESS.load(Ordering::Relaxed); + unsafe { + let current_config = address.add(REGISTER_TIMER0_CONFIG).read_volatile(); + address.add(REGISTER_TIMER0_CONFIG).write_volatile(current_config & !TIMER_CONFIG_ENABLE); + } + EARLY_SLEEP.store(false, Ordering::Relaxed); + return; + } + warn!("Spurious HPET interrupt"); +} +pub fn early_sleep(ms: usize) { + EARLY_SLEEP.store(true, Ordering::Relaxed); + unsafe { + let address = ADDRESS.load(Ordering::Relaxed); + let period = PERIOD.load(Ordering::Relaxed); + let current_counter = address.add(REGISTER_COUNTER).read_volatile(); + address.add(REGISTER_TIMER0_COMPARATOR).write_volatile(current_counter + u64::pow(10, 12) / period * ms as u64); + let current_config = address.add(REGISTER_TIMER0_CONFIG).read_volatile(); + address.add(REGISTER_TIMER0_CONFIG).write_volatile(current_config | TIMER_CONFIG_ENABLE); + } + while EARLY_SLEEP.load(Ordering::Relaxed) { + pause(); + } +} pub fn setup_hpet() { let signature = b"HPET" as *const u8; let address; @@ -42,7 +72,8 @@ pub fn setup_hpet() { } PERIOD.store(period, Ordering::Relaxed); unsafe { - address.add(REGISTER_CONFIG).write_volatile(CONFIG_ENABLE | CONFIG_LEGACY_REPLACEMENT); + let current_config = address.add(REGISTER_CONFIG).read_volatile(); + address.add(REGISTER_CONFIG).write_volatile(current_config | CONFIG_ENABLE | CONFIG_LEGACY_REPLACEMENT); } register_isa_irq_handler(0, handler); } diff --git a/kernel/src/sys/madt.rs b/kernel/src/sys/madt.rs index b28f1f2..200a7df 100644 --- a/kernel/src/sys/madt.rs +++ b/kernel/src/sys/madt.rs @@ -1,4 +1,6 @@ -use core::{arch::asm, mem::size_of}; +use core::mem::size_of; + +use kernel_common::instructions::sti; use crate::sys::acpica_osl::AE_OK; @@ -67,6 +69,6 @@ pub fn parse_madt() { subtable_address_i += subtable_header.Length as u64; } unsafe { - asm!("sti"); + sti(); } } diff --git a/lib/acpica b/lib/acpica index 1d9c129..993a257 160000 --- a/lib/acpica +++ b/lib/acpica @@ -1 +1 @@ -Subproject commit 1d9c129746c737b68e642f9f29a894e2700fbf46 +Subproject commit 993a25704ac18784b44c1af75cb54abec5141981 diff --git a/lib/kernel-common/src/instructions.rs b/lib/kernel-common/src/instructions.rs index 28d4d8f..309c42b 100644 --- a/lib/kernel-common/src/instructions.rs +++ b/lib/kernel-common/src/instructions.rs @@ -1,10 +1,20 @@ use core::arch::asm; +pub fn pause() { + unsafe { + asm!("pause"); + } +} pub fn cli() { unsafe { asm!("cli"); } } +pub unsafe fn sti() { + unsafe { + asm!("sti"); + } +} pub fn hlt() { unsafe { asm!("hlt");