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