diff --git a/build.sh b/build.sh index a630f55..5c4c65f 100755 --- a/build.sh +++ b/build.sh @@ -2,9 +2,12 @@ set -euo pipefail rm -rf img mkdir -p img/boot/efi/boot -cd lib/acpica-build && make -j4 && cd ../.. -cd kernel && cargo build --release && cd .. -cd loader && cargo build --release && cd .. +cd lib/acpica-build +cd ../../kernel +cargo build --release +cd ../loader +cargo build --release +cd .. cp target/x86_64-unknown-uefi/release/loader.efi img/boot/efi/boot/bootx64.efi cd img dd if=/dev/zero of=boot.img bs=1M count=16 status=none diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 2cdd8d4..2723ef5 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -21,7 +21,7 @@ use kernel_common::{ paging::{KERNEL_HEAP_INITIAL_SIZE, KERNEL_HEAP_START}, }; use log::{error, info}; -use sys::{acpica::AcpiInitializeTables, acpica_osl::AE_OK, hpet::setup_hpet, madt::parse_madt, pic::disable_pic}; +use sys::{acpica::AcpiInitializeTables, acpica_osl::AE_OK, hpet::setup_hpet, lapic::setup_lapic_timer, madt::parse_madt, pic::disable_pic}; mod cpu; mod misc; @@ -57,6 +57,7 @@ extern "C" fn main(temp_loader_struct: *const LoaderStruct) -> ! { } parse_madt(); setup_hpet(); + setup_lapic_timer(); loop { hlt(); } diff --git a/kernel/src/sys/lapic.rs b/kernel/src/sys/lapic.rs index 3b45a6e..ce5db9d 100644 --- a/kernel/src/sys/lapic.rs +++ b/kernel/src/sys/lapic.rs @@ -1,16 +1,23 @@ use core::{ ptr::null_mut, - sync::atomic::{AtomicPtr, AtomicU8, Ordering}, + sync::atomic::{AtomicPtr, AtomicU8, AtomicUsize, Ordering}, }; use crate::cpu::paging::map_physical; +use super::hpet::early_sleep; + const REGISTER_ID: usize = 8; const REGISTER_EOI: usize = 0x2c; const REGISTER_SPURIOUS_INT: usize = 0x3c; +const REGISTER_TIMER_LVT: usize = 0xc8; +const REGISTER_TIMER_INITIAL_COUNT: usize = 0xe0; +const REGISTER_TIMER_CURRENT_COUNT: usize = 0xe4; +const REGISTER_TIMER_DIVIDE: usize = 0xf8; static ADDRESS: AtomicPtr = AtomicPtr::new(null_mut()); pub static BSP_LAPIC_ID: AtomicU8 = AtomicU8::new(0); +static TICKS_PER_MS: AtomicUsize = AtomicUsize::new(0); pub fn send_eoi() { let address = ADDRESS.load(Ordering::Relaxed); @@ -27,3 +34,25 @@ pub fn setup_lapic(phys: u64) { } send_eoi(); } +fn calibrate_timer() { + let address = ADDRESS.load(Ordering::Relaxed); + unsafe { + address.add(REGISTER_TIMER_INITIAL_COUNT).write_volatile(0xffffffff); + } + early_sleep(10); + let ticks_in_10ms = 0xffffffff - unsafe { address.add(REGISTER_TIMER_CURRENT_COUNT).read_volatile() }; + TICKS_PER_MS.store(ticks_in_10ms as usize / 10, Ordering::Relaxed); + unsafe { + address.add(REGISTER_TIMER_INITIAL_COUNT).write_volatile(0); + } +} +pub fn setup_lapic_timer() { + let address = ADDRESS.load(Ordering::Relaxed); + unsafe { + address.add(REGISTER_TIMER_DIVIDE).write_volatile(3); + } + calibrate_timer(); + unsafe { + address.add(REGISTER_TIMER_LVT).write_volatile(254); + } +} diff --git a/kernel/src/sys/madt.rs b/kernel/src/sys/madt.rs index c49a3b4..dff1f1b 100644 --- a/kernel/src/sys/madt.rs +++ b/kernel/src/sys/madt.rs @@ -10,17 +10,16 @@ use super::{ lapic::setup_lapic, }; -fn process_subtables(subtable_address: u64, end_address: u64, target_type: u8, handler: &mut dyn FnMut(u64)) { +fn process_subtables(subtable_address: u64, end_address: u64, subtable_type: u8, handler: &mut dyn FnMut(u64)) { let mut subtable_address_i = subtable_address; while subtable_address_i < end_address { let subtable_header = unsafe { &*(subtable_address_i as *const acpi_subtable_header) }; - if subtable_header.Type == target_type { + if subtable_header.Type == subtable_type { handler(subtable_address_i); } subtable_address_i += subtable_header.Length as u64; } } - pub fn parse_madt() { let madt: &acpi_table_madt; let signature = b"APIC" as *const u8;