diff --git a/sdk/xtdk/amd64/arfuncs.h b/sdk/xtdk/amd64/arfuncs.h index 50ebe29..72a9d2c 100644 --- a/sdk/xtdk/amd64/arfuncs.h +++ b/sdk/xtdk/amd64/arfuncs.h @@ -24,6 +24,10 @@ XTCDECL BOOLEAN ArCpuId(IN OUT PCPUID_REGISTERS Registers); +XTCDECL +VOID +ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap); + XTCDECL VOID ArHalt(VOID); diff --git a/sdk/xtdk/amd64/artypes.h b/sdk/xtdk/amd64/artypes.h index a6196b1..b9fdedd 100644 --- a/sdk/xtdk/amd64/artypes.h +++ b/sdk/xtdk/amd64/artypes.h @@ -39,13 +39,22 @@ #define CR4_PCE 0x00000100 #define CR4_FXSR 0x00000200 #define CR4_XMMEXCPT 0x00000400 +#define CR4_UMIP 0x00000800 #define CR4_LA57 0x00001000 -#define CR4_RESERVED1 0x00001800 #define CR4_VMXE 0x00002000 #define CR4_SMXE 0x00004000 -#define CR4_RESERVED2 0x00018000 -#define CR4_XSAVE 0x00020000 -#define CR4_RESERVED3 0xFFFC0000 +#define CR4_FSGSBASE 0x00010000 +#define CR4_PCIDE 0x00020000 +#define CR4_XSAVE 0x00040000 +#define CR4_KL 0x00080000 +#define CR4_SMEP 0x00100000 +#define CR4_SMAP 0x00200000 +#define CR4_PKE 0x00400000 +#define CR4_CET 0x00800000 +#define CR4_PKS 0x01000000 +#define CR4_UINTR 0x02000000 +#define CR4_LASS 0x08000000 +#define CR4_LAM_SUP 0x10000000 /* Descriptors size */ #define GDT_ENTRIES 128 @@ -84,6 +93,7 @@ #define X86_MSR_FSBASE 0xC0000100 #define X86_MSR_GSBASE 0xC0000101 #define X86_MSR_KERNEL_GSBASE 0xC0000102 +#define X86_MSR_TSC_AUX 0xC0000103 /* Processor features in the EFER MSR */ #define X86_MSR_EFER_SCE (1 << 0) @@ -91,6 +101,10 @@ #define X86_MSR_EFER_LMA (1 << 10) #define X86_MSR_EFER_NXE (1 << 11) #define X86_MSR_EFER_SVME (1 << 12) +#define X86_EFER_LMSLE (1 << 13) +#define X86_EFER_FFXSR (1 << 14) +#define X86_EFER_TCE (1 << 15) +#define X86_EFER_AUTOIBRS (1 << 21) /* X86 EFLAG bit masks definitions */ #define X86_EFLAGS_NF_MASK 0x00000000 /* None */ diff --git a/sdk/xtdk/amd64/mmtypes.h b/sdk/xtdk/amd64/mmtypes.h index a961e37..3b8db1f 100644 --- a/sdk/xtdk/amd64/mmtypes.h +++ b/sdk/xtdk/amd64/mmtypes.h @@ -18,11 +18,18 @@ #define MM_PAGE_SHIFT 12L #define MM_PAGE_SIZE 4096 -/* Page directory and page base addresses */ -#define MM_PTE_BASE 0xFFFFF68000000000UI64 -#define MM_PDE_BASE 0xFFFFF6FB40000000UI64 -#define MM_PPE_BASE 0xFFFFF6FB7DA00000UI64 -#define MM_PXE_BASE 0xFFFFF6FB7DBED000UI64 +/* Page directory and page base addresses for 4-level paging */ +#define MM_PTE_BASE 0xFFFFF68000000000ULL +#define MM_PDE_BASE 0xFFFFF6FB40000000ULL +#define MM_PPE_BASE 0xFFFFF6FB7DA00000ULL +#define MM_PXE_BASE 0xFFFFF6FB7DBED000ULL + +/* Page directory and page base addresses for 5-level paging */ +#define MM_PTE_LA57_BASE 0xFFFF000000000000ULL +#define MM_PDE_LA57_BASE 0xFFFF010000000000ULL +#define MM_PPE_LA57_BASE 0xFFFF010800000000ULL +#define MM_PXE_LA57_BASE 0xFFFF010840000000ULL +#define MM_P5E_LA57_BASE 0xFFFF010840200000ULL /* PTE shift values */ #define MM_PTE_SHIFT 3 @@ -30,7 +37,7 @@ #define MM_PDI_SHIFT 21 #define MM_PPI_SHIFT 30 #define MM_PXI_SHIFT 39 -#define MM_LA57_SHIFT 48 +#define MM_P5I_SHIFT 48 /* Number of PTEs per page */ #define MM_PTE_PER_PAGE 512 @@ -54,7 +61,10 @@ #define MM_HARDWARE_VA_START 0xFFFFFFFFFFC00000ULL /* Maximum physical address used by HAL allocations */ -#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFF +#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFFULL + +/* Trampoline code address */ +#define MM_TRAMPOLINE_ADDRESS 0x80000 /* Page size enumeration list */ typedef enum _PAGE_SIZE @@ -85,6 +95,18 @@ typedef struct _HARDWARE_PTE ULONGLONG NoExecute:1; } HARDWARE_PTE, *PHARDWARE_PTE; +/* Page map information structure definition */ +typedef struct _MMPAGEMAP_INFO +{ + BOOLEAN Xpa; + ULONGLONG PteBase; + ULONGLONG PdeBase; + ULONGLONG PpeBase; + ULONGLONG PxeBase; + ULONGLONG P5eBase; + ULONG VaBits; +} MMPAGEMAP_INFO, *PMMPAGEMAP_INFO; + /* A Page Table Entry on AMD64 system */ typedef struct _MMPTE_HARDWARE { diff --git a/sdk/xtdk/amd64/xtstruct.h b/sdk/xtdk/amd64/xtstruct.h index 282c29b..1403809 100644 --- a/sdk/xtdk/amd64/xtstruct.h +++ b/sdk/xtdk/amd64/xtstruct.h @@ -51,6 +51,7 @@ typedef struct _KSWITCH_FRAME KSWITCH_FRAME, *PKSWITCH_FRAME; typedef struct _KTHREAD_INIT_FRAME KTHREAD_INIT_FRAME, *PKTHREAD_INIT_FRAME; typedef struct _KTRAP_FRAME KTRAP_FRAME, *PKTRAP_FRAME; typedef struct _KTSS KTSS, *PKTSS; +typedef struct _MMPAGEMAP_INFO MMPAGEMAP_INFO, *PMMPAGEMAP_INFO; typedef struct _MMPFN MMPFN, *PMMPFN; typedef struct _MMPTE_HARDWARE MMPTE_HARDWARE, *PMMPTE_HARDWARE; typedef struct _MMPTE_HARDWARE_LARGEPAGE MMPTE_HARDWARE_LARGEPAGE, *PMMPTE_HARDWARE_LARGEPAGE; @@ -66,6 +67,7 @@ typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER; typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER; typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER; typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER; +typedef union _MMPTE MMP5E, *PMMP5E; typedef union _MMPTE MMPDE, *PMMPDE; typedef union _MMPTE MMPPE, *PMMPPE; typedef union _MMPTE MMPTE, *PMMPTE; diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index ffd467c..42ffaa3 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -43,7 +43,7 @@ typedef LONG (*PBL_GET_MEMTYPE_ROUTINE)(IN EFI_MEMORY_TYPE EfiMemoryType); /* Boot Loader protocol routine pointers */ -typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN ULONGLONG Size, OUT PEFI_PHYSICAL_ADDRESS Memory); +typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN EFI_ALLOCATE_TYPE AllocationType, IN ULONGLONG Size, OUT PEFI_PHYSICAL_ADDRESS Memory); typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory); typedef EFI_STATUS (*PBL_BOOTMENU_INITIALIZE_OS_LIST)(OUT PXTBL_BOOTMENU_ITEM *MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); typedef BOOLEAN (*PBL_BOOTUTIL_GET_BOOLEAN_PARAMETER)(IN CONST PWCHAR Parameters, IN CONST PWCHAR Needle); diff --git a/sdk/xtdk/i686/artypes.h b/sdk/xtdk/i686/artypes.h index 1f818dd..0c4da8b 100644 --- a/sdk/xtdk/i686/artypes.h +++ b/sdk/xtdk/i686/artypes.h @@ -39,13 +39,22 @@ #define CR4_PCE 0x00000100 #define CR4_FXSR 0x00000200 #define CR4_XMMEXCPT 0x00000400 +#define CR4_UMIP 0x00000800 #define CR4_LA57 0x00001000 -#define CR4_RESERVED1 0x00001800 #define CR4_VMXE 0x00002000 #define CR4_SMXE 0x00004000 -#define CR4_RESERVED2 0x00018000 -#define CR4_XSAVE 0x00020000 -#define CR4_RESERVED3 0xFFFC0000 +#define CR4_FSGSBASE 0x00010000 +#define CR4_PCIDE 0x00020000 +#define CR4_XSAVE 0x00040000 +#define CR4_KL 0x00080000 +#define CR4_SMEP 0x00100000 +#define CR4_SMAP 0x00200000 +#define CR4_PKE 0x00400000 +#define CR4_CET 0x00800000 +#define CR4_PKS 0x01000000 +#define CR4_UINTR 0x02000000 +#define CR4_LASS 0x08000000 +#define CR4_LAM_SUP 0x10000000 /* Descriptors size */ #define GDT_ENTRIES 128 diff --git a/sdk/xtdk/i686/mmtypes.h b/sdk/xtdk/i686/mmtypes.h index eb97748..027fc1a 100644 --- a/sdk/xtdk/i686/mmtypes.h +++ b/sdk/xtdk/i686/mmtypes.h @@ -28,7 +28,11 @@ #define MM_PDI_SHIFT 21 #define MM_PPI_SHIFT 30 +/* Page directory and page base legacy address */ +#define MM_PDE_LEGACY_BASE 0xC0300000 + /* PTE legacy shift values */ +#define MM_PTE_LEGACY_SHIFT 2 #define MM_PDI_LEGACY_SHIFT 22 /* Minimum number of physical pages needed by the system */ @@ -49,6 +53,8 @@ /* Maximum physical address used by HAL allocations */ #define MM_MAXIMUM_PHYSICAL_ADDRESS 0xFFFFFFFF +/* Trampoline code address */ +#define MM_TRAMPOLINE_ADDRESS 0x80000 /* Page size enumeration list */ typedef enum _PAGE_SIZE @@ -58,8 +64,26 @@ typedef enum _PAGE_SIZE Size4M } PAGE_SIZE, *PPAGE_SIZE; -/* Page Table entry structure definition (with PAE support) */ -typedef struct _HARDWARE_PTE +/* Legacy Page Table entry structure definition (PML2) */ +typedef struct _HARDWARE_LEGACY_PTE +{ + ULONG Valid:1; + ULONG Writable:1; + ULONG Owner:1; + ULONG WriteThrough:1; + ULONG CacheDisable:1; + ULONG Accessed:1; + ULONG Dirty:1; + ULONG LargePage:1; + ULONG Global:1; + ULONG CopyOnWrite:1; + ULONG Prototype:1; + ULONG Reserved0:1; + ULONG PageFrameNumber:20; +} HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE; + +/* Page Table entry structure definition (PML3) */ +typedef struct _HARDWARE_MODERN_PTE { ULONGLONG Valid:1; ULONGLONG Writable:1; @@ -77,10 +101,117 @@ typedef struct _HARDWARE_PTE ULONGLONG Reserved1:14; ULONGLONG SoftwareWsIndex:11; ULONGLONG NoExecute:1; +} HARDWARE_MODERN_PTE, *PHARDWARE_MODERN_PTE; + +/* Generic Page Table entry union to abstract PML2 and PML3 formats */ +typedef union _HARDWARE_PTE +{ + ULONGLONG Long; + HARDWARE_LEGACY_PTE Pml2; + HARDWARE_MODERN_PTE Pml3; } HARDWARE_PTE, *PHARDWARE_PTE; -/* Page Table Entry on PAE enabled system */ -typedef struct _MMPTE_HARDWARE +/* Page map information structure definition */ +typedef struct _MMPAGEMAP_INFO +{ + BOOLEAN Xpa; + ULONG PteBase; + ULONG PdeBase; + ULONG PdiShift; + ULONG PteShift; +} MMPAGEMAP_INFO, *PMMPAGEMAP_INFO; + +/* Legacy Page Table Entry hardware structure definition (PML2) */ +typedef struct _MMPML2_PTE_HARDWARE +{ + ULONG Valid:1; + ULONG Writable:1; + ULONG Owner:1; + ULONG WriteThrough:1; + ULONG CacheDisable:1; + ULONG Accessed:1; + ULONG Dirty:1; + ULONG LargePage:1; + ULONG Global:1; + ULONG CopyOnWrite:1; + ULONG Prototype:1; + ULONG Write:1; + ULONG PageFrameNumber:20; +} MMPML2_PTE_HARDWARE, *PMMPML2_PTE_HARDWARE; + +/* Legacy Page Table Entry list structure definition (PML2) */ +typedef struct _MMPML2_PTE_LIST +{ + ULONG Valid:1; + ULONG OneEntry:1; + ULONG Reserved0:8; + ULONG Prototype:1; + ULONG Reserved1:1; + ULONG NextEntry:20; +} MMPML2_PTE_LIST, *PMMPML2_PTE_LIST; + +/* Legacy Page Table Entry subsection structure definition (PML2) */ +typedef struct _MMPML2_PTE_PROTOTYPE +{ + ULONG Valid:1; + ULONG ProtoAddressLow:7; + ULONG ReadOnly:1; + ULONG WhichPool:1; + ULONG Prototype:1; + ULONG ProtoAddressHigh:21; +} MMPML2_PTE_PROTOTYPE, *PMMPML2_PTE_PROTOTYPE; + +/* Legacy Page Table Entry software structure definition (PML2) */ +typedef struct _MMPML2_PTE_SOFTWARE +{ + ULONG Valid:1; + ULONG PageFileLow:4; + ULONG Protection:5; + ULONG Prototype:1; + ULONG Transition:1; + ULONG PageFileHigh:20; +} MMPML2_PTE_SOFTWARE, *PMMPML2_PTE_SOFTWARE; + +/* Legacy Page Table Entry subsection structure definition (PML2) */ +typedef struct _MMPML2_PTE_SUBSECTION +{ + ULONG Valid:1; + ULONG SubsectionAddressLow:4; + ULONG Protection:5; + ULONG Prototype:1; + ULONG SubsectionAddressHigh:20; + ULONG WhichPool:1; +} MMPML2_PTE_SUBSECTION, *PMMPML2_PTE_SUBSECTION; + +/* Legacy Page Table Entry transition structure definition (PML2) */ +typedef struct _MMPML2_PTE_TRANSITION +{ + ULONG Valid:1; + ULONG Write:1; + ULONG Owner:1; + ULONG WriteThrough:1; + ULONG CacheDisable:1; + ULONG Protection:5; + ULONG Prototype:1; + ULONG Transition:1; + ULONG PageFrameNumber:20; +} MMPML2_PTE_TRANSITION, *PMMPML2_PTE_TRANSITION; + +/* Legacy Page Table Entry union definition (PML2) */ +typedef union _MMPML2_PTE +{ + ULONG Long; + HARDWARE_PTE Flush; + MMPML2_PTE_HARDWARE Hard; + MMPML2_PTE_PROTOTYPE Proto; + MMPML2_PTE_SOFTWARE Soft; + MMPML2_PTE_TRANSITION Trans; + MMPML2_PTE_SUBSECTION Subsect; + MMPML2_PTE_LIST List; +} MMPML2_PTE, *PMMPML2_PTE; + +/* Page Table Entry hardware structure definition (PML3) */ +typedef struct _MMPML3_PTE_HARDWARE { ULONGLONG Valid:1; ULONGLONG Writable:1; @@ -95,59 +226,59 @@ typedef struct _MMPTE_HARDWARE ULONGLONG Prototype:1; ULONGLONG Write:1; ULONGLONG PageFrameNumber:26; - ULONGLONG Reserved1:25; + ULONGLONG Reserved0:25; ULONGLONG NoExecute:1; -} MMPTE_HARDWARE, *PMMPTE_HARDWARE; +} MMPML3_PTE_HARDWARE, *PMMPML3_PTE_HARDWARE; -/* Page Table Entry list structure definition (with PAE support) */ -typedef struct _MMPTE_LIST +/* Page Table Entry list structure definition (PML3) */ +typedef struct _MMPML3_PTE_LIST { ULONGLONG Valid:1; ULONGLONG OneEntry:1; - ULONGLONG Reserved1:8; + ULONGLONG Reserved0:8; ULONGLONG Prototype:1; - ULONGLONG Reserved2:21; + ULONGLONG Reserved1:21; ULONGLONG NextEntry:32; -} MMPTE_LIST, *PMMPTE_LIST; +} MMPML3_PTE_LIST, *PMMPML3_PTE_LIST; -/* Page Table Entry subsection structure definition (with PAE support) */ -typedef struct _MMPTE_PROTOTYPE +/* Page Table Entry subsection structure definition (PML3) */ +typedef struct _MMPML3_PTE_PROTOTYPE { ULONGLONG Valid:1; - ULONGLONG Reserved1:7; + ULONGLONG Reserved0:7; ULONGLONG ReadOnly:1; - ULONGLONG Reserved2:1; + ULONGLONG Reserved1:1; ULONGLONG Prototype:1; ULONGLONG Protection:5; - ULONGLONG Reserved3:16; + ULONGLONG Reserved2:16; ULONGLONG ProtoAddress:32; -} MMPTE_PROTOTYPE, *PMMPTE_PROTOTYPE; +} MMPML3_PTE_PROTOTYPE, *PMMPML3_PTE_PROTOTYPE; -/* Page Table Entry software structure definition (with PAE support) */ -typedef struct _MMPTE_SOFTWARE +/* Page Table Entry software structure definition (PML3) */ +typedef struct _MMPML3_PTE_SOFTWARE { ULONGLONG Valid:1; ULONGLONG PageFileLow:4; ULONGLONG Protection:5; ULONGLONG Prototype:1; ULONGLONG Transition:1; - ULONGLONG Reserved1:20; + ULONGLONG Reserved0:20; ULONGLONG PageFileHigh:32; -} MMPTE_SOFTWARE, *PMMPTE_SOFTWARE; +} MMPML3_PTE_SOFTWARE, *PMMPML3_PTE_SOFTWARE; -/* Page Table Entry subsection structure definition (with PAE support) */ -typedef struct _MMPTE_SUBSECTION +/* Page Table Entry subsection structure definition (PML3) */ +typedef struct _MMPML3_PTE_SUBSECTION { ULONGLONG Valid:1; - ULONGLONG Reserved1:4; + ULONGLONG Reserved0:4; ULONGLONG Protection:5; ULONGLONG Prototype:1; - ULONGLONG Reserved2:21; + ULONGLONG Reserved1:21; ULONGLONG SubsectionAddress:32; -} MMPTE_SUBSECTION, *PMMPTE_SUBSECTION; +} MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSECTION; -/* Page Table Entry transition structure definition (with PAE support) */ -typedef struct _MMPTE_TRANSITION +/* Page Table Entry transition structure definition (PML3) */ +typedef struct _MMPML3_PTE_TRANSITION { ULONGLONG Valid:1; ULONGLONG Write:1; @@ -159,38 +290,28 @@ typedef struct _MMPTE_TRANSITION ULONGLONG Transition:1; ULONGLONG PageFrameNumber:26; ULONGLONG Unused:26; -} MMPTE_TRANSITION, *PMMPTE_TRANSITION; +} MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION; -/* Page Table Entry structure definition (with PAE support) */ -typedef union _MMPTE +/* Page Table Entry union definition (PML3) */ +typedef union _MMPML3_PTE { ULONGLONG Long; HARDWARE_PTE Flush; - MMPTE_HARDWARE Hardware; - MMPTE_PROTOTYPE Prototype; - MMPTE_SOFTWARE Software; - MMPTE_TRANSITION Transition; - MMPTE_SUBSECTION Subsection; - MMPTE_LIST List; -} MMPTE, *PMMPTE; + MMPML3_PTE_HARDWARE Hardware; + MMPML3_PTE_PROTOTYPE Prototype; + MMPML3_PTE_SOFTWARE Software; + MMPML3_PTE_TRANSITION Transition; + MMPML3_PTE_SUBSECTION Subsection; + MMPML3_PTE_LIST List; +} MMPML3_PTE, *PMMPML3_PTE; -/* Legacy Page Table entry structure definition (without PAE support) */ -typedef struct _HARDWARE_LEGACY_PTE +/* Generic Page Table Entry union to abstract PML2 and PML3 formats */ +typedef union _MMPTE { - ULONG Valid:1; - ULONG Writable:1; - ULONG Owner:1; - ULONG WriteThrough:1; - ULONG CacheDisable:1; - ULONG Accessed:1; - ULONG Dirty:1; - ULONG LargePage:1; - ULONG Global:1; - ULONG CopyOnWrite:1; - ULONG Prototype:1; - ULONG Reserved0:1; - ULONG PageFrameNumber:20; -} HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE; + ULONGLONG Long; + MMPML2_PTE Pml2; + MMPML3_PTE Pml3; +} MMPTE, *PMMPTE; /* Page Frame Number structure definition */ typedef struct _MMPFN diff --git a/sdk/xtdk/i686/xtstruct.h b/sdk/xtdk/i686/xtstruct.h index 3fd7ff5..bd93426 100644 --- a/sdk/xtdk/i686/xtstruct.h +++ b/sdk/xtdk/i686/xtstruct.h @@ -40,7 +40,7 @@ typedef struct _FN_SAVE_FORMAT FN_SAVE_FORMAT, *PFN_SAVE_FORMAT; typedef struct _FX_SAVE_AREA FX_SAVE_AREA, *PFX_SAVE_AREA; typedef struct _FX_SAVE_FORMAT FX_SAVE_FORMAT, *PFX_SAVE_FORMAT; typedef struct _HARDWARE_LEGACY_PTE HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE; -typedef struct _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE; +typedef struct _HARDWARE_MODERN_PTE HARDWARE_MODERN_PTE, *PHARDWARE_MODERN_PTE; typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR; typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME; typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY; @@ -55,13 +55,20 @@ typedef struct _KSWITCH_FRAME KSWITCH_FRAME, *PKSWITCH_FRAME; typedef struct _KTHREAD_INIT_FRAME KTHREAD_INIT_FRAME, *PKTHREAD_INIT_FRAME; typedef struct _KTRAP_FRAME KTRAP_FRAME, *PKTRAP_FRAME; typedef struct _KTSS KTSS, *PKTSS; +typedef struct _MMPAGEMAP_INFO MMPAGEMAP_INFO, *PMMPAGEMAP_INFO; typedef struct _MMPFN MMPFN, *PMMPFN; -typedef struct _MMPTE_HARDWARE MMPTE_HARDWARE, *PMMPTE_HARDWARE; -typedef struct _MMPTE_LIST MMPTE_LIST, *PMMPTE_LIST; -typedef struct _MMPTE_PROTOTYPE MMPTE_PROTOTYPE, *PMMPTE_PROTOTYPE; -typedef struct _MMPTE_SOFTWARE MMPTE_SOFTWARE, *PMMPTE_SOFTWARE; -typedef struct _MMPTE_SUBSECTION MMPTE_SUBSECTION, *PMMPTE_SUBSECTION; -typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION; +typedef struct _MMPML2_PTE_HARDWARE MMPML2_PTE_HARDWARE, *PMMPML2_PTE_HARDWARE; +typedef struct _MMPML2_PTE_LIST MMPML2_PTE_LIST, *PMMPML2_PTE_LIST; +typedef struct _MMPML2_PTE_PROTOTYPE MMPML2_PTE_PROTOTYPE, *PMMPML2_PTE_PROTOTYPE; +typedef struct _MMPML2_PTE_SOFTWARE MMPML2_PTE_SOFTWARE, *PMMPML2_PTE_SOFTWARE; +typedef struct _MMPML2_PTE_SUBSECTION MMPML2_PTE_SUBSECTION, *PMMPML2_PTE_SUBSECTION; +typedef struct _MMPML2_PTE_TRANSITION MMPML2_PTE_TRANSITION, *PMMPML2_PTE_TRANSITION; +typedef struct _MMPML3_PTE_HARDWARE MMPML3_PTE_HARDWARE, *PMMPML3_PTE_HARDWARE; +typedef struct _MMPML3_PTE_LIST MMPML3_PTE_LIST, *PMMPML3_PTE_LIST; +typedef struct _MMPML3_PTE_PROTOTYPE MMPML3_PTE_PROTOTYPE, *PMMPML3_PTE_PROTOTYPE; +typedef struct _MMPML3_PTE_SOFTWARE MMPML3_PTE_SOFTWARE, *PMMPML3_PTE_SOFTWARE; +typedef struct _MMPML3_PTE_SUBSECTION MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSECTION; +typedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION; typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK; /* Unions forward references */ @@ -69,12 +76,15 @@ typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER; typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER; typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER; typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER; +typedef union _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE; +typedef union _MMPML2_PTE MMPML2_PTE, *PMMPML2_PTE; +typedef union _MMPML3_PTE MMPML3_PTE, *PMMPML3_PTE; typedef union _MMPTE MMPDE, *PMMPDE; +typedef union _MMPTE MMPPE, *PMMPPE; typedef union _MMPTE MMPTE, *PMMPTE; typedef union _PIC_I8259_ICW1 PIC_I8259_ICW1, *PPIC_I8259_ICW1; typedef union _PIC_I8259_ICW2 PIC_I8259_ICW2, *PPIC_I8259_ICW2; typedef union _PIC_I8259_ICW3 PIC_I8259_ICW3, *PPIC_I8259_ICW3; typedef union _PIC_I8259_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4; - #endif /* __XTDK_I686_XTSTRUCT_H */ diff --git a/sdk/xtdk/mmtypes.h b/sdk/xtdk/mmtypes.h index acbf7ed..2cddd97 100644 --- a/sdk/xtdk/mmtypes.h +++ b/sdk/xtdk/mmtypes.h @@ -10,8 +10,18 @@ #define __XTDK_MMTYPES_H #include +#include ARCH_HEADER(xtstruct.h) +/* Page map routines structure definition */ +typedef CONST STRUCT _CMMPAGEMAP_ROUTINES +{ + VOID (XTAPI *ClearPte)(PHARDWARE_PTE PtePointer); + BOOLEAN (XTAPI *PteValid)(PHARDWARE_PTE PtePointer); + VOID (XTAPI *SetPteCaching)(PHARDWARE_PTE PtePointer, BOOLEAN CacheDisable, BOOLEAN WriteThrough); + VOID (XTAPI *SetPte)(PHARDWARE_PTE PtePointer, PFN_NUMBER PageFrameNumber, BOOLEAN Writable); +} CMMPAGEMAP_ROUTINES, *PCMMPAGEMAP_ROUTINES; + /* Color tables structure definition */ typedef struct _MMCOLOR_TABLES { diff --git a/sdk/xtdk/xtfw.h b/sdk/xtdk/xtfw.h index 925d429..1a4642a 100644 --- a/sdk/xtdk/xtfw.h +++ b/sdk/xtdk/xtfw.h @@ -89,7 +89,6 @@ typedef struct _FIRMWARE_INFORMATION_BLOCK typedef struct _LOADER_INFORMATION_BLOCK { PVOID DbgPrint; - ULONG PageMapLevel; } LOADER_INFORMATION_BLOCK, *PLOADER_INFORMATION_BLOCK; /* Boot Loader memory mapping information */ diff --git a/sdk/xtdk/xtstruct.h b/sdk/xtdk/xtstruct.h index 21b7464..a5043ba 100644 --- a/sdk/xtdk/xtstruct.h +++ b/sdk/xtdk/xtstruct.h @@ -69,6 +69,7 @@ typedef struct _ANSI_STRING ANSI_STRING, *PANSI_STRING; typedef struct _ANSI_STRING32 ANSI_STRING32, *PANSI_STRING32; typedef struct _ANSI_STRING64 ANSI_STRING64, *PANSI_STRING64; typedef struct _CPPORT CPPORT, *PCPPORT; +typedef const struct _CMMPAGEMAP_ROUTINES CMMPAGEMAP_ROUTINES, *PCMMPAGEMAP_ROUTINES; typedef struct _CSTRING CSTRING, *PCSTRING; typedef struct _EFI_1394_DEVICE_PATH EFI_1394_DEVICE_PATH, *PEFI_1394_DEVICE_PATH; typedef struct _EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR, *PEFI_ACPI_ADDRESS_SPACE_DESCRIPTOR; diff --git a/xtldr/arch/amd64/memory.c b/xtldr/arch/amd64/memory.c index 1b6a6c6..c94e735 100644 --- a/xtldr/arch/amd64/memory.c +++ b/xtldr/arch/amd64/memory.c @@ -35,7 +35,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, EFI_STATUS Status; /* Allocate pages for the Page Map */ - Status = BlAllocateMemoryPages(1, &Address); + Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -54,6 +54,15 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, return Status; } + /* Map the trampoline code area */ + Status = BlMapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS, + 1, LoaderFirmwareTemporary); + if(Status != STATUS_EFI_SUCCESS) + { + /* Mapping trampoline code failed */ + return Status; + } + /* Get list of XTLDR modules */ ModulesList = BlGetModulesList(); ModulesListEntry = ModulesList->Flink; @@ -167,7 +176,7 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap, while(NumberOfPages > 0) { /* Calculate the indices in the various Page Tables from the virtual address */ - Pml5Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_LA57_SHIFT)) >> MM_LA57_SHIFT; + Pml5Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_P5I_SHIFT)) >> MM_P5I_SHIFT; Pml4Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PXI_SHIFT)) >> MM_PXI_SHIFT; Pml3Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PPI_SHIFT)) >> MM_PPI_SHIFT; Pml2Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PDI_SHIFT)) >> MM_PDI_SHIFT; @@ -279,7 +288,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, else { /* Allocate pages for new PML entry */ - Status = BlAllocateMemoryPages(1, &Address); + Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -338,22 +347,21 @@ BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, /* Check page map level */ if(PageMap->PageMapLevel == 5) { - /* Self-mapping for PML5 is not supported */ - BlDebugPrint(L"PML5 self-mapping not supported yet!\n"); - return STATUS_EFI_UNSUPPORTED; + /* Calculate PML index based on provided self map address for PML5 */ + PmlIndex = (SelfMapAddress >> MM_P5I_SHIFT) & 0x1FF; } else { - /* Calculate PML index based on provided self map address */ + /* Calculate PML index based on provided self map address for PML4 */ PmlIndex = (SelfMapAddress >> MM_PXI_SHIFT) & 0x1FF; - - /* Add self-mapping for PML4 */ - RtlZeroMemory(&PmlBase[PmlIndex], sizeof(HARDWARE_PTE)); - PmlBase[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE; - PmlBase[PmlIndex].Valid = 1; - PmlBase[PmlIndex].Writable = 1; } + /* Add self-mapping */ + RtlZeroMemory(&PmlBase[PmlIndex], sizeof(HARDWARE_PTE)); + PmlBase[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE; + PmlBase[PmlIndex].Valid = 1; + PmlBase[PmlIndex].Writable = 1; + /* Return success */ return STATUS_EFI_SUCCESS; } diff --git a/xtldr/arch/i686/memory.c b/xtldr/arch/i686/memory.c index f3cb652..f6aede9 100644 --- a/xtldr/arch/i686/memory.c +++ b/xtldr/arch/i686/memory.c @@ -36,7 +36,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, if(PageMap->PageMapLevel == 3) { /* Allocate a page for the 3-level page map structure (PAE enabled) */ - Status = BlAllocateMemoryPages(1, &Address); + Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failed, cannot proceed with page map creation */ @@ -48,7 +48,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, RtlZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE); /* Allocate 4 pages for the Page Directories (PDs) */ - Status = BlAllocateMemoryPages(4, &DirectoryAddress); + Status = BlAllocateMemoryPages(AllocateAnyPages, 4, &DirectoryAddress); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failed, cannot proceed with page map creation */ @@ -61,16 +61,16 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, /* Fill the PDPT with pointers to the Page Directories */ for(Index = 0; Index < 4; Index++) { - RtlZeroMemory(&((PHARDWARE_PTE)PageMap->PtePointer)[Index], sizeof(HARDWARE_PTE)); - ((PHARDWARE_PTE)PageMap->PtePointer)[Index].PageFrameNumber = DirectoryAddress / EFI_PAGE_SIZE; - ((PHARDWARE_PTE)PageMap->PtePointer)[Index].Valid = 1; + RtlZeroMemory(&((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index], sizeof(HARDWARE_MODERN_PTE)); + ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].PageFrameNumber = DirectoryAddress / EFI_PAGE_SIZE; + ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].Valid = 1; DirectoryAddress += EFI_PAGE_SIZE; } } else { /* Allocate a page for the 2-level page map structure (PAE disabled) */ - Status = BlAllocateMemoryPages(1, &Address); + Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failed, cannot proceed with page map creation */ @@ -90,6 +90,15 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, return Status; } + /* Map the trampoline code area */ + Status = BlMapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS, + 1, LoaderFirmwareTemporary); + if(Status != STATUS_EFI_SUCCESS) + { + /* Mapping trampoline code failed */ + return Status; + } + /* Get list of XTLDR modules */ ModulesList = BlGetModulesList(); ModulesListEntry = ModulesList->Flink; @@ -193,8 +202,8 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap, SIZE_T PageFrameNumber; PVOID Pml1, Pml2, Pml3; SIZE_T Pml1Entry, Pml2Entry, Pml3Entry; - PHARDWARE_PTE PmlTable; PHARDWARE_LEGACY_PTE LegacyPmlTable; + PHARDWARE_MODERN_PTE PmlTable; EFI_STATUS Status; /* Set the Page Frame Number (PFN) */ @@ -231,8 +240,8 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap, } /* Set the 64-bit PTE entry */ - PmlTable = (PHARDWARE_PTE)Pml1; - RtlZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_PTE)); + PmlTable = (PHARDWARE_MODERN_PTE)Pml1; + RtlZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_MODERN_PTE)); PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber; PmlTable[Pml1Entry].Valid = 1; PmlTable[Pml1Entry].Writable = 1; @@ -304,14 +313,14 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, ULONGLONG PmlPointer = 0; EFI_STATUS Status; PHARDWARE_LEGACY_PTE LegacyPmlTable; - PHARDWARE_PTE PmlTable; + PHARDWARE_MODERN_PTE PmlTable; BOOLEAN ValidPte = FALSE; /* Check page map level to determine PTE size */ if(PageMap->PageMapLevel >= 3) { /* 64-bit PTE for PML3 (PAE enabled) */ - PmlTable = (PHARDWARE_PTE)PageTable; + PmlTable = (PHARDWARE_MODERN_PTE)PageTable; if(PmlTable[Entry].Valid) { /* Get page frame number from page table entry */ @@ -340,7 +349,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, else { /* Allocate pages for new PML entry */ - Status = BlAllocateMemoryPages(1, &Address); + Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -362,7 +371,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, if(PageMap->PageMapLevel >= 3) { /* 64-bit PTE for PML3 (PAE enabled) */ - PmlTable = (PHARDWARE_PTE)PageTable; + PmlTable = (PHARDWARE_MODERN_PTE)PageTable; PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE; PmlTable[Entry].Valid = 1; PmlTable[Entry].Writable = 1; @@ -406,7 +415,7 @@ BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress) { PHARDWARE_LEGACY_PTE LegacyPml; - PHARDWARE_PTE Pml; + PHARDWARE_MODERN_PTE Pml; ULONGLONG PmlIndex; ULONG Index; @@ -417,13 +426,13 @@ BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, PmlIndex = (SelfMapAddress >> MM_PDI_SHIFT) & 0x1FF; /* Get Page Directory */ - Pml = (PHARDWARE_PTE)(((PHARDWARE_PTE)PageMap->PtePointer)[SelfMapAddress >> MM_PPI_SHIFT].PageFrameNumber * EFI_PAGE_SIZE); + Pml = (PHARDWARE_MODERN_PTE)(((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[SelfMapAddress >> MM_PPI_SHIFT].PageFrameNumber * EFI_PAGE_SIZE); /* Add self-mapping for PML3 (PAE enabled) */ for(Index = 0; Index < 4; Index++) { - RtlZeroMemory(&Pml[PmlIndex + Index], sizeof(HARDWARE_PTE)); - Pml[PmlIndex + Index].PageFrameNumber = ((PHARDWARE_PTE)PageMap->PtePointer)[Index].PageFrameNumber; + RtlZeroMemory(&Pml[PmlIndex + Index], sizeof(HARDWARE_MODERN_PTE)); + Pml[PmlIndex + Index].PageFrameNumber = ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].PageFrameNumber; Pml[PmlIndex + Index].Valid = 1; Pml[PmlIndex + Index].Writable = 1; } diff --git a/xtldr/includes/xtldr.h b/xtldr/includes/xtldr.h index 1564402..791b09a 100644 --- a/xtldr/includes/xtldr.h +++ b/xtldr/includes/xtldr.h @@ -18,7 +18,8 @@ /* XTLDR routines forward references */ XTCDECL EFI_STATUS -BlAllocateMemoryPages(IN ULONGLONG NumberOfPages, +BlAllocateMemoryPages(IN EFI_ALLOCATE_TYPE AllocationType, + IN ULONGLONG NumberOfPages, OUT PEFI_PHYSICAL_ADDRESS Memory); XTCDECL diff --git a/xtldr/memory.c b/xtldr/memory.c index c135d03..1d6f25b 100644 --- a/xtldr/memory.c +++ b/xtldr/memory.c @@ -24,10 +24,11 @@ */ XTCDECL EFI_STATUS -BlAllocateMemoryPages(IN ULONGLONG NumberOfPages, +BlAllocateMemoryPages(IN EFI_ALLOCATE_TYPE AllocationType, + IN ULONGLONG NumberOfPages, OUT PEFI_PHYSICAL_ADDRESS Memory) { - return EfiSystemTable->BootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, NumberOfPages, Memory); + return EfiSystemTable->BootServices->AllocatePages(AllocationType, EfiLoaderData, NumberOfPages, Memory); } /** diff --git a/xtldr/modules/pecoff/pecoff.c b/xtldr/modules/pecoff/pecoff.c index 5288c37..aac0208 100644 --- a/xtldr/modules/pecoff/pecoff.c +++ b/xtldr/modules/pecoff/pecoff.c @@ -409,7 +409,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, Pages = EFI_SIZE_TO_PAGES(ImageData->FileSize); /* Allocate pages */ - Status = XtLdrProtocol->Memory.AllocatePages(Pages, &Address); + Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Pages allocation failure */ @@ -472,7 +472,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, ImageData->ImagePages = EFI_SIZE_TO_PAGES(ImageData->ImageSize); /* Allocate image pages */ - Status = XtLdrProtocol->Memory.AllocatePages(ImageData->ImagePages, &Address); + Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, ImageData->ImagePages, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Pages reallocation failure */ diff --git a/xtldr/modules/xtos_o/amd64/memory.c b/xtldr/modules/xtos_o/amd64/memory.c index 36d9890..55f8ec8 100644 --- a/xtldr/modules/xtos_o/amd64/memory.c +++ b/xtldr/modules/xtos_o/amd64/memory.c @@ -70,25 +70,54 @@ XTCDECL EFI_STATUS XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) { - PHARDWARE_PTE PdeBase, PpeBase, PxeBase; + PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase; EFI_PHYSICAL_ADDRESS Address; EFI_STATUS Status; - /* Check page map level */ - if(PageMap->PageMapLevel > 4) + if(PageMap->PageMapLevel == 5) { - /* PML5 (LA57) is not supported yet */ - return STATUS_EFI_UNSUPPORTED; - } + /* Get P5E (PML5) base address */ + P5eBase = (PHARDWARE_PTE)PageMap->PtePointer; - /* Get PXE (PML4) base address */ - PxeBase = ((PHARDWARE_PTE)(PageMap->PtePointer)); + /* Check if P5E entry already exists */ + if(!P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Valid) + { + /* No valid P5E, allocate memory */ + Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure, return error */ + return Status; + } + + /* Zero fill memory used by P5E */ + RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE); + + /* Make P5E valid */ + P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Valid = 1; + P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].PageFrameNumber = Address / EFI_PAGE_SIZE; + P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Writable = 1; + + /* Set PXE base address */ + PxeBase = (PHARDWARE_PTE)(UINT_PTR)Address; + } + else + { + /* Set PXE base address based on existing P5E */ + PxeBase = (PHARDWARE_PTE)((P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].PageFrameNumber) << EFI_PAGE_SHIFT); + } + } + else + { + /* Get PXE (PML4) base address */ + PxeBase = (PHARDWARE_PTE)PageMap->PtePointer; + } /* Check if PXE entry already exists */ if(!PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Valid) { /* No valid PXE, allocate memory */ - Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); + Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure, return error */ @@ -116,7 +145,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) if(!PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Valid) { /* No valid PPE, allocate memory */ - Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); + Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure, return error */ @@ -147,7 +176,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) if(!PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid) { /* No valid PDE, allocate memory */ - Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); + Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure, return error */ @@ -183,9 +212,12 @@ EFI_STATUS XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap) { EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS TrampolineAddress; + PXT_TRAMPOLINE_ENTRY TrampolineEntry; + ULONG_PTR TrampolineSize; /* Build page map */ - Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, 0xFFFFF6FB7DBED000); + Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE); if(Status != STATUS_EFI_SUCCESS) { /* Failed to build page map */ @@ -202,6 +234,29 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap) return Status; } + /* Check the configured page map level to set the LA57 state accordingly */ + if(PageMap->PageMapLevel == 5) + { + /* Set the address of the trampoline code below 1MB */ + TrampolineAddress = MM_TRAMPOLINE_ADDRESS; + + /* Calculate the size of the trampoline code */ + TrampolineSize = (ULONG_PTR)ArEnableExtendedPhysicalAddressingEnd - (ULONG_PTR)ArEnableExtendedPhysicalAddressing; + + /* Allocate pages for the trampoline */ + Status = XtLdrProtocol->Memory.AllocatePages(AllocateAddress, EFI_SIZE_TO_PAGES(TrampolineSize), &TrampolineAddress); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to allocate memory for trampoline code */ + XtLdrProtocol->Debug.Print(L"Failed to allocate memory for trampoline code (Status code: %zX)\n", Status); + return Status; + } + + /* Set the trampoline entry point and copy its code into the allocated buffer */ + TrampolineEntry = (PXT_TRAMPOLINE_ENTRY)(UINT_PTR)TrampolineAddress; + RtlCopyMemory(TrampolineEntry, ArEnableExtendedPhysicalAddressing, TrampolineSize); + } + /* Exit EFI Boot Services */ XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n"); Status = XtLdrProtocol->Util.ExitBootServices(); @@ -217,19 +272,20 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap) { /* Enable Linear Address 57-bit (LA57) extension */ XtLdrProtocol->Debug.Print(L"Enabling Linear Address 57-bit (LA57)\n"); + + /* Execute the trampoline to enable LA57 and write PML5 to CR3 */ + TrampolineEntry((UINT64)PageMap->PtePointer); } else { /* Disable Linear Address 57-bit (LA57) extension */ XtLdrProtocol->Debug.Print(L"Disabling Linear Address 57-bit (LA57)\n"); + + /* Write PML4 to CR3 and enable paging */ + ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer); + ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG); } - /* Write PML4 to CR3 */ - ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer); - - /* Enable paging */ - ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG); - /* Return success */ return STATUS_EFI_SUCCESS; } diff --git a/xtldr/modules/xtos_o/i686/memory.c b/xtldr/modules/xtos_o/i686/memory.c index 50f4194..959ac8c 100644 --- a/xtldr/modules/xtos_o/i686/memory.c +++ b/xtldr/modules/xtos_o/i686/memory.c @@ -60,11 +60,11 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) { EFI_PHYSICAL_ADDRESS Address; PHARDWARE_LEGACY_PTE LegacyPdeBase; - PHARDWARE_PTE PdeBase; + PHARDWARE_MODERN_PTE PdeBase; EFI_STATUS Status; /* Allocate memory */ - Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); + Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure, return error */ @@ -78,10 +78,10 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) if(PageMap->PageMapLevel == 3) { /* Get PDE base address (PAE enabled) */ - PdeBase = (PHARDWARE_PTE)(((PHARDWARE_PTE)PageMap->PtePointer)[MM_HARDWARE_VA_START >> MM_PPI_SHIFT].PageFrameNumber << MM_PAGE_SHIFT); + PdeBase = (PHARDWARE_MODERN_PTE)(((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[MM_HARDWARE_VA_START >> MM_PPI_SHIFT].PageFrameNumber << MM_PAGE_SHIFT); /* Make PDE valid */ - RtlZeroMemory(&PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF], sizeof(HARDWARE_PTE)); + RtlZeroMemory(&PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF], sizeof(HARDWARE_MODERN_PTE)); PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].PageFrameNumber = Address >> MM_PAGE_SHIFT; PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].Valid = 1; PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].Writable = 1; @@ -126,7 +126,7 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap) EFI_STATUS Status; /* Build page map */ - Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, 0xC0000000); + Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, MM_PTE_BASE); if(Status != STATUS_EFI_SUCCESS) { /* Failed to build page map */ diff --git a/xtldr/modules/xtos_o/includes/xtos.h b/xtldr/modules/xtos_o/includes/xtos.h index 7bd30f8..2f4da6a 100644 --- a/xtldr/modules/xtos_o/includes/xtos.h +++ b/xtldr/modules/xtos_o/includes/xtos.h @@ -29,9 +29,15 @@ typedef struct _XT_FRAMEBUFFER_PROTOCOL /* EFI XT Loader Protocol */ EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol; +/* XTOS trampoline end address to calculate trampoline size */ +EXTERN PVOID ArEnableExtendedPhysicalAddressingEnd[]; + /* XTOS kernel entry point */ typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters); +/* XTOS trampoline entry point */ +typedef VOID (*PXT_TRAMPOLINE_ENTRY)(UINT64 PageMap); + /* XTOS boot protocol related routines forward references */ XTCDECL EFI_STATUS diff --git a/xtldr/modules/xtos_o/xtos.c b/xtldr/modules/xtos_o/xtos.c index 65e0129..f9af717 100644 --- a/xtldr/modules/xtos_o/xtos.c +++ b/xtldr/modules/xtos_o/xtos.c @@ -75,7 +75,7 @@ XtGetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap, Pages = (ULONGLONG)EFI_SIZE_TO_PAGES((PageMap->MapSize + 1) * sizeof(LOADER_MEMORY_DESCRIPTOR)); - Status = XtLdrProtocol->Memory.AllocatePages(Pages, &Address); + Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address); if(Status != STATUS_EFI_SUCCESS) { return Status; @@ -136,7 +136,7 @@ XtGetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap, Pages = (ULONGLONG)EFI_SIZE_TO_PAGES(sizeof(SYSTEM_RESOURCE_ACPI) + sizeof(SYSTEM_RESOURCE_FRAMEBUFFER)); - Status = XtLdrProtocol->Memory.AllocatePages(Pages, &Address); + Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address); if(Status != STATUS_EFI_SUCCESS) { return Status; @@ -552,7 +552,7 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK)); /* Allocate memory for kernel initialization block */ - Status = XtLdrProtocol->Memory.AllocatePages(BlockPages, &Address); + Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -571,9 +571,6 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, /* Set LoaderInformation block properties */ LoaderBlock->LoaderInformation.DbgPrint = XtLdrProtocol->Debug.Print; - /* Store page map level */ - LoaderBlock->LoaderInformation.PageMapLevel = PageMap->PageMapLevel; - /* Attempt to find virtual address of the EFI Runtime Services */ // Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices); // if(Status == STATUS_EFI_SUCCESS) diff --git a/xtldr/volume.c b/xtldr/volume.c index 73f3499..abc3793 100644 --- a/xtldr/volume.c +++ b/xtldr/volume.c @@ -616,7 +616,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize); /* Allocate pages */ - Status = BlAllocateMemoryPages(Pages, &Address); + Status = BlAllocateMemoryPages(AllocateAnyPages, Pages, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Pages allocation failure */ diff --git a/xtoskrnl/CMakeLists.txt b/xtoskrnl/CMakeLists.txt index d6a2f57..9f208da 100644 --- a/xtoskrnl/CMakeLists.txt +++ b/xtoskrnl/CMakeLists.txt @@ -9,6 +9,7 @@ include_directories( # Specify list of library source code files list(APPEND LIBXTOS_SOURCE + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c ${XTOSKRNL_SOURCE_DIR}/hl/cport.c ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c @@ -23,6 +24,7 @@ list(APPEND LIBXTOS_SOURCE # Specify list of kernel source code files list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/archsup.S + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/globals.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.c @@ -60,8 +62,10 @@ list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/mm/init.c ${XTOSKRNL_SOURCE_DIR}/mm/kpools.c ${XTOSKRNL_SOURCE_DIR}/mm/pages.c + ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/globals.c ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/init.c ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pages.c + ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pmap.c ${XTOSKRNL_SOURCE_DIR}/po/idle.c ${XTOSKRNL_SOURCE_DIR}/rtl/atomic.c ${XTOSKRNL_SOURCE_DIR}/rtl/bitmap.c diff --git a/xtoskrnl/ar/amd64/archsup.S b/xtoskrnl/ar/amd64/archsup.S index 1c18ab2..849df4f 100644 --- a/xtoskrnl/ar/amd64/archsup.S +++ b/xtoskrnl/ar/amd64/archsup.S @@ -13,7 +13,7 @@ /** - * This macro creates a trap handler for the specified vector. + * Creates a trap handler for the specified vector. * * @param Vector * Supplies a trap vector number. diff --git a/xtoskrnl/ar/amd64/boot.S b/xtoskrnl/ar/amd64/boot.S new file mode 100644 index 0000000..d631845 --- /dev/null +++ b/xtoskrnl/ar/amd64/boot.S @@ -0,0 +1,133 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ar/amd64/boot.S + * DESCRIPTION: AMD64-specific boot code for setting up the low-level CPU environment + * DEVELOPERS: Aiken Harris + */ + +#include + +.altmacro +.text + + +/** + * Enables eXtended Physical Addressing (XPA). + * + * @param PageMap + * Supplies a pointer to the page map to be used. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +.global ArEnableExtendedPhysicalAddressing +ArEnableExtendedPhysicalAddressing: + /* Save the original CR4 register */ + movq %cr4, %rax + + /* Save the state of stack pointer and non-volatile registers */ + movq %rsp, XpaRegisterSaveArea(%rip) + movq %rbp, XpaRegisterSaveArea+0x08(%rip) + movq %rax, XpaRegisterSaveArea+0x10(%rip) + movq %rbx, XpaRegisterSaveArea+0x18(%rip) + + /* Save the original CR0 register */ + movq %cr0, %rbp + + /* Load temporary GDT required for mode transitions */ + leaq XpaTemporaryGdtDesc(%rip), %rax + movq %rax, XpaTemporaryGdtBase(%rip) + lgdtq XpaTemporaryGdtSize(%rip) + + /* Load addresses for entering compatibility mode and re-entering long mode */ + leaq XpaEnterCompatMode(%rip), %rax + leaq XpaEnterLongMode(%rip), %rbx + + /* Push the 32-bit code segment selector and the target address for a far jump */ + pushq $GDT_R0_CMCODE + pushq %rax + + /* Perform a far return to switch to 32-bit compatibility mode */ + lretq + +XpaEnterCompatMode: + /* Enter 32-bit compatibility mode */ + .code32 + + /* Store the PageMap pointer on the stack for future use */ + pushl %ecx + + /* Set the stack segment to the 32-bit data segment selector */ + movl $GDT_R0_DATA, %eax + movl %eax, %ss + + /* Disable PGE and PCIDE to ensure all TLB entries will be flushed */ + movl %cr4, %eax + andl $~(CR4_PGE | CR4_PCIDE), %eax + movl %eax, %cr4 + + /* Temporarily disable paging */ + movl %ebp, %eax + andl $~CR0_PG, %eax + movl %eax, %cr0 + + /* Disable Long Mode as prerequisite for enabling 5-level paging */ + movl $X86_MSR_EFER, %ecx + rdmsr + andl $~X86_MSR_EFER_LME, %eax + wrmsr + + /* Transition to 5-level paging (PML5/LA57) */ + movl %cr4, %eax + orl $CR4_LA57, %eax + movl %eax, %cr4 + + /* Restore the PageMap pointer from the stack and load it into CR3 */ + popl %ecx + movl %ecx, %cr3 + + /* Re-enable Long Mode */ + movl $X86_MSR_EFER, %ecx + rdmsr + orl $X86_MSR_EFER_LME, %eax + wrmsr + + /* Restore CR0 with paging enabled and flush the instruction pipeline */ + movl %ebp, %cr0 + call XpaFlushInstructions + +XpaFlushInstructions: + /* Push the 64-bit code segment selector and the target address for a far jump */ + pushl $GDT_R0_CODE + pushl %ebx + + /* Perform a far return to switch to 64-bit long mode */ + lretl + +XpaEnterLongMode: + /* Enter 64-bit long mode */ + .code64 + + /* Restore the stack pointer and non-volatile registers */ + movq XpaRegisterSaveArea(%rip), %rsp + movq XpaRegisterSaveArea+8(%rip), %rbp + movq XpaRegisterSaveArea+0x10(%rip), %rax + movq XpaRegisterSaveArea+0x18(%rip), %rbx + + /* Restore the original CR4 register with LA57 bit set */ + orq $CR4_LA57, %rax + movq %rax, %cr4 + + /* Return to the caller */ + retq + +/* Data section for saving registers and temporary GDT */ +XpaRegisterSaveArea: .quad 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 +XpaTemporaryGdtSize: .short ArEnableExtendedPhysicalAddressingEnd - XpaTemporaryGdtDesc - 1 +XpaTemporaryGdtBase: .quad 0x0000000000000000 +XpaTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF + +.global ArEnableExtendedPhysicalAddressingEnd +ArEnableExtendedPhysicalAddressingEnd: diff --git a/xtoskrnl/ar/i686/boot.S b/xtoskrnl/ar/i686/boot.S new file mode 100644 index 0000000..edb4c05 --- /dev/null +++ b/xtoskrnl/ar/i686/boot.S @@ -0,0 +1,14 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ar/i686/boot.S + * DESCRIPTION: i686-specific boot code for setting up the low-level CPU environment + * DEVELOPERS: Aiken Harris + */ + +#include + +.altmacro +.text + + diff --git a/xtoskrnl/includes/amd64/asmsup.h b/xtoskrnl/includes/amd64/asmsup.h index 6b243d2..7e04ab6 100644 --- a/xtoskrnl/includes/amd64/asmsup.h +++ b/xtoskrnl/includes/amd64/asmsup.h @@ -10,6 +10,21 @@ #define __XTOSKRNL_AMD64_ASMSUP_H +/* Control Register bit definitions */ +#define CR0_PG 0x80000000 +#define CR4_PGE 0x00000080 +#define CR4_LA57 0x00001000 +#define CR4_PCIDE 0x00020000 + +/* GDT selectors */ +#define GDT_R0_CMCODE 0x08 +#define GDT_R0_CODE 0x10 +#define GDT_R0_DATA 0x18 + +/* MSR registers */ +#define X86_MSR_EFER 0xC0000080 +#define X86_MSR_EFER_LME (1 << 8) + /* KTRAP_FRAME structure offsets */ #define TrapXmm0 0 #define TrapXmm1 16 diff --git a/xtoskrnl/includes/amd64/globals.h b/xtoskrnl/includes/amd64/globals.h index 70c6aa0..234379a 100644 --- a/xtoskrnl/includes/amd64/globals.h +++ b/xtoskrnl/includes/amd64/globals.h @@ -30,4 +30,10 @@ EXTERN UCHAR ArKernelBootStack[KERNEL_STACK_SIZE]; /* Kernel own fault stack */ EXTERN UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE]; +/* Page mapping routines for systems using 4-level paging (PML4) */ +EXTERN CMMPAGEMAP_ROUTINES MmpPml4Routines; + +/* Page mapping routines for systems using 5-level paging (PML5) */ +EXTERN CMMPAGEMAP_ROUTINES MmpPml5Routines; + #endif /* __XTOSKRNL_AMD64_GLOBALS_H */ diff --git a/xtoskrnl/includes/amd64/mmi.h b/xtoskrnl/includes/amd64/mmi.h index 9d9ab6a..dbbcba0 100644 --- a/xtoskrnl/includes/amd64/mmi.h +++ b/xtoskrnl/includes/amd64/mmi.h @@ -13,17 +13,33 @@ /* AMD64 Memory Manager routines forward references */ +XTAPI +VOID +MmInitializePageMapSupport(VOID); + XTFASTCALL VOID MmZeroPages(IN PVOID Address, IN ULONG Size); XTAPI -PMMPTE +VOID +MmpClearPte(PHARDWARE_PTE PtePointer); + +XTAPI +BOOLEAN +MmpGetExtendedPhysicalAddressingStatus(VOID); + +XTAPI +PMMP5E +MmpGetP5eAddress(PVOID Address); + +XTAPI +PMMPDE MmpGetPdeAddress(PVOID Address); XTAPI -PMMPTE +PMMPPE MmpGetPpeAddress(PVOID Address); XTAPI @@ -31,7 +47,7 @@ PMMPTE MmpGetPteAddress(PVOID Address); XTAPI -PMMPTE +PMMPXE MmpGetPxeAddress(PVOID Address); XTAPI @@ -40,6 +56,18 @@ MmpInitializeArchitecture(VOID); XTAPI BOOLEAN -MmpMemoryExtensionEnabled(VOID); +MmpPteValid(PHARDWARE_PTE PtePointer); + +XTAPI +VOID +MmpSetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable); + +XTAPI +VOID +MmpSetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough); #endif /* __XTOSKRNL_AMD64_MMI_H */ diff --git a/xtoskrnl/includes/globals.h b/xtoskrnl/includes/globals.h index 64de0f1..3ce700e 100644 --- a/xtoskrnl/includes/globals.h +++ b/xtoskrnl/includes/globals.h @@ -75,9 +75,6 @@ EXTERN ULONG MmNumberOfPhysicalPages; /* Old biggest free memory descriptor */ EXTERN LOADER_MEMORY_DESCRIPTOR MmOldFreeDescriptor; -/* Page Map Level */ -EXTERN ULONG MmPageMapLevel; - /* Processor structures data (THIS IS A TEMPORARY HACK) */ EXTERN UCHAR MmProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE]; @@ -87,8 +84,11 @@ EXTERN LOADER_MEMORY_DESCRIPTOR MmpHardwareAllocationDescriptors[MM_HARDWARE_ALL /* Live address of kernel's hardware heap */ EXTERN PVOID MmpHardwareHeapStart; -/* Architecture-specific memory extension */ -EXTERN BOOLEAN MmpMemoryExtension; +/* Information about the current page map */ +EXTERN MMPAGEMAP_INFO MmpPageMapInfo; + +/* Pointers to page map routines for the current paging mode */ +EXTERN PCMMPAGEMAP_ROUTINES MmpPageMapRoutines; /* Number of used hardware allocation descriptors */ EXTERN ULONG MmpUsedHardwareAllocationDescriptors; diff --git a/xtoskrnl/includes/i686/globals.h b/xtoskrnl/includes/i686/globals.h index 0c5f6ec..e5bf03e 100644 --- a/xtoskrnl/includes/i686/globals.h +++ b/xtoskrnl/includes/i686/globals.h @@ -34,4 +34,10 @@ EXTERN UCHAR ArKernelBootStack[KERNEL_STACK_SIZE]; /* Kernel own fault stack */ EXTERN UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE]; +/* Page mapping routines for systems using 2-level paging (PML2) */ +EXTERN CMMPAGEMAP_ROUTINES MmpPml2Routines; + +/* Page mapping routines for systems using 3-level paging (PML3) */ +EXTERN CMMPAGEMAP_ROUTINES MmpPml3Routines; + #endif /* __XTOSKRNL_I686_GLOBALS_H */ diff --git a/xtoskrnl/includes/i686/mmi.h b/xtoskrnl/includes/i686/mmi.h index 31c0c10..cc36a58 100644 --- a/xtoskrnl/includes/i686/mmi.h +++ b/xtoskrnl/includes/i686/mmi.h @@ -13,15 +13,31 @@ /* i686 Memory Manager routines forward references */ +XTAPI +VOID +MmInitializePageMapSupport(VOID); + XTFASTCALL VOID MmZeroPages(IN PVOID Address, IN ULONG Size); XTAPI -PMMPTE +VOID +MmpClearPte(PHARDWARE_PTE PtePointer); + +XTAPI +BOOLEAN +MmpGetExtendedPhysicalAddressingStatus(VOID); + +XTAPI +PMMPDE MmpGetPdeAddress(PVOID Address); +XTAPI +PMMPPE +MmpGetPpeAddress(PVOID Address); + XTAPI PMMPTE MmpGetPteAddress(PVOID Address); @@ -32,6 +48,34 @@ MmpInitializeArchitecture(VOID); XTAPI BOOLEAN -MmpMemoryExtensionEnabled(VOID); +MmpPml2PteValid(PHARDWARE_PTE PtePointer); + +XTAPI +VOID +MmpSetPml2Pte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable); + +XTAPI +VOID +MmpSetPml2PteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough); + +XTAPI +BOOLEAN +MmpPml3PteValid(PHARDWARE_PTE PtePointer); + +XTAPI +VOID +MmpSetPml3Pte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable); + +XTAPI +VOID +MmpSetPml3PteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough); #endif /* __XTOSKRNL_I686_MMI_H */ diff --git a/xtoskrnl/ke/amd64/krnlinit.c b/xtoskrnl/ke/amd64/krnlinit.c index 986a403..610e4ef 100644 --- a/xtoskrnl/ke/amd64/krnlinit.c +++ b/xtoskrnl/ke/amd64/krnlinit.c @@ -52,6 +52,9 @@ KepInitializeMachine(VOID) /* Initialize processor */ HlInitializeProcessor(); + + /* Initialize page map support */ + MmInitializePageMapSupport(); } /** diff --git a/xtoskrnl/ke/i686/krnlinit.c b/xtoskrnl/ke/i686/krnlinit.c index a671565..6d0d725 100644 --- a/xtoskrnl/ke/i686/krnlinit.c +++ b/xtoskrnl/ke/i686/krnlinit.c @@ -52,6 +52,9 @@ KepInitializeMachine(VOID) /* Initialize processor */ HlInitializeProcessor(); + + /* Initialize page map support */ + MmInitializePageMapSupport(); } /** diff --git a/xtoskrnl/mm/amd64/globals.c b/xtoskrnl/mm/amd64/globals.c new file mode 100644 index 0000000..f5959a1 --- /dev/null +++ b/xtoskrnl/mm/amd64/globals.c @@ -0,0 +1,26 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/mm/amd64/globals.c + * DESCRIPTION: AMD64-specific global variables for the Memory Manager + * DEVELOPERS: Aiken Harris + */ + +#include + + +/* Page mapping routines for systems using 4-level paging (PML4) */ +CMMPAGEMAP_ROUTINES MmpPml4Routines = { + .ClearPte = MmpClearPte, + .PteValid = MmpPteValid, + .SetPteCaching = MmpSetPteCaching, + .SetPte = MmpSetPte, +}; + +/* Page mapping routines for systems using 5-level paging (PML5) */ +CMMPAGEMAP_ROUTINES MmpPml5Routines = { + .ClearPte = MmpClearPte, + .PteValid = MmpPteValid, + .SetPteCaching = MmpSetPteCaching, + .SetPte = MmpSetPte, +}; diff --git a/xtoskrnl/mm/amd64/init.c b/xtoskrnl/mm/amd64/init.c index f746c4d..31483d4 100644 --- a/xtoskrnl/mm/amd64/init.c +++ b/xtoskrnl/mm/amd64/init.c @@ -4,89 +4,60 @@ * FILE: xtoskrnl/mm/amd64/init.c * DESCRIPTION: Architecture specific Memory Manager initialization routines * DEVELOPERS: Rafal Kupiec + * Aiken Harris */ #include /** - * Gets the address of the PDE (Page Directory Entry), that maps given address. + * Detects if eXtended Physical Addressing (XPA) is enabled and initializes page map support. * - * @param Address - * Specifies the address to find the PDE for. - * - * @return This routine returns the address of the PDE. + * @return This routine does not return any value. * * @since XT 1.0 */ XTAPI -PMMPTE -MmpGetPdeAddress(PVOID Address) +VOID +MmInitializePageMapSupport(VOID) { - ULONGLONG Offset; + /* Check if XPA is enabled */ + if(MmpGetExtendedPhysicalAddressingStatus()) + { + /* XPA enabled, use LA57 paging (PML5) */ + MmpPageMapRoutines = &MmpPml5Routines; - Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << 48) - 1)) >> MM_PDI_SHIFT) << MM_PTE_SHIFT); - return (PMMPTE)(MM_PDE_BASE + Offset); -} + /* Set PML5 page map information */ + MmpPageMapInfo.Xpa = TRUE; -/** - * Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address. - * - * @param Address - * Specifies the address to find the PPE for. - * - * @return This routine returns the address of the PPE. - * - * @since XT 1.0 - */ -XTAPI -PMMPTE -MmpGetPpeAddress(PVOID Address) -{ - ULONGLONG Offset; + /* Set PML5 base addresses */ + MmpPageMapInfo.PteBase = MM_PTE_LA57_BASE; + MmpPageMapInfo.PdeBase = MM_PDE_LA57_BASE; + MmpPageMapInfo.PpeBase = MM_PPE_LA57_BASE; + MmpPageMapInfo.PxeBase = MM_PXE_LA57_BASE; + MmpPageMapInfo.P5eBase = MM_P5E_LA57_BASE; - Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << 48) - 1)) >> MM_PPI_SHIFT) << MM_PTE_SHIFT); - return (PMMPTE)(MM_PPE_BASE + Offset); -} + /* PML5 use 57-bit virtual addresses */ + MmpPageMapInfo.VaBits = 57; + } + else + { + /* XPA disabled, use LA48 paging (PML4) */ + MmpPageMapRoutines = &MmpPml4Routines; -/** - * Gets the address of the PTE (Page Table Entry), that maps given address. - * - * @param Address - * Specifies the address to find the PTE for. - * - * @return This routine returns the address of the PTE. - * - * @since XT 1.0 - */ -XTAPI -PMMPTE -MmpGetPteAddress(PVOID Address) -{ - ULONGLONG Offset; + /* Set PML4 page map information */ + MmpPageMapInfo.Xpa = FALSE; - Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << 48) - 1)) >> MM_PTI_SHIFT) << MM_PTE_SHIFT); - return (PMMPTE)(MM_PTE_BASE + Offset); -} + /* Set PML4 base addresses */ + MmpPageMapInfo.PteBase = MM_PTE_BASE; + MmpPageMapInfo.PdeBase = MM_PDE_BASE; + MmpPageMapInfo.PpeBase = MM_PPE_BASE; + MmpPageMapInfo.PxeBase = MM_PXE_BASE; + MmpPageMapInfo.P5eBase = 0x0; -/** - * Gets the address of the PXE (Extended Page Entry), that maps given address. - * - * @param Address - * Specifies the address to find the PXE for. - * - * @return This routine returns the address of the PXE. - * - * @since XT 1.0 - */ -XTAPI -PMMPTE -MmpGetPxeAddress(PVOID Address) -{ - ULONGLONG Offset; - - Offset = (((ULONGLONG)Address >> MM_PXI_SHIFT) & (MM_PXE_PER_PAGE - 1)); - return (PMMPTE)(MM_PXE_BASE + Offset); + /* PML use 48-bit virtual addresses */ + MmpPageMapInfo.VaBits = 48; + } } /** @@ -102,18 +73,3 @@ MmpInitializeArchitecture(VOID) { UNIMPLEMENTED; } - -/** - * Checks if LA57 (PML5) is enabled. - * - * @return This routine returns TRUE if LA57 is enabled, or FALSE otherwise. - * - * @since XT 1.0 - */ -XTAPI -BOOLEAN -MmpMemoryExtensionEnabled(VOID) -{ - /* Check if LA57 (PML5) is enabled */ - return ((ArReadControlRegister(4) & CR4_LA57) != 0) ? TRUE : FALSE; -} diff --git a/xtoskrnl/mm/amd64/pmap.c b/xtoskrnl/mm/amd64/pmap.c new file mode 100644 index 0000000..bc29a75 --- /dev/null +++ b/xtoskrnl/mm/amd64/pmap.c @@ -0,0 +1,216 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/mm/amd64/pmap.c + * DESCRIPTION: Low-level support for AMD64 page map manipulation + * DEVELOPERS: Aiken Harris + */ + +#include + + +/** + * Clears the contents of a page table entry (PTE). + * + * @param PtePointer + * Pointer to the page table entry (PTE) to be cleared. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MmpClearPte(PHARDWARE_PTE PtePointer) +{ + PtePointer->CacheDisable = 0; + PtePointer->PageFrameNumber = 0; + PtePointer->Valid = 0; + PtePointer->Writable = 0; + PtePointer->WriteThrough = 0; +} + +/** + * Checks if eXtended Physical Addressing (XPA) is enabled. + * + * @return This routine returns TRUE if LA57 is enabled, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MmpGetExtendedPhysicalAddressingStatus(VOID) +{ + /* Check if LA57 is enabled */ + return ((ArReadControlRegister(4) & CR4_LA57) != 0) ? TRUE : FALSE; +} + +/** + * Gets the address of the P5E (Page Map Level 5 Entry), that maps given address. + * + * @param Address + * Specifies the virtual address for which to retrieve the corresponding P5E. + * + * @return This routine returns the address of the P5E, or NULL if LA57 is not enabled. + * + * @since XT 1.0 + */ +XTAPI +PMMP5E +MmpGetP5eAddress(PVOID Address) +{ + ULONGLONG Offset; + + Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << MmpPageMapInfo.VaBits) - 1)) >> MM_P5I_SHIFT) << MM_PTE_SHIFT); + return (PMMP5E)((MmpPageMapInfo.P5eBase + Offset) * MmpPageMapInfo.Xpa); +} + +/** + * Gets the address of the PDE (Page Directory Entry), that maps given address. + * + * @param Address + * Specifies the virtual address for which to retrieve the corresponding PDE. + * + * @return This routine returns the address of the PDE. + * + * @since XT 1.0 + */ +XTAPI +PMMPDE +MmpGetPdeAddress(PVOID Address) +{ + ULONGLONG Offset; + + Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << MmpPageMapInfo.VaBits) - 1)) >> MM_PDI_SHIFT) << MM_PTE_SHIFT); + return (PMMPDE)(MmpPageMapInfo.PdeBase + Offset); +} + +/** + * Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address. + * + * @param Address + * Specifies the virtual address for which to retrieve the corresponding PPE. + * + * @return This routine returns the address of the PPE. + * + * @since XT 1.0 + */ +XTAPI +PMMPPE +MmpGetPpeAddress(PVOID Address) +{ + ULONGLONG Offset; + + Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << MmpPageMapInfo.VaBits) - 1)) >> MM_PPI_SHIFT) << MM_PTE_SHIFT); + return (PMMPPE)(MmpPageMapInfo.PpeBase + Offset); +} + +/** + * Gets the address of the PTE (Page Table Entry), that maps given address. + * + * @param Address + * Specifies the virtual address for which to retrieve the corresponding PTE. + * + * @return This routine returns the address of the PTE. + * + * @since XT 1.0 + */ +XTAPI +PMMPTE +MmpGetPteAddress(PVOID Address) +{ + ULONGLONG Offset; + + Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << MmpPageMapInfo.VaBits) - 1)) >> MM_PTI_SHIFT) << MM_PTE_SHIFT); + return (PMMPTE)(MmpPageMapInfo.PteBase + Offset); +} + +/** + * Gets the address of the PXE (Extended Page Entry), that maps given address. + * + * @param Address + * Specifies the virtual address for which to retrieve the corresponding PXE. + * + * @return This routine returns the address of the PXE. + * + * @since XT 1.0 + */ +XTAPI +PMMPXE +MmpGetPxeAddress(PVOID Address) +{ + ULONGLONG Offset; + + Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << MmpPageMapInfo.VaBits) - 1)) >> MM_PXI_SHIFT) << MM_PTE_SHIFT); + return (PMMPXE)(MmpPageMapInfo.PxeBase + Offset); +} + +/** + * Checks whether the given page table entry (PTE) is valid. + * + * @param PtePointer + * Pointer to the page table entry (PTE) to check. + * + * @return Returns TRUE if the entry is valid, FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MmpPteValid(PHARDWARE_PTE PtePointer) +{ + return (BOOLEAN)PtePointer->Valid; +} + +/** + * Sets a page table entry (PTE) with the specified physical page and access flags. + * + * @param PtePointer + * Pointer to the page table entry (PTE) to set. + * + * @param PageFrameNumber + * Physical frame number to map. + * + * @param Writable + * Indicates whether the page should be writable. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MmpSetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable) +{ + PtePointer->PageFrameNumber = PageFrameNumber; + PtePointer->Valid = 1; + PtePointer->Writable = Writable; +} + +/** + * Sets caching attributes for a page table entry (PTE). + * + * @param PtePointer + * Pointer to the page table entry (PTE) to modify. + * + * @param CacheDisable + * Indicates whether caching should be disabled for this page. + * + * @param WriteThrough + * Indicates whether write-through caching should be enabled. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MmpSetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough) +{ + PtePointer->CacheDisable = CacheDisable; + PtePointer->WriteThrough = WriteThrough; +} diff --git a/xtoskrnl/mm/globals.c b/xtoskrnl/mm/globals.c index 723c6c9..f3e0878 100644 --- a/xtoskrnl/mm/globals.c +++ b/xtoskrnl/mm/globals.c @@ -24,9 +24,6 @@ ULONG MmNumberOfPhysicalPages; /* Old biggest free memory descriptor */ LOADER_MEMORY_DESCRIPTOR MmOldFreeDescriptor; -/* Page Map Level */ -ULONG MmPageMapLevel; - /* Processor structures data (THIS IS A TEMPORARY HACK) */ UCHAR MmProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE] = {0}; @@ -36,8 +33,11 @@ LOADER_MEMORY_DESCRIPTOR MmpHardwareAllocationDescriptors[MM_HARDWARE_ALLOCATION /* Live address of kernel's hardware heap */ PVOID MmpHardwareHeapStart = MM_HARDWARE_HEAP_START_ADDRESS; -/* Architecture-specific memory extension */ -BOOLEAN MmpMemoryExtension; +/* Information about the current page map */ +MMPAGEMAP_INFO MmpPageMapInfo; + +/* Pointers to page map routines for the current paging mode */ +PCMMPAGEMAP_ROUTINES MmpPageMapRoutines; /* Number of used hardware allocation descriptors */ ULONG MmpUsedHardwareAllocationDescriptors = 0; diff --git a/xtoskrnl/mm/hlpool.c b/xtoskrnl/mm/hlpool.c index 67263e4..5b96fa9 100644 --- a/xtoskrnl/mm/hlpool.c +++ b/xtoskrnl/mm/hlpool.c @@ -190,7 +190,7 @@ MmMapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, ReturnAddress = (PVOID)(ULONG_PTR)ReturnAddress + MM_PAGE_SIZE; /* Check if PTE is valid */ - if(PtePointer->Valid) + if(MmpPageMapRoutines->PteValid(PtePointer)) { /* PTE is not available, go to the next one */ BaseAddress = ReturnAddress; @@ -219,9 +219,7 @@ MmMapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, PtePointer = (PHARDWARE_PTE)MmpGetPteAddress(BaseAddress); /* Fill the PTE */ - PtePointer->PageFrameNumber = (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT); - PtePointer->Valid = 1; - PtePointer->Writable = 1; + MmpPageMapRoutines->SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), TRUE); /* Advance to the next address */ PhysicalAddress.QuadPart += MM_PAGE_SIZE; @@ -268,8 +266,7 @@ MmMarkHardwareMemoryWriteThrough(IN PVOID VirtualAddress, for(Page = 0; Page < PageCount; Page++) { /* Mark pages as CD/WT */ - PtePointer->CacheDisable = 1; - PtePointer->WriteThrough = 1; + MmpPageMapRoutines->SetPteCaching(PtePointer, TRUE, TRUE); PtePointer++; } } @@ -302,9 +299,7 @@ MmRemapHardwareMemory(IN PVOID VirtualAddress, PtePointer = (PHARDWARE_PTE)MmpGetPteAddress(VirtualAddress); /* Remap the PTE */ - PtePointer->PageFrameNumber = (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT); - PtePointer->Valid = 1; - PtePointer->Writable = 1; + MmpPageMapRoutines->SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), TRUE); /* Check if TLB needs to be flushed */ if(FlushTlb) @@ -356,11 +351,7 @@ MmUnmapHardwareMemory(IN PVOID VirtualAddress, for(Page = 0; Page < PageCount; Page++) { /* Unmap the PTE and get the next one */ - PtePointer->CacheDisable = 0; - PtePointer->Valid = 0; - PtePointer->Writable = 0; - PtePointer->WriteThrough = 0; - PtePointer->PageFrameNumber = 0; + MmpPageMapRoutines->ClearPte(PtePointer); PtePointer++; } diff --git a/xtoskrnl/mm/i686/globals.c b/xtoskrnl/mm/i686/globals.c new file mode 100644 index 0000000..97db43e --- /dev/null +++ b/xtoskrnl/mm/i686/globals.c @@ -0,0 +1,26 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/mm/i686/globals.c + * DESCRIPTION: i686-specific global variables for the Memory Manager + * DEVELOPERS: Aiken Harris + */ + +#include + + +/* Page mapping routines for systems using 2-level paging (PML2) */ +CMMPAGEMAP_ROUTINES MmpPml2Routines = { + .ClearPte = MmpClearPte, + .PteValid = MmpPml2PteValid, + .SetPteCaching = MmpSetPml2PteCaching, + .SetPte = MmpSetPml2Pte, +}; + +/* Page mapping routines for systems using 3-level paging (PML3) */ +CMMPAGEMAP_ROUTINES MmpPml3Routines = { + .ClearPte = MmpClearPte, + .PteValid = MmpPml3PteValid, + .SetPteCaching = MmpSetPml3PteCaching, + .SetPte = MmpSetPml3Pte, +}; diff --git a/xtoskrnl/mm/i686/init.c b/xtoskrnl/mm/i686/init.c index aed604b..a473449 100644 --- a/xtoskrnl/mm/i686/init.c +++ b/xtoskrnl/mm/i686/init.c @@ -4,51 +4,56 @@ * FILE: xtoskrnl/mm/i686/init.c * DESCRIPTION: Architecture specific Memory Manager initialization routines * DEVELOPERS: Rafal Kupiec + * Aiken Harris */ #include /** - * Gets the address of the PDE (Page Directory Entry), that maps given address. + * Detects if eXtended Physical Addressing (XPA) is enabled and initializes page map support. * - * @param Address - * Specifies the address to find the PDE for. - * - * @return This routine returns the address of the PDE. + * @return This routine does not return any value. * * @since XT 1.0 */ XTAPI -PMMPTE -MmpGetPdeAddress(PVOID Address) +VOID +MmInitializePageMapSupport(VOID) { - ULONG Offset; + /* Check if XPA is enabled */ + if(MmpGetExtendedPhysicalAddressingStatus()) + { + /* XPA enabled, use modern PAE paging (PML3) */ + MmpPageMapRoutines = &MmpPml3Routines; - /* Calculate offset and return PTE address */ - Offset = ((((ULONG)(Address)) >> MM_PDI_SHIFT) << MM_PTE_SHIFT); - return (PMMPTE)(MM_PDE_BASE + Offset); -} + /* Set PML3 page map information */ + MmpPageMapInfo.Xpa = TRUE; -/** - * Gets the address of the PTE (Page Table Entry), that maps given address. - * - * @param Address - * Specifies the address to find the PTE for. - * - * @return This routine returns the address of the PTE. - * - * @since XT 1.0 - */ -XTAPI -PMMPTE -MmpGetPteAddress(PVOID Address) -{ - ULONG Offset; + /* Set PML3 base addresses */ + MmpPageMapInfo.PteBase = MM_PTE_BASE; + MmpPageMapInfo.PdeBase = MM_PDE_BASE; - /* Calculate offset and return PTE address */ - Offset = ((((ULONG)(Address)) >> MM_PTI_SHIFT) << MM_PTE_SHIFT); - return (PMMPTE)(MM_PTE_BASE + Offset); + /* Set PML3 shift values */ + MmpPageMapInfo.PdiShift = MM_PDI_SHIFT; + MmpPageMapInfo.PteShift = MM_PTE_SHIFT; + } + else + { + /* XPA disabled, use legacy i386 paging (PML2) */ + MmpPageMapRoutines = &MmpPml2Routines; + + /* Set PML2 page map information */ + MmpPageMapInfo.Xpa = FALSE; + + /* Set PML2 base addresses */ + MmpPageMapInfo.PteBase = MM_PTE_BASE; + MmpPageMapInfo.PdeBase = MM_PDE_LEGACY_BASE; + + /* Set PML2 shift values */ + MmpPageMapInfo.PdiShift = MM_PDI_LEGACY_SHIFT; + MmpPageMapInfo.PteShift = MM_PTE_LEGACY_SHIFT; + } } /** @@ -64,18 +69,3 @@ MmpInitializeArchitecture(VOID) { UNIMPLEMENTED; } - -/** - * Checks if PAE (Physical Address Extension) is enabled. - * - * @return This routine returns TRUE if PAE is enabled, or FALSE otherwise. - * - * @since XT 1.0 - */ -XTAPI -BOOLEAN -MmpMemoryExtensionEnabled(VOID) -{ - /* Check if PAE is enabled */ - return ((ArReadControlRegister(4) & CR4_PAE) != 0) ? TRUE : FALSE; -} diff --git a/xtoskrnl/mm/i686/pmap.c b/xtoskrnl/mm/i686/pmap.c new file mode 100644 index 0000000..4decaba --- /dev/null +++ b/xtoskrnl/mm/i686/pmap.c @@ -0,0 +1,242 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/mm/i686/pmap.c + * DESCRIPTION: Low-level support for i686 page map manipulation + * DEVELOPERS: Aiken Harris + */ + +#include + + +/** + * Clears the contents of a page table entry (PTE). + * + * @param PtePointer + * Pointer to the page table entry (PTE) to be cleared. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MmpClearPte(PHARDWARE_PTE PtePointer) +{ + PtePointer->Long = 0; +} + +/** + * Checks if eXtended Physical Addressing (XPA) is enabled. + * + * @return This routine returns TRUE if PAE is enabled, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MmpGetExtendedPhysicalAddressingStatus(VOID) +{ + /* Check if PAE is enabled */ + return ((ArReadControlRegister(4) & CR4_PAE) != 0) ? TRUE : FALSE; +} + +/** + * Gets the address of the PDE (Page Directory Entry), that maps given address. + * + * @param Address + * Specifies the virtual address for which to retrieve the corresponding PDE. + * + * @return This routine returns the address of the PDE. + * + * @since XT 1.0 + */ +XTAPI +PMMPDE +MmpGetPdeAddress(PVOID Address) +{ + ULONG Offset; + + /* Calculate offset and return PTE address */ + Offset = ((((ULONG)(Address)) >> MmpPageMapInfo.PdiShift) << MmpPageMapInfo.PteShift); + return (PMMPTE)(MmpPageMapInfo.PdeBase + Offset); +} + +/** + * Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address. + * + * @param Address + * Specifies the virtual address for which to retrieve the corresponding PDE. + * + * @return This routine returns the address of the PPE. + * + * @since XT 1.0 + */ +XTAPI +PMMPPE +MmpGetPpeAddress(PVOID Address) +{ + /* Return zero */ + return 0; +} + +/** + * Gets the address of the PTE (Page Table Entry), that maps given address. + * + * @param Address + * Specifies the virtual address for which to retrieve the corresponding PTE. + * + * @return This routine returns the address of the PTE. + * + * @since XT 1.0 + */ +XTAPI +PMMPTE +MmpGetPteAddress(PVOID Address) +{ + ULONG Offset; + + /* Calculate offset and return PTE address */ + Offset = ((((ULONG)(Address)) >> MM_PTI_SHIFT) << MmpPageMapInfo.PteShift); + return (PMMPTE)(MM_PTE_BASE + Offset); +} + +/** + * Checks whether the given PML2 page table entry (PTE) is valid. + * + * @param PtePointer + * Pointer to the page table entry (PTE) to check. + * + * @return Returns TRUE if the entry is valid, FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MmpPml2PteValid(PHARDWARE_PTE PtePointer) +{ + return (BOOLEAN)PtePointer->Pml2.Valid; +} + +/** + * Sets a PML2 page table entry (PTE) with the specified physical page and access flags. + * + * @param PtePointer + * Pointer to the page table entry (PTE) to set. + * + * @param PageFrameNumber + * Physical frame number to map. + * + * @param Writable + * Indicates whether the page should be writable. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MmpSetPml2Pte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable) +{ + PtePointer->Pml2.PageFrameNumber = PageFrameNumber; + PtePointer->Pml2.Valid = 1; + PtePointer->Pml2.Writable = Writable; +} + +/** + * Sets caching attributes for a PML2 page table entry (PTE). + * + * @param PtePointer + * Pointer to the page table entry (PTE) to modify. + * + * @param CacheDisable + * Indicates whether caching should be disabled for this page. + * + * @param WriteThrough + * Indicates whether write-through caching should be enabled. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MmpSetPml2PteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough) +{ + PtePointer->Pml2.CacheDisable = CacheDisable; + PtePointer->Pml2.WriteThrough = WriteThrough; +} + +/** + * Checks whether the given PML3 page table entry (PTE) is valid. + * + * @param PtePointer + * Pointer to the page table entry (PTE) to check. + * + * @return Returns TRUE if the entry is valid, FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MmpPml3PteValid(PHARDWARE_PTE PtePointer) +{ + return PtePointer->Pml3.Valid; +} + +/** + * Sets a PML3 page table entry (PTE) with the specified physical page and access flags. + * + * @param PtePointer + * Pointer to the page table entry (PTE) to set. + * + * @param PageFrameNumber + * Physical frame number to map. + * + * @param Writable + * Indicates whether the page should be writable. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MmpSetPml3Pte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable) +{ + PtePointer->Pml3.PageFrameNumber = PageFrameNumber; + PtePointer->Pml3.Valid = 1; + PtePointer->Pml3.Writable = Writable; +} + +/** + * Sets caching attributes for a PML3 page table entry (PTE). + * + * @param PtePointer + * Pointer to the page table entry (PTE) to modify. + * + * @param CacheDisable + * Indicates whether caching should be disabled for this page. + * + * @param WriteThrough + * Indicates whether write-through caching should be enabled. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MmpSetPml3PteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough) +{ + PtePointer->Pml3.CacheDisable = CacheDisable; + PtePointer->Pml3.WriteThrough = WriteThrough; +} diff --git a/xtoskrnl/mm/init.c b/xtoskrnl/mm/init.c index a7d5afd..a0917b9 100644 --- a/xtoskrnl/mm/init.c +++ b/xtoskrnl/mm/init.c @@ -31,9 +31,6 @@ MmInitializeMemoryManager(VOID) KePanic(0); } - /* Store Page Map Level */ - MmPageMapLevel = KeInitializationBlock->LoaderInformation.PageMapLevel; - /* Proceed with architecture specific initialization */ MmpInitializeArchitecture(); }