]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDriver1CommandsLib/Devices.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Library / UefiShellDriver1CommandsLib / Devices.c
1 /** @file
2 Main file for devices shell Driver1 function.
3
4 (C) Copyright 2012-2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "UefiShellDriver1CommandsLib.h"
11
12 /**
13 Get lots of info about a device from its handle.
14
15 @param[in] TheHandle The device handle to get info on.
16 @param[in, out] Type On successful return R, B, or D (root, bus, or
17 device) will be placed in this buffer.
18 @param[in, out] Cfg On successful return this buffer will be
19 TRUE if the handle has configuration, FALSE
20 otherwise.
21 @param[in, out] Diag On successful return this buffer will be
22 TRUE if the handle has disgnostics, FALSE
23 otherwise.
24 @param[in, out] Parents On successful return this buffer will be
25 contain the number of parent handles.
26 @param[in, out] Devices On successful return this buffer will be
27 contain the number of devices controlled.
28 @param[in, out] Children On successful return this buffer will be
29 contain the number of child handles.
30 @param[out] Name The pointer to a buffer that will be allocated
31 and contain the string name of the handle.
32 The caller must free this memory.
33 @param[in] Language The language code as defined by the UEFI spec.
34
35 @retval EFI_SUCCESS The info is there.
36 @retval EFI_INVALID_PARAMETER A parameter was invalid.
37 **/
38 EFI_STATUS
39 GetDeviceHandleInfo (
40 IN EFI_HANDLE TheHandle,
41 IN OUT CHAR16 *Type,
42 IN OUT BOOLEAN *Cfg,
43 IN OUT BOOLEAN *Diag,
44 IN OUT UINTN *Parents,
45 IN OUT UINTN *Devices,
46 IN OUT UINTN *Children,
47 OUT CHAR16 **Name,
48 IN CONST CHAR8 *Language
49 )
50 {
51 EFI_STATUS Status;
52 EFI_HANDLE *HandleBuffer;
53 UINTN Count;
54
55 if ( (TheHandle == NULL)
56 || (Type == NULL)
57 || (Cfg == NULL)
58 || (Diag == NULL)
59 || (Parents == NULL)
60 || (Devices == NULL)
61 || (Children == NULL)
62 || (Name == NULL))
63 {
64 return (EFI_INVALID_PARAMETER);
65 }
66
67 *Cfg = FALSE;
68 *Diag = FALSE;
69 *Children = 0;
70 *Parents = 0;
71 *Devices = 0;
72 *Type = L' ';
73 *Name = CHAR_NULL;
74 HandleBuffer = NULL;
75 Status = EFI_SUCCESS;
76
77 gEfiShellProtocol->GetDeviceName (TheHandle, EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8 *)Language, Name);
78
79 Status = ParseHandleDatabaseForChildControllers (TheHandle, Children, NULL);
80 // if (!EFI_ERROR(Status)) {
81 Status = PARSE_HANDLE_DATABASE_PARENTS (TheHandle, Parents, NULL);
82 if (/*!EFI_ERROR(Status) && */ (Parents != NULL) && (Children != NULL)) {
83 if (*Parents == 0) {
84 *Type = L'R';
85 } else if (*Children > 0) {
86 *Type = L'B';
87 } else {
88 *Type = L'D';
89 }
90 }
91
92 // }
93 Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (TheHandle, Devices, &HandleBuffer);
94 if (!EFI_ERROR (Status) && (Devices != NULL) && (HandleBuffer != NULL)) {
95 for (Count = 0; Count < *Devices; Count++) {
96 if (!EFI_ERROR (gBS->OpenProtocol (HandleBuffer[Count], &gEfiDriverConfigurationProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
97 *Cfg = TRUE;
98 }
99
100 if (!EFI_ERROR (gBS->OpenProtocol (HandleBuffer[Count], &gEfiDriverDiagnosticsProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
101 *Diag = TRUE;
102 }
103
104 if (!EFI_ERROR (gBS->OpenProtocol (HandleBuffer[Count], &gEfiDriverDiagnostics2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
105 *Diag = TRUE;
106 }
107 }
108
109 SHELL_FREE_NON_NULL (HandleBuffer);
110 }
111
112 return (Status);
113 }
114
115 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
116 { L"-sfo", TypeFlag },
117 { L"-l", TypeValue },
118 { NULL, TypeMax }
119 };
120
121 /**
122 Function for 'devices' command.
123
124 @param[in] ImageHandle Handle to the Image (NULL if Internal).
125 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
126 **/
127 SHELL_STATUS
128 EFIAPI
129 ShellCommandRunDevices (
130 IN EFI_HANDLE ImageHandle,
131 IN EFI_SYSTEM_TABLE *SystemTable
132 )
133 {
134 EFI_STATUS Status;
135 LIST_ENTRY *Package;
136 CHAR16 *ProblemParam;
137 SHELL_STATUS ShellStatus;
138 CHAR8 *Language;
139 EFI_HANDLE *HandleList;
140 EFI_HANDLE *HandleListWalker;
141 CHAR16 Type;
142 BOOLEAN Cfg;
143 BOOLEAN Diag;
144 UINTN Parents;
145 UINTN Devices;
146 UINTN Children;
147 CHAR16 *Name;
148 CONST CHAR16 *Lang;
149 BOOLEAN SfoFlag;
150
151 ShellStatus = SHELL_SUCCESS;
152 Language = NULL;
153 SfoFlag = FALSE;
154
155 //
156 // initialize the shell lib (we must be in non-auto-init...)
157 //
158 Status = ShellInitialize ();
159 ASSERT_EFI_ERROR (Status);
160
161 Status = CommandInit ();
162 ASSERT_EFI_ERROR (Status);
163
164 //
165 // parse the command line
166 //
167 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
168 if (EFI_ERROR (Status)) {
169 if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
170 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"devices", ProblemParam);
171 FreePool (ProblemParam);
172 ShellStatus = SHELL_INVALID_PARAMETER;
173 } else {
174 ASSERT (FALSE);
175 }
176 } else {
177 //
178 // if more than 0 'value' parameters we have too many parameters
179 //
180 if (ShellCommandLineGetRawValue (Package, 1) != NULL) {
181 //
182 // error for too many parameters
183 //
184 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"devices");
185 ShellStatus = SHELL_INVALID_PARAMETER;
186 } else {
187 //
188 // get the language if necessary
189 //
190 Lang = ShellCommandLineGetValue (Package, L"-l");
191 if (Lang != NULL) {
192 Language = AllocateZeroPool (StrSize (Lang));
193 AsciiSPrint (Language, StrSize (Lang), "%S", Lang);
194 } else if (!ShellCommandLineGetFlag (Package, L"-l")) {
195 ASSERT (Language == NULL);
196 // Language = AllocateZeroPool(10);
197 // AsciiSPrint(Language, 10, "en-us");
198 } else {
199 ASSERT (Language == NULL);
200 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"devices", L"-l");
201 ShellCommandLineFreeVarList (Package);
202 return (SHELL_INVALID_PARAMETER);
203 }
204
205 //
206 // Print Header
207
208 //
209 if (ShellCommandLineGetFlag (Package, L"-sfo")) {
210 ShellPrintHiiEx (-1, -1, Language, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellDriver1HiiHandle, L"devices");
211 SfoFlag = TRUE;
212 } else {
213 ShellPrintHiiEx (-1, -1, Language, STRING_TOKEN (STR_DEVICES_HEADER_LINES), gShellDriver1HiiHandle);
214 }
215
216 //
217 // loop through each handle
218 //
219 HandleList = GetHandleListByProtocol (NULL);
220 ASSERT (HandleList != NULL);
221 for (HandleListWalker = HandleList
222 ; HandleListWalker != NULL && *HandleListWalker != NULL /*&& !EFI_ERROR(Status)*/
223 ; HandleListWalker++
224 )
225 {
226 //
227 // get all the info on each handle
228 //
229 Name = NULL;
230 Status = GetDeviceHandleInfo (*HandleListWalker, &Type, &Cfg, &Diag, &Parents, &Devices, &Children, &Name, Language);
231 if ((Name != NULL) && ((Parents != 0) || (Devices != 0) || (Children != 0))) {
232 ShellPrintHiiEx (
233 -1,
234 -1,
235 Language,
236 SfoFlag ? STRING_TOKEN (STR_DEVICES_ITEM_LINE_SFO) : STRING_TOKEN (STR_DEVICES_ITEM_LINE),
237 gShellDriver1HiiHandle,
238 ConvertHandleToHandleIndex (*HandleListWalker),
239 Type,
240 Cfg ? (SfoFlag ? L'Y' : L'X') : (SfoFlag ? L'N' : L'-'),
241 Diag ? (SfoFlag ? L'Y' : L'X') : (SfoFlag ? L'N' : L'-'),
242 Parents,
243 Devices,
244 Children,
245 Name != NULL ? Name : L"<UNKNOWN>"
246 );
247 }
248
249 if (Name != NULL) {
250 FreePool (Name);
251 }
252
253 if (ShellGetExecutionBreakFlag ()) {
254 ShellStatus = SHELL_ABORTED;
255 break;
256 }
257 }
258
259 if (HandleList != NULL) {
260 FreePool (HandleList);
261 }
262 }
263
264 SHELL_FREE_NON_NULL (Language);
265 ShellCommandLineFreeVarList (Package);
266 }
267
268 return (ShellStatus);
269 }