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