diff --git a/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c index 614ea5a860..9d71f36957 100644 --- a/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c +++ b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.c @@ -23,49 +23,57 @@ #include #include -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); diff --git a/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf index 2b9a34aa30..c417514e3e 100644 --- a/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf +++ b/ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf @@ -15,7 +15,7 @@ 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