Move PAT initialization to rmm

Rmm needs to know the exact PAT configuration to produce the correct
bits in the page table.
This commit is contained in:
bjorn3
2026-03-30 18:59:42 +02:00
parent c4b064ea44
commit 6e5c25b7a0
5 changed files with 44 additions and 54 deletions
+1
View File
@@ -13,6 +13,7 @@ pub mod riscv64;
pub mod x86;
#[cfg(target_pointer_width = "64")]
pub mod x86_64;
mod x86_shared;
pub trait Arch: Clone + Copy {
/// Does the architecture use a separate page table for the kernel.
+1 -8
View File
@@ -57,14 +57,7 @@ impl Arch for X86Arch {
}
}
bitflags::bitflags! {
pub struct EntryFlags: usize {
const NO_CACHE = 1 << 4;
const HUGE_PAGE = 1 << 7;
const GLOBAL = 1 << 8;
const DEV_MEM = 0;
}
}
pub use super::x86_shared::*;
const _: () = {
assert!(X86Arch::PAGE_SIZE == 4096);
+1 -8
View File
@@ -60,14 +60,7 @@ impl Arch for X8664Arch {
}
}
bitflags::bitflags! {
pub struct EntryFlags: usize {
const NO_CACHE = 1 << 4;
const HUGE_PAGE = 1 << 7;
const GLOBAL = 1 << 8;
const DEV_MEM = 0;
}
}
pub use super::x86_shared::*;
const _: () = {
assert!(X8664Arch::PAGE_SIZE == 4096);
+37
View File
@@ -0,0 +1,37 @@
bitflags::bitflags! {
pub struct EntryFlags: usize {
const NO_CACHE = 1 << 4;
const HUGE_PAGE = 1 << 7;
const GLOBAL = 1 << 8;
const DEV_MEM = 0;
}
}
/// Setup page attribute table
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[inline(always)]
pub unsafe fn init_pat() {
unsafe {
let uncacheable = 0;
let write_combining = 1;
let write_through = 4;
//let write_protected = 5;
let write_back = 6;
let uncached = 7;
let pat0 = write_back;
let pat1 = write_through;
let pat2 = uncached;
let pat3 = uncacheable;
let pat4 = write_combining;
let pat5 = pat1;
let pat6 = pat2;
let pat7 = pat3;
let msr = 631; // IA32_PAT
let low = u32::from_be_bytes([pat3, pat2, pat1, pat0]);
let high = u32::from_be_bytes([pat7, pat6, pat5, pat4]);
core::arch::asm!("wrmsr", in("ecx") msr, in("eax") low, in("edx") high);
}
}
+4 -38
View File
@@ -3,8 +3,6 @@
use core::fmt::Debug;
use x86::msr;
pub use super::CurrentRmmArch as RmmA;
pub use rmm::{Arch as RmmArch, PageFlags, PhysicalAddress, TableKind, VirtualAddress};
@@ -21,46 +19,14 @@ pub mod mapper;
pub const PAGE_SIZE: usize = RmmA::PAGE_SIZE;
pub const PAGE_MASK: usize = RmmA::PAGE_OFFSET_MASK;
/// Setup page attribute table
#[cold]
unsafe fn init_pat() {
unsafe {
let uncacheable = 0;
let write_combining = 1;
let write_through = 4;
//let write_protected = 5;
let write_back = 6;
let uncached = 7;
let pat0 = write_back;
let pat1 = write_through;
let pat2 = uncached;
let pat3 = uncacheable;
let pat4 = write_combining;
let pat5 = pat1;
let pat6 = pat2;
let pat7 = pat3;
msr::wrmsr(
msr::IA32_PAT,
(pat7 << 56)
| (pat6 << 48)
| (pat5 << 40)
| (pat4 << 32)
| (pat3 << 24)
| (pat2 << 16)
| (pat1 << 8)
| pat0,
);
}
}
/// Initialize PAT
#[cold]
pub unsafe fn init() {
unsafe {
init_pat();
#[cfg(target_arch = "x86")]
rmm::x86::init_pat();
#[cfg(target_arch = "x86_64")]
rmm::x86_64::init_pat();
}
}