Implement PHYS_OFFSET mapping

This commit is contained in:
Jeremy Soller
2020-09-06 14:30:50 -06:00
parent a40b26293b
commit d5111d429e
4 changed files with 20 additions and 16 deletions
+4 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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> {