]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
Vlv2TbltDevicePkg: Find UEFI Shell using gUefiShellFileGuid
[mirror_edk2.git] / Vlv2TbltDevicePkg / Library / PlatformBdsLib / BdsPlatform.c
1 /** @file
2
3 Copyright (c) 2004 - 2018, 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 switch (BootMode) {
1706
1707 case BOOT_WITH_MINIMAL_CONFIGURATION:
1708 PlatformBdsInitHotKeyEvent ();
1709 PlatformBdsConnectSimpleConsole (gPlatformSimpleConsole);
1710
1711
1712 //
1713 // Check to see if it's needed to dispatch more DXE drivers.
1714 //
1715 for (Index = 0; Index < sizeof(ConnectDriverTable)/sizeof(EFI_GUID *); Index++) {
1716 Status = gBS->LocateHandleBuffer (
1717 ByProtocol,
1718 ConnectDriverTable[Index],
1719 NULL,
1720 &HandleCount,
1721 &HandleBuffer
1722 );
1723 if (!EFI_ERROR (Status)) {
1724 for (Index1 = 0; Index1 < HandleCount; Index1++) {
1725 gBS->ConnectController (
1726 HandleBuffer[Index1],
1727 NULL,
1728 NULL,
1729 TRUE
1730 );
1731 }
1732 }
1733
1734 if (HandleBuffer != NULL) {
1735 FreePool (HandleBuffer);
1736 }
1737
1738 gDS->Dispatch ();
1739 }
1740
1741 //
1742 // Locate the Global NVS Protocol.
1743 //
1744 Status = gBS->LocateProtocol (
1745 &gEfiGlobalNvsAreaProtocolGuid,
1746 NULL,
1747 (void **)&GlobalNvsArea
1748 );
1749 if (GlobalNvsArea->Area->emmcVersion == 0){
1750 EmmcBootDevPath = (PLATFORM_PCI_DEVICE_PATH *)gPlatformSimpleBootOption[0];
1751 EmmcBootDevPath->PciDevice.Device = 0x10;
1752 }
1753
1754 //
1755 // Connect boot device here to give time to read keyboard.
1756 //
1757 BdsLibConnectDevicePath (gPlatformSimpleBootOption[0]);
1758
1759 //
1760 // This is a workround for dectecting hotkey from USB keyboard.
1761 //
1762 gBS->Stall(KEYBOARD_TIMER_INTERVAL);
1763
1764 if (mHotKeyTimerEvent != NULL) {
1765 gBS->SetTimer (
1766 mHotKeyTimerEvent,
1767 TimerCancel,
1768 0
1769 );
1770 gBS->CloseEvent (mHotKeyTimerEvent);
1771 mHotKeyTimerEvent = NULL;
1772 }
1773 if (mHotKeyPressed) {
1774 //
1775 // Skip show progress count down
1776 //
1777 Timeout = 0xFFFF;
1778 goto FULL_CONFIGURATION;
1779 }
1780
1781 if (SystemConfiguration.QuietBoot) {
1782 EnableQuietBoot (PcdGetPtr(PcdLogoFile));
1783 } else {
1784 PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest);
1785 }
1786
1787
1788 #ifdef TPM_ENABLED
1789 TcgPhysicalPresenceLibProcessRequest();
1790 #endif
1791 #ifdef FTPM_ENABLE
1792 Tcg2PhysicalPresenceLibProcessRequest(NULL);
1793 #endif
1794
1795 if (EsrtManagement != NULL) {
1796 EsrtManagement->LockEsrtRepository();
1797 }
1798
1799 //
1800 // Close boot script and install ready to lock
1801 //
1802 InstallReadyToLock ();
1803
1804 //
1805 // Give one chance to enter the setup if we
1806 // select Gummiboot "Reboot Into Firmware Interface" and Fast Boot is enabled.
1807 //
1808 BootIntoFirmwareInterface();
1809 break;
1810
1811 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
1812
1813 //
1814 // In no-configuration boot mode, we can connect the
1815 // console directly.
1816 //
1817 BdsLibConnectAllDefaultConsoles ();
1818 PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);
1819
1820 //
1821 // Perform some platform specific connect sequence
1822 //
1823 PlatformBdsConnectSequence ();
1824
1825 //
1826 // As console is ready, perform user identification again.
1827 //
1828 if (mCurrentUser == NULL) {
1829 PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
1830 if (DeferredImageExist) {
1831 //
1832 // After user authentication, the deferred drivers was loaded again.
1833 // Here, need to ensure the deferred images are connected.
1834 //
1835 BdsLibConnectAllDefaultConsoles ();
1836 PlatformBdsConnectSequence ();
1837 }
1838 }
1839
1840 if (EsrtManagement != NULL) {
1841 EsrtManagement->LockEsrtRepository();
1842 }
1843
1844 //
1845 // Close boot script and install ready to lock
1846 //
1847 InstallReadyToLock ();
1848
1849 //
1850 // Notes: current time out = 0 can not enter the
1851 // front page
1852 //
1853 PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
1854
1855 //
1856 // Check the boot option with the boot option list
1857 //
1858 BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
1859 break;
1860
1861 case BOOT_ON_FLASH_UPDATE:
1862
1863 //
1864 // Boot with the specific configuration
1865 //
1866 PlatformBdsConnectConsole (gPlatformConsole);
1867 PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest);
1868 EnableQuietBoot (PcdGetPtr(PcdLogoFile));
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 if (SystemConfiguration.QuietBoot) {
1972 EnableQuietBoot (PcdGetPtr(PcdLogoFile));
1973 } else {
1974 PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest);
1975 }
1976
1977 //
1978 // Do a pre-delay so Hard Disk can spin up and see more logo.
1979 //
1980 gBS->Stall(SystemConfiguration.HddPredelay * 1000000);
1981
1982 //
1983 // Perform user identification
1984 //
1985 if (mCurrentUser == NULL) {
1986 PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
1987 if (DeferredImageExist) {
1988 //
1989 // After user authentication, the deferred drivers was loaded again.
1990 // Here, need to ensure the deferred drivers are connected.
1991 //
1992 Status = PlatformBdsConnectConsole (gPlatformConsole);
1993 if (EFI_ERROR (Status)) {
1994 PlatformBdsNoConsoleAction ();
1995 }
1996 PlatformBdsConnectSequence ();
1997 }
1998 }
1999 #ifdef TPM_ENABLED
2000 TcgPhysicalPresenceLibProcessRequest();
2001 #endif
2002 #ifdef FTPM_ENABLE
2003 Tcg2PhysicalPresenceLibProcessRequest(NULL);
2004 #endif
2005
2006 if (EsrtManagement != NULL) {
2007 EsrtManagement->SyncEsrtFmp();
2008 }
2009 //
2010 // Close boot script and install ready to lock
2011 //
2012 InstallReadyToLock ();
2013
2014 //
2015 // Here we have enough time to do the enumeration of boot device
2016 //
2017 PlatformBdsLibEnumerateAllBootOption (BootOptionList);
2018
2019 //
2020 // Give one chance to enter the setup if we
2021 // have the time out
2022 //
2023 PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
2024
2025 //
2026 // Give one chance to enter the setup if we
2027 // select Gummiboot "Reboot Into Firmware Interface"
2028 //
2029 BootIntoFirmwareInterface();
2030
2031 //
2032 // In default boot mode, always find all boot
2033 // option and do enumerate all the default boot option
2034 //
2035 if (Timeout == 0) {
2036 BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
2037 if (IsListEmpty(BootOptionList)) {
2038 PlatformBdsPredictBootOption (BootOptionList);
2039 }
2040
2041 return;
2042 }
2043
2044
2045 break;
2046 }
2047
2048
2049 IsFirstBoot = PcdGetBool(PcdBootState);
2050 if (IsFirstBoot) {
2051 PcdSetBool(PcdBootState, FALSE);
2052 }
2053 return;
2054
2055 }
2056
2057 /**
2058 Hook point after a boot attempt succeeds. We don't expect a boot option to
2059 return, so the UEFI 2.0 specification defines that you will default to an
2060 interactive mode and stop processing the BootOrder list in this case. This
2061 is alos a platform implementation and can be customized by IBV/OEM.
2062
2063 @param Option Pointer to Boot Option that succeeded to boot.
2064
2065 @retval None.
2066
2067 **/
2068 VOID
2069 EFIAPI
2070 PlatformBdsBootSuccess (
2071 IN BDS_COMMON_OPTION *Option
2072 )
2073 {
2074 CHAR16 *TmpStr;
2075
2076 //
2077 // If Boot returned with EFI_SUCCESS and there is not in the boot device
2078 // select loop then we need to pop up a UI and wait for user input.
2079 //
2080 TmpStr = Option->StatusString;
2081 if (TmpStr != NULL) {
2082 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
2083 FreePool(TmpStr);
2084 }
2085 }
2086
2087 /**
2088 Hook point after a boot attempt fails.
2089
2090 @param Option - Pointer to Boot Option that failed to boot.
2091 @param Status - Status returned from failed boot.
2092 @param ExitData - Exit data returned from failed boot.
2093 @param ExitDataSize - Exit data size returned from failed boot.
2094
2095 @retval None.
2096
2097 **/
2098 VOID
2099 EFIAPI
2100 PlatformBdsBootFail (
2101 IN BDS_COMMON_OPTION *Option,
2102 IN EFI_STATUS Status,
2103 IN CHAR16 *ExitData,
2104 IN UINTN ExitDataSize
2105 )
2106 {
2107 CHAR16 *TmpStr;
2108 EFI_HANDLE FvProtocolHandle;
2109
2110 //
2111 // If Boot returned with failed status then we need to pop up a UI and wait
2112 // for user input.
2113 //
2114 TmpStr = Option->StatusString;
2115 if (TmpStr != NULL) {
2116 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
2117 FreePool(TmpStr);
2118 }
2119 if (PcdGet32(PcdFlashFvShellSize) > 0){
2120 gDS->ProcessFirmwareVolume (
2121 (VOID *)(UINTN)PcdGet32(PcdFlashFvShellBase),
2122 PcdGet32(PcdFlashFvShellSize),
2123 &FvProtocolHandle
2124 );
2125 }
2126 PlatformBdsConnectSequence ();
2127 }
2128
2129 /**
2130 This function is remained for IBV/OEM to do some platform action,
2131 if there no console device can be connected.
2132
2133 @param None.
2134
2135 @retval EFI_SUCCESS Direct return success now.
2136
2137 **/
2138 EFI_STATUS
2139 PlatformBdsNoConsoleAction (
2140 VOID
2141 )
2142 {
2143 return EFI_SUCCESS;
2144 }
2145
2146 /**
2147 This function locks the block
2148
2149 @param Base The base address flash region to be locked.
2150
2151 **/
2152 VOID
2153 BdsLockFv (
2154 IN EFI_PHYSICAL_ADDRESS Base
2155 )
2156 {
2157 EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
2158 EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
2159 EFI_PHYSICAL_ADDRESS BaseAddress;
2160 UINT32 BlockLength;
2161 UINTN Index;
2162
2163 BaseAddress = Base - 0x400000 + 2;
2164 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (Base));
2165 BlockMap = &(FvHeader->BlockMap[0]);
2166
2167 while ((BlockMap->NumBlocks != 0) && (BlockMap->Length != 0)) {
2168 BlockLength = BlockMap->Length;
2169 for (Index = 0; Index < BlockMap->NumBlocks; Index++) {
2170 MmioOr8 ((UINTN) BaseAddress, 0x03);
2171 BaseAddress += BlockLength;
2172 }
2173 BlockMap++;
2174 }
2175 }
2176
2177 VOID
2178 EFIAPI
2179 PlatformBdsLockNonUpdatableFlash (
2180 VOID
2181 )
2182 {
2183 EFI_PHYSICAL_ADDRESS Base;
2184
2185 Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvMainBase);
2186 if (Base > 0) {
2187 BdsLockFv (Base);
2188 }
2189
2190 Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvRecoveryBase);
2191 if (Base > 0) {
2192 BdsLockFv (Base);
2193 }
2194 }
2195
2196 /**
2197 Lock the ConsoleIn device in system table. All key
2198 presses will be ignored until the Password is typed in. The only way to
2199 disable the password is to type it in to a ConIn device.
2200
2201 @param Password Password used to lock ConIn device.
2202
2203 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
2204 @retval EFI_UNSUPPORTED Password not found
2205
2206 **/
2207 EFI_STATUS
2208 EFIAPI
2209 LockKeyboards (
2210 IN CHAR16 *Password
2211 )
2212 {
2213 return EFI_UNSUPPORTED;
2214 }
2215
2216 /**
2217 Connect the predefined platform default authentication devices.
2218
2219 This function connects the predefined device path for authentication device,
2220 and if the predefined device path has child device path, the child handle will
2221 be connected too. But the child handle of the child will not be connected.
2222
2223 **/
2224 VOID
2225 EFIAPI
2226 PlatformBdsConnectAuthDevice (
2227 VOID
2228 )
2229 {
2230 EFI_STATUS Status;
2231 UINTN Index;
2232 UINTN HandleIndex;
2233 UINTN HandleCount;
2234 EFI_HANDLE *HandleBuffer;
2235 EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath;
2236 EFI_USER_MANAGER_PROTOCOL *Manager;
2237
2238 Status = gBS->LocateProtocol (
2239 &gEfiUserManagerProtocolGuid,
2240 NULL,
2241 (VOID **) &Manager
2242 );
2243 if (EFI_ERROR (Status)) {
2244 //
2245 // As user manager protocol is not installed, the authentication devices
2246 // should not be connected.
2247 //
2248 return ;
2249 }
2250
2251 Index = 0;
2252 while (gUserAuthenticationDevice[Index] != NULL) {
2253 //
2254 // Connect the platform customized device paths
2255 //
2256 BdsLibConnectDevicePath (gUserAuthenticationDevice[Index]);
2257 Index++;
2258 }
2259
2260 //
2261 // Find and connect the child device paths of the platform customized device paths
2262 //
2263 HandleBuffer = NULL;
2264 for (Index = 0; gUserAuthenticationDevice[Index] != NULL; Index++) {
2265 HandleCount = 0;
2266 Status = gBS->LocateHandleBuffer (
2267 AllHandles,
2268 NULL,
2269 NULL,
2270 &HandleCount,
2271 &HandleBuffer
2272 );
2273 ASSERT (!EFI_ERROR (Status));
2274
2275 //
2276 // Find and connect the child device paths of gUserIdentificationDevice[Index]
2277 //
2278 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
2279 ChildDevicePath = NULL;
2280 Status = gBS->HandleProtocol (
2281 HandleBuffer[HandleIndex],
2282 &gEfiDevicePathProtocolGuid,
2283 (VOID **) &ChildDevicePath
2284 );
2285 if (EFI_ERROR (Status) || ChildDevicePath == NULL) {
2286 continue;
2287 }
2288
2289 if (CompareMem (
2290 ChildDevicePath,
2291 gUserAuthenticationDevice[Index],
2292 (GetDevicePathSize (gUserAuthenticationDevice[Index]) - sizeof (EFI_DEVICE_PATH_PROTOCOL))
2293 ) != 0) {
2294 continue;
2295 }
2296 gBS->ConnectController (
2297 HandleBuffer[HandleIndex],
2298 NULL,
2299 NULL,
2300 TRUE
2301 );
2302 }
2303 }
2304
2305 if (HandleBuffer != NULL) {
2306 FreePool (HandleBuffer);
2307 }
2308 }
2309
2310 /**
2311 This function is to identify a user, and return whether deferred images exist.
2312
2313 @param[out] User Point to user profile handle.
2314 @param[out] DeferredImageExist On return, points to TRUE if the deferred image
2315 exist or FALSE if it did not exist.
2316
2317 **/
2318 VOID
2319 EFIAPI
2320 PlatformBdsUserIdentify (
2321 OUT EFI_USER_PROFILE_HANDLE *User,
2322 OUT BOOLEAN *DeferredImageExist
2323 )
2324 {
2325 EFI_STATUS Status;
2326 EFI_DEFERRED_IMAGE_LOAD_PROTOCOL *DeferredImage;
2327 UINTN HandleCount;
2328 EFI_HANDLE *HandleBuf;
2329 UINTN Index;
2330 UINTN DriverIndex;
2331 EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
2332 VOID *DriverImage;
2333 UINTN ImageSize;
2334 BOOLEAN BootOption;
2335
2336 //
2337 // Perform user identification
2338 //
2339 do {
2340 Status = BdsLibUserIdentify (User);
2341 } while (EFI_ERROR (Status));
2342
2343 //
2344 // After user authentication now, try to find whether deferred image exists
2345 //
2346 HandleCount = 0;
2347 HandleBuf = NULL;
2348 *DeferredImageExist = FALSE;
2349 Status = gBS->LocateHandleBuffer (
2350 ByProtocol,
2351 &gEfiDeferredImageLoadProtocolGuid,
2352 NULL,
2353 &HandleCount,
2354 &HandleBuf
2355 );
2356 if (EFI_ERROR (Status)) {
2357 return ;
2358 }
2359
2360 for (Index = 0; Index < HandleCount; Index++) {
2361 Status = gBS->HandleProtocol (
2362 HandleBuf[Index],
2363 &gEfiDeferredImageLoadProtocolGuid,
2364 (VOID **) &DeferredImage
2365 );
2366 if (!EFI_ERROR (Status)) {
2367 //
2368 // Find whether deferred image exists in this instance.
2369 //
2370 DriverIndex = 0;
2371 Status = DeferredImage->GetImageInfo(
2372 DeferredImage,
2373 DriverIndex,
2374 &ImageDevicePath,
2375 (VOID **) &DriverImage,
2376 &ImageSize,
2377 &BootOption
2378 );
2379 if (!EFI_ERROR (Status)) {
2380 //
2381 // The deferred image is found.
2382 //
2383 FreePool (HandleBuf);
2384 *DeferredImageExist = TRUE;
2385 return ;
2386 }
2387 }
2388 }
2389
2390 FreePool (HandleBuf);
2391 }
2392
2393 UINTN gHotKey = 0;
2394
2395
2396 EFI_STATUS
2397 ShowProgressHotKey (
2398 IN UINT16 TimeoutDefault
2399 )
2400 {
2401 CHAR16 *TmpStr;
2402 UINT16 TimeoutRemain;
2403 EFI_STATUS Status;
2404 EFI_INPUT_KEY Key;
2405 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
2406 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
2407 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
2408 UINT32 GpioValue;
2409 CHAR16 *TmpStr1;
2410 CHAR16 *TmpStr2;
2411 CHAR16 *TmpStr3;
2412 UINTN TmpStrSize;
2413 VOID *Buffer;
2414 UINTN Size;
2415
2416 if (TimeoutDefault == 0) {
2417 return EFI_TIMEOUT;
2418 }
2419
2420 gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
2421
2422 if (DebugAssertEnabled())
2423 {
2424 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"));
2425 }
2426 else
2427 {
2428 #ifdef __GNUC__
2429 SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)[GCC]", 76);
2430 #else
2431 SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)", 71);
2432 #endif
2433 }
2434 SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
2435 SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
2436 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
2437
2438 TmpStr2 = NULL;
2439 TmpStr3 = NULL;
2440
2441 //
2442 // Check if the platform is using test key.
2443 //
2444 Status = GetSectionFromAnyFv(
2445 PcdGetPtr(PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid),
2446 EFI_SECTION_RAW,
2447 0,
2448 &Buffer,
2449 &Size
2450 );
2451 if (!EFI_ERROR(Status)) {
2452 if ((Size == PcdGetSize(PcdRsa2048Sha256PublicKeyBuffer)) &&
2453 (CompareMem(Buffer, PcdGetPtr(PcdRsa2048Sha256PublicKeyBuffer), Size) == 0)) {
2454 TmpStr2 = L"WARNING: Recovery Test Key is used.\r\n";
2455 if (DebugAssertEnabled()) {
2456 DEBUG ((DEBUG_INFO, "\n\nWARNING: Recovery Test Key is used.\n"));
2457 } else {
2458 SerialPortWrite((UINT8 *)"\n\nWARNING: Recovery Test Key is used.", sizeof("\n\nWARNING: Recovery Test Key is used."));
2459 }
2460 PcdSetBoolS(PcdTestKeyUsed, TRUE);
2461 }
2462 FreePool(Buffer);
2463 }
2464 Status = GetSectionFromAnyFv(
2465 PcdGetPtr(PcdEdkiiPkcs7TestPublicKeyFileGuid),
2466 EFI_SECTION_RAW,
2467 0,
2468 &Buffer,
2469 &Size
2470 );
2471 if (!EFI_ERROR(Status)) {
2472 if ((Size == PcdGetSize(PcdPkcs7CertBuffer)) &&
2473 (CompareMem(Buffer, PcdGetPtr(PcdPkcs7CertBuffer), Size) == 0)) {
2474 TmpStr3 = L"WARNING: Capsule Test Key is used.\r\n";
2475 if (DebugAssertEnabled()) {
2476 DEBUG ((DEBUG_INFO, "\n\nWARNING: Capsule Test Key is used.\r\n"));
2477 } else {
2478 SerialPortWrite((UINT8 *)"\n\nWARNING: Capsule Test Key is used.", sizeof("\n\nWARNING: Capsule Test Key is used."));
2479 }
2480 PcdSetBoolS(PcdTestKeyUsed, TRUE);
2481 }
2482 FreePool(Buffer);
2483 }
2484
2485 //
2486 // Clear the progress status bar first
2487 //
2488 TmpStr1 = L"Start boot option, Press <F2> or <DEL> to enter setup page.\r\n";
2489 TmpStrSize = StrSize(TmpStr1);
2490 if (TmpStr2 != NULL) {
2491 TmpStrSize += StrSize(TmpStr2);
2492 }
2493 if (TmpStr3 != NULL) {
2494 TmpStrSize += StrSize(TmpStr3);
2495 }
2496 TmpStr = AllocatePool (TmpStrSize);
2497 if (TmpStr == NULL) {
2498 TmpStr = TmpStr1;
2499 } else {
2500 StrCpyS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr1);
2501 if (TmpStr2 != NULL) {
2502 StrCatS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr2);
2503 }
2504 if (TmpStr3 != NULL) {
2505 StrCatS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr3);
2506 }
2507 }
2508 PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);
2509
2510 TimeoutRemain = TimeoutDefault;
2511 while (TimeoutRemain != 0) {
2512 if (DebugAssertEnabled())
2513 {
2514 DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));
2515 }
2516 else
2517 {
2518 SerialPortWrite ((UINT8 *)".", 1);
2519 }
2520 Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);
2521 if (Status != EFI_TIMEOUT) {
2522 break;
2523 }
2524 TimeoutRemain--;
2525
2526 //
2527 // Show progress
2528 //
2529 if (TmpStr != NULL) {
2530 PlatformBdsShowProgress (
2531 Foreground,
2532 Background,
2533 TmpStr,
2534 Color,
2535 ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),
2536 0
2537 );
2538 }
2539 }
2540
2541 //
2542 // Timeout expired
2543 //
2544 if (TimeoutRemain == 0) {
2545 if (DebugAssertEnabled())
2546 {
2547 }
2548 else
2549 {
2550 SerialPortWrite ((UINT8 *)"\r\n", 2);
2551 }
2552 return EFI_TIMEOUT;
2553 }
2554
2555 //
2556 // User pressed some key
2557 //
2558 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
2559 if (EFI_ERROR (Status)) {
2560 return Status;
2561 }
2562
2563 //
2564 // Check Volume Up Key to enter Setup
2565 //
2566 GpioValue = MmioRead32 (IO_BASE_ADDRESS + 0x0668); // The value of GPIOC_5
2567 if (((GpioValue & BIT0) == 0) && (Key.ScanCode == SCAN_UP)) {
2568 gHotKey = 0;
2569 return EFI_SUCCESS;
2570 }
2571
2572 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
2573 //
2574 // User pressed enter, equivalent to select "continue"
2575 //
2576 return EFI_TIMEOUT;
2577 }
2578
2579 //
2580 //F2 -- Front Page
2581 //F5 -- Device Manager
2582 //F7 -- Boot Manager
2583 // do not use F8. generally people assume it is windows safe mode key.
2584 //F9 -- Boot order
2585 //
2586 DEBUG ((EFI_D_INFO, "[Key Pressed]: ScanCode 0x%x\n", Key.ScanCode));
2587 switch(Key.ScanCode) {
2588 case SCAN_F2:
2589 gHotKey = 0;
2590 break;
2591
2592 case SCAN_DELETE:
2593 gHotKey = 0;
2594 break;
2595
2596 case SCAN_F5:
2597 gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
2598 break;
2599
2600 case SCAN_F7:
2601 gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
2602 break;
2603
2604 case SCAN_F9:
2605 gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
2606 break;
2607
2608 default:
2609 //set gHotKey to continue so that flow will not go into CallFrontPage
2610 gHotKey = FRONT_PAGE_KEY_CONTINUE;
2611 return EFI_TIMEOUT;
2612 break;
2613 }
2614
2615 return EFI_SUCCESS;
2616 }
2617
2618
2619
2620 /**
2621 This function is the main entry of the platform setup entry.
2622 The function will present the main menu of the system setup,
2623 this is the platform reference part and can be customize.
2624
2625
2626 @param TimeoutDefault The fault time out value before the system
2627 continue to boot.
2628 @param ConnectAllHappened The indicater to check if the connect all have
2629 already happened.
2630
2631 **/
2632 VOID
2633 PlatformBdsEnterFrontPageWithHotKey (
2634 IN UINT16 TimeoutDefault,
2635 IN BOOLEAN ConnectAllHappened
2636 )
2637 {
2638 EFI_STATUS Status;
2639
2640 EFI_STATUS LogoStatus;
2641 EFI_BOOT_LOGO_PROTOCOL *BootLogo;
2642 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
2643 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
2644 UINTN BootTextColumn;
2645 UINTN BootTextRow;
2646
2647 GraphicsOutput = NULL;
2648 SimpleTextOut = NULL;
2649
2650 PERF_START (NULL, "BdsTimeOut", "BDS", 0);
2651
2652 //
2653 // Indicate if we need connect all in the platform setup
2654 //
2655 if (ConnectAllHappened) {
2656 gConnectAllHappened = TRUE;
2657 }
2658
2659 if (!mModeInitialized) {
2660 //
2661 // After the console is ready, get current video resolution
2662 // and text mode before launching setup at first time.
2663 //
2664 Status = gBS->HandleProtocol (
2665 gST->ConsoleOutHandle,
2666 &gEfiGraphicsOutputProtocolGuid,
2667 (VOID**)&GraphicsOutput
2668 );
2669 if (EFI_ERROR (Status)) {
2670 GraphicsOutput = NULL;
2671 }
2672
2673 Status = gBS->HandleProtocol (
2674 gST->ConsoleOutHandle,
2675 &gEfiSimpleTextOutProtocolGuid,
2676 (VOID**)&SimpleTextOut
2677 );
2678 if (EFI_ERROR (Status)) {
2679 SimpleTextOut = NULL;
2680 }
2681
2682 if (GraphicsOutput != NULL) {
2683 //
2684 // Get current video resolution and text mode.
2685 //
2686 mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
2687 mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
2688 }
2689
2690 if (SimpleTextOut != NULL) {
2691 Status = SimpleTextOut->QueryMode (
2692 SimpleTextOut,
2693 SimpleTextOut->Mode->Mode,
2694 &BootTextColumn,
2695 &BootTextRow
2696 );
2697 mBootTextModeColumn = (UINT32)BootTextColumn;
2698 mBootTextModeRow = (UINT32)BootTextRow;
2699 }
2700
2701 //
2702 // Get user defined text mode for setup.
2703 //
2704 mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
2705 mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
2706 mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);
2707 mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);
2708
2709 mModeInitialized = TRUE;
2710 }
2711
2712 if (TimeoutDefault != 0xffff) {
2713 Status = ShowProgressHotKey (TimeoutDefault);
2714
2715 //
2716 // Ensure screen is clear when switch Console from Graphics mode to Text mode
2717 //
2718 gST->ConOut->EnableCursor (gST->ConOut, TRUE);
2719 gST->ConOut->ClearScreen (gST->ConOut);
2720
2721 //
2722 // Boot Logo is corrupted, report it using Boot Logo protocol.
2723 //
2724 LogoStatus = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);
2725 if (!EFI_ERROR (LogoStatus) && (BootLogo != NULL)) {
2726 BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);
2727 }
2728
2729 if (EFI_ERROR (Status)) {
2730 //
2731 // Timeout or user press enter to continue
2732 //
2733 goto Exit;
2734 }
2735 }
2736
2737 //
2738 // Install BM HiiPackages.
2739 // Keep BootMaint HiiPackage, so that it can be covered by global setting.
2740 //
2741 InitBMPackage ();
2742 do {
2743
2744 BdsSetConsoleMode (TRUE);
2745
2746 InitializeFrontPage (FALSE);
2747
2748 //
2749 // Update Front Page strings
2750 //
2751 UpdateFrontPageStrings ();
2752
2753 Status = EFI_SUCCESS;
2754 gCallbackKey = 0;
2755 if (gHotKey == 0) {
2756 Status = CallFrontPage ();
2757 } else {
2758 gCallbackKey = gHotKey;
2759 gHotKey = 0;
2760 }
2761
2762 //
2763 // If gCallbackKey is greater than 1 and less or equal to 5,
2764 // it will launch configuration utilities.
2765 // 2 = set language
2766 // 3 = boot manager
2767 // 4 = device manager
2768 // 5 = boot maintenance manager
2769 //
2770 if (gCallbackKey != 0) {
2771 REPORT_STATUS_CODE (
2772 EFI_PROGRESS_CODE,
2773 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
2774 );
2775 }
2776
2777 //
2778 // Based on the key that was set, we can determine what to do
2779 //
2780 switch (gCallbackKey) {
2781 //
2782 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
2783 // describe to their customers in documentation how to find their setup information (namely
2784 // under the device manager and specific buckets)
2785 //
2786 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
2787 //
2788 case FRONT_PAGE_KEY_CONTINUE:
2789
2790 //
2791 // User hit continue
2792 //
2793 break;
2794
2795 case FRONT_PAGE_KEY_LANGUAGE:
2796
2797 //
2798 // User made a language setting change - display front page again
2799 //
2800 break;
2801
2802 case FRONT_PAGE_KEY_BOOT_MANAGER:
2803 //
2804 // Remove the installed BootMaint HiiPackages when exit.
2805 //
2806 FreeBMPackage ();
2807
2808 //
2809 // User chose to run the Boot Manager
2810 //
2811 CallBootManager ();
2812
2813 //
2814 // Reinstall BootMaint HiiPackages after exiting from Boot Manager.
2815 //
2816 InitBMPackage ();
2817 break;
2818
2819 case FRONT_PAGE_KEY_DEVICE_MANAGER:
2820
2821 //
2822 // Display the Device Manager
2823 //
2824 do {
2825 CallDeviceManager ();
2826 } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);
2827 break;
2828
2829 case FRONT_PAGE_KEY_BOOT_MAINTAIN:
2830
2831 //
2832 // Display the Boot Maintenance Manager
2833 //
2834 BdsStartBootMaint ();
2835 break;
2836 }
2837
2838 } while (((UINTN)gCallbackKey) != FRONT_PAGE_KEY_CONTINUE);
2839
2840 //
2841 //Will leave browser, check any reset required change is applied? if yes, reset system
2842 //
2843 SetupResetReminder ();
2844 //
2845 // Remove the installed BootMaint HiiPackages when exit.
2846 //
2847 FreeBMPackage ();
2848
2849 Exit:
2850 //
2851 // Automatically load current entry
2852 // Note: The following lines of code only execute when Auto boot
2853 // takes affect
2854 //
2855 PERF_END (NULL, "BdsTimeOut", "BDS", 0);
2856 }
2857
2858
2859 VOID
2860 BootIntoFirmwareInterface(
2861 VOID
2862 )
2863 {
2864 EFI_STATUS Status;
2865 UINTN DataSize;
2866 UINT16 Timeout;
2867 UINT64 OsIndication;
2868
2869
2870 OsIndication = 0;
2871 DataSize = sizeof(UINT64);
2872 Status = gRT->GetVariable (
2873 L"OsIndications",
2874 &gEfiGlobalVariableGuid,
2875 NULL,
2876 &DataSize,
2877 &OsIndication
2878 );
2879
2880 DEBUG ((EFI_D_INFO, "OSIndication Variable Value %d\n", OsIndication));
2881 //
2882 //Goto FrontPage directly when bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted.
2883 //
2884 if (!EFI_ERROR(Status) && (OsIndication != 0)) {
2885 Timeout = 0xffff;
2886 PlatformBdsEnterFrontPage (Timeout, FALSE);
2887 }
2888 }
2889
2890
2891 EFI_STATUS
2892 PlatformBdsConnectSimpleConsole (
2893 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
2894 )
2895 {
2896 EFI_STATUS Status;
2897 UINTN Index;
2898 EFI_DEVICE_PATH_PROTOCOL *VarConout;
2899 EFI_DEVICE_PATH_PROTOCOL *VarConin;
2900 UINTN DevicePathSize;
2901
2902
2903 Index = 0;
2904 Status = EFI_SUCCESS;
2905 DevicePathSize = 0;
2906 VarConout = BdsLibGetVariableAndSize (
2907 L"ConOut",
2908 &gEfiGlobalVariableGuid,
2909 &DevicePathSize
2910 );
2911 VarConin = BdsLibGetVariableAndSize (
2912 L"ConIn",
2913 &gEfiGlobalVariableGuid,
2914 &DevicePathSize
2915 );
2916 if (VarConout == NULL || VarConin == NULL) {
2917 //
2918 // Have chance to connect the platform default console,
2919 // the platform default console is the minimum device group
2920 // the platform should support
2921 //
2922 while (PlatformConsole[Index].DevicePath != NULL) {
2923
2924 //
2925 // Update the console variable with the connect type
2926 //
2927 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
2928 BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);
2929 }
2930
2931 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
2932 BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);
2933 }
2934
2935 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
2936 BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);
2937 }
2938
2939 Index ++;
2940 }
2941 }
2942
2943 //
2944 // Connect ConIn first to give keyboard time to parse hot key event.
2945 //
2946 Status = BdsLibConnectConsoleVariable (L"ConIn");
2947 if (EFI_ERROR (Status)) {
2948 return Status;
2949 }
2950
2951 //
2952 // Make sure we have at least one active VGA, and have the right
2953 // active VGA in console variable
2954 //
2955 Status = PlatformBdsForceActiveVga ();
2956
2957 //
2958 // It seems impossible not to have any ConOut device on platform,
2959 // so we check the status here.
2960 //
2961 Status = BdsLibConnectConsoleVariable (L"ConOut");
2962 if (EFI_ERROR (Status)) {
2963 return Status;
2964 }
2965
2966 return EFI_SUCCESS;
2967 }
2968
2969
2970 /**
2971 Timer handler to convert the key from USB.
2972
2973 @param Event Indicates the event that invoke this function.
2974 @param Context Indicates the calling context.
2975 **/
2976 VOID
2977 EFIAPI
2978 HotKeyTimerHandler (
2979 IN EFI_EVENT Event,
2980 IN VOID *Context
2981 )
2982 {
2983 EFI_STATUS Status;
2984 EFI_INPUT_KEY Key;
2985
2986 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
2987 if (EFI_ERROR (Status)) {
2988 return;
2989 }
2990
2991 switch(Key.ScanCode) {
2992 case SCAN_F2:
2993 gHotKey = 0;
2994 mHotKeyPressed = TRUE;
2995 break;
2996
2997 case SCAN_F5:
2998 gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
2999 mHotKeyPressed = TRUE;
3000 break;
3001
3002 case SCAN_F7:
3003 gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
3004 mHotKeyPressed = TRUE;
3005 break;
3006
3007 case SCAN_F9:
3008 gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
3009 mHotKeyPressed = TRUE;
3010 break;
3011 }
3012
3013 if (mHotKeyPressed) {
3014 gBS->SetTimer (
3015 mHotKeyTimerEvent,
3016 TimerCancel,
3017 0
3018 );
3019 gBS->CloseEvent (mHotKeyTimerEvent);
3020 mHotKeyTimerEvent = NULL;
3021 }
3022
3023 return;
3024 }
3025
3026
3027 /**
3028 Callback function for SimpleTextInEx protocol install events
3029
3030 @param Event the event that is signaled.
3031 @param Context not used here.
3032
3033 **/
3034 VOID
3035 EFIAPI
3036 HitHotkeyEvent (
3037 IN EFI_EVENT Event,
3038 IN VOID *Context
3039 )
3040 {
3041 EFI_STATUS Status;
3042
3043 Status = gBS->CloseEvent(mHitHotkeyEvent);
3044 if (EFI_ERROR (Status)) {
3045 return;
3046 }
3047 Status = gBS->CreateEvent (
3048 EVT_TIMER | EVT_NOTIFY_SIGNAL,
3049 TPL_NOTIFY,
3050 HotKeyTimerHandler,
3051 NULL,
3052 &mHotKeyTimerEvent
3053 );
3054 if (EFI_ERROR (Status)) {
3055 return;
3056 }
3057 Status = gBS->SetTimer (
3058 mHotKeyTimerEvent,
3059 TimerPeriodic,
3060 KEYBOARD_TIMER_INTERVAL
3061 );
3062 if (EFI_ERROR (Status)) {
3063 return;
3064 }
3065
3066 return;
3067 }
3068
3069
3070 VOID
3071 EFIAPI
3072 PlatformBdsInitHotKeyEvent (
3073 VOID
3074 )
3075 {
3076 EFI_STATUS Status;
3077
3078 //
3079 // Register Protocol notify for Hotkey service
3080 //
3081 Status = gBS->CreateEvent (
3082 EVT_NOTIFY_SIGNAL,
3083 TPL_CALLBACK,
3084 HitHotkeyEvent,
3085 NULL,
3086 &mHitHotkeyEvent
3087 );
3088 ASSERT_EFI_ERROR (Status);
3089
3090 //
3091 // Register for protocol notifications on this event
3092 //
3093 Status = gBS->RegisterProtocolNotify (
3094 &gEfiSimpleTextInputExProtocolGuid,
3095 mHitHotkeyEvent,
3096 &mHitHotkeyRegistration
3097 );
3098 ASSERT_EFI_ERROR (Status);
3099 }