20#define IA32_PG_RW BIT1
24#define IA32_PG_PS BIT7
25#define IA32_PG_NX BIT63
27#define PAGE_ATTRIBUTE_BITS (IA32_PG_RW | IA32_PG_P)
28#define PAGE_PROGATE_BITS (IA32_PG_D | IA32_PG_A | IA32_PG_NX | IA32_PG_U | \
31#define PAGING_PAE_INDEX_MASK 0x1FF
32#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull
33#define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull
34#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull
35#define PAGING_512G_ADDRESS_MASK_64 0x000FFF8000000000ull
48 PAGE_ATTRIBUTE Attribute;
51 UINTN AddressBitOffset;
52 UINTN AddressBitLength;
56 { PageNone, 0, 0, 0, 0 },
57 { Page4K, SIZE_4KB, PAGING_4K_ADDRESS_MASK_64, 12, 9 },
58 { Page2M, SIZE_2MB, PAGING_2M_ADDRESS_MASK_64, 21, 9 },
59 { Page1G, SIZE_1GB, PAGING_1G_ADDRESS_MASK_64, 30, 9 },
60 { Page512G, SIZE_512GB, PAGING_512G_ADDRESS_MASK_64, 39, 9 },
65 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
66 &gEfiPeiMemoryDiscoveredPpiGuid,
113 if (Address !=
NULL) {
136 return (MsrEfer.
Bits.
LMA == 1) ? Page512G : Page1G;
149 IN PHYSICAL_ADDRESS Address,
150 OUT PAGE_ATTRIBUTE *PageAttribute
156 UINT64 AddressEncMask;
158 AddressEncMask =
PcdGet64 (PcdPteMemoryEncryptionAddressOrMask);
159 PageTable = (UINT64 *)(
UINTN)(
AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64);
161 Index = (
UINTN)
RShiftU64 (Address, mPageAttributeTable[Level].AddressBitOffset);
162 Index &= PAGING_PAE_INDEX_MASK;
167 if (PageTable[Index] == 0) {
168 *PageAttribute = PageNone;
175 if (((PageTable[Index] & IA32_PG_PS) != 0) || (Level == PageMin)) {
176 *PageAttribute = (PAGE_ATTRIBUTE)Level;
177 return &PageTable[Index];
183 PageTable = (UINT64 *)(
UINTN)(PageTable[Index] &
185 PAGING_4K_ADDRESS_MASK_64);
188 *PageAttribute = PageNone;
206 IN UINT64 *PageEntry,
207 IN PAGE_ATTRIBUTE PageAttribute,
208 IN PAGE_ATTRIBUTE SplitAttribute,
209 IN BOOLEAN Recursively
213 UINT64 *NewPageEntry;
215 UINT64 AddressEncMask;
216 PAGE_ATTRIBUTE SplitTo;
218 if ((SplitAttribute == PageNone) || (SplitAttribute >= PageAttribute)) {
219 ASSERT (SplitAttribute != PageNone);
220 ASSERT (SplitAttribute < PageAttribute);
225 if (NewPageEntry ==
NULL) {
226 ASSERT (NewPageEntry !=
NULL);
233 SplitTo = PageAttribute - 1;
234 AddressEncMask =
PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) &
235 mPageAttributeTable[SplitTo].AddressMask;
236 BaseAddress = *PageEntry &
237 ~PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) &
238 mPageAttributeTable[PageAttribute].AddressMask;
239 for (Index = 0; Index < SIZE_4KB /
sizeof (UINT64); Index++) {
240 NewPageEntry[Index] = BaseAddress | AddressEncMask |
241 ((*PageEntry) & PAGE_PROGATE_BITS);
243 if (SplitTo != PageMin) {
244 NewPageEntry[Index] |= IA32_PG_PS;
247 if (Recursively && (SplitTo > SplitAttribute)) {
248 SplitPage (&NewPageEntry[Index], SplitTo, SplitAttribute, Recursively);
251 BaseAddress += mPageAttributeTable[SplitTo].Length;
254 (*PageEntry) = (UINT64)(
UINTN)NewPageEntry | AddressEncMask | PAGE_ATTRIBUTE_BITS;
284 IN PHYSICAL_ADDRESS BaseAddress,
290 PAGE_ATTRIBUTE PageAttribute;
291 RETURN_STATUS Status;
295 ((BaseAddress & (SIZE_4KB - 1)) != 0) ||
296 ((Length & (SIZE_4KB - 1)) != 0))
299 ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0);
300 ASSERT ((Length & (SIZE_4KB - 1)) == 0);
306 if ((BaseAddress > MaximumAddress) ||
307 (Length > MaximumAddress) ||
308 (BaseAddress > MaximumAddress - (Length - 1)))
316 while (Length != 0) {
318 if (PageEntry ==
NULL) {
322 if (PageAttribute != Page4K) {
337 if ((Attributes & IA32_PG_P) != 0) {
338 *PageEntry |= (UINT64)IA32_PG_P;
340 *PageEntry &= ~((UINT64)IA32_PG_P);
346 BaseAddress += SIZE_4KB;
376 MapAttribute.Uint64 = 0;
377 MapMask.Uint64 = MAX_UINT64;
378 MapAttribute.Bits.Present = 1;
379 MapAttribute.Bits.ReadWrite = 1;
384 Status =
PageTableMap (&PageTable, PagingPae, 0, &BufferSize, 0, SIZE_4GB, &MapAttribute, &MapMask,
NULL);
385 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
386 if (Status != EFI_BUFFER_TOO_SMALL) {
394 ASSERT (Buffer !=
NULL);
395 if (Buffer ==
NULL) {
396 return EFI_OUT_OF_RESOURCES;
399 Status =
PageTableMap (&PageTable, PagingPae, Buffer, &BufferSize, 0, SIZE_4GB, &MapAttribute, &MapMask,
NULL);
401 if (EFI_ERROR (Status) || (PageTable == 0)) {
402 return EFI_OUT_OF_RESOURCES;
422 "EnablePaePageTable: Created PageTable = 0x%x, BufferSize = %x\n",
451 StackBase += BASE_4KB;
453 StackBase -=
PcdGet32 (PcdCpuApStackSize);
470 UINTN NumberOfProcessors;
478 if (
PcdGet32 (PcdCpuApStackSize) <= EFI_PAGE_SIZE) {
479 DEBUG ((DEBUG_ERROR,
"PcdCpuApStackSize is not big enough for Stack Guard!\n"));
486 if (EFI_ERROR (Status)) {
487 NumberOfProcessors = 1;
491 for (Index = 0; Index < NumberOfProcessors; ++Index) {
496 while ((Hob.Raw =
GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) !=
NULL) {
498 &gEfiHobMemoryAllocStackGuid,
506 Hob.Raw = GET_NEXT_HOB (Hob);
515 ASSERT (StackBase != 0);
522 "Stack Guard set at %lx [cpu%lu]!\n",
556 BOOLEAN InitStackGuard;
566 InitStackGuard =
FALSE;
570 InitStackGuard =
PcdGetBool (PcdCpuStackGuard);
578 if ((Cr0.Bits.PG == 0) && (InitStackGuard || (Hob.Raw !=
NULL))) {
579 ASSERT (
sizeof (
UINTN) ==
sizeof (UINT32));
582 if (EFI_ERROR (Status)) {
583 DEBUG ((DEBUG_ERROR,
"MemoryDiscoveredPpiNotifyCallback: Failed to enable PAE page table: %r.\n", Status));
591 if (InitStackGuard) {
595 while (Hob.Raw !=
NULL) {
596 MigratedFvInfo = GET_GUID_HOB_DATA (Hob);
604 Hob.Raw = GET_NEXT_HOB (Hob);
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
VOID *EFIAPI GetNextHob(IN UINT16 Type, IN CONST VOID *HobStart)
VOID *EFIAPI GetNextGuidHob(IN CONST EFI_GUID *Guid, IN CONST VOID *HobStart)
VOID *EFIAPI GetHobList(VOID)
#define RETURN_ERROR(StatusCode)
#define RETURN_UNSUPPORTED
#define RETURN_OUT_OF_RESOURCES
#define RETURN_INVALID_PARAMETER
VOID EFIAPI CpuDeadLoop(VOID)
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define MSR_CORE_IA32_EFER
VOID EFIAPI CpuFlushTlb(VOID)
EFI_STATUS InitializeCpuMpWorker(IN CONST EFI_PEI_SERVICES **PeiServices)
RETURN_STATUS EFIAPI PageTableMap(IN OUT UINTN *PageTable OPTIONAL, IN PAGING_MODE PagingMode, IN VOID *Buffer, IN OUT UINTN *BufferSize, IN UINT64 LinearAddress, IN UINT64 Length, IN IA32_MAP_ATTRIBUTE *Attribute, IN IA32_MAP_ATTRIBUTE *Mask, OUT BOOLEAN *IsModified OPTIONAL)
PAGE_ATTRIBUTE GetPageTableTopLevelType(VOID)
VOID SetupStackGuardPage(VOID)
BOOLEAN IsIa32PaeSupported(VOID)
VOID * GetPageTableEntry(IN PHYSICAL_ADDRESS Address, OUT PAGE_ATTRIBUTE *PageAttribute)
EFI_STATUS EFIAPI MemoryDiscoveredPpiNotifyCallback(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi)
RETURN_STATUS EFIAPI ConvertMemoryPageAttributes(IN PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
VOID * AllocatePageTableMemory(IN UINTN Pages)
EFI_STATUS EnablePaePageTable(VOID)
VOID EFIAPI GetStackBase(IN OUT VOID *Buffer)
RETURN_STATUS SplitPage(IN UINT64 *PageEntry, IN PAGE_ATTRIBUTE PageAttribute, IN PAGE_ATTRIBUTE SplitAttribute, IN BOOLEAN Recursively)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
UINTN EFIAPI AsmReadCr3(VOID)
UINT64 EFIAPI AsmReadMsr64(IN UINT32 Index)
UINTN EFIAPI AsmWriteCr3(UINTN Cr3)
UINTN EFIAPI AsmWriteCr4(UINTN Cr4)
UINTN EFIAPI AsmReadCr0(VOID)
UINTN EFIAPI AsmWriteCr0(UINTN Cr0)
UINTN EFIAPI AsmReadCr4(VOID)
#define CPUID_VERSION_INFO
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
EFI_STATUS EFIAPI MpInitLibWhoAmI(OUT UINTN *ProcessorNumber)
EFI_STATUS EFIAPI MpInitLibGetNumberOfProcessors(OUT UINTN *NumberOfProcessors OPTIONAL, OUT UINTN *NumberOfEnabledProcessors OPTIONAL)
EFI_STATUS EFIAPI MpInitLibStartupThisAP(IN EFI_AP_PROCEDURE Procedure, IN UINTN ProcessorNumber, IN EFI_EVENT WaitEvent OPTIONAL, IN UINTN TimeoutInMicroseconds, IN VOID *ProcedureArgument OPTIONAL, OUT BOOLEAN *Finished OPTIONAL)
#define PcdGet64(TokenName)
#define PcdGet32(TokenName)
#define PcdGetBool(TokenName)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_PAGES_TO_SIZE(Pages)
#define EFI_SIZE_TO_PAGES(Size)
EFI_PHYSICAL_ADDRESS MemoryBaseAddress
EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor
struct CPUID_VERSION_INFO_EDX::@633 Bits
struct MSR_IA32_EFER_REGISTER::@628 Bits