/** @file | |
Define DebugLibFdtPL011UartWrite() for modules that may run from flash or RAM. | |
Copyright (C) Red Hat | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include <Library/FdtSerialPortAddressLib.h> | |
#include <Library/PL011UartLib.h> | |
#include <Library/PcdLib.h> | |
#include "Write.h" | |
/** | |
(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 | |
) | |
{ | |
CONST VOID *DeviceTree; | |
RETURN_STATUS Status; | |
FDT_SERIAL_PORTS Ports; | |
UINT64 DebugAddress; | |
UINT64 BaudRate; | |
UINT32 ReceiveFifoDepth; | |
EFI_PARITY_TYPE Parity; | |
UINT8 DataBits; | |
EFI_STOP_BITS_TYPE StopBits; | |
DeviceTree = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress); | |
if (DeviceTree == NULL) { | |
return 0; | |
} | |
Status = FdtSerialGetPorts (DeviceTree, "arm,pl011", &Ports); | |
if (RETURN_ERROR (Status)) { | |
return 0; | |
} | |
if (Ports.NumberOfPorts == 1) { | |
// | |
// Just one UART; direct DebugLib to it. | |
// | |
DebugAddress = Ports.BaseAddress[0]; | |
} else { | |
UINT64 ConsoleAddress; | |
Status = FdtSerialGetConsolePort (DeviceTree, &ConsoleAddress); | |
if (EFI_ERROR (Status)) { | |
// | |
// At least two UARTs; but failed to get the console preference. Use the | |
// second UART for DebugLib. | |
// | |
DebugAddress = Ports.BaseAddress[1]; | |
} else { | |
// | |
// At least two UARTs; and console preference available. Use the first | |
// such UART for DebugLib that *differs* from ConsoleAddress. | |
// | |
if (ConsoleAddress == Ports.BaseAddress[0]) { | |
DebugAddress = Ports.BaseAddress[1]; | |
} else { | |
DebugAddress = Ports.BaseAddress[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 ( | |
(UINTN)DebugAddress, | |
FixedPcdGet32 (PL011UartClkInHz), | |
&BaudRate, | |
&ReceiveFifoDepth, | |
&Parity, | |
&DataBits, | |
&StopBits | |
); | |
if (RETURN_ERROR (Status)) { | |
return 0; | |
} | |
return PL011UartWrite ((UINTN)DebugAddress, Buffer, NumberOfBytes); | |
} |