1 /** @file 2 3 Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12 Module Name: 13 Paging.c 14 15 Abstract: 16 17 Revision History: 18 19 **/ 20 21 #include "DxeIpl.h" 22 #include "HobGeneration.h" 23 #include "VirtualMemory.h" 24 #include "Debug.h" 25 26 #define EFI_PAGE_SIZE_4K 0x1000 27 #define EFI_PAGE_SIZE_4M 0x400000 28 29 // 30 // Create 4G 4M-page table 31 // PDE (31:22) : 1024 entries 32 // 33 #define EFI_MAX_ENTRY_NUM 1024 34 35 #define EFI_PDE_ENTRY_NUM EFI_MAX_ENTRY_NUM 36 37 #define EFI_PDE_PAGE_NUM 1 38 39 #define EFI_PAGE_NUMBER_4M (EFI_PDE_PAGE_NUM) 40 41 // 42 // Create 4M 4K-page table 43 // PTE (21:12) : 1024 entries 44 // 45 #define EFI_PTE_ENTRY_NUM EFI_MAX_ENTRY_NUM 46 #define EFI_PTE_PAGE_NUM 1 47 48 #define EFI_PAGE_NUMBER_4K (EFI_PTE_PAGE_NUM) 49 50 #define EFI_PAGE_NUMBER (EFI_PAGE_NUMBER_4M + EFI_PAGE_NUMBER_4K) 51 52 VOID 53 EnableNullPointerProtection ( 54 UINT8 *PageTable 55 ) 56 { 57 IA32_PAGE_TABLE_ENTRY_4K *PageTableEntry4KB; 58 59 PageTableEntry4KB = (IA32_PAGE_TABLE_ENTRY_4K *)((UINTN)PageTable + EFI_PAGE_NUMBER_4M * EFI_PAGE_SIZE_4K); 60 61 // 62 // Fill in the Page Table entries 63 // Mark 0~4K as not present 64 // 65 PageTableEntry4KB->Bits.Present = 0; 66 67 return ; 68 } 69 70 VOID 71 Ia32Create4KPageTables ( 72 UINT8 *PageTable 73 ) 74 { 75 UINT64 PageAddress; 76 UINTN PTEIndex; 77 IA32_PAGE_DIRECTORY_ENTRY_4K *PageDirectoryEntry4KB; 78 IA32_PAGE_TABLE_ENTRY_4K *PageTableEntry4KB; 79 80 PageAddress = 0; 81 82 // 83 // Page Table structure 2 level 4K. 84 // 85 // Page Table 4K : PageDirectoryEntry4K : bits 31-22 86 // PageTableEntry : bits 21-12 87 // 88 89 PageTableEntry4KB = (IA32_PAGE_TABLE_ENTRY_4K *)((UINTN)PageTable + EFI_PAGE_NUMBER_4M * EFI_PAGE_SIZE_4K); 90 PageDirectoryEntry4KB = (IA32_PAGE_DIRECTORY_ENTRY_4K *)((UINTN)PageTable); 91 92 PageDirectoryEntry4KB->Uint32 = (UINT32)(UINTN)PageTableEntry4KB; 93 PageDirectoryEntry4KB->Bits.ReadWrite = 0; 94 PageDirectoryEntry4KB->Bits.Present = 1; 95 PageDirectoryEntry4KB->Bits.MustBeZero = 1; 96 97 for (PTEIndex = 0; PTEIndex < EFI_PTE_ENTRY_NUM; PTEIndex++, PageTableEntry4KB++) { 98 // 99 // Fill in the Page Table entries 100 // 101 PageTableEntry4KB->Uint32 = (UINT32)PageAddress; 102 PageTableEntry4KB->Bits.ReadWrite = 1; 103 PageTableEntry4KB->Bits.Present = 1; 104 105 PageAddress += EFI_PAGE_SIZE_4K; 106 } 107 108 return ; 109 } 110 111 VOID 112 Ia32Create4MPageTables ( 113 UINT8 *PageTable 114 ) 115 { 116 UINT32 PageAddress; 117 UINT8 *TempPageTable; 118 UINTN PDEIndex; 119 IA32_PAGE_TABLE_ENTRY_4M *PageDirectoryEntry4MB; 120 121 TempPageTable = PageTable; 122 123 PageAddress = 0; 124 125 // 126 // Page Table structure 1 level 4MB. 127 // 128 // Page Table 4MB : PageDirectoryEntry4M : bits 31-22 129 // 130 131 PageDirectoryEntry4MB = (IA32_PAGE_TABLE_ENTRY_4M *)TempPageTable; 132 133 for (PDEIndex = 0; PDEIndex < EFI_PDE_ENTRY_NUM; PDEIndex++, PageDirectoryEntry4MB++) { 134 // 135 // Fill in the Page Directory entries 136 // 137 PageDirectoryEntry4MB->Uint32 = (UINT32)PageAddress; 138 PageDirectoryEntry4MB->Bits.ReadWrite = 1; 139 PageDirectoryEntry4MB->Bits.Present = 1; 140 PageDirectoryEntry4MB->Bits.MustBe1 = 1; 141 142 PageAddress += EFI_PAGE_SIZE_4M; 143 } 144 145 return ; 146 } 147 148 VOID * 149 PreparePageTable ( 150 VOID *PageNumberTop, 151 UINT8 SizeOfMemorySpace 152 ) 153 /*++ 154 Description: 155 Generate pagetable below PageNumberTop, 156 and return the bottom address of pagetable for putting other things later. 157 --*/ 158 { 159 VOID *PageNumberBase; 160 161 PageNumberBase = (VOID *)((UINTN)PageNumberTop - EFI_PAGE_NUMBER * EFI_PAGE_SIZE_4K); 162 ZeroMem (PageNumberBase, EFI_PAGE_NUMBER * EFI_PAGE_SIZE_4K); 163 164 Ia32Create4MPageTables (PageNumberBase); 165 Ia32Create4KPageTables (PageNumberBase); 166 // 167 // Not enable NULL Pointer Protection if using INTX call 168 // 169 // EnableNullPointerProtection (PageNumberBase); 170 171 return PageNumberBase; 172 } 173