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