]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
Vlv2TbltDevicePkg:Signal EndOfDxe 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 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 //
231 // Signal EndOfDxe PI Event
232 //
233 EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
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 UINT8 Data;
2167 UINT32 BlockLength;
2168 UINTN Index;
2169
2170 BaseAddress = Base - 0x400000 + 2;
2171 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (Base));
2172 BlockMap = &(FvHeader->BlockMap[0]);
2173
2174 while ((BlockMap->NumBlocks != 0) && (BlockMap->Length != 0)) {
2175 BlockLength = BlockMap->Length;
2176 for (Index = 0; Index < BlockMap->NumBlocks; Index++) {
2177 Data = MmioOr8 ((UINTN) BaseAddress, 0x03);
2178 BaseAddress += BlockLength;
2179 }
2180 BlockMap++;
2181 }
2182 }
2183
2184 VOID
2185 EFIAPI
2186 PlatformBdsLockNonUpdatableFlash (
2187 VOID
2188 )
2189 {
2190 EFI_PHYSICAL_ADDRESS Base;
2191
2192 Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvMainBase);
2193 if (Base > 0) {
2194 BdsLockFv (Base);
2195 }
2196
2197 Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvRecoveryBase);
2198 if (Base > 0) {
2199 BdsLockFv (Base);
2200 }
2201 }
2202
2203 /**
2204 Lock the ConsoleIn device in system table. All key
2205 presses will be ignored until the Password is typed in. The only way to
2206 disable the password is to type it in to a ConIn device.
2207
2208 @param Password Password used to lock ConIn device.
2209
2210 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
2211 @retval EFI_UNSUPPORTED Password not found
2212
2213 **/
2214 EFI_STATUS
2215 EFIAPI
2216 LockKeyboards (
2217 IN CHAR16 *Password
2218 )
2219 {
2220 return EFI_UNSUPPORTED;
2221 }
2222
2223 /**
2224 Connect the predefined platform default authentication devices.
2225
2226 This function connects the predefined device path for authentication device,
2227 and if the predefined device path has child device path, the child handle will
2228 be connected too. But the child handle of the child will not be connected.
2229
2230 **/
2231 VOID
2232 EFIAPI
2233 PlatformBdsConnectAuthDevice (
2234 VOID
2235 )
2236 {
2237 EFI_STATUS Status;
2238 UINTN Index;
2239 UINTN HandleIndex;
2240 UINTN HandleCount;
2241 EFI_HANDLE *HandleBuffer;
2242 EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath;
2243 EFI_USER_MANAGER_PROTOCOL *Manager;
2244
2245 Status = gBS->LocateProtocol (
2246 &gEfiUserManagerProtocolGuid,
2247 NULL,
2248 (VOID **) &Manager
2249 );
2250 if (EFI_ERROR (Status)) {
2251 //
2252 // As user manager protocol is not installed, the authentication devices
2253 // should not be connected.
2254 //
2255 return ;
2256 }
2257
2258 Index = 0;
2259 while (gUserAuthenticationDevice[Index] != NULL) {
2260 //
2261 // Connect the platform customized device paths
2262 //
2263 BdsLibConnectDevicePath (gUserAuthenticationDevice[Index]);
2264 Index++;
2265 }
2266
2267 //
2268 // Find and connect the child device paths of the platform customized device paths
2269 //
2270 HandleBuffer = NULL;
2271 for (Index = 0; gUserAuthenticationDevice[Index] != NULL; Index++) {
2272 HandleCount = 0;
2273 Status = gBS->LocateHandleBuffer (
2274 AllHandles,
2275 NULL,
2276 NULL,
2277 &HandleCount,
2278 &HandleBuffer
2279 );
2280 ASSERT (!EFI_ERROR (Status));
2281
2282 //
2283 // Find and connect the child device paths of gUserIdentificationDevice[Index]
2284 //
2285 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
2286 ChildDevicePath = NULL;
2287 Status = gBS->HandleProtocol (
2288 HandleBuffer[HandleIndex],
2289 &gEfiDevicePathProtocolGuid,
2290 (VOID **) &ChildDevicePath
2291 );
2292 if (EFI_ERROR (Status) || ChildDevicePath == NULL) {
2293 continue;
2294 }
2295
2296 if (CompareMem (
2297 ChildDevicePath,
2298 gUserAuthenticationDevice[Index],
2299 (GetDevicePathSize (gUserAuthenticationDevice[Index]) - sizeof (EFI_DEVICE_PATH_PROTOCOL))
2300 ) != 0) {
2301 continue;
2302 }
2303 gBS->ConnectController (
2304 HandleBuffer[HandleIndex],
2305 NULL,
2306 NULL,
2307 TRUE
2308 );
2309 }
2310 }
2311
2312 if (HandleBuffer != NULL) {
2313 FreePool (HandleBuffer);
2314 }
2315 }
2316
2317 /**
2318 This function is to identify a user, and return whether deferred images exist.
2319
2320 @param[out] User Point to user profile handle.
2321 @param[out] DeferredImageExist On return, points to TRUE if the deferred image
2322 exist or FALSE if it did not exist.
2323
2324 **/
2325 VOID
2326 EFIAPI
2327 PlatformBdsUserIdentify (
2328 OUT EFI_USER_PROFILE_HANDLE *User,
2329 OUT BOOLEAN *DeferredImageExist
2330 )
2331 {
2332 EFI_STATUS Status;
2333 EFI_DEFERRED_IMAGE_LOAD_PROTOCOL *DeferredImage;
2334 UINTN HandleCount;
2335 EFI_HANDLE *HandleBuf;
2336 UINTN Index;
2337 UINTN DriverIndex;
2338 EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
2339 VOID *DriverImage;
2340 UINTN ImageSize;
2341 BOOLEAN BootOption;
2342
2343 //
2344 // Perform user identification
2345 //
2346 do {
2347 Status = BdsLibUserIdentify (User);
2348 } while (EFI_ERROR (Status));
2349
2350 //
2351 // After user authentication now, try to find whether deferred image exists
2352 //
2353 HandleCount = 0;
2354 HandleBuf = NULL;
2355 *DeferredImageExist = FALSE;
2356 Status = gBS->LocateHandleBuffer (
2357 ByProtocol,
2358 &gEfiDeferredImageLoadProtocolGuid,
2359 NULL,
2360 &HandleCount,
2361 &HandleBuf
2362 );
2363 if (EFI_ERROR (Status)) {
2364 return ;
2365 }
2366
2367 for (Index = 0; Index < HandleCount; Index++) {
2368 Status = gBS->HandleProtocol (
2369 HandleBuf[Index],
2370 &gEfiDeferredImageLoadProtocolGuid,
2371 (VOID **) &DeferredImage
2372 );
2373 if (!EFI_ERROR (Status)) {
2374 //
2375 // Find whether deferred image exists in this instance.
2376 //
2377 DriverIndex = 0;
2378 Status = DeferredImage->GetImageInfo(
2379 DeferredImage,
2380 DriverIndex,
2381 &ImageDevicePath,
2382 (VOID **) &DriverImage,
2383 &ImageSize,
2384 &BootOption
2385 );
2386 if (!EFI_ERROR (Status)) {
2387 //
2388 // The deferred image is found.
2389 //
2390 FreePool (HandleBuf);
2391 *DeferredImageExist = TRUE;
2392 return ;
2393 }
2394 }
2395 }
2396
2397 FreePool (HandleBuf);
2398 }
2399
2400 UINTN gHotKey = 0;
2401
2402
2403 EFI_STATUS
2404 ShowProgressHotKey (
2405 IN UINT16 TimeoutDefault
2406 )
2407 {
2408 CHAR16 *TmpStr;
2409 UINT16 TimeoutRemain;
2410 EFI_STATUS Status;
2411 EFI_INPUT_KEY Key;
2412 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
2413 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
2414 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
2415 UINT32 GpioValue;
2416
2417 if (TimeoutDefault == 0) {
2418 return EFI_TIMEOUT;
2419 }
2420
2421 gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
2422
2423 if (DebugAssertEnabled())
2424 {
2425 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"));
2426 }
2427 else
2428 {
2429 #ifdef __GNUC__
2430 SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)[GCC]", 76);
2431 #else
2432 SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)", 71);
2433 #endif
2434 }
2435 SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
2436 SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
2437 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
2438
2439 //
2440 // Clear the progress status bar first
2441 //
2442 TmpStr = L"Start boot option, Press <F2> or <DEL> to enter setup page.";
2443 PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);
2444
2445 TimeoutRemain = TimeoutDefault;
2446 while (TimeoutRemain != 0) {
2447 if (DebugAssertEnabled())
2448 {
2449 DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));
2450 }
2451 else
2452 {
2453 SerialPortWrite ((UINT8 *)".", 1);
2454 }
2455 Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);
2456 if (Status != EFI_TIMEOUT) {
2457 break;
2458 }
2459 TimeoutRemain--;
2460
2461 //
2462 // Show progress
2463 //
2464 if (TmpStr != NULL) {
2465 PlatformBdsShowProgress (
2466 Foreground,
2467 Background,
2468 TmpStr,
2469 Color,
2470 ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),
2471 0
2472 );
2473 }
2474 }
2475
2476 //
2477 // Timeout expired
2478 //
2479 if (TimeoutRemain == 0) {
2480 if (DebugAssertEnabled())
2481 {
2482 }
2483 else
2484 {
2485 SerialPortWrite ((UINT8 *)"\r\n", 2);
2486 }
2487 return EFI_TIMEOUT;
2488 }
2489
2490 //
2491 // User pressed some key
2492 //
2493 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
2494 if (EFI_ERROR (Status)) {
2495 return Status;
2496 }
2497
2498 //
2499 // Check Volume Up Key to enter Setup
2500 //
2501 GpioValue = MmioRead32 (IO_BASE_ADDRESS + 0x0668); // The value of GPIOC_5
2502 if (((GpioValue & BIT0) == 0) && (Key.ScanCode == SCAN_UP)) {
2503 gHotKey = 0;
2504 return EFI_SUCCESS;
2505 }
2506
2507 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
2508 //
2509 // User pressed enter, equivalent to select "continue"
2510 //
2511 return EFI_TIMEOUT;
2512 }
2513
2514 //
2515 //F2 -- Front Page
2516 //F5 -- Device Manager
2517 //F7 -- Boot Manager
2518 // do not use F8. generally people assume it is windows safe mode key.
2519 //F9 -- Boot order
2520 //
2521 DEBUG ((EFI_D_INFO, "[Key Pressed]: ScanCode 0x%x\n", Key.ScanCode));
2522 switch(Key.ScanCode) {
2523 case SCAN_F2:
2524 gHotKey = 0;
2525 break;
2526
2527 case SCAN_DELETE:
2528 gHotKey = 0;
2529 break;
2530
2531 case SCAN_F5:
2532 gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
2533 break;
2534
2535 case SCAN_F7:
2536 gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
2537 break;
2538
2539 case SCAN_F9:
2540 gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
2541 break;
2542
2543 default:
2544 //set gHotKey to continue so that flow will not go into CallFrontPage
2545 gHotKey = FRONT_PAGE_KEY_CONTINUE;
2546 return EFI_TIMEOUT;
2547 break;
2548 }
2549
2550 return EFI_SUCCESS;
2551 }
2552
2553
2554
2555 /**
2556 This function is the main entry of the platform setup entry.
2557 The function will present the main menu of the system setup,
2558 this is the platform reference part and can be customize.
2559
2560
2561 @param TimeoutDefault The fault time out value before the system
2562 continue to boot.
2563 @param ConnectAllHappened The indicater to check if the connect all have
2564 already happened.
2565
2566 **/
2567 VOID
2568 PlatformBdsEnterFrontPageWithHotKey (
2569 IN UINT16 TimeoutDefault,
2570 IN BOOLEAN ConnectAllHappened
2571 )
2572 {
2573 EFI_STATUS Status;
2574
2575 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
2576 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
2577 UINTN BootTextColumn;
2578 UINTN BootTextRow;
2579
2580 GraphicsOutput = NULL;
2581 SimpleTextOut = NULL;
2582
2583 PERF_START (NULL, "BdsTimeOut", "BDS", 0);
2584
2585 //
2586 // Indicate if we need connect all in the platform setup
2587 //
2588 if (ConnectAllHappened) {
2589 gConnectAllHappened = TRUE;
2590 }
2591
2592 if (!mModeInitialized) {
2593 //
2594 // After the console is ready, get current video resolution
2595 // and text mode before launching setup at first time.
2596 //
2597 Status = gBS->HandleProtocol (
2598 gST->ConsoleOutHandle,
2599 &gEfiGraphicsOutputProtocolGuid,
2600 (VOID**)&GraphicsOutput
2601 );
2602 if (EFI_ERROR (Status)) {
2603 GraphicsOutput = NULL;
2604 }
2605
2606 Status = gBS->HandleProtocol (
2607 gST->ConsoleOutHandle,
2608 &gEfiSimpleTextOutProtocolGuid,
2609 (VOID**)&SimpleTextOut
2610 );
2611 if (EFI_ERROR (Status)) {
2612 SimpleTextOut = NULL;
2613 }
2614
2615 if (GraphicsOutput != NULL) {
2616 //
2617 // Get current video resolution and text mode.
2618 //
2619 mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
2620 mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
2621 }
2622
2623 if (SimpleTextOut != NULL) {
2624 Status = SimpleTextOut->QueryMode (
2625 SimpleTextOut,
2626 SimpleTextOut->Mode->Mode,
2627 &BootTextColumn,
2628 &BootTextRow
2629 );
2630 mBootTextModeColumn = (UINT32)BootTextColumn;
2631 mBootTextModeRow = (UINT32)BootTextRow;
2632 }
2633
2634 //
2635 // Get user defined text mode for setup.
2636 //
2637 mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
2638 mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
2639 mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);
2640 mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);
2641
2642 mModeInitialized = TRUE;
2643 }
2644
2645 if (TimeoutDefault != 0xffff) {
2646 Status = ShowProgressHotKey (TimeoutDefault);
2647
2648 //
2649 // Ensure screen is clear when switch Console from Graphics mode to Text mode
2650 //
2651 gST->ConOut->EnableCursor (gST->ConOut, TRUE);
2652 gST->ConOut->ClearScreen (gST->ConOut);
2653
2654 if (EFI_ERROR (Status)) {
2655 //
2656 // Timeout or user press enter to continue
2657 //
2658 goto Exit;
2659 }
2660 }
2661 //
2662 // Install BM HiiPackages.
2663 // Keep BootMaint HiiPackage, so that it can be covered by global setting.
2664 //
2665 InitBMPackage ();
2666 do {
2667
2668 BdsSetConsoleMode (TRUE);
2669
2670 InitializeFrontPage (FALSE);
2671
2672 //
2673 // Update Front Page strings
2674 //
2675 UpdateFrontPageStrings ();
2676
2677 Status = EFI_SUCCESS;
2678 gCallbackKey = 0;
2679 if (gHotKey == 0) {
2680 Status = CallFrontPage ();
2681 } else {
2682 gCallbackKey = gHotKey;
2683 gHotKey = 0;
2684 }
2685
2686 //
2687 // If gCallbackKey is greater than 1 and less or equal to 5,
2688 // it will launch configuration utilities.
2689 // 2 = set language
2690 // 3 = boot manager
2691 // 4 = device manager
2692 // 5 = boot maintenance manager
2693 //
2694 if (gCallbackKey != 0) {
2695 REPORT_STATUS_CODE (
2696 EFI_PROGRESS_CODE,
2697 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
2698 );
2699 }
2700
2701 //
2702 // Based on the key that was set, we can determine what to do
2703 //
2704 switch (gCallbackKey) {
2705 //
2706 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
2707 // describe to their customers in documentation how to find their setup information (namely
2708 // under the device manager and specific buckets)
2709 //
2710 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
2711 //
2712 case FRONT_PAGE_KEY_CONTINUE:
2713
2714 //
2715 // User hit continue
2716 //
2717 break;
2718
2719 case FRONT_PAGE_KEY_LANGUAGE:
2720
2721 //
2722 // User made a language setting change - display front page again
2723 //
2724 break;
2725
2726 case FRONT_PAGE_KEY_BOOT_MANAGER:
2727 //
2728 // Remove the installed BootMaint HiiPackages when exit.
2729 //
2730 FreeBMPackage ();
2731
2732 //
2733 // User chose to run the Boot Manager
2734 //
2735 CallBootManager ();
2736
2737 //
2738 // Reinstall BootMaint HiiPackages after exiting from Boot Manager.
2739 //
2740 InitBMPackage ();
2741 break;
2742
2743 case FRONT_PAGE_KEY_DEVICE_MANAGER:
2744
2745 //
2746 // Display the Device Manager
2747 //
2748 do {
2749 CallDeviceManager ();
2750 } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);
2751 break;
2752
2753 case FRONT_PAGE_KEY_BOOT_MAINTAIN:
2754
2755 //
2756 // Display the Boot Maintenance Manager
2757 //
2758 BdsStartBootMaint ();
2759 break;
2760 }
2761
2762 } while (((UINTN)gCallbackKey) != FRONT_PAGE_KEY_CONTINUE);
2763
2764 //
2765 //Will leave browser, check any reset required change is applied? if yes, reset system
2766 //
2767 SetupResetReminder ();
2768 //
2769 // Remove the installed BootMaint HiiPackages when exit.
2770 //
2771 FreeBMPackage ();
2772
2773 Exit:
2774 //
2775 // Automatically load current entry
2776 // Note: The following lines of code only execute when Auto boot
2777 // takes affect
2778 //
2779 PERF_END (NULL, "BdsTimeOut", "BDS", 0);
2780 }
2781
2782
2783 VOID
2784 BootIntoFirmwareInterface(
2785 VOID
2786 )
2787 {
2788 EFI_STATUS Status;
2789 UINTN DataSize;
2790 UINT16 Timeout;
2791 UINT64 OsIndication;
2792
2793
2794 OsIndication = 0;
2795 DataSize = sizeof(UINT64);
2796 Status = gRT->GetVariable (
2797 L"OsIndications",
2798 &gEfiGlobalVariableGuid,
2799 NULL,
2800 &DataSize,
2801 &OsIndication
2802 );
2803
2804 DEBUG ((EFI_D_INFO, "OSIndication Variable Value %d\n", OsIndication));
2805 //
2806 //Goto FrontPage directly when bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted.
2807 //
2808 if (!EFI_ERROR(Status) && (OsIndication != 0)) {
2809 Timeout = 0xffff;
2810 PlatformBdsEnterFrontPage (Timeout, FALSE);
2811 }
2812 }
2813
2814
2815 EFI_STATUS
2816 PlatformBdsConnectSimpleConsole (
2817 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
2818 )
2819 {
2820 EFI_STATUS Status;
2821 UINTN Index;
2822 EFI_DEVICE_PATH_PROTOCOL *VarConout;
2823 EFI_DEVICE_PATH_PROTOCOL *VarConin;
2824 UINTN DevicePathSize;
2825
2826
2827 Index = 0;
2828 Status = EFI_SUCCESS;
2829 DevicePathSize = 0;
2830 VarConout = BdsLibGetVariableAndSize (
2831 L"ConOut",
2832 &gEfiGlobalVariableGuid,
2833 &DevicePathSize
2834 );
2835 VarConin = BdsLibGetVariableAndSize (
2836 L"ConIn",
2837 &gEfiGlobalVariableGuid,
2838 &DevicePathSize
2839 );
2840 if (VarConout == NULL || VarConin == NULL) {
2841 //
2842 // Have chance to connect the platform default console,
2843 // the platform default console is the minimue device group
2844 // the platform should support
2845 //
2846 while (PlatformConsole[Index].DevicePath != NULL) {
2847
2848 //
2849 // Update the console variable with the connect type
2850 //
2851 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
2852 BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);
2853 }
2854
2855 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
2856 BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);
2857 }
2858
2859 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
2860 BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);
2861 }
2862
2863 Index ++;
2864 }
2865 }
2866
2867 //
2868 // Connect ConIn first to give keyboard time to parse hot key event.
2869 //
2870 Status = BdsLibConnectConsoleVariable (L"ConIn");
2871 if (EFI_ERROR (Status)) {
2872 return Status;
2873 }
2874
2875 //
2876 // Make sure we have at least one active VGA, and have the right
2877 // active VGA in console variable
2878 //
2879 Status = PlatformBdsForceActiveVga ();
2880
2881 //
2882 // It seems impossible not to have any ConOut device on platform,
2883 // so we check the status here.
2884 //
2885 Status = BdsLibConnectConsoleVariable (L"ConOut");
2886 if (EFI_ERROR (Status)) {
2887 return Status;
2888 }
2889
2890 return EFI_SUCCESS;
2891 }
2892
2893
2894 /**
2895 Timer handler to convert the key from USB.
2896
2897 @param Event Indicates the event that invoke this function.
2898 @param Context Indicates the calling context.
2899 **/
2900 VOID
2901 EFIAPI
2902 HotKeyTimerHandler (
2903 IN EFI_EVENT Event,
2904 IN VOID *Context
2905 )
2906 {
2907 EFI_STATUS Status;
2908 EFI_INPUT_KEY Key;
2909
2910 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
2911 if (EFI_ERROR (Status)) {
2912 return;
2913 }
2914
2915 switch(Key.ScanCode) {
2916 case SCAN_F2:
2917 gHotKey = 0;
2918 mHotKeyPressed = TRUE;
2919 break;
2920
2921 case SCAN_F5:
2922 gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
2923 mHotKeyPressed = TRUE;
2924 break;
2925
2926 case SCAN_F7:
2927 gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
2928 mHotKeyPressed = TRUE;
2929 break;
2930
2931 case SCAN_F9:
2932 gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
2933 mHotKeyPressed = TRUE;
2934 break;
2935 }
2936
2937 if (mHotKeyPressed) {
2938 gBS->SetTimer (
2939 mHotKeyTimerEvent,
2940 TimerCancel,
2941 0
2942 );
2943 gBS->CloseEvent (mHotKeyTimerEvent);
2944 mHotKeyTimerEvent = NULL;
2945 }
2946
2947 return;
2948 }
2949
2950
2951 /**
2952 Callback function for SimpleTextInEx protocol install events
2953
2954 @param Event the event that is signaled.
2955 @param Context not used here.
2956
2957 **/
2958 VOID
2959 EFIAPI
2960 HitHotkeyEvent (
2961 IN EFI_EVENT Event,
2962 IN VOID *Context
2963 )
2964 {
2965 EFI_STATUS Status;
2966
2967 Status = gBS->CloseEvent(mHitHotkeyEvent);
2968 if (EFI_ERROR (Status)) {
2969 return;
2970 }
2971 Status = gBS->CreateEvent (
2972 EVT_TIMER | EVT_NOTIFY_SIGNAL,
2973 TPL_NOTIFY,
2974 HotKeyTimerHandler,
2975 NULL,
2976 &mHotKeyTimerEvent
2977 );
2978 if (EFI_ERROR (Status)) {
2979 return;
2980 }
2981 Status = gBS->SetTimer (
2982 mHotKeyTimerEvent,
2983 TimerPeriodic,
2984 KEYBOARD_TIMER_INTERVAL
2985 );
2986 if (EFI_ERROR (Status)) {
2987 return;
2988 }
2989
2990 return;
2991 }
2992
2993
2994 VOID
2995 EFIAPI
2996 PlatformBdsInitHotKeyEvent (
2997 VOID
2998 )
2999 {
3000 EFI_STATUS Status;
3001
3002 //
3003 // Register Protocol notify for Hotkey service
3004 //
3005 Status = gBS->CreateEvent (
3006 EVT_NOTIFY_SIGNAL,
3007 TPL_CALLBACK,
3008 HitHotkeyEvent,
3009 NULL,
3010 &mHitHotkeyEvent
3011 );
3012 ASSERT_EFI_ERROR (Status);
3013
3014 //
3015 // Register for protocol notifications on this event
3016 //
3017 Status = gBS->RegisterProtocolNotify (
3018 &gEfiSimpleTextInputExProtocolGuid,
3019 mHitHotkeyEvent,
3020 &mHitHotkeyRegistration
3021 );
3022 ASSERT_EFI_ERROR (Status);
3023 }