DrvDiag.c 17 KB

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