From 6dbb85d4c94292d2949e446e1f489fbc4a388088 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Fri, 26 Aug 2022 11:08:13 -0600 Subject: [PATCH] Static mapping of some CPU devices outside of physmap --- rmm | 2 +- src/acpi/hpet.rs | 30 ++++++++++++++++++++++++++++-- src/arch/x86/consts.rs | 15 +++++++++++---- src/arch/x86/device/ioapic.rs | 4 ++-- src/arch/x86/device/local_apic.rs | 4 ++-- 5 files changed, 44 insertions(+), 11 deletions(-) diff --git a/rmm b/rmm index 61ba2e6c..27bb8e44 160000 --- a/rmm +++ b/rmm @@ -1 +1 @@ -Subproject commit 61ba2e6c8e2bba0b6460b681b7f566fa0fe231ca +Subproject commit 27bb8e44ddfb962741e7023b35d0e9eafff041be diff --git a/src/acpi/hpet.rs b/src/acpi/hpet.rs index 241bdaad..e037e5cd 100644 --- a/src/acpi/hpet.rs +++ b/src/acpi/hpet.rs @@ -3,7 +3,8 @@ use core::{mem, ptr}; use core::intrinsics::{volatile_load, volatile_store}; use crate::memory::Frame; -use crate::paging::{KernelMapper, PhysicalAddress, PageFlags}; +use crate::paging::{KernelMapper, PhysicalAddress, Page, PageFlags, VirtualAddress}; +use crate::paging::entry::EntryFlags; use super::sdt::Sdt; use super::{ACPI_TABLE, find_sdt}; @@ -63,13 +64,38 @@ impl Hpet { } } +//TODO: x86 use assumes only one HPET and only one GenericAddressStructure +#[cfg(target_arch = "x86")] +impl GenericAddressStructure { + pub unsafe fn init(&self, mapper: &mut KernelMapper) { + let frame = Frame::containing_address(PhysicalAddress::new(self.address as usize)); + let page = Page::containing_address(VirtualAddress::new(crate::HPET_OFFSET)); + + mapper + .get_mut() + .expect("KernelMapper locked re-entrant while mapping memory for GenericAddressStructure") + .map_phys(page.start_address(), frame.start_address(), PageFlags::new().write(true).custom_flag(EntryFlags::NO_CACHE.bits(), true)) + .expect("failed to map memory for GenericAddressStructure") + .flush(); + } + + pub unsafe fn read_u64(&self, offset: usize) -> u64{ + volatile_load((crate::HPET_OFFSET + offset) as *const u64) + } + + pub unsafe fn write_u64(&mut self, offset: usize, value: u64) { + volatile_store((crate::HPET_OFFSET + offset) as *mut u64, value); + } +} + +#[cfg(not(target_arch = "x86"))] impl GenericAddressStructure { pub unsafe fn init(&self, mapper: &mut KernelMapper) { let frame = Frame::containing_address(PhysicalAddress::new(self.address as usize)); let (_, result) = mapper .get_mut() .expect("KernelMapper locked re-entrant while mapping memory for GenericAddressStructure") - .map_linearly(frame.start_address(), PageFlags::new().write(true)) + .map_linearly(frame.start_address(), PageFlags::new().write(true).custom_flag(EntryFlags::NO_CACHE.bits(), true)) .expect("failed to map memory for GenericAddressStructure"); result.flush(); } diff --git a/src/arch/x86/consts.rs b/src/arch/x86/consts.rs index e05b2754..bcd6df17 100644 --- a/src/arch/x86/consts.rs +++ b/src/arch/x86/consts.rs @@ -3,21 +3,28 @@ // Each PML4 entry references up to 512 GB of memory // The second from the top (510) PML4 is reserved for the kernel - /// Offset of kernel + /// Offset of kernel (256 MiB max) pub const KERNEL_OFFSET: usize = 0xC000_0000; - /// Offset to kernel heap + // Framebuffer mapped by bootloader to 0xD000_0000 (128 MiB max) + + // Offset to APIC mappings (optional) + pub const LAPIC_OFFSET: usize = 0xD800_0000; + pub const IOAPIC_OFFSET: usize = LAPIC_OFFSET + 4096; + pub const HPET_OFFSET: usize = IOAPIC_OFFSET + 4096; + + /// Offset to kernel heap (256 MiB max) pub const KERNEL_HEAP_OFFSET: usize = 0xE000_0000; /// Size of kernel heap pub const KERNEL_HEAP_SIZE: usize = rmm::MEGABYTE; - /// Offset to kernel percpu variables + /// Offset to kernel percpu variables (256 MiB max) pub const KERNEL_PERCPU_OFFSET: usize = 0xF000_0000; /// Size of kernel percpu variables pub const KERNEL_PERCPU_SHIFT: u8 = 16; // 2^16 = 64 KiB pub const KERNEL_PERCPU_SIZE: usize = 1_usize << KERNEL_PERCPU_SHIFT; - /// Offset of physmap + /// Offset of physmap (1 GiB max) // This needs to match RMM's PHYS_OFFSET pub const PHYS_OFFSET: usize = 0x8000_0000; diff --git a/src/arch/x86/device/ioapic.rs b/src/arch/x86/device/ioapic.rs index 9fdf416f..bbd37358 100644 --- a/src/arch/x86/device/ioapic.rs +++ b/src/arch/x86/device/ioapic.rs @@ -8,7 +8,7 @@ use crate::acpi::madt::{self, Madt, MadtEntry, MadtIoApic, MadtIntSrcOverride}; use crate::arch::interrupt::irq; use crate::memory::Frame; -use crate::paging::{KernelMapper, Page, PageFlags, PhysicalAddress, RmmA, RmmArch}; +use crate::paging::{KernelMapper, Page, PageFlags, PhysicalAddress, RmmA, RmmArch, VirtualAddress}; use crate::paging::entry::EntryFlags; use super::super::cpuid::cpuid; @@ -234,7 +234,7 @@ pub unsafe fn handle_ioapic(mapper: &mut KernelMapper, madt_ioapic: &'static Mad // map the I/O APIC registers let frame = Frame::containing_address(PhysicalAddress::new(madt_ioapic.address as usize)); - let page = Page::containing_address(RmmA::phys_to_virt(frame.start_address())); + let page = Page::containing_address(VirtualAddress::new(crate::IOAPIC_OFFSET)); assert!(mapper.translate(page.start_address()).is_none()); diff --git a/src/arch/x86/device/local_apic.rs b/src/arch/x86/device/local_apic.rs index 58745bcb..9ad4f575 100644 --- a/src/arch/x86/device/local_apic.rs +++ b/src/arch/x86/device/local_apic.rs @@ -2,7 +2,7 @@ use core::sync::atomic::{self, AtomicU32}; use core::intrinsics::{volatile_load, volatile_store}; use x86::msr::*; -use crate::paging::{KernelMapper, PhysicalAddress, PageFlags, RmmA, RmmArch}; +use crate::paging::{KernelMapper, PhysicalAddress, PageFlags, RmmA, RmmArch, VirtualAddress}; use super::super::cpuid::cpuid; @@ -45,7 +45,7 @@ impl LocalApic { let mapper = mapper.get_mut().expect("expected KernelMapper not to be locked re-entrant while initializing LAPIC"); let physaddr = PhysicalAddress::new(rdmsr(IA32_APIC_BASE) as usize & 0xFFFF_0000); - let virtaddr = RmmA::phys_to_virt(physaddr); + let virtaddr = VirtualAddress::new(crate::LAPIC_OFFSET); self.address = virtaddr.data(); self.x2 = cpuid().map_or(false, |cpuid| { -- GitLab