--- /dev/null
+/** @file\r
+ Early Platform Hook Library instance for 16550 Uart.\r
+\r
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Uefi.h>\r
+\r
+#include <Pi/PiBootMode.h>\r
+#include <Pi/PiHob.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PlatformHookLib.h>\r
+#include <libfdt.h>\r
+\r
+/** Get the UART base address of the console serial-port from the DT.\r
+\r
+ This function fetches the node referenced in the "stdout-path"\r
+ property of the "chosen" node and returns the base address of\r
+ the console UART.\r
+\r
+ @param [in] Fdt Pointer to a Flattened Device Tree (Fdt).\r
+ @param [out] SerialConsoleAddress If success, contains the base address\r
+ of the console serial-port.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_NOT_FOUND Console serial-port info not found in DT.\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+GetSerialConsolePortAddress (\r
+ IN CONST VOID *Fdt,\r
+ OUT UINT64 *SerialConsoleAddress\r
+ )\r
+{\r
+ CONST CHAR8 *Prop;\r
+ INT32 PropSize;\r
+ CONST CHAR8 *Path;\r
+ INT32 PathLen;\r
+ INT32 ChosenNode;\r
+ INT32 SerialConsoleNode;\r
+ INT32 Len;\r
+ CONST CHAR8 *NodeStatus;\r
+ CONST UINT64 *RegProperty;\r
+\r
+ if ((Fdt == NULL) || (fdt_check_header (Fdt) != 0)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ // The "chosen" node resides at the the root of the DT. Fetch it.\r
+ ChosenNode = fdt_path_offset (Fdt, "/chosen");\r
+ if (ChosenNode < 0) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Prop = fdt_getprop (Fdt, ChosenNode, "stdout-path", &PropSize);\r
+ if (PropSize < 0) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ // Determine the actual path length, as a colon terminates the path.\r
+ Path = ScanMem8 (Prop, ':', PropSize);\r
+ if (Path == NULL) {\r
+ PathLen = AsciiStrLen (Prop);\r
+ } else {\r
+ PathLen = Path - Prop;\r
+ }\r
+\r
+ // Aliases cannot start with a '/', so it must be the actual path.\r
+ if (Prop[0] == '/') {\r
+ SerialConsoleNode = fdt_path_offset_namelen (Fdt, Prop, PathLen);\r
+ } else {\r
+ // Lookup the alias, as this contains the actual path.\r
+ Path = fdt_get_alias_namelen (Fdt, Prop, PathLen);\r
+ if (Path == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ SerialConsoleNode = fdt_path_offset (Fdt, Path);\r
+ }\r
+\r
+ NodeStatus = fdt_getprop (Fdt, SerialConsoleNode, "status", &Len);\r
+ if ((NodeStatus != NULL) && (AsciiStrCmp (NodeStatus, "okay") != 0)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ RegProperty = fdt_getprop (Fdt, SerialConsoleNode, "reg", &Len);\r
+ if (Len != 16) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *SerialConsoleAddress = fdt64_to_cpu (ReadUnaligned64 (RegProperty));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Platform hook to retrieve the 16550 UART base address from the platform\r
+ Device tree and store it in PcdSerialRegisterBase.\r
+\r
+ @retval RETURN_SUCCESS Success.\r
+ @retval RETURN_INVALID_PARAMETER A parameter was invalid.\r
+ @retval RETURN_NOT_FOUND Serial port information not found.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+PlatformHookSerialPortInitialize (\r
+ VOID\r
+ )\r
+{\r
+ RETURN_STATUS Status;\r
+ VOID *DeviceTreeBase;\r
+ UINT64 SerialConsoleAddress;\r
+\r
+ if (PcdGet64 (PcdSerialRegisterBase) != 0) {\r
+ return RETURN_SUCCESS;\r
+ }\r
+\r
+ DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);\r
+ if (DeviceTreeBase == NULL) {\r
+ return RETURN_NOT_FOUND;\r
+ }\r
+\r
+ Status = GetSerialConsolePortAddress (DeviceTreeBase, &SerialConsoleAddress);\r
+ if (RETURN_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return (EFI_STATUS)PcdSet64S (PcdSerialRegisterBase, SerialConsoleAddress);\r
+}\r
--- /dev/null
+/** @file\r
+ Platform Hook Library instance for 16550 Uart.\r
+\r
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Uefi.h>\r
+\r
+#include <Pi/PiBootMode.h>\r
+#include <Pi/PiHob.h>\r
+\r
+#include <Guid/Early16550UartBaseAddress.h>\r
+#include <Guid/Fdt.h>\r
+#include <Guid/FdtHob.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PlatformHookLib.h>\r
+\r
+/** Platform hook to retrieve the 16550 UART base address from the GUID Hob\r
+ that caches the UART base address from early boot stage and store it in\r
+ PcdSerialRegisterBase.\r
+\r
+ @retval RETURN_SUCCESS Success.\r
+ @retval RETURN_NOT_FOUND Serial Port information not found.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+PlatformHookSerialPortInitialize (\r
+ VOID\r
+ )\r
+{\r
+ VOID *Hob;\r
+ UINT64 *UartBase;\r
+\r
+ if (PcdGet64 (PcdSerialRegisterBase) != 0) {\r
+ return RETURN_SUCCESS;\r
+ }\r
+\r
+ Hob = GetFirstGuidHob (&gEarly16550UartBaseAddressGuid);\r
+ if ((Hob == NULL) || (GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (*UartBase))) {\r
+ return RETURN_NOT_FOUND;\r
+ }\r
+\r
+ UartBase = GET_GUID_HOB_DATA (Hob);\r
+ if ((UINTN)*UartBase == 0) {\r
+ return RETURN_NOT_FOUND;\r
+ }\r
+\r
+ return (RETURN_STATUS)PcdSet64S (PcdSerialRegisterBase, (UINTN)*UartBase);\r
+}\r
--- /dev/null
+## @file\r
+# Platform Hook Library instance for 16550 Uart.\r
+#\r
+# Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x0001001B\r
+ BASE_NAME = Fdt16550SerialPortHookLib\r
+ MODULE_UNI_FILE = Fdt16550SerialPortHookLib.uni\r
+ FILE_GUID = C6DFD3F0-179D-4376-89A5-F641A2E7EFB5\r
+ MODULE_TYPE = BASE\r
+ VERSION_STRING = 1.0\r
+ LIBRARY_CLASS = PlatformHookLib|DXE_CORE DXE_DRIVER UEFI_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION\r
+ CONSTRUCTOR = PlatformHookSerialPortInitialize\r
+\r
+[Sources]\r
+ Fdt16550SerialPortHookLib.c\r
+\r
+[LibraryClasses]\r
+ BaseLib\r
+ PcdLib\r
+ HobLib\r
+\r
+[Packages]\r
+ ArmVirtPkg/ArmVirtPkg.dec\r
+ EmbeddedPkg/EmbeddedPkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
+ MdePkg/MdePkg.dec\r
+\r
+[Pcd]\r
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase\r
+\r
+[Guids]\r
+ gEarly16550UartBaseAddressGuid\r