]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDriver1CommandsLib/DrvDiag.c
Adding Driver1 profile commands to the UEFI Shell 2.0.
[mirror_edk2.git] / ShellPkg / Library / UefiShellDriver1CommandsLib / DrvDiag.c
1 /** @file
2 Main file for DrvDiag shell Driver1 function.
3
4 Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "UefiShellDriver1CommandsLib.h"
16
17 STATIC CONST EFI_GUID *DiagGuidList[] = {&gEfiDriverDiagnosticsProtocolGuid, &gEfiDriverDiagnostics2ProtocolGuid, NULL};
18 //
19 // We need 1 more item on the list...
20 //
21 typedef enum {
22 TEST_MODE_STANDARD = EfiDriverDiagnosticTypeStandard,
23 TEST_MODE_EXTENDED = EfiDriverDiagnosticTypeExtended,
24 TEST_MODE_MANUFACTURING = EfiDriverDiagnosticTypeManufacturing,
25 TEST_MODE_LIST,
26 TEST_MODE_MAX
27 } DRV_DIAG_TEST_MODE;
28
29 EFI_STATUS
30 EFIAPI
31 DoDiagnostics (
32 IN CONST DRV_DIAG_TEST_MODE Mode,
33 IN CONST CHAR8 *Lang,
34 IN CONST BOOLEAN AllChilds,
35 IN CONST EFI_HANDLE DriverHandle,
36 IN CONST EFI_HANDLE ControllerHandle,
37 IN CONST EFI_HANDLE ChildHandle
38 )
39 {
40 EFI_DRIVER_DIAGNOSTICS_PROTOCOL *DriverDiagnostics;
41 EFI_DRIVER_DIAGNOSTICS2_PROTOCOL *DriverDiagnostics2;
42 EFI_HANDLE *DriverHandleList;
43 EFI_HANDLE *ControllerHandleList;
44 EFI_HANDLE *ChildHandleList;
45 EFI_HANDLE *Walker;
46 UINTN DriverHandleListCount;
47 UINTN ControllerHandleListCount;
48 UINTN ChildHandleListCount;
49 UINTN DriverHandleListLoop;
50 UINTN ControllerHandleListLoop;
51 UINTN ChildHandleListLoop;
52 EFI_STATUS Status;
53 EFI_STATUS Status2;
54 EFI_GUID *ErrorType;
55 UINTN OutBufferSize;
56 CHAR16 *OutBuffer;
57 UINTN HandleIndex1;
58 UINTN HandleIndex2;
59
60 if ((ChildHandle != NULL && AllChilds) || (Mode >= TEST_MODE_MAX)){
61 return (EFI_INVALID_PARAMETER);
62 }
63
64 if (Lang == NULL || AsciiStrLen(Lang) < 3) {
65 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"-l <value>");
66 return (EFI_INVALID_PARAMETER);
67 }
68
69 DriverDiagnostics = NULL;
70 DriverDiagnostics2 = NULL;
71 Status = EFI_SUCCESS;
72 Status2 = EFI_SUCCESS;
73 DriverHandleList = NULL;
74 ControllerHandleList = NULL;
75 ChildHandleList = NULL;
76 OutBuffer = NULL;
77 ErrorType = NULL;
78 DriverHandleListCount = 0;
79 ControllerHandleListCount = 0;
80 ChildHandleListCount = 0;
81
82 if (DriverHandle != NULL) {
83 DriverHandleList = AllocateZeroPool(2*sizeof(EFI_HANDLE));
84 ASSERT(DriverHandleList!=NULL);
85 DriverHandleList[0] = DriverHandle;
86 DriverHandleListCount = 1;
87 } else {
88 DriverHandleList = GetHandleListByProtocolList(DiagGuidList);
89 if (DriverHandleList == NULL) {
90 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVCFG_NONE), gShellDriver1HiiHandle);
91 return (EFI_NOT_FOUND);
92 }
93 for (Walker = DriverHandleList ; Walker != NULL && *Walker != NULL ; DriverHandleListCount++, Walker++);
94 }
95
96 if (ControllerHandle != NULL) {
97 ControllerHandleList = AllocateZeroPool(2*sizeof(EFI_HANDLE));
98 ASSERT(ControllerHandleList!=NULL);
99 ControllerHandleList[0] = ControllerHandle;
100 ControllerHandleListCount = 1;
101 } else {
102 ControllerHandleList = NULL;
103 }
104
105 if (ChildHandle != NULL) {
106 ChildHandleList = AllocateZeroPool(2*sizeof(EFI_HANDLE));
107 ASSERT(ChildHandleList!=NULL);
108 ChildHandleList[0] = ChildHandle;
109 ChildHandleListCount = 1;
110 } else if (AllChilds) {
111 ChildHandleList = NULL;
112 //
113 // This gets handled in the loop below.
114 //
115 } else {
116 ChildHandleList = NULL;
117 }
118
119 for (DriverHandleListLoop = 0
120 ; DriverHandleListLoop < DriverHandleListCount
121 ; DriverHandleListLoop++
122 ){
123 if (ControllerHandle == NULL) {
124 PARSE_HANDLE_DATABASE_DEVICES(DriverHandleList[DriverHandleListLoop], &ControllerHandleListCount, &ControllerHandleList);
125 }
126 for (ControllerHandleListLoop = 0
127 ; ControllerHandleListLoop < ControllerHandleListCount
128 ; ControllerHandleListLoop++
129 ){
130 if (AllChilds) {
131 ASSERT(ChildHandleList == NULL);
132 PARSE_HANDLE_DATABASE_MANAGED_CHILDREN(
133 DriverHandleList[DriverHandleListLoop],
134 ControllerHandleList[ControllerHandleListLoop],
135 &ChildHandleListCount,
136 &ChildHandleList);
137 }
138 for (ChildHandleListLoop = 0
139 ; (ChildHandleListLoop < ChildHandleListCount || ChildHandleList == NULL)
140 ; ChildHandleListLoop++
141 ){
142 if (Mode != TEST_MODE_LIST) {
143 if (Lang[2] == '-') {
144 //
145 // Get the protocol pointer and call the function
146 //
147 Status = gBS->OpenProtocol(
148 DriverHandleList[DriverHandleListLoop],
149 &gEfiDriverDiagnostics2ProtocolGuid,
150 (VOID**)&DriverDiagnostics2,
151 gImageHandle,
152 NULL,
153 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
154 if (!EFI_ERROR(Status)) {
155 Status = DriverDiagnostics2->RunDiagnostics(
156 DriverDiagnostics2,
157 ControllerHandleList[ControllerHandleListLoop],
158 ChildHandleList == NULL?NULL:ChildHandleList[ChildHandleListLoop],
159 (EFI_DRIVER_DIAGNOSTIC_TYPE)Mode,
160 (CHAR8*)Lang,
161 &ErrorType,
162 &OutBufferSize,
163 &OutBuffer);
164 }
165 } else {
166 Status = gBS->OpenProtocol(
167 DriverHandleList[DriverHandleListLoop],
168 &gEfiDriverDiagnosticsProtocolGuid,
169 (VOID**)&DriverDiagnostics,
170 gImageHandle,
171 NULL,
172 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
173 if (!EFI_ERROR(Status)) {
174 Status = DriverDiagnostics->RunDiagnostics(
175 DriverDiagnostics,
176 ControllerHandleList[ControllerHandleListLoop],
177 ChildHandleList == NULL?NULL:ChildHandleList[ChildHandleListLoop],
178 (EFI_DRIVER_DIAGNOSTIC_TYPE)Mode,
179 (CHAR8*)Lang,
180 &ErrorType,
181 &OutBufferSize,
182 &OutBuffer);
183 }
184 }
185 if (EFI_ERROR(Status)) {
186 Status2 = Status;
187 }
188 HandleIndex1 = ConvertHandleToHandleIndex(DriverHandleList[DriverHandleListLoop]);
189 HandleIndex2 = ConvertHandleToHandleIndex(ControllerHandleList[ControllerHandleListLoop]);
190 ShellPrintHiiEx(
191 -1,
192 -1,
193 NULL,
194 STRING_TOKEN (STR_3P_RESULT),
195 gShellDriver1HiiHandle,
196 L"DrvDiag",
197 HandleIndex1,
198 HandleIndex2,
199 ChildHandleList == NULL?0:ConvertHandleToHandleIndex(ChildHandleList[ChildHandleListLoop]),
200 Status);
201 if (OutBuffer!=NULL) {
202 FreePool(OutBuffer);
203 OutBuffer = NULL;
204 }
205 if (ErrorType!=NULL) {
206 FreePool(ErrorType);
207 ErrorType = NULL;
208 }
209 } else {
210 HandleIndex1 = ConvertHandleToHandleIndex(DriverHandleList[DriverHandleListLoop]);
211 HandleIndex2 = ConvertHandleToHandleIndex(ControllerHandleList[ControllerHandleListLoop]);
212 //
213 // Print out the information that this set can be tested
214 //
215 ShellPrintHiiEx(
216 -1,
217 -1,
218 NULL,
219 STRING_TOKEN (STR_DRV_DIAG_ITEM_LINE),
220 gShellDriver1HiiHandle,
221 HandleIndex1,
222 HandleIndex2,
223 ChildHandleList == NULL?0:ConvertHandleToHandleIndex(ChildHandleList[ChildHandleListLoop])
224 );
225 }
226
227 //
228 // If we are doing a single pass with NULL child jump out after a single loop
229 //
230 if (ChildHandleList == NULL) {
231 break;
232 }
233 }
234 if (AllChilds) {
235 SHELL_FREE_NON_NULL(ChildHandleList);
236 ChildHandleList = NULL;
237 ChildHandleListCount = 0;
238 }
239 }
240 if (ControllerHandle == NULL) {
241 SHELL_FREE_NON_NULL(ControllerHandleList);
242 ControllerHandleList = NULL;
243 ControllerHandleListCount = 0;
244 }
245 }
246
247 if (DriverHandleList != NULL) {
248 FreePool(DriverHandleList);
249 }
250 if (ControllerHandleList != NULL) {
251 FreePool(ControllerHandleList);
252 }
253 if (ChildHandleList != NULL) {
254 FreePool(ChildHandleList);
255 }
256 return (Status2);
257 }
258
259
260 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
261 {L"-c", TypeFlag},
262 {L"-s", TypeFlag},
263 {L"-e", TypeFlag},
264 {L"-m", TypeFlag},
265 {L"-l", TypeValue},
266 {NULL, TypeMax}
267 };
268
269 SHELL_STATUS
270 EFIAPI
271 ShellCommandRunDrvDiag (
272 IN EFI_HANDLE ImageHandle,
273 IN EFI_SYSTEM_TABLE *SystemTable
274 )
275 {
276 EFI_STATUS Status;
277 LIST_ENTRY *Package;
278 CHAR16 *ProblemParam;
279 SHELL_STATUS ShellStatus;
280 DRV_DIAG_TEST_MODE Mode;
281 CHAR8 *Language;
282 CONST CHAR16 *DriverHandleStr;
283 CONST CHAR16 *ControllerHandleStr;
284 CONST CHAR16 *ChildHandleStr;
285 CONST CHAR16 *Lang;
286 EFI_HANDLE Handle1;
287 EFI_HANDLE Handle2;
288 EFI_HANDLE Handle3;
289
290 ShellStatus = SHELL_SUCCESS;
291 Mode = TEST_MODE_MAX;
292 Language = NULL;
293
294 //
295 // initialize the shell lib (we must be in non-auto-init...)
296 //
297 Status = ShellInitialize();
298 ASSERT_EFI_ERROR(Status);
299
300 Status = CommandInit();
301 ASSERT_EFI_ERROR(Status);
302
303 //
304 // parse the command line
305 //
306 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
307 if (EFI_ERROR(Status)) {
308 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
309 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, ProblemParam);
310 FreePool(ProblemParam);
311 ShellStatus = SHELL_INVALID_PARAMETER;
312 } else {
313 ASSERT(FALSE);
314 }
315 } else {
316 //
317 // if more than 3 'value' parameters (plus the name one) or we have any 2 mode flags
318 //
319 if ((ShellCommandLineGetCount(Package) > 4)
320 ||(ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-e"))
321 ||(ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-m"))
322 ||(ShellCommandLineGetFlag(Package, L"-e") && ShellCommandLineGetFlag(Package, L"-m"))
323 ){
324 //
325 // error for too many parameters
326 //
327 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle);
328 ShellStatus = SHELL_INVALID_PARAMETER;
329 } else if ((ShellCommandLineGetFlag(Package, L"-s"))
330 || (ShellCommandLineGetFlag(Package, L"-e"))
331 || (ShellCommandLineGetFlag(Package, L"-m"))
332 ){
333 //
334 // Run the apropriate test
335 //
336 if (ShellCommandLineGetFlag(Package, L"-s")) {
337 Mode = TEST_MODE_STANDARD;
338 } else if (ShellCommandLineGetFlag(Package, L"-e")) {
339 Mode = TEST_MODE_EXTENDED;
340 } else if (ShellCommandLineGetFlag(Package, L"-m")) {
341 Mode = TEST_MODE_MANUFACTURING;
342 } else {
343 ASSERT(FALSE);
344 }
345 } else {
346 //
347 // Do a listing of what's available to test
348 //
349 Mode = TEST_MODE_LIST;
350 }
351
352 Lang = ShellCommandLineGetValue(Package, L"-l");
353 if (Lang != NULL) {
354 Language = AllocateZeroPool(StrSize(Lang));
355 AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
356 } else if (!ShellCommandLineGetFlag(Package, L"-l")){
357 Language = AllocateZeroPool(10);
358 AsciiSPrint(Language, 10, "en-us");
359 } else {
360 ASSERT(Language == NULL);
361 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"-l");
362 ShellCommandLineFreeVarList (Package);
363 return (SHELL_INVALID_PARAMETER);
364 }
365
366 DriverHandleStr = ShellCommandLineGetRawValue(Package, 1);
367 ControllerHandleStr = ShellCommandLineGetRawValue(Package, 2);
368 ChildHandleStr = ShellCommandLineGetRawValue(Package, 3);
369
370 if (DriverHandleStr == NULL) {
371 Handle1 = NULL;
372 } else {
373 Handle1 = ConvertHandleIndexToHandle(StrHexToUintn(DriverHandleStr ));
374 }
375 if (ControllerHandleStr == NULL) {
376 Handle2 = NULL;
377 } else {
378 Handle2 = ConvertHandleIndexToHandle(StrHexToUintn(ControllerHandleStr));
379 }
380 if (ChildHandleStr == NULL) {
381 Handle3 = NULL;
382 } else {
383 Handle3 = ConvertHandleIndexToHandle(StrHexToUintn(ChildHandleStr ));
384 }
385
386 Status = DoDiagnostics (
387 Mode,
388 Language,
389 ShellCommandLineGetFlag(Package, L"-c"),
390 Handle1,
391 Handle2,
392 Handle3
393 );
394
395 SHELL_FREE_NON_NULL(Language);
396 ShellCommandLineFreeVarList (Package);
397
398 }
399 if (ShellStatus == SHELL_SUCCESS) {
400 if (Status == EFI_SECURITY_VIOLATION) {
401 ShellStatus = SHELL_SECURITY_VIOLATION;
402 } else if (Status == EFI_INVALID_PARAMETER) {
403 ShellStatus = SHELL_INVALID_PARAMETER;
404 } else if (Status == EFI_NOT_FOUND) {
405 ShellStatus = SHELL_NOT_FOUND;
406 } else if (EFI_ERROR(Status)) {
407 ShellStatus = SHELL_NOT_FOUND;
408 }
409 }
410
411 return (ShellStatus);
412 }