]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDriver1CommandsLib/DrvDiag.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Library / UefiShellDriver1CommandsLib / DrvDiag.c
1 /** @file
2 Main file for DrvDiag shell Driver1 function.
3
4 (C) Copyright 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 STATIC CONST EFI_GUID *DiagGuidList[] = { &gEfiDriverDiagnosticsProtocolGuid, &gEfiDriverDiagnostics2ProtocolGuid, NULL };
13 //
14 // We need 1 more item on the list...
15 //
16 typedef enum {
17 TestModeStandard = EfiDriverDiagnosticTypeStandard,
18 TestModeExtended = EfiDriverDiagnosticTypeExtended,
19 TestModeManufacturing = EfiDriverDiagnosticTypeManufacturing,
20 TestModeList,
21 TestModeMax
22 } DRV_DIAG_TEST_MODE;
23
24 /**
25 Do the diagnostics call for some set of handles.
26
27 @param[in] Mode The type of diagnostic test to run.
28 @param[in] Lang The language code to use.
29 @param[in] AllChilds Should the test be on all children.
30 @param[in] DriverHandle The driver handle to test with.
31 @param[in] ControllerHandle The specific controller handle to test.
32 @param[in] ChildHandle The specific child handle to test.
33
34 @retval EFI_SUCCESS The operation was successful.
35 @retval EFI_INVALID_PARAMETER A parameter had an invalid value.
36 @retval EFI_NOT_FOUND No diagnostic handle could be found.
37 **/
38 EFI_STATUS
39 DoDiagnostics (
40 IN CONST DRV_DIAG_TEST_MODE Mode,
41 IN CONST CHAR8 *Lang,
42 IN CONST BOOLEAN AllChilds,
43 IN CONST EFI_HANDLE DriverHandle,
44 IN CONST EFI_HANDLE ControllerHandle,
45 IN CONST EFI_HANDLE ChildHandle
46 )
47 {
48 EFI_DRIVER_DIAGNOSTICS_PROTOCOL *DriverDiagnostics;
49 EFI_DRIVER_DIAGNOSTICS2_PROTOCOL *DriverDiagnostics2;
50 EFI_HANDLE *DriverHandleList;
51 EFI_HANDLE *ControllerHandleList;
52 EFI_HANDLE *ChildHandleList;
53 EFI_HANDLE *Walker;
54 UINTN DriverHandleListCount;
55 UINTN ControllerHandleListCount;
56 UINTN ChildHandleListCount;
57 UINTN DriverHandleListLoop;
58 UINTN ControllerHandleListLoop;
59 UINTN ChildHandleListLoop;
60 EFI_STATUS Status;
61 EFI_STATUS Status2;
62 EFI_GUID *ErrorType;
63 UINTN OutBufferSize;
64 CHAR16 *OutBuffer;
65 UINTN HandleIndex1;
66 UINTN HandleIndex2;
67 CHAR8 *Language;
68 BOOLEAN Found;
69
70 if (((ChildHandle != NULL) && AllChilds) || (Mode >= TestModeMax)) {
71 return (EFI_INVALID_PARAMETER);
72 }
73
74 DriverDiagnostics = NULL;
75 DriverDiagnostics2 = NULL;
76 Status = EFI_SUCCESS;
77 Status2 = EFI_SUCCESS;
78 DriverHandleList = NULL;
79 ControllerHandleList = NULL;
80 ChildHandleList = NULL;
81 Language = NULL;
82 OutBuffer = NULL;
83 ErrorType = NULL;
84 DriverHandleListCount = 0;
85 ControllerHandleListCount = 0;
86 ChildHandleListCount = 0;
87
88 if (DriverHandle != NULL) {
89 DriverHandleList = AllocateZeroPool (2*sizeof (EFI_HANDLE));
90 if (DriverHandleList == NULL) {
91 return EFI_OUT_OF_RESOURCES;
92 }
93
94 DriverHandleList[0] = DriverHandle;
95 DriverHandleListCount = 1;
96 } else {
97 DriverHandleList = GetHandleListByProtocolList (DiagGuidList);
98 if (DriverHandleList == NULL) {
99 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROTOCOL_NF), gShellDriver1HiiHandle, L"drvdiag", L"gEfiDriverDiagnosticsProtocolGuid", &gEfiDriverDiagnosticsProtocolGuid);
100 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROTOCOL_NF), gShellDriver1HiiHandle, L"drvdiag", L"gEfiDriverDiagnostics2ProtocolGuid", &gEfiDriverDiagnostics2ProtocolGuid);
101 return (EFI_NOT_FOUND);
102 }
103
104 for (Walker = DriverHandleList; Walker != NULL && *Walker != NULL; DriverHandleListCount++, Walker++) {
105 }
106 }
107
108 if (ControllerHandle != NULL) {
109 ControllerHandleList = AllocateZeroPool (2*sizeof (EFI_HANDLE));
110 if (ControllerHandleList == NULL) {
111 SHELL_FREE_NON_NULL (DriverHandleList);
112 return EFI_OUT_OF_RESOURCES;
113 }
114
115 ControllerHandleList[0] = ControllerHandle;
116 ControllerHandleListCount = 1;
117 } else {
118 ControllerHandleList = NULL;
119 }
120
121 if (ChildHandle != NULL) {
122 ChildHandleList = AllocateZeroPool (2*sizeof (EFI_HANDLE));
123 if (ChildHandleList == NULL) {
124 SHELL_FREE_NON_NULL (ControllerHandleList);
125 SHELL_FREE_NON_NULL (DriverHandleList);
126 return EFI_OUT_OF_RESOURCES;
127 }
128
129 ChildHandleList[0] = ChildHandle;
130 ChildHandleListCount = 1;
131 } else if (AllChilds) {
132 ChildHandleList = NULL;
133 //
134 // This gets handled in the loop below.
135 //
136 } else {
137 ChildHandleList = NULL;
138 }
139
140 if (Mode == TestModeList) {
141 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVDIAG_HEADER), gShellDriver1HiiHandle);
142 }
143
144 for (DriverHandleListLoop = 0
145 ; DriverHandleListLoop < DriverHandleListCount
146 ; DriverHandleListLoop++
147 )
148 {
149 if (Mode == TestModeList) {
150 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVDIAG_DRIVER_HEADER), gShellDriver1HiiHandle, ConvertHandleToHandleIndex (DriverHandleList[DriverHandleListLoop]));
151 }
152
153 if (ControllerHandle == NULL) {
154 PARSE_HANDLE_DATABASE_DEVICES (DriverHandleList[DriverHandleListLoop], &ControllerHandleListCount, &ControllerHandleList);
155 }
156
157 if (ControllerHandleListCount == 0) {
158 if (Mode == TestModeList) {
159 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVDIAG_DRIVER_NO_HANDLES), gShellDriver1HiiHandle);
160 }
161 } else {
162 if (Mode == TestModeList) {
163 ShellPrintEx (-1, -1, L"\r\n");
164 }
165
166 for (ControllerHandleListLoop = 0
167 ; ControllerHandleListLoop < ControllerHandleListCount
168 ; ControllerHandleListLoop++
169 )
170 {
171 if (AllChilds) {
172 ASSERT (ChildHandleList == NULL);
173 PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
174 DriverHandleList[DriverHandleListLoop],
175 ControllerHandleList[ControllerHandleListLoop],
176 &ChildHandleListCount,
177 &ChildHandleList
178 );
179 }
180
181 for (ChildHandleListLoop = 0
182 ; (ChildHandleListLoop < ChildHandleListCount || ChildHandleList == NULL)
183 ; ChildHandleListLoop++
184 )
185 {
186 Found = FALSE;
187 if (Mode != TestModeList) {
188 if ((Lang == NULL) || (Lang[2] == '-')) {
189 //
190 // Get the protocol pointer and call the function
191 //
192 Status = gBS->OpenProtocol (
193 DriverHandleList[DriverHandleListLoop],
194 &gEfiDriverDiagnostics2ProtocolGuid,
195 (VOID **)&DriverDiagnostics2,
196 gImageHandle,
197 NULL,
198 EFI_OPEN_PROTOCOL_GET_PROTOCOL
199 );
200 if (!EFI_ERROR (Status) && (DriverDiagnostics2 != NULL)) {
201 Language = GetBestLanguageForDriver (DriverDiagnostics2->SupportedLanguages, Lang, FALSE);
202 Found = TRUE;
203 Status = DriverDiagnostics2->RunDiagnostics (
204 DriverDiagnostics2,
205 ControllerHandleList[ControllerHandleListLoop],
206 ChildHandleList == NULL ? NULL : ChildHandleList[ChildHandleListLoop],
207 (EFI_DRIVER_DIAGNOSTIC_TYPE)Mode,
208 Language,
209 &ErrorType,
210 &OutBufferSize,
211 &OutBuffer
212 );
213 FreePool (Language);
214 }
215 }
216
217 if (!Found && ((Lang == NULL) || ((Lang != NULL) && (Lang[2] != '-')))) {
218 Status = gBS->OpenProtocol (
219 DriverHandleList[DriverHandleListLoop],
220 &gEfiDriverDiagnosticsProtocolGuid,
221 (VOID **)&DriverDiagnostics,
222 gImageHandle,
223 NULL,
224 EFI_OPEN_PROTOCOL_GET_PROTOCOL
225 );
226 if (!EFI_ERROR (Status)) {
227 Language = GetBestLanguageForDriver (DriverDiagnostics->SupportedLanguages, Lang, FALSE);
228 Status = DriverDiagnostics->RunDiagnostics (
229 DriverDiagnostics,
230 ControllerHandleList[ControllerHandleListLoop],
231 ChildHandleList == NULL ? NULL : ChildHandleList[ChildHandleListLoop],
232 (EFI_DRIVER_DIAGNOSTIC_TYPE)Mode,
233 Language,
234 &ErrorType,
235 &OutBufferSize,
236 &OutBuffer
237 );
238 FreePool (Language);
239 }
240 }
241
242 if (EFI_ERROR (Status)) {
243 Status2 = Status;
244 }
245
246 HandleIndex1 = ConvertHandleToHandleIndex (DriverHandleList[DriverHandleListLoop]);
247 HandleIndex2 = ConvertHandleToHandleIndex (ControllerHandleList[ControllerHandleListLoop]);
248 ShellPrintHiiEx (
249 -1,
250 -1,
251 NULL,
252 STRING_TOKEN (STR_3P_RESULT),
253 gShellDriver1HiiHandle,
254 L"DrvDiag",
255 HandleIndex1,
256 HandleIndex2,
257 ChildHandleList == NULL ? 0 : ConvertHandleToHandleIndex (ChildHandleList[ChildHandleListLoop]),
258 Status
259 );
260 if (OutBuffer != NULL) {
261 FreePool (OutBuffer);
262 OutBuffer = NULL;
263 }
264
265 if (ErrorType != NULL) {
266 FreePool (ErrorType);
267 ErrorType = NULL;
268 }
269 } else {
270 HandleIndex1 = ConvertHandleToHandleIndex (DriverHandleList[DriverHandleListLoop]);
271 HandleIndex2 = ConvertHandleToHandleIndex (ControllerHandleList[ControllerHandleListLoop]);
272 //
273 // Print out the information that this set can be tested
274 //
275 ShellPrintHiiEx (
276 -1,
277 -1,
278 NULL,
279 STRING_TOKEN (STR_DRV_DIAG_ITEM_LINE),
280 gShellDriver1HiiHandle,
281 HandleIndex1,
282 HandleIndex2,
283 ChildHandleList == NULL ? 0 : ConvertHandleToHandleIndex (ChildHandleList[ChildHandleListLoop])
284 );
285 }
286
287 //
288 // If we are doing a single pass with NULL child jump out after a single loop
289 //
290 if (ChildHandleList == NULL) {
291 break;
292 }
293 }
294
295 if (AllChilds) {
296 SHELL_FREE_NON_NULL (ChildHandleList);
297 ChildHandleList = NULL;
298 ChildHandleListCount = 0;
299 }
300 }
301
302 if (ControllerHandle == NULL) {
303 SHELL_FREE_NON_NULL (ControllerHandleList);
304 ControllerHandleList = NULL;
305 ControllerHandleListCount = 0;
306 }
307 }
308 }
309
310 if (DriverHandleList != NULL) {
311 FreePool (DriverHandleList);
312 }
313
314 if (ControllerHandleList != NULL) {
315 FreePool (ControllerHandleList);
316 }
317
318 if (ChildHandleList != NULL) {
319 FreePool (ChildHandleList);
320 }
321
322 return (Status2);
323 }
324
325 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
326 { L"-c", TypeFlag },
327 { L"-s", TypeFlag },
328 { L"-e", TypeFlag },
329 { L"-m", TypeFlag },
330 { L"-l", TypeValue },
331 { NULL, TypeMax }
332 };
333
334 /**
335 Function for 'drvdiag' command.
336
337 @param[in] ImageHandle Handle to the Image (NULL if Internal).
338 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
339 **/
340 SHELL_STATUS
341 EFIAPI
342 ShellCommandRunDrvDiag (
343 IN EFI_HANDLE ImageHandle,
344 IN EFI_SYSTEM_TABLE *SystemTable
345 )
346 {
347 EFI_STATUS Status;
348 LIST_ENTRY *Package;
349 CHAR16 *ProblemParam;
350 SHELL_STATUS ShellStatus;
351 DRV_DIAG_TEST_MODE Mode;
352 CHAR8 *Language;
353 CONST CHAR16 *DriverHandleStr;
354 CONST CHAR16 *ControllerHandleStr;
355 CONST CHAR16 *ChildHandleStr;
356 CONST CHAR16 *Lang;
357 EFI_HANDLE Handle1;
358 EFI_HANDLE Handle2;
359 EFI_HANDLE Handle3;
360 UINT64 Intermediate;
361
362 ShellStatus = SHELL_SUCCESS;
363 Mode = TestModeMax;
364 Language = NULL;
365
366 //
367 // initialize the shell lib (we must be in non-auto-init...)
368 //
369 Status = ShellInitialize ();
370 ASSERT_EFI_ERROR (Status);
371
372 Status = CommandInit ();
373 ASSERT_EFI_ERROR (Status);
374
375 //
376 // parse the command line
377 //
378 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
379 if (EFI_ERROR (Status)) {
380 if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
381 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"drvdiag", ProblemParam);
382 FreePool (ProblemParam);
383 ShellStatus = SHELL_INVALID_PARAMETER;
384 } else {
385 ASSERT (FALSE);
386 }
387 } else {
388 //
389 // if more than 3 'value' parameters (plus the name one) or we have any 2 mode flags
390 //
391 if ( (ShellCommandLineGetCount (Package) > 4)
392 || (ShellCommandLineGetFlag (Package, L"-s") && ShellCommandLineGetFlag (Package, L"-e"))
393 || (ShellCommandLineGetFlag (Package, L"-s") && ShellCommandLineGetFlag (Package, L"-m"))
394 || (ShellCommandLineGetFlag (Package, L"-e") && ShellCommandLineGetFlag (Package, L"-m"))
395 )
396 {
397 //
398 // error for too many parameters
399 //
400 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"drvdiag");
401 ShellStatus = SHELL_INVALID_PARAMETER;
402 } else if ( (ShellCommandLineGetFlag (Package, L"-s"))
403 || (ShellCommandLineGetFlag (Package, L"-e"))
404 || (ShellCommandLineGetFlag (Package, L"-m"))
405 )
406 {
407 //
408 // Run the appropriate test
409 //
410 if (ShellCommandLineGetFlag (Package, L"-s")) {
411 Mode = TestModeStandard;
412 } else if (ShellCommandLineGetFlag (Package, L"-e")) {
413 Mode = TestModeExtended;
414 } else if (ShellCommandLineGetFlag (Package, L"-m")) {
415 Mode = TestModeManufacturing;
416 } else {
417 ASSERT (FALSE);
418 }
419 } else {
420 //
421 // Do a listing of what's available to test
422 //
423 Mode = TestModeList;
424 }
425
426 Lang = ShellCommandLineGetValue (Package, L"-l");
427 if (ShellCommandLineGetFlag (Package, L"-l") && (Lang == NULL)) {
428 ASSERT (Language == NULL);
429 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvdiag", L"-l");
430 ShellCommandLineFreeVarList (Package);
431 return (SHELL_INVALID_PARAMETER);
432 } else if (Lang != NULL) {
433 Language = AllocateZeroPool (StrSize (Lang));
434 AsciiSPrint (Language, StrSize (Lang), "%S", Lang);
435 }
436
437 DriverHandleStr = ShellCommandLineGetRawValue (Package, 1);
438 ControllerHandleStr = ShellCommandLineGetRawValue (Package, 2);
439 ChildHandleStr = ShellCommandLineGetRawValue (Package, 3);
440
441 if (DriverHandleStr == NULL) {
442 Handle1 = NULL;
443 } else {
444 ShellConvertStringToUint64 (DriverHandleStr, &Intermediate, TRUE, FALSE);
445 Handle1 = ConvertHandleIndexToHandle ((UINTN)Intermediate);
446 }
447
448 if (ControllerHandleStr == NULL) {
449 Handle2 = NULL;
450 } else {
451 ShellConvertStringToUint64 (ControllerHandleStr, &Intermediate, TRUE, FALSE);
452 Handle2 = ConvertHandleIndexToHandle ((UINTN)Intermediate);
453 }
454
455 if (ChildHandleStr == NULL) {
456 Handle3 = NULL;
457 } else {
458 ShellConvertStringToUint64 (ChildHandleStr, &Intermediate, TRUE, FALSE);
459 Handle3 = ConvertHandleIndexToHandle ((UINTN)Intermediate);
460 }
461
462 Status = DoDiagnostics (
463 Mode,
464 Language,
465 ShellCommandLineGetFlag (Package, L"-c"),
466 Handle1,
467 Handle2,
468 Handle3
469 );
470
471 SHELL_FREE_NON_NULL (Language);
472 ShellCommandLineFreeVarList (Package);
473 }
474
475 if (ShellStatus == SHELL_SUCCESS) {
476 if (Status == EFI_SECURITY_VIOLATION) {
477 ShellStatus = SHELL_SECURITY_VIOLATION;
478 } else if (Status == EFI_INVALID_PARAMETER) {
479 ShellStatus = SHELL_INVALID_PARAMETER;
480 } else if (Status == EFI_NOT_FOUND) {
481 ShellStatus = SHELL_NOT_FOUND;
482 } else if (EFI_ERROR (Status)) {
483 ShellStatus = SHELL_NOT_FOUND;
484 }
485 }
486
487 return (ShellStatus);
488 }