mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-11-27 12:15:19 +01:00
f35acfa5ab
Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
188 lines
8.2 KiB
C
188 lines
8.2 KiB
C
/**
|
|
x64 Long Mode Virtual Memory Management Definitions
|
|
|
|
References:
|
|
1) IA-32 Intel(R) Architecture Software Developer's Manual Volume 1:Basic Architecture, Intel
|
|
2) IA-32 Intel(R) Architecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel
|
|
3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel
|
|
4) AMD64 Architecture Programmer's Manual Volume 2: System Programming
|
|
|
|
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
Extended by dmazar.
|
|
|
|
**/
|
|
|
|
|
|
#define SYS_CODE64_SEL 0x38
|
|
|
|
#pragma pack(1)
|
|
|
|
//
|
|
// Page-Map Level-4 Offset (PML4) and
|
|
// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
|
|
//
|
|
|
|
typedef union {
|
|
struct {
|
|
UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
|
|
UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
|
|
UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
|
|
UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
|
|
UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
|
|
UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)
|
|
UINT64 Reserved:1; // Reserved
|
|
UINT64 MustBeZero:2; // Must Be Zero
|
|
UINT64 Available:3; // Available for use by system software
|
|
UINT64 PageTableBaseAddress:40; // Page Table Base Address
|
|
UINT64 AvabilableHigh:11; // Available for use by system software
|
|
UINT64 Nx:1; // No Execute bit
|
|
} Bits;
|
|
UINT64 Uint64;
|
|
} PAGE_MAP_AND_DIRECTORY_POINTER;
|
|
|
|
//
|
|
// Page Table Entry 4KB
|
|
//
|
|
typedef union {
|
|
struct {
|
|
UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
|
|
UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
|
|
UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
|
|
UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
|
|
UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
|
|
UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)
|
|
UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page
|
|
UINT64 PAT:1; //
|
|
UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
|
|
UINT64 Available:3; // Available for use by system software
|
|
UINT64 PageTableBaseAddress:40; // Page Table Base Address
|
|
UINT64 AvabilableHigh:11; // Available for use by system software
|
|
UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution
|
|
} Bits;
|
|
UINT64 Uint64;
|
|
} PAGE_TABLE_4K_ENTRY;
|
|
|
|
//
|
|
// Page Table Entry 2MB
|
|
//
|
|
typedef union {
|
|
struct {
|
|
UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
|
|
UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
|
|
UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
|
|
UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
|
|
UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
|
|
UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)
|
|
UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page
|
|
UINT64 MustBe1:1; // Must be 1
|
|
UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
|
|
UINT64 Available:3; // Available for use by system software
|
|
UINT64 PAT:1; //
|
|
UINT64 MustBeZero:8; // Must be zero;
|
|
UINT64 PageTableBaseAddress:31; // Page Table Base Address
|
|
UINT64 AvabilableHigh:11; // Available for use by system software
|
|
UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution
|
|
} Bits;
|
|
UINT64 Uint64;
|
|
} PAGE_TABLE_2M_ENTRY;
|
|
|
|
//
|
|
// Page Table Entry 1GB
|
|
//
|
|
typedef union {
|
|
struct {
|
|
UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
|
|
UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
|
|
UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
|
|
UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
|
|
UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
|
|
UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)
|
|
UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page
|
|
UINT64 MustBe1:1; // Must be 1
|
|
UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
|
|
UINT64 Available:3; // Available for use by system software
|
|
UINT64 PAT:1; //
|
|
UINT64 MustBeZero:17; // Must be zero;
|
|
UINT64 PageTableBaseAddress:22; // Page Table Base Address
|
|
UINT64 AvabilableHigh:11; // Available for use by system software
|
|
UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution
|
|
} Bits;
|
|
UINT64 Uint64;
|
|
} PAGE_TABLE_1G_ENTRY;
|
|
|
|
typedef union {
|
|
struct {
|
|
UINT64 PhysPgOffset:12; // 0 = Physical Page Offset
|
|
UINT64 PTOffset:9; // 0 = Page Table Offset
|
|
UINT64 PDOffset:9; // 0 = Page Directory Offset
|
|
UINT64 PDPOffset:9; // 0 = Page Directory Pointer Offset
|
|
UINT64 PML4Offset:9; // 0 = Page Map Level 4 Offset
|
|
UINT64 SignExtend:16; // 0 = Sign Extend
|
|
} Pg4K;
|
|
struct {
|
|
UINT64 PhysPgOffset:21; // 0 = Physical Page Offset
|
|
UINT64 PDOffset:9; // 0 = Page Directory Offset
|
|
UINT64 PDPOffset:9; // 0 = Page Directory Pointer Offset
|
|
UINT64 PML4Offset:9; // 0 = Page Map Level 4 Offset
|
|
UINT64 SignExtend:16; // 0 = Sign Extend
|
|
} Pg2M;
|
|
struct {
|
|
UINT64 PhysPgOffset:30; // 0 = Physical Page Offset
|
|
UINT64 PDPOffset:9; // 0 = Page Directory Pointer Offset
|
|
UINT64 PML4Offset:9; // 0 = Page Map Level 4 Offset
|
|
UINT64 SignExtend:16; // 0 = Sign Extend
|
|
} Pg1G;
|
|
UINT64 Uint64;
|
|
} VIRTUAL_ADDR;
|
|
|
|
#define VA_FIX_SIGN_EXTEND(VA) VA.Pg4K.SignExtend = (VA.Pg4K.PML4Offset & 0x100) ? 0xFFFF : 0;
|
|
|
|
#pragma pack()
|
|
|
|
|
|
// 64 bit
|
|
#define CR3_ADDR_MASK 0x000FFFFFFFFFF000
|
|
#define CR3_FLAG_PWT 0x0000000000000008
|
|
#define CR3_FLAG_PCD 0x0000000000000010
|
|
|
|
#define PT_ADDR_MASK_4K 0x000FFFFFFFFFF000
|
|
#define PT_ADDR_MASK_2M 0x000FFFFFFFE00000
|
|
#define PT_ADDR_MASK_1G 0x000FFFFFC0000000
|
|
|
|
|
|
/** Returns pointer to PML4 table in PageTable and PWT and PCD flags in Flags. */
|
|
VOID
|
|
GetCurrentPageTable(PAGE_MAP_AND_DIRECTORY_POINTER **PageTable, UINTN *Flags);
|
|
|
|
/** Prints given PageTable. */
|
|
VOID
|
|
PrintPageTable(PAGE_MAP_AND_DIRECTORY_POINTER *PageTable, UINTN Flags);
|
|
|
|
/** Returns physical addr for given virtual addr. */
|
|
EFI_STATUS
|
|
GetPhysicalAddr(PAGE_MAP_AND_DIRECTORY_POINTER *PageTable, EFI_VIRTUAL_ADDRESS VirtualAddr, EFI_PHYSICAL_ADDRESS *PhysicalAddr);
|
|
|
|
/** Inits vm memory pool. Should be called while boot services are still usable. */
|
|
EFI_STATUS
|
|
VmAllocateMemoryPool(VOID);
|
|
|
|
/** Maps (remaps) 4K page given by VirtualAddr to PhysicalAddr page in PageTable. */
|
|
EFI_STATUS
|
|
VmMapVirtualPage(PAGE_MAP_AND_DIRECTORY_POINTER *PageTable, EFI_VIRTUAL_ADDRESS VirtualAddr, EFI_PHYSICAL_ADDRESS PhysicalAddr);
|
|
|
|
/** Maps (remaps) NumPages 4K pages given by VirtualAddr to PhysicalAddr pages in PageTable. */
|
|
EFI_STATUS
|
|
VmMapVirtualPages(PAGE_MAP_AND_DIRECTORY_POINTER *PageTable, EFI_VIRTUAL_ADDRESS VirtualAddr, UINTN NumPages, EFI_PHYSICAL_ADDRESS PhysicalAddr);
|
|
|
|
/** Flashes TLB caches. */
|
|
VOID
|
|
VmFlashCaches(VOID);
|