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