diff --git a/ArmVirtPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.c b/ArmVirtPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.c index c340212432..dc5459b4ce 100644 --- a/ArmVirtPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.c +++ b/ArmVirtPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include 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; - } - - 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; diff --git a/ArmVirtPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.inf b/ArmVirtPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.inf index 32b2d337d4..f47692f06a 100644 --- a/ArmVirtPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.inf +++ b/ArmVirtPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.inf @@ -22,11 +22,10 @@ [LibraryClasses] PL011UartLib PcdLib - FdtLib + FdtSerialPortAddressLib [Packages] MdePkg/MdePkg.dec - EmbeddedPkg/EmbeddedPkg.dec ArmPlatformPkg/ArmPlatformPkg.dec ArmVirtPkg/ArmVirtPkg.dec diff --git a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c index 1b43d77dd1..d5dcc7cbfd 100644 --- a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c +++ b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -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; @@ -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; // @@ -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); diff --git a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf index 3f97ef0805..08a8f23bb4 100644 --- a/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf +++ b/ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf @@ -34,6 +34,7 @@ DebugLib HobLib FdtLib + FdtSerialPortAddressLib PcdLib PeiServicesLib