Ring3: Added DebugLibFdtPL011UartUser without HOB dependancy.

This commit is contained in:
Mikhail Krichanov 2024-09-23 11:22:43 +03:00
parent 1cea3f7fb8
commit 469ae18183
8 changed files with 201 additions and 82 deletions

View File

@ -373,6 +373,8 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD5
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|TRUE
[Components.common]
#

View File

@ -464,10 +464,18 @@
MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
FatPkg/EnhancedFatDxe/Fat.inf
FatPkg/EnhancedFatDxe/Fat.inf {
<LibraryClasses>
!if $(TARGET) != RELEASE
DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartUser.inf
!endif
}
MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf {
<LibraryClasses>
MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf
!if $(TARGET) != RELEASE
DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartUser.inf
!endif
}
MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf

View File

@ -0,0 +1,48 @@
## @file
# DebugLib instance that produces debug output directly via PL011UartLib.
#
# Copyright (C) Red Hat
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
[Defines]
INF_VERSION = 1.27
BASE_NAME = DebugLibFdtPL011UartUser
FILE_GUID = 5932FA0B-FC1A-43B9-B149-5C16137622B1
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = DebugLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION
CONSTRUCTOR = DebugLibFdtPL011UartUserConstructor
[Sources]
DebugLib.c
User.c
[Packages]
ArmPlatformPkg/ArmPlatformPkg.dec
ArmVirtPkg/ArmVirtPkg.dec
MdePkg/MdePkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugPrintErrorLevelLib
PL011UartLib
PcdLib
PrintLib
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel
[FixedPcd]
gArmPlatformTokenSpaceGuid.PL011UartClkInHz
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
[Guids]
gEarlyPL011BaseAddressGuid

View File

@ -0,0 +1,94 @@
/** @file
Copyright (c) 2024, Mikhail Krichanov. All rights reserved.
Copyright (C) Red Hat
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Guid/EarlyPL011BaseAddress.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PcdLib.h>
#include <Library/PL011UartLib.h>
UINTN mDebugLibFdtPL011UartAddress;
EFI_STATUS
EFIAPI
DebugLibFdtPL011UartUserConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
UINTN Index;
mDebugLibFdtPL011UartAddress = 0;
for (Index = 0; Index < SystemTable->NumberOfTableEntries; ++Index) {
if (CompareGuid (&gEarlyPL011BaseAddressGuid, &(SystemTable->ConfigurationTable[Index].VendorGuid))) {
mDebugLibFdtPL011UartAddress = (UINTN)SystemTable->ConfigurationTable[Index].VendorTable;
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
/**
(Copied from SerialPortWrite() in "MdePkg/Include/Library/SerialPortLib.h" at
commit c4547aefb3d0, with the Buffer non-nullity assertion removed:)
Write data from buffer to serial device.
Writes NumberOfBytes data bytes from Buffer to the serial device.
The number of bytes actually written to the serial device is returned.
If the return value is less than NumberOfBytes, then the write operation failed.
If NumberOfBytes is zero, then return 0.
@param Buffer Pointer to the data buffer to be written.
@param NumberOfBytes Number of bytes to written to the serial device.
@retval 0 NumberOfBytes is 0.
@retval >0 The number of bytes written to the serial device.
If this value is less than NumberOfBytes, then the write operation failed.
**/
UINTN
DebugLibFdtPL011UartWrite (
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
EFI_STATUS Status;
UINT64 BaudRate;
UINT32 ReceiveFifoDepth;
EFI_PARITY_TYPE Parity;
UINT8 DataBits;
EFI_STOP_BITS_TYPE StopBits;
if (mDebugLibFdtPL011UartAddress == 0) {
return 0;
}
BaudRate = (UINTN)FixedPcdGet64 (PcdUartDefaultBaudRate);
ReceiveFifoDepth = 0; // Use the default value for Fifo depth
Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);
DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);
StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits);
Status = PL011UartInitializePort (
mDebugLibFdtPL011UartAddress,
FixedPcdGet32 (PL011UartClkInHz),
&BaudRate,
&ReceiveFifoDepth,
&Parity,
&DataBits,
&StopBits
);
if (EFI_ERROR (Status)) {
return 0;
}
return PL011UartWrite (mDebugLibFdtPL011UartAddress, Buffer, NumberOfBytes);
}

View File

@ -223,6 +223,7 @@
gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase ## CONSUMES
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES
# [Hob]
# RESOURCE_DESCRIPTOR ## CONSUMES

View File

@ -6,14 +6,13 @@
**/
#include <Chipset/AArch64.h>
#include <Guid/EarlyPL011BaseAddress.h>
#include <Library/ArmLib.h>
#include <Library/DefaultExceptionHandlerLib.h>
#include "DxeMain.h"
STATIC UINTN mCoreSp;
UINTN gUartBaseAddress;
extern UINTN gUartBaseAddress;
EFI_STATUS
EFIAPI
@ -95,13 +94,7 @@ InitializeMsr (
IN UINTN NumberOfEntries
)
{
UINTN Tcr;
UINTN Index;
EARLY_PL011_BASE_ADDRESS *UartBase;
EFI_PHYSICAL_ADDRESS Physical;
EFI_HOB_GENERIC_HEADER *Ring3Hob;
UINT16 HobLength;
EFI_STATUS Status;
UINTN Tcr;
//
// If HCR_EL2.NV is 1 and the current Exception level is EL1,
// then EL1 read accesses to the CurrentEL register return a value of 0x2 in bits[3:2].
@ -115,49 +108,6 @@ InitializeMsr (
Tcr = ArmGetTCR ();
Tcr |= TCR_EL1_HPD0_MASK | TCR_EL1_HPD1_MASK;
ArmSetTCR (Tcr);
//
// Problem 1: Uart is memory maped.
//
for (Index = 0; Index < NumberOfEntries; ++Index) {
if (CompareGuid (&gEfiHobListGuid, &(Table[Index].VendorGuid))) {
UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable);
gUartBaseAddress = UartBase->DebugAddress;
//
// Copy Hob into Ring3.
//
Status = CoreAllocatePages (
AllocateAnyPages,
EfiRing3MemoryType,
1,
&Physical
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Hob.\n"));
ASSERT (FALSE);
}
DEBUG ((DEBUG_ERROR, "UartBaseAddress = %p.\n", gUartBaseAddress));
Ring3Hob = (EFI_HOB_GENERIC_HEADER *)(UINTN)Physical;
HobLength = (UINT16)((sizeof (EFI_HOB_GUID_TYPE) + sizeof (EARLY_PL011_BASE_ADDRESS) + 0x7) & (~0x7));
Ring3Hob->HobType = EFI_HOB_TYPE_GUID_EXTENSION;
Ring3Hob->HobLength = HobLength;
Ring3Hob->Reserved = 0;
CopyGuid (&((EFI_HOB_GUID_TYPE *)Ring3Hob)->Name, &gEarlyPL011BaseAddressGuid);
Ring3Hob = (EFI_HOB_GENERIC_HEADER *)((UINTN)Ring3Hob + HobLength);
Ring3Hob->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
Ring3Hob->HobLength = sizeof (EFI_HOB_GENERIC_HEADER);
Ring3Hob->Reserved = 0;
Table[Index].VendorTable = (VOID *)(UINTN)Physical;
UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable);
UartBase->DebugAddress = gUartBaseAddress;
}
}
if (ArmHasPan ()) {
//

View File

@ -5,6 +5,8 @@
**/
#include <Guid/EarlyPL011BaseAddress.h>
#include "DxeMain.h"
VOID *gCoreSysCallStackTop;
@ -14,6 +16,7 @@ VOID *gRing3CallStackBase;
VOID *gRing3EntryPoint;
RING3_DATA *gRing3Data;
VOID *gRing3Interfaces;
UINTN gUartBaseAddress;
VOID
EFIAPI
@ -29,12 +32,13 @@ InitializeRing3 (
IN LOADED_IMAGE_PRIVATE_DATA *Image
)
{
EFI_STATUS Status;
VOID *TopOfStack;
UINTN SizeOfStack;
EFI_PHYSICAL_ADDRESS Physical;
UINTN Index;
EFI_CONFIGURATION_TABLE *Conf;
EFI_STATUS Status;
VOID *TopOfStack;
UINTN SizeOfStack;
EFI_PHYSICAL_ADDRESS Physical;
UINTN Index;
EFI_CONFIGURATION_TABLE *Conf;
EARLY_PL011_BASE_ADDRESS *UartBase;
//
// Set Ring3 EntryPoint and BootServices.
@ -54,27 +58,41 @@ InitializeRing3 (
CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE));
Status = CoreAllocatePages (
AllocateAnyPages,
EfiRing3MemoryType,
EFI_SIZE_TO_PAGES (gRing3Data->SystemTable.NumberOfTableEntries * sizeof (EFI_CONFIGURATION_TABLE)),
&Physical
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n"));
return Status;
if (FixedPcdGetBool (PcdSerialUseMmio)) {
Status = CoreAllocatePages (
AllocateAnyPages,
EfiRing3MemoryType,
EFI_SIZE_TO_PAGES ((gRing3Data->SystemTable.NumberOfTableEntries + 1) * sizeof (EFI_CONFIGURATION_TABLE)),
&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;
if (CompareGuid (&gEfiHobListGuid, &(Conf->VendorGuid))) {
UartBase = GET_GUID_HOB_DATA (Conf->VendorTable);
gUartBaseAddress = UartBase->DebugAddress;
}
++Conf;
}
CopyGuid (&(Conf->VendorGuid), &gEarlyPL011BaseAddressGuid);
Conf->VendorTable = (VOID *)gUartBaseAddress;
++gRing3Data->SystemTable.NumberOfTableEntries;
DEBUG ((DEBUG_ERROR, "Core: gUartBaseAddress = %p\n", gUartBaseAddress));
gRing3Data->SystemTable.ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical;
}
Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical;
for (Index = 0; Index < gRing3Data->SystemTable.NumberOfTableEntries; ++Index) {
Conf->VendorGuid = gRing3Data->SystemTable.ConfigurationTable[Index].VendorGuid;
Conf->VendorTable = gRing3Data->SystemTable.ConfigurationTable[Index].VendorTable;
++Conf;
}
gRing3Data->SystemTable.ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical;
//
// Initialize DxeRing3 with Supervisor privileges.
//

View File

@ -99,9 +99,7 @@ GoToRing3 (
// and can be used for translation table later.
//
AllowSupervisorAccessToUserMemory ();
//
// Problem 3: QEMU ramdomly breaks GP registers' context.
//
SetUefiImageMemoryAttributes (
gUartBaseAddress,
EFI_PAGE_SIZE,