From 115b59d9c60fffb22eeab2ed467b888e4b24c1dc Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Sun, 8 Oct 2023 17:39:08 +0200 Subject: ArmVirtPkg: store separate console and debug PL011 addresses in GUID HOB PlatformPeiLib produces the EarlyPL011BaseAddress GUID HOB, and FdtPL011SerialPortLib consumes it. Extend the HOB such that it also carry the base address of the PL011 UART meant for DebugLib usage -- namely the first UART that is *not* designated by the /chosen node's "stdout-path" property. Implement this policy in PlatformPeiLib. Note that as far as the SerialPortLib+console UART is concerned, this patch makes no difference. That selection remains consistent with the pre-patch state, and therefore consistent with EarlyFdtPL011SerialPortLib. Cc: Ard Biesheuvel Cc: Gerd Hoffmann Cc: Leif Lindholm Cc: Sami Mujawar Signed-off-by: Laszlo Ersek Message-Id: <20231008153912.175941-6-lersek@redhat.com> Acked-by: Ard Biesheuvel Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4577 [lersek@redhat.com: add TianoCore BZ reference] --- ArmVirtPkg/Include/Guid/EarlyPL011BaseAddress.h | 15 +++++- .../FdtPL011SerialPortLib/FdtPL011SerialPortLib.c | 4 +- ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c | 60 +++++++++++++++++----- .../Library/PlatformPeiLib/PlatformPeiLib.inf | 1 + 4 files changed, 62 insertions(+), 18 deletions(-) (limited to 'ArmVirtPkg') diff --git a/ArmVirtPkg/Include/Guid/EarlyPL011BaseAddress.h b/ArmVirtPkg/Include/Guid/EarlyPL011BaseAddress.h index 492cbbcb15..43b106f3ff 100644 --- a/ArmVirtPkg/Include/Guid/EarlyPL011BaseAddress.h +++ b/ArmVirtPkg/Include/Guid/EarlyPL011BaseAddress.h @@ -1,6 +1,6 @@ /** @file - GUID for the HOB that caches the base address of the PL011 serial port, for - when PCD access is not available. + GUID for the HOB that caches the base address(es) of the PL011 serial port(s), + for when PCD access is not available. Copyright (C) 2014, Red Hat, Inc. @@ -18,4 +18,15 @@ extern EFI_GUID gEarlyPL011BaseAddressGuid; +typedef struct { + // + // for SerialPortLib and console IO + // + UINT64 ConsoleAddress; + // + // for DebugLib; may equal ConsoleAddress if there's only one PL011 UART + // + UINT64 DebugAddress; +} EARLY_PL011_BASE_ADDRESS; + #endif diff --git a/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c index 5718b02977..20e29e3f57 100644 --- a/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c +++ b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c @@ -46,7 +46,7 @@ SerialPortInitialize ( { VOID *Hob; RETURN_STATUS Status; - CONST UINT64 *UartBase; + CONST EARLY_PL011_BASE_ADDRESS *UartBase; UINTN SerialBaseAddress; UINT64 BaudRate; UINT32 ReceiveFifoDepth; @@ -70,7 +70,7 @@ SerialPortInitialize ( UartBase = GET_GUID_HOB_DATA (Hob); - SerialBaseAddress = (UINTN)*UartBase; + SerialBaseAddress = (UINTN)UartBase->ConsoleAddress; if (SerialBaseAddress == 0) { Status = RETURN_NOT_FOUND; goto Failed; diff --git a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c index d5dcc7cbfd..7ab4aa2d6b 100644 --- a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c +++ b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -43,7 +44,7 @@ PlatformPeim ( UINTN FdtSize; UINTN FdtPages; UINT64 *FdtHobData; - UINT64 *UartHobData; + EARLY_PL011_BASE_ADDRESS *UartHobData; FDT_SERIAL_PORTS Ports; INT32 Node, Prev; INT32 Parent, Depth; @@ -72,24 +73,55 @@ PlatformPeim ( UartHobData = BuildGuidHob (&gEarlyPL011BaseAddressGuid, sizeof *UartHobData); ASSERT (UartHobData != NULL); - *UartHobData = 0; + SetMem (UartHobData, sizeof *UartHobData, 0); Status = FdtSerialGetPorts (Base, "arm,pl011", &Ports); if (!EFI_ERROR (Status)) { - UINT64 UartBase; - - // - // Default to the first port found, but (if there are multiple ports) allow - // the "/chosen" node to override it. Note that if FdtSerialGetConsolePort() - // fails, it does not modify UartBase. - // - UartBase = Ports.BaseAddress[0]; - if (Ports.NumberOfPorts > 1) { - FdtSerialGetConsolePort (Base, &UartBase); + if (Ports.NumberOfPorts == 1) { + // + // Just one UART; direct both SerialPortLib+console and DebugLib to it. + // + UartHobData->ConsoleAddress = Ports.BaseAddress[0]; + UartHobData->DebugAddress = Ports.BaseAddress[0]; + } else { + UINT64 ConsoleAddress; + + Status = FdtSerialGetConsolePort (Base, &ConsoleAddress); + if (EFI_ERROR (Status)) { + // + // At least two UARTs; but failed to get the console preference. Use the + // first UART for SerialPortLib+console, and the second one for + // DebugLib. + // + UartHobData->ConsoleAddress = Ports.BaseAddress[0]; + UartHobData->DebugAddress = Ports.BaseAddress[1]; + } else { + // + // At least two UARTs; and console preference available. Use the + // preferred UART for SerialPortLib+console, and *another* UART for + // DebugLib. + // + UartHobData->ConsoleAddress = ConsoleAddress; + if (ConsoleAddress == Ports.BaseAddress[0]) { + UartHobData->DebugAddress = Ports.BaseAddress[1]; + } else { + UartHobData->DebugAddress = Ports.BaseAddress[0]; + } + } } - DEBUG ((DEBUG_INFO, "%a: PL011 UART @ 0x%lx\n", __func__, UartBase)); - *UartHobData = UartBase; + DEBUG (( + DEBUG_INFO, + "%a: PL011 UART (console) @ 0x%lx\n", + __func__, + UartHobData->ConsoleAddress + )); + DEBUG (( + DEBUG_INFO, + "%a: PL011 UART (debug) @ 0x%lx\n", + __func__, + UartHobData->DebugAddress + )); } TpmBase = 0; diff --git a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf index 08a8f23bb4..b867d8bb89 100644 --- a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf +++ b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf @@ -31,6 +31,7 @@ gArmVirtTokenSpaceGuid.PcdTpm2SupportEnabled [LibraryClasses] + BaseMemoryLib DebugLib HobLib FdtLib -- cgit v1.2.3