From 469ae18183ab447e9f672fd6222ecc0e306b73d7 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 23 Sep 2024 11:22:43 +0300 Subject: [PATCH] Ring3: Added DebugLibFdtPL011UartUser without HOB dependancy. --- ArmVirtPkg/ArmVirt.dsc.inc | 2 + ArmVirtPkg/ArmVirtQemu.dsc | 10 +- .../DebugLibFdtPL011UartUser.inf | 48 ++++++++++ .../Library/DebugLibFdtPL011Uart/User.c | 94 +++++++++++++++++++ MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 54 +---------- .../Core/Dxe/SysCall/Initialization.c | 70 +++++++++----- .../Core/Dxe/SysCall/SupportedProtocols.c | 4 +- 8 files changed, 201 insertions(+), 82 deletions(-) create mode 100644 ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartUser.inf create mode 100644 ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 2fc2ac840f..6a9bf65a18 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -373,6 +373,8 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD5 gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|TRUE [Components.common] # diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index dbaf476b91..8fda77e058 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -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 { + + !if $(TARGET) != RELEASE + DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartUser.inf + !endif + } MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf { 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 diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartUser.inf b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartUser.inf new file mode 100644 index 0000000000..28149b30fe --- /dev/null +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartUser.inf @@ -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 diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c new file mode 100644 index 0000000000..2229cffde0 --- /dev/null +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c @@ -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 +#include +#include +#include + +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); +} diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 92627bf1ca..6b15d89df8 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -223,6 +223,7 @@ gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES # [Hob] # RESOURCE_DESCRIPTOR ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index 7d11e063fe..0ab3d85e38 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -6,14 +6,13 @@ **/ #include -#include #include #include #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 ()) { // diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 3a0af40149..383e0579fc 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -5,6 +5,8 @@ **/ +#include + #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. // diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index d0e8944913..a04c7aa92c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -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,