mirror of https://github.com/acidanthera/audk.git
Ring3: Added support for separate User address space.
This commit is contained in:
parent
983649444e
commit
3b8cd407d3
|
@ -229,6 +229,7 @@ typedef struct {
|
|||
|
||||
VOID *HiiData;
|
||||
BOOLEAN IsUserImage;
|
||||
UINTN UserPageTable;
|
||||
} LOADED_IMAGE_PRIVATE_DATA;
|
||||
|
||||
typedef struct {
|
||||
|
@ -288,6 +289,10 @@ extern VOID *gCoreSysCallStackTop;
|
|||
extern VOID *gRing3CallStackBase;
|
||||
extern VOID *gRing3CallStackTop;
|
||||
extern VOID *gRing3EntryPoint;
|
||||
extern VOID *gUserPageTableTemplate;
|
||||
extern UINTN gUserPageTableTemplateSize;
|
||||
extern UINTN gUserPageTable;
|
||||
extern UINTN gCorePageTable;
|
||||
|
||||
//
|
||||
// Service Initialization Functions
|
||||
|
@ -2777,4 +2782,10 @@ FreeProtocolsList (
|
|||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
MakeUserPageTableTemplate (
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -150,6 +150,7 @@
|
|||
gUefiImageLoaderImageContextGuid ## CONSUMES ## HOB
|
||||
gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## SysCall
|
||||
gEarlyPL011BaseAddressGuid ## CONSUMES
|
||||
gEfiHobPageTableInfoGuid ## CONSUMES ## HOB
|
||||
|
||||
[Ppis]
|
||||
gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB
|
||||
|
|
|
@ -328,6 +328,8 @@ DxeMain (
|
|||
|
||||
ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext, mCurrentImage->IsUserImage);
|
||||
|
||||
MakeUserPageTableTemplate ();
|
||||
|
||||
//
|
||||
// Call constructor for all libraries
|
||||
//
|
||||
|
|
|
@ -1108,6 +1108,7 @@ CoreLoadImageCommon (
|
|||
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
|
||||
UINT8 ImageOrigin;
|
||||
EFI_FV_FILE_ATTRIBUTES FileAttributes;
|
||||
VOID *UserPageTable;
|
||||
|
||||
SecurityStatus = EFI_SUCCESS;
|
||||
|
||||
|
@ -1348,6 +1349,14 @@ CoreLoadImageCommon (
|
|||
Image->Info.ParentHandle = ParentImageHandle;
|
||||
Image->IsUserImage = (FileAttributes & EFI_FV_FILE_ATTRIB_USER) != 0;
|
||||
|
||||
if ((gRing3Data != NULL) && Image->IsUserImage) {
|
||||
UserPageTable = AllocatePages (EFI_SIZE_TO_PAGES (gUserPageTableTemplateSize));
|
||||
CopyMem (UserPageTable, gUserPageTableTemplate, gUserPageTableTemplateSize);
|
||||
|
||||
Image->UserPageTable = (UINTN)UserPageTable;
|
||||
gUserPageTable = Image->UserPageTable;
|
||||
}
|
||||
|
||||
if (NumberOfPages != NULL) {
|
||||
Image->NumberOfPages = *NumberOfPages;
|
||||
} else {
|
||||
|
|
|
@ -82,6 +82,10 @@ SetUefiImageMemoryAttributes (
|
|||
|
||||
ASSERT (gCpu != NULL);
|
||||
gCpu->SetMemoryAttributes (gCpu, BaseAddress, Length, FinalAttributes);
|
||||
|
||||
if ((Attributes & EFI_MEMORY_USER) != 0) {
|
||||
gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, BaseAddress, Length, FinalAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -59,6 +59,12 @@ InitializeRing3 (
|
|||
|
||||
CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE));
|
||||
|
||||
SetUefiImageMemoryAttributes (
|
||||
(UINTN)gRing3Data,
|
||||
ALIGN_VALUE (sizeof (RING3_DATA), EFI_PAGE_SIZE),
|
||||
EFI_MEMORY_XP | EFI_MEMORY_USER
|
||||
);
|
||||
|
||||
if (PcdGetBool (PcdSerialUseMmio)) {
|
||||
Status = CoreAllocatePages (
|
||||
AllocateAnyPages,
|
||||
|
@ -124,6 +130,12 @@ InitializeRing3 (
|
|||
|
||||
gRing3Interfaces = (VOID *)(UINTN)Physical;
|
||||
|
||||
SetUefiImageMemoryAttributes (
|
||||
(UINTN)gRing3Interfaces,
|
||||
EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES),
|
||||
EFI_MEMORY_XP | EFI_MEMORY_USER
|
||||
);
|
||||
|
||||
SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE;
|
||||
|
||||
//
|
||||
|
@ -141,6 +153,9 @@ InitializeRing3 (
|
|||
gCoreSysCallStackTop = TopOfStack;
|
||||
|
||||
SetUefiImageMemoryAttributes ((UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP);
|
||||
//
|
||||
// gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, (UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP);
|
||||
//
|
||||
DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop));
|
||||
|
||||
//
|
||||
|
|
|
@ -123,8 +123,13 @@ copy:
|
|||
;
|
||||
; (On User Stack) Argument 4, 5, ...
|
||||
;------------------------------------------------------------------------------
|
||||
ALIGN 4096
|
||||
|
||||
global ASM_PFX(CoreBootServices)
|
||||
ASM_PFX(CoreBootServices):
|
||||
mov rax, [ASM_PFX(gCorePageTable)]
|
||||
mov cr3, rax
|
||||
|
||||
; Switch from User to Core data segment selectors.
|
||||
mov ax, ss
|
||||
mov ds, ax
|
||||
|
@ -175,6 +180,8 @@ ASM_PFX(CoreBootServices):
|
|||
pop rbp
|
||||
pop rsp
|
||||
|
||||
mov rdx, [ASM_PFX(gUserPageTable)]
|
||||
mov cr3, rdx
|
||||
; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX.
|
||||
o64 sysret
|
||||
; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11.
|
||||
|
@ -190,9 +197,9 @@ o64 sysret
|
|||
;------------------------------------------------------------------------------
|
||||
global ASM_PFX(CallRing3)
|
||||
ASM_PFX(CallRing3):
|
||||
cli
|
||||
pushfq
|
||||
pop r11
|
||||
cli
|
||||
; Save nonvolatile registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15.
|
||||
push rbx
|
||||
push rbp
|
||||
|
@ -221,6 +228,8 @@ ASM_PFX(CallRing3):
|
|||
mov rsp, r8
|
||||
mov rbp, rsp
|
||||
|
||||
mov r8, [ASM_PFX(gUserPageTable)]
|
||||
mov cr3, r8
|
||||
; Pass control to user image
|
||||
o64 sysret
|
||||
|
||||
|
@ -248,5 +257,15 @@ ASM_PFX(ReturnToCore):
|
|||
ret
|
||||
|
||||
SECTION .data
|
||||
ALIGN 4096
|
||||
|
||||
global ASM_PFX(gCorePageTable)
|
||||
ASM_PFX(gCorePageTable):
|
||||
resq 1
|
||||
|
||||
global ASM_PFX(gUserPageTable)
|
||||
ASM_PFX(gUserPageTable):
|
||||
resq 1
|
||||
|
||||
ASM_PFX(CoreRsp):
|
||||
resq 1
|
||||
|
|
|
@ -8,6 +8,202 @@
|
|||
#include "DxeMain.h"
|
||||
|
||||
#include <Register/Intel/ArchitecturalMsr.h>
|
||||
#include <IndustryStandard/PageTable.h>
|
||||
|
||||
VOID *gUserPageTableTemplate;
|
||||
UINTN gUserPageTableTemplateSize;
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
MakeUserPageTableTemplate (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_HOB_GUID_TYPE *GuidHob;
|
||||
EFI_PAGE_TABLE_INFO *PageTableInfo;
|
||||
UINTN BigPageAddress;
|
||||
EFI_PHYSICAL_ADDRESS PageAddress;
|
||||
UINTN IndexOfPml5Entries;
|
||||
UINTN IndexOfPml4Entries;
|
||||
UINTN IndexOfPdpEntries;
|
||||
UINTN IndexOfPageDirectoryEntries;
|
||||
PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel5Entry;
|
||||
PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;
|
||||
PAGE_MAP_AND_DIRECTORY_POINTER *PageMap;
|
||||
PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;
|
||||
PAGE_TABLE_ENTRY *PageDirectoryEntry;
|
||||
PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;
|
||||
|
||||
GuidHob = GetFirstGuidHob (&gEfiHobPageTableInfoGuid);
|
||||
if (GuidHob == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "Core: Could not retrieve PageTableInfo HOB.\n"));
|
||||
CpuDeadLoop ();
|
||||
}
|
||||
|
||||
PageTableInfo = (EFI_PAGE_TABLE_INFO *)(GET_GUID_HOB_DATA (GuidHob));
|
||||
|
||||
BigPageAddress = (UINTN)AllocateAlignedPages (PageTableInfo->TotalPagesNum, PAGE_TABLE_POOL_ALIGNMENT);
|
||||
if (BigPageAddress == 0) {
|
||||
DEBUG ((DEBUG_ERROR, "Core: Could not allocate buffer for User page table.\n"));
|
||||
CpuDeadLoop ();
|
||||
}
|
||||
|
||||
//
|
||||
// By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
|
||||
//
|
||||
PageMap = (VOID *)BigPageAddress;
|
||||
if (PageTableInfo->Page5LevelEnabled) {
|
||||
//
|
||||
// By architecture only one PageMapLevel5 exists - so lets allocate storage for it.
|
||||
//
|
||||
PageMapLevel5Entry = PageMap;
|
||||
BigPageAddress += SIZE_4KB;
|
||||
}
|
||||
|
||||
PageAddress = 0;
|
||||
|
||||
for ( IndexOfPml5Entries = 0
|
||||
; IndexOfPml5Entries < PageTableInfo->NumberOfPml5EntriesNeeded
|
||||
; IndexOfPml5Entries++)
|
||||
{
|
||||
//
|
||||
// Each PML5 entry points to a page of PML4 entires.
|
||||
// So lets allocate space for them and fill them in in the IndexOfPml4Entries loop.
|
||||
// When 5-Level Paging is disabled, below allocation happens only once.
|
||||
//
|
||||
PageMapLevel4Entry = (VOID *)BigPageAddress;
|
||||
BigPageAddress += SIZE_4KB;
|
||||
|
||||
if (PageTableInfo->Page5LevelEnabled) {
|
||||
//
|
||||
// Make a PML5 Entry
|
||||
//
|
||||
PageMapLevel5Entry->Uint64 = (UINT64)(UINTN)PageMapLevel4Entry | PageTableInfo->AddressEncMask;
|
||||
PageMapLevel5Entry->Bits.ReadWrite = 1;
|
||||
PageMapLevel5Entry->Bits.UserSupervisor = 1;
|
||||
PageMapLevel5Entry->Bits.Present = 1;
|
||||
PageMapLevel5Entry++;
|
||||
}
|
||||
|
||||
for ( IndexOfPml4Entries = 0
|
||||
; IndexOfPml4Entries < (PageTableInfo->NumberOfPml5EntriesNeeded == 1 ? PageTableInfo->NumberOfPml4EntriesNeeded : 512)
|
||||
; IndexOfPml4Entries++, PageMapLevel4Entry++)
|
||||
{
|
||||
//
|
||||
// Each PML4 entry points to a page of Page Directory Pointer entires.
|
||||
// So lets allocate space for them and fill them in in the IndexOfPdpEntries loop.
|
||||
//
|
||||
PageDirectoryPointerEntry = (VOID *)BigPageAddress;
|
||||
BigPageAddress += SIZE_4KB;
|
||||
|
||||
//
|
||||
// Make a PML4 Entry
|
||||
//
|
||||
PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | PageTableInfo->AddressEncMask;
|
||||
PageMapLevel4Entry->Bits.ReadWrite = 1;
|
||||
PageMapLevel4Entry->Bits.UserSupervisor = 1;
|
||||
PageMapLevel4Entry->Bits.Present = 1;
|
||||
|
||||
if (PageTableInfo->Page1GSupport) {
|
||||
PageDirectory1GEntry = (VOID *)PageDirectoryPointerEntry;
|
||||
|
||||
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {
|
||||
//
|
||||
// Fill in the Page Directory entries
|
||||
//
|
||||
PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | PageTableInfo->AddressEncMask;
|
||||
PageDirectory1GEntry->Bits.ReadWrite = 1;
|
||||
PageDirectory1GEntry->Bits.Present = 1;
|
||||
PageDirectory1GEntry->Bits.MustBe1 = 1;
|
||||
}
|
||||
} else {
|
||||
for ( IndexOfPdpEntries = 0
|
||||
; IndexOfPdpEntries < (PageTableInfo->NumberOfPml4EntriesNeeded == 1 ? PageTableInfo->NumberOfPdpEntriesNeeded : 512)
|
||||
; 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 *)BigPageAddress;
|
||||
BigPageAddress += SIZE_4KB;
|
||||
|
||||
//
|
||||
// Fill in a Page Directory Pointer Entries
|
||||
//
|
||||
PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | PageTableInfo->AddressEncMask;
|
||||
PageDirectoryPointerEntry->Bits.ReadWrite = 1;
|
||||
PageDirectoryPointerEntry->Bits.UserSupervisor = 1;
|
||||
PageDirectoryPointerEntry->Bits.Present = 1;
|
||||
|
||||
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {
|
||||
//
|
||||
// Fill in the Page Directory entries
|
||||
//
|
||||
PageDirectoryEntry->Uint64 = (UINT64)PageAddress | PageTableInfo->AddressEncMask;
|
||||
PageDirectoryEntry->Bits.ReadWrite = 1;
|
||||
PageDirectoryEntry->Bits.Present = 0;
|
||||
PageDirectoryEntry->Bits.MustBe1 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Fill with null entry for unused PDPTE
|
||||
//
|
||||
ZeroMem (PageDirectoryPointerEntry, (512 - IndexOfPdpEntries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// For the PML4 entries we are not using fill in a null entry.
|
||||
//
|
||||
ZeroMem (PageMapLevel4Entry, (512 - IndexOfPml4Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER));
|
||||
}
|
||||
|
||||
if (PageTableInfo->Page5LevelEnabled) {
|
||||
//
|
||||
// For the PML5 entries we are not using fill in a null entry.
|
||||
//
|
||||
ZeroMem (PageMapLevel5Entry, (512 - IndexOfPml5Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER));
|
||||
}
|
||||
|
||||
gUserPageTableTemplate = (VOID *)PageMap;
|
||||
gUserPageTableTemplateSize = ALIGN_VALUE (EFI_PAGES_TO_SIZE (PageTableInfo->TotalPagesNum), PAGE_TABLE_POOL_ALIGNMENT);
|
||||
gUserPageTable = (UINTN)gUserPageTableTemplate;
|
||||
|
||||
SetUefiImageMemoryAttributes ((UINT64)PageMap, gUserPageTableTemplateSize, EFI_MEMORY_XP);
|
||||
//
|
||||
// Map CoreBootServices
|
||||
//
|
||||
gCpu->SetUserMemoryAttributes (
|
||||
gCpu,
|
||||
(UINTN)PageMap,
|
||||
(EFI_PHYSICAL_ADDRESS)(UINTN)CoreBootServices,
|
||||
SIZE_4KB,
|
||||
EFI_MEMORY_RO
|
||||
);
|
||||
|
||||
gCpu->SetUserMemoryAttributes (
|
||||
gCpu,
|
||||
(UINTN)PageMap,
|
||||
(EFI_PHYSICAL_ADDRESS)(UINTN)&gCorePageTable,
|
||||
SIZE_4KB,
|
||||
EFI_MEMORY_RO | EFI_MEMORY_XP
|
||||
);
|
||||
//
|
||||
// Map ExceptionHandlerAsm: AsmIdtVectorBegin - AsmGetTemplateAddressMap
|
||||
// mCorePageTable, gCoreSysCallStackTop
|
||||
//
|
||||
// gCpu->SetUserMemoryAttributes (gCpu, (UINTN)PageMap, BaseAddress, SIZE_4KB, EFI_MEMORY_RO);
|
||||
|
||||
gCpu->SetUserMemoryAttributes (
|
||||
gCpu,
|
||||
(UINTN)PageMap,
|
||||
FixedPcdGet32 (PcdOvmfWorkAreaBase),
|
||||
FixedPcdGet32 (PcdOvmfWorkAreaSize),
|
||||
EFI_MEMORY_XP | EFI_MEMORY_USER
|
||||
);
|
||||
}
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
|
@ -26,6 +222,9 @@ InitializeMsr (
|
|||
Ebx = 0;
|
||||
Edx = 0;
|
||||
|
||||
// The Intel-64 and IA-32 architectures also allow for global pages when the PGE flag (bit 7) is 1 in CR4.
|
||||
// PGE must be zero.
|
||||
|
||||
//
|
||||
// Forbid supervisor-mode accesses to any user-mode pages.
|
||||
//
|
||||
|
@ -76,4 +275,6 @@ InitializeMsr (
|
|||
//
|
||||
Msr = (UINT64)BIT9;
|
||||
AsmWriteMsr64 (MSR_IA32_FMASK, Msr);
|
||||
|
||||
gCorePageTable = AsmReadCr3 ();
|
||||
}
|
||||
|
|
|
@ -90,6 +90,7 @@
|
|||
## SOMETIMES_PRODUCES ## HOB
|
||||
gEfiMemoryTypeInformationGuid
|
||||
gUefiImageLoaderImageContextGuid
|
||||
gEfiHobPageTableInfoGuid
|
||||
|
||||
[FeaturePcd.IA32]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES
|
||||
|
|
|
@ -705,6 +705,7 @@ CreateIdentityMappingPageTables (
|
|||
PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;
|
||||
UINT64 AddressEncMask;
|
||||
IA32_CR4 Cr4;
|
||||
EFI_PAGE_TABLE_INFO PageTableInfo;
|
||||
|
||||
//
|
||||
// Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings
|
||||
|
@ -828,6 +829,16 @@ CreateIdentityMappingPageTables (
|
|||
(UINT64)TotalPagesNum
|
||||
));
|
||||
|
||||
PageTableInfo.NumberOfPml5EntriesNeeded = NumberOfPml5EntriesNeeded;
|
||||
PageTableInfo.NumberOfPml4EntriesNeeded = NumberOfPml4EntriesNeeded;
|
||||
PageTableInfo.NumberOfPdpEntriesNeeded = NumberOfPdpEntriesNeeded;
|
||||
PageTableInfo.TotalPagesNum = TotalPagesNum;
|
||||
PageTableInfo.Page5LevelEnabled = Page5LevelEnabled;
|
||||
PageTableInfo.Page1GSupport = Page1GSupport;
|
||||
PageTableInfo.AddressEncMask = AddressEncMask;
|
||||
|
||||
BuildGuidDataHob (&gEfiHobPageTableInfoGuid, &PageTableInfo, sizeof (EFI_PAGE_TABLE_INFO));
|
||||
|
||||
BigPageAddress = (UINTN)AllocatePageTableMemory (TotalPagesNum);
|
||||
ASSERT (BigPageAddress != 0);
|
||||
|
||||
|
|
|
@ -21,8 +21,12 @@
|
|||
#define EFI_HOB_MEMORY_ALLOC_MODULE_GUID \
|
||||
{0xf8e21975, 0x899, 0x4f58, {0xa4, 0xbe, 0x55, 0x25, 0xa9, 0xc6, 0xd7, 0x7a} }
|
||||
|
||||
#define EFI_HOB_PAGE_TABLE_INFO_GUID \
|
||||
{0xac992fe9, 0xb0cc, 0x45df, {0xae, 0xcf, 0x51, 0x5a, 0xd2, 0xc4, 0xe8, 0xb3} }
|
||||
|
||||
extern EFI_GUID gEfiHobMemoryAllocBspStoreGuid;
|
||||
extern EFI_GUID gEfiHobMemoryAllocStackGuid;
|
||||
extern EFI_GUID gEfiHobMemoryAllocModuleGuid;
|
||||
extern EFI_GUID gEfiHobPageTableInfoGuid;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,16 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||
#ifndef __MEMORY_ALLOCATION_LIB_H__
|
||||
#define __MEMORY_ALLOCATION_LIB_H__
|
||||
|
||||
typedef struct {
|
||||
UINT32 NumberOfPml5EntriesNeeded;
|
||||
UINT32 NumberOfPml4EntriesNeeded;
|
||||
UINT32 NumberOfPdpEntriesNeeded;
|
||||
UINTN TotalPagesNum;
|
||||
BOOLEAN Page5LevelEnabled;
|
||||
BOOLEAN Page1GSupport;
|
||||
UINT64 AddressEncMask;
|
||||
} EFI_PAGE_TABLE_INFO;
|
||||
|
||||
/**
|
||||
Allocates one or more 4KB pages of type EfiBootServicesData.
|
||||
|
||||
|
|
|
@ -258,6 +258,16 @@ EFI_STATUS
|
|||
OUT UINT64 *Attributes
|
||||
);
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_CPU_SET_USER_MEMORY_ATTRIBUTES)(
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN UINTN UserPageTable,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Attributes
|
||||
);
|
||||
|
||||
///
|
||||
/// The EFI_CPU_ARCH_PROTOCOL is used to abstract processor-specific functions from the DXE
|
||||
/// Foundation. This includes flushing caches, enabling and disabling interrupts, hooking interrupt
|
||||
|
@ -288,6 +298,7 @@ struct _EFI_CPU_ARCH_PROTOCOL {
|
|||
///
|
||||
UINT32 DmaBufferAlignment;
|
||||
EFI_CPU_GET_MEMORY_ATTRIBUTES GetMemoryAttributes;
|
||||
EFI_CPU_SET_USER_MEMORY_ATTRIBUTES SetUserMemoryAttributes;
|
||||
};
|
||||
|
||||
extern EFI_GUID gEfiCpuArchProtocolGuid;
|
||||
|
|
|
@ -781,6 +781,9 @@
|
|||
## Include/Guid/MemoryAllocationHob.h
|
||||
gEfiHobMemoryAllocBspStoreGuid = { 0x564B33CD, 0xC92A, 0x4593, { 0x90, 0xBF, 0x24, 0x73, 0xE4, 0x3C, 0x63, 0x22 }}
|
||||
|
||||
## Include/Guid/MemoryAllocationHob.h
|
||||
gEfiHobPageTableInfoGuid = { 0xAC992FE9, 0xB0CC, 0x45DF, { 0xAE, 0xCF, 0x51, 0x5A, 0xD2, 0xC4, 0xE8, 0xB3 }}
|
||||
|
||||
## Include/Guid/EventLegacyBios.h
|
||||
gEfiEventLegacyBootGuid = { 0x2A571201, 0x4966, 0x47F6, { 0x8B, 0x86, 0xF3, 0x1E, 0x41, 0xF3, 0x2F, 0x10 }}
|
||||
|
||||
|
|
|
@ -158,4 +158,6 @@ typedef union {
|
|||
#define PTE_OFFSET(x) ( (x >> 12) & PAGETABLE_ENTRY_MASK)
|
||||
#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull
|
||||
|
||||
#define PAGE_TABLE_POOL_ALIGNMENT BASE_2MB
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,7 +32,8 @@ EFI_CPU_ARCH_PROTOCOL gCpuImpl = {
|
|||
CpuSetMemoryAttributes,
|
||||
1, // NumberOfTimers
|
||||
4, // DmaBufferAlignment
|
||||
CpuGetMemoryAttributes
|
||||
CpuGetMemoryAttributes,
|
||||
CpuSetUserMemoryAttributes
|
||||
};
|
||||
|
||||
EFI_HOB_PLATFORM_INFO *mPlatformInfoHob2 = NULL;
|
||||
|
|
|
@ -229,6 +229,16 @@ CpuGetMemoryAttributes (
|
|||
OUT UINT64 *Attributes
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuSetUserMemoryAttributes (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN UINTN UserPageTable,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Attributes
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize Global Descriptor Table.
|
||||
|
||||
|
|
|
@ -429,6 +429,35 @@ CpuGetMemoryAttributes (
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CpuSetUserMemoryAttributes (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *This,
|
||||
IN UINTN UserPageTable,
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 Attributes
|
||||
)
|
||||
{
|
||||
UINT64 MemoryAttributes;
|
||||
PAGE_TABLE_LIB_PAGING_CONTEXT PagingContext;
|
||||
|
||||
MemoryAttributes = Attributes & EFI_MEMORY_ATTRIBUTE_MASK;
|
||||
|
||||
GetCurrentPagingContext (&PagingContext);
|
||||
|
||||
if (PagingContext.MachineType == IMAGE_FILE_MACHINE_I386) {
|
||||
PagingContext.ContextData.Ia32.PageTableBase = (UINT32)UserPageTable;
|
||||
} else {
|
||||
PagingContext.ContextData.X64.PageTableBase = (UINT64)UserPageTable;
|
||||
}
|
||||
|
||||
//
|
||||
// Set memory attribute by page table
|
||||
//
|
||||
return AssignMemoryPageAttributes (&PagingContext, BaseAddress, Length, MemoryAttributes, AllocatePages);
|
||||
}
|
||||
|
||||
/**
|
||||
Modify memory attributes of page entry.
|
||||
|
||||
|
|
Loading…
Reference in New Issue