BoardBdsHookLib.c 40 KB

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