Use map_linearly in many places

This commit is contained in:
bjorn3
2026-04-04 12:07:13 +02:00
parent a1b6bd965e
commit dee230ffca
5 changed files with 42 additions and 50 deletions
+2 -3
View File
@@ -189,9 +189,8 @@ unsafe fn new_tables<A: Arch>(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::<A>::new().write(true))
let (_, flush) = mapper
.map_linearly(phys, PageFlags::<A>::new().write(true))
.expect("failed to map page to frame");
flush.ignore(); // Not the active table
}
+10 -2
View File
@@ -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,
);
}
+12 -17
View File
@@ -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<true>, 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!(
+7 -16
View File
@@ -55,29 +55,18 @@ impl LocalApic {
unsafe fn init(&mut self, mapper: &mut KernelMapper<true>) {
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);
}
+11 -12
View File
@@ -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::<Mmio<u32>>::new(address) };
let lpss = unsafe { SerialPort::<Mmio<u32>>::new(virt.data()) };
if lpss.init().is_ok() {
*LPSS.lock() = SerialKind::Ns16550u32(lpss);
}