[edk2-devel] [PATCH 1/1] ArmVirtPkg/FdtPL011SerialPortLib: initialize implicitly
Laszlo Ersek
lersek at redhat.com
Mon Oct 2 14:47:00 UTC 2023
On 9/30/23 23:23, Laszlo Ersek wrote:
> FdtPL011SerialPortLib claims that it's usable from the DXE_CORE. That's
> not correct: the DXE_CORE calls DEBUG() and ASSERT() before it calls
> ProcessLibraryConstructorList(). Via the BaseDebugLibSerialPort instance,
> those DEBUG() and ASSERT() calls result in SerialPortWrite() calls, before
> ProcessLibraryConstructorList() called either our constructor
> FdtPL011SerialPortLibInitialize(), or BaseDebugLibSerialPortConstructor().
>
> (And even if the DXE_CORE called the latter function early enough, it
> would just invoke our SerialPortInitialize() function -- which does
> nothing.)
>
> This means that the earliest DXE_CORE debug messages are lost.
>
> Rename FdtPL011SerialPortLibInitialize() to SerialPortInitialize(), so
> that the same initialization occur through the constructor and the public
> SerialPortInitialize() library API.
>
> Turn SerialPortInitialize() calls after the first one into no-ops.
>
> Our SerialPortLib APIs already use (mSerialBaseAddress != 0) to track
> initialization. Rework those checks to actually initialize the library if
> that hasn't happened yet.
>
> The following new lines appear in the log:
>
>> CoreInitializeMemoryServices:
>> BaseAddress - 0x48000000 Length - 0xF8000000 MinimalMemorySizeNeeded - 0x38C8000
>> InstallProtocolInterface: [EfiLoadedImageProtocol] 46EFC3E0
>> ProtectUefiImageCommon - 0x46EFC3E0
>> - 0x0000000046EB2000 - 0x0000000000068000
>
> (0x46EB2000 is the load address of the DXE Core.)
>
> Cc: Ard Biesheuvel <ardb+tianocore at kernel.org>
> Cc: Gerd Hoffmann <kraxel at redhat.com>
> Cc: Leif Lindholm <quic_llindhol at quicinc.com>
> Cc: Oliver Smith-Denny <osde at linux.microsoft.com>
> Cc: Oliver Steffen <osteffen at redhat.com>
> Cc: Sami Mujawar <sami.mujawar at arm.com>
> Cc: Sean Brogan <sean.brogan at microsoft.com>
> Reported-by: Oliver Smith-Denny <osde at linux.microsoft.com>
> Signed-off-by: Laszlo Ersek <lersek at redhat.com>
> ---
>
> Notes:
> In my opinion this is the wrong approach to fix the bug, but the right
> approach would require so much work all over edk2 (and outside of it)
> that it's just not practical.
NB I'd still like this patch to be merged; "wrong approach" is too
strongly worded. I'd now refine that as "theoretically not 100% pure".
Merging this one is a compromise, but an easy one -- I had worked
several hours on the "pure approach", and it absolutely spiralled out of
control. So this is the only one practical thing to do.
Thanks
Laszlo
>
> ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf | 2 +-
> ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c | 84 ++++++++++++--------
> 2 files changed, 52 insertions(+), 34 deletions(-)
>
> diff --git a/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf
> index 2b9a34aa30d1..c417514e3ed5 100644
> --- a/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf
> +++ b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf
> @@ -15,7 +15,7 @@ [Defines]
> MODULE_TYPE = BASE
> VERSION_STRING = 1.0
> LIBRARY_CLASS = SerialPortLib|DXE_CORE DXE_DRIVER UEFI_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION
> - CONSTRUCTOR = FdtPL011SerialPortLibInitialize
> + CONSTRUCTOR = SerialPortInitialize
>
> [Sources.common]
> FdtPL011SerialPortLib.c
> diff --git a/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c
> index 614ea5a860b9..9d71f369570f 100644
> --- a/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c
> +++ b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c
> @@ -23,49 +23,57 @@
> #include <Library/HobLib.h>
> #include <Guid/EarlyPL011BaseAddress.h>
>
> -STATIC UINTN mSerialBaseAddress;
> -
> -RETURN_STATUS
> -EFIAPI
> -SerialPortInitialize (
> - VOID
> - )
> -{
> - return RETURN_SUCCESS;
> -}
> +STATIC UINTN mSerialBaseAddress;
> +STATIC RETURN_STATUS mPermanentStatus = RETURN_SUCCESS;
>
> /**
> -
> Program hardware of Serial port
>
> - @return RETURN_NOT_FOUND if no PL011 base address could be found
> - Otherwise, result of PL011UartInitializePort () is returned
> + @retval RETURN_SUCCESS If the serial port was initialized successfully by
> + this call, or an earlier call, to
> + SerialPortInitialize().
>
> + @retval RETURN_NOT_FOUND If no PL011 base address could be found.
> +
> + @return Error codes forwarded from
> + PL011UartInitializePort().
> **/
> RETURN_STATUS
> EFIAPI
> -FdtPL011SerialPortLibInitialize (
> +SerialPortInitialize (
> VOID
> )
> {
> VOID *Hob;
> + RETURN_STATUS Status;
> CONST UINT64 *UartBase;
> + UINTN SerialBaseAddress;
> UINT64 BaudRate;
> UINT32 ReceiveFifoDepth;
> EFI_PARITY_TYPE Parity;
> UINT8 DataBits;
> EFI_STOP_BITS_TYPE StopBits;
>
> + if (mSerialBaseAddress != 0) {
> + return RETURN_SUCCESS;
> + }
> +
> + if (RETURN_ERROR (mPermanentStatus)) {
> + return mPermanentStatus;
> + }
> +
> Hob = GetFirstGuidHob (&gEarlyPL011BaseAddressGuid);
> if ((Hob == NULL) || (GET_GUID_HOB_DATA_SIZE (Hob) != sizeof *UartBase)) {
> - return RETURN_NOT_FOUND;
> + Status = RETURN_NOT_FOUND;
> + goto Failed;
> }
>
> UartBase = GET_GUID_HOB_DATA (Hob);
>
> - mSerialBaseAddress = (UINTN)*UartBase;
> - if (mSerialBaseAddress == 0) {
> - return RETURN_NOT_FOUND;
> + SerialBaseAddress = (UINTN)*UartBase;
> + if (SerialBaseAddress == 0) {
> + Status = RETURN_NOT_FOUND;
> + goto Failed;
> }
>
> BaudRate = (UINTN)PcdGet64 (PcdUartDefaultBaudRate);
> @@ -74,15 +82,25 @@ FdtPL011SerialPortLibInitialize (
> DataBits = PcdGet8 (PcdUartDefaultDataBits);
> StopBits = (EFI_STOP_BITS_TYPE)PcdGet8 (PcdUartDefaultStopBits);
>
> - return PL011UartInitializePort (
> - mSerialBaseAddress,
> - FixedPcdGet32 (PL011UartClkInHz),
> - &BaudRate,
> - &ReceiveFifoDepth,
> - &Parity,
> - &DataBits,
> - &StopBits
> - );
> + Status = PL011UartInitializePort (
> + SerialBaseAddress,
> + FixedPcdGet32 (PL011UartClkInHz),
> + &BaudRate,
> + &ReceiveFifoDepth,
> + &Parity,
> + &DataBits,
> + &StopBits
> + );
> + if (RETURN_ERROR (Status)) {
> + goto Failed;
> + }
> +
> + mSerialBaseAddress = SerialBaseAddress;
> + return RETURN_SUCCESS;
> +
> +Failed:
> + mPermanentStatus = Status;
> + return Status;
> }
>
> /**
> @@ -102,7 +120,7 @@ SerialPortWrite (
> IN UINTN NumberOfBytes
> )
> {
> - if (mSerialBaseAddress != 0) {
> + if (!RETURN_ERROR (SerialPortInitialize ())) {
> return PL011UartWrite (mSerialBaseAddress, Buffer, NumberOfBytes);
> }
>
> @@ -126,7 +144,7 @@ SerialPortRead (
> IN UINTN NumberOfBytes
> )
> {
> - if (mSerialBaseAddress != 0) {
> + if (!RETURN_ERROR (SerialPortInitialize ())) {
> return PL011UartRead (mSerialBaseAddress, Buffer, NumberOfBytes);
> }
>
> @@ -146,7 +164,7 @@ SerialPortPoll (
> VOID
> )
> {
> - if (mSerialBaseAddress != 0) {
> + if (!RETURN_ERROR (SerialPortInitialize ())) {
> return PL011UartPoll (mSerialBaseAddress);
> }
>
> @@ -199,7 +217,7 @@ SerialPortSetAttributes (
> {
> RETURN_STATUS Status;
>
> - if (mSerialBaseAddress == 0) {
> + if (RETURN_ERROR (SerialPortInitialize ())) {
> Status = RETURN_UNSUPPORTED;
> } else {
> Status = PL011UartInitializePort (
> @@ -234,7 +252,7 @@ SerialPortSetControl (
> {
> RETURN_STATUS Status;
>
> - if (mSerialBaseAddress == 0) {
> + if (RETURN_ERROR (SerialPortInitialize ())) {
> Status = RETURN_UNSUPPORTED;
> } else {
> Status = PL011UartSetControl (mSerialBaseAddress, Control);
> @@ -261,7 +279,7 @@ SerialPortGetControl (
> {
> RETURN_STATUS Status;
>
> - if (mSerialBaseAddress == 0) {
> + if (RETURN_ERROR (SerialPortInitialize ())) {
> Status = RETURN_UNSUPPORTED;
> } else {
> Status = PL011UartGetControl (mSerialBaseAddress, Control);
>
>
>
>
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#109255): https://edk2.groups.io/g/devel/message/109255
Mute This Topic: https://groups.io/mt/101682671/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/leave/3943202/1813853/130120423/xyzzy [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-
More information about the edk2-devel-archive
mailing list