aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/ShellPkg/Library/UefiShellDriver1CommandsLib/DevTree.c
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/edk2/ShellPkg/Library/UefiShellDriver1CommandsLib/DevTree.c
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/edk2/ShellPkg/Library/UefiShellDriver1CommandsLib/DevTree.c')
-rw-r--r--roms/edk2/ShellPkg/Library/UefiShellDriver1CommandsLib/DevTree.c271
1 files changed, 271 insertions, 0 deletions
diff --git a/roms/edk2/ShellPkg/Library/UefiShellDriver1CommandsLib/DevTree.c b/roms/edk2/ShellPkg/Library/UefiShellDriver1CommandsLib/DevTree.c
new file mode 100644
index 000000000..0e6683449
--- /dev/null
+++ b/roms/edk2/ShellPkg/Library/UefiShellDriver1CommandsLib/DevTree.c
@@ -0,0 +1,271 @@
+/** @file
+ Main file for DevTree shell Driver1 function.
+
+ (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
+ Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UefiShellDriver1CommandsLib.h"
+
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
+ {L"-d", TypeFlag},
+ {L"-l", TypeValue},
+ {NULL, TypeMax}
+ };
+
+/**
+ Display a tree starting from this handle.
+
+ @param[in] TheHandle The handle to start with.
+ @param[in] Lang Optionally, a UEFI defined language code.
+ @param[in] UseDevPaths TRUE to display info from DevPath as identifiers.
+ FALSE will use component name protocol instead.
+ @param[in] IndentCharCount How many characters to indent (allows for recursion).
+ @param[in] HiiString The string from HII to use for output.
+
+ @retval SHELL_SUCCESS The operation was successful.
+**/
+SHELL_STATUS
+DoDevTreeForHandle(
+ IN CONST EFI_HANDLE TheHandle,
+ IN CONST CHAR8 *Lang OPTIONAL,
+ IN CONST BOOLEAN UseDevPaths,
+ IN CONST UINTN IndentCharCount,
+ IN CONST CHAR16 *HiiString
+ )
+{
+ SHELL_STATUS ShellStatus;
+ EFI_STATUS Status;
+ CHAR16 *FormatString;
+ CHAR16 *Name;
+ EFI_HANDLE *ChildHandleBuffer;
+ UINTN ChildCount;
+ UINTN LoopVar;
+
+ Status = EFI_SUCCESS;
+ ShellStatus = SHELL_SUCCESS;
+ Name = NULL;
+ ChildHandleBuffer = NULL;
+ ChildCount = 0;
+
+ ASSERT (TheHandle != NULL);
+ ASSERT (HiiString != NULL);
+
+ if (ShellGetExecutionBreakFlag()) {
+ ShellStatus = SHELL_ABORTED;
+ return ShellStatus;
+ }
+
+ //
+ // We want controller handles. they will not have LoadedImage or DriverBinding (or others...)
+ //
+ Status = gBS->OpenProtocol (
+ TheHandle,
+ &gEfiDriverBindingProtocolGuid,
+ NULL,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ return SHELL_SUCCESS;
+ }
+
+ Status = gBS->OpenProtocol (
+ TheHandle,
+ &gEfiLoadedImageProtocolGuid,
+ NULL,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ return SHELL_SUCCESS;
+ }
+
+ FormatString = AllocateZeroPool(StrSize(HiiString) + (10)*sizeof(FormatString[0]));
+ if (FormatString == NULL) {
+ return SHELL_OUT_OF_RESOURCES;
+ }
+
+ //
+ // we generate the format string on the fly so that we can control the
+ // number of space characters that the first (empty) string has. this
+ // handles the indenting.
+ //
+
+ UnicodeSPrint(FormatString, StrSize(HiiString) + (10)*sizeof(FormatString[0]), L"%%%ds %s", IndentCharCount, HiiString);
+ gEfiShellProtocol->GetDeviceName((EFI_HANDLE)TheHandle, !UseDevPaths?EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH:EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Lang, &Name);
+ //
+ // print out the information for ourselves
+ //
+ ShellPrintEx(
+ -1,
+ -1,
+ FormatString,
+ L"",
+ ConvertHandleToHandleIndex(TheHandle),
+ Name==NULL?L"Unknown":Name);
+
+ FreePool(FormatString);
+ if (Name != NULL) {
+ FreePool(Name);
+ }
+
+ //
+ // recurse on each child handle with IndentCharCount + 2
+ //
+ ParseHandleDatabaseForChildControllers(TheHandle, &ChildCount, &ChildHandleBuffer);
+ for (LoopVar = 0 ; LoopVar < ChildCount && ShellStatus == SHELL_SUCCESS; LoopVar++){
+ ShellStatus = DoDevTreeForHandle(ChildHandleBuffer[LoopVar], Lang, UseDevPaths, IndentCharCount+2, HiiString);
+ if (ShellStatus == SHELL_ABORTED) {
+ break;
+ }
+ }
+
+ if (ChildHandleBuffer != NULL) {
+ FreePool(ChildHandleBuffer);
+ }
+
+ return (ShellStatus);
+}
+
+/**
+ Function for 'devtree' command.
+
+ @param[in] ImageHandle Handle to the Image (NULL if Internal).
+ @param[in] SystemTable Pointer to the System Table (NULL if Internal).
+**/
+SHELL_STATUS
+EFIAPI
+ShellCommandRunDevTree (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ LIST_ENTRY *Package;
+ CHAR16 *ProblemParam;
+ SHELL_STATUS ShellStatus;
+ CHAR8 *Language;
+ CONST CHAR16 *Lang;
+ CHAR16 *HiiString;
+ UINTN LoopVar;
+ EFI_HANDLE TheHandle;
+ BOOLEAN FlagD;
+ UINT64 Intermediate;
+ UINTN ParentControllerHandleCount;
+ EFI_HANDLE *ParentControllerHandleBuffer;
+
+ ShellStatus = SHELL_SUCCESS;
+ Status = EFI_SUCCESS;
+ Language = NULL;
+
+ //
+ // initialize the shell lib (we must be in non-auto-init...)
+ //
+ Status = ShellInitialize();
+ ASSERT_EFI_ERROR(Status);
+
+ Status = CommandInit();
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // parse the command line
+ //
+ Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
+ if (EFI_ERROR(Status)) {
+ if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"devtree", ProblemParam);
+ FreePool(ProblemParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ ASSERT(FALSE);
+ }
+ } else {
+ if (ShellCommandLineGetCount(Package) > 2) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"devtree");
+ ShellCommandLineFreeVarList (Package);
+ return (SHELL_INVALID_PARAMETER);
+ }
+ Lang = ShellCommandLineGetValue(Package, L"-l");
+ if (Lang != NULL) {
+ Language = AllocateZeroPool(StrSize(Lang));
+ AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
+ } else if (!ShellCommandLineGetFlag(Package, L"-l")){
+ ASSERT(Language == NULL);
+// Language = AllocateZeroPool(10);
+// AsciiSPrint(Language, 10, "en-us");
+ } else {
+ ASSERT(Language == NULL);
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"devtree", L"-l");
+ ShellCommandLineFreeVarList (Package);
+ return (SHELL_INVALID_PARAMETER);
+ }
+ FlagD = ShellCommandLineGetFlag(Package, L"-d");
+
+ Lang = ShellCommandLineGetRawValue(Package, 1);
+ HiiString = HiiGetString(gShellDriver1HiiHandle, STRING_TOKEN (STR_DEV_TREE_OUTPUT), Language);
+
+ if (Lang == NULL) {
+ for (LoopVar = 1 ; ; LoopVar++){
+ TheHandle = ConvertHandleIndexToHandle(LoopVar);
+ if (TheHandle == NULL){
+ break;
+ }
+
+ //
+ // Skip handles that do not have device path protocol
+ //
+ Status = gBS->OpenProtocol (
+ TheHandle,
+ &gEfiDevicePathProtocolGuid,
+ NULL,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ //
+ // Skip handles that do have parents
+ //
+ ParentControllerHandleBuffer = NULL;
+ Status = PARSE_HANDLE_DATABASE_PARENTS (
+ TheHandle,
+ &ParentControllerHandleCount,
+ &ParentControllerHandleBuffer
+ );
+ SHELL_FREE_NON_NULL (ParentControllerHandleBuffer);
+ if (ParentControllerHandleCount > 0) {
+ continue;
+ }
+
+ //
+ // Start a devtree from TheHandle that has a device path and no parents
+ //
+ ShellStatus = DoDevTreeForHandle(TheHandle, Language, FlagD, 0, HiiString);
+ }
+ } else {
+ Status = ShellConvertStringToUint64(Lang, &Intermediate, TRUE, FALSE);
+ if (EFI_ERROR(Status) || ConvertHandleIndexToHandle((UINTN)Intermediate) == NULL) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"devtree", Lang);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ ShellStatus = DoDevTreeForHandle(ConvertHandleIndexToHandle((UINTN)Intermediate), Language, FlagD, 0, HiiString);
+ }
+ }
+
+ if (HiiString != NULL) {
+ FreePool(HiiString);
+ }
+ SHELL_FREE_NON_NULL(Language);
+ ShellCommandLineFreeVarList (Package);
+ }
+
+ return (ShellStatus);
+}