]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
Upload BSD-licensed Vlv2TbltDevicePkg and Vlv2DeviceRefCodePkg to
[mirror_edk2.git] / Vlv2TbltDevicePkg / Library / PlatformBdsLib / BdsPlatform.c
1 /** @file
2
3 Copyright (c) 2004 - 2014, 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
45 EFI_GUID *ConnectDriverTable[] = {
46 &gEfiMmioDeviceProtocolGuid,
47 &gEfiI2cMasterProtocolGuid,
48 &gEfiI2cHostProtocolGuid
49 };
50
51 #define SHELL_ENVIRONMENT_INTERFACE_PROTOCOL \
52 { \
53 0x47c7b221, 0xc42a, 0x11d2, 0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b \
54 }
55 VOID *mShellImageCallbackReg = NULL;
56
57
58
59 EFI_USER_PROFILE_HANDLE mCurrentUser = NULL;
60 EFI_EVENT mHotKeyTimerEvent = NULL;
61 EFI_EVENT mHitHotkeyEvent = NULL;
62 EFI_EVENT mUsbKeyboardConnectEvent = NULL;
63 BOOLEAN mHotKeyPressed = FALSE;
64 VOID *mHitHotkeyRegistration;
65 #define KEYBOARD_TIMER_INTERVAL 20000 // 0.02s
66
67 VOID
68 ConnectUSBController (
69 VOID
70 );
71
72 EFI_STATUS
73 PlatformBdsConnectSimpleConsole (
74 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
75 );
76
77 VOID
78 BootIntoFirmwareInterface(
79 VOID
80 );
81
82 VOID
83 EFIAPI
84 PlatformBdsInitHotKeyEvent (
85 VOID
86 );
87
88 VOID
89 EFIAPI
90 DisableAhciCtlr (
91 IN EFI_EVENT Event,
92 IN VOID *Context
93 )
94 {
95 UINT32 PmcDisableAddress;
96 UINT8 SataStorageAmount;
97 UINT32 SataBase;
98 UINT16 SataPortStatus;
99
100
101 DEBUG ((EFI_D_INFO, "Disable AHCI event is signalled\n"));
102 SataStorageAmount = 0;
103 SataBase = *(UINT32*) Context;
104
105 //
106 // BayTrail-M EDS chapter 16 ---- PCI IO Register Offset 92 (SATA Port Control and Status)
107 //
108 SataPortStatus = MmioRead16 (SataBase + R_PCH_SATA_PCS);
109
110 //
111 // Bit 8 EN: Port 0 Present
112 //
113 if ((SataPortStatus & 0x100) == 0x100) {
114 SataStorageAmount++;
115 }
116
117 //
118 // Bit 9 EN: Port 1 Present
119 //
120 if ((SataPortStatus & 0x200) == 0x200) {
121 SataStorageAmount++;
122 }
123
124 //
125 // Disable SATA controller when it sets to AHCI mode without carrying any devices
126 // in order to prevent AHCI yellow bang under Win device manager.
127 //
128 if (SataStorageAmount == 0) {
129 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;
130 MmioOr32 (PmcDisableAddress, B_PCH_PMC_FUNC_DIS_SATA);
131 S3BootScriptSaveMemWrite (
132 EfiBootScriptWidthUint32,
133 (UINTN) PmcDisableAddress,
134 1,
135 (VOID *) (UINTN) PmcDisableAddress
136 );
137 }
138 }
139
140 VOID
141 InstallReadyToLock (
142 VOID
143 )
144 {
145 EFI_STATUS Status;
146 EFI_HANDLE Handle;
147 EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
148 EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;
149
150 //
151 // Install DxeSmmReadyToLock protocol prior to the processing of boot options
152 //
153 Status = gBS->LocateProtocol (
154 &gEfiSmmAccess2ProtocolGuid,
155 NULL,
156 (VOID **) &SmmAccess
157 );
158 if (!EFI_ERROR (Status)) {
159
160 //
161 // Prepare S3 information, this MUST be done before DxeSmmReadyToLock
162 //
163 Status = gBS->LocateProtocol (
164 &gEfiAcpiS3SaveProtocolGuid,
165 NULL,
166 (VOID **)&AcpiS3Save
167 );
168 if (!EFI_ERROR (Status)) {
169 AcpiS3Save->S3Save (AcpiS3Save, NULL);
170 }
171
172 Handle = NULL;
173 Status = gBS->InstallProtocolInterface (
174 &Handle,
175 &gExitPmAuthProtocolGuid,
176 EFI_NATIVE_INTERFACE,
177 NULL
178 );
179 ASSERT_EFI_ERROR (Status);
180
181 Handle = NULL;
182 Status = gBS->InstallProtocolInterface (
183 &Handle,
184 &gEfiDxeSmmReadyToLockProtocolGuid,
185 EFI_NATIVE_INTERFACE,
186 NULL
187 );
188 ASSERT_EFI_ERROR (Status);
189 }
190
191 return ;
192 }
193
194 VOID
195 EFIAPI
196 ShellImageCallback (
197 IN EFI_EVENT Event,
198 IN VOID *Context
199 )
200 {
201 BdsSetConsoleMode (TRUE);
202 DEBUG ((EFI_D_INFO, "BdsEntry ShellImageCallback \n"));
203 }
204
205 //
206 // BDS Platform Functions
207 //
208 /**
209 Platform Bds init. Incude the platform firmware vendor, revision
210 and so crc check.
211
212 @param VOID
213
214 @retval None.
215
216 **/
217 VOID
218 EFIAPI
219 PlatformBdsInit (
220 VOID
221 )
222 {
223 EFI_STATUS Status;
224 EFI_EVENT ShellImageEvent;
225 EFI_GUID ShellEnvProtocol = SHELL_ENVIRONMENT_INTERFACE_PROTOCOL;
226
227 #ifdef __GNUC__
228 SerialPortWrite((UINT8 *)">>>>BdsEntry[GCC]\r\n", 19);
229 #else
230 SerialPortWrite((UINT8 *)">>>>BdsEntry\r\n", 14);
231 #endif
232 BdsLibSaveMemoryTypeInformation ();
233
234 //
235 // Before user authentication, the user identification devices need be connected
236 // from the platform customized device paths
237 //
238 PlatformBdsConnectAuthDevice ();
239
240 //
241 // As console is not ready, the auto logon user will be identified.
242 //
243 BdsLibUserIdentify (&mCurrentUser);
244
245 //
246 // Change Gop mode when boot into Shell
247 //
248 if (mShellImageCallbackReg == NULL) {
249 Status = gBS->CreateEvent (
250 EFI_EVENT_NOTIFY_SIGNAL,
251 EFI_TPL_CALLBACK,
252 ShellImageCallback,
253 NULL,
254 &ShellImageEvent
255 );
256 if (!EFI_ERROR (Status)) {
257 Status = gBS->RegisterProtocolNotify (
258 &ShellEnvProtocol,
259 ShellImageEvent,
260 &mShellImageCallbackReg
261 );
262
263 DEBUG ((EFI_D_INFO, "BdsEntry ShellImageCallback \n"));
264 }
265 }
266 }
267
268 EFI_STATUS
269 GetGopDevicePath (
270 IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,
271 OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath
272 )
273 {
274 UINTN Index;
275 EFI_STATUS Status;
276 EFI_HANDLE PciDeviceHandle;
277 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
278 EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath;
279 UINTN GopHandleCount;
280 EFI_HANDLE *GopHandleBuffer;
281
282 UINTN VarSize;
283 SYSTEM_CONFIGURATION mSystemConfiguration;
284
285 if (PciDevicePath == NULL || GopDevicePath == NULL) {
286 return EFI_INVALID_PARAMETER;
287 }
288
289 //
290 // Initialize the GopDevicePath to be PciDevicePath
291 //
292 *GopDevicePath = PciDevicePath;
293 TempPciDevicePath = PciDevicePath;
294
295 Status = gBS->LocateDevicePath (
296 &gEfiDevicePathProtocolGuid,
297 &TempPciDevicePath,
298 &PciDeviceHandle
299 );
300 if (EFI_ERROR (Status)) {
301 return Status;
302 }
303
304 //
305 // Try to connect this handle, so that GOP dirver could start on this
306 // device and create child handles with GraphicsOutput Protocol installed
307 // on them, then we get device paths of these child handles and select
308 // them as possible console device.
309 //
310
311 //
312 // Select display devices
313 //
314 VarSize = sizeof(SYSTEM_CONFIGURATION);
315 Status = gRT->GetVariable(
316 L"Setup",
317 &gEfiNormalSetupGuid,
318 NULL,
319 &VarSize,
320 &mSystemConfiguration
321 );
322 ASSERT_EFI_ERROR (Status);
323
324 if(mSystemConfiguration.BootDisplayDevice != 0x0)
325 {
326 ACPI_ADR_DEVICE_PATH AcpiAdr;
327 EFI_DEVICE_PATH_PROTOCOL *MyDevicePath = NULL;
328
329 AcpiAdr.Header.Type = ACPI_DEVICE_PATH;
330 AcpiAdr.Header.SubType = ACPI_ADR_DP;
331
332 switch (mSystemConfiguration.BootDisplayDevice) {
333 case 1:
334 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0); //CRT Device
335 break;
336 case 2:
337 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_HDMI, 0); //HDMI Device Port B
338 break;
339 case 3:
340 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_DP, 0); //DP PortB
341 break;
342 case 4:
343 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_C_DP, 0); //DP PortC
344 break;
345 case 5:
346 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_C_DP, 0); //eDP Port C
347 break;
348 case 6:
349 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_A, 0); //DSI Port A
350 break;
351 case 7:
352 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_C, 0); //DSI Port C
353 break;
354 default:
355 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0);
356 break;
357 }
358
359 SetDevicePathNodeLength (&AcpiAdr.Header, sizeof (ACPI_ADR_DEVICE_PATH));
360
361 MyDevicePath = AppendDevicePathNode(MyDevicePath, (EFI_DEVICE_PATH_PROTOCOL*)&AcpiAdr);
362
363 gBS->ConnectController (
364 PciDeviceHandle,
365 NULL,
366 MyDevicePath,
367 FALSE
368 );
369
370 FreePool(MyDevicePath);
371 }
372 else
373 {
374 gBS->ConnectController (
375 PciDeviceHandle,
376 NULL,
377 NULL,
378 FALSE
379 );
380 }
381
382 Status = gBS->LocateHandleBuffer (
383 ByProtocol,
384 &gEfiGraphicsOutputProtocolGuid,
385 NULL,
386 &GopHandleCount,
387 &GopHandleBuffer
388 );
389 if (!EFI_ERROR (Status)) {
390 //
391 // Add all the child handles as possible Console Device
392 //
393 for (Index = 0; Index < GopHandleCount; Index++) {
394 Status = gBS->HandleProtocol (
395 GopHandleBuffer[Index],
396 &gEfiDevicePathProtocolGuid,
397 (VOID**)&TempDevicePath
398 );
399 if (EFI_ERROR (Status)) {
400 continue;
401 }
402 if (CompareMem (
403 PciDevicePath,
404 TempDevicePath,
405 GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH
406 ) == 0) {
407 //
408 // In current implementation, we only enable one of the child handles
409 // as console device, i.e. sotre one of the child handle's device
410 // path to variable "ConOut"
411 // In futhure, we could select all child handles to be console device
412 //
413 *GopDevicePath = TempDevicePath;
414 }
415 }
416 gBS->FreePool (GopHandleBuffer);
417 }
418
419 return EFI_SUCCESS;
420 }
421
422 /**
423
424 Search out all the platform pci or agp video device. The function may will
425 find multiple video device, and return all enabled device path.
426
427 @param PlugInPciVgaDevicePath Return the platform plug in pci video device
428 path if the system have plug in pci video device.
429 @param OnboardPciVgaDevicePath Return the platform active agp video device path
430 if the system have plug in agp video device or on
431 chip agp device.
432
433 @retval EFI_SUCCSS Get all platform active video device path.
434 @retval EFI_STATUS Return the status of gBS->LocateDevicePath (),
435 gBS->ConnectController (),
436 and gBS->LocateHandleBuffer ().
437
438 **/
439 EFI_STATUS
440 GetPlugInPciVgaDevicePath (
441 IN OUT EFI_DEVICE_PATH_PROTOCOL **PlugInPciVgaDevicePath,
442 IN OUT EFI_DEVICE_PATH_PROTOCOL **OnboardPciVgaDevicePath
443 )
444 {
445 EFI_STATUS Status;
446 EFI_HANDLE RootHandle;
447 UINTN HandleCount;
448 EFI_HANDLE *HandleBuffer;
449 UINTN Index;
450 UINTN Index1;
451 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
452 BOOLEAN PlugInPciVga;
453 EFI_PCI_IO_PROTOCOL *PciIo;
454 PCI_TYPE00 Pci;
455
456 DevicePath = NULL;
457 PlugInPciVga = TRUE;
458 HandleCount = 0;
459 HandleBuffer = NULL;
460
461 //
462 // Make all the PCI_IO protocols on PCI Seg 0 show up
463 //
464 BdsLibConnectDevicePath (gPlatformRootBridges[0]);
465
466 Status = gBS->LocateDevicePath (
467 &gEfiDevicePathProtocolGuid,
468 &gPlatformRootBridges[0],
469 &RootHandle
470 );
471 if (EFI_ERROR (Status)) {
472 return Status;
473 }
474
475 Status = gBS->ConnectController (
476 RootHandle,
477 NULL,
478 NULL,
479 FALSE
480 );
481 if (EFI_ERROR (Status)) {
482 return Status;
483 }
484
485 //
486 // Start to check all the pci io to find all possible VGA device
487 //
488 HandleCount = 0;
489 HandleBuffer = NULL;
490 Status = gBS->LocateHandleBuffer (
491 ByProtocol,
492 &gEfiPciIoProtocolGuid,
493 NULL,
494 &HandleCount,
495 &HandleBuffer
496 );
497 if (EFI_ERROR (Status)) {
498 return Status;
499 }
500
501 for (Index = 0; Index < HandleCount; Index++) {
502 Status = gBS->HandleProtocol (
503 HandleBuffer[Index],
504 &gEfiPciIoProtocolGuid,
505 (VOID**)&PciIo
506 );
507 if (!EFI_ERROR (Status)) {
508
509 //
510 // Check for all VGA device
511 //
512 Status = PciIo->Pci.Read (
513 PciIo,
514 EfiPciIoWidthUint32,
515 0,
516 sizeof (Pci) / sizeof (UINT32),
517 &Pci
518 );
519 if (EFI_ERROR (Status)) {
520 continue;
521 }
522
523 //
524 // Here we decide which VGA device to enable in PCI bus
525 //
526 // The first plugin PCI VGA card device will be present as PCI VGA
527 // The onchip AGP or AGP card will be present as AGP VGA
528 //
529 if (!IS_PCI_VGA (&Pci)) {
530 continue;
531 }
532
533 //
534 // Set the device as the possible console out device,
535 //
536 // Below code will make every VGA device to be one
537 // of the possibe console out device
538 //
539 PlugInPciVga = TRUE;
540 gBS->HandleProtocol (
541 HandleBuffer[Index],
542 &gEfiDevicePathProtocolGuid,
543 (VOID**)&DevicePath
544 );
545
546 Index1 = 0;
547
548 while (gPlatformAllPossiblePciVgaConsole[Index1] != NULL) {
549 if (CompareMem (
550 DevicePath,
551 gPlatformAllPossiblePciVgaConsole[Index1],
552 GetDevicePathSize (gPlatformAllPossiblePciVgaConsole[Index1])
553 ) == 0) {
554
555 //
556 // This device is an AGP device
557 //
558 *OnboardPciVgaDevicePath = DevicePath;
559 PlugInPciVga = FALSE;
560 break;
561 }
562
563 Index1 ++;
564 }
565
566 if (PlugInPciVga) {
567 *PlugInPciVgaDevicePath = DevicePath;
568 }
569 }
570 }
571
572 FreePool (HandleBuffer);
573
574 return EFI_SUCCESS;
575 }
576
577 /**
578
579 Find the platform active vga, and base on the policy to enable the vga as
580 the console out device. The policy is driven by one setup variable "VBIOS".
581
582 None.
583
584 @param EFI_UNSUPPORTED There is no active vga device
585
586 @retval EFI_STATUS Return the status of BdsLibGetVariableAndSize ()
587
588 **/
589 EFI_STATUS
590 PlatformBdsForceActiveVga (
591 VOID
592 )
593 {
594 EFI_STATUS Status;
595 EFI_DEVICE_PATH_PROTOCOL *PlugInPciVgaDevicePath;
596 EFI_DEVICE_PATH_PROTOCOL *OnboardPciVgaDevicePath;
597 EFI_DEVICE_PATH_PROTOCOL *DevicePathFirst;
598 EFI_DEVICE_PATH_PROTOCOL *DevicePathSecond;
599 EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
600 UINTN VarSize;
601 SYSTEM_CONFIGURATION mSystemConfiguration;
602
603 Status = EFI_SUCCESS;
604 PlugInPciVgaDevicePath = NULL;
605 OnboardPciVgaDevicePath = NULL;
606
607 //
608 // Check the policy which is the first enabled VGA
609 //
610 GetPlugInPciVgaDevicePath (&PlugInPciVgaDevicePath, &OnboardPciVgaDevicePath);
611
612 if (PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath == NULL) {
613 return EFI_UNSUPPORTED;
614 }
615
616 VarSize = sizeof(SYSTEM_CONFIGURATION);
617 Status = gRT->GetVariable(
618 L"Setup",
619 &gEfiNormalSetupGuid,
620 NULL,
621 &VarSize,
622 &mSystemConfiguration
623 );
624 ASSERT_EFI_ERROR (Status);
625
626
627 if ((PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath != NULL) ) {
628 DEBUG ((EFI_D_ERROR,"Update onboard PCI VGA ...\n"));
629 DevicePathFirst = OnboardPciVgaDevicePath;
630 DevicePathSecond = PlugInPciVgaDevicePath;
631 goto UpdateConOut;
632 }
633 if(OnboardPciVgaDevicePath != NULL && mSystemConfiguration.PrimaryVideoAdaptor == 0) {
634 DEBUG ((EFI_D_ERROR,"Update onboard PCI VGA When set primary!!!...\n"));
635 DevicePathFirst = OnboardPciVgaDevicePath;
636 DevicePathSecond = PlugInPciVgaDevicePath;
637 goto UpdateConOut;
638 }
639
640 DEBUG ((EFI_D_ERROR,"Update plug in PCI VGA ...\n"));
641 DevicePathFirst = PlugInPciVgaDevicePath;
642 DevicePathSecond = OnboardPciVgaDevicePath;
643
644 UpdateConOut:
645 GetGopDevicePath (DevicePathFirst, &GopDevicePath);
646 DevicePathFirst = GopDevicePath;
647
648 Status = BdsLibUpdateConsoleVariable (
649 L"ConOut",
650 DevicePathFirst,
651 DevicePathSecond
652 );
653
654 return Status;
655 }
656
657 VOID
658 UpdateConsoleResolution(
659 VOID
660 )
661 {
662 UINT32 HorizontalResolution;
663 UINT32 VerticalResolution;
664 SYSTEM_CONFIGURATION SystemConfiguration;
665 UINTN VarSize;
666 EFI_STATUS Status;
667
668
669 HorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
670 VerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
671
672 VarSize = sizeof(SYSTEM_CONFIGURATION);
673 Status = gRT->GetVariable(
674 L"Setup",
675 &gEfiNormalSetupGuid,
676 NULL,
677 &VarSize,
678 &SystemConfiguration
679 );
680 ASSERT_EFI_ERROR (Status);
681
682 switch (SystemConfiguration.IgdFlatPanel) {
683
684 case 0:
685 //
686 // Use the detault PCD values.
687 //
688 break;
689
690 case 1:
691 HorizontalResolution = 640;
692 VerticalResolution = 480;
693 break;
694
695 case 2:
696 HorizontalResolution = 800;
697 VerticalResolution = 600;
698 break;
699
700 case 3:
701 HorizontalResolution = 1024;
702 VerticalResolution = 768;
703 break;
704
705 case 4:
706 HorizontalResolution = 1280;
707 VerticalResolution = 1024;
708 break;
709
710 case 5:
711 HorizontalResolution = 1366;
712 VerticalResolution = 768;
713 break;
714
715 case 6:
716 HorizontalResolution = 1680;
717 VerticalResolution = 1050;
718 break;
719
720 case 7:
721 HorizontalResolution = 1920;
722 VerticalResolution = 1200;
723 break;
724
725 case 8:
726 HorizontalResolution = 1280;
727 VerticalResolution = 800;
728 break;
729 }
730
731 PcdSet32 (PcdSetupVideoHorizontalResolution, HorizontalResolution);
732 PcdSet32 (PcdSetupVideoVerticalResolution, VerticalResolution);
733 DEBUG ((EFI_D_ERROR, "HorizontalResolution = %x; VerticalResolution = %x", HorizontalResolution, VerticalResolution));
734
735 return;
736 }
737
738 /**
739 Connect the predefined platform default console device. Always try to find
740 and enable the vga device if have.
741
742 @param PlatformConsole Predfined platform default console device array.
743
744 @retval EFI_SUCCESS Success connect at least one ConIn and ConOut
745 device, there must have one ConOut device is
746 active vga device.
747
748 @retval EFI_STATUS Return the status of
749 BdsLibConnectAllDefaultConsoles ()
750
751 **/
752 EFI_STATUS
753 PlatformBdsConnectConsole (
754 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
755 )
756 {
757 EFI_STATUS Status;
758 UINTN Index;
759 EFI_DEVICE_PATH_PROTOCOL *VarConout;
760 EFI_DEVICE_PATH_PROTOCOL *VarConin;
761 UINTN DevicePathSize;
762
763 UpdateConsoleResolution();
764
765 Index = 0;
766 Status = EFI_SUCCESS;
767 DevicePathSize = 0;
768 VarConout = BdsLibGetVariableAndSize (
769 L"ConOut",
770 &gEfiGlobalVariableGuid,
771 &DevicePathSize
772 );
773 VarConin = BdsLibGetVariableAndSize (
774 L"ConIn",
775 &gEfiGlobalVariableGuid,
776 &DevicePathSize
777 );
778 if (VarConout == NULL || VarConin == NULL) {
779 //
780 // Have chance to connect the platform default console,
781 // the platform default console is the minimue device group
782 // the platform should support
783 //
784 while (PlatformConsole[Index].DevicePath != NULL) {
785
786 //
787 // Update the console variable with the connect type
788 //
789 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
790 BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);
791 }
792
793 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
794 BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);
795 }
796
797 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
798 BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);
799 }
800
801 Index ++;
802 }
803 }
804
805 //
806 // Make sure we have at least one active VGA, and have the right
807 // active VGA in console variable
808 //
809 Status = PlatformBdsForceActiveVga ();
810 if (EFI_ERROR (Status)) {
811 return Status;
812 }
813
814 DEBUG ((EFI_D_INFO, "DISPLAY INIT DONE\n"));
815
816 //
817 // Connect the all the default console with current console variable
818 //
819 Status = BdsLibConnectAllDefaultConsoles ();
820 if (EFI_ERROR (Status)) {
821 return Status;
822 }
823
824 return EFI_SUCCESS;
825 }
826
827 /**
828 Connect with predeined platform connect sequence,
829 the OEM/IBV can customize with their own connect sequence.
830
831 @param None.
832
833 @retval None.
834
835 **/
836 VOID
837 PlatformBdsConnectSequence (
838 VOID
839 )
840 {
841 UINTN Index;
842
843 Index = 0;
844
845 //
846 // Here we can get the customized platform connect sequence
847 // Notes: we can connect with new variable which record the
848 // last time boots connect device path sequence
849 //
850 while (gPlatformConnectSequence[Index] != NULL) {
851
852 //
853 // Build the platform boot option
854 //
855 BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);
856 Index ++;
857 }
858
859 //
860 // Just use the simple policy to connect all devices
861 // There should be no difference between debug tip and release tip, or it will be extremely hard to debug.
862 //
863 // There is case that IdeController driver will write boot script in driver model Start() function. It will be rejected by boot script save.
864 // It is only found when DEBUG disabled, because we are using BdsLibConnectAll() when DEBUG enabled.
865 //
866 // So we use BdsLibConnectAll() here to make sure IdeController.Start() is invoked before InstallReadyToLock().
867 // We may also consider to connect SataController only later if needed.
868 //
869 BdsLibConnectAll ();
870 }
871
872 /**
873
874 Load the predefined driver option, OEM/IBV can customize this
875 to load their own drivers
876
877 @param BdsDriverLists The header of the driver option link list.
878
879 @retval None.
880
881 **/
882 VOID
883 PlatformBdsGetDriverOption (
884 IN OUT LIST_ENTRY *BdsDriverLists
885 )
886 {
887 UINTN Index;
888
889 Index = 0;
890
891 //
892 // Here we can get the customized platform driver option
893 //
894 while (gPlatformDriverOption[Index] != NULL) {
895
896 //
897 // Build the platform boot option
898 //
899 BdsLibRegisterNewOption (BdsDriverLists, gPlatformDriverOption[Index], NULL, L"DriverOrder");
900 Index ++;
901 }
902
903 }
904
905 /**
906 This function is used for some critical time if the the system
907 have no any boot option, and there is no time out for user to add
908 the new boot option. This can also treat as the platform default
909 boot option.
910
911 @param BdsBootOptionList The header of the boot option link list.
912
913 @retval None.
914
915 **/
916 VOID
917 PlatformBdsPredictBootOption (
918 IN OUT LIST_ENTRY *BdsBootOptionList
919 )
920 {
921 UINTN Index;
922
923 Index = 0;
924
925 //
926 // Here give chance to get platform boot option data
927 //
928 while (gPlatformBootOption[Index] != NULL) {
929
930 //
931 // Build the platform boot option
932 //
933 BdsLibRegisterNewOption (BdsBootOptionList, gPlatformBootOption[Index], NULL, L"BootOrder");
934 Index ++;
935 }
936 }
937
938 /**
939 Perform the platform diagnostic, such like test memory. OEM/IBV also
940 can customize this fuction to support specific platform diagnostic.
941
942 @param MemoryTestLevel The memory test intensive level
943 @param QuietBoot Indicate if need to enable the quiet boot
944 @param BaseMemoryTest A pointer to BdsMemoryTest()
945
946 @retval None.
947
948 **/
949 VOID
950 PlatformBdsDiagnostics (
951 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,
952 IN BOOLEAN QuietBoot,
953 IN BASEM_MEMORY_TEST BaseMemoryTest
954 )
955 {
956 EFI_STATUS Status;
957
958 //
959 // Here we can decide if we need to show
960 // the diagnostics screen
961 // Notes: this quiet boot code should be remove
962 // from the graphic lib
963 //
964 if (QuietBoot) {
965 EnableQuietBoot (PcdGetPtr(PcdLogoFile));
966
967 //
968 // Perform system diagnostic
969 //
970 Status = BaseMemoryTest (MemoryTestLevel);
971 if (EFI_ERROR (Status)) {
972 DisableQuietBoot ();
973 }
974
975 return;
976 }
977
978 //
979 // Perform system diagnostic
980 //
981 Status = BaseMemoryTest (MemoryTestLevel);
982 }
983
984
985 /**
986
987 The function will excute with as the platform policy, current policy
988 is driven by boot mode. IBV/OEM can customize this code for their specific
989 policy action.
990
991 @param DriverOptionList - The header of the driver option link list
992 @param BootOptionList - The header of the boot option link list
993 @param ProcessCapsules - A pointer to ProcessCapsules()
994 @param BaseMemoryTest - A pointer to BaseMemoryTest()
995
996 @retval None.
997
998 **/
999 VOID
1000 EFIAPI
1001 PlatformBdsPolicyBehavior (
1002 IN OUT LIST_ENTRY *DriverOptionList,
1003 IN OUT LIST_ENTRY *BootOptionList,
1004 IN PROCESS_CAPSULES ProcessCapsules,
1005 IN BASEM_MEMORY_TEST BaseMemoryTest
1006 )
1007 {
1008 EFI_STATUS Status;
1009 UINT16 Timeout;
1010 EFI_BOOT_MODE BootMode;
1011 BOOLEAN DeferredImageExist;
1012 UINTN Index;
1013 CHAR16 CapsuleVarName[36];
1014 CHAR16 *TempVarName;
1015 SYSTEM_CONFIGURATION SystemConfiguration;
1016 UINTN VarSize;
1017 BOOLEAN SetVariableFlag;
1018 PLATFORM_PCI_DEVICE_PATH *EmmcBootDevPath;
1019 EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsArea;
1020 EFI_HANDLE FvProtocolHandle;
1021 UINTN HandleCount;
1022 EFI_HANDLE *HandleBuffer;
1023 UINTN Index1;
1024 UINTN SataPciRegBase = 0;
1025 UINT16 SataModeSelect = 0;
1026 VOID *RegistrationExitPmAuth = NULL;
1027 EFI_EVENT Event;
1028 BOOLEAN IsFirstBoot;
1029 UINT16 *BootOrder;
1030 UINTN BootOrderSize;
1031
1032 Timeout = PcdGet16 (PcdPlatformBootTimeOut);
1033 VarSize = sizeof(SYSTEM_CONFIGURATION);
1034 Status = gRT->GetVariable(
1035 NORMAL_SETUP_NAME,
1036 &gEfiNormalSetupGuid,
1037 NULL,
1038 &VarSize,
1039 &SystemConfiguration
1040 );
1041 if (EFI_ERROR (Status)) {
1042 return;
1043 }
1044
1045 //
1046 // Load the driver option as the driver option list
1047 //
1048 PlatformBdsGetDriverOption (DriverOptionList);
1049
1050 //
1051 // Get current Boot Mode
1052 //
1053 BootMode = GetBootModeHob();
1054
1055 //
1056 // Clear all the capsule variables CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...
1057 // as early as possible which will avoid the next time boot after the capsule update
1058 // will still into the capsule loop
1059 //
1060 StrCpy (CapsuleVarName, EFI_CAPSULE_VARIABLE_NAME);
1061 TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
1062 Index = 0;
1063 SetVariableFlag = TRUE;
1064 while (SetVariableFlag) {
1065 if (Index > 0) {
1066 UnicodeValueToString (TempVarName, 0, Index, 0);
1067 }
1068 Status = gRT->SetVariable (
1069 CapsuleVarName,
1070 &gEfiCapsuleVendorGuid,
1071 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS |
1072 EFI_VARIABLE_BOOTSERVICE_ACCESS,
1073 0,
1074 (VOID *)NULL
1075 );
1076 if (EFI_ERROR (Status)) {
1077 //
1078 // There is no capsule variables, quit
1079 //
1080 SetVariableFlag = FALSE;
1081 continue;
1082 }
1083 Index++;
1084 }
1085
1086 //
1087 // No deferred images exist by default
1088 //
1089 DeferredImageExist = FALSE;
1090 if ((BootMode != BOOT_WITH_MINIMAL_CONFIGURATION) && (PcdGet32(PcdFlashFvShellSize) > 0)){
1091 gDS->ProcessFirmwareVolume (
1092 (VOID *)(UINTN)PcdGet32(PcdFlashFvShellBase),
1093 PcdGet32(PcdFlashFvShellSize),
1094 &FvProtocolHandle
1095 );
1096 }
1097
1098 if (SystemConfiguration.FastBoot == 1) {
1099 BootOrder = BdsLibGetVariableAndSize (
1100 L"BootOrder",
1101 &gEfiGlobalVariableGuid,
1102 &BootOrderSize
1103 );
1104 if ((BootOrder != NULL) && (BootMode != BOOT_ON_FLASH_UPDATE)) {
1105 //
1106 // BootOrder exist, it means system has boot before. We can do fast boot.
1107 //
1108 BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;
1109 }
1110 }
1111
1112
1113 //
1114 // Use eMMC to boot OS and turn on AHCI, when SATA HDD is diconnected,
1115 // SATA AHCI CTLR device will show yellow bang, implement this solution to solve it.
1116 //
1117 SataPciRegBase = MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, 0, 0);
1118 SataModeSelect = MmioRead16 (SataPciRegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK;
1119 Status = EFI_SUCCESS;
1120 if (SataModeSelect != V_PCH_SATA_MAP_SMS_IDE) {
1121 Status = gBS->CreateEvent (
1122 EVT_NOTIFY_SIGNAL,
1123 TPL_CALLBACK,
1124 DisableAhciCtlr,
1125 &SataPciRegBase,
1126 &Event
1127 );
1128 if (!EFI_ERROR (Status)) {
1129 Status = gBS->RegisterProtocolNotify (
1130 &gExitPmAuthProtocolGuid,
1131 Event,
1132 &RegistrationExitPmAuth
1133 );
1134 }
1135 }
1136
1137 switch (BootMode) {
1138
1139 case BOOT_WITH_MINIMAL_CONFIGURATION:
1140 PlatformBdsInitHotKeyEvent ();
1141 PlatformBdsConnectSimpleConsole (gPlatformSimpleConsole);
1142
1143
1144 //
1145 // Check to see if it's needed to dispatch more DXE drivers.
1146 //
1147 for (Index = 0; Index < sizeof(ConnectDriverTable)/sizeof(EFI_GUID *); Index++) {
1148 Status = gBS->LocateHandleBuffer (
1149 ByProtocol,
1150 ConnectDriverTable[Index],
1151 NULL,
1152 &HandleCount,
1153 &HandleBuffer
1154 );
1155 if (!EFI_ERROR (Status)) {
1156 for (Index1 = 0; Index1 < HandleCount; Index1++) {
1157 gBS->ConnectController (
1158 HandleBuffer[Index1],
1159 NULL,
1160 NULL,
1161 TRUE
1162 );
1163 }
1164 }
1165
1166 if (HandleBuffer != NULL) {
1167 FreePool (HandleBuffer);
1168 }
1169
1170 gDS->Dispatch ();
1171 }
1172
1173 //
1174 // Locate the Global NVS Protocol.
1175 //
1176 Status = gBS->LocateProtocol (
1177 &gEfiGlobalNvsAreaProtocolGuid,
1178 NULL,
1179 (void **)&GlobalNvsArea
1180 );
1181 if (GlobalNvsArea->Area->emmcVersion == 0){
1182 EmmcBootDevPath = (PLATFORM_PCI_DEVICE_PATH *)gPlatformSimpleBootOption[0];
1183 EmmcBootDevPath->PciDevice.Device = 0x10;
1184 }
1185
1186 //
1187 // Connect boot device here to give time to read keyboard.
1188 //
1189 BdsLibConnectDevicePath (gPlatformSimpleBootOption[0]);
1190
1191 //
1192 // This is a workround for dectecting hotkey from USB keyboard.
1193 //
1194 gBS->Stall(KEYBOARD_TIMER_INTERVAL);
1195
1196 if (mHotKeyTimerEvent != NULL) {
1197 gBS->SetTimer (
1198 mHotKeyTimerEvent,
1199 TimerCancel,
1200 0
1201 );
1202 gBS->CloseEvent (mHotKeyTimerEvent);
1203 mHotKeyTimerEvent = NULL;
1204 }
1205 if (mHotKeyPressed) {
1206 //
1207 // Skip show progress count down
1208 //
1209 Timeout = 0xFFFF;
1210 goto FULL_CONFIGURATION;
1211 }
1212
1213 if (SystemConfiguration.QuietBoot) {
1214 EnableQuietBoot (PcdGetPtr(PcdLogoFile));
1215 } else {
1216 PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest);
1217 }
1218
1219
1220 #ifdef TPM_ENABLED
1221 TcgPhysicalPresenceLibProcessRequest();
1222 #endif
1223
1224 //
1225 // Close boot script and install ready to lock
1226 //
1227 InstallReadyToLock ();
1228
1229 //
1230 // Give one chance to enter the setup if we
1231 // select Gummiboot "Reboot Into Firmware Interface" and Fast Boot is enabled.
1232 //
1233 BootIntoFirmwareInterface();
1234 break;
1235
1236 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
1237
1238 //
1239 // In no-configuration boot mode, we can connect the
1240 // console directly.
1241 //
1242 BdsLibConnectAllDefaultConsoles ();
1243 PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);
1244
1245 //
1246 // Perform some platform specific connect sequence
1247 //
1248 PlatformBdsConnectSequence ();
1249
1250 //
1251 // As console is ready, perform user identification again.
1252 //
1253 if (mCurrentUser == NULL) {
1254 PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
1255 if (DeferredImageExist) {
1256 //
1257 // After user authentication, the deferred drivers was loaded again.
1258 // Here, need to ensure the deferred images are connected.
1259 //
1260 BdsLibConnectAllDefaultConsoles ();
1261 PlatformBdsConnectSequence ();
1262 }
1263 }
1264
1265 //
1266 // Close boot script and install ready to lock
1267 //
1268 InstallReadyToLock ();
1269
1270 //
1271 // Notes: current time out = 0 can not enter the
1272 // front page
1273 //
1274 PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
1275
1276 //
1277 // Check the boot option with the boot option list
1278 //
1279 BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
1280 break;
1281
1282 case BOOT_ON_FLASH_UPDATE:
1283
1284 //
1285 // Boot with the specific configuration
1286 //
1287 PlatformBdsConnectConsole (gPlatformConsole);
1288 PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest);
1289 BdsLibConnectAll ();
1290
1291 //
1292 // Perform user identification
1293 //
1294 if (mCurrentUser == NULL) {
1295 PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
1296 if (DeferredImageExist) {
1297 //
1298 // After user authentication, the deferred drivers was loaded again.
1299 // Here, need to ensure the deferred images are connected.
1300 //
1301 BdsLibConnectAll ();
1302 }
1303 }
1304
1305 //
1306 // Close boot script and install ready to lock
1307 //
1308 InstallReadyToLock ();
1309
1310 ProcessCapsules (BOOT_ON_FLASH_UPDATE);
1311 break;
1312
1313 case BOOT_IN_RECOVERY_MODE:
1314
1315 //
1316 // In recovery mode, just connect platform console
1317 // and show up the front page
1318 //
1319 PlatformBdsConnectConsole (gPlatformConsole);
1320 PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest);
1321 BdsLibConnectAll ();
1322
1323 //
1324 // Perform user identification
1325 //
1326 if (mCurrentUser == NULL) {
1327 PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
1328 if (DeferredImageExist) {
1329 //
1330 // After user authentication, the deferred drivers was loaded again.
1331 // Here, need to ensure the deferred drivers are connected.
1332 //
1333 BdsLibConnectAll ();
1334 }
1335 }
1336
1337 //
1338 // Close boot script and install ready to lock
1339 //
1340 InstallReadyToLock ();
1341
1342 //
1343 // In recovery boot mode, we still enter to the
1344 // frong page now
1345 //
1346 PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
1347 break;
1348
1349 FULL_CONFIGURATION:
1350 case BOOT_WITH_FULL_CONFIGURATION:
1351 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
1352 case BOOT_WITH_DEFAULT_SETTINGS:
1353 default:
1354
1355 //
1356 // Connect platform console
1357 //
1358 Status = PlatformBdsConnectConsole (gPlatformConsole);
1359 if (EFI_ERROR (Status)) {
1360
1361 //
1362 // Here OEM/IBV can customize with defined action
1363 //
1364 PlatformBdsNoConsoleAction ();
1365 }
1366
1367 //
1368 // Chenyunh[TODO]: This is Workgroud to show the fs for uSDcard,
1369 // Need to root cause this issue.
1370 //
1371 DEBUG ((DEBUG_ERROR, "Start to reconnect all driver.\n"));
1372 BdsLibDisconnectAllEfi();
1373 BdsLibConnectAll ();
1374 DEBUG ((DEBUG_ERROR, "End to reconnect all driver.\n"));
1375
1376 //
1377 // Perform some platform specific connect sequence
1378 //
1379 PlatformBdsConnectSequence ();
1380 if (SystemConfiguration.QuietBoot) {
1381 EnableQuietBoot (PcdGetPtr(PcdLogoFile));
1382 } else {
1383 PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest);
1384 }
1385
1386 //
1387 // Do a pre-delay so Hard Disk can spin up and see more logo.
1388 //
1389 gBS->Stall(SystemConfiguration.HddPredelay * 1000000);
1390
1391 //
1392 // Perform user identification
1393 //
1394 if (mCurrentUser == NULL) {
1395 PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);
1396 if (DeferredImageExist) {
1397 //
1398 // After user authentication, the deferred drivers was loaded again.
1399 // Here, need to ensure the deferred drivers are connected.
1400 //
1401 Status = PlatformBdsConnectConsole (gPlatformConsole);
1402 if (EFI_ERROR (Status)) {
1403 PlatformBdsNoConsoleAction ();
1404 }
1405 PlatformBdsConnectSequence ();
1406 }
1407 }
1408 #ifdef TPM_ENABLED
1409 TcgPhysicalPresenceLibProcessRequest();
1410 #endif
1411
1412 //
1413 // Close boot script and install ready to lock
1414 //
1415 InstallReadyToLock ();
1416
1417 //
1418 // Give one chance to enter the setup if we
1419 // have the time out
1420 //
1421 PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
1422
1423 //
1424 // Give one chance to enter the setup if we
1425 // select Gummiboot "Reboot Into Firmware Interface"
1426 //
1427 BootIntoFirmwareInterface();
1428
1429 //
1430 // In default boot mode, always find all boot
1431 // option and do enumerate all the default boot option
1432 //
1433 if (Timeout == 0) {
1434 BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
1435 if (IsListEmpty(BootOptionList)) {
1436 PlatformBdsPredictBootOption (BootOptionList);
1437 }
1438
1439 return;
1440 }
1441
1442 //
1443 // Here we have enough time to do the enumeration of boot device
1444 //
1445 BdsLibEnumerateAllBootOption (BootOptionList);
1446 break;
1447 }
1448
1449
1450 IsFirstBoot = PcdGetBool(PcdBootState);
1451 if (IsFirstBoot) {
1452 PcdSetBool(PcdBootState, FALSE);
1453 }
1454 return;
1455
1456 }
1457
1458 /**
1459 Hook point after a boot attempt succeeds. We don't expect a boot option to
1460 return, so the UEFI 2.0 specification defines that you will default to an
1461 interactive mode and stop processing the BootOrder list in this case. This
1462 is alos a platform implementation and can be customized by IBV/OEM.
1463
1464 @param Option Pointer to Boot Option that succeeded to boot.
1465
1466 @retval None.
1467
1468 **/
1469 VOID
1470 EFIAPI
1471 PlatformBdsBootSuccess (
1472 IN BDS_COMMON_OPTION *Option
1473 )
1474 {
1475 CHAR16 *TmpStr;
1476
1477 //
1478 // If Boot returned with EFI_SUCCESS and there is not in the boot device
1479 // select loop then we need to pop up a UI and wait for user input.
1480 //
1481 TmpStr = Option->StatusString;
1482 if (TmpStr != NULL) {
1483 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
1484 FreePool(TmpStr);
1485 }
1486 }
1487
1488 /**
1489 Hook point after a boot attempt fails.
1490
1491 @param Option - Pointer to Boot Option that failed to boot.
1492 @param Status - Status returned from failed boot.
1493 @param ExitData - Exit data returned from failed boot.
1494 @param ExitDataSize - Exit data size returned from failed boot.
1495
1496 @retval None.
1497
1498 **/
1499 VOID
1500 EFIAPI
1501 PlatformBdsBootFail (
1502 IN BDS_COMMON_OPTION *Option,
1503 IN EFI_STATUS Status,
1504 IN CHAR16 *ExitData,
1505 IN UINTN ExitDataSize
1506 )
1507 {
1508 CHAR16 *TmpStr;
1509 EFI_HANDLE FvProtocolHandle;
1510
1511 //
1512 // If Boot returned with failed status then we need to pop up a UI and wait
1513 // for user input.
1514 //
1515 TmpStr = Option->StatusString;
1516 if (TmpStr != NULL) {
1517 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
1518 FreePool(TmpStr);
1519 }
1520 if (PcdGet32(PcdFlashFvShellSize) > 0){
1521 gDS->ProcessFirmwareVolume (
1522 (VOID *)(UINTN)PcdGet32(PcdFlashFvShellBase),
1523 PcdGet32(PcdFlashFvShellSize),
1524 &FvProtocolHandle
1525 );
1526 }
1527 PlatformBdsConnectSequence ();
1528 }
1529
1530 /**
1531 This function is remained for IBV/OEM to do some platform action,
1532 if there no console device can be connected.
1533
1534 @param None.
1535
1536 @retval EFI_SUCCESS Direct return success now.
1537
1538 **/
1539 EFI_STATUS
1540 PlatformBdsNoConsoleAction (
1541 VOID
1542 )
1543 {
1544 return EFI_SUCCESS;
1545 }
1546
1547 /**
1548 This function locks the block
1549
1550 @param Base The base address flash region to be locked.
1551
1552 **/
1553 VOID
1554 BdsLockFv (
1555 IN EFI_PHYSICAL_ADDRESS Base
1556 )
1557 {
1558 EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
1559 EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
1560 EFI_PHYSICAL_ADDRESS BaseAddress;
1561 UINT8 Data;
1562 UINT32 BlockLength;
1563 UINTN Index;
1564
1565 BaseAddress = Base - 0x400000 + 2;
1566 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (Base));
1567 BlockMap = &(FvHeader->BlockMap[0]);
1568
1569 while ((BlockMap->NumBlocks != 0) && (BlockMap->Length != 0)) {
1570 BlockLength = BlockMap->Length;
1571 for (Index = 0; Index < BlockMap->NumBlocks; Index++) {
1572 Data = MmioOr8 ((UINTN) BaseAddress, 0x03);
1573 BaseAddress += BlockLength;
1574 }
1575 BlockMap++;
1576 }
1577 }
1578
1579 VOID
1580 EFIAPI
1581 PlatformBdsLockNonUpdatableFlash (
1582 VOID
1583 )
1584 {
1585 EFI_PHYSICAL_ADDRESS Base;
1586
1587 Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvMainBase);
1588 if (Base > 0) {
1589 BdsLockFv (Base);
1590 }
1591
1592 Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvRecoveryBase);
1593 if (Base > 0) {
1594 BdsLockFv (Base);
1595 }
1596 }
1597
1598 /**
1599 Lock the ConsoleIn device in system table. All key
1600 presses will be ignored until the Password is typed in. The only way to
1601 disable the password is to type it in to a ConIn device.
1602
1603 @param Password Password used to lock ConIn device.
1604
1605 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
1606 @retval EFI_UNSUPPORTED Password not found
1607
1608 **/
1609 EFI_STATUS
1610 EFIAPI
1611 LockKeyboards (
1612 IN CHAR16 *Password
1613 )
1614 {
1615 return EFI_UNSUPPORTED;
1616 }
1617
1618 /**
1619 Connect the predefined platform default authentication devices.
1620
1621 This function connects the predefined device path for authentication device,
1622 and if the predefined device path has child device path, the child handle will
1623 be connected too. But the child handle of the child will not be connected.
1624
1625 **/
1626 VOID
1627 EFIAPI
1628 PlatformBdsConnectAuthDevice (
1629 VOID
1630 )
1631 {
1632 EFI_STATUS Status;
1633 UINTN Index;
1634 UINTN HandleIndex;
1635 UINTN HandleCount;
1636 EFI_HANDLE *HandleBuffer;
1637 EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath;
1638 EFI_USER_MANAGER_PROTOCOL *Manager;
1639
1640 Status = gBS->LocateProtocol (
1641 &gEfiUserManagerProtocolGuid,
1642 NULL,
1643 (VOID **) &Manager
1644 );
1645 if (EFI_ERROR (Status)) {
1646 //
1647 // As user manager protocol is not installed, the authentication devices
1648 // should not be connected.
1649 //
1650 return ;
1651 }
1652
1653 Index = 0;
1654 while (gUserAuthenticationDevice[Index] != NULL) {
1655 //
1656 // Connect the platform customized device paths
1657 //
1658 BdsLibConnectDevicePath (gUserAuthenticationDevice[Index]);
1659 Index++;
1660 }
1661
1662 //
1663 // Find and connect the child device paths of the platform customized device paths
1664 //
1665 HandleBuffer = NULL;
1666 for (Index = 0; gUserAuthenticationDevice[Index] != NULL; Index++) {
1667 HandleCount = 0;
1668 Status = gBS->LocateHandleBuffer (
1669 AllHandles,
1670 NULL,
1671 NULL,
1672 &HandleCount,
1673 &HandleBuffer
1674 );
1675 ASSERT (!EFI_ERROR (Status));
1676
1677 //
1678 // Find and connect the child device paths of gUserIdentificationDevice[Index]
1679 //
1680 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
1681 ChildDevicePath = NULL;
1682 Status = gBS->HandleProtocol (
1683 HandleBuffer[HandleIndex],
1684 &gEfiDevicePathProtocolGuid,
1685 (VOID **) &ChildDevicePath
1686 );
1687 if (EFI_ERROR (Status) || ChildDevicePath == NULL) {
1688 continue;
1689 }
1690
1691 if (CompareMem (
1692 ChildDevicePath,
1693 gUserAuthenticationDevice[Index],
1694 (GetDevicePathSize (gUserAuthenticationDevice[Index]) - sizeof (EFI_DEVICE_PATH_PROTOCOL))
1695 ) != 0) {
1696 continue;
1697 }
1698 gBS->ConnectController (
1699 HandleBuffer[HandleIndex],
1700 NULL,
1701 NULL,
1702 TRUE
1703 );
1704 }
1705 }
1706
1707 if (HandleBuffer != NULL) {
1708 FreePool (HandleBuffer);
1709 }
1710 }
1711
1712 /**
1713 This function is to identify a user, and return whether deferred images exist.
1714
1715 @param[out] User Point to user profile handle.
1716 @param[out] DeferredImageExist On return, points to TRUE if the deferred image
1717 exist or FALSE if it did not exist.
1718
1719 **/
1720 VOID
1721 EFIAPI
1722 PlatformBdsUserIdentify (
1723 OUT EFI_USER_PROFILE_HANDLE *User,
1724 OUT BOOLEAN *DeferredImageExist
1725 )
1726 {
1727 EFI_STATUS Status;
1728 EFI_DEFERRED_IMAGE_LOAD_PROTOCOL *DeferredImage;
1729 UINTN HandleCount;
1730 EFI_HANDLE *HandleBuf;
1731 UINTN Index;
1732 UINTN DriverIndex;
1733 EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
1734 VOID *DriverImage;
1735 UINTN ImageSize;
1736 BOOLEAN BootOption;
1737
1738 //
1739 // Perform user identification
1740 //
1741 do {
1742 Status = BdsLibUserIdentify (User);
1743 } while (EFI_ERROR (Status));
1744
1745 //
1746 // After user authentication now, try to find whether deferred image exists
1747 //
1748 HandleCount = 0;
1749 HandleBuf = NULL;
1750 *DeferredImageExist = FALSE;
1751 Status = gBS->LocateHandleBuffer (
1752 ByProtocol,
1753 &gEfiDeferredImageLoadProtocolGuid,
1754 NULL,
1755 &HandleCount,
1756 &HandleBuf
1757 );
1758 if (EFI_ERROR (Status)) {
1759 return ;
1760 }
1761
1762 for (Index = 0; Index < HandleCount; Index++) {
1763 Status = gBS->HandleProtocol (
1764 HandleBuf[Index],
1765 &gEfiDeferredImageLoadProtocolGuid,
1766 (VOID **) &DeferredImage
1767 );
1768 if (!EFI_ERROR (Status)) {
1769 //
1770 // Find whether deferred image exists in this instance.
1771 //
1772 DriverIndex = 0;
1773 Status = DeferredImage->GetImageInfo(
1774 DeferredImage,
1775 DriverIndex,
1776 &ImageDevicePath,
1777 (VOID **) &DriverImage,
1778 &ImageSize,
1779 &BootOption
1780 );
1781 if (!EFI_ERROR (Status)) {
1782 //
1783 // The deferred image is found.
1784 //
1785 FreePool (HandleBuf);
1786 *DeferredImageExist = TRUE;
1787 return ;
1788 }
1789 }
1790 }
1791
1792 FreePool (HandleBuf);
1793 }
1794
1795 UINTN gHotKey = 0;
1796
1797
1798 EFI_STATUS
1799 ShowProgressHotKey (
1800 IN UINT16 TimeoutDefault
1801 )
1802 {
1803 CHAR16 *TmpStr;
1804 UINT16 TimeoutRemain;
1805 EFI_STATUS Status;
1806 EFI_INPUT_KEY Key;
1807 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
1808 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
1809 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
1810 UINT32 GpioValue;
1811
1812 if (TimeoutDefault == 0) {
1813 return EFI_TIMEOUT;
1814 }
1815
1816 if (DebugAssertEnabled())
1817 {
1818 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"));
1819 }
1820 else
1821 {
1822 #ifdef __GNUC__
1823 SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)[GCC]", 76);
1824 #else
1825 SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)", 71);
1826 #endif
1827 }
1828 SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
1829 SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
1830 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
1831
1832 //
1833 // Clear the progress status bar first
1834 //
1835 TmpStr = L"Start boot option, Press <F2> or <DEL> to enter setup page.";
1836 PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);
1837
1838 TimeoutRemain = TimeoutDefault;
1839 while (TimeoutRemain != 0) {
1840 if (DebugAssertEnabled())
1841 {
1842 DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));
1843 }
1844 else
1845 {
1846 SerialPortWrite ((UINT8 *)".", 1);
1847 }
1848 Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);
1849 if (Status != EFI_TIMEOUT) {
1850 break;
1851 }
1852 TimeoutRemain--;
1853
1854 //
1855 // Show progress
1856 //
1857 if (TmpStr != NULL) {
1858 PlatformBdsShowProgress (
1859 Foreground,
1860 Background,
1861 TmpStr,
1862 Color,
1863 ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),
1864 0
1865 );
1866 }
1867 }
1868
1869 //
1870 // Timeout expired
1871 //
1872 if (TimeoutRemain == 0) {
1873 if (DebugAssertEnabled())
1874 {
1875 }
1876 else
1877 {
1878 SerialPortWrite ((UINT8 *)"\r\n", 2);
1879 }
1880 return EFI_TIMEOUT;
1881 }
1882
1883 //
1884 // User pressed some key
1885 //
1886 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
1887 if (EFI_ERROR (Status)) {
1888 return Status;
1889 }
1890
1891 //
1892 // Check Volume Up Key to enter Setup
1893 //
1894 GpioValue = MmioRead32 (IO_BASE_ADDRESS + 0x0668); // The value of GPIOC_5
1895 if (((GpioValue & BIT0) == 0) && (Key.ScanCode == SCAN_UP)) {
1896 gHotKey = 0;
1897 return EFI_SUCCESS;
1898 }
1899
1900 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
1901 //
1902 // User pressed enter, equivalent to select "continue"
1903 //
1904 return EFI_TIMEOUT;
1905 }
1906
1907 //
1908 //F2 -- Front Page
1909 //F5 -- Device Manager
1910 //F7 -- Boot Manager
1911 // do not use F8. generally people assume it is windows safe mode key.
1912 //F9 -- Boot order
1913 //
1914 DEBUG ((EFI_D_INFO, "[Key Pressed]: ScanCode 0x%x\n", Key.ScanCode));
1915 switch(Key.ScanCode) {
1916 case SCAN_F2:
1917 gHotKey = 0;
1918 break;
1919
1920 case SCAN_DELETE:
1921 gHotKey = 0;
1922 break;
1923
1924 case SCAN_F5:
1925 gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
1926 break;
1927
1928 case SCAN_F7:
1929 gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
1930 break;
1931
1932 case SCAN_F9:
1933 gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
1934 break;
1935
1936 default:
1937 //set gHotKey to continue so that flow will not go into CallFrontPage
1938 gHotKey = FRONT_PAGE_KEY_CONTINUE;
1939 return EFI_TIMEOUT;
1940 break;
1941 }
1942
1943 return EFI_SUCCESS;
1944 }
1945
1946
1947
1948 /**
1949 This function is the main entry of the platform setup entry.
1950 The function will present the main menu of the system setup,
1951 this is the platform reference part and can be customize.
1952
1953
1954 @param TimeoutDefault The fault time out value before the system
1955 continue to boot.
1956 @param ConnectAllHappened The indicater to check if the connect all have
1957 already happened.
1958
1959 **/
1960 VOID
1961 PlatformBdsEnterFrontPageWithHotKey (
1962 IN UINT16 TimeoutDefault,
1963 IN BOOLEAN ConnectAllHappened
1964 )
1965 {
1966 EFI_STATUS Status;
1967
1968 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1969 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
1970 UINTN BootTextColumn;
1971 UINTN BootTextRow;
1972
1973 GraphicsOutput = NULL;
1974 SimpleTextOut = NULL;
1975
1976 PERF_START (NULL, "BdsTimeOut", "BDS", 0);
1977
1978 //
1979 // Indicate if we need connect all in the platform setup
1980 //
1981 if (ConnectAllHappened) {
1982 gConnectAllHappened = TRUE;
1983 }
1984
1985 if (!mModeInitialized) {
1986 //
1987 // After the console is ready, get current video resolution
1988 // and text mode before launching setup at first time.
1989 //
1990 Status = gBS->HandleProtocol (
1991 gST->ConsoleOutHandle,
1992 &gEfiGraphicsOutputProtocolGuid,
1993 (VOID**)&GraphicsOutput
1994 );
1995 if (EFI_ERROR (Status)) {
1996 GraphicsOutput = NULL;
1997 }
1998
1999 Status = gBS->HandleProtocol (
2000 gST->ConsoleOutHandle,
2001 &gEfiSimpleTextOutProtocolGuid,
2002 (VOID**)&SimpleTextOut
2003 );
2004 if (EFI_ERROR (Status)) {
2005 SimpleTextOut = NULL;
2006 }
2007
2008 if (GraphicsOutput != NULL) {
2009 //
2010 // Get current video resolution and text mode.
2011 //
2012 mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
2013 mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
2014 }
2015
2016 if (SimpleTextOut != NULL) {
2017 Status = SimpleTextOut->QueryMode (
2018 SimpleTextOut,
2019 SimpleTextOut->Mode->Mode,
2020 &BootTextColumn,
2021 &BootTextRow
2022 );
2023 mBootTextModeColumn = (UINT32)BootTextColumn;
2024 mBootTextModeRow = (UINT32)BootTextRow;
2025 }
2026
2027 //
2028 // Get user defined text mode for setup.
2029 //
2030 mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
2031 mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
2032 mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);
2033 mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);
2034
2035 mModeInitialized = TRUE;
2036 }
2037
2038 if (TimeoutDefault != 0xffff) {
2039 Status = ShowProgressHotKey (TimeoutDefault);
2040
2041 //
2042 // Ensure screen is clear when switch Console from Graphics mode to Text mode
2043 //
2044 gST->ConOut->EnableCursor (gST->ConOut, TRUE);
2045 gST->ConOut->ClearScreen (gST->ConOut);
2046
2047 if (EFI_ERROR (Status)) {
2048 //
2049 // Timeout or user press enter to continue
2050 //
2051 goto Exit;
2052 }
2053 }
2054
2055 do {
2056
2057 BdsSetConsoleMode (TRUE);
2058
2059 InitializeFrontPage (FALSE);
2060
2061 //
2062 // Update Front Page strings
2063 //
2064 UpdateFrontPageStrings ();
2065
2066 Status = EFI_SUCCESS;
2067 gCallbackKey = 0;
2068 if (gHotKey == 0) {
2069 Status = CallFrontPage ();
2070 } else {
2071 gCallbackKey = gHotKey;
2072 gHotKey = 0;
2073 }
2074
2075 //
2076 // If gCallbackKey is greater than 1 and less or equal to 5,
2077 // it will launch configuration utilities.
2078 // 2 = set language
2079 // 3 = boot manager
2080 // 4 = device manager
2081 // 5 = boot maintenance manager
2082 //
2083 if (gCallbackKey != 0) {
2084 REPORT_STATUS_CODE (
2085 EFI_PROGRESS_CODE,
2086 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
2087 );
2088 }
2089
2090 //
2091 // Based on the key that was set, we can determine what to do
2092 //
2093 switch (gCallbackKey) {
2094 //
2095 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
2096 // describe to their customers in documentation how to find their setup information (namely
2097 // under the device manager and specific buckets)
2098 //
2099 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
2100 //
2101 case FRONT_PAGE_KEY_CONTINUE:
2102
2103 //
2104 // User hit continue
2105 //
2106 break;
2107
2108 case FRONT_PAGE_KEY_LANGUAGE:
2109
2110 //
2111 // User made a language setting change - display front page again
2112 //
2113 break;
2114
2115 case FRONT_PAGE_KEY_BOOT_MANAGER:
2116
2117 //
2118 // User chose to run the Boot Manager
2119 //
2120 CallBootManager ();
2121 break;
2122
2123 case FRONT_PAGE_KEY_DEVICE_MANAGER:
2124
2125 //
2126 // Display the Device Manager
2127 //
2128 do {
2129 CallDeviceManager ();
2130 } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);
2131 break;
2132
2133 case FRONT_PAGE_KEY_BOOT_MAINTAIN:
2134
2135 //
2136 // Display the Boot Maintenance Manager
2137 //
2138 BdsStartBootMaint ();
2139 break;
2140 }
2141
2142 } while (((UINTN)gCallbackKey) != FRONT_PAGE_KEY_CONTINUE);
2143
2144 //
2145 //Will leave browser, check any reset required change is applied? if yes, reset system
2146 //
2147 SetupResetReminder ();
2148
2149 Exit:
2150 //
2151 // Automatically load current entry
2152 // Note: The following lines of code only execute when Auto boot
2153 // takes affect
2154 //
2155 PERF_END (NULL, "BdsTimeOut", "BDS", 0);
2156 }
2157
2158
2159 VOID
2160 BootIntoFirmwareInterface(
2161 VOID
2162 )
2163 {
2164 EFI_STATUS Status;
2165 UINTN DataSize;
2166 UINT16 Timeout;
2167 UINT64 OsIndication;
2168
2169
2170 OsIndication = 0;
2171 DataSize = sizeof(UINT64);
2172 Status = gRT->GetVariable (
2173 L"OsIndications",
2174 &gEfiGlobalVariableGuid,
2175 NULL,
2176 &DataSize,
2177 &OsIndication
2178 );
2179
2180 DEBUG ((EFI_D_INFO, "OSIndication Variable Value %d\n", OsIndication));
2181 //
2182 //Goto FrontPage directly when bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted.
2183 //
2184 if (!EFI_ERROR(Status) && (OsIndication != 0)) {
2185 Timeout = 0xffff;
2186 PlatformBdsEnterFrontPage (Timeout, FALSE);
2187 }
2188 }
2189
2190
2191 EFI_STATUS
2192 PlatformBdsConnectSimpleConsole (
2193 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
2194 )
2195 {
2196 EFI_STATUS Status;
2197 UINTN Index;
2198 EFI_DEVICE_PATH_PROTOCOL *VarConout;
2199 EFI_DEVICE_PATH_PROTOCOL *VarConin;
2200 UINTN DevicePathSize;
2201
2202
2203 Index = 0;
2204 Status = EFI_SUCCESS;
2205 DevicePathSize = 0;
2206 VarConout = BdsLibGetVariableAndSize (
2207 L"ConOut",
2208 &gEfiGlobalVariableGuid,
2209 &DevicePathSize
2210 );
2211 VarConin = BdsLibGetVariableAndSize (
2212 L"ConIn",
2213 &gEfiGlobalVariableGuid,
2214 &DevicePathSize
2215 );
2216 if (VarConout == NULL || VarConin == NULL) {
2217 //
2218 // Have chance to connect the platform default console,
2219 // the platform default console is the minimue device group
2220 // the platform should support
2221 //
2222 while (PlatformConsole[Index].DevicePath != NULL) {
2223
2224 //
2225 // Update the console variable with the connect type
2226 //
2227 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
2228 BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);
2229 }
2230
2231 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
2232 BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);
2233 }
2234
2235 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
2236 BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);
2237 }
2238
2239 Index ++;
2240 }
2241 }
2242
2243 //
2244 // Connect ConIn first to give keyboard time to parse hot key event.
2245 //
2246 Status = BdsLibConnectConsoleVariable (L"ConIn");
2247 if (EFI_ERROR (Status)) {
2248 return Status;
2249 }
2250
2251 //
2252 // Make sure we have at least one active VGA, and have the right
2253 // active VGA in console variable
2254 //
2255 Status = PlatformBdsForceActiveVga ();
2256
2257 //
2258 // It seems impossible not to have any ConOut device on platform,
2259 // so we check the status here.
2260 //
2261 Status = BdsLibConnectConsoleVariable (L"ConOut");
2262 if (EFI_ERROR (Status)) {
2263 return Status;
2264 }
2265
2266 return EFI_SUCCESS;
2267 }
2268
2269
2270 /**
2271 Timer handler to convert the key from USB.
2272
2273 @param Event Indicates the event that invoke this function.
2274 @param Context Indicates the calling context.
2275 **/
2276 VOID
2277 EFIAPI
2278 HotKeyTimerHandler (
2279 IN EFI_EVENT Event,
2280 IN VOID *Context
2281 )
2282 {
2283 EFI_STATUS Status;
2284 EFI_INPUT_KEY Key;
2285
2286 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
2287 if (EFI_ERROR (Status)) {
2288 return;
2289 }
2290
2291 switch(Key.ScanCode) {
2292 case SCAN_F2:
2293 gHotKey = 0;
2294 mHotKeyPressed = TRUE;
2295 break;
2296
2297 case SCAN_F5:
2298 gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
2299 mHotKeyPressed = TRUE;
2300 break;
2301
2302 case SCAN_F7:
2303 gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
2304 mHotKeyPressed = TRUE;
2305 break;
2306
2307 case SCAN_F9:
2308 gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
2309 mHotKeyPressed = TRUE;
2310 break;
2311 }
2312
2313 if (mHotKeyPressed) {
2314 gBS->SetTimer (
2315 mHotKeyTimerEvent,
2316 TimerCancel,
2317 0
2318 );
2319 gBS->CloseEvent (mHotKeyTimerEvent);
2320 mHotKeyTimerEvent = NULL;
2321 }
2322
2323 return;
2324 }
2325
2326
2327 /**
2328 Callback function for SimpleTextInEx protocol install events
2329
2330 @param Event the event that is signaled.
2331 @param Context not used here.
2332
2333 **/
2334 VOID
2335 EFIAPI
2336 HitHotkeyEvent (
2337 IN EFI_EVENT Event,
2338 IN VOID *Context
2339 )
2340 {
2341 EFI_STATUS Status;
2342
2343 Status = gBS->CloseEvent(mHitHotkeyEvent);
2344 if (EFI_ERROR (Status)) {
2345 return;
2346 }
2347 Status = gBS->CreateEvent (
2348 EVT_TIMER | EVT_NOTIFY_SIGNAL,
2349 TPL_NOTIFY,
2350 HotKeyTimerHandler,
2351 NULL,
2352 &mHotKeyTimerEvent
2353 );
2354 if (EFI_ERROR (Status)) {
2355 return;
2356 }
2357 Status = gBS->SetTimer (
2358 mHotKeyTimerEvent,
2359 TimerPeriodic,
2360 KEYBOARD_TIMER_INTERVAL
2361 );
2362 if (EFI_ERROR (Status)) {
2363 return;
2364 }
2365
2366 return;
2367 }
2368
2369
2370 VOID
2371 EFIAPI
2372 PlatformBdsInitHotKeyEvent (
2373 VOID
2374 )
2375 {
2376 EFI_STATUS Status;
2377
2378 //
2379 // Register Protocol notify for Hotkey service
2380 //
2381 Status = gBS->CreateEvent (
2382 EVT_NOTIFY_SIGNAL,
2383 TPL_CALLBACK,
2384 HitHotkeyEvent,
2385 NULL,
2386 &mHitHotkeyEvent
2387 );
2388 ASSERT_EFI_ERROR (Status);
2389
2390 //
2391 // Register for protocol notifications on this event
2392 //
2393 Status = gBS->RegisterProtocolNotify (
2394 &gEfiSimpleTextInputExProtocolGuid,
2395 mHitHotkeyEvent,
2396 &mHitHotkeyRegistration
2397 );
2398 ASSERT_EFI_ERROR (Status);
2399 }