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