mirror of https://github.com/acidanthera/audk.git
MdeModulePkg DxeIpl: Add stack NX support
This feature is added for UEFI spec that says "Stack may be marked as non-executable in identity mapped page tables". A PCD PcdSetNxForStack is added to turn on/off this feature, and it is FALSE by default. Cc: Jiewen Yao <jiewen.yao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: "Yao, Jiewen" <Jiewen.yao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18166 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
edaea0e7bf
commit
5630cdfe9f
|
@ -5,7 +5,7 @@
|
|||
# PPI to discover and dispatch the DXE Foundation and components that are
|
||||
# needed to run the DXE Foundation.
|
||||
#
|
||||
# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -104,6 +104,7 @@
|
|||
|
||||
[Pcd.IA32,Pcd.X64]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES
|
||||
|
||||
[Depex]
|
||||
gEfiPeiMemoryDiscoveredPpiGuid AND gEfiPeiLoadFilePpiGuid AND gEfiPeiMasterBootModePpiGuid
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Ia32-specific functionality for DxeLoad.
|
||||
|
||||
Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -56,6 +56,151 @@ GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR gLidtDescriptor = {
|
|||
0
|
||||
};
|
||||
|
||||
/**
|
||||
Allocates and fills in the Page Directory and Page Table Entries to
|
||||
establish a 4G page table.
|
||||
|
||||
@param[in] StackBase Stack base address.
|
||||
@param[in] StackSize Stack size.
|
||||
|
||||
@return The address of page table.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
Create4GPageTablesIa32Pae (
|
||||
IN EFI_PHYSICAL_ADDRESS StackBase,
|
||||
IN UINTN StackSize
|
||||
)
|
||||
{
|
||||
UINT8 PhysicalAddressBits;
|
||||
EFI_PHYSICAL_ADDRESS PhysicalAddress;
|
||||
UINTN IndexOfPdpEntries;
|
||||
UINTN IndexOfPageDirectoryEntries;
|
||||
UINT32 NumberOfPdpEntriesNeeded;
|
||||
PAGE_MAP_AND_DIRECTORY_POINTER *PageMap;
|
||||
PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;
|
||||
PAGE_TABLE_ENTRY *PageDirectoryEntry;
|
||||
UINTN TotalPagesNum;
|
||||
UINTN PageAddress;
|
||||
|
||||
PhysicalAddressBits = 32;
|
||||
|
||||
//
|
||||
// Calculate the table entries needed.
|
||||
//
|
||||
NumberOfPdpEntriesNeeded = (UINT32) LShiftU64 (1, (PhysicalAddressBits - 30));
|
||||
|
||||
TotalPagesNum = NumberOfPdpEntriesNeeded + 1;
|
||||
PageAddress = (UINTN) AllocatePages (TotalPagesNum);
|
||||
ASSERT (PageAddress != 0);
|
||||
|
||||
PageMap = (VOID *) PageAddress;
|
||||
PageAddress += SIZE_4KB;
|
||||
|
||||
PageDirectoryPointerEntry = PageMap;
|
||||
PhysicalAddress = 0;
|
||||
|
||||
for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
|
||||
//
|
||||
// Each Directory Pointer entries points to a page of Page Directory entires.
|
||||
// So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
|
||||
//
|
||||
PageDirectoryEntry = (VOID *) PageAddress;
|
||||
PageAddress += SIZE_4KB;
|
||||
|
||||
//
|
||||
// Fill in a Page Directory Pointer Entries
|
||||
//
|
||||
PageDirectoryPointerEntry->Uint64 = (UINT64) (UINTN) PageDirectoryEntry;
|
||||
PageDirectoryPointerEntry->Bits.Present = 1;
|
||||
|
||||
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress += SIZE_2MB) {
|
||||
if ((PhysicalAddress < StackBase + StackSize) && ((PhysicalAddress + SIZE_2MB) > StackBase)) {
|
||||
//
|
||||
// Need to split this 2M page that covers stack range.
|
||||
//
|
||||
Split2MPageTo4K (PhysicalAddress, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);
|
||||
} else {
|
||||
//
|
||||
// Fill in the Page Directory entries
|
||||
//
|
||||
PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress;
|
||||
PageDirectoryEntry->Bits.ReadWrite = 1;
|
||||
PageDirectoryEntry->Bits.Present = 1;
|
||||
PageDirectoryEntry->Bits.MustBe1 = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
|
||||
ZeroMem (
|
||||
PageDirectoryPointerEntry,
|
||||
sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)
|
||||
);
|
||||
}
|
||||
|
||||
return (UINTN) PageMap;
|
||||
}
|
||||
|
||||
/**
|
||||
The function will check if IA32 PAE is supported.
|
||||
|
||||
@retval TRUE IA32 PAE is supported.
|
||||
@retval FALSE IA32 PAE is not supported.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IsIa32PaeSupport (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT32 RegEax;
|
||||
UINT32 RegEdx;
|
||||
BOOLEAN Ia32PaeSupport;
|
||||
|
||||
Ia32PaeSupport = FALSE;
|
||||
AsmCpuid (0x0, &RegEax, NULL, NULL, NULL);
|
||||
if (RegEax >= 0x1) {
|
||||
AsmCpuid (0x1, NULL, NULL, NULL, &RegEdx);
|
||||
if ((RegEdx & BIT6) != 0) {
|
||||
Ia32PaeSupport = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return Ia32PaeSupport;
|
||||
}
|
||||
|
||||
/**
|
||||
The function will check if Execute Disable Bit is available.
|
||||
|
||||
@retval TRUE Execute Disable Bit is available.
|
||||
@retval FALSE Execute Disable Bit is not available.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IsExecuteDisableBitAvailable (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT32 RegEax;
|
||||
UINT32 RegEdx;
|
||||
BOOLEAN Available;
|
||||
|
||||
Available = FALSE;
|
||||
AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
|
||||
if (RegEax >= 0x80000001) {
|
||||
AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
|
||||
if ((RegEdx & BIT20) != 0) {
|
||||
//
|
||||
// Bit 20: Execute Disable Bit available.
|
||||
//
|
||||
Available = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return Available;
|
||||
}
|
||||
|
||||
/**
|
||||
Transfers control to DxeCore.
|
||||
|
||||
|
@ -85,6 +230,7 @@ HandOffToDxeCore (
|
|||
X64_IDT_TABLE *IdtTableForX64;
|
||||
EFI_VECTOR_HANDOFF_INFO *VectorInfo;
|
||||
EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;
|
||||
BOOLEAN BuildPageTablesIa32Pae;
|
||||
|
||||
Status = PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
@ -114,7 +260,7 @@ HandOffToDxeCore (
|
|||
//
|
||||
// Create page table and save PageMapLevel4 to CR3
|
||||
//
|
||||
PageTables = CreateIdentityMappingPageTables ();
|
||||
PageTables = CreateIdentityMappingPageTables (BaseOfStack, STACK_SIZE);
|
||||
|
||||
//
|
||||
// End of PEI phase signal
|
||||
|
@ -215,12 +361,26 @@ HandOffToDxeCore (
|
|||
TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT;
|
||||
TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
|
||||
|
||||
BuildPageTablesIa32Pae = (BOOLEAN) (PcdGetBool (PcdSetNxForStack) && IsIa32PaeSupport () && IsExecuteDisableBitAvailable ());
|
||||
if (BuildPageTablesIa32Pae) {
|
||||
PageTables = Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZE);
|
||||
EnableExecuteDisableBit ();
|
||||
}
|
||||
|
||||
//
|
||||
// End of PEI phase signal
|
||||
//
|
||||
Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
if (BuildPageTablesIa32Pae) {
|
||||
AsmWriteCr3 (PageTables);
|
||||
//
|
||||
// Set Physical Address Extension (bit 5 of CR4).
|
||||
//
|
||||
AsmWriteCr4 (AsmReadCr4 () | BIT5);
|
||||
}
|
||||
|
||||
//
|
||||
// Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
|
||||
//
|
||||
|
@ -229,12 +389,21 @@ HandOffToDxeCore (
|
|||
//
|
||||
// Transfer the control to the entry point of DxeCore.
|
||||
//
|
||||
SwitchStack (
|
||||
(SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
|
||||
HobList.Raw,
|
||||
NULL,
|
||||
(VOID *) (UINTN) TopOfStack
|
||||
);
|
||||
if (BuildPageTablesIa32Pae) {
|
||||
AsmEnablePaging32 (
|
||||
(SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
|
||||
HobList.Raw,
|
||||
NULL,
|
||||
(VOID *) (UINTN) TopOfStack
|
||||
);
|
||||
} else {
|
||||
SwitchStack (
|
||||
(SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
|
||||
HobList.Raw,
|
||||
NULL,
|
||||
(VOID *) (UINTN) TopOfStack
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
x64-specifc functionality for DxeLoad.
|
||||
|
||||
Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -84,7 +84,13 @@ HandOffToDxeCore (
|
|||
//
|
||||
// Create page table and save PageMapLevel4 to CR3
|
||||
//
|
||||
PageTables = CreateIdentityMappingPageTables ();
|
||||
PageTables = CreateIdentityMappingPageTables ((EFI_PHYSICAL_ADDRESS) (UINTN) BaseOfStack, STACK_SIZE);
|
||||
} else {
|
||||
//
|
||||
// Set NX for stack feature also require PcdDxeIplBuildPageTables be TRUE
|
||||
// for the DxeIpl and the DxeCore are both X64.
|
||||
//
|
||||
ASSERT (PcdGetBool (PcdSetNxForStack) == FALSE);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
2) IA-32 Intel(R) Architecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel
|
||||
3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel
|
||||
|
||||
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -29,21 +29,126 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
#include "DxeIpl.h"
|
||||
#include "VirtualMemory.h"
|
||||
|
||||
/**
|
||||
Enable Execute Disable Bit.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EnableExecuteDisableBit (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT64 MsrRegisters;
|
||||
|
||||
MsrRegisters = AsmReadMsr64 (0xC0000080);
|
||||
MsrRegisters |= BIT11;
|
||||
AsmWriteMsr64 (0xC0000080, MsrRegisters);
|
||||
}
|
||||
|
||||
/**
|
||||
Split 2M page to 4K.
|
||||
|
||||
@param[in] PhysicalAddress Start physical address the 2M page covered.
|
||||
@param[in, out] PageEntry2M Pointer to 2M page entry.
|
||||
@param[in] StackBase Stack base address.
|
||||
@param[in] StackSize Stack size.
|
||||
|
||||
**/
|
||||
VOID
|
||||
Split2MPageTo4K (
|
||||
IN EFI_PHYSICAL_ADDRESS PhysicalAddress,
|
||||
IN OUT UINT64 *PageEntry2M,
|
||||
IN EFI_PHYSICAL_ADDRESS StackBase,
|
||||
IN UINTN StackSize
|
||||
)
|
||||
{
|
||||
EFI_PHYSICAL_ADDRESS PhysicalAddress4K;
|
||||
UINTN IndexOfPageTableEntries;
|
||||
PAGE_TABLE_4K_ENTRY *PageTableEntry;
|
||||
|
||||
PageTableEntry = AllocatePages (1);
|
||||
//
|
||||
// Fill in 2M page entry.
|
||||
//
|
||||
*PageEntry2M = (UINT64) (UINTN) PageTableEntry | IA32_PG_P | IA32_PG_RW;
|
||||
|
||||
PhysicalAddress4K = PhysicalAddress;
|
||||
for (IndexOfPageTableEntries = 0; IndexOfPageTableEntries < 512; IndexOfPageTableEntries++, PageTableEntry++, PhysicalAddress4K += SIZE_4KB) {
|
||||
//
|
||||
// Fill in the Page Table entries
|
||||
//
|
||||
PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K;
|
||||
PageTableEntry->Bits.ReadWrite = 1;
|
||||
PageTableEntry->Bits.Present = 1;
|
||||
if ((PhysicalAddress4K >= StackBase) && (PhysicalAddress4K < StackBase + StackSize)) {
|
||||
//
|
||||
// Set Nx bit for stack.
|
||||
//
|
||||
PageTableEntry->Bits.Nx = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Split 1G page to 2M.
|
||||
|
||||
@param[in] PhysicalAddress Start physical address the 1G page covered.
|
||||
@param[in, out] PageEntry1G Pointer to 1G page entry.
|
||||
@param[in] StackBase Stack base address.
|
||||
@param[in] StackSize Stack size.
|
||||
|
||||
**/
|
||||
VOID
|
||||
Split1GPageTo2M (
|
||||
IN EFI_PHYSICAL_ADDRESS PhysicalAddress,
|
||||
IN OUT UINT64 *PageEntry1G,
|
||||
IN EFI_PHYSICAL_ADDRESS StackBase,
|
||||
IN UINTN StackSize
|
||||
)
|
||||
{
|
||||
EFI_PHYSICAL_ADDRESS PhysicalAddress2M;
|
||||
UINTN IndexOfPageDirectoryEntries;
|
||||
PAGE_TABLE_ENTRY *PageDirectoryEntry;
|
||||
|
||||
PageDirectoryEntry = AllocatePages (1);
|
||||
//
|
||||
// Fill in 1G page entry.
|
||||
//
|
||||
*PageEntry1G = (UINT64) (UINTN) PageDirectoryEntry | IA32_PG_P | IA32_PG_RW;
|
||||
|
||||
PhysicalAddress2M = PhysicalAddress;
|
||||
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += SIZE_2MB) {
|
||||
if ((PhysicalAddress2M < StackBase + StackSize) && ((PhysicalAddress2M + SIZE_2MB) > StackBase)) {
|
||||
//
|
||||
// Need to split this 2M page that covers stack range.
|
||||
//
|
||||
Split2MPageTo4K (PhysicalAddress2M, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);
|
||||
} else {
|
||||
//
|
||||
// Fill in the Page Directory entries
|
||||
//
|
||||
PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress2M;
|
||||
PageDirectoryEntry->Bits.ReadWrite = 1;
|
||||
PageDirectoryEntry->Bits.Present = 1;
|
||||
PageDirectoryEntry->Bits.MustBe1 = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates and fills in the Page Directory and Page Table Entries to
|
||||
establish a 1:1 Virtual to Physical mapping.
|
||||
|
||||
@param NumberOfProcessorPhysicalAddressBits Number of processor address bits
|
||||
to use. Limits the number of page
|
||||
table entries to the physical
|
||||
address space.
|
||||
@param[in] StackBase Stack base address.
|
||||
@param[in] StackSize Stack size.
|
||||
|
||||
@return The address of 4 level page map.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
CreateIdentityMappingPageTables (
|
||||
VOID
|
||||
IN EFI_PHYSICAL_ADDRESS StackBase,
|
||||
IN UINTN StackSize
|
||||
)
|
||||
{
|
||||
UINT32 RegEax;
|
||||
|
@ -149,13 +254,17 @@ CreateIdentityMappingPageTables (
|
|||
PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry;
|
||||
|
||||
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {
|
||||
//
|
||||
// Fill in the Page Directory entries
|
||||
//
|
||||
PageDirectory1GEntry->Uint64 = (UINT64)PageAddress;
|
||||
PageDirectory1GEntry->Bits.ReadWrite = 1;
|
||||
PageDirectory1GEntry->Bits.Present = 1;
|
||||
PageDirectory1GEntry->Bits.MustBe1 = 1;
|
||||
if (PcdGetBool (PcdSetNxForStack) && (PageAddress < StackBase + StackSize) && ((PageAddress + SIZE_1GB) > StackBase)) {
|
||||
Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry, StackBase, StackSize);
|
||||
} else {
|
||||
//
|
||||
// Fill in the Page Directory entries
|
||||
//
|
||||
PageDirectory1GEntry->Uint64 = (UINT64)PageAddress;
|
||||
PageDirectory1GEntry->Bits.ReadWrite = 1;
|
||||
PageDirectory1GEntry->Bits.Present = 1;
|
||||
PageDirectory1GEntry->Bits.MustBe1 = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
|
||||
|
@ -174,13 +283,20 @@ CreateIdentityMappingPageTables (
|
|||
PageDirectoryPointerEntry->Bits.Present = 1;
|
||||
|
||||
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {
|
||||
//
|
||||
// Fill in the Page Directory entries
|
||||
//
|
||||
PageDirectoryEntry->Uint64 = (UINT64)PageAddress;
|
||||
PageDirectoryEntry->Bits.ReadWrite = 1;
|
||||
PageDirectoryEntry->Bits.Present = 1;
|
||||
PageDirectoryEntry->Bits.MustBe1 = 1;
|
||||
if (PcdGetBool (PcdSetNxForStack) && (PageAddress < StackBase + StackSize) && ((PageAddress + SIZE_2MB) > StackBase)) {
|
||||
//
|
||||
// Need to split this 2M page that covers stack range.
|
||||
//
|
||||
Split2MPageTo4K (PageAddress, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);
|
||||
} else {
|
||||
//
|
||||
// Fill in the Page Directory entries
|
||||
//
|
||||
PageDirectoryEntry->Uint64 = (UINT64)PageAddress;
|
||||
PageDirectoryEntry->Bits.ReadWrite = 1;
|
||||
PageDirectoryEntry->Bits.Present = 1;
|
||||
PageDirectoryEntry->Bits.MustBe1 = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,6 +319,10 @@ CreateIdentityMappingPageTables (
|
|||
);
|
||||
}
|
||||
|
||||
if (PcdGetBool (PcdSetNxForStack)) {
|
||||
EnableExecuteDisableBit ();
|
||||
}
|
||||
|
||||
return (UINTN)PageMap;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel
|
||||
4) AMD64 Architecture Programmer's Manual Volume 2: System Programming
|
||||
|
||||
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -73,6 +73,28 @@ typedef union {
|
|||
UINT64 Uint64;
|
||||
} PAGE_MAP_AND_DIRECTORY_POINTER;
|
||||
|
||||
//
|
||||
// Page Table Entry 4KB
|
||||
//
|
||||
typedef union {
|
||||
struct {
|
||||
UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
|
||||
UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
|
||||
UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
|
||||
UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
|
||||
UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
|
||||
UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)
|
||||
UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page
|
||||
UINT64 PAT:1; //
|
||||
UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
|
||||
UINT64 Available:3; // Available for use by system software
|
||||
UINT64 PageTableBaseAddress:40; // Page Table Base Address
|
||||
UINT64 AvabilableHigh:11; // Available for use by system software
|
||||
UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution
|
||||
} Bits;
|
||||
UINT64 Uint64;
|
||||
} PAGE_TABLE_4K_ENTRY;
|
||||
|
||||
//
|
||||
// Page Table Entry 2MB
|
||||
//
|
||||
|
@ -123,22 +145,49 @@ typedef union {
|
|||
|
||||
#pragma pack()
|
||||
|
||||
#define IA32_PG_P BIT0
|
||||
#define IA32_PG_RW BIT1
|
||||
|
||||
/**
|
||||
Enable Execute Disable Bit.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EnableExecuteDisableBit (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Split 2M page to 4K.
|
||||
|
||||
@param[in] PhysicalAddress Start physical address the 2M page covered.
|
||||
@param[in, out] PageEntry2M Pointer to 2M page entry.
|
||||
@param[in] StackBase Stack base address.
|
||||
@param[in] StackSize Stack size.
|
||||
|
||||
**/
|
||||
VOID
|
||||
Split2MPageTo4K (
|
||||
IN EFI_PHYSICAL_ADDRESS PhysicalAddress,
|
||||
IN OUT UINT64 *PageEntry2M,
|
||||
IN EFI_PHYSICAL_ADDRESS StackBase,
|
||||
IN UINTN StackSize
|
||||
);
|
||||
|
||||
/**
|
||||
Allocates and fills in the Page Directory and Page Table Entries to
|
||||
establish a 1:1 Virtual to Physical mapping.
|
||||
|
||||
@param NumberOfProcessorPhysicalAddressBits Number of processor address bits
|
||||
to use. Limits the number of page
|
||||
table entries to the physical
|
||||
address space.
|
||||
@param[in] StackBase Stack base address.
|
||||
@param[in] StackSize Stack size.
|
||||
|
||||
@return The address of 4 level page map.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
CreateIdentityMappingPageTables (
|
||||
VOID
|
||||
IN EFI_PHYSICAL_ADDRESS StackBase,
|
||||
IN UINTN StackSize
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -960,7 +960,16 @@
|
|||
## The number of bytes between registers in serial device. The default is 1 byte.
|
||||
# @Prompt Serial Port Register Stride in Bytes
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|1|UINT32|0x0001006d
|
||||
|
||||
|
||||
## Indicates if to set NX for stack.<BR><BR>
|
||||
# For the DxeIpl and the DxeCore are both X64, set NX for stack feature also require PcdDxeIplBuildPageTables be TRUE.<BR>
|
||||
# For the DxeIpl and the DxeCore are both IA32 (PcdDxeIplSwitchToLongMode is FALSE), set NX for stack feature also require
|
||||
# IA32 PAE is supported and Execute Disable Bit is available.<BR>
|
||||
# TRUE - to set NX for stack.<BR>
|
||||
# FALSE - Not to set NX for stack.<BR>
|
||||
# @Prompt Set NX for stack.
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE|BOOLEAN|0x0001006f
|
||||
|
||||
[PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
|
||||
## This PCD defines the Console output row. The default value is 25 according to UEFI spec.
|
||||
# This PCD could be set to 0 then console output would be at max column and max row.
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue