BdsPlatform.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363
  1. /** @file
  2. This file include all platform action which can be customized by IBV/OEM.
  3. Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
  4. Copyright (c) 2021, American Megatrends International LLC.<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include "BdsPlatform.h"
  8. #include <Guid/EventGroup.h>
  9. #include <Protocol/DxeSmmReadyToLock.h>
  10. #include <Protocol/FirmwareVolume2.h>
  11. #include <Protocol/PciRootBridgeIo.h>
  12. #include <Protocol/BlockIo.h>
  13. #include <Protocol/PciIo.h>
  14. #include <Library/IoLib.h>
  15. #include <Library/PciLib.h>
  16. #include <Guid/EventGroup.h>
  17. #include <Library/Tcg2PhysicalPresenceLib.h>
  18. #include <Library/HobLib.h>
  19. #include <Protocol/UsbIo.h>
  20. #include <Library/UefiBootManagerLib.h>
  21. GLOBAL_REMOVE_IF_UNREFERENCED EFI_BOOT_MODE gBootMode;
  22. BOOLEAN gPPRequireUIConfirm;
  23. extern UINTN mBootMenuOptionNumber;
  24. EFI_STATUS
  25. LinuxBootStart (
  26. VOID
  27. );
  28. GLOBAL_REMOVE_IF_UNREFERENCED USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevicePath = {
  29. {
  30. {
  31. MESSAGING_DEVICE_PATH,
  32. MSG_USB_CLASS_DP,
  33. {
  34. (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)),
  35. (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
  36. }
  37. },
  38. 0xffff, // VendorId
  39. 0xffff, // ProductId
  40. CLASS_HID, // DeviceClass
  41. SUBCLASS_BOOT, // DeviceSubClass
  42. PROTOCOL_KEYBOARD // DeviceProtocol
  43. },
  44. gEndEntire
  45. };
  46. //
  47. // Internal shell mode
  48. //
  49. GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellModeColumn;
  50. GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellModeRow;
  51. GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellHorizontalResolution;
  52. GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellVerticalResolution;
  53. //
  54. // BDS Platform Functions
  55. //
  56. BOOLEAN
  57. IsMorBitSet (
  58. VOID
  59. )
  60. {
  61. UINTN MorControl;
  62. EFI_STATUS Status;
  63. UINTN DataSize;
  64. //
  65. // Check if the MOR bit is set.
  66. //
  67. DataSize = sizeof (MorControl);
  68. Status = gRT->GetVariable (
  69. MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
  70. &gEfiMemoryOverwriteControlDataGuid,
  71. NULL,
  72. &DataSize,
  73. &MorControl
  74. );
  75. if (EFI_ERROR (Status)) {
  76. DEBUG ((DEBUG_INFO, " PlatformBootMangerLib: gEfiMemoryOverwriteControlDataGuid doesn't exist!!***\n"));
  77. MorControl = 0;
  78. } else {
  79. DEBUG ((DEBUG_INFO, " PlatformBootMangerLib: Get the gEfiMemoryOverwriteControlDataGuid = %x!!***\n", MorControl));
  80. }
  81. return (BOOLEAN) (MorControl & 0x01);
  82. }
  83. VOID
  84. DumpDevicePath (
  85. IN CHAR16 *Name,
  86. IN EFI_DEVICE_PATH *DevicePath
  87. )
  88. {
  89. CHAR16 *Str;
  90. Str = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
  91. DEBUG ((DEBUG_INFO, "%s: %s\n", Name, Str));
  92. if (Str != NULL) {
  93. FreePool (Str);
  94. }
  95. }
  96. /**
  97. An empty function to pass error checking of CreateEventEx ().
  98. This empty function ensures that EVT_NOTIFY_SIGNAL_ALL is error
  99. checked correctly since it is now mapped into CreateEventEx() in UEFI 2.0.
  100. @param Event Event whose notification function is being invoked.
  101. @param Context The pointer to the notification function's context,
  102. which is implementation-dependent.
  103. **/
  104. VOID
  105. EFIAPI
  106. InternalBdsEmptyCallbackFuntion (
  107. IN EFI_EVENT Event,
  108. IN VOID *Context
  109. )
  110. {
  111. return;
  112. }
  113. VOID
  114. ExitPmAuth (
  115. VOID
  116. )
  117. {
  118. EFI_HANDLE Handle;
  119. EFI_STATUS Status;
  120. EFI_EVENT EndOfDxeEvent;
  121. DEBUG((DEBUG_INFO,"ExitPmAuth ()- Start\n"));
  122. //
  123. // Prepare S3 information, this MUST be done before ExitPmAuth/EndOfDxe
  124. //
  125. //
  126. // Since PI1.2.1, we need signal EndOfDxe as ExitPmAuth
  127. //
  128. Status = gBS->CreateEventEx (
  129. EVT_NOTIFY_SIGNAL,
  130. TPL_CALLBACK,
  131. InternalBdsEmptyCallbackFuntion,
  132. NULL,
  133. &gEfiEndOfDxeEventGroupGuid,
  134. &EndOfDxeEvent
  135. );
  136. ASSERT_EFI_ERROR (Status);
  137. gBS->SignalEvent (EndOfDxeEvent);
  138. gBS->CloseEvent (EndOfDxeEvent);
  139. DEBUG((DEBUG_INFO,"All EndOfDxe callbacks have returned successfully\n"));
  140. //
  141. // NOTE: We need install DxeSmmReadyToLock directly here because many boot script is added via ExitPmAuth/EndOfDxe callback.
  142. // If we install them at same callback, these boot script will be rejected because BootScript Driver runs first to lock them done.
  143. // So we seperate them to be 2 different events, ExitPmAuth is last chance to let platform add boot script. DxeSmmReadyToLock will
  144. // make boot script save driver lock down the interface.
  145. //
  146. Handle = NULL;
  147. Status = gBS->InstallProtocolInterface (
  148. &Handle,
  149. &gEfiDxeSmmReadyToLockProtocolGuid,
  150. EFI_NATIVE_INTERFACE,
  151. NULL
  152. );
  153. ASSERT_EFI_ERROR (Status);
  154. DEBUG((DEBUG_INFO,"ExitPmAuth ()- End\n"));
  155. }
  156. VOID
  157. ConnectRootBridge (
  158. BOOLEAN Recursive
  159. )
  160. {
  161. UINTN RootBridgeHandleCount;
  162. EFI_HANDLE *RootBridgeHandleBuffer;
  163. UINTN RootBridgeIndex;
  164. RootBridgeHandleCount = 0;
  165. gBS->LocateHandleBuffer (
  166. ByProtocol,
  167. &gEfiPciRootBridgeIoProtocolGuid,
  168. NULL,
  169. &RootBridgeHandleCount,
  170. &RootBridgeHandleBuffer
  171. );
  172. for (RootBridgeIndex = 0; RootBridgeIndex < RootBridgeHandleCount; RootBridgeIndex++) {
  173. gBS->ConnectController (RootBridgeHandleBuffer[RootBridgeIndex], NULL, NULL, Recursive);
  174. }
  175. }
  176. /**
  177. Return whether the device is trusted console.
  178. @param Device The device to be tested.
  179. @retval TRUE The device can be trusted.
  180. @retval FALSE The device cannot be trusted.
  181. **/
  182. BOOLEAN
  183. IsTrustedConsole (
  184. IN CONSOLE_TYPE ConsoleType,
  185. IN EFI_DEVICE_PATH_PROTOCOL *Device
  186. )
  187. {
  188. VOID *TrustedConsoleDevicepath;
  189. EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
  190. EFI_DEVICE_PATH_PROTOCOL *Instance;
  191. UINTN Size;
  192. EFI_DEVICE_PATH_PROTOCOL *ConsoleDevice;
  193. if (Device == NULL) {
  194. return FALSE;
  195. }
  196. ConsoleDevice = DuplicateDevicePath(Device);
  197. TrustedConsoleDevicepath = NULL;
  198. switch (ConsoleType) {
  199. case ConIn:
  200. TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleInputDevicePath);
  201. break;
  202. case ConOut:
  203. //
  204. // Check GOP and remove last node
  205. //
  206. TempDevicePath = ConsoleDevice;
  207. while (!IsDevicePathEndType (TempDevicePath)) {
  208. if (DevicePathType (TempDevicePath) == ACPI_DEVICE_PATH &&
  209. DevicePathSubType (TempDevicePath) == ACPI_ADR_DP) {
  210. SetDevicePathEndNode (TempDevicePath);
  211. break;
  212. }
  213. TempDevicePath = NextDevicePathNode (TempDevicePath);
  214. }
  215. TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleOutputDevicePath);
  216. break;
  217. default:
  218. ASSERT(FALSE);
  219. break;
  220. }
  221. TempDevicePath = TrustedConsoleDevicepath;
  222. do {
  223. Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
  224. if (Instance == NULL) {
  225. break;
  226. }
  227. if (CompareMem (ConsoleDevice, Instance, Size - END_DEVICE_PATH_LENGTH) == 0) {
  228. FreePool (Instance);
  229. FreePool (ConsoleDevice);
  230. return TRUE;
  231. }
  232. FreePool (Instance);
  233. } while (TempDevicePath != NULL);
  234. FreePool (ConsoleDevice);
  235. return FALSE;
  236. }
  237. BOOLEAN
  238. IsUsbShortForm (
  239. IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
  240. )
  241. {
  242. if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
  243. ((DevicePathSubType (DevicePath) == MSG_USB_CLASS_DP) || (DevicePathSubType (DevicePath) == MSG_USB_WWID_DP)) ) {
  244. return TRUE;
  245. }
  246. return FALSE;
  247. }
  248. /**
  249. Connect the USB short form device path.
  250. @param DevicePath USB short form device path
  251. @retval EFI_SUCCESS Successfully connected the USB device
  252. @retval EFI_NOT_FOUND Cannot connect the USB device
  253. @retval EFI_INVALID_PARAMETER The device path is invalid.
  254. **/
  255. EFI_STATUS
  256. ConnectUsbShortFormDevicePath (
  257. IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
  258. )
  259. {
  260. EFI_STATUS Status;
  261. EFI_HANDLE *Handles;
  262. UINTN HandleCount;
  263. UINTN Index;
  264. EFI_PCI_IO_PROTOCOL *PciIo;
  265. UINT8 Class[3];
  266. BOOLEAN AtLeastOneConnected;
  267. //
  268. // Check the passed in parameters
  269. //
  270. if (DevicePath == NULL) {
  271. return EFI_INVALID_PARAMETER;
  272. }
  273. if (!IsUsbShortForm (DevicePath)) {
  274. return EFI_INVALID_PARAMETER;
  275. }
  276. //
  277. // Find the usb host controller firstly, then connect with the remaining device path
  278. //
  279. AtLeastOneConnected = FALSE;
  280. Status = gBS->LocateHandleBuffer (
  281. ByProtocol,
  282. &gEfiPciIoProtocolGuid,
  283. NULL,
  284. &HandleCount,
  285. &Handles
  286. );
  287. for (Index = 0; Index < HandleCount; Index++) {
  288. Status = gBS->HandleProtocol (
  289. Handles[Index],
  290. &gEfiPciIoProtocolGuid,
  291. (VOID **) &PciIo
  292. );
  293. if (!EFI_ERROR (Status)) {
  294. //
  295. // Check whether the Pci device is the wanted usb host controller
  296. //
  297. Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class);
  298. if (!EFI_ERROR (Status) &&
  299. ((PCI_CLASS_SERIAL == Class[2]) && (PCI_CLASS_SERIAL_USB == Class[1]))
  300. ) {
  301. Status = gBS->ConnectController (
  302. Handles[Index],
  303. NULL,
  304. DevicePath,
  305. FALSE
  306. );
  307. if (!EFI_ERROR(Status)) {
  308. AtLeastOneConnected = TRUE;
  309. }
  310. }
  311. }
  312. }
  313. return AtLeastOneConnected ? EFI_SUCCESS : EFI_NOT_FOUND;
  314. }
  315. /**
  316. Update the ConIn variable with USB Keyboard device path,if its not already exists in ConIn
  317. **/
  318. VOID
  319. EnumUsbKeyboard (
  320. VOID
  321. )
  322. {
  323. DEBUG ((DEBUG_INFO, "[EnumUsbKeyboard]\n"));
  324. EfiBootManagerUpdateConsoleVariable (ConIn, (EFI_DEVICE_PATH_PROTOCOL *) &gUsbClassKeyboardDevicePath, NULL);
  325. //
  326. // Append Usb Keyboard short form DevicePath into "ConInDev"
  327. //
  328. EfiBootManagerUpdateConsoleVariable (ConInDev, (EFI_DEVICE_PATH_PROTOCOL *) &gUsbClassKeyboardDevicePath, NULL);
  329. }
  330. BOOLEAN
  331. IsVgaHandle (
  332. IN EFI_HANDLE Handle
  333. )
  334. {
  335. EFI_PCI_IO_PROTOCOL *PciIo;
  336. PCI_TYPE00 Pci;
  337. EFI_STATUS Status;
  338. Status = gBS->HandleProtocol (
  339. Handle,
  340. &gEfiPciIoProtocolGuid,
  341. (VOID **)&PciIo
  342. );
  343. if (!EFI_ERROR (Status)) {
  344. Status = PciIo->Pci.Read (
  345. PciIo,
  346. EfiPciIoWidthUint32,
  347. 0,
  348. sizeof (Pci) / sizeof (UINT32),
  349. &Pci
  350. );
  351. if (!EFI_ERROR (Status)) {
  352. if (IS_PCI_VGA (&Pci) || IS_PCI_OLD_VGA (&Pci)) {
  353. return TRUE;
  354. }
  355. }
  356. }
  357. return FALSE;
  358. }
  359. EFI_HANDLE
  360. IsVideoController (
  361. IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
  362. )
  363. {
  364. EFI_DEVICE_PATH_PROTOCOL *DupDevicePath;
  365. EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
  366. EFI_STATUS Status;
  367. EFI_HANDLE DeviceHandle;
  368. DupDevicePath = DuplicateDevicePath (DevicePath);
  369. ASSERT (DupDevicePath != NULL);
  370. if (DupDevicePath == NULL) {
  371. return NULL;
  372. }
  373. TempDevicePath = DupDevicePath;
  374. Status = gBS->LocateDevicePath (
  375. &gEfiDevicePathProtocolGuid,
  376. &TempDevicePath,
  377. &DeviceHandle
  378. );
  379. FreePool (DupDevicePath);
  380. if (EFI_ERROR (Status)) {
  381. return NULL;
  382. }
  383. if (IsVgaHandle (DeviceHandle)) {
  384. return DeviceHandle;
  385. } else {
  386. return NULL;
  387. }
  388. }
  389. BOOLEAN
  390. IsGopDevicePath (
  391. IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
  392. )
  393. {
  394. while (!IsDevicePathEndType (DevicePath)) {
  395. if (DevicePathType (DevicePath) == ACPI_DEVICE_PATH &&
  396. DevicePathSubType (DevicePath) == ACPI_ADR_DP) {
  397. return TRUE;
  398. }
  399. DevicePath = NextDevicePathNode (DevicePath);
  400. }
  401. return FALSE;
  402. }
  403. /**
  404. Remove all GOP device path instance from DevicePath and add the Gop to the DevicePath.
  405. **/
  406. EFI_DEVICE_PATH_PROTOCOL *
  407. UpdateGopDevicePath (
  408. EFI_DEVICE_PATH_PROTOCOL *DevicePath,
  409. EFI_DEVICE_PATH_PROTOCOL *Gop
  410. )
  411. {
  412. UINTN Size;
  413. UINTN GopSize;
  414. EFI_DEVICE_PATH_PROTOCOL *Temp;
  415. EFI_DEVICE_PATH_PROTOCOL *Return;
  416. EFI_DEVICE_PATH_PROTOCOL *Instance;
  417. BOOLEAN Exist;
  418. Exist = FALSE;
  419. Return = NULL;
  420. GopSize = GetDevicePathSize (Gop);
  421. do {
  422. Instance = GetNextDevicePathInstance (&DevicePath, &Size);
  423. if (Instance == NULL) {
  424. break;
  425. }
  426. if (!IsGopDevicePath (Instance) ||
  427. (Size == GopSize && CompareMem (Instance, Gop, GopSize) == 0)
  428. ) {
  429. if (Size == GopSize && CompareMem (Instance, Gop, GopSize) == 0) {
  430. Exist = TRUE;
  431. }
  432. Temp = Return;
  433. Return = AppendDevicePathInstance (Return, Instance);
  434. if (Temp != NULL) {
  435. FreePool (Temp);
  436. }
  437. }
  438. FreePool (Instance);
  439. } while (DevicePath != NULL);
  440. if (!Exist) {
  441. Temp = Return;
  442. Return = AppendDevicePathInstance (Return, Gop);
  443. if (Temp != NULL) {
  444. FreePool (Temp);
  445. }
  446. }
  447. return Return;
  448. }
  449. /**
  450. Get Graphics Controller Handle.
  451. @retval GraphicsController Successfully located
  452. @retval NULL Failed to locate
  453. **/
  454. EFI_HANDLE
  455. EFIAPI
  456. GetGraphicsController (
  457. IN BOOLEAN NeedTrustedConsole
  458. )
  459. {
  460. EFI_STATUS Status;
  461. UINTN Index;
  462. EFI_HANDLE *PciHandles;
  463. UINTN PciHandlesSize;
  464. EFI_DEVICE_PATH_PROTOCOL *DevicePath;
  465. Status = gBS->LocateHandleBuffer (
  466. ByProtocol,
  467. &gEfiPciIoProtocolGuid,
  468. NULL,
  469. &PciHandlesSize,
  470. &PciHandles
  471. );
  472. if (EFI_ERROR (Status)) {
  473. return NULL;
  474. }
  475. for (Index = 0; Index < PciHandlesSize; Index++) {
  476. Status = gBS->HandleProtocol (
  477. PciHandles[Index],
  478. &gEfiDevicePathProtocolGuid,
  479. (VOID **) &DevicePath
  480. );
  481. if (EFI_ERROR(Status)) {
  482. continue;
  483. }
  484. if (!IsVgaHandle (PciHandles[Index])) {
  485. continue;
  486. }
  487. if ((NeedTrustedConsole && IsTrustedConsole (ConOut, DevicePath)) ||
  488. ((!NeedTrustedConsole) && (!IsTrustedConsole (ConOut, DevicePath)))) {
  489. return PciHandles[Index];
  490. }
  491. }
  492. return NULL;
  493. }
  494. VOID
  495. UpdateGraphicConOut (
  496. IN BOOLEAN NeedTrustedConsole
  497. )
  498. {
  499. EFI_HANDLE GraphicsControllerHandle;
  500. EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
  501. EFI_DEVICE_PATH_PROTOCOL *ConOutDevicePath;
  502. EFI_DEVICE_PATH_PROTOCOL *UpdatedConOutDevicePath;
  503. //
  504. // Update ConOut variable
  505. //
  506. GraphicsControllerHandle = GetGraphicsController (NeedTrustedConsole);
  507. if (GraphicsControllerHandle != NULL) {
  508. //
  509. // Connect the GOP driver
  510. //
  511. gBS->ConnectController (GraphicsControllerHandle, NULL, NULL, TRUE);
  512. //
  513. // Get the GOP device path
  514. // NOTE: We may get a device path that contains Controller node in it.
  515. //
  516. GopDevicePath = EfiBootManagerGetGopDevicePath (GraphicsControllerHandle);
  517. if (GopDevicePath != NULL) {
  518. GetEfiGlobalVariable2 (L"ConOut", (VOID **)&ConOutDevicePath, NULL);
  519. UpdatedConOutDevicePath = UpdateGopDevicePath (ConOutDevicePath, GopDevicePath);
  520. if (ConOutDevicePath != NULL) {
  521. FreePool (ConOutDevicePath);
  522. }
  523. FreePool (GopDevicePath);
  524. gRT->SetVariable (
  525. L"ConOut",
  526. &gEfiGlobalVariableGuid,
  527. EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
  528. GetDevicePathSize (UpdatedConOutDevicePath),
  529. UpdatedConOutDevicePath
  530. );
  531. }
  532. }
  533. }
  534. VOID
  535. AddConsoleVariable (
  536. IN CONSOLE_TYPE ConsoleType,
  537. IN EFI_DEVICE_PATH *ConsoleDevicePath
  538. )
  539. {
  540. EFI_DEVICE_PATH *TempDevicePath;
  541. EFI_DEVICE_PATH *Instance;
  542. UINTN Size;
  543. EFI_HANDLE GraphicsControllerHandle;
  544. EFI_DEVICE_PATH *GopDevicePath;
  545. TempDevicePath = ConsoleDevicePath;
  546. do {
  547. Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
  548. if (Instance == NULL) {
  549. break;
  550. }
  551. switch (ConsoleType) {
  552. case ConIn:
  553. if (IsUsbShortForm (Instance)) {
  554. //
  555. // Append Usb Keyboard short form DevicePath into "ConInDev"
  556. //
  557. EfiBootManagerUpdateConsoleVariable (ConInDev, Instance, NULL);
  558. }
  559. EfiBootManagerUpdateConsoleVariable (ConsoleType, Instance, NULL);
  560. break;
  561. case ConOut:
  562. GraphicsControllerHandle = IsVideoController (Instance);
  563. if (GraphicsControllerHandle == NULL) {
  564. EfiBootManagerUpdateConsoleVariable (ConsoleType, Instance, NULL);
  565. } else {
  566. //
  567. // Connect the GOP driver
  568. //
  569. gBS->ConnectController (GraphicsControllerHandle, NULL, NULL, TRUE);
  570. //
  571. // Get the GOP device path
  572. // NOTE: We may get a device path that contains Controller node in it.
  573. //
  574. GopDevicePath = EfiBootManagerGetGopDevicePath (GraphicsControllerHandle);
  575. if (GopDevicePath != NULL) {
  576. EfiBootManagerUpdateConsoleVariable (ConsoleType, GopDevicePath, NULL);
  577. }
  578. }
  579. break;
  580. default:
  581. ASSERT(FALSE);
  582. break;
  583. }
  584. FreePool (Instance);
  585. } while (TempDevicePath != NULL);
  586. }
  587. /**
  588. The function connects the trusted consoles.
  589. **/
  590. VOID
  591. ConnectTrustedConsole (
  592. VOID
  593. )
  594. {
  595. EFI_DEVICE_PATH_PROTOCOL *Consoles;
  596. EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
  597. EFI_DEVICE_PATH_PROTOCOL *Instance;
  598. EFI_DEVICE_PATH_PROTOCOL *Next;
  599. UINTN Size;
  600. UINTN Index;
  601. EFI_HANDLE Handle;
  602. EFI_STATUS Status;
  603. CHAR16 *ConsoleVar[] = {L"ConIn", L"ConOut"};
  604. VOID *TrustedConsoleDevicepath;
  605. TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleInputDevicePath);
  606. DumpDevicePath (L"TrustedConsoleIn", TrustedConsoleDevicepath);
  607. TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleOutputDevicePath);
  608. DumpDevicePath (L"TrustedConsoleOut", TrustedConsoleDevicepath);
  609. for (Index = 0; Index < sizeof (ConsoleVar) / sizeof (ConsoleVar[0]); Index++) {
  610. GetEfiGlobalVariable2 (ConsoleVar[Index], (VOID **)&Consoles, NULL);
  611. TempDevicePath = Consoles;
  612. do {
  613. Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
  614. if (Instance == NULL) {
  615. break;
  616. }
  617. if (IsTrustedConsole (Index, Instance)) {
  618. if (IsUsbShortForm (Instance)) {
  619. ConnectUsbShortFormDevicePath (Instance);
  620. } else {
  621. for (Next = Instance; !IsDevicePathEnd (Next); Next = NextDevicePathNode (Next)) {
  622. if (DevicePathType (Next) == ACPI_DEVICE_PATH && DevicePathSubType (Next) == ACPI_ADR_DP) {
  623. break;
  624. } else if (DevicePathType (Next) == HARDWARE_DEVICE_PATH &&
  625. DevicePathSubType (Next) == HW_CONTROLLER_DP &&
  626. DevicePathType (NextDevicePathNode (Next)) == ACPI_DEVICE_PATH &&
  627. DevicePathSubType (NextDevicePathNode (Next)) == ACPI_ADR_DP
  628. ) {
  629. break;
  630. }
  631. }
  632. if (!IsDevicePathEnd (Next)) {
  633. SetDevicePathEndNode (Next);
  634. Status = EfiBootManagerConnectDevicePath (Instance, &Handle);
  635. if (!EFI_ERROR (Status)) {
  636. gBS->ConnectController (Handle, NULL, NULL, TRUE);
  637. }
  638. } else {
  639. EfiBootManagerConnectDevicePath (Instance, NULL);
  640. }
  641. }
  642. }
  643. FreePool (Instance);
  644. } while (TempDevicePath != NULL);
  645. if (Consoles != NULL) {
  646. FreePool (Consoles);
  647. }
  648. }
  649. }
  650. /**
  651. The function connects the trusted Storages.
  652. **/
  653. VOID
  654. ConnectTrustedStorage (
  655. VOID
  656. )
  657. {
  658. VOID *TrustedStorageDevicepath;
  659. EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
  660. EFI_DEVICE_PATH_PROTOCOL *Instance;
  661. UINTN Size;
  662. EFI_DEVICE_PATH_PROTOCOL *TempStorageDevicePath;
  663. EFI_STATUS Status;
  664. EFI_HANDLE DeviceHandle;
  665. TrustedStorageDevicepath = PcdGetPtr (PcdTrustedStorageDevicePath);
  666. DumpDevicePath (L"TrustedStorage", TrustedStorageDevicepath);
  667. TempDevicePath = TrustedStorageDevicepath;
  668. do {
  669. Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
  670. if (Instance == NULL) {
  671. break;
  672. }
  673. EfiBootManagerConnectDevicePath (Instance, NULL);
  674. TempStorageDevicePath = Instance;
  675. Status = gBS->LocateDevicePath (
  676. &gEfiDevicePathProtocolGuid,
  677. &TempStorageDevicePath,
  678. &DeviceHandle
  679. );
  680. if (!EFI_ERROR (Status)) {
  681. gBS->ConnectController (DeviceHandle, NULL, NULL, FALSE);
  682. }
  683. FreePool (Instance);
  684. } while (TempDevicePath != NULL);
  685. }
  686. /**
  687. The function connects the trusted consoles and then call the PP processing library interface.
  688. **/
  689. VOID
  690. ProcessTcgPp (
  691. VOID
  692. )
  693. {
  694. gPPRequireUIConfirm |= Tcg2PhysicalPresenceLibNeedUserConfirm();
  695. if (gPPRequireUIConfirm) {
  696. ConnectTrustedConsole ();
  697. }
  698. Tcg2PhysicalPresenceLibProcessRequest (NULL);
  699. }
  700. /**
  701. The function connects the trusted storage to perform TPerReset.
  702. **/
  703. VOID
  704. ProcessTcgMor (
  705. VOID
  706. )
  707. {
  708. if (IsMorBitSet ()) {
  709. ConnectTrustedConsole();
  710. ConnectTrustedStorage();
  711. }
  712. }
  713. /**
  714. Check if current BootCurrent variable is internal shell boot option.
  715. @retval TRUE BootCurrent is internal shell.
  716. @retval FALSE BootCurrent is not internal shell.
  717. **/
  718. BOOLEAN
  719. BootCurrentIsInternalShell (
  720. VOID
  721. )
  722. {
  723. UINTN VarSize;
  724. UINT16 BootCurrent;
  725. CHAR16 BootOptionName[16];
  726. UINT8 *BootOption;
  727. UINT8 *Ptr;
  728. BOOLEAN Result;
  729. EFI_STATUS Status;
  730. EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
  731. EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode;
  732. EFI_GUID *GuidPoint;
  733. BootOption = NULL;
  734. Result = FALSE;
  735. //
  736. // Get BootCurrent variable
  737. //
  738. VarSize = sizeof (UINT16);
  739. Status = gRT->GetVariable (
  740. L"BootCurrent",
  741. &gEfiGlobalVariableGuid,
  742. NULL,
  743. &VarSize,
  744. &BootCurrent
  745. );
  746. if (EFI_ERROR (Status)) {
  747. return FALSE;
  748. }
  749. //
  750. // Create boot option Bootxxxx from BootCurrent
  751. //
  752. UnicodeSPrint (BootOptionName, sizeof(BootOptionName), L"Boot%04X", BootCurrent);
  753. GetEfiGlobalVariable2 (BootOptionName, (VOID **) &BootOption, &VarSize);
  754. if (BootOption == NULL || VarSize == 0) {
  755. return FALSE;
  756. }
  757. Ptr = BootOption;
  758. Ptr += sizeof (UINT32);
  759. Ptr += sizeof (UINT16);
  760. Ptr += StrSize ((CHAR16 *) Ptr);
  761. TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
  762. LastDeviceNode = TempDevicePath;
  763. while (!IsDevicePathEnd (TempDevicePath)) {
  764. LastDeviceNode = TempDevicePath;
  765. TempDevicePath = NextDevicePathNode (TempDevicePath);
  766. }
  767. GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode (
  768. (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode
  769. );
  770. if ((GuidPoint != NULL) &&
  771. ((CompareGuid (GuidPoint, &gUefiShellFileGuid)))
  772. ) {
  773. //
  774. // if this option is internal shell, return TRUE
  775. //
  776. Result = TRUE;
  777. }
  778. if (BootOption != NULL) {
  779. FreePool (BootOption);
  780. BootOption = NULL;
  781. }
  782. return Result;
  783. }
  784. /**
  785. This function will change video resolution and text mode
  786. for internl shell when internal shell is launched.
  787. @param None.
  788. @retval EFI_SUCCESS Mode is changed successfully.
  789. @retval Others Mode failed to changed.
  790. **/
  791. EFI_STATUS
  792. EFIAPI
  793. ChangeModeForInternalShell (
  794. VOID
  795. )
  796. {
  797. EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
  798. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
  799. UINTN SizeOfInfo;
  800. EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
  801. UINT32 MaxGopMode;
  802. UINT32 MaxTextMode;
  803. UINT32 ModeNumber;
  804. UINTN HandleCount;
  805. EFI_HANDLE *HandleBuffer;
  806. EFI_STATUS Status;
  807. UINTN Index;
  808. UINTN CurrentColumn;
  809. UINTN CurrentRow;
  810. Status = gBS->HandleProtocol (
  811. gST->ConsoleOutHandle,
  812. &gEfiGraphicsOutputProtocolGuid,
  813. (VOID**)&GraphicsOutput
  814. );
  815. if (EFI_ERROR (Status)) {
  816. GraphicsOutput = NULL;
  817. }
  818. Status = gBS->HandleProtocol (
  819. gST->ConsoleOutHandle,
  820. &gEfiSimpleTextOutProtocolGuid,
  821. (VOID**)&SimpleTextOut
  822. );
  823. if (EFI_ERROR (Status)) {
  824. SimpleTextOut = NULL;
  825. }
  826. if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {
  827. return EFI_UNSUPPORTED;
  828. }
  829. MaxGopMode = GraphicsOutput->Mode->MaxMode;
  830. MaxTextMode = SimpleTextOut->Mode->MaxMode;
  831. //
  832. // 1. If current video resolution is same with new video resolution,
  833. // video resolution need not be changed.
  834. // 1.1. If current text mode is same with new text mode, text mode need not be change.
  835. // 1.2. If current text mode is different with new text mode, text mode need be change to new text mode.
  836. // 2. If current video resolution is different with new video resolution, we need restart whole console drivers.
  837. //
  838. for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {
  839. Status = GraphicsOutput->QueryMode (
  840. GraphicsOutput,
  841. ModeNumber,
  842. &SizeOfInfo,
  843. &Info
  844. );
  845. if (!EFI_ERROR (Status)) {
  846. if ((Info->HorizontalResolution == mShellHorizontalResolution) &&
  847. (Info->VerticalResolution == mShellVerticalResolution)) {
  848. if ((GraphicsOutput->Mode->Info->HorizontalResolution == mShellHorizontalResolution) &&
  849. (GraphicsOutput->Mode->Info->VerticalResolution == mShellVerticalResolution)) {
  850. //
  851. // If current video resolution is same with new resolution,
  852. // then check if current text mode is same with new text mode.
  853. //
  854. Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);
  855. ASSERT_EFI_ERROR (Status);
  856. if (CurrentColumn == mShellModeColumn && CurrentRow == mShellModeRow) {
  857. //
  858. // Current text mode is same with new text mode, text mode need not be change.
  859. //
  860. FreePool (Info);
  861. return EFI_SUCCESS;
  862. } else {
  863. //
  864. // Current text mode is different with new text mode, text mode need be change to new text mode.
  865. //
  866. for (Index = 0; Index < MaxTextMode; Index++) {
  867. Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);
  868. if (!EFI_ERROR(Status)) {
  869. if ((CurrentColumn == mShellModeColumn) && (CurrentRow == mShellModeRow)) {
  870. //
  871. // New text mode is supported, set it.
  872. //
  873. Status = SimpleTextOut->SetMode (SimpleTextOut, Index);
  874. ASSERT_EFI_ERROR (Status);
  875. //
  876. // Update text mode PCD.
  877. //
  878. Status = PcdSet32S (PcdConOutColumn, mShellModeColumn);
  879. ASSERT_EFI_ERROR (Status);
  880. Status = PcdSet32S (PcdConOutRow, mShellModeRow);
  881. ASSERT_EFI_ERROR (Status);
  882. FreePool (Info);
  883. return EFI_SUCCESS;
  884. }
  885. }
  886. }
  887. if (Index == MaxTextMode) {
  888. //
  889. // If new text mode is not supported, return error.
  890. //
  891. FreePool (Info);
  892. return EFI_UNSUPPORTED;
  893. }
  894. }
  895. } else {
  896. FreePool (Info);
  897. //
  898. // If current video resolution is not same with the new one, set new video resolution.
  899. // In this case, the driver which produces simple text out need be restarted.
  900. //
  901. Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
  902. if (!EFI_ERROR (Status)) {
  903. //
  904. // Set PCD to restart GraphicsConsole and Consplitter to change video resolution
  905. // and produce new text mode based on new resolution.
  906. //
  907. Status = PcdSet32S (PcdVideoHorizontalResolution, mShellHorizontalResolution);
  908. ASSERT_EFI_ERROR (Status);
  909. Status = PcdSet32S (PcdVideoVerticalResolution, mShellVerticalResolution);
  910. ASSERT_EFI_ERROR (Status);
  911. Status = PcdSet32S (PcdConOutColumn, mShellModeColumn);
  912. ASSERT_EFI_ERROR (Status);
  913. Status = PcdSet32S (PcdConOutRow, mShellModeRow);
  914. ASSERT_EFI_ERROR (Status);
  915. Status = gBS->LocateHandleBuffer (
  916. ByProtocol,
  917. &gEfiSimpleTextOutProtocolGuid,
  918. NULL,
  919. &HandleCount,
  920. &HandleBuffer
  921. );
  922. if (!EFI_ERROR (Status)) {
  923. for (Index = 0; Index < HandleCount; Index++) {
  924. gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
  925. }
  926. for (Index = 0; Index < HandleCount; Index++) {
  927. gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
  928. }
  929. if (HandleBuffer != NULL) {
  930. FreePool (HandleBuffer);
  931. }
  932. break;
  933. }
  934. }
  935. }
  936. }
  937. FreePool (Info);
  938. }
  939. }
  940. if (ModeNumber == MaxGopMode) {
  941. //
  942. // If the new resolution is not supported, return error.
  943. //
  944. return EFI_UNSUPPORTED;
  945. }
  946. return EFI_SUCCESS;
  947. }
  948. /**
  949. ReadyToBoot callback to set video and text mode for internal shell boot.
  950. That will not connect USB controller while CSM and FastBoot are disabled, we need to connect them
  951. before booting to Shell for showing USB devices in Shell.
  952. When FastBoot is enabled and Windows Console is the chosen Console behavior, input devices will not be connected
  953. by default. Hence, when booting to EFI shell, connecting input consoles are required.
  954. @param Event Pointer to this event
  955. @param Context Event hanlder private data
  956. @retval None.
  957. **/
  958. VOID
  959. EFIAPI
  960. OnReadyToBootCallBack (
  961. IN EFI_EVENT Event,
  962. IN VOID *Context
  963. )
  964. {
  965. DEBUG ((EFI_D_INFO, "OnReadyToBootCallBack\n"));
  966. if (BootCurrentIsInternalShell ()) {
  967. ChangeModeForInternalShell ();
  968. EfiBootManagerConnectAllDefaultConsoles();
  969. gDS->Dispatch ();
  970. }
  971. }
  972. /**
  973. Platform Bds init. Incude the platform firmware vendor, revision
  974. and so crc check.
  975. **/
  976. VOID
  977. EFIAPI
  978. PlatformBootManagerBeforeConsole (
  979. VOID
  980. )
  981. {
  982. EFI_STATUS Status;
  983. EFI_DEVICE_PATH_PROTOCOL *VarConOut;
  984. EFI_DEVICE_PATH_PROTOCOL *VarConIn;
  985. EFI_EVENT Event;
  986. DEBUG ((EFI_D_INFO, "PlatformBootManagerBeforeConsole\n"));
  987. Status = EFI_SUCCESS;
  988. //
  989. // Get user defined text mode for internal shell only once.
  990. //
  991. mShellHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
  992. mShellVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
  993. mShellModeColumn = PcdGet32 (PcdSetupConOutColumn);
  994. mShellModeRow = PcdGet32 (PcdSetupConOutRow);
  995. if (PcdGetBool (PcdUpdateConsoleInBds) == TRUE) {
  996. //
  997. // Create event to set proper video resolution and text mode for internal shell.
  998. //
  999. Status = EfiCreateEventReadyToBootEx (
  1000. TPL_CALLBACK,
  1001. OnReadyToBootCallBack,
  1002. NULL,
  1003. &Event
  1004. );
  1005. ASSERT_EFI_ERROR (Status);
  1006. //
  1007. // Connect Root Bridge to make PCI BAR resource allocated and all PciIo created
  1008. //
  1009. ConnectRootBridge (FALSE);
  1010. //
  1011. // Fill ConIn/ConOut in Full Configuration boot mode
  1012. //
  1013. DEBUG ((DEBUG_INFO, "PlatformBootManagerInit - %x\n", gBootMode));
  1014. if (gBootMode == BOOT_WITH_FULL_CONFIGURATION ||
  1015. gBootMode == BOOT_WITH_DEFAULT_SETTINGS ||
  1016. gBootMode == BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS ||
  1017. gBootMode == BOOT_IN_RECOVERY_MODE) {
  1018. GetEfiGlobalVariable2 (L"ConOut", (VOID **)&VarConOut, NULL); if (VarConOut != NULL) { FreePool (VarConOut); }
  1019. GetEfiGlobalVariable2 (L"ConIn", (VOID **)&VarConIn, NULL); if (VarConIn != NULL) { FreePool (VarConIn); }
  1020. //
  1021. // Only fill ConIn/ConOut when ConIn/ConOut is empty because we may drop to Full Configuration boot mode in non-first boot
  1022. //
  1023. if (VarConOut == NULL || VarConIn == NULL) {
  1024. if (PcdGetSize (PcdTrustedConsoleOutputDevicePath) >= sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
  1025. AddConsoleVariable (ConOut, PcdGetPtr (PcdTrustedConsoleOutputDevicePath));
  1026. }
  1027. if (PcdGetSize (PcdTrustedConsoleInputDevicePath) >= sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
  1028. AddConsoleVariable (ConIn, PcdGetPtr (PcdTrustedConsoleInputDevicePath));
  1029. }
  1030. }
  1031. }
  1032. EnumUsbKeyboard ();
  1033. //
  1034. // For trusted console it must be handled here.
  1035. //
  1036. UpdateGraphicConOut (TRUE);
  1037. //
  1038. // Dynamically register hot key: F2/F7/Enter
  1039. //
  1040. RegisterDefaultBootOption ();
  1041. RegisterStaticHotkey ();
  1042. }
  1043. PERF_START_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7010);
  1044. if (PcdGetBool (PcdTpm2Enable)) {
  1045. ProcessTcgPp ();
  1046. ProcessTcgMor ();
  1047. }
  1048. PERF_END_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7011);
  1049. //
  1050. // We should make all UEFI memory and GCD information populated before ExitPmAuth.
  1051. // SMM may consume these information.
  1052. //
  1053. MemoryTest((EXTENDMEM_COVERAGE_LEVEL) PcdGet32 (PcdPlatformMemoryCheckLevel));
  1054. PERF_START_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7020);
  1055. ExitPmAuth ();
  1056. PERF_END_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7021);
  1057. //
  1058. // Dispatch the deferred 3rd party images.
  1059. //
  1060. EfiBootManagerDispatchDeferredImages ();
  1061. //
  1062. // For non-trusted console it must be handled here.
  1063. //
  1064. if (PcdGetBool (PcdUpdateConsoleInBds) == TRUE) {
  1065. UpdateGraphicConOut (FALSE);
  1066. }
  1067. }
  1068. /**
  1069. Connect with predeined platform connect sequence,
  1070. the OEM/IBV can customize with their own connect sequence.
  1071. @param[in] BootMode Boot mode of this boot.
  1072. **/
  1073. VOID
  1074. ConnectSequence (
  1075. IN EFI_BOOT_MODE BootMode
  1076. )
  1077. {
  1078. EfiBootManagerConnectAll ();
  1079. }
  1080. /**
  1081. The function is to consider the boot order which is not in our expectation.
  1082. In the case that we need to re-sort the boot option.
  1083. @retval TRUE Need to sort Boot Option.
  1084. @retval FALSE Don't need to sort Boot Option.
  1085. **/
  1086. BOOLEAN
  1087. IsNeedSortBootOption (
  1088. VOID
  1089. )
  1090. {
  1091. EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
  1092. UINTN BootOptionCount;
  1093. BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
  1094. //
  1095. // If setup is the first priority in boot option, we need to sort boot option.
  1096. //
  1097. if ((BootOptionCount > 1) &&
  1098. (((StrnCmp (BootOptions->Description, L"Enter Setup", StrLen (L"Enter Setup"))) == 0) ||
  1099. ((StrnCmp (BootOptions->Description, L"BootManagerMenuApp", StrLen (L"BootManagerMenuApp"))) == 0))) {
  1100. return TRUE;
  1101. }
  1102. return FALSE;
  1103. }
  1104. /**
  1105. The function will excute with as the platform policy, current policy
  1106. is driven by boot mode. IBV/OEM can customize this code for their specific
  1107. policy action.
  1108. @param DriverOptionList - The header of the driver option link list
  1109. @param BootOptionList - The header of the boot option link list
  1110. @param ProcessCapsules - A pointer to ProcessCapsules()
  1111. @param BaseMemoryTest - A pointer to BaseMemoryTest()
  1112. **/
  1113. VOID
  1114. EFIAPI
  1115. PlatformBootManagerAfterConsole (
  1116. VOID
  1117. )
  1118. {
  1119. EFI_BOOT_MODE LocalBootMode;
  1120. DEBUG ((EFI_D_INFO, "PlatformBootManagerAfterConsole\n"));
  1121. //
  1122. // Get current Boot Mode
  1123. //
  1124. LocalBootMode = gBootMode;
  1125. DEBUG ((DEBUG_INFO, "Current local bootmode - %x\n", LocalBootMode));
  1126. LinuxBootStart();
  1127. //
  1128. // Go the different platform policy with different boot mode
  1129. // Notes: this part code can be change with the table policy
  1130. //
  1131. switch (LocalBootMode) {
  1132. case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
  1133. case BOOT_WITH_MINIMAL_CONFIGURATION:
  1134. case BOOT_ON_S4_RESUME:
  1135. //
  1136. // Perform some platform specific connect sequence
  1137. //
  1138. if (PcdGetBool (PcdFastBoot) == FALSE) {
  1139. PERF_START_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7050);
  1140. ConnectSequence (LocalBootMode);
  1141. PERF_END_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7051);
  1142. }
  1143. break;
  1144. case BOOT_WITH_FULL_CONFIGURATION:
  1145. case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
  1146. case BOOT_WITH_DEFAULT_SETTINGS:
  1147. default:
  1148. //
  1149. // Perform some platform specific connect sequence
  1150. //
  1151. ConnectSequence (LocalBootMode);
  1152. //
  1153. // Only in Full Configuration boot mode we do the enumeration of boot device
  1154. //
  1155. //
  1156. // Dispatch all but Storage Oprom explicitly, because we assume Int13Thunk driver is there.
  1157. //
  1158. EfiBootManagerRefreshAllBootOption ();
  1159. if (IsNeedSortBootOption()) {
  1160. EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, CompareBootOption);
  1161. }
  1162. //
  1163. // PXE boot option may appear after boot option enumeration
  1164. //
  1165. break;
  1166. }
  1167. if (PcdGetBool (PcdFastBoot) == FALSE) {
  1168. Print (L"Press F7 for BootMenu!\n");
  1169. EfiBootManagerRefreshAllBootOption ();
  1170. EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, CompareBootOption);
  1171. }
  1172. }
  1173. /**
  1174. The function is called when no boot option could be launched,
  1175. including platform recovery options and options pointing to applications
  1176. built into firmware volumes.
  1177. If this function returns, BDS attempts to enter an infinite loop.
  1178. **/
  1179. VOID
  1180. EFIAPI
  1181. PlatformBootManagerUnableToBoot (
  1182. VOID
  1183. )
  1184. {
  1185. EFI_STATUS Status;
  1186. EFI_BOOT_MANAGER_LOAD_OPTION BootDeviceList;
  1187. CHAR16 OptionName[sizeof ("Boot####")];
  1188. if (mBootMenuOptionNumber == LoadOptionNumberUnassigned) {
  1189. return;
  1190. }
  1191. UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", mBootMenuOptionNumber);
  1192. Status = EfiBootManagerVariableToLoadOption (OptionName, &BootDeviceList);
  1193. if (EFI_ERROR (Status)) {
  1194. return;
  1195. }
  1196. for (;;) {
  1197. EfiBootManagerBoot (&BootDeviceList);
  1198. }
  1199. }