summaryrefslogtreecommitdiffstats
path: root/ArmVirtPkg/Library/DebugLibFdtPL011Uart/Flash.c
diff options
context:
space:
mode:
Diffstat (limited to 'ArmVirtPkg/Library/DebugLibFdtPL011Uart/Flash.c')
-rw-r--r--ArmVirtPkg/Library/DebugLibFdtPL011Uart/Flash.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/Flash.c b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/Flash.c
new file mode 100644
index 0000000000..a624e0860d
--- /dev/null
+++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/Flash.c
@@ -0,0 +1,107 @@
+/** @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);
+}