# PPI to discover and dispatch the DXE Foundation and components that are\r
# needed to run the DXE Foundation.\r
#\r
-# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
# This program and the accompanying materials\r
# are licensed and made available under the terms and conditions of the BSD License\r
# which accompanies this distribution. The full text of the license may be found at\r
\r
[Pcd.IA32,Pcd.X64]\r
gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES\r
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES\r
\r
[Depex]\r
gEfiPeiMemoryDiscoveredPpiGuid AND gEfiPeiLoadFilePpiGuid AND gEfiPeiMasterBootModePpiGuid\r
/** @file\r
Ia32-specific functionality for DxeLoad.\r
\r
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
0\r
};\r
\r
+/**\r
+ Allocates and fills in the Page Directory and Page Table Entries to\r
+ establish a 4G page table.\r
+\r
+ @param[in] StackBase Stack base address.\r
+ @param[in] StackSize Stack size.\r
+\r
+ @return The address of page table.\r
+\r
+**/\r
+UINTN\r
+Create4GPageTablesIa32Pae (\r
+ IN EFI_PHYSICAL_ADDRESS StackBase,\r
+ IN UINTN StackSize\r
+ )\r
+{ \r
+ UINT8 PhysicalAddressBits;\r
+ EFI_PHYSICAL_ADDRESS PhysicalAddress;\r
+ UINTN IndexOfPdpEntries;\r
+ UINTN IndexOfPageDirectoryEntries;\r
+ UINT32 NumberOfPdpEntriesNeeded;\r
+ PAGE_MAP_AND_DIRECTORY_POINTER *PageMap;\r
+ PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;\r
+ PAGE_TABLE_ENTRY *PageDirectoryEntry;\r
+ UINTN TotalPagesNum;\r
+ UINTN PageAddress;\r
+\r
+ PhysicalAddressBits = 32;\r
+\r
+ //\r
+ // Calculate the table entries needed.\r
+ //\r
+ NumberOfPdpEntriesNeeded = (UINT32) LShiftU64 (1, (PhysicalAddressBits - 30));\r
+\r
+ TotalPagesNum = NumberOfPdpEntriesNeeded + 1;\r
+ PageAddress = (UINTN) AllocatePages (TotalPagesNum);\r
+ ASSERT (PageAddress != 0);\r
+\r
+ PageMap = (VOID *) PageAddress;\r
+ PageAddress += SIZE_4KB;\r
+\r
+ PageDirectoryPointerEntry = PageMap;\r
+ PhysicalAddress = 0;\r
+\r
+ for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {\r
+ //\r
+ // Each Directory Pointer entries points to a page of Page Directory entires.\r
+ // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.\r
+ // \r
+ PageDirectoryEntry = (VOID *) PageAddress;\r
+ PageAddress += SIZE_4KB;\r
+\r
+ //\r
+ // Fill in a Page Directory Pointer Entries\r
+ //\r
+ PageDirectoryPointerEntry->Uint64 = (UINT64) (UINTN) PageDirectoryEntry;\r
+ PageDirectoryPointerEntry->Bits.Present = 1;\r
+\r
+ for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress += SIZE_2MB) {\r
+ if ((PhysicalAddress < StackBase + StackSize) && ((PhysicalAddress + SIZE_2MB) > StackBase)) {\r
+ //\r
+ // Need to split this 2M page that covers stack range.\r
+ //\r
+ Split2MPageTo4K (PhysicalAddress, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);\r
+ } else {\r
+ //\r
+ // Fill in the Page Directory entries\r
+ //\r
+ PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress;\r
+ PageDirectoryEntry->Bits.ReadWrite = 1;\r
+ PageDirectoryEntry->Bits.Present = 1;\r
+ PageDirectoryEntry->Bits.MustBe1 = 1;\r
+ }\r
+ }\r
+ }\r
+\r
+ for (; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {\r
+ ZeroMem (\r
+ PageDirectoryPointerEntry,\r
+ sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)\r
+ );\r
+ }\r
+\r
+ return (UINTN) PageMap;\r
+}\r
+\r
+/**\r
+ The function will check if IA32 PAE is supported.\r
+\r
+ @retval TRUE IA32 PAE is supported.\r
+ @retval FALSE IA32 PAE is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+IsIa32PaeSupport (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 RegEax;\r
+ UINT32 RegEdx;\r
+ BOOLEAN Ia32PaeSupport;\r
+\r
+ Ia32PaeSupport = FALSE;\r
+ AsmCpuid (0x0, &RegEax, NULL, NULL, NULL);\r
+ if (RegEax >= 0x1) {\r
+ AsmCpuid (0x1, NULL, NULL, NULL, &RegEdx);\r
+ if ((RegEdx & BIT6) != 0) {\r
+ Ia32PaeSupport = TRUE;\r
+ }\r
+ }\r
+\r
+ return Ia32PaeSupport;\r
+}\r
+\r
+/**\r
+ The function will check if Execute Disable Bit is available.\r
+\r
+ @retval TRUE Execute Disable Bit is available.\r
+ @retval FALSE Execute Disable Bit is not available.\r
+\r
+**/\r
+BOOLEAN\r
+IsExecuteDisableBitAvailable (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 RegEax;\r
+ UINT32 RegEdx;\r
+ BOOLEAN Available;\r
+\r
+ Available = FALSE;\r
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
+ if (RegEax >= 0x80000001) {\r
+ AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);\r
+ if ((RegEdx & BIT20) != 0) {\r
+ //\r
+ // Bit 20: Execute Disable Bit available.\r
+ //\r
+ Available = TRUE;\r
+ }\r
+ }\r
+\r
+ return Available;\r
+}\r
+\r
/**\r
Transfers control to DxeCore.\r
\r
X64_IDT_TABLE *IdtTableForX64;\r
EFI_VECTOR_HANDOFF_INFO *VectorInfo;\r
EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;\r
+ BOOLEAN BuildPageTablesIa32Pae;\r
\r
Status = PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);\r
ASSERT_EFI_ERROR (Status);\r
//\r
// Create page table and save PageMapLevel4 to CR3\r
//\r
- PageTables = CreateIdentityMappingPageTables ();\r
+ PageTables = CreateIdentityMappingPageTables (BaseOfStack, STACK_SIZE);\r
\r
//\r
// End of PEI phase signal\r
TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT;\r
TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);\r
\r
+ BuildPageTablesIa32Pae = (BOOLEAN) (PcdGetBool (PcdSetNxForStack) && IsIa32PaeSupport () && IsExecuteDisableBitAvailable ());\r
+ if (BuildPageTablesIa32Pae) {\r
+ PageTables = Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZE);\r
+ EnableExecuteDisableBit ();\r
+ }\r
+\r
//\r
// End of PEI phase signal\r
//\r
Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ if (BuildPageTablesIa32Pae) {\r
+ AsmWriteCr3 (PageTables);\r
+ //\r
+ // Set Physical Address Extension (bit 5 of CR4).\r
+ //\r
+ AsmWriteCr4 (AsmReadCr4 () | BIT5);\r
+ }\r
+\r
//\r
// Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.\r
//\r
//\r
// Transfer the control to the entry point of DxeCore.\r
//\r
- SwitchStack (\r
- (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,\r
- HobList.Raw,\r
- NULL,\r
- (VOID *) (UINTN) TopOfStack\r
- );\r
+ if (BuildPageTablesIa32Pae) {\r
+ AsmEnablePaging32 (\r
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,\r
+ HobList.Raw,\r
+ NULL,\r
+ (VOID *) (UINTN) TopOfStack\r
+ );\r
+ } else {\r
+ SwitchStack (\r
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,\r
+ HobList.Raw,\r
+ NULL,\r
+ (VOID *) (UINTN) TopOfStack\r
+ );\r
+ }\r
}\r
}\r
\r
/** @file\r
x64-specifc functionality for DxeLoad.\r
\r
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
//\r
// Create page table and save PageMapLevel4 to CR3\r
//\r
- PageTables = CreateIdentityMappingPageTables ();\r
+ PageTables = CreateIdentityMappingPageTables ((EFI_PHYSICAL_ADDRESS) (UINTN) BaseOfStack, STACK_SIZE);\r
+ } else {\r
+ //\r
+ // Set NX for stack feature also require PcdDxeIplBuildPageTables be TRUE\r
+ // for the DxeIpl and the DxeCore are both X64.\r
+ //\r
+ ASSERT (PcdGetBool (PcdSetNxForStack) == FALSE);\r
}\r
\r
//\r
2) IA-32 Intel(R) Architecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel\r
3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel\r
\r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
#include "DxeIpl.h"\r
#include "VirtualMemory.h"\r
\r
+/**\r
+ Enable Execute Disable Bit.\r
+\r
+**/\r
+VOID\r
+EnableExecuteDisableBit (\r
+ VOID\r
+ )\r
+{\r
+ UINT64 MsrRegisters;\r
+\r
+ MsrRegisters = AsmReadMsr64 (0xC0000080);\r
+ MsrRegisters |= BIT11;\r
+ AsmWriteMsr64 (0xC0000080, MsrRegisters);\r
+}\r
+\r
+/**\r
+ Split 2M page to 4K.\r
+\r
+ @param[in] PhysicalAddress Start physical address the 2M page covered.\r
+ @param[in, out] PageEntry2M Pointer to 2M page entry.\r
+ @param[in] StackBase Stack base address.\r
+ @param[in] StackSize Stack size.\r
+\r
+**/\r
+VOID\r
+Split2MPageTo4K (\r
+ IN EFI_PHYSICAL_ADDRESS PhysicalAddress,\r
+ IN OUT UINT64 *PageEntry2M,\r
+ IN EFI_PHYSICAL_ADDRESS StackBase,\r
+ IN UINTN StackSize\r
+ )\r
+{\r
+ EFI_PHYSICAL_ADDRESS PhysicalAddress4K;\r
+ UINTN IndexOfPageTableEntries;\r
+ PAGE_TABLE_4K_ENTRY *PageTableEntry;\r
+\r
+ PageTableEntry = AllocatePages (1);\r
+ //\r
+ // Fill in 2M page entry.\r
+ //\r
+ *PageEntry2M = (UINT64) (UINTN) PageTableEntry | IA32_PG_P | IA32_PG_RW;\r
+\r
+ PhysicalAddress4K = PhysicalAddress;\r
+ for (IndexOfPageTableEntries = 0; IndexOfPageTableEntries < 512; IndexOfPageTableEntries++, PageTableEntry++, PhysicalAddress4K += SIZE_4KB) {\r
+ //\r
+ // Fill in the Page Table entries\r
+ //\r
+ PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K;\r
+ PageTableEntry->Bits.ReadWrite = 1;\r
+ PageTableEntry->Bits.Present = 1;\r
+ if ((PhysicalAddress4K >= StackBase) && (PhysicalAddress4K < StackBase + StackSize)) {\r
+ //\r
+ // Set Nx bit for stack.\r
+ //\r
+ PageTableEntry->Bits.Nx = 1;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Split 1G page to 2M.\r
+\r
+ @param[in] PhysicalAddress Start physical address the 1G page covered.\r
+ @param[in, out] PageEntry1G Pointer to 1G page entry.\r
+ @param[in] StackBase Stack base address.\r
+ @param[in] StackSize Stack size.\r
+\r
+**/\r
+VOID\r
+Split1GPageTo2M (\r
+ IN EFI_PHYSICAL_ADDRESS PhysicalAddress,\r
+ IN OUT UINT64 *PageEntry1G,\r
+ IN EFI_PHYSICAL_ADDRESS StackBase,\r
+ IN UINTN StackSize\r
+ )\r
+{\r
+ EFI_PHYSICAL_ADDRESS PhysicalAddress2M;\r
+ UINTN IndexOfPageDirectoryEntries;\r
+ PAGE_TABLE_ENTRY *PageDirectoryEntry;\r
+\r
+ PageDirectoryEntry = AllocatePages (1);\r
+ //\r
+ // Fill in 1G page entry.\r
+ //\r
+ *PageEntry1G = (UINT64) (UINTN) PageDirectoryEntry | IA32_PG_P | IA32_PG_RW;\r
+\r
+ PhysicalAddress2M = PhysicalAddress;\r
+ for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += SIZE_2MB) {\r
+ if ((PhysicalAddress2M < StackBase + StackSize) && ((PhysicalAddress2M + SIZE_2MB) > StackBase)) {\r
+ //\r
+ // Need to split this 2M page that covers stack range.\r
+ //\r
+ Split2MPageTo4K (PhysicalAddress2M, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);\r
+ } else {\r
+ //\r
+ // Fill in the Page Directory entries\r
+ //\r
+ PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress2M;\r
+ PageDirectoryEntry->Bits.ReadWrite = 1;\r
+ PageDirectoryEntry->Bits.Present = 1;\r
+ PageDirectoryEntry->Bits.MustBe1 = 1;\r
+ }\r
+ }\r
+}\r
+\r
/**\r
Allocates and fills in the Page Directory and Page Table Entries to\r
establish a 1:1 Virtual to Physical mapping.\r
\r
- @param NumberOfProcessorPhysicalAddressBits Number of processor address bits \r
- to use. Limits the number of page \r
- table entries to the physical \r
- address space. \r
+ @param[in] StackBase Stack base address.\r
+ @param[in] StackSize Stack size.\r
\r
@return The address of 4 level page map.\r
\r
**/\r
UINTN\r
CreateIdentityMappingPageTables (\r
- VOID\r
+ IN EFI_PHYSICAL_ADDRESS StackBase,\r
+ IN UINTN StackSize\r
)\r
{ \r
UINT32 RegEax;\r
PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry;\r
\r
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {\r
- //\r
- // Fill in the Page Directory entries\r
- //\r
- PageDirectory1GEntry->Uint64 = (UINT64)PageAddress;\r
- PageDirectory1GEntry->Bits.ReadWrite = 1;\r
- PageDirectory1GEntry->Bits.Present = 1;\r
- PageDirectory1GEntry->Bits.MustBe1 = 1;\r
+ if (PcdGetBool (PcdSetNxForStack) && (PageAddress < StackBase + StackSize) && ((PageAddress + SIZE_1GB) > StackBase)) {\r
+ Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry, StackBase, StackSize);\r
+ } else {\r
+ //\r
+ // Fill in the Page Directory entries\r
+ //\r
+ PageDirectory1GEntry->Uint64 = (UINT64)PageAddress;\r
+ PageDirectory1GEntry->Bits.ReadWrite = 1;\r
+ PageDirectory1GEntry->Bits.Present = 1;\r
+ PageDirectory1GEntry->Bits.MustBe1 = 1;\r
+ }\r
}\r
} else {\r
for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {\r
PageDirectoryPointerEntry->Bits.Present = 1;\r
\r
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {\r
- //\r
- // Fill in the Page Directory entries\r
- //\r
- PageDirectoryEntry->Uint64 = (UINT64)PageAddress;\r
- PageDirectoryEntry->Bits.ReadWrite = 1;\r
- PageDirectoryEntry->Bits.Present = 1;\r
- PageDirectoryEntry->Bits.MustBe1 = 1;\r
+ if (PcdGetBool (PcdSetNxForStack) && (PageAddress < StackBase + StackSize) && ((PageAddress + SIZE_2MB) > StackBase)) {\r
+ //\r
+ // Need to split this 2M page that covers stack range.\r
+ //\r
+ Split2MPageTo4K (PageAddress, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);\r
+ } else {\r
+ //\r
+ // Fill in the Page Directory entries\r
+ //\r
+ PageDirectoryEntry->Uint64 = (UINT64)PageAddress;\r
+ PageDirectoryEntry->Bits.ReadWrite = 1;\r
+ PageDirectoryEntry->Bits.Present = 1;\r
+ PageDirectoryEntry->Bits.MustBe1 = 1;\r
+ }\r
}\r
}\r
\r
);\r
}\r
\r
+ if (PcdGetBool (PcdSetNxForStack)) {\r
+ EnableExecuteDisableBit ();\r
+ }\r
+\r
return (UINTN)PageMap;\r
}\r
\r
3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel\r
4) AMD64 Architecture Programmer's Manual Volume 2: System Programming\r
\r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
UINT64 Uint64;\r
} PAGE_MAP_AND_DIRECTORY_POINTER;\r
\r
+//\r
+// Page Table Entry 4KB\r
+//\r
+typedef union {\r
+ struct {\r
+ UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory\r
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write\r
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User\r
+ UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching\r
+ UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached\r
+ UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)\r
+ UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page\r
+ UINT64 PAT:1; //\r
+ UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write\r
+ UINT64 Available:3; // Available for use by system software\r
+ UINT64 PageTableBaseAddress:40; // Page Table Base Address\r
+ UINT64 AvabilableHigh:11; // Available for use by system software\r
+ UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution\r
+ } Bits;\r
+ UINT64 Uint64;\r
+} PAGE_TABLE_4K_ENTRY;\r
+\r
//\r
// Page Table Entry 2MB\r
//\r
\r
#pragma pack()\r
\r
+#define IA32_PG_P BIT0\r
+#define IA32_PG_RW BIT1\r
+\r
+/**\r
+ Enable Execute Disable Bit.\r
+\r
+**/\r
+VOID\r
+EnableExecuteDisableBit (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Split 2M page to 4K.\r
+\r
+ @param[in] PhysicalAddress Start physical address the 2M page covered.\r
+ @param[in, out] PageEntry2M Pointer to 2M page entry.\r
+ @param[in] StackBase Stack base address.\r
+ @param[in] StackSize Stack size.\r
+\r
+**/\r
+VOID\r
+Split2MPageTo4K (\r
+ IN EFI_PHYSICAL_ADDRESS PhysicalAddress,\r
+ IN OUT UINT64 *PageEntry2M,\r
+ IN EFI_PHYSICAL_ADDRESS StackBase,\r
+ IN UINTN StackSize\r
+ );\r
\r
/**\r
Allocates and fills in the Page Directory and Page Table Entries to\r
establish a 1:1 Virtual to Physical mapping.\r
\r
- @param NumberOfProcessorPhysicalAddressBits Number of processor address bits \r
- to use. Limits the number of page \r
- table entries to the physical \r
- address space. \r
+ @param[in] StackBase Stack base address.\r
+ @param[in] StackSize Stack size.\r
\r
@return The address of 4 level page map.\r
\r
**/\r
UINTN\r
CreateIdentityMappingPageTables (\r
- VOID\r
+ IN EFI_PHYSICAL_ADDRESS StackBase,\r
+ IN UINTN StackSize\r
);\r
\r
\r
## The number of bytes between registers in serial device. The default is 1 byte.\r
# @Prompt Serial Port Register Stride in Bytes\r
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|1|UINT32|0x0001006d\r
- \r
+\r
+ ## Indicates if to set NX for stack.<BR><BR>\r
+ # For the DxeIpl and the DxeCore are both X64, set NX for stack feature also require PcdDxeIplBuildPageTables be TRUE.<BR>\r
+ # For the DxeIpl and the DxeCore are both IA32 (PcdDxeIplSwitchToLongMode is FALSE), set NX for stack feature also require\r
+ # IA32 PAE is supported and Execute Disable Bit is available.<BR>\r
+ # TRUE - to set NX for stack.<BR>\r
+ # FALSE - Not to set NX for stack.<BR>\r
+ # @Prompt Set NX for stack.\r
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE|BOOLEAN|0x0001006f\r
+\r
[PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]\r
## This PCD defines the Console output row. The default value is 25 according to UEFI spec.\r
# This PCD could be set to 0 then console output would be at max column and max row.\r