summaryrefslogtreecommitdiffstats
path: root/ArmVirtPkg/Include
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2023-10-08 17:39:04 +0200
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-10-26 18:55:43 +0000
commiteb83b53309611aba6160ef396c91f36eb8975eca (patch)
treea1fe42a08309c153f21817649c4c3665d7ef7b9a /ArmVirtPkg/Include
parent74c687cc2f2f29d3bdd454a416624f0ca5a86566 (diff)
downloadedk2-eb83b53309611aba6160ef396c91f36eb8975eca.tar.gz
ArmVirtPkg: introduce FdtSerialPortAddressLib
Introduce a new library class + instance for: - collecting serial port base addresses from the device tree, - collecting the /chosen stdout-path serial port base address from the device tree. The logic is loosely based on the following functions: - SerialPortGetBaseAddress() [ArmVirtPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.c] - PlatformPeim() [ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c] - GetSerialConsolePortAddress() [ArmVirtPkg/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.c] which are going to be converted to clients of the new library later. Copyright notices from those other files are preserved. The new library fixes the following warts, found by reading the existent code: - Neither of the three functions check whether the "reg" property exists. (This may be implicitly checked when they compare the property size to 16.) - GetSerialConsolePortAddress() uses ScanMem8() for locating a colon (":") node path separator in "stdout-path", when AsciiStrStr() could work just as fine. While ScanMem8() is likely faster, "stdout-path" is presumably very short, and ScanMem8() introduces an extra lib class dependency (namely BaseMemoryLib). - If ScanMem8() fails to locate a colon in "stdout-path", then GetSerialConsolePortAddress() re-measures the length of the whole "stdout-path" property. This is conceptually (if not performance-wise) disturbing, because we know the whole size of the "stdout-path" property from the property lookup just before, so we only need to subtract the NUL-terminator for learning the length. - GetSerialConsolePortAddress() does not check if the first (or only) node path inside the "stdout-path" property is empty. (Not a big deal, the subsequent alias resolution should simply fail.) - GetSerialConsolePortAddress() does not verify if the node path retrieved (and potentially alias-resolved) from "stdout-path" can be located in the device tree; it assumes it. - Code is duplicated (of course) between SerialPortGetBaseAddress() and PlatformPeim(), but more surprisingly, all three functions embed the same code for verifying the "status" property of the serial port node, and for checking and reading its "reg" property. 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-2-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]
Diffstat (limited to 'ArmVirtPkg/Include')
-rw-r--r--ArmVirtPkg/Include/Library/FdtSerialPortAddressLib.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/ArmVirtPkg/Include/Library/FdtSerialPortAddressLib.h b/ArmVirtPkg/Include/Library/FdtSerialPortAddressLib.h
new file mode 100644
index 0000000000..3d4c911f58
--- /dev/null
+++ b/ArmVirtPkg/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 <Base.h>
+
+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