rmm: Add device_memory and uncachable flags to PageFlags

This commit is contained in:
bjorn3
2026-03-30 20:34:01 +02:00
parent e311b41821
commit c8879531ae
18 changed files with 40 additions and 68 deletions
+3 -8
View File
@@ -34,7 +34,9 @@ impl Arch for AArch64Arch {
const ENTRY_FLAG_EXEC: usize = 0;
const ENTRY_FLAG_GLOBAL: usize = 0;
const ENTRY_FLAG_NO_GLOBAL: usize = 1 << 11;
const ENTRY_FLAG_WRITE_COMBINING: usize = 0;
const ENTRY_FLAG_DEVICE_MEMORY: usize = MEM_ATTR_DEVICE_nGnRnE << 2;
const ENTRY_FLAG_UNCACHEABLE: usize = MEM_ATTR_NC << 2;
const ENTRY_FLAG_WRITE_COMBINING: usize = MEM_ATTR_NC << 2;
const PHYS_OFFSET: usize = 0xFFFF_8000_0000_0000;
@@ -99,13 +101,6 @@ impl Arch for AArch64Arch {
}
}
bitflags::bitflags! {
pub struct EntryFlags: usize {
const NO_CACHE = MEM_ATTR_NC << 2;
const DEV_MEM = MEM_ATTR_DEVICE_nGnRnE << 2;
}
}
#[cfg_attr(not(target_arch = "aarch64"), allow(unused))]
const MEM_ATTR_WB: usize = 0;
const MEM_ATTR_NC: usize = 1;
+2
View File
@@ -40,6 +40,8 @@ pub trait Arch: Clone + Copy {
const ENTRY_FLAG_EXEC: usize;
const ENTRY_FLAG_GLOBAL: usize;
const ENTRY_FLAG_NO_GLOBAL: usize;
const ENTRY_FLAG_DEVICE_MEMORY: usize;
const ENTRY_FLAG_UNCACHEABLE: usize;
const ENTRY_FLAG_WRITE_COMBINING: usize;
const PHYS_OFFSET: usize;
-7
View File
@@ -3,10 +3,3 @@ pub use sv48::RiscV64Sv48Arch;
mod sv39;
mod sv48;
bitflags::bitflags! {
pub struct EntryFlags: usize {
const NO_CACHE = 1 << 4;
const DEV_MEM = 0;
}
}
+3 -1
View File
@@ -30,7 +30,9 @@ impl Arch for RiscV64Sv39Arch {
const ENTRY_FLAG_EXEC: usize = 1 << 3;
const ENTRY_FLAG_GLOBAL: usize = 1 << 5;
const ENTRY_FLAG_NO_GLOBAL: usize = 0;
const ENTRY_FLAG_WRITE_COMBINING: usize = 0;
const ENTRY_FLAG_DEVICE_MEMORY: usize = 0; // FIXME use Svpbmt
const ENTRY_FLAG_UNCACHEABLE: usize = 0; // FIXME use Svpbmt
const ENTRY_FLAG_WRITE_COMBINING: usize = 0; // FIXME use Svpbmt
const PHYS_OFFSET: usize = 0xFFFF_FFC0_0000_0000;
+3 -1
View File
@@ -26,7 +26,9 @@ impl Arch for RiscV64Sv48Arch {
const ENTRY_FLAG_EXEC: usize = 1 << 3;
const ENTRY_FLAG_GLOBAL: usize = 1 << 5;
const ENTRY_FLAG_NO_GLOBAL: usize = 0;
const ENTRY_FLAG_WRITE_COMBINING: usize = 0;
const ENTRY_FLAG_DEVICE_MEMORY: usize = 0; // FIXME use Svpbmt
const ENTRY_FLAG_UNCACHEABLE: usize = 0; // FIXME use Svpbmt
const ENTRY_FLAG_WRITE_COMBINING: usize = 0; // FIXME use Svpbmt
const PHYS_OFFSET: usize = 0xFFFF_8000_0000_0000;
+2
View File
@@ -25,6 +25,8 @@ impl Arch for X86Arch {
const ENTRY_FLAG_NO_GLOBAL: usize = 0;
const ENTRY_FLAG_NO_EXEC: usize = 0; // NOT AVAILABLE UNLESS PAE IS USED!
const ENTRY_FLAG_EXEC: usize = 0;
const ENTRY_FLAG_DEVICE_MEMORY: usize = 1 << 4;
const ENTRY_FLAG_UNCACHEABLE: usize = 1 << 4;
const ENTRY_FLAG_WRITE_COMBINING: usize = 1 << 7;
const PHYS_OFFSET: usize = 0x8000_0000;
+2
View File
@@ -24,6 +24,8 @@ impl Arch for X8664Arch {
const ENTRY_FLAG_NO_GLOBAL: usize = 0;
const ENTRY_FLAG_NO_EXEC: usize = 1 << 63;
const ENTRY_FLAG_EXEC: usize = 0;
const ENTRY_FLAG_DEVICE_MEMORY: usize = 1 << 4;
const ENTRY_FLAG_UNCACHEABLE: usize = 1 << 4;
const ENTRY_FLAG_WRITE_COMBINING: usize = 1 << 7;
const PHYS_OFFSET: usize = Self::PAGE_NEGATIVE_MASK + (Self::PAGE_ADDRESS_SIZE >> 1) as usize; // PML4 slot 256 and onwards
-7
View File
@@ -1,10 +1,3 @@
bitflags::bitflags! {
pub struct EntryFlags: usize {
const NO_CACHE = 1 << 4;
const DEV_MEM = 0;
}
}
/// Setup page attribute table
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[inline(always)]
+12
View File
@@ -56,6 +56,18 @@ impl<A: Arch> PageFlags<A> {
self
}
#[must_use]
#[inline(always)]
pub fn device_memory(self, value: bool) -> Self {
self.custom_flag(A::ENTRY_FLAG_DEVICE_MEMORY, value)
}
#[must_use]
#[inline(always)]
pub fn uncacheable(self, value: bool) -> Self {
self.custom_flag(A::ENTRY_FLAG_UNCACHEABLE, value)
}
#[must_use]
#[inline(always)]
pub fn write_combining(self, value: bool) -> Self {
+2 -4
View File
@@ -60,7 +60,7 @@ impl Hpet {
unsafe {
use crate::{
memory::{Frame, KernelMapper},
paging::{EntryFlags, Page, VirtualAddress},
paging::{Page, VirtualAddress},
};
use rmm::PageFlags;
@@ -71,9 +71,7 @@ impl Hpet {
.map_phys(
page.start_address(),
frame.base(),
PageFlags::new()
.write(true)
.custom_flag(EntryFlags::NO_CACHE.bits(), true),
PageFlags::new().write(true).device_memory(true),
)
.expect("failed to map memory for GenericAddressStructure")
.flush();
+1 -3
View File
@@ -2,9 +2,7 @@
//! Some code was borrowed from [Phil Opp's Blog](http://os.phil-opp.com/modifying-page-tables.html)
pub use super::CurrentRmmArch as RmmA;
pub use rmm::{
aarch64::EntryFlags, Arch as RmmArch, PageFlags, PhysicalAddress, TableKind, VirtualAddress,
};
pub use rmm::{Arch as RmmArch, PageFlags, PhysicalAddress, TableKind, VirtualAddress};
pub type PageMapper = rmm::PageMapper<RmmA, crate::memory::TheFrameAllocator>;
+1 -3
View File
@@ -1,9 +1,7 @@
#![allow(unused)]
pub use super::CurrentRmmArch as RmmA;
pub use rmm::{
aarch64::EntryFlags, Arch as RmmArch, PageFlags, PhysicalAddress, TableKind, VirtualAddress,
};
pub use rmm::{Arch as RmmArch, PageFlags, PhysicalAddress, TableKind, VirtualAddress};
pub type PageMapper = rmm::PageMapper<RmmA, crate::memory::TheFrameAllocator>;
pub use crate::rmm::KernelMapper;
+2 -4
View File
@@ -9,7 +9,7 @@ use crate::acpi::madt::{self, Madt, MadtEntry, MadtIntSrcOverride, MadtIoApic};
use crate::{
arch::interrupt::irq,
memory::{Frame, KernelMapper},
paging::{EntryFlags, Page, PageFlags, PhysicalAddress},
paging::{Page, PageFlags, PhysicalAddress},
};
use super::{local_apic::ApicId, pic};
@@ -253,9 +253,7 @@ pub unsafe fn handle_ioapic(mapper: &mut KernelMapper<true>, madt_ioapic: &'stat
.map_phys(
page.start_address(),
frame.base(),
PageFlags::new()
.write(true)
.custom_flag(EntryFlags::NO_CACHE.bits(), true),
PageFlags::new().write(true).device_memory(true),
)
.expect("failed to map I/O APIC")
.flush();
-5
View File
@@ -8,11 +8,6 @@ pub use rmm::{Arch as RmmArch, PageFlags, PhysicalAddress, TableKind, VirtualAdd
pub type PageMapper = rmm::PageMapper<RmmA, crate::memory::TheFrameAllocator>;
#[cfg(target_arch = "x86")]
pub use rmm::x86::EntryFlags;
#[cfg(target_arch = "x86_64")]
pub use rmm::x86_64::EntryFlags;
pub mod mapper;
/// Size of pages
-2
View File
@@ -4,8 +4,6 @@ use core::ptr;
#[cfg(feature = "pti")]
use crate::memory::Frame;
#[cfg(feature = "pti")]
use crate::paging::entry::EntryFlags;
#[cfg(feature = "pti")]
use crate::paging::ActivePageTable;
#[cfg(feature = "pti")]
+2 -4
View File
@@ -20,7 +20,7 @@ use crate::{
memory::{AccessMode, PfError},
},
kernel_executable_offsets::{__usercopy_end, __usercopy_start},
paging::{EntryFlags, Page, PageFlags},
paging::{Page, PageFlags},
sync::CleanLockToken,
syscall::error::{Error, ENOMEM},
};
@@ -246,9 +246,7 @@ pub unsafe fn map_device_memory(addr: PhysicalAddress, len: usize) -> VirtualAdd
let (_, flush) = mapper
.map_linearly(
base.add(page_idx * crate::memory::PAGE_SIZE),
PageFlags::new()
.write(true)
.custom_flag(EntryFlags::NO_CACHE.bits(), true),
PageFlags::new().write(true).device_memory(true),
)
.expect("failed to linearly map SDT");
flush.flush();
+3 -14
View File
@@ -9,7 +9,7 @@ use crate::{
memory::{handle_notify_files, AddrSpace, AddrSpaceWrapper, Grant, PageSpan},
},
memory::{free_frames, used_frames, Frame, PAGE_SIZE},
paging::{EntryFlags, VirtualAddress},
paging::VirtualAddress,
sync::CleanLockToken,
syscall::{
data::{Map, StatVfs},
@@ -150,19 +150,8 @@ impl MemoryScheme {
MemoryType::Writeback => (),
MemoryType::WriteCombining => page_flags = page_flags.write_combining(true),
MemoryType::Uncacheable => {
page_flags = page_flags.custom_flag(EntryFlags::NO_CACHE.bits(), true)
}
MemoryType::DeviceMemory => {
// MemoryType::DeviceMemory doesn't exist on x86 && x86_64, which instead support
// uncacheable, write-combining, write-through, write-protect, and write-back.
#[cfg(target_arch = "aarch64")]
{
page_flags = page_flags.custom_flag(EntryFlags::DEV_MEM.bits(), true);
}
}
MemoryType::Uncacheable => page_flags = page_flags.uncacheable(true),
MemoryType::DeviceMemory => page_flags = page_flags.device_memory(true),
}
Grant::physmap(
+2 -5
View File
@@ -1,5 +1,5 @@
use crate::{
arch::{consts::KERNEL_OFFSET, paging::EntryFlags, rmm::page_flags, CurrentRmmArch},
arch::{consts::KERNEL_OFFSET, rmm::page_flags, CurrentRmmArch},
memory::PAGE_SIZE,
startup::{memory::BootloaderMemoryKind::Null, KernelArgs},
};
@@ -349,10 +349,7 @@ unsafe fn map_memory<A: Arch>(areas: &[MemoryArea], mut bump_allocator: &mut Bum
for i in 0..size / PAGE_SIZE {
let phys = PhysicalAddress::new(base + i * PAGE_SIZE);
let virt = A::phys_to_virt(phys);
// use the same mair_el1 value with bootloader,
// mair_el1 == 0x00000000000044FF
// set mem_attr == device memory
let flags = page_flags::<A>(virt).custom_flag(EntryFlags::DEV_MEM.bits(), true);
let flags = page_flags::<A>(virt).device_memory(true);
let flush = mapper
.map_phys(virt, phys, flags)
.expect("failed to map frame");