diff --git a/src/arch/emulate.rs b/src/arch/emulate.rs index 40274c6633..6cf7c9d606 100644 --- a/src/arch/emulate.rs +++ b/src/arch/emulate.rs @@ -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::(PhysicalAddress::new(pml4), pdp | flags); - // Recursive mapping - machine.write_phys::(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::(PhysicalAddress::new(pml4 + 256 * Self::PAGE_ENTRY_SIZE), pdp | flags); // PDP link to PD let pd = pdp + Self::PAGE_SIZE; diff --git a/src/arch/mod.rs b/src/arch/mod.rs index a53d7e8a92..21a88f6368 100644 --- a/src/arch/mod.rs +++ b/src/arch/mod.rs @@ -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) } } diff --git a/src/arch/x86_64.rs b/src/arch/x86_64.rs index a718b273e8..f5d3bf084b 100644 --- a/src/arch/x86_64.rs +++ b/src/arch/x86_64.rs @@ -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); } } diff --git a/src/page/table.rs b/src/page/table.rs index 15a13f34d7..38691e0e3f 100644 --- a/src/page/table.rs +++ b/src/page/table.rs @@ -40,17 +40,16 @@ impl PageTable { } 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 {