From 0cca97e0a839eac1a333193d7811a32ad5c44c5f Mon Sep 17 00:00:00 2001 From: Chao Li Date: Tue, 16 Jan 2024 20:26:22 +0800 Subject: ArmVirtPkg: Move the FdtSerialPortAddressLib to OvmfPkg Move the FdtSerialPortAddressLib to Ovmfpkg so that other ARCH can easily use it. Build-tested only (with "ArmVirtQemu.dsc and OvmfPkgX64.dsc"). BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Ard Biesheuvel Cc: Laszlo Ersek Cc: Leif Lindholm Cc: Sami Mujawar Cc: Gerd Hoffmann Cc: Jiewen Yao Signed-off-by: Chao Li Reviewed-by: Laszlo Ersek --- ArmVirtPkg/ArmVirt.dsc.inc | 2 +- ArmVirtPkg/ArmVirtPkg.dec | 1 - .../Include/Library/FdtSerialPortAddressLib.h | 83 ------- .../FdtSerialPortAddressLib.c | 256 --------------------- .../FdtSerialPortAddressLib.inf | 27 --- OvmfPkg/Include/Library/FdtSerialPortAddressLib.h | 83 +++++++ .../FdtSerialPortAddressLib.c | 256 +++++++++++++++++++++ .../FdtSerialPortAddressLib.inf | 27 +++ OvmfPkg/OvmfPkg.dec | 4 + 9 files changed, 371 insertions(+), 368 deletions(-) delete mode 100644 ArmVirtPkg/Include/Library/FdtSerialPortAddressLib.h delete mode 100644 ArmVirtPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.c delete mode 100644 ArmVirtPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf create mode 100644 OvmfPkg/Include/Library/FdtSerialPortAddressLib.h create mode 100644 OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.c create mode 100644 OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 9b23ef9..2bc6a29 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -122,7 +122,7 @@ # ARM PL011 UART Driver PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf SerialPortLib|ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf - FdtSerialPortAddressLib|ArmVirtPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf + FdtSerialPortAddressLib|OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf #PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf diff --git a/ArmVirtPkg/ArmVirtPkg.dec b/ArmVirtPkg/ArmVirtPkg.dec index 05d2d36..a658c91 100644 --- a/ArmVirtPkg/ArmVirtPkg.dec +++ b/ArmVirtPkg/ArmVirtPkg.dec @@ -27,7 +27,6 @@ [LibraryClasses] ArmVirtMemInfoLib|Include/Library/ArmVirtMemInfoLib.h - FdtSerialPortAddressLib|Include/Library/FdtSerialPortAddressLib.h [Guids.common] gArmVirtTokenSpaceGuid = { 0x0B6F5CA7, 0x4F53, 0x445A, { 0xB7, 0x6E, 0x2E, 0x36, 0x5B, 0x80, 0x63, 0x66 } } diff --git a/ArmVirtPkg/Include/Library/FdtSerialPortAddressLib.h b/ArmVirtPkg/Include/Library/FdtSerialPortAddressLib.h deleted file mode 100644 index 3d4c911..0000000 --- a/ArmVirtPkg/Include/Library/FdtSerialPortAddressLib.h +++ /dev/null @@ -1,83 +0,0 @@ -/** @file - Determine the base addresses of serial ports from the Device Tree. - - Copyright (C) Red Hat - - SPDX-License-Identifier: BSD-2-Clause-Patent -**/ - -#ifndef FDT_SERIAL_PORT_ADDRESS_LIB_H_ -#define FDT_SERIAL_PORT_ADDRESS_LIB_H_ - -#include - -typedef struct { - UINTN NumberOfPorts; - UINT64 BaseAddress[2]; -} FDT_SERIAL_PORTS; - -/** - Collect the first ARRAY_SIZE (Ports->BaseAddress) serial ports into Ports from - DeviceTree. - - @param[in] DeviceTree The flat device tree (FDT) to scan. - - @param[in] Compatible Look for Compatible in the "compatible" property of the - scanned nodes. - - @param[out] Ports On successful return, Ports->NumberOfPorts contains the - number of serial ports found; it is (a) positive and - (b) at most ARRAY_SIZE (Ports->BaseAddress). If the FDT - had more serial ports, those are not reported. On - error, the contents of Ports are indeterminate. - - @retval RETURN_INVALID_PARAMETER DeviceTree does not point to a valid FDT - header. - - @retval RETURN_NOT_FOUND No compatible and enabled serial port has - been found. - - @retval RETURN_SUCCESS At least one compatible and enabled serial - port has been found; Ports has been filled - in. -**/ -RETURN_STATUS -EFIAPI -FdtSerialGetPorts ( - IN CONST VOID *DeviceTree, - IN CONST CHAR8 *Compatible, - OUT FDT_SERIAL_PORTS *Ports - ); - -/** - Fetch the base address of the serial port identified in the "stdout-path" - property of the "/chosen" node in DeviceTree. - - @param[in] DeviceTree The flat device tree (FDT) to scan. - - @param[out] BaseAddress On success, the base address of the preferred serial - port (to be used as console). On error, BaseAddress - is not modified. - - @retval RETURN_INVALID_PARAMETER DeviceTree does not point to a valid FDT - header. - - @retval RETURN_NOT_FOUND No enabled console port has been found. - - @retval RETURN_PROTOCOL_ERROR The first (or only) node path in the - "stdout-path" property is an empty string. - - @retval RETURN_PROTOCOL_ERROR The console port has been found in the FDT, - but its base address is not correctly - represented. - - @retval RETURN_SUCCESS BaseAddress has been populated. -**/ -RETURN_STATUS -EFIAPI -FdtSerialGetConsolePort ( - IN CONST VOID *DeviceTree, - OUT UINT64 *BaseAddress - ); - -#endif diff --git a/ArmVirtPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.c b/ArmVirtPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.c deleted file mode 100644 index f6508e0..0000000 --- a/ArmVirtPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.c +++ /dev/null @@ -1,256 +0,0 @@ -/** @file - Determine the base addresses of serial ports from the Device Tree. - - Copyright (C) Red Hat - Copyright (c) 2011 - 2023, Arm Ltd. All rights reserved.
- Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
- Copyright (c) 2014 - 2020, Linaro Ltd. All rights reserved.
- Copyright (c) 2015, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent -**/ - -#include -#include -#include - -/** - Read the "reg" property of Node in DeviceTree as a UINT64 base address. - - @param[in] DeviceTree The flat device tree (FDT) to scan. - - @param[in] Node The node to read the "reg" property of. - - @param[out] BaseAddress On success, the base address read out of Node's "reg" - property. On error, not modified. - - @retval RETURN_DEVICE_ERROR Node has a "status" property with value - different from "okay". - - @retval RETURN_NOT_FOUND Node does not have a "reg" property. - - @retval RETURN_BAD_BUFFER_SIZE The size of Node's "reg" property is not 16 - bytes. - - @retval RETURN_SUCCESS BaseAddress has been populated. -**/ -STATIC -RETURN_STATUS -GetBaseAddress ( - IN CONST VOID *DeviceTree, - IN INT32 Node, - OUT UINT64 *BaseAddress - ) -{ - CONST CHAR8 *NodeStatus; - CONST VOID *RegProp; - INT32 PropSize; - - NodeStatus = fdt_getprop (DeviceTree, Node, "status", NULL); - if ((NodeStatus != NULL) && (AsciiStrCmp (NodeStatus, "okay") != 0)) { - return RETURN_DEVICE_ERROR; - } - - RegProp = fdt_getprop (DeviceTree, Node, "reg", &PropSize); - if (RegProp == NULL) { - return RETURN_NOT_FOUND; - } - - if (PropSize != 16) { - return RETURN_BAD_BUFFER_SIZE; - } - - *BaseAddress = fdt64_to_cpu (ReadUnaligned64 (RegProp)); - return RETURN_SUCCESS; -} - -/** - Collect the first ARRAY_SIZE (Ports->BaseAddress) serial ports into Ports from - DeviceTree. - - @param[in] DeviceTree The flat device tree (FDT) to scan. - - @param[in] Compatible Look for Compatible in the "compatible" property of the - scanned nodes. - - @param[out] Ports On successful return, Ports->NumberOfPorts contains the - number of serial ports found; it is (a) positive and - (b) at most ARRAY_SIZE (Ports->BaseAddress). If the FDT - had more serial ports, those are not reported. On - error, the contents of Ports are indeterminate. - - @retval RETURN_INVALID_PARAMETER DeviceTree does not point to a valid FDT - header. - - @retval RETURN_NOT_FOUND No compatible and enabled serial port has - been found. - - @retval RETURN_SUCCESS At least one compatible and enabled serial - port has been found; Ports has been filled - in. -**/ -RETURN_STATUS -EFIAPI -FdtSerialGetPorts ( - IN CONST VOID *DeviceTree, - IN CONST CHAR8 *Compatible, - OUT FDT_SERIAL_PORTS *Ports - ) -{ - INT32 Node; - - if (fdt_check_header (DeviceTree) != 0) { - return RETURN_INVALID_PARAMETER; - } - - Ports->NumberOfPorts = 0; - Node = fdt_next_node (DeviceTree, 0, NULL); - while ((Node > 0) && - (Ports->NumberOfPorts < ARRAY_SIZE (Ports->BaseAddress))) - { - CONST CHAR8 *CompatProp; - INT32 PropSize; - - CompatProp = fdt_getprop (DeviceTree, Node, "compatible", &PropSize); - if (CompatProp != NULL) { - CONST CHAR8 *CompatItem; - - CompatItem = CompatProp; - while ((CompatItem < CompatProp + PropSize) && - (AsciiStrCmp (CompatItem, Compatible) != 0)) - { - CompatItem += AsciiStrLen (CompatItem) + 1; - } - - if (CompatItem < CompatProp + PropSize) { - RETURN_STATUS Status; - UINT64 BaseAddress; - - Status = GetBaseAddress (DeviceTree, Node, &BaseAddress); - if (!RETURN_ERROR (Status)) { - Ports->BaseAddress[Ports->NumberOfPorts++] = BaseAddress; - } - } - } - - Node = fdt_next_node (DeviceTree, Node, NULL); - } - - return Ports->NumberOfPorts > 0 ? RETURN_SUCCESS : RETURN_NOT_FOUND; -} - -/** - Fetch the base address of the serial port identified in the "stdout-path" - property of the "/chosen" node in DeviceTree. - - @param[in] DeviceTree The flat device tree (FDT) to scan. - - @param[out] BaseAddress On success, the base address of the preferred serial - port (to be used as console). On error, BaseAddress - is not modified. - - @retval RETURN_INVALID_PARAMETER DeviceTree does not point to a valid FDT - header. - - @retval RETURN_NOT_FOUND No enabled console port has been found. - - @retval RETURN_PROTOCOL_ERROR The first (or only) node path in the - "stdout-path" property is an empty string. - - @retval RETURN_PROTOCOL_ERROR The console port has been found in the FDT, - but its base address is not correctly - represented. - - @retval RETURN_SUCCESS BaseAddress has been populated. -**/ -RETURN_STATUS -EFIAPI -FdtSerialGetConsolePort ( - IN CONST VOID *DeviceTree, - OUT UINT64 *BaseAddress - ) -{ - INT32 ChosenNode; - CONST CHAR8 *StdoutPathProp; - INT32 PropSize; - CONST CHAR8 *StdoutPathEnd; - UINTN StdoutPathLength; - INT32 ConsoleNode; - RETURN_STATUS Status; - - if (fdt_check_header (DeviceTree) != 0) { - return RETURN_INVALID_PARAMETER; - } - - ChosenNode = fdt_path_offset (DeviceTree, "/chosen"); - if (ChosenNode < 0) { - return RETURN_NOT_FOUND; - } - - StdoutPathProp = fdt_getprop ( - DeviceTree, - ChosenNode, - "stdout-path", - &PropSize - ); - if (StdoutPathProp == NULL) { - return RETURN_NOT_FOUND; - } - - // - // If StdoutPathProp contains a colon (":"), then the colon terminates the - // path we're interested in. - // - StdoutPathEnd = AsciiStrStr (StdoutPathProp, ":"); - if (StdoutPathEnd == NULL) { - StdoutPathLength = PropSize - 1; - } else { - StdoutPathLength = StdoutPathEnd - StdoutPathProp; - } - - if (StdoutPathLength == 0) { - return RETURN_PROTOCOL_ERROR; - } - - if (StdoutPathProp[0] == '/') { - // - // StdoutPathProp starts with an absolute node path. - // - ConsoleNode = fdt_path_offset_namelen ( - DeviceTree, - StdoutPathProp, - (INT32)StdoutPathLength - ); - } else { - // - // StdoutPathProp starts with an alias. - // - CONST CHAR8 *ResolvedStdoutPath; - - ResolvedStdoutPath = fdt_get_alias_namelen ( - DeviceTree, - StdoutPathProp, - (INT32)StdoutPathLength - ); - if (ResolvedStdoutPath == NULL) { - return RETURN_NOT_FOUND; - } - - ConsoleNode = fdt_path_offset (DeviceTree, ResolvedStdoutPath); - } - - if (ConsoleNode < 0) { - return RETURN_NOT_FOUND; - } - - Status = GetBaseAddress (DeviceTree, ConsoleNode, BaseAddress); - switch (Status) { - case RETURN_NOT_FOUND: - case RETURN_BAD_BUFFER_SIZE: - return RETURN_PROTOCOL_ERROR; - case RETURN_SUCCESS: - return RETURN_SUCCESS; - default: - return RETURN_NOT_FOUND; - } -} diff --git a/ArmVirtPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf b/ArmVirtPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf deleted file mode 100644 index ae6d0d3..0000000 --- a/ArmVirtPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf +++ /dev/null @@ -1,27 +0,0 @@ -## @file -# Determine the base addresses of serial ports from the Device Tree. -# -# Copyright (C) Red Hat -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] - INF_VERSION = 1.27 - BASE_NAME = FdtSerialPortAddressLib - FILE_GUID = AEBE813B-25EA-40E5-95C4-2B864FE1E951 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = FdtSerialPortAddressLib - -[Sources] - FdtSerialPortAddressLib.c - -[Packages] - ArmVirtPkg/ArmVirtPkg.dec - EmbeddedPkg/EmbeddedPkg.dec - MdePkg/MdePkg.dec - -[LibraryClasses] - BaseLib - FdtLib diff --git a/OvmfPkg/Include/Library/FdtSerialPortAddressLib.h b/OvmfPkg/Include/Library/FdtSerialPortAddressLib.h new file mode 100644 index 0000000..3d4c911 --- /dev/null +++ b/OvmfPkg/Include/Library/FdtSerialPortAddressLib.h @@ -0,0 +1,83 @@ +/** @file + Determine the base addresses of serial ports from the Device Tree. + + Copyright (C) Red Hat + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef FDT_SERIAL_PORT_ADDRESS_LIB_H_ +#define FDT_SERIAL_PORT_ADDRESS_LIB_H_ + +#include + +typedef struct { + UINTN NumberOfPorts; + UINT64 BaseAddress[2]; +} FDT_SERIAL_PORTS; + +/** + Collect the first ARRAY_SIZE (Ports->BaseAddress) serial ports into Ports from + DeviceTree. + + @param[in] DeviceTree The flat device tree (FDT) to scan. + + @param[in] Compatible Look for Compatible in the "compatible" property of the + scanned nodes. + + @param[out] Ports On successful return, Ports->NumberOfPorts contains the + number of serial ports found; it is (a) positive and + (b) at most ARRAY_SIZE (Ports->BaseAddress). If the FDT + had more serial ports, those are not reported. On + error, the contents of Ports are indeterminate. + + @retval RETURN_INVALID_PARAMETER DeviceTree does not point to a valid FDT + header. + + @retval RETURN_NOT_FOUND No compatible and enabled serial port has + been found. + + @retval RETURN_SUCCESS At least one compatible and enabled serial + port has been found; Ports has been filled + in. +**/ +RETURN_STATUS +EFIAPI +FdtSerialGetPorts ( + IN CONST VOID *DeviceTree, + IN CONST CHAR8 *Compatible, + OUT FDT_SERIAL_PORTS *Ports + ); + +/** + Fetch the base address of the serial port identified in the "stdout-path" + property of the "/chosen" node in DeviceTree. + + @param[in] DeviceTree The flat device tree (FDT) to scan. + + @param[out] BaseAddress On success, the base address of the preferred serial + port (to be used as console). On error, BaseAddress + is not modified. + + @retval RETURN_INVALID_PARAMETER DeviceTree does not point to a valid FDT + header. + + @retval RETURN_NOT_FOUND No enabled console port has been found. + + @retval RETURN_PROTOCOL_ERROR The first (or only) node path in the + "stdout-path" property is an empty string. + + @retval RETURN_PROTOCOL_ERROR The console port has been found in the FDT, + but its base address is not correctly + represented. + + @retval RETURN_SUCCESS BaseAddress has been populated. +**/ +RETURN_STATUS +EFIAPI +FdtSerialGetConsolePort ( + IN CONST VOID *DeviceTree, + OUT UINT64 *BaseAddress + ); + +#endif diff --git a/OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.c b/OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.c new file mode 100644 index 0000000..f6508e0 --- /dev/null +++ b/OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.c @@ -0,0 +1,256 @@ +/** @file + Determine the base addresses of serial ports from the Device Tree. + + Copyright (C) Red Hat + Copyright (c) 2011 - 2023, Arm Ltd. All rights reserved.
+ Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
+ Copyright (c) 2014 - 2020, Linaro Ltd. All rights reserved.
+ Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include + +/** + Read the "reg" property of Node in DeviceTree as a UINT64 base address. + + @param[in] DeviceTree The flat device tree (FDT) to scan. + + @param[in] Node The node to read the "reg" property of. + + @param[out] BaseAddress On success, the base address read out of Node's "reg" + property. On error, not modified. + + @retval RETURN_DEVICE_ERROR Node has a "status" property with value + different from "okay". + + @retval RETURN_NOT_FOUND Node does not have a "reg" property. + + @retval RETURN_BAD_BUFFER_SIZE The size of Node's "reg" property is not 16 + bytes. + + @retval RETURN_SUCCESS BaseAddress has been populated. +**/ +STATIC +RETURN_STATUS +GetBaseAddress ( + IN CONST VOID *DeviceTree, + IN INT32 Node, + OUT UINT64 *BaseAddress + ) +{ + CONST CHAR8 *NodeStatus; + CONST VOID *RegProp; + INT32 PropSize; + + NodeStatus = fdt_getprop (DeviceTree, Node, "status", NULL); + if ((NodeStatus != NULL) && (AsciiStrCmp (NodeStatus, "okay") != 0)) { + return RETURN_DEVICE_ERROR; + } + + RegProp = fdt_getprop (DeviceTree, Node, "reg", &PropSize); + if (RegProp == NULL) { + return RETURN_NOT_FOUND; + } + + if (PropSize != 16) { + return RETURN_BAD_BUFFER_SIZE; + } + + *BaseAddress = fdt64_to_cpu (ReadUnaligned64 (RegProp)); + return RETURN_SUCCESS; +} + +/** + Collect the first ARRAY_SIZE (Ports->BaseAddress) serial ports into Ports from + DeviceTree. + + @param[in] DeviceTree The flat device tree (FDT) to scan. + + @param[in] Compatible Look for Compatible in the "compatible" property of the + scanned nodes. + + @param[out] Ports On successful return, Ports->NumberOfPorts contains the + number of serial ports found; it is (a) positive and + (b) at most ARRAY_SIZE (Ports->BaseAddress). If the FDT + had more serial ports, those are not reported. On + error, the contents of Ports are indeterminate. + + @retval RETURN_INVALID_PARAMETER DeviceTree does not point to a valid FDT + header. + + @retval RETURN_NOT_FOUND No compatible and enabled serial port has + been found. + + @retval RETURN_SUCCESS At least one compatible and enabled serial + port has been found; Ports has been filled + in. +**/ +RETURN_STATUS +EFIAPI +FdtSerialGetPorts ( + IN CONST VOID *DeviceTree, + IN CONST CHAR8 *Compatible, + OUT FDT_SERIAL_PORTS *Ports + ) +{ + INT32 Node; + + if (fdt_check_header (DeviceTree) != 0) { + return RETURN_INVALID_PARAMETER; + } + + Ports->NumberOfPorts = 0; + Node = fdt_next_node (DeviceTree, 0, NULL); + while ((Node > 0) && + (Ports->NumberOfPorts < ARRAY_SIZE (Ports->BaseAddress))) + { + CONST CHAR8 *CompatProp; + INT32 PropSize; + + CompatProp = fdt_getprop (DeviceTree, Node, "compatible", &PropSize); + if (CompatProp != NULL) { + CONST CHAR8 *CompatItem; + + CompatItem = CompatProp; + while ((CompatItem < CompatProp + PropSize) && + (AsciiStrCmp (CompatItem, Compatible) != 0)) + { + CompatItem += AsciiStrLen (CompatItem) + 1; + } + + if (CompatItem < CompatProp + PropSize) { + RETURN_STATUS Status; + UINT64 BaseAddress; + + Status = GetBaseAddress (DeviceTree, Node, &BaseAddress); + if (!RETURN_ERROR (Status)) { + Ports->BaseAddress[Ports->NumberOfPorts++] = BaseAddress; + } + } + } + + Node = fdt_next_node (DeviceTree, Node, NULL); + } + + return Ports->NumberOfPorts > 0 ? RETURN_SUCCESS : RETURN_NOT_FOUND; +} + +/** + Fetch the base address of the serial port identified in the "stdout-path" + property of the "/chosen" node in DeviceTree. + + @param[in] DeviceTree The flat device tree (FDT) to scan. + + @param[out] BaseAddress On success, the base address of the preferred serial + port (to be used as console). On error, BaseAddress + is not modified. + + @retval RETURN_INVALID_PARAMETER DeviceTree does not point to a valid FDT + header. + + @retval RETURN_NOT_FOUND No enabled console port has been found. + + @retval RETURN_PROTOCOL_ERROR The first (or only) node path in the + "stdout-path" property is an empty string. + + @retval RETURN_PROTOCOL_ERROR The console port has been found in the FDT, + but its base address is not correctly + represented. + + @retval RETURN_SUCCESS BaseAddress has been populated. +**/ +RETURN_STATUS +EFIAPI +FdtSerialGetConsolePort ( + IN CONST VOID *DeviceTree, + OUT UINT64 *BaseAddress + ) +{ + INT32 ChosenNode; + CONST CHAR8 *StdoutPathProp; + INT32 PropSize; + CONST CHAR8 *StdoutPathEnd; + UINTN StdoutPathLength; + INT32 ConsoleNode; + RETURN_STATUS Status; + + if (fdt_check_header (DeviceTree) != 0) { + return RETURN_INVALID_PARAMETER; + } + + ChosenNode = fdt_path_offset (DeviceTree, "/chosen"); + if (ChosenNode < 0) { + return RETURN_NOT_FOUND; + } + + StdoutPathProp = fdt_getprop ( + DeviceTree, + ChosenNode, + "stdout-path", + &PropSize + ); + if (StdoutPathProp == NULL) { + return RETURN_NOT_FOUND; + } + + // + // If StdoutPathProp contains a colon (":"), then the colon terminates the + // path we're interested in. + // + StdoutPathEnd = AsciiStrStr (StdoutPathProp, ":"); + if (StdoutPathEnd == NULL) { + StdoutPathLength = PropSize - 1; + } else { + StdoutPathLength = StdoutPathEnd - StdoutPathProp; + } + + if (StdoutPathLength == 0) { + return RETURN_PROTOCOL_ERROR; + } + + if (StdoutPathProp[0] == '/') { + // + // StdoutPathProp starts with an absolute node path. + // + ConsoleNode = fdt_path_offset_namelen ( + DeviceTree, + StdoutPathProp, + (INT32)StdoutPathLength + ); + } else { + // + // StdoutPathProp starts with an alias. + // + CONST CHAR8 *ResolvedStdoutPath; + + ResolvedStdoutPath = fdt_get_alias_namelen ( + DeviceTree, + StdoutPathProp, + (INT32)StdoutPathLength + ); + if (ResolvedStdoutPath == NULL) { + return RETURN_NOT_FOUND; + } + + ConsoleNode = fdt_path_offset (DeviceTree, ResolvedStdoutPath); + } + + if (ConsoleNode < 0) { + return RETURN_NOT_FOUND; + } + + Status = GetBaseAddress (DeviceTree, ConsoleNode, BaseAddress); + switch (Status) { + case RETURN_NOT_FOUND: + case RETURN_BAD_BUFFER_SIZE: + return RETURN_PROTOCOL_ERROR; + case RETURN_SUCCESS: + return RETURN_SUCCESS; + default: + return RETURN_NOT_FOUND; + } +} diff --git a/OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf b/OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf new file mode 100644 index 0000000..e27742e --- /dev/null +++ b/OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf @@ -0,0 +1,27 @@ +## @file +# Determine the base addresses of serial ports from the Device Tree. +# +# Copyright (C) Red Hat +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 1.27 + BASE_NAME = FdtSerialPortAddressLib + FILE_GUID = AEBE813B-25EA-40E5-95C4-2B864FE1E951 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = FdtSerialPortAddressLib + +[Sources] + FdtSerialPortAddressLib.c + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + FdtLib diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index 7bc2bf1..13e69e6 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -29,6 +29,10 @@ ## @libraryclass Verify blobs read from the VMM BlobVerifierLib|Include/Library/BlobVerifierLib.h + ## @libraryclass FdtSerialPortAddressLib + # + FdtSerialPortAddressLib|Include/Library/FdtSerialPortAddressLib.h + ## @libraryclass Loads and boots a Linux kernel image # LoadLinuxLib|Include/Library/LoadLinuxLib.h -- cgit v1.1