+/** @file\r
+ Platform Hook Library instance for UART device.\r
+\r
+ Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <PiDxe.h>\r
+#include <UniversalPayload/SerialPortInfo.h>\r
+#include <Library/PlatformHookLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/HobLib.h>\r
+\r
+/**\r
+ Performs platform specific initialization required for the CPU to access\r
+ the hardware associated with a SerialPortLib instance. This function does\r
+ not initialize the serial port hardware itself. Instead, it initializes\r
+ hardware devices that are required for the CPU to access the serial port\r
+ hardware. This function may be called more than once.\r
+\r
+ @retval RETURN_SUCCESS The platform specific initialization succeeded.\r
+ @retval RETURN_DEVICE_ERROR The platform specific initialization could not be completed.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+PlatformHookSerialPortInitialize (\r
+ VOID\r
+ )\r
+{\r
+ RETURN_STATUS Status;\r
+ UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *SerialPortInfo;\r
+ UINT8 *GuidHob;\r
+ UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader;\r
+\r
+ GuidHob = GetFirstGuidHob (&gUniversalPayloadSerialPortInfoGuid);\r
+ if (GuidHob == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *) GET_GUID_HOB_DATA (GuidHob);\r
+ if ((sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) > GET_GUID_HOB_DATA_SIZE (GuidHob)) || (GenericHeader->Length > GET_GUID_HOB_DATA_SIZE (GuidHob))) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ if (GenericHeader->Revision == UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO_REVISION) {\r
+ SerialPortInfo = (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *) GET_GUID_HOB_DATA (GuidHob);\r
+ if (GenericHeader->Length < UNIVERSAL_PAYLOAD_SIZEOF_THROUGH_FIELD (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO, RegisterBase)) {\r
+ //\r
+ // Return if can't find the Serial Port Info Hob with enough length\r
+ //\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Status = PcdSetBoolS (PcdSerialUseMmio, SerialPortInfo->UseMmio);\r
+ if (RETURN_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ Status = PcdSet64S (PcdSerialRegisterBase, SerialPortInfo->RegisterBase);\r
+ if (RETURN_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ Status = PcdSet32S (PcdSerialRegisterStride, SerialPortInfo->RegisterStride);\r
+ if (RETURN_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ Status = PcdSet32S (PcdSerialBaudRate, SerialPortInfo->BaudRate);\r
+ if (RETURN_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ Status = PcdSet64S (PcdUartDefaultBaudRate, SerialPortInfo->BaudRate);\r
+ if (RETURN_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r