Skip to content

Commit

Permalink
ArmVirtPkg: adhere to the serial port selected by /chosen "stdout-path"
Browse files Browse the repository at this point in the history
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]
  • Loading branch information
lersek authored and mergify[bot] committed Oct 26, 2023
1 parent 5fc3c39 commit 66046ae
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len);
if (Compatible == NULL) {
continue;
}

//
// 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;
}
}
}
UartBase = Ports.BaseAddress[0];
if (Ports.NumberOfPorts > 1) {
FdtSerialGetConsolePort (DeviceTreeBase, &UartBase);
}

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 (!RETURN_ERROR (Status)) {
return UartBase;
}

return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@
[LibraryClasses]
PL011UartLib
PcdLib
FdtLib
FdtSerialPortAddressLib

[Packages]
MdePkg/MdePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
ArmVirtPkg/ArmVirtPkg.dec

Expand Down
42 changes: 22 additions & 20 deletions ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <Library/PeiServicesLib.h>
#include <Library/FdtSerialPortAddressLib.h>
#include <libfdt.h>

#include <Guid/EarlyPL011BaseAddress.h>
Expand Down Expand Up @@ -43,17 +44,15 @@ PlatformPeim (
UINTN FdtPages;
UINT64 *FdtHobData;
UINT64 *UartHobData;
FDT_SERIAL_PORTS Ports;
INT32 Node, Prev;
INT32 Parent, Depth;
CONST CHAR8 *Compatible;
CONST CHAR8 *CompItem;
CONST CHAR8 *NodeStatus;
INT32 Len;
INT32 RangesLen;
INT32 StatusLen;
CONST UINT64 *RegProp;
CONST UINT32 *RangesProp;
UINT64 UartBase;
UINT64 TpmBase;
EFI_STATUS Status;

Expand All @@ -75,6 +74,24 @@ PlatformPeim (
ASSERT (UartHobData != NULL);
*UartHobData = 0;

Status = FdtSerialGetPorts (Base, "arm,pl011", &Ports);
if (!EFI_ERROR (Status)) {
UINT64 UartBase;

//
// 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.
//
UartBase = Ports.BaseAddress[0];
if (Ports.NumberOfPorts > 1) {
FdtSerialGetConsolePort (Base, &UartBase);
}

DEBUG ((DEBUG_INFO, "%a: PL011 UART @ 0x%lx\n", __func__, UartBase));
*UartHobData = UartBase;
}

TpmBase = 0;

//
Expand All @@ -100,23 +117,8 @@ PlatformPeim (
for (CompItem = Compatible; CompItem != NULL && CompItem < Compatible + Len;
CompItem += 1 + AsciiStrLen (CompItem))
{
if (AsciiStrCmp (CompItem, "arm,pl011") == 0) {
NodeStatus = fdt_getprop (Base, Node, "status", &StatusLen);
if ((NodeStatus != NULL) && (AsciiStrCmp (NodeStatus, "okay") != 0)) {
continue;
}

RegProp = fdt_getprop (Base, Node, "reg", &Len);
ASSERT (Len == 16);

UartBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));

DEBUG ((DEBUG_INFO, "%a: PL011 UART @ 0x%lx\n", __func__, UartBase));

*UartHobData = UartBase;
break;
} else if (FeaturePcdGet (PcdTpm2SupportEnabled) &&
(AsciiStrCmp (CompItem, "tcg,tpm-tis-mmio") == 0))
if (FeaturePcdGet (PcdTpm2SupportEnabled) &&
(AsciiStrCmp (CompItem, "tcg,tpm-tis-mmio") == 0))
{
RegProp = fdt_getprop (Base, Node, "reg", &Len);
ASSERT (Len == 8 || Len == 16);
Expand Down
1 change: 1 addition & 0 deletions ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
DebugLib
HobLib
FdtLib
FdtSerialPortAddressLib
PcdLib
PeiServicesLib

Expand Down

0 comments on commit 66046ae

Please sign in to comment.