diff --git a/rmm/src/main.rs b/rmm/src/main.rs index e0c6455a5d..e2419dc2fc 100644 --- a/rmm/src/main.rs +++ b/rmm/src/main.rs @@ -189,9 +189,8 @@ unsafe fn new_tables(areas: &'static [MemoryArea]) { for area in areas.iter() { for i in 0..area.size / A::PAGE_SIZE { let phys = area.base.add(i * A::PAGE_SIZE); - let virt = A::phys_to_virt(phys); - let flush = mapper - .map_phys(virt, phys, PageFlags::::new().write(true)) + let (_, flush) = mapper + .map_linearly(phys, PageFlags::::new().write(true)) .expect("failed to map page to frame"); flush.ignore(); // Not the active table } diff --git a/src/acpi/hpet.rs b/src/acpi/hpet.rs index 322637004e..c8b707466f 100644 --- a/src/acpi/hpet.rs +++ b/src/acpi/hpet.rs @@ -2,6 +2,8 @@ use core::{mem, ptr}; use core::ptr::{read_volatile, write_volatile}; +#[cfg(not(target_arch = "x86"))] +use crate::memory::{RmmA, RmmArch}; use crate::{find_one_sdt, memory::PhysicalAddress}; use super::{sdt::Sdt, GenericAddressStructure, ACPI_TABLE}; @@ -99,7 +101,10 @@ impl Hpet { pub unsafe fn read_u64(&self, offset: usize) -> u64 { unsafe { read_volatile( - (self.base_address.address as usize + offset + crate::PHYS_OFFSET) as *const u64, + RmmA::phys_to_virt(PhysicalAddress::new( + self.base_address.address as usize + offset, + )) + .data() as *const u64, ) } } @@ -107,7 +112,10 @@ impl Hpet { pub unsafe fn write_u64(&mut self, offset: usize, value: u64) { unsafe { write_volatile( - (self.base_address.address as usize + offset + crate::PHYS_OFFSET) as *mut u64, + RmmA::phys_to_virt(PhysicalAddress::new( + self.base_address.address as usize + offset, + )) + .data() as *mut u64, value, ); } diff --git a/src/arch/x86_shared/device/ioapic.rs b/src/arch/x86_shared/device/ioapic.rs index f3d377fdc2..8d8e4f2b6a 100644 --- a/src/arch/x86_shared/device/ioapic.rs +++ b/src/arch/x86_shared/device/ioapic.rs @@ -4,17 +4,17 @@ use alloc::vec::Vec; use spin::Mutex; #[cfg(feature = "acpi")] -use crate::acpi::madt::{self, Madt, MadtEntry, MadtIntSrcOverride, MadtIoApic}; +use crate::{ + acpi::madt::{self, Madt, MadtEntry, MadtIntSrcOverride, MadtIoApic}, + memory::{Frame, PageFlags, PhysicalAddress, RmmA, RmmArch}, +}; use crate::{ - arch::interrupt::irq, - memory::{Frame, KernelMapper, Page, PageFlags, PhysicalAddress}, + arch::{cpuid::cpuid, interrupt::irq}, + memory::KernelMapper, }; use super::{local_apic::ApicId, pic}; -use crate::arch::cpuid::cpuid; -#[cfg(target_arch = "x86_64")] -use {crate::memory::RmmA, rmm::Arch}; pub struct IoApicRegs { pointer: *const u32, @@ -241,23 +241,18 @@ pub unsafe fn handle_ioapic(mapper: &mut KernelMapper, madt_ioapic: &'stat // map the I/O APIC registers let frame = Frame::containing(PhysicalAddress::new(madt_ioapic.address as usize)); - #[cfg(target_arch = "x86")] - let page = Page::containing_address(rmm::VirtualAddress::new(crate::IOAPIC_OFFSET)); - #[cfg(target_arch = "x86_64")] - let page = Page::containing_address(RmmA::phys_to_virt(frame.base())); - assert!(mapper.translate(page.start_address()).is_none()); + assert!(mapper.translate(RmmA::phys_to_virt(frame.base())).is_none()); - mapper - .map_phys( - page.start_address(), + let (virt, flush) = mapper + .map_linearly( frame.base(), PageFlags::new().write(true).device_memory(true), ) - .expect("failed to map I/O APIC") - .flush(); + .expect("failed to map I/O APIC"); + flush.flush(); - let ioapic_registers = page.start_address().data() as *const u32; + let ioapic_registers = virt.data() as *const u32; let ioapic = IoApic::new(ioapic_registers, madt_ioapic.gsi_base); assert_eq!( diff --git a/src/arch/x86_shared/device/local_apic.rs b/src/arch/x86_shared/device/local_apic.rs index 3e547a6275..7f4b0af891 100644 --- a/src/arch/x86_shared/device/local_apic.rs +++ b/src/arch/x86_shared/device/local_apic.rs @@ -55,29 +55,18 @@ impl LocalApic { unsafe fn init(&mut self, mapper: &mut KernelMapper) { unsafe { let physaddr = PhysicalAddress::new(rdmsr(IA32_APIC_BASE) as usize & 0xFFFF_0000); - #[cfg(target_arch = "x86")] - let virtaddr = rmm::VirtualAddress::new(crate::LAPIC_OFFSET); - #[cfg(target_arch = "x86_64")] - let virtaddr = { - use rmm::Arch; - crate::memory::RmmA::phys_to_virt(physaddr) - }; - self.address = virtaddr.data(); self.x2 = cpuid() .get_feature_info() .is_some_and(|feature_info| feature_info.has_x2apic()); if !self.x2 { debug!("Detected xAPIC at {:#x}", physaddr.data()); - if let Some((_entry, _, flush)) = mapper.unmap_phys(virtaddr) { - // Unmap xAPIC page if already mapped - flush.flush(); - } - mapper - .map_phys(virtaddr, physaddr, PageFlags::new().write(true)) - .expect("failed to map local APIC memory") - .flush(); + let (virt, flush) = mapper + .map_linearly(physaddr, PageFlags::new().write(true)) + .expect("failed to map local APIC memory"); + flush.flush(); + self.address = virt.data(); } else { debug!("Detected x2APIC"); } @@ -105,10 +94,12 @@ impl LocalApic { } unsafe fn read(&self, reg: u32) -> u32 { + debug_assert!(!self.x2); unsafe { read_volatile((self.address + reg as usize) as *const u32) } } unsafe fn write(&mut self, reg: u32, value: u32) { + debug_assert!(!self.x2); unsafe { write_volatile((self.address + reg as usize) as *mut u32, value); } diff --git a/src/arch/x86_shared/device/serial.rs b/src/arch/x86_shared/device/serial.rs index 58846a1f38..9c78591aa3 100644 --- a/src/arch/x86_shared/device/serial.rs +++ b/src/arch/x86_shared/device/serial.rs @@ -32,25 +32,24 @@ pub unsafe fn init() { return; } - // TODO: Make this configurable - let address = crate::PHYS_OFFSET + 0xFE032000; + let virt = { + use crate::memory::{KernelMapper, PageFlags, PhysicalAddress}; - { - use crate::memory::{KernelMapper, PageFlags, PhysicalAddress, VirtualAddress}; + // TODO: Make this configurable + let phys = PhysicalAddress::new(0xFE032000); let mut mapper = KernelMapper::lock_rw(); - let virt = VirtualAddress::new(address); - let phys = PhysicalAddress::new(address - crate::PHYS_OFFSET); let flags = PageFlags::new().write(true).execute(false); - unsafe { + let (virt, flush) = unsafe { mapper - .map_phys(virt, phys, flags) + .map_linearly(phys, flags) .expect("failed to map frame") - .flush(); - } - } + }; + flush.flush(); + virt + }; - let lpss = unsafe { SerialPort::>::new(address) }; + let lpss = unsafe { SerialPort::>::new(virt.data()) }; if lpss.init().is_ok() { *LPSS.lock() = SerialKind::Ns16550u32(lpss); }