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:
@@ -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
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user