Core/Dxe: Placed platform dependent code into separate files.

This commit is contained in:
Mikhail Krichanov 2025-01-27 18:51:13 +03:00
parent e358acb6d9
commit 2cd1b35113
7 changed files with 294 additions and 139 deletions

View File

@ -149,10 +149,10 @@
gEfiHobMemoryAllocStackGuid ## SOMETIMES_CONSUMES ## SystemTable
gUefiImageLoaderImageContextGuid ## CONSUMES ## HOB
gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## SysCall
gEarlyPL011BaseAddressGuid ## CONSUMES
[Guids.ARM, Guids.AARCH64]
gArmVirtSystemMemorySizeGuid ## CONSUMES
gArmVirtSystemMemorySizeGuid ## SOMETIMES_CONSUMES ## SysCall
gEarlyPL011BaseAddressGuid ## SOMETIMES_CONSUMES ## SysCall
[Ppis]
gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB
@ -226,7 +226,6 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace ## CONSUMES
gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask ## CONSUMES
gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES
[Pcd.IA32, Pcd.X64]
gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES

View File

@ -1700,6 +1700,9 @@ CoreStartImage (
if (PcdGetBool (PcdEnableUserSpace) && (Image->IsUserImage)) {
if (gRing3Data == NULL) {
Image->Status = InitializeRing3 (ImageHandle, Image);
if (EFI_ERROR (Image->Status)) {
CpuDeadLoop ();
}
} else {
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes);
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);

View File

@ -6,6 +6,7 @@
**/
#include <Chipset/AArch64.h>
#include <Guid/EarlyPL011BaseAddress.h>
#include <Library/ArmLib.h>
#include <Library/ArmMmuLib.h>
#include <Library/DefaultExceptionHandlerLib.h>
@ -14,6 +15,10 @@
UINTN gUserPageTable;
STATIC UINTN mConfigurationTable;
STATIC UINTN mConfigurationTableSize;
STATIC UINTN mUartBaseAddress;
EFI_STATUS
EFIAPI
ArmCallRing3 (
@ -89,15 +94,55 @@ MakeUserPageTableTemplate (
);
}
VOID
EFI_STATUS
EFIAPI
InitializeMsr (
IN OUT EFI_CONFIGURATION_TABLE *Table,
IN UINTN NumberOfEntries
InitializePlatform (
IN OUT EFI_SYSTEM_TABLE *System
)
{
UINTN Tcr;
UINTN Sctlr;
EFI_STATUS Status;
UINTN Tcr;
UINTN Sctlr;
EFI_PHYSICAL_ADDRESS Physical;
UINTN Index;
EFI_CONFIGURATION_TABLE *Conf;
EARLY_PL011_BASE_ADDRESS *UartBase;
CONST VOID *Hob;
mConfigurationTableSize = (System->NumberOfTableEntries + 1) * sizeof (EFI_CONFIGURATION_TABLE);
Status = CoreAllocatePages (
AllocateAnyPages,
EfiRing3MemoryType,
EFI_SIZE_TO_PAGES (mConfigurationTableSize),
&Physical
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n"));
return Status;
}
Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical;
for (Index = 0; Index < System->NumberOfTableEntries; ++Index) {
CopyGuid (&Conf->VendorGuid, &System->ConfigurationTable[Index].VendorGuid);
Conf->VendorTable = System->ConfigurationTable[Index].VendorTable;
++Conf;
}
Hob = GetFirstGuidHob (&gEarlyPL011BaseAddressGuid);
UartBase = GET_GUID_HOB_DATA (Hob);
mUartBaseAddress = (UINTN)UartBase->DebugAddress;
CopyGuid (&(Conf->VendorGuid), &gEarlyPL011BaseAddressGuid);
Conf->VendorTable = (VOID *)mUartBaseAddress;
++System->NumberOfTableEntries;
System->ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical;
mConfigurationTable = (UINTN)Physical;
//
// Disable Hierarchical permissions just in case.
//
@ -118,6 +163,33 @@ InitializeMsr (
InitializeSysCallHandler ((VOID *)SysCallBootService);
SetExceptionAddresses (NULL, 0);
return EFI_SUCCESS;
}
VOID
EFIAPI
MapPlatform (
IN OUT UINTN UserPageTable
)
{
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
mConfigurationTable,
ALIGN_VALUE (mConfigurationTableSize, EFI_PAGE_SIZE),
EFI_MEMORY_XP | EFI_MEMORY_USER
);
//
// Necessary fix for DEBUG printings.
//
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
mUartBaseAddress,
SIZE_4KB,
EFI_MEMORY_XP | EFI_MEMORY_USER
);
}
VOID

View File

@ -5,6 +5,7 @@
**/
#include <Guid/EarlyPL011BaseAddress.h>
#include <Library/ArmLib.h>
#include <Library/ArmMmuLib.h>
#include <Library/DefaultExceptionHandlerLib.h>
@ -13,6 +14,10 @@
UINTN gUserPageTable;
STATIC UINTN mConfigurationTable;
STATIC UINTN mConfigurationTableSize;
STATIC UINTN mUartBaseAddress;
EFI_STATUS
EFIAPI
ArmCallRing3 (
@ -116,13 +121,53 @@ MakeUserPageTableTemplate (
);
}
VOID
EFI_STATUS
EFIAPI
InitializeMsr (
IN OUT EFI_CONFIGURATION_TABLE *Table,
IN UINTN NumberOfEntries
InitializePlatform (
IN OUT EFI_SYSTEM_TABLE *System
)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Physical;
UINTN Index;
EFI_CONFIGURATION_TABLE *Conf;
EARLY_PL011_BASE_ADDRESS *UartBase;
CONST VOID *Hob;
mConfigurationTableSize = (System->NumberOfTableEntries + 1) * sizeof (EFI_CONFIGURATION_TABLE);
Status = CoreAllocatePages (
AllocateAnyPages,
EfiRing3MemoryType,
EFI_SIZE_TO_PAGES (mConfigurationTableSize),
&Physical
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n"));
return Status;
}
Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical;
for (Index = 0; Index < System->NumberOfTableEntries; ++Index) {
CopyGuid (&Conf->VendorGuid, &System->ConfigurationTable[Index].VendorGuid);
Conf->VendorTable = System->ConfigurationTable[Index].VendorTable;
++Conf;
}
Hob = GetFirstGuidHob (&gEarlyPL011BaseAddressGuid);
UartBase = GET_GUID_HOB_DATA (Hob);
mUartBaseAddress = (UINTN)UartBase->DebugAddress;
CopyGuid (&(Conf->VendorGuid), &gEarlyPL011BaseAddressGuid);
Conf->VendorTable = (VOID *)mUartBaseAddress;
++System->NumberOfTableEntries;
System->ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical;
mConfigurationTable = (UINTN)Physical;
if (ArmHasPan ()) {
//
// Enable Privileged Access Never feature.
@ -132,6 +177,33 @@ InitializeMsr (
InitializeSysCallHandler (SysCallBootService);
SetExceptionAddresses (NULL, 0);
return EFI_SUCCESS;
}
VOID
EFIAPI
MapPlatform (
IN OUT UINTN UserPageTable
)
{
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
mConfigurationTable,
ALIGN_VALUE (mConfigurationTableSize, EFI_PAGE_SIZE),
EFI_MEMORY_XP | EFI_MEMORY_USER
);
//
// Necessary fix for DEBUG printings.
//
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
mUartBaseAddress,
SIZE_4KB,
EFI_MEMORY_XP | EFI_MEMORY_USER
);
}
VOID

View File

@ -10,6 +10,8 @@
#include <Register/Intel/ArchitecturalMsr.h>
#include <IndustryStandard/PageTable.h>
extern EXCEPTION_ADDRESSES *mExceptionAddresses;
VOID
EFIAPI
MakeUserPageTableTemplate (
@ -87,11 +89,10 @@ MakeUserPageTableTemplate (
*UserPageTableTemplateSize = EFI_PAGES_TO_SIZE (TotalPagesNum);
}
VOID
EFI_STATUS
EFIAPI
InitializeMsr (
IN OUT EFI_CONFIGURATION_TABLE *Table,
IN UINTN NumberOfEntries
InitializePlatform (
IN OUT EFI_SYSTEM_TABLE *System
)
{
UINT64 Msr;
@ -140,7 +141,7 @@ InitializeMsr (
AsmCpuidEx (0x01, 0x0, NULL, NULL, NULL, &Edx);
if ((Edx & BIT11) == 0) {
DEBUG ((DEBUG_ERROR, "Core: SYSENTER and SYSEXIT are not supported.\n"));
CpuDeadLoop ();
return EFI_UNSUPPORTED;
}
//
@ -154,4 +155,52 @@ InitializeMsr (
AsmWriteMsr64 (MSR_IA32_SYSENTER_EIP, Msr);
gCorePageTable = AsmReadCr3 ();
return EFI_SUCCESS;
}
VOID
EFIAPI
MapPlatform (
IN OUT UINTN UserPageTable
)
{
IA32_DESCRIPTOR IdtDescriptor;
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
(UINTN)&gCorePageTable,
SIZE_4KB,
EFI_MEMORY_RO | EFI_MEMORY_XP
);
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
mExceptionAddresses->ExceptionStackBase,
mExceptionAddresses->ExceptionStackSize,
EFI_MEMORY_XP
);
AsmReadIdtr (&IdtDescriptor);
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
IdtDescriptor.Base,
SIZE_4KB,
EFI_MEMORY_RO | EFI_MEMORY_XP
);
//
// Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor()
//
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
FixedPcdGet32 (PcdOvmfWorkAreaBase),
FixedPcdGet32 (PcdOvmfWorkAreaSize),
EFI_MEMORY_XP | EFI_MEMORY_USER
);
}

View File

@ -5,25 +5,20 @@
**/
#include <Guid/EarlyPL011BaseAddress.h>
#include "DxeMain.h"
VOID *gRing3EntryPoint;
RING3_DATA *gRing3Data;
VOID *gRing3Interfaces;
UINTN gUartBaseAddress;
UEFI_IMAGE_RECORD *mDxeRing3;
EXCEPTION_ADDRESSES *mExceptionAddresses;
UINTN mConfigurationTable;
UINTN mConfigurationTableSize;
EFI_PHYSICAL_ADDRESS mCoreStackBase;
UINT64 mCoreStackSize;
EXCEPTION_ADDRESSES *mExceptionAddresses;
extern UINTN SysCallBase;
extern UINTN SysCallEnd;
STATIC UEFI_IMAGE_RECORD *mDxeRing3;
STATIC EFI_PHYSICAL_ADDRESS mCoreStackBase;
STATIC UINT64 mCoreStackSize;
VOID
EFIAPI
MakeUserPageTableTemplate (
@ -31,11 +26,16 @@ MakeUserPageTableTemplate (
OUT UINTN *UserPageTableTemplateSize
);
EFI_STATUS
EFIAPI
InitializePlatform (
IN OUT EFI_SYSTEM_TABLE *System
);
VOID
EFIAPI
InitializeMsr (
IN OUT EFI_CONFIGURATION_TABLE *Table,
IN UINTN NumberOfEntries
MapPlatform (
IN OUT UINTN UserPageTable
);
EFI_STATUS
@ -47,10 +47,6 @@ InitializeRing3 (
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Physical;
UINTN Index;
EFI_CONFIGURATION_TABLE *Conf;
EARLY_PL011_BASE_ADDRESS *UartBase;
CONST VOID *Hob;
EFI_PEI_HOB_POINTERS PeiHob;
EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
@ -78,43 +74,6 @@ InitializeRing3 (
EFI_MEMORY_XP | EFI_MEMORY_USER
);
if (PcdGetBool (PcdSerialUseMmio)) {
mConfigurationTableSize = (gRing3Data->SystemTable.NumberOfTableEntries + 1) * sizeof (EFI_CONFIGURATION_TABLE);
Status = CoreAllocatePages (
AllocateAnyPages,
EfiRing3MemoryType,
EFI_SIZE_TO_PAGES (mConfigurationTableSize),
&Physical
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n"));
return Status;
}
Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical;
for (Index = 0; Index < gRing3Data->SystemTable.NumberOfTableEntries; ++Index) {
CopyGuid (&(Conf->VendorGuid), &gRing3Data->SystemTable.ConfigurationTable[Index].VendorGuid);
Conf->VendorTable = gRing3Data->SystemTable.ConfigurationTable[Index].VendorTable;
++Conf;
}
Hob = GetFirstGuidHob (&gEarlyPL011BaseAddressGuid);
UartBase = GET_GUID_HOB_DATA (Hob);
gUartBaseAddress = (UINTN)UartBase->DebugAddress;
CopyGuid (&(Conf->VendorGuid), &gEarlyPL011BaseAddressGuid);
Conf->VendorTable = (VOID *)gUartBaseAddress;
++gRing3Data->SystemTable.NumberOfTableEntries;
DEBUG ((DEBUG_ERROR, "Core: gUartBaseAddress = 0x%p\n", gUartBaseAddress));
gRing3Data->SystemTable.ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical;
mConfigurationTable = (UINTN)Physical;
}
//
// Initialize DxeRing3 with Supervisor privileges.
//
@ -155,10 +114,18 @@ InitializeRing3 (
EFI_MEMORY_XP | EFI_MEMORY_USER
);
InitializeMsr (
gRing3Data->SystemTable.ConfigurationTable,
gRing3Data->SystemTable.NumberOfTableEntries
);
Status = InitializePlatform (&gRing3Data->SystemTable);
if (EFI_ERROR (Status)) {
CoreFreePages (
(EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data,
EFI_SIZE_TO_PAGES (sizeof (RING3_DATA))
);
CoreFreePages (
(EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Interfaces,
RING3_INTERFACES_PAGES
);
return Status;
}
mExceptionAddresses = GetExceptionAddresses ();
@ -249,7 +216,7 @@ InitializeUserPageTable (
);
//
// Map ExceptionHandlers, ExceptionStacks, Idt
// Map ExceptionHandlers
//
gCpu->SetUserMemoryAttributes (
gCpu,
@ -267,63 +234,7 @@ InitializeUserPageTable (
EFI_MEMORY_XP
);
#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32)
IA32_DESCRIPTOR IdtDescriptor;
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
(UINTN)&gCorePageTable,
SIZE_4KB,
EFI_MEMORY_RO | EFI_MEMORY_XP
);
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
mExceptionAddresses->ExceptionStackBase,
mExceptionAddresses->ExceptionStackSize,
EFI_MEMORY_XP
);
AsmReadIdtr (&IdtDescriptor);
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
IdtDescriptor.Base,
SIZE_4KB,
EFI_MEMORY_RO | EFI_MEMORY_XP
);
//
// Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor()
//
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
FixedPcdGet32 (PcdOvmfWorkAreaBase),
FixedPcdGet32 (PcdOvmfWorkAreaSize),
EFI_MEMORY_XP | EFI_MEMORY_USER
);
#elif defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM)
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
mConfigurationTable,
ALIGN_VALUE (mConfigurationTableSize, EFI_PAGE_SIZE),
EFI_MEMORY_XP | EFI_MEMORY_USER
);
//
// Necessary fix for DEBUG printings.
//
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
gUartBaseAddress,
SIZE_4KB,
EFI_MEMORY_XP | EFI_MEMORY_USER
);
#endif
MapPlatform (UserPageTable);
//
// Map User Image

View File

@ -11,6 +11,8 @@
#include <Register/Intel/Cpuid.h>
#include <IndustryStandard/PageTable.h>
extern EXCEPTION_ADDRESSES *mExceptionAddresses;
VOID
EFIAPI
MakeUserPageTableTemplate (
@ -284,11 +286,10 @@ MakeUserPageTableTemplate (
*UserPageTableTemplateSize = EFI_PAGES_TO_SIZE (TotalPagesNum);
}
VOID
EFI_STATUS
EFIAPI
InitializeMsr (
IN OUT EFI_CONFIGURATION_TABLE *Table,
IN UINTN NumberOfEntries
InitializePlatform (
IN OUT EFI_SYSTEM_TABLE *System
)
{
UINT64 Msr;
@ -342,7 +343,7 @@ InitializeMsr (
AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64);
} else {
DEBUG ((DEBUG_ERROR, "Core: SYSCALL and SYSRET are not supported.\n"));
CpuDeadLoop ();
return EFI_UNSUPPORTED;
}
//
@ -360,4 +361,52 @@ InitializeMsr (
AsmWriteMsr64 (MSR_IA32_FMASK, Msr);
gCorePageTable = AsmReadCr3 ();
return EFI_SUCCESS;
}
VOID
EFIAPI
MapPlatform (
IN OUT UINTN UserPageTable
)
{
IA32_DESCRIPTOR IdtDescriptor;
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
(UINTN)&gCorePageTable,
SIZE_4KB,
EFI_MEMORY_RO | EFI_MEMORY_XP
);
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
mExceptionAddresses->ExceptionStackBase,
mExceptionAddresses->ExceptionStackSize,
EFI_MEMORY_XP
);
AsmReadIdtr (&IdtDescriptor);
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
IdtDescriptor.Base,
SIZE_4KB,
EFI_MEMORY_RO | EFI_MEMORY_XP
);
//
// Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor()
//
gCpu->SetUserMemoryAttributes (
gCpu,
UserPageTable,
FixedPcdGet32 (PcdOvmfWorkAreaBase),
FixedPcdGet32 (PcdOvmfWorkAreaSize),
EFI_MEMORY_XP | EFI_MEMORY_USER
);
}