From: "Narinder Dhillon" <ndhillon@marvell.com>
To: <devel@edk2.groups.io>
Cc: <quic_llindhol@quicinc.com>, <mw@semihalf.com>,
<sbalcerak@marvell.com>, Narinder Dhillon <ndhillon@marvell.com>
Subject: [edk2-devel] [edk2-platforms PATCH v2 7/8] Silicon/Marvell: Driver to dump board configuration
Date: Wed, 20 Dec 2023 16:54:26 -0800 [thread overview]
Message-ID: <20231221005427.13932-8-ndhillon@marvell.com> (raw)
In-Reply-To: <20231221005427.13932-1-ndhillon@marvell.com>
From: Narinder Dhillon <ndhillon@marvell.com>
This patch adds an EDK2 shell command to dump board configuration
device tree.
Signed-off-by: Narinder Dhillon <ndhillon@marvell.com>
---
.../Drivers/Fdt/FdtPlatformDxe/FdtPlatform.c | 361 ++++++++++++++++++
.../Drivers/Fdt/FdtPlatformDxe/FdtPlatform.h | 102 +++++
.../Fdt/FdtPlatformDxe/FdtPlatformDxe.inf | 60 +++
.../Fdt/FdtPlatformDxe/FdtPlatformDxe.uni | 106 +++++
.../Drivers/Fdt/FdtPlatformDxe/README.txt | 69 ++++
.../Drivers/Fdt/FdtPlatformDxe/ShellDumpFdt.c | 283 ++++++++++++++
6 files changed, 981 insertions(+)
create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.c
create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.h
create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf
create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.uni
create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/README.txt
create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/ShellDumpFdt.c
diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.c b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.c
new file mode 100644
index 0000000000..8faa135003
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.c
@@ -0,0 +1,361 @@
+/** @file
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+ https://spdx.org/licenses
+
+ Copyright (C) 2023 Marvell
+
+ Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+
+**/
+
+#include "FdtPlatform.h"
+
+#include <PiDxe.h>
+
+#include <Library/PcdLib.h>
+#include <Library/BdsLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Guid/FdtHob.h>
+
+//
+// Internal variables
+//
+
+STATIC CONST EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mShellDynCmdProtocolDumpFdt = {
+ L"dumpfdt", // Name of the command
+ ShellDynCmdDumpFdtHandler, // Handler
+ ShellDynCmdDumpFdtGetHelp // GetHelp
+};
+
+STATIC CONST EFI_GUID mFdtPlatformDxeHiiGuid = {
+ 0x8afa7610, 0x62b1, 0x46aa,
+ {0xb5, 0x34, 0xc3, 0xde, 0xff, 0x39, 0x77, 0x8c}
+ };
+
+EFI_HANDLE mFdtPlatformDxeHiiHandle;
+VOID *mFdtBlobBase;
+
+EFI_STATUS
+DeleteFdtNode (
+ IN VOID *FdtAddr,
+ CONST CHAR8 *NodePath,
+ CONST CHAR8 *Compatible
+)
+{
+ INTN Offset = -1;
+ INTN Return;
+
+ if ((NodePath != NULL) && (Compatible != NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (NodePath != NULL) {
+ Offset = fdt_path_offset (FdtAddr, NodePath);
+
+ DEBUG ((DEBUG_INFO, "Offset: %d\n", Offset));
+
+ if (Offset < 0) {
+ DEBUG ((DEBUG_ERROR, "Error getting the device node %a offset: %a\n",
+ NodePath, fdt_strerror (Offset)));
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ if (Compatible != NULL) {
+ Offset = fdt_node_offset_by_compatible (FdtAddr, -1, Compatible);
+
+ DEBUG ((DEBUG_INFO, "Offset: %d\n", Offset));
+
+ if (Offset < 0) {
+ DEBUG ((DEBUG_ERROR, "Error getting the device node for %a offset: %a\n",
+ Compatible, fdt_strerror (Offset)));
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ if (Offset >= 0) {
+ Return = fdt_del_node (FdtAddr, Offset);
+
+ DEBUG ((DEBUG_INFO, "Return: %d\n", Return));
+
+ if (Return < 0) {
+ DEBUG ((DEBUG_ERROR, "Error deleting the device node %a: %a\n",
+ NodePath, fdt_strerror (Return)));
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DeleteRtcNode (
+ IN VOID *FdtAddr
+ )
+{
+ INT32 Offset, NameLen, Return;
+ BOOLEAN Found;
+ CONST CHAR8 *Name;
+
+ Found = FALSE;
+ for (Offset = fdt_next_node(FdtAddr, 0, NULL);
+ Offset >= 0;
+ Offset = fdt_next_node(FdtAddr, Offset, NULL)) {
+
+ Name = fdt_get_name(FdtAddr, Offset, &NameLen);
+ if (!Name) {
+ continue;
+ }
+
+ if ((Name[0] == 'r') && (Name[1] == 't') && (Name[2] == 'c')) {
+ Found = TRUE;
+ break;
+ }
+ }
+
+ if (Found == TRUE) {
+ Return = fdt_del_node (FdtAddr, Offset);
+
+ if (Return < 0) {
+ DEBUG ((DEBUG_ERROR, "Error deleting the device node %a\n", Name));
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FdtFixup(
+ IN VOID *FdtAddr
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (FeaturePcdGet(PcdFixupFdt)) {
+ Status |= DeleteFdtNode (FdtAddr, (CHAR8*)PcdGetPtr (PcdFdtConfigRootNode), NULL);
+
+ // Hide the RTC
+ Status |= DeleteRtcNode (FdtAddr);
+ }
+
+ if (!EFI_ERROR(Status)) {
+ fdt_pack(FdtAddr);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Install the FDT specified by its device path in text form.
+
+ @retval EFI_SUCCESS The FDT was installed.
+ @retval EFI_NOT_FOUND Failed to locate a protocol or a file.
+ @retval EFI_INVALID_PARAMETER Invalid device path.
+ @retval EFI_UNSUPPORTED Device path not supported.
+ @retval EFI_OUT_OF_RESOURCES An allocation failed.
+**/
+STATIC
+EFI_STATUS
+InstallFdt (
+ VOID
+)
+{
+ EFI_STATUS Status;
+ UINTN FdtBlobSize;
+ VOID *FdtConfigurationTableBase;
+ VOID *HobList;
+ EFI_HOB_GUID_TYPE *GuidHob;
+
+ //
+ // Get the HOB list. If it is not present, then ASSERT.
+ //
+ HobList = GetHobList ();
+ ASSERT (HobList != NULL);
+
+ //
+ // Search for FDT GUID HOB. If it is not present, then
+ // there's nothing we can do. It may not exist on the update path.
+ //
+ GuidHob = GetNextGuidHob (&gFdtHobGuid, HobList);
+ if (GuidHob != NULL) {
+ mFdtBlobBase = (VOID *)*(UINT64 *)(GET_GUID_HOB_DATA (GuidHob));
+ FdtBlobSize = fdt_totalsize((VOID *)mFdtBlobBase);
+
+ //
+ // Ensure that the FDT header is valid and that the Size of the Device Tree
+ // is smaller than the size of the read file
+ //
+ if (fdt_check_header (mFdtBlobBase)) {
+ DEBUG ((DEBUG_ERROR, "InstallFdt() - FDT blob seems to be corrupt\n"));
+ mFdtBlobBase = NULL;
+ Status = EFI_LOAD_ERROR;
+ goto Error;
+ }
+ } else {
+ Status = EFI_NOT_FOUND;
+ goto Error;
+ }
+
+ Status = EFI_SUCCESS;
+
+ if (FeaturePcdGet(PcdPublishFdt)) {
+ FdtConfigurationTableBase = AllocateRuntimeCopyPool (FdtBlobSize, mFdtBlobBase);
+
+ if (FdtConfigurationTableBase == NULL) {
+ goto Error;
+ }
+
+ Status = FdtFixup((VOID*)FdtConfigurationTableBase);
+
+ if (EFI_ERROR (Status)) {
+ FreePool (FdtConfigurationTableBase);
+ goto Error;
+ }
+
+ //
+ // Install the FDT into the Configuration Table
+ //
+ Status = gBS->InstallConfigurationTable (
+ &gFdtTableGuid,
+ FdtConfigurationTableBase
+ );
+
+ if (EFI_ERROR (Status)) {
+ FreePool (FdtConfigurationTableBase);
+ }
+ }
+
+Error:
+ return Status;
+}
+
+/**
+ Main entry point of the FDT platform driver.
+
+ @param[in] ImageHandle The firmware allocated handle for the present driver
+ UEFI image.
+ @param[in] *SystemTable A pointer to the EFI System table.
+
+ @retval EFI_SUCCESS The driver was initialized.
+ @retval EFI_OUT_OF_RESOURCES The "End of DXE" event could not be allocated or
+ there was not enough memory in pool to install
+ the Shell Dynamic Command protocol.
+ @retval EFI_LOAD_ERROR Unable to add the HII package.
+
+**/
+EFI_STATUS
+FdtPlatformEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ //
+ // Install the Device Tree from its expected location
+ //
+ Status = InstallFdt ();
+
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Register the strings for the user interface in the HII Database.
+ // This shows the way to the multi-language support, even if
+ // only the English language is actually supported. The strings to register
+ // are stored in the "ShellSetFdtStrings[]" array. This array is
+ // built by the building process from the "*.uni" file associated to
+ // the present driver (cf. FdtPlatfromDxe.inf). Examine your Build
+ // folder under your package's DEBUG folder and you will find the array
+ // defined in a xxxStrDefs.h file.
+ //
+ mFdtPlatformDxeHiiHandle = HiiAddPackages (
+ &mFdtPlatformDxeHiiGuid,
+ ImageHandle,
+ FdtPlatformDxeStrings,
+ NULL
+ );
+ if (mFdtPlatformDxeHiiHandle != NULL) {
+ // We install dynamic EFI command on separate handles as we cannot register
+ // more than one protocol of the same protocol interface on the same handle.
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiShellDynamicCommandProtocolGuid,
+ &mShellDynCmdProtocolDumpFdt,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ HiiRemovePackages (mFdtPlatformDxeHiiHandle);
+ }
+ } else {
+ Status = EFI_LOAD_ERROR;
+ }
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_WARN,
+ "Unable to install \"dumpfdt\" EFI Shell command - %r \n",
+ Status
+ ));
+ }
+
+ return Status;
+}
+
+/**
+ Transcode one of the EFI return code used by the model into an EFI Shell return code.
+
+ @param[in] Status EFI return code.
+
+ @return Transcoded EFI Shell return code.
+
+**/
+SHELL_STATUS
+EfiCodeToShellCode (
+ IN EFI_STATUS Status
+ )
+{
+ SHELL_STATUS ShellStatus;
+
+ switch (Status) {
+ case EFI_SUCCESS :
+ ShellStatus = SHELL_SUCCESS;
+ break;
+
+ case EFI_INVALID_PARAMETER :
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ break;
+
+ case EFI_UNSUPPORTED :
+ ShellStatus = SHELL_UNSUPPORTED;
+ break;
+
+ case EFI_DEVICE_ERROR :
+ ShellStatus = SHELL_DEVICE_ERROR;
+ break;
+
+ case EFI_WRITE_PROTECTED :
+ case EFI_SECURITY_VIOLATION :
+ ShellStatus = SHELL_ACCESS_DENIED;
+ break;
+
+ case EFI_OUT_OF_RESOURCES :
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ break;
+
+ case EFI_NOT_FOUND :
+ ShellStatus = SHELL_NOT_FOUND;
+ break;
+
+ default :
+ ShellStatus = SHELL_ABORTED;
+ }
+
+ return ShellStatus;
+}
diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.h b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.h
new file mode 100644
index 0000000000..22517b6d28
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatform.h
@@ -0,0 +1,102 @@
+/** @file
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+ https://spdx.org/licenses
+
+ Copyright (C) 2023 Marvell
+
+ Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+
+**/
+
+#ifndef __FDT_PLATFORM_DXE_H__
+#define __FDT_PLATFORM_DXE_H__
+
+#include <Uefi.h>
+
+#include <Library/DevicePathLib.h>
+#include <Protocol/Shell.h>
+#include <Protocol/ShellDynamicCommand.h>
+
+#include <Library/DebugLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/ShellLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include <Guid/Fdt.h>
+
+#include <libfdt.h>
+
+extern EFI_HANDLE mFdtPlatformDxeHiiHandle;
+
+/**
+ Transcode one of the EFI return code used by the model into an EFI Shell return code.
+
+ @param[in] Status EFI return code.
+
+ @return Transcoded EFI Shell return code.
+
+**/
+SHELL_STATUS
+EfiCodeToShellCode (
+ IN EFI_STATUS Status
+ );
+
+/**
+ Run the FDT installation process.
+
+ Loop in priority order over the device paths from which the FDT has
+ been asked to be retrieved for. For each device path, try to install
+ the FDT. Stop as soon as an installation succeeds.
+
+ @param[in] SuccessfullDevicePath If not NULL, address where to store the
+ pointer to the text device path from
+ which the FDT was successfully retrieved.
+ Not used if the FDT installation failed.
+ The returned address is the address of
+ an allocated buffer that has to be
+ freed by the caller.
+
+ @retval EFI_SUCCESS The FDT was installed.
+ @retval EFI_NOT_FOUND Failed to locate a protocol or a file.
+ @retval EFI_INVALID_PARAMETER Invalid device path.
+ @retval EFI_UNSUPPORTED Device path not supported.
+ @retval EFI_OUT_OF_RESOURCES An allocation failed.
+
+**/
+EFI_STATUS
+RunFdtInstallation (
+ OUT CHAR16 **SuccessfullDevicePath
+ );
+
+SHELL_STATUS
+EFIAPI
+ShellDynCmdDumpFdtHandler (
+ IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
+ IN EFI_SHELL_PROTOCOL *Shell
+ );
+
+/**
+ This is the shell command "dumpfdt" help handler function. This
+ function returns the formatted help for the "dumpfdt" command.
+ The format matchs that in Appendix B of the revision 2.1 of the
+ UEFI Shell Specification.
+
+ @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+ @param[in] Language The pointer to the language string to use.
+
+ @return CHAR16* Pool allocated help string, must be freed by caller.
+**/
+CHAR16*
+EFIAPI
+ShellDynCmdDumpFdtGetHelp (
+ IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
+ IN CONST CHAR8 *Language
+ );
+
+#endif /* __FDT_PLATFORM_DXE_H__ */
diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf
new file mode 100644
index 0000000000..1c3496d13f
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.inf
@@ -0,0 +1,60 @@
+#/** @file
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+# https://spdx.org/licenses
+#
+# Copyright (C) 2023 Marvell
+#
+# Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = FdtPlatformDxe
+ MODULE_UNI_FILE = FdtPlatformDxe.uni
+ FILE_GUID = 6e9a4c69-57c6-4fcd-b083-4f2c3bdb6051
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 0.1
+ ENTRY_POINT = FdtPlatformEntryPoint
+
+[Sources.common]
+ FdtPlatform.c
+ FdtPlatformDxe.uni
+ ShellDumpFdt.c
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ Platform/ARM/ARM.dec
+ Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ BaseMemoryLib
+ DebugLib
+ FdtLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ HiiLib
+ ShellLib
+ HobLib
+
+[Protocols]
+ gEfiShellDynamicCommandProtocolGuid
+
+[Guids]
+ gFdtHobGuid
+ gFdtTableGuid
+
+[FeaturePcd]
+ gMarvellSiliconTokenSpaceGuid.PcdPublishFdt
+ gMarvellSiliconTokenSpaceGuid.PcdFixupFdt
+
+[FixedPcd]
+ gMarvellSiliconTokenSpaceGuid.PcdFdtConfigRootNode
+
+[Depex]
+ TRUE
diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.uni b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.uni
new file mode 100644
index 0000000000..828fb9a609
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/FdtPlatformDxe.uni
@@ -0,0 +1,106 @@
+// *++
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+// https://spdx.org/licenses
+//
+// Copyright (C) 2023 Marvell
+//
+// Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+//
+//
+// Module Name:
+//
+// FdtPlatformDxe
+//
+// Abstract:
+//
+// String definitions for the EFI Shell 'setfdt' command
+//
+// Revision History:
+//
+// --*/
+
+/=#
+
+#langdef en-US "English"
+
+#string STR_SETFDT_INSTALLING #language en-US "Installing the FDT ...\r\n"
+#string STR_SETFDT_INSTALL_SUCCEEDED #language en-US "Installation of\r\n'%s'\r\ncompleted.\r\n"
+
+#string STR_SETFDT_UPDATING #language en-US "Updating the FDT device path ...\r\n"
+#string STR_SETFDT_UPDATE_SUCCEEDED #language en-US "Update of the FDT device path '%s' completed.\r\n"
+#string STR_SETFDT_UPDATE_DELETED #language en-US "The UEFI variable "Fdt" was deleted.\r\n"
+
+#string STR_SETFDT_INVALID_DEVICE_PATH #language en-US "Invalid device path.\r\n"
+#string STR_SETFDT_INVALID_PATH #language en-US "The EFI Shell or device file path '%s' is invalid.\r\n"
+#string STR_SETFDT_ERROR #language en-US "Error - %r.\r\n"
+#string STR_SETFDT_DEVICE_PATH_LIST #language en-US "FDT device paths :\r\n"
+#string STR_SETFDT_DEVICE_PATH #language en-US "'%s'\r\n"
+
+#string STR_GET_HELP_SETFDT #language en-US ""
+".TH setfdt 0 "Define and/or install a new Flat Device Tree (FDT) for the platform."\r\n"
+".SH NAME\r\n"
+"Define and/or re-install a Flat Device Tree (FDT)\r\n"
+".SH SYNOPSIS\r\n"
+"setfdt [-i] [fdt_path]\r\n"
+".SH OPTIONS\r\n"
+"-i run the FDT installation process\r\n"
+"file_path EFI Shell file path or device path to a FDT\r\n"
+"\r\n"
+".SH DESCRIPTION\r\n"
+"NOTES:\r\n"
+"1. If a valid EFI Shell file path is passed to the command, then the\r\n"
+" command translates the EFI Shell file path into a device path in the\r\n"
+" text form and saves it in the non volatile UEFI variable "Fdt". If\r\n"
+" the path to the FDT is a device path in the text form, it is saved as\r\n"
+" it is in the non volatile UEFI variable "Fdt". The next time the FDT\r\n"
+" installation process is run, it will first try to install the FDT from\r\n"
+" the device path specified by the UEFI variable "Fdt".\r\n"
+" \r\n
+"2. If the option -i is passed to the command, then the FDT installation\r\n"
+" process is run. If a path to the FDT is passed to the command as well,\r\n"
+" the update of the "Fdt" UEFI variable is done first before to launch\r\n"
+" the FDT installation process.\r\n"
+" \r\n
+".SH RETURNVALUES\r\n"
+"SHELL_SUCCESS Operation(s) completed.\r\n"
+"SHELL_ABORTED Operation aborted.\r\n"
+"SHELL_INVALID_PARAMETER Invalid argument(s).\r\n"
+"SHELL_NOT_FOUND Failed to locate a protocol or a file.\r\n"
+"SHELL_UNSUPPORTED Device path not supported.\r\n"
+"SHELL_OUT_OF_RESOURCES A memory allocation failed.\r\n"
+"SHELL_DEVICE ERROR Hardware failure.\r\n"
+"SHELL_ACCESS_DENIED Access to the Fdt UEFI variable for modification denied.\r\n"
+".SH EXAMPLES\r\n"
+"EXAMPLES:\r\n"
+"1. Relaunch the FDT installation process :\r\n"
+" Shell> setfdt -i\r\n"
+" \r\n"
+"2. Set the EFI Shell file path 'fs0:\>fdt.dtb' to be the default path\r\n"
+" to the FDT :\r\n"
+" Shell> setfdt fs0:fdt.dtb\r\n"
+" \r\n"
+"3. Set a TFTP device path to be the default path to the FDT :\r\n"
+" Shell> setfdt MAC(0002f700570b,0x1)/IPv4(192.168.1.1)/fdt.dtb\r\n"
+" where . 00:02:f7:00:57:0b is the MAC address of the network\r\n"
+" interface card to be used. The 'ifconfig -l' EFI Shell\r\n"
+" command allows to get the MAC address of the network\r\n"
+" interface cards.\r\n"
+" . 192.168.1.1 is the address of the TFTP server.\r\n"
+" . fdt.dtb is the file path to the FDT file on the server.\r\n"
+"4. Display the FDT device paths from the highest to the lowest\r\n"
+" priority :\r\n"
+" Shell> setfdt\r\n"
+"5. Delete the "Fdt" UEFI variable :\r\n"
+" Shell> setfdt ""\r\n"
+"\r\n"
+
+#string STR_GET_HELP_DUMPFDT #language en-US ""
+".TH dumpfdt 0 "Dump installed Flat Device Tree (FDT) of the platform."\r\n"
+".SH NAME\r\n"
+"Dump current Flat Device Tree (FDT)\r\n"
+".SH SYNOPSIS\r\n"
+"dumpfdt\r\n"
+"\r\n"
+".SH DESCRIPTION\r\n"
+"\r\n"
diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/README.txt b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/README.txt
new file mode 100644
index 0000000000..fe0ee0ba1b
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/README.txt
@@ -0,0 +1,69 @@
+/** @file
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+ https://spdx.org/licenses
+
+ Copyright (C) 2023 Marvell
+
+ Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+
+**/
+
+The purpose of the FdtPlatformDxe UEFI driver is to install the Flat Device
+Tree (FDT) of the platform the UEFI frimware is running on into the UEFI
+Configuration Table. The FDT is identified within the UEFI Configuration
+Table by the "gFdtTableGuid" GUID defined in "EmbeddedPkg.dec".
+
+Once installed, an UEFI application or OS boot loader can get from the UEFI
+Configuration Table the FDT of the platform from the "gFdtTableGuid" GUID.
+
+The installation is done after each boot at the end of the DXE phase,
+just before the BDS phase. It is done at the end of the DXE phase to be sure
+that all drivers have been dispatched. That way, all UEFI protocols that may
+be needed to retrieve the FDT can be made available. It is done before the BDS
+phase to be able to provide the FDT during that phase.
+
+The present driver tries to retrieve the FDT from the device paths defined in the
+"gEmbeddedTokenSpaceGuid.PcdFdtDevicePaths" PCD. The "PcdFdtDevicePaths" PCD
+contains a list a device paths. The device paths are in the text form and
+separated by semi-colons. The present driver tries the device paths in the order
+it finds them in the "PcdFdtDevicePaths" PCD as long as he did not install
+succesfully a FDT.
+
+The "PcdFdtDevicePaths" PCD is a dynamic PCD that can be modified during the
+DXE phase. This allows for exemple to select the right FDT when a binary is
+intended to run on several platforms and/or variants of a platform.
+
+If the driver manages to download a FDT from one of the device paths mentioned
+above then it installs it in the UEFI Configuration table and the run over the
+device paths is stopped.
+
+For development purposes only, if the feature PCD "gEmbeddedTokenSpaceGuid.
+PcdOverridePlatformFdt" is equal to TRUE, then before to try to install the
+FDT from the device paths listed in the "PcdFdtDevicePaths" PCD, the present
+driver tries to install it using the device path defined by the UEFI variable
+"Fdt". If the variable does not exist or the installation using the device path
+defined by the UEFI variable fails then the installation proceeds as described
+above.
+
+Furthermore and again for development purposes only, if the feature PCD
+"PcdOverridePlatformFdt" is equal to TRUE, the current driver provides the EFI
+Shell command "setfdt" to define the location of the FDT by the mean of an EFI
+Shell file path (like "fs2:\boot\fdt.dtb") or a device path.
+
+If the path passed in to the command is a valid EFI Shell file path, the
+command translates it into the corresponding device path and stores that
+device path in the "Fdt" UEFI variable asking for the variable to be non
+volatile.
+
+If the path passed in to the command is not recognised as a valid EFI
+Shell device path, the command handles it as device path and stored
+in the "Fdt" UEFI variable as it is.
+
+Finally, the "-i" option of the "setfdt" command allows to trigger the FDT
+installation process. The installation process is completed when the command
+returns. The command can be invoked with the "-i" option only and in that
+case the "Fdt" UEFI variable is not updated and the command just runs the
+FDT installation process. If the command is invoked with the "-i" option and
+an EFI Shell file path then first the "Fdt" UEFI variable is updated accordingly
+and then the FDT installation process is run.
diff --git a/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/ShellDumpFdt.c b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/ShellDumpFdt.c
new file mode 100644
index 0000000000..cf570b1576
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtPlatformDxe/ShellDumpFdt.c
@@ -0,0 +1,283 @@
+/** @file
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+ https://spdx.org/licenses
+
+ Copyright (C) 2023 Marvell
+
+ Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+
+**/
+
+#include "FdtPlatform.h"
+
+extern VOID *mFdtBlobBase;
+
+#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
+#define PALIGN(p, a) ((void *)(ALIGN ((unsigned long)(p), (a))))
+#define GET_CELL(p) (p += 4, *((const uint32_t *)(p-4)))
+
+STATIC
+UINTN
+IsPrintableString (
+ IN CONST VOID* data,
+ IN UINTN len
+ )
+{
+ CONST CHAR8 *s = data;
+ CONST CHAR8 *ss;
+
+ // Zero length is not
+ if (len == 0) {
+ return 0;
+ }
+
+ // Must terminate with zero
+ if (s[len - 1] != '\0') {
+ return 0;
+ }
+
+ ss = s;
+ while (*s/* && isprint (*s)*/) {
+ s++;
+ }
+
+ // Not zero, or not done yet
+ if (*s != '\0' || (s + 1 - ss) < len) {
+ return 0;
+ }
+
+ return 1;
+}
+
+STATIC
+VOID
+PrintData (
+ IN CONST CHAR8* data,
+ IN UINTN len
+ )
+{
+ UINTN i;
+ CONST CHAR8 *p = data;
+
+ // No data, don't print
+ if (len == 0)
+ return;
+
+ if (IsPrintableString (data, len)) {
+ Print (L" = \"%a\"", (const char *)data);
+ } else if ((len % 4) == 0) {
+ Print (L" = <");
+ for (i = 0; i < len; i += 4) {
+ Print (L"0x%08x%a", fdt32_to_cpu (GET_CELL (p)), i < (len - 4) ? " " : "");
+ }
+ Print (L">");
+ } else {
+ Print (L" = [");
+ for (i = 0; i < len; i++)
+ Print (L"%02x%a", *p++, i < len - 1 ? " " : "");
+ Print (L"]");
+ }
+}
+
+STATIC
+VOID
+DumpFdt (
+ IN VOID* FdtBlob
+ )
+{
+ struct fdt_header *bph;
+ UINT32 off_dt;
+ UINT32 off_str;
+ CONST CHAR8* p_struct;
+ CONST CHAR8* p_strings;
+ CONST CHAR8* p;
+ CONST CHAR8* s;
+ CONST CHAR8* t;
+ UINT32 tag;
+ UINTN sz;
+ UINTN depth;
+ UINTN shift;
+ UINT32 version;
+
+ {
+ // Can 'memreserve' be printed by below code?
+ INTN num = fdt_num_mem_rsv (FdtBlob);
+ INTN i, err;
+ UINT64 addr = 0, size = 0;
+
+ for (i = 0; i < num; i++) {
+ err = fdt_get_mem_rsv (FdtBlob, i, &addr, &size);
+ if (err) {
+ DEBUG ((DEBUG_ERROR, "Error (%d) : Cannot get memreserve section (%d)\n", err, i));
+ }
+ else {
+ Print (L"/memreserve/ \t0x%lx \t0x%lx;\n", addr, size);
+ }
+ }
+ }
+
+ depth = 0;
+ shift = 4;
+
+ bph = FdtBlob;
+ off_dt = fdt32_to_cpu (bph->off_dt_struct);
+ off_str = fdt32_to_cpu (bph->off_dt_strings);
+ p_struct = (CONST CHAR8*)FdtBlob + off_dt;
+ p_strings = (CONST CHAR8*)FdtBlob + off_str;
+ version = fdt32_to_cpu (bph->version);
+
+ p = p_struct;
+ while ((tag = fdt32_to_cpu (GET_CELL (p))) != FDT_END) {
+ if (tag == FDT_BEGIN_NODE) {
+ s = p;
+ p = PALIGN (p + AsciiStrLen (s) + 1, 4);
+
+ if (*s == '\0')
+ s = "/";
+
+ Print (L"%*s%a {\n", depth * shift, L" ", s);
+
+ depth++;
+ continue;
+ }
+
+ if (tag == FDT_END_NODE) {
+ depth--;
+
+ Print (L"%*s};\n", depth * shift, L" ");
+ continue;
+ }
+
+ if (tag == FDT_NOP) {
+ /* Print (L"%*s// [NOP]\n", depth * shift, L" "); */
+ continue;
+ }
+
+ if (tag != FDT_PROP) {
+ Print (L"%*s ** Unknown tag 0x%08x\n", depth * shift, L" ", tag);
+ break;
+ }
+ sz = fdt32_to_cpu (GET_CELL (p));
+ s = p_strings + fdt32_to_cpu (GET_CELL (p));
+ if (version < 16 && sz >= 8)
+ p = PALIGN (p, 8);
+ t = p;
+
+ p = PALIGN (p + sz, 4);
+
+ Print (L"%*s%a", depth * shift, L" ", s);
+ PrintData (t, sz);
+ Print (L";\n");
+ }
+}
+
+/**
+ This is the shell command "dumpfdt" handler function. This function handles
+ the command when it is invoked in the shell.
+
+ @param[in] This The instance of the
+ EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+ @param[in] SystemTable The pointer to the UEFI system table.
+ @param[in] ShellParameters The parameters associated with the command.
+ @param[in] Shell The instance of the shell protocol used in the
+ context of processing this command.
+
+ @return SHELL_SUCCESS The operation was successful.
+ @return SHELL_ABORTED Operation aborted due to internal error.
+ @return SHELL_NOT_FOUND Failed to locate the Device Tree into the EFI Configuration Table
+ @return SHELL_OUT_OF_RESOURCES A memory allocation failed.
+
+**/
+SHELL_STATUS
+EFIAPI
+ShellDynCmdDumpFdtHandler (
+ IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
+ IN EFI_SHELL_PROTOCOL *Shell
+ )
+{
+ SHELL_STATUS ShellStatus;
+ EFI_STATUS Status;
+ VOID *FdtBlob;
+
+ ShellStatus = SHELL_SUCCESS;
+
+ //
+ // Install the Shell and Shell Parameters Protocols on the driver
+ // image. This is necessary for the initialisation of the Shell
+ // Library to succeed in the next step.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &gImageHandle,
+ &gEfiShellProtocolGuid, Shell,
+ &gEfiShellParametersProtocolGuid, ShellParameters,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return SHELL_ABORTED;
+ }
+
+ //
+ // Initialise the Shell Library as we are going to use it.
+ // Assert that the return code is EFI_SUCCESS as it should.
+ // To anticipate any change is the codes returned by
+ // ShellInitialize(), leave in case of error.
+ //
+ Status = ShellInitialize ();
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return SHELL_ABORTED;
+ }
+
+ if (PcdGetBool (PcdPublishFdt)) {
+ Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &FdtBlob);
+
+ if (EFI_ERROR (Status)) {
+ Print (L"ERROR: Did not find the Fdt Blob.\n");
+ return EfiCodeToShellCode (Status);
+ }
+ } else {
+ FdtBlob = mFdtBlobBase;
+ }
+
+ DumpFdt (FdtBlob);
+
+ gBS->UninstallMultipleProtocolInterfaces (
+ gImageHandle,
+ &gEfiShellProtocolGuid, Shell,
+ &gEfiShellParametersProtocolGuid, ShellParameters,
+ NULL
+ );
+
+ return ShellStatus;
+}
+
+/**
+ This is the shell command "dumpfdt" help handler function. This
+ function returns the formatted help for the "dumpfdt" command.
+ The format matchs that in Appendix B of the revision 2.1 of the
+ UEFI Shell Specification.
+
+ @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+ @param[in] Language The pointer to the language string to use.
+
+ @return CHAR16* Pool allocated help string, must be freed by caller.
+**/
+CHAR16*
+EFIAPI
+ShellDynCmdDumpFdtGetHelp (
+ IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
+ IN CONST CHAR8 *Language
+ )
+{
+ //
+ // This allocates memory. The caller has to free the allocated memory.
+ //
+ return HiiGetString (
+ mFdtPlatformDxeHiiHandle,
+ STRING_TOKEN (STR_GET_HELP_DUMPFDT),
+ Language
+ );
+}
--
2.34.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#112785): https://edk2.groups.io/g/devel/message/112785
Mute This Topic: https://groups.io/mt/103292517/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2023-12-21 0:54 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-21 0:54 [edk2-devel] [edk2-platforms PATCH v2 0/8] Silicon/Marvell/OdysseyPkg: Narinder Dhillon
2023-12-21 0:54 ` [edk2-devel] [edk2-platforms PATCH v2 1/8] Silicon/Marvell: New Marvell Odyssey processor Narinder Dhillon
2024-01-12 11:14 ` Marcin Wojtas via groups.io
2023-12-21 0:54 ` [edk2-devel] [edk2-platforms PATCH v2 2/8] Silicon/Marvell: Odyssey ArmPlatformLib Narinder Dhillon
2024-01-12 11:27 ` Marcin Wojtas via groups.io
2023-12-21 0:54 ` [edk2-devel] [edk2-platforms PATCH v2 3/8] Silicon/Marvell: Odyssey SmcLib Narinder Dhillon
2024-01-12 10:48 ` Marcin Wojtas via groups.io
2023-12-21 0:54 ` [edk2-devel] [edk2-platforms PATCH v2 4/8] Silicon/Marvell: Odyssey watchdog driver Narinder Dhillon
2024-01-12 11:34 ` Marcin Wojtas via groups.io
2024-01-15 20:26 ` Narinder Dhillon
2023-12-21 0:54 ` [edk2-devel] [edk2-platforms PATCH v2 5/8] Silicon/Marvell: RTC driver Narinder Dhillon
2024-01-12 11:44 ` Marcin Wojtas via groups.io
2023-12-21 0:54 ` [edk2-devel] [edk2-platforms PATCH v2 6/8] Silicon/Marvell: Device tree driver Narinder Dhillon
2024-01-12 12:00 ` Marcin Wojtas via groups.io
2024-01-12 12:01 ` Marcin Wojtas via groups.io
2023-12-21 0:54 ` Narinder Dhillon [this message]
2024-01-12 12:18 ` [edk2-devel] [edk2-platforms PATCH v2 7/8] Silicon/Marvell: Driver to dump board configuration Marcin Wojtas via groups.io
2024-01-13 0:58 ` Narinder Dhillon
2023-12-21 0:54 ` [edk2-devel] [edk2-platforms PATCH v2 8/8] Silicon/Marvell: Odyssey project description files Narinder Dhillon
2024-01-12 13:25 ` [edk2-devel] [edk2-platforms PATCH v2 0/8] Silicon/Marvell/OdysseyPkg: Marcin Wojtas via groups.io
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231221005427.13932-8-ndhillon@marvell.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox