Implement PHYS_OFFSET mapping
This commit is contained in:
+4
-3
@@ -20,7 +20,6 @@ impl Arch for EmulateArch {
|
||||
const PAGE_SHIFT: usize = X8664Arch::PAGE_SHIFT;
|
||||
const PAGE_ENTRY_SHIFT: usize = X8664Arch::PAGE_ENTRY_SHIFT;
|
||||
const PAGE_LEVELS: usize = X8664Arch::PAGE_LEVELS;
|
||||
const PAGE_OFFSET: usize = X8664Arch::PAGE_OFFSET;
|
||||
|
||||
const ENTRY_ADDRESS_SHIFT: usize = X8664Arch::ENTRY_ADDRESS_SHIFT;
|
||||
const ENTRY_FLAG_PRESENT: usize = X8664Arch::ENTRY_FLAG_PRESENT;
|
||||
@@ -30,6 +29,8 @@ impl Arch for EmulateArch {
|
||||
const ENTRY_FLAG_GLOBAL: usize = X8664Arch::ENTRY_FLAG_GLOBAL;
|
||||
const ENTRY_FLAG_NO_EXEC: usize = X8664Arch::ENTRY_FLAG_NO_EXEC;
|
||||
|
||||
const PHYS_OFFSET: usize = X8664Arch::PHYS_OFFSET;
|
||||
|
||||
unsafe fn init() -> &'static [MemoryArea] {
|
||||
// Create machine with PAGE_ENTRIES pages identity mapped (2 MiB on x86_64)
|
||||
// Pages over 1 MiB will be mapped writable
|
||||
@@ -41,8 +42,8 @@ impl Arch for EmulateArch {
|
||||
let flags = Self::ENTRY_FLAG_WRITABLE | Self::ENTRY_FLAG_PRESENT;
|
||||
machine.write_phys::<usize>(PhysicalAddress::new(pml4), pdp | flags);
|
||||
|
||||
// Recursive mapping
|
||||
machine.write_phys::<usize>(PhysicalAddress::new(pml4 + (Self::PAGE_ENTRIES - 1) * Self::PAGE_ENTRY_SIZE), pml4 | flags);
|
||||
// PML4 index 256, set to PDP again for PHYS_OFFSET mapping
|
||||
machine.write_phys::<usize>(PhysicalAddress::new(pml4 + 256 * Self::PAGE_ENTRY_SIZE), pdp | flags);
|
||||
|
||||
// PDP link to PD
|
||||
let pd = pdp + Self::PAGE_SIZE;
|
||||
|
||||
+3
-2
@@ -13,7 +13,6 @@ pub trait Arch {
|
||||
const PAGE_SHIFT: usize;
|
||||
const PAGE_ENTRY_SHIFT: usize;
|
||||
const PAGE_LEVELS: usize;
|
||||
const PAGE_OFFSET: usize;
|
||||
|
||||
const ENTRY_ADDRESS_SHIFT: usize;
|
||||
const ENTRY_FLAG_PRESENT: usize;
|
||||
@@ -23,6 +22,8 @@ pub trait Arch {
|
||||
const ENTRY_FLAG_GLOBAL: usize;
|
||||
const ENTRY_FLAG_NO_EXEC: usize;
|
||||
|
||||
const PHYS_OFFSET: usize;
|
||||
|
||||
const PAGE_SIZE: usize = 1 << Self::PAGE_SHIFT;
|
||||
const PAGE_OFFSET_MASK: usize = Self::PAGE_SIZE - 1;
|
||||
const PAGE_ADDRESS_SHIFT: usize = Self::PAGE_LEVELS * Self::PAGE_ENTRY_SHIFT + Self::PAGE_SHIFT;
|
||||
@@ -61,6 +62,6 @@ pub trait Arch {
|
||||
unsafe fn set_table(address: PhysicalAddress);
|
||||
|
||||
unsafe fn phys_to_virt(phys: PhysicalAddress) -> VirtualAddress {
|
||||
VirtualAddress::new(phys.data() + Self::PAGE_OFFSET)
|
||||
VirtualAddress::new(phys.data() + Self::PHYS_OFFSET)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -11,7 +11,6 @@ impl Arch for X8664Arch {
|
||||
const PAGE_SHIFT: usize = 12; // 4096 bytes
|
||||
const PAGE_ENTRY_SHIFT: usize = 9; // 512 entries, 8 bytes each
|
||||
const PAGE_LEVELS: usize = 4; // PML4, PDP, PD, PT
|
||||
const PAGE_OFFSET: usize = Self::PAGE_NEGATIVE_MASK; // PML4 slot 256 and onwards
|
||||
|
||||
const ENTRY_ADDRESS_SHIFT: usize = 52;
|
||||
const ENTRY_FLAG_PRESENT: usize = 1 << 0;
|
||||
@@ -21,6 +20,8 @@ impl Arch for X8664Arch {
|
||||
const ENTRY_FLAG_GLOBAL: usize = 1 << 8;
|
||||
const ENTRY_FLAG_NO_EXEC: usize = 1 << 63;
|
||||
|
||||
const PHYS_OFFSET: usize = Self::PAGE_NEGATIVE_MASK + (Self::PAGE_ADDRESS_SIZE >> 1); // PML4 slot 256 and onwards
|
||||
|
||||
unsafe fn init() -> &'static [MemoryArea] {
|
||||
unimplemented!()
|
||||
}
|
||||
@@ -63,5 +64,7 @@ mod tests {
|
||||
assert_eq!(X8664Arch::ENTRY_ADDRESS_SIZE, 0x0010_0000_0000_0000);
|
||||
assert_eq!(X8664Arch::ENTRY_ADDRESS_MASK, 0x000F_FFFF_FFFF_F000);
|
||||
assert_eq!(X8664Arch::ENTRY_FLAGS_MASK, 0xFFF0_0000_0000_0FFF);
|
||||
|
||||
assert_eq!(X8664Arch::PHYS_OFFSET, 0xFFFF_8000_0000_0000);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-10
@@ -40,17 +40,16 @@ impl<A: Arch> PageTable<A> {
|
||||
}
|
||||
|
||||
pub unsafe fn virt(&self) -> VirtualAddress {
|
||||
// Recursive mapping
|
||||
let mut addr = 0xFFFF_FFFF_FFFF_F000;
|
||||
for level in (self.level + 1 .. A::PAGE_LEVELS).rev() {
|
||||
let index = (self.base.0 >> (level * A::PAGE_ENTRY_SHIFT + A::PAGE_SHIFT)) & A::PAGE_ENTRY_MASK;
|
||||
addr <<= A::PAGE_ENTRY_SHIFT;
|
||||
addr |= index << A::PAGE_SHIFT;
|
||||
}
|
||||
VirtualAddress::new(addr)
|
||||
A::phys_to_virt(self.phys)
|
||||
|
||||
// Identity mapping
|
||||
//VirtualAddress(self.phys.0)
|
||||
// Recursive mapping
|
||||
// let mut addr = 0xFFFF_FFFF_FFFF_F000;
|
||||
// for level in (self.level + 1 .. A::PAGE_LEVELS).rev() {
|
||||
// let index = (self.base.0 >> (level * A::PAGE_ENTRY_SHIFT + A::PAGE_SHIFT)) & A::PAGE_ENTRY_MASK;
|
||||
// addr <<= A::PAGE_ENTRY_SHIFT;
|
||||
// addr |= index << A::PAGE_SHIFT;
|
||||
// }
|
||||
// VirtualAddress::new(addr)
|
||||
}
|
||||
|
||||
pub fn entry_base(&self, i: usize) -> Option<VirtualAddress> {
|
||||
|
||||
Reference in New Issue
Block a user