]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
Remove override to ConSplitter
[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 gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
1817
1818 if (DebugAssertEnabled())
1819 {
1820 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"));
1821 }
1822 else
1823 {
1824 #ifdef __GNUC__
1825 SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)[GCC]", 76);
1826 #else
1827 SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)", 71);
1828 #endif
1829 }
1830 SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
1831 SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
1832 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
1833
1834 //
1835 // Clear the progress status bar first
1836 //
1837 TmpStr = L"Start boot option, Press <F2> or <DEL> to enter setup page.";
1838 PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);
1839
1840 TimeoutRemain = TimeoutDefault;
1841 while (TimeoutRemain != 0) {
1842 if (DebugAssertEnabled())
1843 {
1844 DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));
1845 }
1846 else
1847 {
1848 SerialPortWrite ((UINT8 *)".", 1);
1849 }
1850 Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);
1851 if (Status != EFI_TIMEOUT) {
1852 break;
1853 }
1854 TimeoutRemain--;
1855
1856 //
1857 // Show progress
1858 //
1859 if (TmpStr != NULL) {
1860 PlatformBdsShowProgress (
1861 Foreground,
1862 Background,
1863 TmpStr,
1864 Color,
1865 ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),
1866 0
1867 );
1868 }
1869 }
1870
1871 //
1872 // Timeout expired
1873 //
1874 if (TimeoutRemain == 0) {
1875 if (DebugAssertEnabled())
1876 {
1877 }
1878 else
1879 {
1880 SerialPortWrite ((UINT8 *)"\r\n", 2);
1881 }
1882 return EFI_TIMEOUT;
1883 }
1884
1885 //
1886 // User pressed some key
1887 //
1888 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
1889 if (EFI_ERROR (Status)) {
1890 return Status;
1891 }
1892
1893 //
1894 // Check Volume Up Key to enter Setup
1895 //
1896 GpioValue = MmioRead32 (IO_BASE_ADDRESS + 0x0668); // The value of GPIOC_5
1897 if (((GpioValue & BIT0) == 0) && (Key.ScanCode == SCAN_UP)) {
1898 gHotKey = 0;
1899 return EFI_SUCCESS;
1900 }
1901
1902 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
1903 //
1904 // User pressed enter, equivalent to select "continue"
1905 //
1906 return EFI_TIMEOUT;
1907 }
1908
1909 //
1910 //F2 -- Front Page
1911 //F5 -- Device Manager
1912 //F7 -- Boot Manager
1913 // do not use F8. generally people assume it is windows safe mode key.
1914 //F9 -- Boot order
1915 //
1916 DEBUG ((EFI_D_INFO, "[Key Pressed]: ScanCode 0x%x\n", Key.ScanCode));
1917 switch(Key.ScanCode) {
1918 case SCAN_F2:
1919 gHotKey = 0;
1920 break;
1921
1922 case SCAN_DELETE:
1923 gHotKey = 0;
1924 break;
1925
1926 case SCAN_F5:
1927 gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
1928 break;
1929
1930 case SCAN_F7:
1931 gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
1932 break;
1933
1934 case SCAN_F9:
1935 gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
1936 break;
1937
1938 default:
1939 //set gHotKey to continue so that flow will not go into CallFrontPage
1940 gHotKey = FRONT_PAGE_KEY_CONTINUE;
1941 return EFI_TIMEOUT;
1942 break;
1943 }
1944
1945 return EFI_SUCCESS;
1946 }
1947
1948
1949
1950 /**
1951 This function is the main entry of the platform setup entry.
1952 The function will present the main menu of the system setup,
1953 this is the platform reference part and can be customize.
1954
1955
1956 @param TimeoutDefault The fault time out value before the system
1957 continue to boot.
1958 @param ConnectAllHappened The indicater to check if the connect all have
1959 already happened.
1960
1961 **/
1962 VOID
1963 PlatformBdsEnterFrontPageWithHotKey (
1964 IN UINT16 TimeoutDefault,
1965 IN BOOLEAN ConnectAllHappened
1966 )
1967 {
1968 EFI_STATUS Status;
1969
1970 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1971 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
1972 UINTN BootTextColumn;
1973 UINTN BootTextRow;
1974
1975 GraphicsOutput = NULL;
1976 SimpleTextOut = NULL;
1977
1978 PERF_START (NULL, "BdsTimeOut", "BDS", 0);
1979
1980 //
1981 // Indicate if we need connect all in the platform setup
1982 //
1983 if (ConnectAllHappened) {
1984 gConnectAllHappened = TRUE;
1985 }
1986
1987 if (!mModeInitialized) {
1988 //
1989 // After the console is ready, get current video resolution
1990 // and text mode before launching setup at first time.
1991 //
1992 Status = gBS->HandleProtocol (
1993 gST->ConsoleOutHandle,
1994 &gEfiGraphicsOutputProtocolGuid,
1995 (VOID**)&GraphicsOutput
1996 );
1997 if (EFI_ERROR (Status)) {
1998 GraphicsOutput = NULL;
1999 }
2000
2001 Status = gBS->HandleProtocol (
2002 gST->ConsoleOutHandle,
2003 &gEfiSimpleTextOutProtocolGuid,
2004 (VOID**)&SimpleTextOut
2005 );
2006 if (EFI_ERROR (Status)) {
2007 SimpleTextOut = NULL;
2008 }
2009
2010 if (GraphicsOutput != NULL) {
2011 //
2012 // Get current video resolution and text mode.
2013 //
2014 mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
2015 mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
2016 }
2017
2018 if (SimpleTextOut != NULL) {
2019 Status = SimpleTextOut->QueryMode (
2020 SimpleTextOut,
2021 SimpleTextOut->Mode->Mode,
2022 &BootTextColumn,
2023 &BootTextRow
2024 );
2025 mBootTextModeColumn = (UINT32)BootTextColumn;
2026 mBootTextModeRow = (UINT32)BootTextRow;
2027 }
2028
2029 //
2030 // Get user defined text mode for setup.
2031 //
2032 mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
2033 mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
2034 mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);
2035 mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);
2036
2037 mModeInitialized = TRUE;
2038 }
2039
2040 if (TimeoutDefault != 0xffff) {
2041 Status = ShowProgressHotKey (TimeoutDefault);
2042
2043 //
2044 // Ensure screen is clear when switch Console from Graphics mode to Text mode
2045 //
2046 gST->ConOut->EnableCursor (gST->ConOut, TRUE);
2047 gST->ConOut->ClearScreen (gST->ConOut);
2048
2049 if (EFI_ERROR (Status)) {
2050 //
2051 // Timeout or user press enter to continue
2052 //
2053 goto Exit;
2054 }
2055 }
2056 //
2057 // Install BM HiiPackages.
2058 // Keep BootMaint HiiPackage, so that it can be covered by global setting.
2059 //
2060 InitBMPackage ();
2061 do {
2062
2063 BdsSetConsoleMode (TRUE);
2064
2065 InitializeFrontPage (FALSE);
2066
2067 //
2068 // Update Front Page strings
2069 //
2070 UpdateFrontPageStrings ();
2071
2072 Status = EFI_SUCCESS;
2073 gCallbackKey = 0;
2074 if (gHotKey == 0) {
2075 Status = CallFrontPage ();
2076 } else {
2077 gCallbackKey = gHotKey;
2078 gHotKey = 0;
2079 }
2080
2081 //
2082 // If gCallbackKey is greater than 1 and less or equal to 5,
2083 // it will launch configuration utilities.
2084 // 2 = set language
2085 // 3 = boot manager
2086 // 4 = device manager
2087 // 5 = boot maintenance manager
2088 //
2089 if (gCallbackKey != 0) {
2090 REPORT_STATUS_CODE (
2091 EFI_PROGRESS_CODE,
2092 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
2093 );
2094 }
2095
2096 //
2097 // Based on the key that was set, we can determine what to do
2098 //
2099 switch (gCallbackKey) {
2100 //
2101 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
2102 // describe to their customers in documentation how to find their setup information (namely
2103 // under the device manager and specific buckets)
2104 //
2105 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager
2106 //
2107 case FRONT_PAGE_KEY_CONTINUE:
2108
2109 //
2110 // User hit continue
2111 //
2112 break;
2113
2114 case FRONT_PAGE_KEY_LANGUAGE:
2115
2116 //
2117 // User made a language setting change - display front page again
2118 //
2119 break;
2120
2121 case FRONT_PAGE_KEY_BOOT_MANAGER:
2122 //
2123 // Remove the installed BootMaint HiiPackages when exit.
2124 //
2125 FreeBMPackage ();
2126
2127 //
2128 // User chose to run the Boot Manager
2129 //
2130 CallBootManager ();
2131
2132 //
2133 // Reinstall BootMaint HiiPackages after exiting from Boot Manager.
2134 //
2135 InitBMPackage ();
2136 break;
2137
2138 case FRONT_PAGE_KEY_DEVICE_MANAGER:
2139
2140 //
2141 // Display the Device Manager
2142 //
2143 do {
2144 CallDeviceManager ();
2145 } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);
2146 break;
2147
2148 case FRONT_PAGE_KEY_BOOT_MAINTAIN:
2149
2150 //
2151 // Display the Boot Maintenance Manager
2152 //
2153 BdsStartBootMaint ();
2154 break;
2155 }
2156
2157 } while (((UINTN)gCallbackKey) != FRONT_PAGE_KEY_CONTINUE);
2158
2159 //
2160 //Will leave browser, check any reset required change is applied? if yes, reset system
2161 //
2162 SetupResetReminder ();
2163 //
2164 // Remove the installed BootMaint HiiPackages when exit.
2165 //
2166 FreeBMPackage ();
2167
2168 Exit:
2169 //
2170 // Automatically load current entry
2171 // Note: The following lines of code only execute when Auto boot
2172 // takes affect
2173 //
2174 PERF_END (NULL, "BdsTimeOut", "BDS", 0);
2175 }
2176
2177
2178 VOID
2179 BootIntoFirmwareInterface(
2180 VOID
2181 )
2182 {
2183 EFI_STATUS Status;
2184 UINTN DataSize;
2185 UINT16 Timeout;
2186 UINT64 OsIndication;
2187
2188
2189 OsIndication = 0;
2190 DataSize = sizeof(UINT64);
2191 Status = gRT->GetVariable (
2192 L"OsIndications",
2193 &gEfiGlobalVariableGuid,
2194 NULL,
2195 &DataSize,
2196 &OsIndication
2197 );
2198
2199 DEBUG ((EFI_D_INFO, "OSIndication Variable Value %d\n", OsIndication));
2200 //
2201 //Goto FrontPage directly when bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted.
2202 //
2203 if (!EFI_ERROR(Status) && (OsIndication != 0)) {
2204 Timeout = 0xffff;
2205 PlatformBdsEnterFrontPage (Timeout, FALSE);
2206 }
2207 }
2208
2209
2210 EFI_STATUS
2211 PlatformBdsConnectSimpleConsole (
2212 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
2213 )
2214 {
2215 EFI_STATUS Status;
2216 UINTN Index;
2217 EFI_DEVICE_PATH_PROTOCOL *VarConout;
2218 EFI_DEVICE_PATH_PROTOCOL *VarConin;
2219 UINTN DevicePathSize;
2220
2221
2222 Index = 0;
2223 Status = EFI_SUCCESS;
2224 DevicePathSize = 0;
2225 VarConout = BdsLibGetVariableAndSize (
2226 L"ConOut",
2227 &gEfiGlobalVariableGuid,
2228 &DevicePathSize
2229 );
2230 VarConin = BdsLibGetVariableAndSize (
2231 L"ConIn",
2232 &gEfiGlobalVariableGuid,
2233 &DevicePathSize
2234 );
2235 if (VarConout == NULL || VarConin == NULL) {
2236 //
2237 // Have chance to connect the platform default console,
2238 // the platform default console is the minimue device group
2239 // the platform should support
2240 //
2241 while (PlatformConsole[Index].DevicePath != NULL) {
2242
2243 //
2244 // Update the console variable with the connect type
2245 //
2246 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
2247 BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);
2248 }
2249
2250 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
2251 BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);
2252 }
2253
2254 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
2255 BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);
2256 }
2257
2258 Index ++;
2259 }
2260 }
2261
2262 //
2263 // Connect ConIn first to give keyboard time to parse hot key event.
2264 //
2265 Status = BdsLibConnectConsoleVariable (L"ConIn");
2266 if (EFI_ERROR (Status)) {
2267 return Status;
2268 }
2269
2270 //
2271 // Make sure we have at least one active VGA, and have the right
2272 // active VGA in console variable
2273 //
2274 Status = PlatformBdsForceActiveVga ();
2275
2276 //
2277 // It seems impossible not to have any ConOut device on platform,
2278 // so we check the status here.
2279 //
2280 Status = BdsLibConnectConsoleVariable (L"ConOut");
2281 if (EFI_ERROR (Status)) {
2282 return Status;
2283 }
2284
2285 return EFI_SUCCESS;
2286 }
2287
2288
2289 /**
2290 Timer handler to convert the key from USB.
2291
2292 @param Event Indicates the event that invoke this function.
2293 @param Context Indicates the calling context.
2294 **/
2295 VOID
2296 EFIAPI
2297 HotKeyTimerHandler (
2298 IN EFI_EVENT Event,
2299 IN VOID *Context
2300 )
2301 {
2302 EFI_STATUS Status;
2303 EFI_INPUT_KEY Key;
2304
2305 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
2306 if (EFI_ERROR (Status)) {
2307 return;
2308 }
2309
2310 switch(Key.ScanCode) {
2311 case SCAN_F2:
2312 gHotKey = 0;
2313 mHotKeyPressed = TRUE;
2314 break;
2315
2316 case SCAN_F5:
2317 gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
2318 mHotKeyPressed = TRUE;
2319 break;
2320
2321 case SCAN_F7:
2322 gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;
2323 mHotKeyPressed = TRUE;
2324 break;
2325
2326 case SCAN_F9:
2327 gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;
2328 mHotKeyPressed = TRUE;
2329 break;
2330 }
2331
2332 if (mHotKeyPressed) {
2333 gBS->SetTimer (
2334 mHotKeyTimerEvent,
2335 TimerCancel,
2336 0
2337 );
2338 gBS->CloseEvent (mHotKeyTimerEvent);
2339 mHotKeyTimerEvent = NULL;
2340 }
2341
2342 return;
2343 }
2344
2345
2346 /**
2347 Callback function for SimpleTextInEx protocol install events
2348
2349 @param Event the event that is signaled.
2350 @param Context not used here.
2351
2352 **/
2353 VOID
2354 EFIAPI
2355 HitHotkeyEvent (
2356 IN EFI_EVENT Event,
2357 IN VOID *Context
2358 )
2359 {
2360 EFI_STATUS Status;
2361
2362 Status = gBS->CloseEvent(mHitHotkeyEvent);
2363 if (EFI_ERROR (Status)) {
2364 return;
2365 }
2366 Status = gBS->CreateEvent (
2367 EVT_TIMER | EVT_NOTIFY_SIGNAL,
2368 TPL_NOTIFY,
2369 HotKeyTimerHandler,
2370 NULL,
2371 &mHotKeyTimerEvent
2372 );
2373 if (EFI_ERROR (Status)) {
2374 return;
2375 }
2376 Status = gBS->SetTimer (
2377 mHotKeyTimerEvent,
2378 TimerPeriodic,
2379 KEYBOARD_TIMER_INTERVAL
2380 );
2381 if (EFI_ERROR (Status)) {
2382 return;
2383 }
2384
2385 return;
2386 }
2387
2388
2389 VOID
2390 EFIAPI
2391 PlatformBdsInitHotKeyEvent (
2392 VOID
2393 )
2394 {
2395 EFI_STATUS Status;
2396
2397 //
2398 // Register Protocol notify for Hotkey service
2399 //
2400 Status = gBS->CreateEvent (
2401 EVT_NOTIFY_SIGNAL,
2402 TPL_CALLBACK,
2403 HitHotkeyEvent,
2404 NULL,
2405 &mHitHotkeyEvent
2406 );
2407 ASSERT_EFI_ERROR (Status);
2408
2409 //
2410 // Register for protocol notifications on this event
2411 //
2412 Status = gBS->RegisterProtocolNotify (
2413 &gEfiSimpleTextInputExProtocolGuid,
2414 mHitHotkeyEvent,
2415 &mHitHotkeyRegistration
2416 );
2417 ASSERT_EFI_ERROR (Status);
2418 }