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