123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- /** @file
- Early Platform Hook Library instance for 16550 Uart.
- Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Base.h>
- #include <Uefi.h>
- #include <Pi/PiBootMode.h>
- #include <Pi/PiHob.h>
- #include <Library/BaseLib.h>
- #include <Library/DebugLib.h>
- #include <Library/HobLib.h>
- #include <Library/PcdLib.h>
- #include <Library/PlatformHookLib.h>
- #include <libfdt.h>
- /** Get the UART base address of the console serial-port from the DT.
- This function fetches the node referenced in the "stdout-path"
- property of the "chosen" node and returns the base address of
- the console UART.
- @param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
- @param [out] SerialConsoleAddress If success, contains the base address
- of the console serial-port.
- @retval EFI_SUCCESS The function completed successfully.
- @retval EFI_NOT_FOUND Console serial-port info not found in DT.
- @retval EFI_INVALID_PARAMETER Invalid parameter.
- **/
- STATIC
- EFI_STATUS
- EFIAPI
- GetSerialConsolePortAddress (
- IN CONST VOID *Fdt,
- OUT UINT64 *SerialConsoleAddress
- )
- {
- CONST CHAR8 *Prop;
- INT32 PropSize;
- CONST CHAR8 *Path;
- INT32 PathLen;
- INT32 ChosenNode;
- INT32 SerialConsoleNode;
- INT32 Len;
- CONST CHAR8 *NodeStatus;
- CONST UINT64 *RegProperty;
- if ((Fdt == NULL) || (fdt_check_header (Fdt) != 0)) {
- return EFI_INVALID_PARAMETER;
- }
- // The "chosen" node resides at the the root of the DT. Fetch it.
- ChosenNode = fdt_path_offset (Fdt, "/chosen");
- if (ChosenNode < 0) {
- return EFI_NOT_FOUND;
- }
- Prop = fdt_getprop (Fdt, ChosenNode, "stdout-path", &PropSize);
- if (PropSize < 0) {
- return EFI_NOT_FOUND;
- }
- // Determine the actual path length, as a colon terminates the path.
- Path = ScanMem8 (Prop, ':', PropSize);
- if (Path == NULL) {
- PathLen = AsciiStrLen (Prop);
- } else {
- PathLen = Path - Prop;
- }
- // Aliases cannot start with a '/', so it must be the actual path.
- if (Prop[0] == '/') {
- SerialConsoleNode = fdt_path_offset_namelen (Fdt, Prop, PathLen);
- } else {
- // Lookup the alias, as this contains the actual path.
- Path = fdt_get_alias_namelen (Fdt, Prop, PathLen);
- if (Path == NULL) {
- return EFI_NOT_FOUND;
- }
- SerialConsoleNode = fdt_path_offset (Fdt, Path);
- }
- NodeStatus = fdt_getprop (Fdt, SerialConsoleNode, "status", &Len);
- if ((NodeStatus != NULL) && (AsciiStrCmp (NodeStatus, "okay") != 0)) {
- return EFI_NOT_FOUND;
- }
- RegProperty = fdt_getprop (Fdt, SerialConsoleNode, "reg", &Len);
- if (Len != 16) {
- return EFI_INVALID_PARAMETER;
- }
- *SerialConsoleAddress = fdt64_to_cpu (ReadUnaligned64 (RegProperty));
- return EFI_SUCCESS;
- }
- /** Platform hook to retrieve the 16550 UART base address from the platform
- Device tree and store it in PcdSerialRegisterBase.
- @retval RETURN_SUCCESS Success.
- @retval RETURN_INVALID_PARAMETER A parameter was invalid.
- @retval RETURN_NOT_FOUND Serial port information not found.
- **/
- RETURN_STATUS
- EFIAPI
- PlatformHookSerialPortInitialize (
- VOID
- )
- {
- RETURN_STATUS Status;
- VOID *DeviceTreeBase;
- UINT64 SerialConsoleAddress;
- if (PcdGet64 (PcdSerialRegisterBase) != 0) {
- return RETURN_SUCCESS;
- }
- DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
- if (DeviceTreeBase == NULL) {
- return RETURN_NOT_FOUND;
- }
- Status = GetSerialConsolePortAddress (DeviceTreeBase, &SerialConsoleAddress);
- if (RETURN_ERROR (Status)) {
- return Status;
- }
- return (EFI_STATUS)PcdSet64S (PcdSerialRegisterBase, SerialConsoleAddress);
- }
|