]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
Fixed system hang issue with accessing to Boot Maintenance Manager
[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 // Install BM HiiPackages.
2056 // Keep BootMaint HiiPackage, so that it can be covered by global setting.
2057 //
2058 InitBMPackage ();
2059 do {
2060
2061 BdsSetConsoleMode (TRUE);
2062
2063 InitializeFrontPage (FALSE);
2064
2065 //
2066 // Update Front Page strings
2067 //
2068 UpdateFrontPageStrings ();
2069
2070 Status = EFI_SUCCESS;
2071 gCallbackKey = 0;
2072 if (gHotKey == 0) {
2073 Status = CallFrontPage ();
2074 } else {
2075 gCallbackKey = gHotKey;
2076 gHotKey = 0;
2077 }
2078
2079 //
2080 // If gCallbackKey is greater than 1 and less or equal to 5,
2081 // it will launch configuration utilities.
2082 // 2 = set language
2083 // 3 = boot manager
2084 // 4 = device manager
2085 // 5 = boot maintenance manager
2086 //
2087 if (gCallbackKey != 0) {
2088 REPORT_STATUS_CODE (
2089 EFI_PROGRESS_CODE,
2090 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
2091 );
2092 }
2093
2094 //
2095 // Based on the key that was set, we can determine what to do
2096 //
2097 switch (gCallbackKey) {
2098 //
2099 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
2100 // describe to their customers in documentation how to find their setup information (namely
2101 // under the device manager and specific buckets)
2102 //
2103 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
2104 //
2105 case FRONT_PAGE_KEY_CONTINUE:
2106
2107 //
2108 // User hit continue
2109 //
2110 break;
2111
2112 case FRONT_PAGE_KEY_LANGUAGE:
2113
2114 //
2115 // User made a language setting change - display front page again
2116 //
2117 break;
2118
2119 case FRONT_PAGE_KEY_BOOT_MANAGER:
2120 //
2121 // Remove the installed BootMaint HiiPackages when exit.
2122 //
2123 FreeBMPackage ();
2124
2125 //
2126 // User chose to run the Boot Manager
2127 //
2128 CallBootManager ();
2129
2130 //
2131 // Reinstall BootMaint HiiPackages after exiting from Boot Manager.
2132 //
2133 InitBMPackage ();
2134 break;
2135
2136 case FRONT_PAGE_KEY_DEVICE_MANAGER:
2137
2138 //
2139 // Display the Device Manager
2140 //
2141 do {
2142 CallDeviceManager ();
2143 } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);
2144 break;
2145
2146 case FRONT_PAGE_KEY_BOOT_MAINTAIN:
2147
2148 //
2149 // Display the Boot Maintenance Manager
2150 //
2151 BdsStartBootMaint ();
2152 break;
2153 }
2154
2155 } while (((UINTN)gCallbackKey) != FRONT_PAGE_KEY_CONTINUE);
2156
2157 //
2158 //Will leave browser, check any reset required change is applied? if yes, reset system
2159 //
2160 SetupResetReminder ();
2161 //
2162 // Remove the installed BootMaint HiiPackages when exit.
2163 //
2164 FreeBMPackage ();
2165
2166 Exit:
2167 //
2168 // Automatically load current entry
2169 // Note: The following lines of code only execute when Auto boot
2170 // takes affect
2171 //
2172 PERF_END (NULL, "BdsTimeOut", "BDS", 0);
2173 }
2174
2175
2176 VOID
2177 BootIntoFirmwareInterface(
2178 VOID
2179 )
2180 {
2181 EFI_STATUS Status;
2182 UINTN DataSize;
2183 UINT16 Timeout;
2184 UINT64 OsIndication;
2185
2186
2187 OsIndication = 0;
2188 DataSize = sizeof(UINT64);
2189 Status = gRT->GetVariable (
2190 L"OsIndications",
2191 &gEfiGlobalVariableGuid,
2192 NULL,
2193 &DataSize,
2194 &OsIndication
2195 );
2196
2197 DEBUG ((EFI_D_INFO, "OSIndication Variable Value %d\n", OsIndication));
2198 //
2199 //Goto FrontPage directly when bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted.
2200 //
2201 if (!EFI_ERROR(Status) && (OsIndication != 0)) {
2202 Timeout = 0xffff;
2203 PlatformBdsEnterFrontPage (Timeout, FALSE);
2204 }
2205 }
2206
2207
2208 EFI_STATUS
2209 PlatformBdsConnectSimpleConsole (
2210 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
2211 )
2212 {
2213 EFI_STATUS Status;
2214 UINTN Index;
2215 EFI_DEVICE_PATH_PROTOCOL *VarConout;
2216 EFI_DEVICE_PATH_PROTOCOL *VarConin;
2217 UINTN DevicePathSize;
2218
2219
2220 Index = 0;
2221 Status = EFI_SUCCESS;
2222 DevicePathSize = 0;
2223 VarConout = BdsLibGetVariableAndSize (
2224 L"ConOut",
2225 &gEfiGlobalVariableGuid,
2226 &DevicePathSize
2227 );
2228 VarConin = BdsLibGetVariableAndSize (
2229 L"ConIn",
2230 &gEfiGlobalVariableGuid,
2231 &DevicePathSize
2232 );
2233 if (VarConout == NULL || VarConin == NULL) {
2234 //
2235 // Have chance to connect the platform default console,
2236 // the platform default console is the minimue device group
2237 // the platform should support
2238 //
2239 while (PlatformConsole[Index].DevicePath != NULL) {
2240
2241 //
2242 // Update the console variable with the connect type
2243 //
2244 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
2245 BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);
2246 }
2247
2248 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
2249 BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);
2250 }
2251
2252 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
2253 BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);
2254 }
2255
2256 Index ++;
2257 }
2258 }
2259
2260 //
2261 // Connect ConIn first to give keyboard time to parse hot key event.
2262 //
2263 Status = BdsLibConnectConsoleVariable (L"ConIn");
2264 if (EFI_ERROR (Status)) {
2265 return Status;
2266 }
2267
2268 //
2269 // Make sure we have at least one active VGA, and have the right
2270 // active VGA in console variable
2271 //
2272 Status = PlatformBdsForceActiveVga ();
2273
2274 //
2275 // It seems impossible not to have any ConOut device on platform,
2276 // so we check the status here.
2277 //
2278 Status = BdsLibConnectConsoleVariable (L"ConOut");
2279 if (EFI_ERROR (Status)) {
2280 return Status;
2281 }
2282
2283 return EFI_SUCCESS;
2284 }
2285
2286
2287 /**
2288 Timer handler to convert the key from USB.
2289
2290 @param Event Indicates the event that invoke this function.
2291 @param Context Indicates the calling context.
2292 **/
2293 VOID
2294 EFIAPI
2295 HotKeyTimerHandler (
2296 IN EFI_EVENT Event,
2297 IN VOID *Context
2298 )
2299 {
2300 EFI_STATUS Status;
2301 EFI_INPUT_KEY Key;
2302
2303 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
2304 if (EFI_ERROR (Status)) {
2305 return;
2306 }
2307
2308 switch(Key.ScanCode) {
2309 case SCAN_F2:
2310 gHotKey = 0;
2311 mHotKeyPressed = TRUE;
2312 break;
2313
2314 case SCAN_F5:
2315 gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
2316 mHotKeyPressed = TRUE;
2317 break;
2318
2319 case SCAN_F7:
2320 gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
2321 mHotKeyPressed = TRUE;
2322 break;
2323
2324 case SCAN_F9:
2325 gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
2326 mHotKeyPressed = TRUE;
2327 break;
2328 }
2329
2330 if (mHotKeyPressed) {
2331 gBS->SetTimer (
2332 mHotKeyTimerEvent,
2333 TimerCancel,
2334 0
2335 );
2336 gBS->CloseEvent (mHotKeyTimerEvent);
2337 mHotKeyTimerEvent = NULL;
2338 }
2339
2340 return;
2341 }
2342
2343
2344 /**
2345 Callback function for SimpleTextInEx protocol install events
2346
2347 @param Event the event that is signaled.
2348 @param Context not used here.
2349
2350 **/
2351 VOID
2352 EFIAPI
2353 HitHotkeyEvent (
2354 IN EFI_EVENT Event,
2355 IN VOID *Context
2356 )
2357 {
2358 EFI_STATUS Status;
2359
2360 Status = gBS->CloseEvent(mHitHotkeyEvent);
2361 if (EFI_ERROR (Status)) {
2362 return;
2363 }
2364 Status = gBS->CreateEvent (
2365 EVT_TIMER | EVT_NOTIFY_SIGNAL,
2366 TPL_NOTIFY,
2367 HotKeyTimerHandler,
2368 NULL,
2369 &mHotKeyTimerEvent
2370 );
2371 if (EFI_ERROR (Status)) {
2372 return;
2373 }
2374 Status = gBS->SetTimer (
2375 mHotKeyTimerEvent,
2376 TimerPeriodic,
2377 KEYBOARD_TIMER_INTERVAL
2378 );
2379 if (EFI_ERROR (Status)) {
2380 return;
2381 }
2382
2383 return;
2384 }
2385
2386
2387 VOID
2388 EFIAPI
2389 PlatformBdsInitHotKeyEvent (
2390 VOID
2391 )
2392 {
2393 EFI_STATUS Status;
2394
2395 //
2396 // Register Protocol notify for Hotkey service
2397 //
2398 Status = gBS->CreateEvent (
2399 EVT_NOTIFY_SIGNAL,
2400 TPL_CALLBACK,
2401 HitHotkeyEvent,
2402 NULL,
2403 &mHitHotkeyEvent
2404 );
2405 ASSERT_EFI_ERROR (Status);
2406
2407 //
2408 // Register for protocol notifications on this event
2409 //
2410 Status = gBS->RegisterProtocolNotify (
2411 &gEfiSimpleTextInputExProtocolGuid,
2412 mHitHotkeyEvent,
2413 &mHitHotkeyRegistration
2414 );
2415 ASSERT_EFI_ERROR (Status);
2416 }