TianoCore EDK2 master
Loading...
Searching...
No Matches
DrvDiag.c
Go to the documentation of this file.
1
11
12STATIC CONST EFI_GUID *DiagGuidList[] = { &gEfiDriverDiagnosticsProtocolGuid, &gEfiDriverDiagnostics2ProtocolGuid, NULL };
13//
14// We need 1 more item on the list...
15//
16typedef enum {
17 TestModeStandard = EfiDriverDiagnosticTypeStandard,
18 TestModeExtended = EfiDriverDiagnosticTypeExtended,
19 TestModeManufacturing = EfiDriverDiagnosticTypeManufacturing,
20 TestModeList,
21 TestModeMax
22} DRV_DIAG_TEST_MODE;
23
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 Status2 = EFI_OUT_OF_RESOURCES;
112 goto Done;
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 Status2 = EFI_OUT_OF_RESOURCES;
125 goto Done;
126 }
127
128 ChildHandleList[0] = ChildHandle;
129 ChildHandleListCount = 1;
130 } else if (AllChilds) {
131 ChildHandleList = NULL;
132 //
133 // This gets handled in the loop below.
134 //
135 } else {
136 ChildHandleList = NULL;
137 }
138
139 if (Mode == TestModeList) {
140 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVDIAG_HEADER), gShellDriver1HiiHandle);
141 }
142
143 for (DriverHandleListLoop = 0
144 ; DriverHandleListLoop < DriverHandleListCount
145 ; DriverHandleListLoop++
146 )
147 {
148 if (Mode == TestModeList) {
149 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVDIAG_DRIVER_HEADER), gShellDriver1HiiHandle, ConvertHandleToHandleIndex (DriverHandleList[DriverHandleListLoop]));
150 }
151
152 if (ControllerHandle == NULL) {
153 PARSE_HANDLE_DATABASE_DEVICES (DriverHandleList[DriverHandleListLoop], &ControllerHandleListCount, &ControllerHandleList);
154 }
155
156 if ((ControllerHandleListCount == 0) || (ControllerHandleList == NULL)) {
157 if (Mode == TestModeList) {
158 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DRVDIAG_DRIVER_NO_HANDLES), gShellDriver1HiiHandle);
159 }
160 } else {
161 if (Mode == TestModeList) {
162 ShellPrintEx (-1, -1, L"\r\n");
163 }
164
165 for (ControllerHandleListLoop = 0
166 ; ControllerHandleListLoop < ControllerHandleListCount
167 ; ControllerHandleListLoop++
168 )
169 {
170 if (AllChilds) {
171 ASSERT (ChildHandleList == NULL);
173 DriverHandleList[DriverHandleListLoop],
174 ControllerHandleList[ControllerHandleListLoop],
175 &ChildHandleListCount,
176 &ChildHandleList
177 );
178 }
179
180 for (ChildHandleListLoop = 0
181 ; (ChildHandleListLoop < ChildHandleListCount || ChildHandleList == NULL)
182 ; ChildHandleListLoop++
183 )
184 {
185 Found = FALSE;
186 if (Mode != TestModeList) {
187 if ((Lang == NULL) || (Lang[2] == '-')) {
188 //
189 // Get the protocol pointer and call the function
190 //
191 Status = gBS->OpenProtocol (
192 DriverHandleList[DriverHandleListLoop],
193 &gEfiDriverDiagnostics2ProtocolGuid,
194 (VOID **)&DriverDiagnostics2,
196 NULL,
197 EFI_OPEN_PROTOCOL_GET_PROTOCOL
198 );
199 if (!EFI_ERROR (Status) && (DriverDiagnostics2 != NULL)) {
200 Language = GetBestLanguageForDriver (DriverDiagnostics2->SupportedLanguages, Lang, FALSE);
201 if (Language == NULL) {
202 Status2 = EFI_NOT_FOUND;
203 goto Done;
204 }
205
206 Found = TRUE;
207 Status = DriverDiagnostics2->RunDiagnostics (
208 DriverDiagnostics2,
209 ControllerHandleList[ControllerHandleListLoop],
210 ChildHandleList == NULL ? NULL : ChildHandleList[ChildHandleListLoop],
212 Language,
213 &ErrorType,
214 &OutBufferSize,
215 &OutBuffer
216 );
217 FreePool (Language);
218 Language = NULL;
219 }
220 }
221
222 if (!Found && ((Lang == NULL) || ((Lang != NULL) && (Lang[2] != '-')))) {
223 Status = gBS->OpenProtocol (
224 DriverHandleList[DriverHandleListLoop],
225 &gEfiDriverDiagnosticsProtocolGuid,
226 (VOID **)&DriverDiagnostics,
228 NULL,
229 EFI_OPEN_PROTOCOL_GET_PROTOCOL
230 );
231 if (!EFI_ERROR (Status)) {
232 Language = GetBestLanguageForDriver (DriverDiagnostics->SupportedLanguages, Lang, FALSE);
233 if (Language == NULL) {
234 Status2 = EFI_NOT_FOUND;
235 goto Done;
236 }
237
238 Status = DriverDiagnostics->RunDiagnostics (
239 DriverDiagnostics,
240 ControllerHandleList[ControllerHandleListLoop],
241 ChildHandleList == NULL ? NULL : ChildHandleList[ChildHandleListLoop],
243 Language,
244 &ErrorType,
245 &OutBufferSize,
246 &OutBuffer
247 );
248 FreePool (Language);
249 Language = NULL;
250 }
251 }
252
253 if (EFI_ERROR (Status)) {
254 Status2 = Status;
255 }
256
257 HandleIndex1 = ConvertHandleToHandleIndex (DriverHandleList[DriverHandleListLoop]);
258 HandleIndex2 = ConvertHandleToHandleIndex (ControllerHandleList[ControllerHandleListLoop]);
260 -1,
261 -1,
262 NULL,
263 STRING_TOKEN (STR_3P_RESULT),
264 gShellDriver1HiiHandle,
265 L"DrvDiag",
266 HandleIndex1,
267 HandleIndex2,
268 ChildHandleList == NULL ? 0 : ConvertHandleToHandleIndex (ChildHandleList[ChildHandleListLoop]),
269 Status
270 );
271 if (OutBuffer != NULL) {
272 FreePool (OutBuffer);
273 OutBuffer = NULL;
274 }
275
276 if (ErrorType != NULL) {
277 FreePool (ErrorType);
278 ErrorType = NULL;
279 }
280 } else {
281 HandleIndex1 = ConvertHandleToHandleIndex (DriverHandleList[DriverHandleListLoop]);
282 HandleIndex2 = ConvertHandleToHandleIndex (ControllerHandleList[ControllerHandleListLoop]);
283 //
284 // Print out the information that this set can be tested
285 //
287 -1,
288 -1,
289 NULL,
290 STRING_TOKEN (STR_DRV_DIAG_ITEM_LINE),
291 gShellDriver1HiiHandle,
292 HandleIndex1,
293 HandleIndex2,
294 ChildHandleList == NULL ? 0 : ConvertHandleToHandleIndex (ChildHandleList[ChildHandleListLoop])
295 );
296 }
297
298 //
299 // If we are doing a single pass with NULL child jump out after a single loop
300 //
301 if (ChildHandleList == NULL) {
302 break;
303 }
304 }
305
306 if (AllChilds) {
307 SHELL_FREE_NON_NULL (ChildHandleList);
308 ChildHandleList = NULL;
309 ChildHandleListCount = 0;
310 }
311 }
312
313 if (ControllerHandle == NULL) {
314 SHELL_FREE_NON_NULL (ControllerHandleList);
315 ControllerHandleList = NULL;
316 ControllerHandleListCount = 0;
317 }
318 }
319 }
320
321Done:
322
323 SHELL_FREE_NON_NULL (DriverHandleList);
324 SHELL_FREE_NON_NULL (ControllerHandleList);
325 SHELL_FREE_NON_NULL (ChildHandleList);
326 SHELL_FREE_NON_NULL (Language);
327 SHELL_FREE_NON_NULL (OutBuffer);
328
329 return (Status2);
330}
331
332STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
333 { L"-c", TypeFlag },
334 { L"-s", TypeFlag },
335 { L"-e", TypeFlag },
336 { L"-m", TypeFlag },
337 { L"-l", TypeValue },
338 { NULL, TypeMax }
339};
340
348EFIAPI
350 IN EFI_HANDLE ImageHandle,
351 IN EFI_SYSTEM_TABLE *SystemTable
352 )
353{
354 EFI_STATUS Status;
355 LIST_ENTRY *Package;
356 CHAR16 *ProblemParam;
357 SHELL_STATUS ShellStatus;
358 DRV_DIAG_TEST_MODE Mode;
359 CHAR8 *Language;
360 CONST CHAR16 *DriverHandleStr;
361 CONST CHAR16 *ControllerHandleStr;
362 CONST CHAR16 *ChildHandleStr;
363 CONST CHAR16 *Lang;
364 EFI_HANDLE Handle1;
365 EFI_HANDLE Handle2;
366 EFI_HANDLE Handle3;
367 UINT64 Intermediate;
368
369 ShellStatus = SHELL_SUCCESS;
370 Mode = TestModeMax;
371 Language = NULL;
372
373 //
374 // initialize the shell lib (we must be in non-auto-init...)
375 //
376 Status = ShellInitialize ();
377 ASSERT_EFI_ERROR (Status);
378
379 Status = CommandInit ();
380 ASSERT_EFI_ERROR (Status);
381
382 //
383 // parse the command line
384 //
385 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
386 if (EFI_ERROR (Status)) {
387 if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {
388 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"drvdiag", ProblemParam);
389 FreePool (ProblemParam);
390 ShellStatus = SHELL_INVALID_PARAMETER;
391 } else {
392 ASSERT (FALSE);
393 }
394 } else {
395 //
396 // if more than 3 'value' parameters (plus the name one) or we have any 2 mode flags
397 //
398 if ( (ShellCommandLineGetCount (Package) > 4)
399 || (ShellCommandLineGetFlag (Package, L"-s") && ShellCommandLineGetFlag (Package, L"-e"))
400 || (ShellCommandLineGetFlag (Package, L"-s") && ShellCommandLineGetFlag (Package, L"-m"))
401 || (ShellCommandLineGetFlag (Package, L"-e") && ShellCommandLineGetFlag (Package, L"-m"))
402 )
403 {
404 //
405 // error for too many parameters
406 //
407 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"drvdiag");
408 ShellStatus = SHELL_INVALID_PARAMETER;
409 } else if ( (ShellCommandLineGetFlag (Package, L"-s"))
410 || (ShellCommandLineGetFlag (Package, L"-e"))
411 || (ShellCommandLineGetFlag (Package, L"-m"))
412 )
413 {
414 //
415 // Run the appropriate test
416 //
417 if (ShellCommandLineGetFlag (Package, L"-s")) {
418 Mode = TestModeStandard;
419 } else if (ShellCommandLineGetFlag (Package, L"-e")) {
420 Mode = TestModeExtended;
421 } else if (ShellCommandLineGetFlag (Package, L"-m")) {
422 Mode = TestModeManufacturing;
423 } else {
424 ASSERT (FALSE);
425 }
426 } else {
427 //
428 // Do a listing of what's available to test
429 //
430 Mode = TestModeList;
431 }
432
433 Lang = ShellCommandLineGetValue (Package, L"-l");
434 if (ShellCommandLineGetFlag (Package, L"-l") && (Lang == NULL)) {
435 ASSERT (Language == NULL);
436 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvdiag", L"-l");
439 } else if (Lang != NULL) {
440 Language = AllocateZeroPool (StrSize (Lang));
441 if (Language == NULL) {
442 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDriver1HiiHandle, L"drvdiag");
444 return (SHELL_OUT_OF_RESOURCES);
445 }
446
447 AsciiSPrint (Language, StrSize (Lang), "%S", Lang);
448 }
449
450 DriverHandleStr = ShellCommandLineGetRawValue (Package, 1);
451 ControllerHandleStr = ShellCommandLineGetRawValue (Package, 2);
452 ChildHandleStr = ShellCommandLineGetRawValue (Package, 3);
453
454 if ((DriverHandleStr != NULL) && !EFI_ERROR (ShellConvertStringToUint64 (DriverHandleStr, &Intermediate, TRUE, FALSE))) {
455 Handle1 = ConvertHandleIndexToHandle ((UINTN)Intermediate);
456 } else {
457 Handle1 = NULL;
458 }
459
460 if ((ControllerHandleStr != NULL) && !EFI_ERROR (ShellConvertStringToUint64 (ControllerHandleStr, &Intermediate, TRUE, FALSE))) {
461 Handle2 = ConvertHandleIndexToHandle ((UINTN)Intermediate);
462 } else {
463 Handle2 = NULL;
464 }
465
466 if ((ChildHandleStr != NULL) && !EFI_ERROR (ShellConvertStringToUint64 (ChildHandleStr, &Intermediate, TRUE, FALSE))) {
467 Handle3 = ConvertHandleIndexToHandle ((UINTN)Intermediate);
468 } else {
469 Handle3 = NULL;
470 }
471
472 Status = DoDiagnostics (
473 Mode,
474 Language,
475 ShellCommandLineGetFlag (Package, L"-c"),
476 Handle1,
477 Handle2,
478 Handle3
479 );
480
481 SHELL_FREE_NON_NULL (Language);
483 }
484
485 if (ShellStatus == SHELL_SUCCESS) {
486 if (Status == EFI_SECURITY_VIOLATION) {
487 ShellStatus = SHELL_SECURITY_VIOLATION;
488 } else if (Status == EFI_INVALID_PARAMETER) {
489 ShellStatus = SHELL_INVALID_PARAMETER;
490 } else if (Status == EFI_NOT_FOUND) {
491 ShellStatus = SHELL_NOT_FOUND;
492 } else if (EFI_ERROR (Status)) {
493 ShellStatus = SHELL_NOT_FOUND;
494 }
495 }
496
497 return (ShellStatus);
498}
UINT64 UINTN
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
EFI_DRIVER_DIAGNOSTIC_TYPE
@ EfiDriverDiagnosticTypeExtended
@ EfiDriverDiagnosticTypeManufacturing
@ EfiDriverDiagnosticTypeStandard
SHELL_STATUS EFIAPI ShellCommandRunDrvDiag(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: DrvDiag.c:349
EFI_STATUS DoDiagnostics(IN CONST DRV_DIAG_TEST_MODE Mode, IN CONST CHAR8 *Lang, IN CONST BOOLEAN AllChilds, IN CONST EFI_HANDLE DriverHandle, IN CONST EFI_HANDLE ControllerHandle, IN CONST EFI_HANDLE ChildHandle)
Definition: DrvDiag.c:39
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define PARSE_HANDLE_DATABASE_MANAGED_CHILDREN(DriverHandle, ControllerHandle, Count, Buffer)
CHAR8 *EFIAPI GetBestLanguageForDriver(IN CONST CHAR8 *SupportedLanguages, IN CONST CHAR8 *InputLanguage, IN BOOLEAN Iso639Language)
EFI_HANDLE EFIAPI ConvertHandleIndexToHandle(IN CONST UINTN TheIndex)
#define PARSE_HANDLE_DATABASE_DEVICES(DriverHandle, Count, Buffer)
UINTN EFIAPI ConvertHandleToHandleIndex(IN CONST EFI_HANDLE TheHandle)
EFI_HANDLE *EFIAPI GetHandleListByProtocolList(IN CONST EFI_GUID **ProtocolGuids)
UINTN EFIAPI AsciiSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
Definition: PrintLib.c:813
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
SHELL_STATUS
Definition: Shell.h:21
@ SHELL_OUT_OF_RESOURCES
Definition: Shell.h:73
@ SHELL_SUCCESS
Definition: Shell.h:25
@ SHELL_NOT_FOUND
Definition: Shell.h:101
@ SHELL_SECURITY_VIOLATION
Definition: Shell.h:141
@ SHELL_INVALID_PARAMETER
Definition: Shell.h:35
EFI_STATUS EFIAPI CommandInit(VOID)
CONST CHAR16 *EFIAPI ShellCommandLineGetValue(IN CONST LIST_ENTRY *CheckPackage, IN CHAR16 *KeyString)
#define ShellCommandLineParse(CheckList, CheckPackage, ProblemParam, AutoPageBreak)
Make it easy to upgrade from older versions of the shell library.
Definition: ShellLib.h:755
EFI_STATUS EFIAPI ShellPrintHiiEx(IN INT32 Col OPTIONAL, IN INT32 Row OPTIONAL, IN CONST CHAR8 *Language OPTIONAL, IN CONST EFI_STRING_ID HiiFormatStringId, IN CONST EFI_HII_HANDLE HiiFormatHandle,...)
BOOLEAN EFIAPI ShellCommandLineGetFlag(IN CONST LIST_ENTRY *CONST CheckPackage, IN CONST CHAR16 *CONST KeyString)
@ TypeValue
A flag that has some data following it with a space (IE "-a 1").
Definition: ShellLib.h:700
@ TypeFlag
A flag that is present or not present only (IE "-a").
Definition: ShellLib.h:699
VOID EFIAPI ShellCommandLineFreeVarList(IN LIST_ENTRY *CheckPackage)
EFI_STATUS EFIAPI ShellInitialize(VOID)
Definition: UefiShellLib.c:532
EFI_STATUS EFIAPI ShellPrintEx(IN INT32 Col OPTIONAL, IN INT32 Row OPTIONAL, IN CONST CHAR16 *Format,...)
CONST CHAR16 *EFIAPI ShellCommandLineGetRawValue(IN CONST LIST_ENTRY *CONST CheckPackage, IN UINTN Position)
UINTN EFIAPI ShellCommandLineGetCount(IN CONST LIST_ENTRY *CheckPackage)
EFI_STATUS EFIAPI ShellConvertStringToUint64(IN CONST CHAR16 *String, OUT UINT64 *Value, IN CONST BOOLEAN ForceHex, IN CONST BOOLEAN StopAtSpace)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_HANDLE gImageHandle
EFI_BOOT_SERVICES * gBS
#define STRING_TOKEN(t)
Definition: Base.h:213