]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
Vlv2TbltDevicePkg: Always enable QuietBoot to produce BGRT
[mirror_edk2.git] / Vlv2TbltDevicePkg / Library / PlatformBdsLib / BdsPlatform.c
1 /** @file
2
3 Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
4
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7
8
9 Module Name:
10
11 BdsPlatform.c
12
13 Abstract:
14
15 This file include all platform action which can be customized
16 by IBV/OEM.
17
18 --*/
19
20 #include "BdsPlatform.h"
21 #include "SetupMode.h"
22 #include <Guid/SetupVariable.h>
23 #include <Library/TcgPhysicalPresenceLib.h>
24 #include <Library/Tcg2PhysicalPresenceLib.h>
25 #include <Protocol/I2cMasterMcg.h>
26 #include <TianoApi.h>
27 #include <PlatformBaseAddresses.h>
28 #include <Protocol/GlobalNvsArea.h>
29 #include <Library/DxeServicesTableLib.h>
30 #include <Protocol/BlockIo.h>
31 #include <PchRegs/PchRegsPcu.h>
32 #include <Library/S3BootScriptLib.h>
33 #include "PchAccess.h"
34 #include "PchRegs/PchRegsSata.h"
35 #include <Library/SerialPortLib.h>
36 #include <Library/DebugLib.h>
37
38 #include <Library/GenericBdsLib/InternalBdsLib.h>
39 #include <Library/GenericBdsLib/String.h>
40 #include <Library/NetLib.h>
41
42 #include <Library/CapsuleLib.h>
43 #include <Protocol/EsrtManagement.h>
44
45 EFI_GUID *ConnectDriverTable[] = {
46 &gEfiMmioDeviceProtocolGuid,
47 &gEfiI2cMasterProtocolGuid,
48 &gEfiI2cHostProtocolGuid
49 };
50
51 #define SHELL_ENVIRONMENT_INTERFACE_PROTOCOL \
52 { \
53 0x47c7b221, 0xc42a, 0x11d2, 0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b \
54 }
55 VOID *mShellImageCallbackReg = NULL;
56
57
58
59 EFI_USER_PROFILE_HANDLE mCurrentUser = NULL;
60 EFI_EVENT mHotKeyTimerEvent = NULL;
61 EFI_EVENT mHitHotkeyEvent = NULL;
62 EFI_EVENT mUsbKeyboardConnectEvent = NULL;
63 BOOLEAN mHotKeyPressed = FALSE;
64 VOID *mHitHotkeyRegistration;
65 #define KEYBOARD_TIMER_INTERVAL 20000 // 0.02s
66
67 VOID
68 ConnectUSBController (
69 VOID
70 );
71
72 EFI_STATUS
73 PlatformBdsConnectSimpleConsole (
74 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
75 );
76
77 VOID
78 BootIntoFirmwareInterface(
79 VOID
80 );
81
82 VOID
83 EFIAPI
84 PlatformBdsInitHotKeyEvent (
85 VOID
86 );
87
88 VOID
89 EFIAPI
90 DisableAhciCtlr (
91 IN EFI_EVENT Event,
92 IN VOID *Context
93 )
94 {
95 UINT32 PmcDisableAddress;
96 UINT8 SataStorageAmount;
97 UINT32 SataBase;
98 UINT16 SataPortStatus;
99
100
101 DEBUG ((EFI_D_INFO, "Disable AHCI event is signalled\n"));
102 SataStorageAmount = 0;
103 SataBase = *(UINT32*) Context;
104
105 //
106 // BayTrail-M EDS chapter 16 ---- PCI IO Register Offset 92 (SATA Port Control and Status)
107 //
108 SataPortStatus = MmioRead16 (SataBase + R_PCH_SATA_PCS);
109
110 //
111 // Bit 8 EN: Port 0 Present
112 //
113 if ((SataPortStatus & 0x100) == 0x100) {
114 SataStorageAmount++;
115 }
116
117 //
118 // Bit 9 EN: Port 1 Present
119 //
120 if ((SataPortStatus & 0x200) == 0x200) {
121 SataStorageAmount++;
122 }
123
124 //
125 // Disable SATA controller when it sets to AHCI mode without carrying any devices
126 // in order to prevent AHCI yellow bang under Win device manager.
127 //
128 if (SataStorageAmount == 0) {
129 PmcDisableAddress = (MmioRead32 ((PCH_PCI_EXPRESS_BASE_ADDRESS + (UINT32) (31 << 15)) + R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR) + R_PCH_PMC_FUNC_DIS;
130 MmioOr32 (PmcDisableAddress, B_PCH_PMC_FUNC_DIS_SATA);
131 S3BootScriptSaveMemWrite (
132 EfiBootScriptWidthUint32,
133 (UINTN) PmcDisableAddress,
134 1,
135 (VOID *) (UINTN) PmcDisableAddress
136 );
137 }
138 }
139
140 VOID
141 InstallReadyToLock (
142 VOID
143 )
144 {
145 EFI_STATUS Status;
146 EFI_HANDLE Handle;
147 EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
148 EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;
149
150 //
151 // Install DxeSmmReadyToLock protocol prior to the processing of boot options
152 //
153 Status = gBS->LocateProtocol (
154 &gEfiSmmAccess2ProtocolGuid,
155 NULL,
156 (VOID **) &SmmAccess
157 );
158 if (!EFI_ERROR (Status)) {
159
160 //
161 // Prepare S3 information, this MUST be done before DxeSmmReadyToLock
162 //
163 Status = gBS->LocateProtocol (
164 &gEfiAcpiS3SaveProtocolGuid,
165 NULL,
166 (VOID **)&AcpiS3Save
167 );
168 if (!EFI_ERROR (Status)) {
169 AcpiS3Save->S3Save (AcpiS3Save, NULL);
170 }
171
172 Handle = NULL;
173 Status = gBS->InstallProtocolInterface (
174 &Handle,
175 &gExitPmAuthProtocolGuid,
176 EFI_NATIVE_INTERFACE,
177 NULL
178 );
179 ASSERT_EFI_ERROR (Status);
180
181 //
182 // Signal EndOfDxe PI Event
183 //
184 EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
185
186 Handle = NULL;
187 Status = gBS->InstallProtocolInterface (
188 &Handle,
189 &gEfiDxeSmmReadyToLockProtocolGuid,
190 EFI_NATIVE_INTERFACE,
191 NULL
192 );
193 ASSERT_EFI_ERROR (Status);
194 }
195
196 return ;
197 }
198
199 VOID
200 EFIAPI
201 ShellImageCallback (
202 IN EFI_EVENT Event,
203 IN VOID *Context
204 )
205 {
206 BdsSetConsoleMode (TRUE);
207 DEBUG ((EFI_D_INFO, "BdsEntry ShellImageCallback \n"));
208 }
209
210 //
211 // BDS Platform Functions
212 //
213 /**
214 Platform Bds init. Include the platform firmware vendor, revision
215 and so crc check.
216
217 @param VOID
218
219 @retval None.
220
221 **/
222 VOID
223 EFIAPI
224 PlatformBdsInit (
225 VOID
226 )
227 {
228 EFI_STATUS Status;
229 EFI_EVENT ShellImageEvent;
230 EFI_GUID ShellEnvProtocol = SHELL_ENVIRONMENT_INTERFACE_PROTOCOL;
231
232 #ifdef __GNUC__
233 SerialPortWrite((UINT8 *)">>>>BdsEntry[GCC]\r\n", 19);
234 #else
235 SerialPortWrite((UINT8 *)">>>>BdsEntry\r\n", 14);
236 #endif
237 BdsLibSaveMemoryTypeInformation ();
238
239 //
240 // Before user authentication, the user identification devices need be connected
241 // from the platform customized device paths
242 //
243 PlatformBdsConnectAuthDevice ();
244
245 //
246 // As console is not ready, the auto logon user will be identified.
247 //
248 BdsLibUserIdentify (&mCurrentUser);
249
250 //
251 // Change Gop mode when boot into Shell
252 //
253 if (mShellImageCallbackReg == NULL) {
254 Status = gBS->CreateEvent (
255 EFI_EVENT_NOTIFY_SIGNAL,
256 EFI_TPL_CALLBACK,
257 ShellImageCallback,
258 NULL,
259 &ShellImageEvent
260 );
261 if (!EFI_ERROR (Status)) {
262 Status = gBS->RegisterProtocolNotify (
263 &ShellEnvProtocol,
264 ShellImageEvent,
265 &mShellImageCallbackReg
266 );
267
268 DEBUG ((EFI_D_INFO, "BdsEntry ShellImageCallback \n"));
269 }
270 }
271 }
272
273 EFI_STATUS
274 GetGopDevicePath (
275 IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,
276 OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath
277 )
278 {
279 UINTN Index;
280 EFI_STATUS Status;
281 EFI_HANDLE PciDeviceHandle;
282 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
283 EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath;
284 UINTN GopHandleCount;
285 EFI_HANDLE *GopHandleBuffer;
286
287 UINTN VarSize;
288 SYSTEM_CONFIGURATION mSystemConfiguration;
289
290 if (PciDevicePath == NULL || GopDevicePath == NULL) {
291 return EFI_INVALID_PARAMETER;
292 }
293
294 //
295 // Initialize the GopDevicePath to be PciDevicePath
296 //
297 *GopDevicePath = PciDevicePath;
298 TempPciDevicePath = PciDevicePath;
299
300 Status = gBS->LocateDevicePath (
301 &gEfiDevicePathProtocolGuid,
302 &TempPciDevicePath,
303 &PciDeviceHandle
304 );
305 if (EFI_ERROR (Status)) {
306 return Status;
307 }
308
309 //
310 // Try to connect this handle, so that GOP driver could start on this
311 // device and create child handles with GraphicsOutput Protocol installed
312 // on them, then we get device paths of these child handles and select
313 // them as possible console device.
314 //
315
316 //
317 // Select display devices
318 //
319 VarSize = sizeof(SYSTEM_CONFIGURATION);
320 Status = gRT->GetVariable(
321 L"Setup",
322 &gEfiNormalSetupGuid,
323 NULL,
324 &VarSize,
325 &mSystemConfiguration
326 );
327 if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
328 //The setup variable is corrupted
329 VarSize = sizeof(SYSTEM_CONFIGURATION);
330 Status = gRT->GetVariable(
331 L"SetupRecovery",
332 &gEfiNormalSetupGuid,
333 NULL,
334 &VarSize,
335 &mSystemConfiguration
336 );
337 ASSERT_EFI_ERROR (Status);
338 }
339
340 if(mSystemConfiguration.BootDisplayDevice != 0x0)
341 {
342 ACPI_ADR_DEVICE_PATH AcpiAdr;
343 EFI_DEVICE_PATH_PROTOCOL *MyDevicePath = NULL;
344
345 AcpiAdr.Header.Type = ACPI_DEVICE_PATH;
346 AcpiAdr.Header.SubType = ACPI_ADR_DP;
347
348 switch (mSystemConfiguration.BootDisplayDevice) {
349 case 1:
350 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0); //CRT Device
351 break;
352 case 2:
353 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_HDMI, 0); //HDMI Device Port B
354 break;
355 case 3:
356 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_DP, 0); //DP PortB
357 break;
358 case 4:
359 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_C_DP, 0); //DP PortC
360 break;
361 case 5:
362 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_C_DP, 0); //eDP Port C
363 break;
364 case 6:
365 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_A, 0); //DSI Port A
366 break;
367 case 7:
368 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_C, 0); //DSI Port C
369 break;
370 default:
371 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0);
372 break;
373 }
374
375 SetDevicePathNodeLength (&AcpiAdr.Header, sizeof (ACPI_ADR_DEVICE_PATH));
376
377 MyDevicePath = AppendDevicePathNode(MyDevicePath, (EFI_DEVICE_PATH_PROTOCOL*)&AcpiAdr);
378
379 gBS->ConnectController (
380 PciDeviceHandle,
381 NULL,
382 MyDevicePath,
383 FALSE
384 );
385
386 FreePool(MyDevicePath);
387 }
388 else
389 {
390 gBS->ConnectController (
391 PciDeviceHandle,
392 NULL,
393 NULL,
394 FALSE
395 );
396 }
397
398 Status = gBS->LocateHandleBuffer (
399 ByProtocol,
400 &gEfiGraphicsOutputProtocolGuid,
401 NULL,
402 &GopHandleCount,
403 &GopHandleBuffer
404 );
405 if (!EFI_ERROR (Status)) {
406 //
407 // Add all the child handles as possible Console Device
408 //
409 for (Index = 0; Index < GopHandleCount; Index++) {
410 Status = gBS->HandleProtocol (
411 GopHandleBuffer[Index],
412 &gEfiDevicePathProtocolGuid,
413 (VOID**)&TempDevicePath
414 );
415 if (EFI_ERROR (Status)) {
416 continue;
417 }
418 if (CompareMem (
419 PciDevicePath,
420 TempDevicePath,
421 GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH
422 ) == 0) {
423 //
424 // In current implementation, we only enable one of the child handles
425 // as console device, i.e. sotre one of the child handle's device
426 // path to variable "ConOut"
427 // In future, we could select all child handles to be console device
428 //
429 *GopDevicePath = TempDevicePath;
430 }
431 }
432 gBS->FreePool (GopHandleBuffer);
433 }
434
435 return EFI_SUCCESS;
436 }
437
438 /**
439
440 Search out all the platform pci or agp video device. The function may will
441 find multiple video device, and return all enabled device path.
442
443 @param PlugInPciVgaDevicePath Return the platform plug in pci video device
444 path if the system have plug in pci video device.
445 @param OnboardPciVgaDevicePath Return the platform active agp video device path
446 if the system have plug in agp video device or on
447 chip agp device.
448
449 @retval EFI_SUCCSS Get all platform active video device path.
450 @retval EFI_STATUS Return the status of gBS->LocateDevicePath (),
451 gBS->ConnectController (),
452 and gBS->LocateHandleBuffer ().
453
454 **/
455 EFI_STATUS
456 GetPlugInPciVgaDevicePath (
457 IN OUT EFI_DEVICE_PATH_PROTOCOL **PlugInPciVgaDevicePath,
458 IN OUT EFI_DEVICE_PATH_PROTOCOL **OnboardPciVgaDevicePath
459 )
460 {
461 EFI_STATUS Status;
462 EFI_HANDLE RootHandle;
463 UINTN HandleCount;
464 EFI_HANDLE *HandleBuffer;
465 UINTN Index;
466 UINTN Index1;
467 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
468 BOOLEAN PlugInPciVga;
469 EFI_PCI_IO_PROTOCOL *PciIo;
470 PCI_TYPE00 Pci;
471
472 DevicePath = NULL;
473 PlugInPciVga = TRUE;
474 HandleCount = 0;
475 HandleBuffer = NULL;
476
477 //
478 // Make all the PCI_IO protocols on PCI Seg 0 show up
479 //
480 BdsLibConnectDevicePath (gPlatformRootBridges[0]);
481
482 Status = gBS->LocateDevicePath (
483 &gEfiDevicePathProtocolGuid,
484 &gPlatformRootBridges[0],
485 &RootHandle
486 );
487 if (EFI_ERROR (Status)) {
488 return Status;
489 }
490
491 Status = gBS->ConnectController (
492 RootHandle,
493 NULL,
494 NULL,
495 FALSE
496 );
497 if (EFI_ERROR (Status)) {
498 return Status;
499 }
500
501 //
502 // Start to check all the pci io to find all possible VGA device
503 //
504 HandleCount = 0;
505 HandleBuffer = NULL;
506 Status = gBS->LocateHandleBuffer (
507 ByProtocol,
508 &gEfiPciIoProtocolGuid,
509 NULL,
510 &HandleCount,
511 &HandleBuffer
512 );
513 if (EFI_ERROR (Status)) {
514 return Status;
515 }
516
517 for (Index = 0; Index < HandleCount; Index++) {
518 Status = gBS->HandleProtocol (
519 HandleBuffer[Index],
520 &gEfiPciIoProtocolGuid,
521 (VOID**)&PciIo
522 );
523 if (!EFI_ERROR (Status)) {
524
525 //
526 // Check for all VGA device
527 //
528 Status = PciIo->Pci.Read (
529 PciIo,
530 EfiPciIoWidthUint32,
531 0,
532 sizeof (Pci) / sizeof (UINT32),
533 &Pci
534 );
535 if (EFI_ERROR (Status)) {
536 continue;
537 }
538
539 //
540 // Here we decide which VGA device to enable in PCI bus
541 //
542 // The first plugin PCI VGA card device will be present as PCI VGA
543 // The onchip AGP or AGP card will be present as AGP VGA
544 //
545 if (!IS_PCI_VGA (&Pci)) {
546 continue;
547 }
548
549 //
550 // Set the device as the possible console out device,
551 //
552 // Below code will make every VGA device to be one
553 // of the possibe console out device
554 //
555 PlugInPciVga = TRUE;
556 gBS->HandleProtocol (
557 HandleBuffer[Index],
558 &gEfiDevicePathProtocolGuid,
559 (VOID**)&DevicePath
560 );
561
562 Index1 = 0;
563
564 while (gPlatformAllPossiblePciVgaConsole[Index1] != NULL) {
565 if (CompareMem (
566 DevicePath,
567 gPlatformAllPossiblePciVgaConsole[Index1],
568 GetDevicePathSize (gPlatformAllPossiblePciVgaConsole[Index1])
569 ) == 0) {
570
571 //
572 // This device is an AGP device
573 //
574 *OnboardPciVgaDevicePath = DevicePath;
575 PlugInPciVga = FALSE;
576 break;
577 }
578
579 Index1 ++;
580 }
581
582 if (PlugInPciVga) {
583 *PlugInPciVgaDevicePath = DevicePath;
584 }
585 }
586 }
587
588 FreePool (HandleBuffer);
589
590 return EFI_SUCCESS;
591 }
592
593 /**
594
595 Find the platform active vga, and base on the policy to enable the vga as
596 the console out device. The policy is driven by one setup variable "VBIOS".
597
598 None.
599
600 @param EFI_UNSUPPORTED There is no active vga device
601
602 @retval EFI_STATUS Return the status of BdsLibGetVariableAndSize ()
603
604 **/
605 EFI_STATUS
606 PlatformBdsForceActiveVga (
607 VOID
608 )
609 {
610 EFI_STATUS Status;
611 EFI_DEVICE_PATH_PROTOCOL *PlugInPciVgaDevicePath;
612 EFI_DEVICE_PATH_PROTOCOL *OnboardPciVgaDevicePath;
613 EFI_DEVICE_PATH_PROTOCOL *DevicePathFirst;
614 EFI_DEVICE_PATH_PROTOCOL *DevicePathSecond;
615 EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
616 UINTN VarSize;
617 SYSTEM_CONFIGURATION mSystemConfiguration;
618
619 Status = EFI_SUCCESS;
620 PlugInPciVgaDevicePath = NULL;
621 OnboardPciVgaDevicePath = NULL;
622
623 //
624 // Check the policy which is the first enabled VGA
625 //
626 GetPlugInPciVgaDevicePath (&PlugInPciVgaDevicePath, &OnboardPciVgaDevicePath);
627
628 if (PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath == NULL) {
629 return EFI_UNSUPPORTED;
630 }
631
632 VarSize = sizeof(SYSTEM_CONFIGURATION);
633 Status = gRT->GetVariable(
634 L"Setup",
635 &gEfiNormalSetupGuid,
636 NULL,
637 &VarSize,
638 &mSystemConfiguration
639 );
640 if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
641 //The setup variable is corrupted
642 VarSize = sizeof(SYSTEM_CONFIGURATION);
643 Status = gRT->GetVariable(
644 L"SetupRecovery",
645 &gEfiNormalSetupGuid,
646 NULL,
647 &VarSize,
648 &mSystemConfiguration
649 );
650 ASSERT_EFI_ERROR (Status);
651 }
652
653
654 if ((PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath != NULL) ) {
655 DEBUG ((EFI_D_ERROR,"Update onboard PCI VGA ...\n"));
656 DevicePathFirst = OnboardPciVgaDevicePath;
657 DevicePathSecond = PlugInPciVgaDevicePath;
658 goto UpdateConOut;
659 }
660 if(OnboardPciVgaDevicePath != NULL && mSystemConfiguration.PrimaryVideoAdaptor == 0) {
661 DEBUG ((EFI_D_ERROR,"Update onboard PCI VGA When set primary!!!...\n"));
662 DevicePathFirst = OnboardPciVgaDevicePath;
663 DevicePathSecond = PlugInPciVgaDevicePath;
664 goto UpdateConOut;
665 }
666
667 DEBUG ((EFI_D_ERROR,"Update plug in PCI VGA ...\n"));
668 DevicePathFirst = PlugInPciVgaDevicePath;
669 DevicePathSecond = OnboardPciVgaDevicePath;
670
671 UpdateConOut:
672 GetGopDevicePath (DevicePathFirst, &GopDevicePath);
673 DevicePathFirst = GopDevicePath;
674
675 Status = BdsLibUpdateConsoleVariable (
676 L"ConOut",
677 DevicePathFirst,
678 DevicePathSecond
679 );
680
681 return Status;
682 }
683
684 VOID
685 UpdateConsoleResolution(
686 VOID
687 )
688 {
689 UINT32 HorizontalResolution;
690 UINT32 VerticalResolution;
691 SYSTEM_CONFIGURATION SystemConfiguration;
692 UINTN VarSize;
693 EFI_STATUS Status;
694
695
696 HorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
697 VerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
698
699 VarSize = sizeof(SYSTEM_CONFIGURATION);
700 Status = gRT->GetVariable(
701 L"Setup",
702 &gEfiNormalSetupGuid,
703 NULL,
704 &VarSize,
705 &SystemConfiguration
706 );
707 if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
708 //The setup variable is corrupted
709 VarSize = sizeof(SYSTEM_CONFIGURATION);
710 Status = gRT->GetVariable(
711 L"SetupRecovery",
712 &gEfiNormalSetupGuid,
713 NULL,
714 &VarSize,
715 &SystemConfiguration
716 );
717 ASSERT_EFI_ERROR (Status);
718 }
719
720 switch (SystemConfiguration.IgdFlatPanel) {
721
722 case 0:
723 //
724 // Use the detault PCD values.
725 //
726 break;
727
728 case 1:
729 HorizontalResolution = 640;
730 VerticalResolution = 480;
731 break;
732
733 case 2:
734 HorizontalResolution = 800;
735 VerticalResolution = 600;
736 break;
737
738 case 3:
739 HorizontalResolution = 1024;
740 VerticalResolution = 768;
741 break;
742
743 case 4:
744 HorizontalResolution = 1280;
745 VerticalResolution = 1024;
746 break;
747
748 case 5:
749 HorizontalResolution = 1366;
750 VerticalResolution = 768;
751 break;
752
753 case 6:
754 HorizontalResolution = 1680;
755 VerticalResolution = 1050;
756 break;
757
758 case 7:
759 HorizontalResolution = 1920;
760 VerticalResolution = 1200;
761 break;
762
763 case 8:
764 HorizontalResolution = 1280;
765 VerticalResolution = 800;
766 break;
767 }
768
769 PcdSet32 (PcdSetupVideoHorizontalResolution, HorizontalResolution);
770 PcdSet32 (PcdSetupVideoVerticalResolution, VerticalResolution);
771 DEBUG ((EFI_D_ERROR, "HorizontalResolution = %x; VerticalResolution = %x", HorizontalResolution, VerticalResolution));
772
773 return;
774 }
775
776 /**
777 Connect the predefined platform default console device. Always try to find
778 and enable the vga device if have.
779
780 @param PlatformConsole Predefined platform default console device array.
781
782 @retval EFI_SUCCESS Success connect at least one ConIn and ConOut
783 device, there must have one ConOut device is
784 active vga device.
785
786 @retval EFI_STATUS Return the status of
787 BdsLibConnectAllDefaultConsoles ()
788
789 **/
790 EFI_STATUS
791 PlatformBdsConnectConsole (
792 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
793 )
794 {
795 EFI_STATUS Status;
796 UINTN Index;
797 EFI_DEVICE_PATH_PROTOCOL *VarConout;
798 EFI_DEVICE_PATH_PROTOCOL *VarConin;
799 UINTN DevicePathSize;
800
801 UpdateConsoleResolution();
802
803 Index = 0;
804 Status = EFI_SUCCESS;
805 DevicePathSize = 0;
806 VarConout = BdsLibGetVariableAndSize (
807 L"ConOut",
808 &gEfiGlobalVariableGuid,
809 &DevicePathSize
810 );
811 VarConin = BdsLibGetVariableAndSize (
812 L"ConIn",
813 &gEfiGlobalVariableGuid,
814 &DevicePathSize
815 );
816 if (VarConout == NULL || VarConin == NULL) {
817 //
818 // Have chance to connect the platform default console,
819 // the platform default console is the minimum device group
820 // the platform should support
821 //
822 while (PlatformConsole[Index].DevicePath != NULL) {
823
824 //
825 // Update the console variable with the connect type
826 //
827 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
828 BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);
829 }
830
831 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
832 BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);
833 }
834
835 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
836 BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);
837 }
838
839 Index ++;
840 }
841 }
842
843 //
844 // Make sure we have at least one active VGA, and have the right
845 // active VGA in console variable
846 //
847 Status = PlatformBdsForceActiveVga ();
848 if (EFI_ERROR (Status)) {
849 return Status;
850 }
851
852 DEBUG ((EFI_D_INFO, "DISPLAY INIT DONE\n"));
853
854 //
855 // Connect the all the default console with current console variable
856 //
857 Status = BdsLibConnectAllDefaultConsoles ();
858 if (EFI_ERROR (Status)) {
859 return Status;
860 }
861
862 return EFI_SUCCESS;
863 }
864
865 /**
866 Connect with predefined platform connect sequence,
867 the OEM/IBV can customize with their own connect sequence.
868
869 @param None.
870
871 @retval None.
872
873 **/
874 VOID
875 PlatformBdsConnectSequence (
876 VOID
877 )
878 {
879 UINTN Index;
880
881 Index = 0;
882
883 //
884 // Here we can get the customized platform connect sequence
885 // Notes: we can connect with new variable which record the
886 // last time boots connect device path sequence
887 //
888 while (gPlatformConnectSequence[Index] != NULL) {
889
890 //
891 // Build the platform boot option
892 //
893 BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);
894 Index ++;
895 }
896
897 //
898 // Just use the simple policy to connect all devices
899 // There should be no difference between debug tip and release tip, or it will be extremely hard to debug.
900 //
901 // There is case that IdeController driver will write boot script in driver model Start() function. It will be rejected by boot script save.
902 // It is only found when DEBUG disabled, because we are using BdsLibConnectAll() when DEBUG enabled.
903 //
904 // So we use BdsLibConnectAll() here to make sure IdeController.Start() is invoked before InstallReadyToLock().
905 // We may also consider to connect SataController only later if needed.
906 //
907 BdsLibConnectAll ();
908 }
909
910 /**
911
912 Load the predefined driver option, OEM/IBV can customize this
913 to load their own drivers
914
915 @param BdsDriverLists The header of the driver option link list.
916
917 @retval None.
918
919 **/
920 VOID
921 PlatformBdsGetDriverOption (
922 IN OUT LIST_ENTRY *BdsDriverLists
923 )
924 {
925 UINTN Index;
926
927 Index = 0;
928
929 //
930 // Here we can get the customized platform driver option
931 //
932 while (gPlatformDriverOption[Index] != NULL) {
933
934 //
935 // Build the platform boot option
936 //
937 BdsLibRegisterNewOption (BdsDriverLists, gPlatformDriverOption[Index], NULL, L"DriverOrder");
938 Index ++;
939 }
940
941 }
942
943 /**
944 This function is used for some critical time if the the system
945 have no any boot option, and there is no time out for user to add
946 the new boot option. This can also treat as the platform default
947 boot option.
948
949 @param BdsBootOptionList The header of the boot option link list.
950
951 @retval None.
952
953 **/
954 VOID
955 PlatformBdsPredictBootOption (
956 IN OUT LIST_ENTRY *BdsBootOptionList
957 )
958 {
959 UINTN Index;
960
961 Index = 0;
962
963 //
964 // Here give chance to get platform boot option data
965 //
966 while (gPlatformBootOption[Index] != NULL) {
967
968 //
969 // Build the platform boot option
970 //
971 BdsLibRegisterNewOption (BdsBootOptionList, gPlatformBootOption[Index], NULL, L"BootOrder");
972 Index ++;
973 }
974 }
975
976 /**
977 Perform the platform diagnostic, such like test memory. OEM/IBV also
978 can customize this fuction to support specific platform diagnostic.
979
980 @param MemoryTestLevel The memory test intensive level
981 @param QuietBoot Indicate if need to enable the quiet boot
982 @param BaseMemoryTest A pointer to BdsMemoryTest()
983
984 @retval None.
985
986 **/
987 VOID
988 PlatformBdsDiagnostics (
989 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,
990 IN BOOLEAN QuietBoot,
991 IN BASEM_MEMORY_TEST BaseMemoryTest
992 )
993 {
994 EFI_STATUS Status;
995
996 //
997 // Here we can decide if we need to show
998 // the diagnostics screen
999 // Notes: this quiet boot code should be remove
1000 // from the graphic lib
1001 //
1002 if (QuietBoot) {
1003 EnableQuietBoot (PcdGetPtr(PcdLogoFile));
1004
1005 //
1006 // Perform system diagnostic
1007 //
1008 Status = BaseMemoryTest (MemoryTestLevel);
1009 if (EFI_ERROR (Status)) {
1010 DisableQuietBoot ();
1011 }
1012
1013 return;
1014 }
1015
1016 //
1017 // Perform system diagnostic
1018 //
1019 Status = BaseMemoryTest (MemoryTestLevel);
1020 }
1021
1022
1023 /**
1024 For EFI boot option, BDS separate them as six types:
1025 1. Network - The boot option points to the SimpleNetworkProtocol device.
1026 Bds will try to automatically create this type boot option when enumerate.
1027 2. Shell - The boot option points to internal flash shell.
1028 Bds will try to automatically create this type boot option when enumerate.
1029 3. Removable BlockIo - The boot option only points to the removable media
1030 device, like USB flash disk, DVD, Floppy etc.
1031 These device should contain a *removable* blockIo
1032 protocol in their device handle.
1033 Bds will try to automatically create this type boot option
1034 when enumerate.
1035 4. Fixed BlockIo - The boot option only points to a Fixed blockIo device,
1036 like HardDisk.
1037 These device should contain a *fixed* blockIo
1038 protocol in their device handle.
1039 BDS will skip fixed blockIo devices, and NOT
1040 automatically create boot option for them. But BDS
1041 will help to delete those fixed blockIo boot option,
1042 whose description rule conflict with other auto-created
1043 boot options.
1044 5. Non-BlockIo Simplefile - The boot option points to a device whose handle
1045 has SimpleFileSystem Protocol, but has no blockio
1046 protocol. These devices do not offer blockIo
1047 protocol, but BDS still can get the
1048 \EFI\BOOT\boot{machinename}.EFI by SimpleFileSystem
1049 Protocol.
1050 6. File - The boot option points to a file. These boot options are usually
1051 created by user manually or OS loader. BDS will not delete or modify
1052 these boot options.
1053
1054 This function will enumerate all possible boot device in the system, and
1055 automatically create boot options for Network, Shell, Removable BlockIo,
1056 and Non-BlockIo Simplefile devices.
1057 It will only execute once of every boot.
1058
1059 @param BdsBootOptionList The header of the link list which indexed all
1060 current boot options
1061
1062 @retval EFI_SUCCESS Finished all the boot device enumerate and create
1063 the boot option base on that boot device
1064
1065 @retval EFI_OUT_OF_RESOURCES Failed to enumerate the boot device and create the boot option list
1066 **/
1067 EFI_STATUS
1068 EFIAPI
1069 PlatformBdsLibEnumerateAllBootOption (
1070 IN OUT LIST_ENTRY *BdsBootOptionList
1071 )
1072 {
1073 EFI_STATUS Status;
1074 UINT16 FloppyNumber;
1075 UINT16 HarddriveNumber;
1076 UINT16 CdromNumber;
1077 UINT16 UsbNumber;
1078 UINT16 MiscNumber;
1079 UINT16 ScsiNumber;
1080 UINT16 NonBlockNumber;
1081 UINTN NumberBlockIoHandles;
1082 EFI_HANDLE *BlockIoHandles;
1083 EFI_BLOCK_IO_PROTOCOL *BlkIo;
1084 BOOLEAN Removable[2];
1085 UINTN RemovableIndex;
1086 UINTN Index;
1087 UINTN NumOfLoadFileHandles;
1088 EFI_HANDLE *LoadFileHandles;
1089 UINTN FvHandleCount;
1090 EFI_HANDLE *FvHandleBuffer;
1091 EFI_FV_FILETYPE Type;
1092 UINTN Size;
1093 EFI_FV_FILE_ATTRIBUTES Attributes;
1094 UINT32 AuthenticationStatus;
1095 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
1096 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
1097 UINTN DevicePathType;
1098 CHAR16 Buffer[40];
1099 EFI_HANDLE *FileSystemHandles;
1100 UINTN NumberFileSystemHandles;
1101 BOOLEAN NeedDelete;
1102 EFI_IMAGE_DOS_HEADER DosHeader;
1103 CHAR8 *PlatLang;
1104 CHAR8 *LastLang;
1105 EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData;
1106 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
1107 CHAR16 *MacStr;
1108 CHAR16 *IPverStr;
1109 EFI_HANDLE *NetworkHandles;
1110 UINTN BufferSize;
1111
1112 FloppyNumber = 0;
1113 HarddriveNumber = 0;
1114 CdromNumber = 0;
1115 UsbNumber = 0;
1116 MiscNumber = 0;
1117 ScsiNumber = 0;
1118 PlatLang = NULL;
1119 LastLang = NULL;
1120 ZeroMem (Buffer, sizeof (Buffer));
1121
1122 //
1123 // If the boot device enumerate happened, just get the boot
1124 // device from the boot order variable
1125 //
1126 if (mEnumBootDevice) {
1127 GetVariable2 (LAST_ENUM_LANGUAGE_VARIABLE_NAME, &gLastEnumLangGuid, (VOID**)&LastLang, NULL);
1128 GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&PlatLang, NULL);
1129 ASSERT (PlatLang != NULL);
1130 if ((LastLang != NULL) && (AsciiStrCmp (LastLang, PlatLang) == 0)) {
1131 Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
1132 FreePool (LastLang);
1133 FreePool (PlatLang);
1134 return Status;
1135 } else {
1136 Status = gRT->SetVariable (
1137 LAST_ENUM_LANGUAGE_VARIABLE_NAME,
1138 &gLastEnumLangGuid,
1139 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
1140 AsciiStrSize (PlatLang),
1141 PlatLang
1142 );
1143 //
1144 // Failure to set the variable only impacts the performance next time enumerating the boot options.
1145 //
1146
1147 if (LastLang != NULL) {
1148 FreePool (LastLang);
1149 }
1150 FreePool (PlatLang);
1151 }
1152 }
1153
1154 //
1155 // Notes: this dirty code is to get the legacy boot option from the
1156 // BBS table and create to variable as the EFI boot option, it should
1157 // be removed after the CSM can provide legacy boot option directly
1158 //
1159 REFRESH_LEGACY_BOOT_OPTIONS;
1160
1161 //
1162 // Delete invalid boot option
1163 //
1164 BdsDeleteAllInvalidEfiBootOption ();
1165
1166 //
1167 // Parse removable media followed by fixed media.
1168 // The Removable[] array is used by the for-loop below to create removable media boot options
1169 // at first, and then to create fixed media boot options.
1170 //
1171 Removable[0] = FALSE;
1172 Removable[1] = TRUE;
1173
1174 gBS->LocateHandleBuffer (
1175 ByProtocol,
1176 &gEfiBlockIoProtocolGuid,
1177 NULL,
1178 &NumberBlockIoHandles,
1179 &BlockIoHandles
1180 );
1181
1182 for (RemovableIndex = 0; RemovableIndex < 2; RemovableIndex++) {
1183 for (Index = 0; Index < NumberBlockIoHandles; Index++) {
1184 Status = gBS->HandleProtocol (
1185 BlockIoHandles[Index],
1186 &gEfiBlockIoProtocolGuid,
1187 (VOID **) &BlkIo
1188 );
1189 //
1190 // skip the logical partition
1191 //
1192 if (EFI_ERROR (Status) || BlkIo->Media->LogicalPartition) {
1193 continue;
1194 }
1195
1196 //
1197 // firstly fixed block io then the removable block io
1198 //
1199 if (BlkIo->Media->RemovableMedia == Removable[RemovableIndex]) {
1200 continue;
1201 }
1202 DevicePath = DevicePathFromHandle (BlockIoHandles[Index]);
1203 DevicePathType = BdsGetBootTypeFromDevicePath (DevicePath);
1204
1205 switch (DevicePathType) {
1206 case BDS_EFI_ACPI_FLOPPY_BOOT:
1207 if (FloppyNumber != 0) {
1208 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)), FloppyNumber);
1209 } else {
1210 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)));
1211 }
1212 BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
1213 FloppyNumber++;
1214 break;
1215
1216 //
1217 // Assume a removable SATA device should be the DVD/CD device, a fixed SATA device should be the Hard Drive device.
1218 //
1219 case BDS_EFI_MESSAGE_ATAPI_BOOT:
1220 case BDS_EFI_MESSAGE_SATA_BOOT:
1221 if (BlkIo->Media->RemovableMedia) {
1222 if (CdromNumber != 0) {
1223 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)), CdromNumber);
1224 } else {
1225 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)));
1226 }
1227 CdromNumber++;
1228 } else {
1229 if (HarddriveNumber != 0) {
1230 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)), HarddriveNumber);
1231 } else {
1232 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)));
1233 }
1234 HarddriveNumber++;
1235 }
1236 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Buffer: %S\n", Buffer));
1237 BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
1238 break;
1239
1240 case BDS_EFI_MESSAGE_USB_DEVICE_BOOT:
1241 if (UsbNumber != 0) {
1242 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)), UsbNumber);
1243 } else {
1244 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)));
1245 }
1246 BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
1247 UsbNumber++;
1248 break;
1249
1250 case BDS_EFI_MESSAGE_SCSI_BOOT:
1251 if (ScsiNumber != 0) {
1252 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)), ScsiNumber);
1253 } else {
1254 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)));
1255 }
1256 BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
1257 ScsiNumber++;
1258 break;
1259
1260 case BDS_EFI_MESSAGE_MISC_BOOT:
1261 default:
1262 if (MiscNumber != 0) {
1263 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)), MiscNumber);
1264 } else {
1265 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)));
1266 }
1267 BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
1268 MiscNumber++;
1269 break;
1270 }
1271 }
1272 }
1273
1274 if (NumberBlockIoHandles != 0) {
1275 FreePool (BlockIoHandles);
1276 }
1277
1278 //
1279 // If there is simple file protocol which does not consume block Io protocol, create a boot option for it here.
1280 //
1281 NonBlockNumber = 0;
1282 gBS->LocateHandleBuffer (
1283 ByProtocol,
1284 &gEfiSimpleFileSystemProtocolGuid,
1285 NULL,
1286 &NumberFileSystemHandles,
1287 &FileSystemHandles
1288 );
1289 for (Index = 0; Index < NumberFileSystemHandles; Index++) {
1290 Status = gBS->HandleProtocol (
1291 FileSystemHandles[Index],
1292 &gEfiBlockIoProtocolGuid,
1293 (VOID **) &BlkIo
1294 );
1295 if (!EFI_ERROR (Status)) {
1296 //
1297 // Skip if the file system handle supports a BlkIo protocol,
1298 //
1299 continue;
1300 }
1301
1302 //
1303 // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
1304 // machinename is ia32, ia64, x64, ...
1305 //
1306 Hdr.Union = &HdrData;
1307 NeedDelete = TRUE;
1308 Status = BdsLibGetImageHeader (
1309 FileSystemHandles[Index],
1310 EFI_REMOVABLE_MEDIA_FILE_NAME,
1311 &DosHeader,
1312 Hdr
1313 );
1314 if (!EFI_ERROR (Status) &&
1315 EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) &&
1316 Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
1317 NeedDelete = FALSE;
1318 }
1319
1320 if (NeedDelete) {
1321 //
1322 // No such file or the file is not a EFI application, delete this boot option
1323 //
1324 BdsLibDeleteOptionFromHandle (FileSystemHandles[Index]);
1325 } else {
1326 if (NonBlockNumber != 0) {
1327 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)), NonBlockNumber);
1328 } else {
1329 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)));
1330 }
1331 BdsLibBuildOptionFromHandle (FileSystemHandles[Index], BdsBootOptionList, Buffer);
1332 NonBlockNumber++;
1333 }
1334 }
1335
1336 if (NumberFileSystemHandles != 0) {
1337 FreePool (FileSystemHandles);
1338 }
1339
1340 //
1341 // Check if we have on flash shell
1342 //
1343 gBS->LocateHandleBuffer (
1344 ByProtocol,
1345 &gEfiFirmwareVolume2ProtocolGuid,
1346 NULL,
1347 &FvHandleCount,
1348 &FvHandleBuffer
1349 );
1350 for (Index = 0; Index < FvHandleCount; Index++) {
1351 gBS->HandleProtocol (
1352 FvHandleBuffer[Index],
1353 &gEfiFirmwareVolume2ProtocolGuid,
1354 (VOID **) &Fv
1355 );
1356
1357 Status = Fv->ReadFile (
1358 Fv,
1359 &gUefiShellFileGuid,
1360 NULL,
1361 &Size,
1362 &Type,
1363 &Attributes,
1364 &AuthenticationStatus
1365 );
1366 if (EFI_ERROR (Status)) {
1367 //
1368 // Skip if no shell file in the FV
1369 //
1370 continue;
1371 }
1372 //
1373 // Build the shell boot option
1374 //
1375 BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);
1376 }
1377
1378 if (FvHandleCount != 0) {
1379 FreePool (FvHandleBuffer);
1380 }
1381
1382 //
1383 // Parse Network Boot Device
1384 //
1385 NumOfLoadFileHandles = 0;
1386 //
1387 // Search Load File protocol for PXE boot option.
1388 //
1389 gBS->LocateHandleBuffer (
1390 ByProtocol,
1391 &gEfiLoadFileProtocolGuid,
1392 NULL,
1393 &NumOfLoadFileHandles,
1394 &LoadFileHandles
1395 );
1396
1397 for (Index = 0; Index < NumOfLoadFileHandles; Index++) {
1398
1399 //
1400 //Locate EFI_DEVICE_PATH_PROTOCOL to dynamically get IPv4/IPv6 protocol information.
1401 //
1402
1403 Status = gBS->HandleProtocol (
1404 LoadFileHandles[Index],
1405 &gEfiDevicePathProtocolGuid,
1406 (VOID **) &DevicePath
1407 );
1408
1409 ASSERT_EFI_ERROR (Status);
1410
1411 while (!IsDevicePathEnd (DevicePath)) {
1412 if ((DevicePath->Type == MESSAGING_DEVICE_PATH) &&
1413 (DevicePath->SubType == MSG_IPv4_DP)) {
1414
1415 //
1416 //Get handle infomation
1417 //
1418 BufferSize = 0;
1419 NetworkHandles = NULL;
1420 Status = gBS->LocateHandle (
1421 ByProtocol,
1422 &gEfiSimpleNetworkProtocolGuid,
1423 NULL,
1424 &BufferSize,
1425 NetworkHandles
1426 );
1427
1428 if (Status == EFI_BUFFER_TOO_SMALL) {
1429 NetworkHandles = AllocateZeroPool(BufferSize);
1430 if (NetworkHandles == NULL) {
1431 return (EFI_OUT_OF_RESOURCES);
1432 }
1433 Status = gBS->LocateHandle(
1434 ByProtocol,
1435 &gEfiSimpleNetworkProtocolGuid,
1436 NULL,
1437 &BufferSize,
1438 NetworkHandles
1439 );
1440 }
1441
1442 //
1443 //Get the MAC string
1444 //
1445 Status = NetLibGetMacString (
1446 *NetworkHandles,
1447 NULL,
1448 &MacStr
1449 );
1450 if (EFI_ERROR (Status)) {
1451 return Status;
1452 }
1453 IPverStr = L" IPv4";
1454 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s%s%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK)),MacStr,IPverStr);
1455 break;
1456 }
1457 if((DevicePath->Type == MESSAGING_DEVICE_PATH) &&
1458 (DevicePath->SubType == MSG_IPv6_DP)) {
1459
1460 //
1461 //Get handle infomation
1462 //
1463 BufferSize = 0;
1464 NetworkHandles = NULL;
1465 Status = gBS->LocateHandle (
1466 ByProtocol,
1467 &gEfiSimpleNetworkProtocolGuid,
1468 NULL,
1469 &BufferSize,
1470 NetworkHandles
1471 );
1472
1473 if (Status == EFI_BUFFER_TOO_SMALL) {
1474 NetworkHandles = AllocateZeroPool(BufferSize);
1475 if (NetworkHandles == NULL) {
1476 return (EFI_OUT_OF_RESOURCES);
1477 }
1478 Status = gBS->LocateHandle(
1479 ByProtocol,
1480 &gEfiSimpleNetworkProtocolGuid,
1481 NULL,
1482 &BufferSize,
1483 NetworkHandles
1484 );
1485 }
1486
1487 //
1488 //Get the MAC string
1489 //
1490 Status = NetLibGetMacString (
1491 *NetworkHandles,
1492 NULL,
1493 &MacStr
1494 );
1495 if (EFI_ERROR (Status)) {
1496 return Status;
1497 }
1498 IPverStr = L" IPv6";
1499 UnicodeSPrint (Buffer, sizeof (Buffer), L"%s%s%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK)),MacStr,IPverStr);
1500 break;
1501 }
1502 DevicePath = NextDevicePathNode (DevicePath);
1503 }
1504
1505 BdsLibBuildOptionFromHandle (LoadFileHandles[Index], BdsBootOptionList, Buffer);
1506 }
1507
1508 if (NumOfLoadFileHandles != 0) {
1509 FreePool (LoadFileHandles);
1510 }
1511
1512 //
1513 // Check if we have on flash shell
1514 //
1515 /* gBS->LocateHandleBuffer (
1516 ByProtocol,
1517 &gEfiFirmwareVolume2ProtocolGuid,
1518 NULL,
1519 &FvHandleCount,
1520 &FvHandleBuffer
1521 );
1522 for (Index = 0; Index < FvHandleCount; Index++) {
1523 gBS->HandleProtocol (
1524 FvHandleBuffer[Index],
1525 &gEfiFirmwareVolume2ProtocolGuid,
1526 (VOID **) &Fv
1527 );
1528
1529 Status = Fv->ReadFile (
1530 Fv,
1531 &gUefiShellFileGuid,
1532 NULL,
1533 &Size,
1534 &Type,
1535 &Attributes,
1536 &AuthenticationStatus
1537 );
1538 if (EFI_ERROR (Status)) {
1539 //
1540 // Skip if no shell file in the FV
1541 //
1542 continue;
1543 }
1544 //
1545 // Build the shell boot option
1546 //
1547 BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);
1548 }
1549
1550 if (FvHandleCount != 0) {
1551 FreePool (FvHandleBuffer);
1552 } */
1553
1554 //
1555 // Make sure every boot only have one time
1556 // boot device enumerate
1557 //
1558 Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
1559 mEnumBootDevice = TRUE;
1560
1561 return Status;
1562 }
1563
1564
1565
1566 /**
1567
1568 The function will execute with as the platform policy, current policy
1569 is driven by boot mode. IBV/OEM can customize this code for their specific
1570 policy action.
1571
1572 @param DriverOptionList - The header of the driver option link list
1573 @param BootOptionList - The header of the boot option link list
1574 @param ProcessCapsules - A pointer to ProcessCapsules()
1575 @param BaseMemoryTest - A pointer to BaseMemoryTest()
1576
1577 @retval None.
1578
1579 **/
1580 VOID
1581 EFIAPI
1582 PlatformBdsPolicyBehavior (
1583 IN OUT LIST_ENTRY *DriverOptionList,
1584 IN OUT LIST_ENTRY *BootOptionList,
1585 IN PROCESS_CAPSULES BdsProcessCapsules,
1586 IN BASEM_MEMORY_TEST BaseMemoryTest
1587 )
1588 {
1589 EFI_STATUS Status;
1590 UINT16 Timeout;
1591 EFI_BOOT_MODE BootMode;
1592 BOOLEAN DeferredImageExist;
1593 UINTN Index;
1594 SYSTEM_CONFIGURATION SystemConfiguration;
1595 UINTN VarSize;
1596 PLATFORM_PCI_DEVICE_PATH *EmmcBootDevPath;
1597 EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsArea;
1598 EFI_HANDLE FvProtocolHandle;
1599 UINTN HandleCount;
1600 EFI_HANDLE *HandleBuffer;
1601 UINTN Index1;
1602 UINTN SataPciRegBase = 0;
1603 UINT16 SataModeSelect = 0;
1604 VOID *RegistrationExitPmAuth = NULL;
1605 EFI_EVENT Event;
1606 BOOLEAN IsFirstBoot;
1607 UINT16 *BootOrder;
1608 UINTN BootOrderSize;
1609 ESRT_MANAGEMENT_PROTOCOL *EsrtManagement;
1610
1611 Timeout = PcdGet16 (PcdPlatformBootTimeOut);
1612 if (Timeout > 10 ) {
1613 //we think the Timeout variable is corrupted
1614 Timeout = 10;
1615 }
1616
1617 VarSize = sizeof(SYSTEM_CONFIGURATION);
1618 Status = gRT->GetVariable(
1619 NORMAL_SETUP_NAME,
1620 &gEfiNormalSetupGuid,
1621 NULL,
1622 &VarSize,
1623 &SystemConfiguration
1624 );
1625
1626 if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
1627 //The setup variable is corrupted
1628 VarSize = sizeof(SYSTEM_CONFIGURATION);
1629 Status = gRT->GetVariable(
1630 L"SetupRecovery",
1631 &gEfiNormalSetupGuid,
1632 NULL,
1633 &VarSize,
1634 &SystemConfiguration
1635 );
1636 ASSERT_EFI_ERROR (Status);
1637 }
1638
1639 //
1640 // Load the driver option as the driver option list
1641 //
1642 PlatformBdsGetDriverOption (DriverOptionList);
1643
1644 //
1645 // Get current Boot Mode
1646 //
1647 BootMode = GetBootModeHob();
1648
1649 //
1650 // No deferred images exist by default
1651 //
1652 DeferredImageExist = FALSE;
1653 if ((BootMode != BOOT_WITH_MINIMAL_CONFIGURATION) && (PcdGet32(PcdFlashFvShellSize) > 0)){
1654 gDS->ProcessFirmwareVolume (
1655 (VOID *)(UINTN)PcdGet32(PcdFlashFvShellBase),
1656 PcdGet32(PcdFlashFvShellSize),
1657 &FvProtocolHandle
1658 );
1659 }
1660
1661 if (SystemConfiguration.FastBoot == 1) {
1662 BootOrder = BdsLibGetVariableAndSize (
1663 L"BootOrder",
1664 &gEfiGlobalVariableGuid,
1665 &BootOrderSize
1666 );
1667 if ((BootOrder != NULL) && (BootMode != BOOT_ON_FLASH_UPDATE)) {
1668 //
1669 // BootOrder exist, it means system has boot before. We can do fast boot.
1670 //
1671 BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;
1672 }
1673 }
1674
1675
1676 //
1677 // Use eMMC to boot OS and turn on AHCI, when SATA HDD is diconnected,
1678 // SATA AHCI CTLR device will show yellow bang, implement this solution to solve it.
1679 //
1680 SataPciRegBase = MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, 0, 0);
1681 SataModeSelect = MmioRead16 (SataPciRegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK;
1682 Status = EFI_SUCCESS;
1683 if (SataModeSelect != V_PCH_SATA_MAP_SMS_IDE) {
1684 Status = gBS->CreateEvent (
1685 EVT_NOTIFY_SIGNAL,
1686 TPL_CALLBACK,
1687 DisableAhciCtlr,
1688 &SataPciRegBase,
1689 &Event
1690 );
1691 if (!EFI_ERROR (Status)) {
1692 Status = gBS->RegisterProtocolNotify (
1693 &gExitPmAuthProtocolGuid,
1694 Event,
1695 &RegistrationExitPmAuth
1696 );
1697 }
1698 }
1699
1700 Status = gBS->LocateProtocol(&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtManagement);
1701 if (EFI_ERROR(Status)) {
1702 EsrtManagement = NULL;
1703 }
1704
1705 DEBUG ((DEBUG_INFO, "BDS: BootMode=%02x\n", BootMode));
1706
1707 switch (BootMode) {
1708
1709 case BOOT_WITH_MINIMAL_CONFIGURATION:
1710 PlatformBdsInitHotKeyEvent ();
1711 PlatformBdsConnectSimpleConsole (gPlatformSimpleConsole);
1712
1713
1714 //
1715 // Check to see if it's needed to dispatch more DXE drivers.
1716 //
1717 for (Index = 0; Index < sizeof(ConnectDriverTable)/sizeof(EFI_GUID *); Index++) {
1718 Status = gBS->LocateHandleBuffer (
1719 ByProtocol,
1720 ConnectDriverTable[Index],
1721 NULL,
1722 &HandleCount,
1723 &HandleBuffer
1724 );
1725 if (!EFI_ERROR (Status)) {
1726 for (Index1 = 0; Index1 < HandleCount; Index1++) {
1727 gBS->ConnectController (
1728 HandleBuffer[Index1],
1729 NULL,
1730 NULL,
1731 TRUE
1732 );
1733 }
1734 }
1735
1736 if (HandleBuffer != NULL) {
1737 FreePool (HandleBuffer);
1738 }
1739
1740 gDS->Dispatch ();
1741 }
1742
1743 //
1744 // Locate the Global NVS Protocol.
1745 //
1746 Status = gBS->LocateProtocol (
1747 &gEfiGlobalNvsAreaProtocolGuid,
1748 NULL,
1749 (void **)&GlobalNvsArea
1750 );
1751 if (GlobalNvsArea->Area->emmcVersion == 0){
1752 EmmcBootDevPath = (PLATFORM_PCI_DEVICE_PATH *)gPlatformSimpleBootOption[0];
1753 EmmcBootDevPath->PciDevice.Device = 0x10;
1754 }
1755
1756 //
1757 // Connect boot device here to give time to read keyboard.
1758 //
1759 BdsLibConnectDevicePath (gPlatformSimpleBootOption[0]);
1760
1761 //
1762 // This is a workround for dectecting hotkey from USB keyboard.
1763 //
1764 gBS->Stall(KEYBOARD_TIMER_INTERVAL);
1765
1766 if (mHotKeyTimerEvent != NULL) {
1767 gBS->SetTimer (
1768 mHotKeyTimerEvent,
1769 TimerCancel,
1770 0
1771 );
1772 gBS->CloseEvent (mHotKeyTimerEvent);
1773 mHotKeyTimerEvent = NULL;
1774 }
1775 if (mHotKeyPressed) {
1776 //
1777 // Skip show progress count down
1778 //
1779 Timeout = 0xFFFF;
1780 goto FULL_CONFIGURATION;
1781 }
1782
1783 EnableQuietBoot (PcdGetPtr(PcdLogoFile));
1784 if (!SystemConfiguration.QuietBoot) {
1785 PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest);
1786 }
1787
1788
1789 #ifdef TPM_ENABLED
1790 TcgPhysicalPresenceLibProcessRequest();
1791 #endif
1792 #ifdef FTPM_ENABLE
1793 Tcg2PhysicalPresenceLibProcessRequest(NULL);
1794 #endif
1795
1796 if (EsrtManagement != NULL) {
1797 EsrtManagement->LockEsrtRepository();
1798 }
1799
1800 //
1801 // Close boot script and install ready to lock
1802 //
1803 InstallReadyToLock ();
1804
1805 //
1806 // Give one chance to enter the setup if we
1807 // select Gummiboot "Reboot Into Firmware Interface" and Fast Boot is enabled.
1808 //
1809 BootIntoFirmwareInterface();
1810 break;
1811
1812 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
1813
1814 //
1815 // In no-configuration boot mode, we can connect the
1816 // console directly.
1817 //
1818 BdsLibConnectAllDefaultConsoles ();
1819 PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);
1820
1821 //
1822 // Perform some platform specific connect sequence
1823 //
1824 PlatformBdsConnectSequence ();
1825
1826 //
1827 // As console is ready, perform user identification again.
1828 //
1829 if (mCurrentUser == NULL) {
1830 PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
1831 if (DeferredImageExist) {
1832 //
1833 // After user authentication, the deferred drivers was loaded again.
1834 // Here, need to ensure the deferred images are connected.
1835 //
1836 BdsLibConnectAllDefaultConsoles ();
1837 PlatformBdsConnectSequence ();
1838 }
1839 }
1840
1841 if (EsrtManagement != NULL) {
1842 EsrtManagement->LockEsrtRepository();
1843 }
1844
1845 //
1846 // Close boot script and install ready to lock
1847 //
1848 InstallReadyToLock ();
1849
1850 //
1851 // Notes: current time out = 0 can not enter the
1852 // front page
1853 //
1854 PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
1855
1856 //
1857 // Check the boot option with the boot option list
1858 //
1859 BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
1860 break;
1861
1862 case BOOT_ON_FLASH_UPDATE:
1863
1864 //
1865 // Boot with the specific configuration
1866 //
1867 PlatformBdsConnectConsole (gPlatformConsole);
1868 PlatformBdsDiagnostics (EXTENSIVE, TRUE, BaseMemoryTest);
1869
1870 DEBUG((DEBUG_INFO, "ProcessCapsules Before EndOfDxe......\n"));
1871 ProcessCapsules ();
1872 DEBUG((DEBUG_INFO, "ProcessCapsules Done\n"));
1873
1874 //
1875 // Close boot script and install ready to lock
1876 //
1877 InstallReadyToLock ();
1878
1879 BdsLibConnectAll ();
1880
1881 //
1882 // Perform user identification
1883 //
1884 if (mCurrentUser == NULL) {
1885 PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
1886 if (DeferredImageExist) {
1887 //
1888 // After user authentication, the deferred drivers was loaded again.
1889 // Here, need to ensure the deferred images are connected.
1890 //
1891 BdsLibConnectAll ();
1892 }
1893 }
1894
1895 if (EsrtManagement != NULL) {
1896 EsrtManagement->SyncEsrtFmp();
1897 }
1898
1899 DEBUG((DEBUG_INFO, "ProcessCapsules After ConnectAll......\n"));
1900 ProcessCapsules();
1901 DEBUG((DEBUG_INFO, "ProcessCapsules Done\n"));
1902 break;
1903
1904 case BOOT_IN_RECOVERY_MODE:
1905
1906 //
1907 // In recovery mode, just connect platform console
1908 // and show up the front page
1909 //
1910 PlatformBdsConnectConsole (gPlatformConsole);
1911 PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest);
1912 BdsLibConnectAll ();
1913
1914 //
1915 // Perform user identification
1916 //
1917 if (mCurrentUser == NULL) {
1918 PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
1919 if (DeferredImageExist) {
1920 //
1921 // After user authentication, the deferred drivers was loaded again.
1922 // Here, need to ensure the deferred drivers are connected.
1923 //
1924 BdsLibConnectAll ();
1925 }
1926 }
1927
1928 //
1929 // Close boot script and install ready to lock
1930 //
1931 InstallReadyToLock ();
1932
1933 //
1934 // In recovery boot mode, we still enter to the
1935 // frong page now
1936 //
1937 PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
1938 break;
1939
1940 FULL_CONFIGURATION:
1941 case BOOT_WITH_FULL_CONFIGURATION:
1942 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
1943 case BOOT_WITH_DEFAULT_SETTINGS:
1944 default:
1945
1946 //
1947 // Connect platform console
1948 //
1949 Status = PlatformBdsConnectConsole (gPlatformConsole);
1950 if (EFI_ERROR (Status)) {
1951
1952 //
1953 // Here OEM/IBV can customize with defined action
1954 //
1955 PlatformBdsNoConsoleAction ();
1956 }
1957
1958 //
1959 // Chenyunh[TODO]: This is Workgroud to show the fs for uSDcard,
1960 // Need to root cause this issue.
1961 //
1962 DEBUG ((DEBUG_ERROR, "Start to reconnect all driver.\n"));
1963 BdsLibDisconnectAllEfi();
1964 BdsLibConnectAll ();
1965 DEBUG ((DEBUG_ERROR, "End to reconnect all driver.\n"));
1966
1967 //
1968 // Perform some platform specific connect sequence
1969 //
1970 PlatformBdsConnectSequence ();
1971 EnableQuietBoot (PcdGetPtr(PcdLogoFile));
1972 if (!SystemConfiguration.QuietBoot) {
1973 PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest);
1974 }
1975
1976 //
1977 // Do a pre-delay so Hard Disk can spin up and see more logo.
1978 //
1979 gBS->Stall(SystemConfiguration.HddPredelay * 1000000);
1980
1981 //
1982 // Perform user identification
1983 //
1984 if (mCurrentUser == NULL) {
1985 PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
1986 if (DeferredImageExist) {
1987 //
1988 // After user authentication, the deferred drivers was loaded again.
1989 // Here, need to ensure the deferred drivers are connected.
1990 //
1991 Status = PlatformBdsConnectConsole (gPlatformConsole);
1992 if (EFI_ERROR (Status)) {
1993 PlatformBdsNoConsoleAction ();
1994 }
1995 PlatformBdsConnectSequence ();
1996 }
1997 }
1998 #ifdef TPM_ENABLED
1999 TcgPhysicalPresenceLibProcessRequest();
2000 #endif
2001 #ifdef FTPM_ENABLE
2002 Tcg2PhysicalPresenceLibProcessRequest(NULL);
2003 #endif
2004
2005 if (EsrtManagement != NULL) {
2006 EsrtManagement->SyncEsrtFmp();
2007 }
2008 //
2009 // Close boot script and install ready to lock
2010 //
2011 InstallReadyToLock ();
2012
2013 //
2014 // Here we have enough time to do the enumeration of boot device
2015 //
2016 PlatformBdsLibEnumerateAllBootOption (BootOptionList);
2017
2018 //
2019 // Give one chance to enter the setup if we
2020 // have the time out
2021 //
2022 PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
2023
2024 //
2025 // Give one chance to enter the setup if we
2026 // select Gummiboot "Reboot Into Firmware Interface"
2027 //
2028 BootIntoFirmwareInterface();
2029
2030 //
2031 // In default boot mode, always find all boot
2032 // option and do enumerate all the default boot option
2033 //
2034 if (Timeout == 0) {
2035 BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
2036 if (IsListEmpty(BootOptionList)) {
2037 PlatformBdsPredictBootOption (BootOptionList);
2038 }
2039
2040 return;
2041 }
2042
2043
2044 break;
2045 }
2046
2047
2048 IsFirstBoot = PcdGetBool(PcdBootState);
2049 if (IsFirstBoot) {
2050 PcdSetBool(PcdBootState, FALSE);
2051 }
2052 return;
2053
2054 }
2055
2056 /**
2057 Hook point after a boot attempt succeeds. We don't expect a boot option to
2058 return, so the UEFI 2.0 specification defines that you will default to an
2059 interactive mode and stop processing the BootOrder list in this case. This
2060 is alos a platform implementation and can be customized by IBV/OEM.
2061
2062 @param Option Pointer to Boot Option that succeeded to boot.
2063
2064 @retval None.
2065
2066 **/
2067 VOID
2068 EFIAPI
2069 PlatformBdsBootSuccess (
2070 IN BDS_COMMON_OPTION *Option
2071 )
2072 {
2073 CHAR16 *TmpStr;
2074
2075 //
2076 // If Boot returned with EFI_SUCCESS and there is not in the boot device
2077 // select loop then we need to pop up a UI and wait for user input.
2078 //
2079 TmpStr = Option->StatusString;
2080 if (TmpStr != NULL) {
2081 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
2082 FreePool(TmpStr);
2083 }
2084 }
2085
2086 /**
2087 Hook point after a boot attempt fails.
2088
2089 @param Option - Pointer to Boot Option that failed to boot.
2090 @param Status - Status returned from failed boot.
2091 @param ExitData - Exit data returned from failed boot.
2092 @param ExitDataSize - Exit data size returned from failed boot.
2093
2094 @retval None.
2095
2096 **/
2097 VOID
2098 EFIAPI
2099 PlatformBdsBootFail (
2100 IN BDS_COMMON_OPTION *Option,
2101 IN EFI_STATUS Status,
2102 IN CHAR16 *ExitData,
2103 IN UINTN ExitDataSize
2104 )
2105 {
2106 CHAR16 *TmpStr;
2107 EFI_HANDLE FvProtocolHandle;
2108
2109 //
2110 // If Boot returned with failed status then we need to pop up a UI and wait
2111 // for user input.
2112 //
2113 TmpStr = Option->StatusString;
2114 if (TmpStr != NULL) {
2115 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
2116 FreePool(TmpStr);
2117 }
2118 if (PcdGet32(PcdFlashFvShellSize) > 0){
2119 gDS->ProcessFirmwareVolume (
2120 (VOID *)(UINTN)PcdGet32(PcdFlashFvShellBase),
2121 PcdGet32(PcdFlashFvShellSize),
2122 &FvProtocolHandle
2123 );
2124 }
2125 PlatformBdsConnectSequence ();
2126 }
2127
2128 /**
2129 This function is remained for IBV/OEM to do some platform action,
2130 if there no console device can be connected.
2131
2132 @param None.
2133
2134 @retval EFI_SUCCESS Direct return success now.
2135
2136 **/
2137 EFI_STATUS
2138 PlatformBdsNoConsoleAction (
2139 VOID
2140 )
2141 {
2142 return EFI_SUCCESS;
2143 }
2144
2145 /**
2146 This function locks the block
2147
2148 @param Base The base address flash region to be locked.
2149
2150 **/
2151 VOID
2152 BdsLockFv (
2153 IN EFI_PHYSICAL_ADDRESS Base
2154 )
2155 {
2156 EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
2157 EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
2158 EFI_PHYSICAL_ADDRESS BaseAddress;
2159 UINT32 BlockLength;
2160 UINTN Index;
2161
2162 BaseAddress = Base - 0x400000 + 2;
2163 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (Base));
2164 BlockMap = &(FvHeader->BlockMap[0]);
2165
2166 while ((BlockMap->NumBlocks != 0) && (BlockMap->Length != 0)) {
2167 BlockLength = BlockMap->Length;
2168 for (Index = 0; Index < BlockMap->NumBlocks; Index++) {
2169 MmioOr8 ((UINTN) BaseAddress, 0x03);
2170 BaseAddress += BlockLength;
2171 }
2172 BlockMap++;
2173 }
2174 }
2175
2176 VOID
2177 EFIAPI
2178 PlatformBdsLockNonUpdatableFlash (
2179 VOID
2180 )
2181 {
2182 EFI_PHYSICAL_ADDRESS Base;
2183
2184 Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvMainBase);
2185 if (Base > 0) {
2186 BdsLockFv (Base);
2187 }
2188
2189 Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvRecoveryBase);
2190 if (Base > 0) {
2191 BdsLockFv (Base);
2192 }
2193 }
2194
2195 /**
2196 Lock the ConsoleIn device in system table. All key
2197 presses will be ignored until the Password is typed in. The only way to
2198 disable the password is to type it in to a ConIn device.
2199
2200 @param Password Password used to lock ConIn device.
2201
2202 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
2203 @retval EFI_UNSUPPORTED Password not found
2204
2205 **/
2206 EFI_STATUS
2207 EFIAPI
2208 LockKeyboards (
2209 IN CHAR16 *Password
2210 )
2211 {
2212 return EFI_UNSUPPORTED;
2213 }
2214
2215 /**
2216 Connect the predefined platform default authentication devices.
2217
2218 This function connects the predefined device path for authentication device,
2219 and if the predefined device path has child device path, the child handle will
2220 be connected too. But the child handle of the child will not be connected.
2221
2222 **/
2223 VOID
2224 EFIAPI
2225 PlatformBdsConnectAuthDevice (
2226 VOID
2227 )
2228 {
2229 EFI_STATUS Status;
2230 UINTN Index;
2231 UINTN HandleIndex;
2232 UINTN HandleCount;
2233 EFI_HANDLE *HandleBuffer;
2234 EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath;
2235 EFI_USER_MANAGER_PROTOCOL *Manager;
2236
2237 Status = gBS->LocateProtocol (
2238 &gEfiUserManagerProtocolGuid,
2239 NULL,
2240 (VOID **) &Manager
2241 );
2242 if (EFI_ERROR (Status)) {
2243 //
2244 // As user manager protocol is not installed, the authentication devices
2245 // should not be connected.
2246 //
2247 return ;
2248 }
2249
2250 Index = 0;
2251 while (gUserAuthenticationDevice[Index] != NULL) {
2252 //
2253 // Connect the platform customized device paths
2254 //
2255 BdsLibConnectDevicePath (gUserAuthenticationDevice[Index]);
2256 Index++;
2257 }
2258
2259 //
2260 // Find and connect the child device paths of the platform customized device paths
2261 //
2262 HandleBuffer = NULL;
2263 for (Index = 0; gUserAuthenticationDevice[Index] != NULL; Index++) {
2264 HandleCount = 0;
2265 Status = gBS->LocateHandleBuffer (
2266 AllHandles,
2267 NULL,
2268 NULL,
2269 &HandleCount,
2270 &HandleBuffer
2271 );
2272 ASSERT (!EFI_ERROR (Status));
2273
2274 //
2275 // Find and connect the child device paths of gUserIdentificationDevice[Index]
2276 //
2277 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
2278 ChildDevicePath = NULL;
2279 Status = gBS->HandleProtocol (
2280 HandleBuffer[HandleIndex],
2281 &gEfiDevicePathProtocolGuid,
2282 (VOID **) &ChildDevicePath
2283 );
2284 if (EFI_ERROR (Status) || ChildDevicePath == NULL) {
2285 continue;
2286 }
2287
2288 if (CompareMem (
2289 ChildDevicePath,
2290 gUserAuthenticationDevice[Index],
2291 (GetDevicePathSize (gUserAuthenticationDevice[Index]) - sizeof (EFI_DEVICE_PATH_PROTOCOL))
2292 ) != 0) {
2293 continue;
2294 }
2295 gBS->ConnectController (
2296 HandleBuffer[HandleIndex],
2297 NULL,
2298 NULL,
2299 TRUE
2300 );
2301 }
2302 }
2303
2304 if (HandleBuffer != NULL) {
2305 FreePool (HandleBuffer);
2306 }
2307 }
2308
2309 /**
2310 This function is to identify a user, and return whether deferred images exist.
2311
2312 @param[out] User Point to user profile handle.
2313 @param[out] DeferredImageExist On return, points to TRUE if the deferred image
2314 exist or FALSE if it did not exist.
2315
2316 **/
2317 VOID
2318 EFIAPI
2319 PlatformBdsUserIdentify (
2320 OUT EFI_USER_PROFILE_HANDLE *User,
2321 OUT BOOLEAN *DeferredImageExist
2322 )
2323 {
2324 EFI_STATUS Status;
2325 EFI_DEFERRED_IMAGE_LOAD_PROTOCOL *DeferredImage;
2326 UINTN HandleCount;
2327 EFI_HANDLE *HandleBuf;
2328 UINTN Index;
2329 UINTN DriverIndex;
2330 EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
2331 VOID *DriverImage;
2332 UINTN ImageSize;
2333 BOOLEAN BootOption;
2334
2335 //
2336 // Perform user identification
2337 //
2338 do {
2339 Status = BdsLibUserIdentify (User);
2340 } while (EFI_ERROR (Status));
2341
2342 //
2343 // After user authentication now, try to find whether deferred image exists
2344 //
2345 HandleCount = 0;
2346 HandleBuf = NULL;
2347 *DeferredImageExist = FALSE;
2348 Status = gBS->LocateHandleBuffer (
2349 ByProtocol,
2350 &gEfiDeferredImageLoadProtocolGuid,
2351 NULL,
2352 &HandleCount,
2353 &HandleBuf
2354 );
2355 if (EFI_ERROR (Status)) {
2356 return ;
2357 }
2358
2359 for (Index = 0; Index < HandleCount; Index++) {
2360 Status = gBS->HandleProtocol (
2361 HandleBuf[Index],
2362 &gEfiDeferredImageLoadProtocolGuid,
2363 (VOID **) &DeferredImage
2364 );
2365 if (!EFI_ERROR (Status)) {
2366 //
2367 // Find whether deferred image exists in this instance.
2368 //
2369 DriverIndex = 0;
2370 Status = DeferredImage->GetImageInfo(
2371 DeferredImage,
2372 DriverIndex,
2373 &ImageDevicePath,
2374 (VOID **) &DriverImage,
2375 &ImageSize,
2376 &BootOption
2377 );
2378 if (!EFI_ERROR (Status)) {
2379 //
2380 // The deferred image is found.
2381 //
2382 FreePool (HandleBuf);
2383 *DeferredImageExist = TRUE;
2384 return ;
2385 }
2386 }
2387 }
2388
2389 FreePool (HandleBuf);
2390 }
2391
2392 UINTN gHotKey = 0;
2393
2394
2395 EFI_STATUS
2396 ShowProgressHotKey (
2397 IN UINT16 TimeoutDefault
2398 )
2399 {
2400 CHAR16 *TmpStr;
2401 UINT16 TimeoutRemain;
2402 EFI_STATUS Status;
2403 EFI_INPUT_KEY Key;
2404 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
2405 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
2406 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
2407 UINT32 GpioValue;
2408 CHAR16 *TmpStr1;
2409 CHAR16 *TmpStr2;
2410 CHAR16 *TmpStr3;
2411 UINTN TmpStrSize;
2412 VOID *Buffer;
2413 UINTN Size;
2414
2415 if (TimeoutDefault == 0) {
2416 return EFI_TIMEOUT;
2417 }
2418
2419 gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
2420
2421 if (DebugAssertEnabled())
2422 {
2423 DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it, or press <F2> or <DEL> to enter setup page! ...Zzz....\n"));
2424 }
2425 else
2426 {
2427 #ifdef __GNUC__
2428 SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)[GCC]", 76);
2429 #else
2430 SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)", 71);
2431 #endif
2432 }
2433 SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
2434 SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
2435 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
2436
2437 TmpStr2 = NULL;
2438 TmpStr3 = NULL;
2439
2440 //
2441 // Check if the platform is using test key.
2442 //
2443 Status = GetSectionFromAnyFv(
2444 PcdGetPtr(PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid),
2445 EFI_SECTION_RAW,
2446 0,
2447 &Buffer,
2448 &Size
2449 );
2450 if (!EFI_ERROR(Status)) {
2451 if ((Size == PcdGetSize(PcdRsa2048Sha256PublicKeyBuffer)) &&
2452 (CompareMem(Buffer, PcdGetPtr(PcdRsa2048Sha256PublicKeyBuffer), Size) == 0)) {
2453 TmpStr2 = L"WARNING: Recovery Test Key is used.\r\n";
2454 if (DebugAssertEnabled()) {
2455 DEBUG ((DEBUG_INFO, "\n\nWARNING: Recovery Test Key is used.\n"));
2456 } else {
2457 SerialPortWrite((UINT8 *)"\n\nWARNING: Recovery Test Key is used.", sizeof("\n\nWARNING: Recovery Test Key is used."));
2458 }
2459 PcdSetBoolS(PcdTestKeyUsed, TRUE);
2460 }
2461 FreePool(Buffer);
2462 }
2463 Status = GetSectionFromAnyFv(
2464 PcdGetPtr(PcdEdkiiPkcs7TestPublicKeyFileGuid),
2465 EFI_SECTION_RAW,
2466 0,
2467 &Buffer,
2468 &Size
2469 );
2470 if (!EFI_ERROR(Status)) {
2471 if ((Size == PcdGetSize(PcdPkcs7CertBuffer)) &&
2472 (CompareMem(Buffer, PcdGetPtr(PcdPkcs7CertBuffer), Size) == 0)) {
2473 TmpStr3 = L"WARNING: Capsule Test Key is used.\r\n";
2474 if (DebugAssertEnabled()) {
2475 DEBUG ((DEBUG_INFO, "\n\nWARNING: Capsule Test Key is used.\r\n"));
2476 } else {
2477 SerialPortWrite((UINT8 *)"\n\nWARNING: Capsule Test Key is used.", sizeof("\n\nWARNING: Capsule Test Key is used."));
2478 }
2479 PcdSetBoolS(PcdTestKeyUsed, TRUE);
2480 }
2481 FreePool(Buffer);
2482 }
2483
2484 //
2485 // Clear the progress status bar first
2486 //
2487 TmpStr1 = L"Start boot option, Press <F2> or <DEL> to enter setup page.\r\n";
2488 TmpStrSize = StrSize(TmpStr1);
2489 if (TmpStr2 != NULL) {
2490 TmpStrSize += StrSize(TmpStr2);
2491 }
2492 if (TmpStr3 != NULL) {
2493 TmpStrSize += StrSize(TmpStr3);
2494 }
2495 TmpStr = AllocatePool (TmpStrSize);
2496 if (TmpStr == NULL) {
2497 TmpStr = TmpStr1;
2498 } else {
2499 StrCpyS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr1);
2500 if (TmpStr2 != NULL) {
2501 StrCatS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr2);
2502 }
2503 if (TmpStr3 != NULL) {
2504 StrCatS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr3);
2505 }
2506 }
2507 PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);
2508
2509 TimeoutRemain = TimeoutDefault;
2510 while (TimeoutRemain != 0) {
2511 if (DebugAssertEnabled())
2512 {
2513 DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));
2514 }
2515 else
2516 {
2517 SerialPortWrite ((UINT8 *)".", 1);
2518 }
2519 Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);
2520 if (Status != EFI_TIMEOUT) {
2521 break;
2522 }
2523 TimeoutRemain--;
2524
2525 //
2526 // Show progress
2527 //
2528 if (TmpStr != NULL) {
2529 PlatformBdsShowProgress (
2530 Foreground,
2531 Background,
2532 TmpStr,
2533 Color,
2534 ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),
2535 0
2536 );
2537 }
2538 }
2539
2540 //
2541 // Timeout expired
2542 //
2543 if (TimeoutRemain == 0) {
2544 if (DebugAssertEnabled())
2545 {
2546 }
2547 else
2548 {
2549 SerialPortWrite ((UINT8 *)"\r\n", 2);
2550 }
2551 return EFI_TIMEOUT;
2552 }
2553
2554 //
2555 // User pressed some key
2556 //
2557 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
2558 if (EFI_ERROR (Status)) {
2559 return Status;
2560 }
2561
2562 //
2563 // Check Volume Up Key to enter Setup
2564 //
2565 GpioValue = MmioRead32 (IO_BASE_ADDRESS + 0x0668); // The value of GPIOC_5
2566 if (((GpioValue & BIT0) == 0) && (Key.ScanCode == SCAN_UP)) {
2567 gHotKey = 0;
2568 return EFI_SUCCESS;
2569 }
2570
2571 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
2572 //
2573 // User pressed enter, equivalent to select "continue"
2574 //
2575 return EFI_TIMEOUT;
2576 }
2577
2578 //
2579 //F2 -- Front Page
2580 //F5 -- Device Manager
2581 //F7 -- Boot Manager
2582 // do not use F8. generally people assume it is windows safe mode key.
2583 //F9 -- Boot order
2584 //
2585 DEBUG ((EFI_D_INFO, "[Key Pressed]: ScanCode 0x%x\n", Key.ScanCode));
2586 switch(Key.ScanCode) {
2587 case SCAN_F2:
2588 gHotKey = 0;
2589 break;
2590
2591 case SCAN_DELETE:
2592 gHotKey = 0;
2593 break;
2594
2595 case SCAN_F5:
2596 gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
2597 break;
2598
2599 case SCAN_F7:
2600 gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
2601 break;
2602
2603 case SCAN_F9:
2604 gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
2605 break;
2606
2607 default:
2608 //set gHotKey to continue so that flow will not go into CallFrontPage
2609 gHotKey = FRONT_PAGE_KEY_CONTINUE;
2610 return EFI_TIMEOUT;
2611 break;
2612 }
2613
2614 return EFI_SUCCESS;
2615 }
2616
2617
2618
2619 /**
2620 This function is the main entry of the platform setup entry.
2621 The function will present the main menu of the system setup,
2622 this is the platform reference part and can be customize.
2623
2624
2625 @param TimeoutDefault The fault time out value before the system
2626 continue to boot.
2627 @param ConnectAllHappened The indicater to check if the connect all have
2628 already happened.
2629
2630 **/
2631 VOID
2632 PlatformBdsEnterFrontPageWithHotKey (
2633 IN UINT16 TimeoutDefault,
2634 IN BOOLEAN ConnectAllHappened
2635 )
2636 {
2637 EFI_STATUS Status;
2638
2639 EFI_STATUS LogoStatus;
2640 EFI_BOOT_LOGO_PROTOCOL *BootLogo;
2641 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
2642 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
2643 UINTN BootTextColumn;
2644 UINTN BootTextRow;
2645
2646 GraphicsOutput = NULL;
2647 SimpleTextOut = NULL;
2648
2649 PERF_START (NULL, "BdsTimeOut", "BDS", 0);
2650
2651 //
2652 // Indicate if we need connect all in the platform setup
2653 //
2654 if (ConnectAllHappened) {
2655 gConnectAllHappened = TRUE;
2656 }
2657
2658 if (!mModeInitialized) {
2659 //
2660 // After the console is ready, get current video resolution
2661 // and text mode before launching setup at first time.
2662 //
2663 Status = gBS->HandleProtocol (
2664 gST->ConsoleOutHandle,
2665 &gEfiGraphicsOutputProtocolGuid,
2666 (VOID**)&GraphicsOutput
2667 );
2668 if (EFI_ERROR (Status)) {
2669 GraphicsOutput = NULL;
2670 }
2671
2672 Status = gBS->HandleProtocol (
2673 gST->ConsoleOutHandle,
2674 &gEfiSimpleTextOutProtocolGuid,
2675 (VOID**)&SimpleTextOut
2676 );
2677 if (EFI_ERROR (Status)) {
2678 SimpleTextOut = NULL;
2679 }
2680
2681 if (GraphicsOutput != NULL) {
2682 //
2683 // Get current video resolution and text mode.
2684 //
2685 mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
2686 mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
2687 }
2688
2689 if (SimpleTextOut != NULL) {
2690 Status = SimpleTextOut->QueryMode (
2691 SimpleTextOut,
2692 SimpleTextOut->Mode->Mode,
2693 &BootTextColumn,
2694 &BootTextRow
2695 );
2696 mBootTextModeColumn = (UINT32)BootTextColumn;
2697 mBootTextModeRow = (UINT32)BootTextRow;
2698 }
2699
2700 //
2701 // Get user defined text mode for setup.
2702 //
2703 mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
2704 mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
2705 mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);
2706 mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);
2707
2708 mModeInitialized = TRUE;
2709 }
2710
2711 if (TimeoutDefault != 0xffff) {
2712 Status = ShowProgressHotKey (TimeoutDefault);
2713
2714 //
2715 // Ensure screen is clear when switch Console from Graphics mode to Text mode
2716 //
2717 gST->ConOut->EnableCursor (gST->ConOut, TRUE);
2718 gST->ConOut->ClearScreen (gST->ConOut);
2719
2720 //
2721 // Boot Logo is corrupted, report it using Boot Logo protocol.
2722 //
2723 LogoStatus = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);
2724 if (!EFI_ERROR (LogoStatus) && (BootLogo != NULL)) {
2725 BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);
2726 }
2727
2728 if (EFI_ERROR (Status)) {
2729 //
2730 // Timeout or user press enter to continue
2731 //
2732 goto Exit;
2733 }
2734 }
2735
2736 //
2737 // Install BM HiiPackages.
2738 // Keep BootMaint HiiPackage, so that it can be covered by global setting.
2739 //
2740 InitBMPackage ();
2741 do {
2742
2743 BdsSetConsoleMode (TRUE);
2744
2745 InitializeFrontPage (FALSE);
2746
2747 //
2748 // Update Front Page strings
2749 //
2750 UpdateFrontPageStrings ();
2751
2752 Status = EFI_SUCCESS;
2753 gCallbackKey = 0;
2754 if (gHotKey == 0) {
2755 Status = CallFrontPage ();
2756 } else {
2757 gCallbackKey = gHotKey;
2758 gHotKey = 0;
2759 }
2760
2761 //
2762 // If gCallbackKey is greater than 1 and less or equal to 5,
2763 // it will launch configuration utilities.
2764 // 2 = set language
2765 // 3 = boot manager
2766 // 4 = device manager
2767 // 5 = boot maintenance manager
2768 //
2769 if (gCallbackKey != 0) {
2770 REPORT_STATUS_CODE (
2771 EFI_PROGRESS_CODE,
2772 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
2773 );
2774 }
2775
2776 //
2777 // Based on the key that was set, we can determine what to do
2778 //
2779 switch (gCallbackKey) {
2780 //
2781 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
2782 // describe to their customers in documentation how to find their setup information (namely
2783 // under the device manager and specific buckets)
2784 //
2785 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
2786 //
2787 case FRONT_PAGE_KEY_CONTINUE:
2788
2789 //
2790 // User hit continue
2791 //
2792 break;
2793
2794 case FRONT_PAGE_KEY_LANGUAGE:
2795
2796 //
2797 // User made a language setting change - display front page again
2798 //
2799 break;
2800
2801 case FRONT_PAGE_KEY_BOOT_MANAGER:
2802 //
2803 // Remove the installed BootMaint HiiPackages when exit.
2804 //
2805 FreeBMPackage ();
2806
2807 //
2808 // User chose to run the Boot Manager
2809 //
2810 CallBootManager ();
2811
2812 //
2813 // Reinstall BootMaint HiiPackages after exiting from Boot Manager.
2814 //
2815 InitBMPackage ();
2816 break;
2817
2818 case FRONT_PAGE_KEY_DEVICE_MANAGER:
2819
2820 //
2821 // Display the Device Manager
2822 //
2823 do {
2824 CallDeviceManager ();
2825 } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);
2826 break;
2827
2828 case FRONT_PAGE_KEY_BOOT_MAINTAIN:
2829
2830 //
2831 // Display the Boot Maintenance Manager
2832 //
2833 BdsStartBootMaint ();
2834 break;
2835 }
2836
2837 } while (((UINTN)gCallbackKey) != FRONT_PAGE_KEY_CONTINUE);
2838
2839 //
2840 //Will leave browser, check any reset required change is applied? if yes, reset system
2841 //
2842 SetupResetReminder ();
2843 //
2844 // Remove the installed BootMaint HiiPackages when exit.
2845 //
2846 FreeBMPackage ();
2847
2848 Exit:
2849 //
2850 // Automatically load current entry
2851 // Note: The following lines of code only execute when Auto boot
2852 // takes affect
2853 //
2854 PERF_END (NULL, "BdsTimeOut", "BDS", 0);
2855 }
2856
2857
2858 VOID
2859 BootIntoFirmwareInterface(
2860 VOID
2861 )
2862 {
2863 EFI_STATUS Status;
2864 UINTN DataSize;
2865 UINT16 Timeout;
2866 UINT64 OsIndication;
2867
2868
2869 OsIndication = 0;
2870 DataSize = sizeof(UINT64);
2871 Status = gRT->GetVariable (
2872 L"OsIndications",
2873 &gEfiGlobalVariableGuid,
2874 NULL,
2875 &DataSize,
2876 &OsIndication
2877 );
2878
2879 DEBUG ((EFI_D_INFO, "OSIndication Variable Value %d\n", OsIndication));
2880 //
2881 //Goto FrontPage directly when bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted.
2882 //
2883 if (!EFI_ERROR(Status) && (OsIndication != 0)) {
2884 Timeout = 0xffff;
2885 PlatformBdsEnterFrontPage (Timeout, FALSE);
2886 }
2887 }
2888
2889
2890 EFI_STATUS
2891 PlatformBdsConnectSimpleConsole (
2892 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
2893 )
2894 {
2895 EFI_STATUS Status;
2896 UINTN Index;
2897 EFI_DEVICE_PATH_PROTOCOL *VarConout;
2898 EFI_DEVICE_PATH_PROTOCOL *VarConin;
2899 UINTN DevicePathSize;
2900
2901
2902 Index = 0;
2903 Status = EFI_SUCCESS;
2904 DevicePathSize = 0;
2905 VarConout = BdsLibGetVariableAndSize (
2906 L"ConOut",
2907 &gEfiGlobalVariableGuid,
2908 &DevicePathSize
2909 );
2910 VarConin = BdsLibGetVariableAndSize (
2911 L"ConIn",
2912 &gEfiGlobalVariableGuid,
2913 &DevicePathSize
2914 );
2915 if (VarConout == NULL || VarConin == NULL) {
2916 //
2917 // Have chance to connect the platform default console,
2918 // the platform default console is the minimum device group
2919 // the platform should support
2920 //
2921 while (PlatformConsole[Index].DevicePath != NULL) {
2922
2923 //
2924 // Update the console variable with the connect type
2925 //
2926 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
2927 BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);
2928 }
2929
2930 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
2931 BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);
2932 }
2933
2934 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
2935 BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);
2936 }
2937
2938 Index ++;
2939 }
2940 }
2941
2942 //
2943 // Connect ConIn first to give keyboard time to parse hot key event.
2944 //
2945 Status = BdsLibConnectConsoleVariable (L"ConIn");
2946 if (EFI_ERROR (Status)) {
2947 return Status;
2948 }
2949
2950 //
2951 // Make sure we have at least one active VGA, and have the right
2952 // active VGA in console variable
2953 //
2954 Status = PlatformBdsForceActiveVga ();
2955
2956 //
2957 // It seems impossible not to have any ConOut device on platform,
2958 // so we check the status here.
2959 //
2960 Status = BdsLibConnectConsoleVariable (L"ConOut");
2961 if (EFI_ERROR (Status)) {
2962 return Status;
2963 }
2964
2965 return EFI_SUCCESS;
2966 }
2967
2968
2969 /**
2970 Timer handler to convert the key from USB.
2971
2972 @param Event Indicates the event that invoke this function.
2973 @param Context Indicates the calling context.
2974 **/
2975 VOID
2976 EFIAPI
2977 HotKeyTimerHandler (
2978 IN EFI_EVENT Event,
2979 IN VOID *Context
2980 )
2981 {
2982 EFI_STATUS Status;
2983 EFI_INPUT_KEY Key;
2984
2985 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
2986 if (EFI_ERROR (Status)) {
2987 return;
2988 }
2989
2990 switch(Key.ScanCode) {
2991 case SCAN_F2:
2992 gHotKey = 0;
2993 mHotKeyPressed = TRUE;
2994 break;
2995
2996 case SCAN_F5:
2997 gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
2998 mHotKeyPressed = TRUE;
2999 break;
3000
3001 case SCAN_F7:
3002 gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
3003 mHotKeyPressed = TRUE;
3004 break;
3005
3006 case SCAN_F9:
3007 gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
3008 mHotKeyPressed = TRUE;
3009 break;
3010 }
3011
3012 if (mHotKeyPressed) {
3013 gBS->SetTimer (
3014 mHotKeyTimerEvent,
3015 TimerCancel,
3016 0
3017 );
3018 gBS->CloseEvent (mHotKeyTimerEvent);
3019 mHotKeyTimerEvent = NULL;
3020 }
3021
3022 return;
3023 }
3024
3025
3026 /**
3027 Callback function for SimpleTextInEx protocol install events
3028
3029 @param Event the event that is signaled.
3030 @param Context not used here.
3031
3032 **/
3033 VOID
3034 EFIAPI
3035 HitHotkeyEvent (
3036 IN EFI_EVENT Event,
3037 IN VOID *Context
3038 )
3039 {
3040 EFI_STATUS Status;
3041
3042 Status = gBS->CloseEvent(mHitHotkeyEvent);
3043 if (EFI_ERROR (Status)) {
3044 return;
3045 }
3046 Status = gBS->CreateEvent (
3047 EVT_TIMER | EVT_NOTIFY_SIGNAL,
3048 TPL_NOTIFY,
3049 HotKeyTimerHandler,
3050 NULL,
3051 &mHotKeyTimerEvent
3052 );
3053 if (EFI_ERROR (Status)) {
3054 return;
3055 }
3056 Status = gBS->SetTimer (
3057 mHotKeyTimerEvent,
3058 TimerPeriodic,
3059 KEYBOARD_TIMER_INTERVAL
3060 );
3061 if (EFI_ERROR (Status)) {
3062 return;
3063 }
3064
3065 return;
3066 }
3067
3068
3069 VOID
3070 EFIAPI
3071 PlatformBdsInitHotKeyEvent (
3072 VOID
3073 )
3074 {
3075 EFI_STATUS Status;
3076
3077 //
3078 // Register Protocol notify for Hotkey service
3079 //
3080 Status = gBS->CreateEvent (
3081 EVT_NOTIFY_SIGNAL,
3082 TPL_CALLBACK,
3083 HitHotkeyEvent,
3084 NULL,
3085 &mHitHotkeyEvent
3086 );
3087 ASSERT_EFI_ERROR (Status);
3088
3089 //
3090 // Register for protocol notifications on this event
3091 //
3092 Status = gBS->RegisterProtocolNotify (
3093 &gEfiSimpleTextInputExProtocolGuid,
3094 mHitHotkeyEvent,
3095 &mHitHotkeyRegistration
3096 );
3097 ASSERT_EFI_ERROR (Status);
3098 }