ArmVirtPkg: adhere to the serial port selected by /chosen "stdout-path"

Convert both EarlyFdtPL011SerialPortLib and PlatformPeiLib at the same
time to clients of FdtSerialPortAddressLib (so that both "early" and
"late" serial output continue going to a common serial port). If the
device tree specifies just one serial port, this conversion makes no
difference, but if there are multiple ports, the output is written to the
port identified by /chosen "stdout-path".

In this patch, DebugLib output is not separated yet from the UEFI console.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20231008153912.175941-5-lersek@redhat.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4577
[lersek@redhat.com: add TianoCore BZ reference]
This commit is contained in:
Laszlo Ersek
2023-10-08 17:39:07 +02:00
committed by mergify[bot]
parent 5fc3c39704
commit 66046aeb6d
4 changed files with 56 additions and 80 deletions

View File

@@ -15,7 +15,7 @@
#include <Library/PcdLib.h>
#include <Library/PL011UartLib.h>
#include <Library/SerialPortLib.h>
#include <libfdt.h>
#include <Library/FdtSerialPortAddressLib.h>
RETURN_STATUS
EFIAPI
@@ -56,74 +56,48 @@ SerialPortGetBaseAddress (
UINT8 DataBits;
EFI_STOP_BITS_TYPE StopBits;
VOID *DeviceTreeBase;
INT32 Node, Prev;
INT32 Len;
CONST CHAR8 *Compatible;
CONST CHAR8 *NodeStatus;
CONST CHAR8 *CompatibleItem;
CONST UINT64 *RegProperty;
UINTN UartBase;
FDT_SERIAL_PORTS Ports;
UINT64 UartBase;
RETURN_STATUS Status;
DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
if ((DeviceTreeBase == NULL) || (fdt_check_header (DeviceTreeBase) != 0)) {
if (DeviceTreeBase == NULL) {
return 0;
}
Status = FdtSerialGetPorts (DeviceTreeBase, "arm,pl011", &Ports);
if (RETURN_ERROR (Status)) {
return 0;
}
//
// Enumerate all FDT nodes looking for a PL011 and capture its base address
// 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.
//
for (Prev = 0; ; Prev = Node) {
Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
if (Node < 0) {
break;
}
UartBase = Ports.BaseAddress[0];
if (Ports.NumberOfPorts > 1) {
FdtSerialGetConsolePort (DeviceTreeBase, &UartBase);
}
Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len);
if (Compatible == NULL) {
continue;
}
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);
//
// Iterate over the NULL-separated items in the compatible string
//
for (CompatibleItem = Compatible; CompatibleItem < Compatible + Len;
CompatibleItem += 1 + AsciiStrLen (CompatibleItem))
{
if (AsciiStrCmp (CompatibleItem, "arm,pl011") == 0) {
NodeStatus = fdt_getprop (DeviceTreeBase, Node, "status", &Len);
if ((NodeStatus != NULL) && (AsciiStrCmp (NodeStatus, "okay") != 0)) {
continue;
}
RegProperty = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
if (Len != 16) {
return 0;
}
UartBase = (UINTN)fdt64_to_cpu (ReadUnaligned64 (RegProperty));
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 (
UartBase,
FixedPcdGet32 (PL011UartClkInHz),
&BaudRate,
&ReceiveFifoDepth,
&Parity,
&DataBits,
&StopBits
);
if (!EFI_ERROR (Status)) {
return UartBase;
}
}
}
Status = PL011UartInitializePort (
UartBase,
FixedPcdGet32 (PL011UartClkInHz),
&BaudRate,
&ReceiveFifoDepth,
&Parity,
&DataBits,
&StopBits
);
if (!RETURN_ERROR (Status)) {
return UartBase;
}
return 0;