Vlv2TbltDevicePkg:Signal EndOfDxe Event.
[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
2166 UINT8 Data;\r
2167 UINT32 BlockLength;\r
2168 UINTN Index;\r
2169\r
2170 BaseAddress = Base - 0x400000 + 2;\r
2171 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (Base));\r
2172 BlockMap = &(FvHeader->BlockMap[0]);\r
2173\r
2174 while ((BlockMap->NumBlocks != 0) && (BlockMap->Length != 0)) {\r
2175 BlockLength = BlockMap->Length;\r
2176 for (Index = 0; Index < BlockMap->NumBlocks; Index++) {\r
2177 Data = MmioOr8 ((UINTN) BaseAddress, 0x03);\r
2178 BaseAddress += BlockLength;\r
2179 }\r
2180 BlockMap++;\r
2181 }\r
2182}\r
2183\r
2184VOID\r
2185EFIAPI\r
2186PlatformBdsLockNonUpdatableFlash (\r
2187 VOID\r
2188 )\r
2189{\r
2190 EFI_PHYSICAL_ADDRESS Base;\r
2191\r
2192 Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvMainBase);\r
2193 if (Base > 0) {\r
2194 BdsLockFv (Base);\r
2195 }\r
2196\r
2197 Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvRecoveryBase);\r
2198 if (Base > 0) {\r
2199 BdsLockFv (Base);\r
2200 }\r
2201}\r
2202\r
2203/**\r
2204 Lock the ConsoleIn device in system table. All key\r
2205 presses will be ignored until the Password is typed in. The only way to\r
2206 disable the password is to type it in to a ConIn device.\r
2207\r
2208 @param Password Password used to lock ConIn device.\r
2209\r
2210 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.\r
2211 @retval EFI_UNSUPPORTED Password not found\r
2212\r
2213**/\r
2214EFI_STATUS\r
2215EFIAPI\r
2216LockKeyboards (\r
2217 IN CHAR16 *Password\r
2218 )\r
2219{\r
2220 return EFI_UNSUPPORTED;\r
2221}\r
2222\r
2223/**\r
2224 Connect the predefined platform default authentication devices.\r
2225\r
2226 This function connects the predefined device path for authentication device,\r
2227 and if the predefined device path has child device path, the child handle will\r
2228 be connected too. But the child handle of the child will not be connected.\r
2229\r
2230**/\r
2231VOID\r
2232EFIAPI\r
2233PlatformBdsConnectAuthDevice (\r
2234 VOID\r
2235 )\r
2236{\r
2237 EFI_STATUS Status;\r
2238 UINTN Index;\r
2239 UINTN HandleIndex;\r
2240 UINTN HandleCount;\r
2241 EFI_HANDLE *HandleBuffer;\r
2242 EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath;\r
2243 EFI_USER_MANAGER_PROTOCOL *Manager;\r
2244\r
2245 Status = gBS->LocateProtocol (\r
2246 &gEfiUserManagerProtocolGuid,\r
2247 NULL,\r
2248 (VOID **) &Manager\r
2249 );\r
2250 if (EFI_ERROR (Status)) {\r
2251 //\r
2252 // As user manager protocol is not installed, the authentication devices\r
2253 // should not be connected.\r
2254 //\r
2255 return ;\r
2256 }\r
2257\r
2258 Index = 0;\r
2259 while (gUserAuthenticationDevice[Index] != NULL) {\r
2260 //\r
2261 // Connect the platform customized device paths\r
2262 //\r
2263 BdsLibConnectDevicePath (gUserAuthenticationDevice[Index]);\r
2264 Index++;\r
2265 }\r
2266\r
2267 //\r
2268 // Find and connect the child device paths of the platform customized device paths\r
2269 //\r
2270 HandleBuffer = NULL;\r
2271 for (Index = 0; gUserAuthenticationDevice[Index] != NULL; Index++) {\r
2272 HandleCount = 0;\r
2273 Status = gBS->LocateHandleBuffer (\r
2274 AllHandles,\r
2275 NULL,\r
2276 NULL,\r
2277 &HandleCount,\r
2278 &HandleBuffer\r
2279 );\r
2280 ASSERT (!EFI_ERROR (Status));\r
2281\r
2282 //\r
2283 // Find and connect the child device paths of gUserIdentificationDevice[Index]\r
2284 //\r
2285 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
2286 ChildDevicePath = NULL;\r
2287 Status = gBS->HandleProtocol (\r
2288 HandleBuffer[HandleIndex],\r
2289 &gEfiDevicePathProtocolGuid,\r
2290 (VOID **) &ChildDevicePath\r
2291 );\r
2292 if (EFI_ERROR (Status) || ChildDevicePath == NULL) {\r
2293 continue;\r
2294 }\r
2295\r
2296 if (CompareMem (\r
2297 ChildDevicePath,\r
2298 gUserAuthenticationDevice[Index],\r
2299 (GetDevicePathSize (gUserAuthenticationDevice[Index]) - sizeof (EFI_DEVICE_PATH_PROTOCOL))\r
2300 ) != 0) {\r
2301 continue;\r
2302 }\r
2303 gBS->ConnectController (\r
2304 HandleBuffer[HandleIndex],\r
2305 NULL,\r
2306 NULL,\r
2307 TRUE\r
2308 );\r
2309 }\r
2310 }\r
2311\r
2312 if (HandleBuffer != NULL) {\r
2313 FreePool (HandleBuffer);\r
2314 }\r
2315}\r
2316\r
2317/**\r
2318 This function is to identify a user, and return whether deferred images exist.\r
2319\r
2320 @param[out] User Point to user profile handle.\r
2321 @param[out] DeferredImageExist On return, points to TRUE if the deferred image\r
2322 exist or FALSE if it did not exist.\r
2323\r
2324**/\r
2325VOID\r
2326EFIAPI\r
2327PlatformBdsUserIdentify (\r
2328 OUT EFI_USER_PROFILE_HANDLE *User,\r
2329 OUT BOOLEAN *DeferredImageExist\r
2330 )\r
2331{\r
2332 EFI_STATUS Status;\r
2333 EFI_DEFERRED_IMAGE_LOAD_PROTOCOL *DeferredImage;\r
2334 UINTN HandleCount;\r
2335 EFI_HANDLE *HandleBuf;\r
2336 UINTN Index;\r
2337 UINTN DriverIndex;\r
2338 EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;\r
2339 VOID *DriverImage;\r
2340 UINTN ImageSize;\r
2341 BOOLEAN BootOption;\r
2342\r
2343 //\r
2344 // Perform user identification\r
2345 //\r
2346 do {\r
2347 Status = BdsLibUserIdentify (User);\r
2348 } while (EFI_ERROR (Status));\r
2349\r
2350 //\r
2351 // After user authentication now, try to find whether deferred image exists\r
2352 //\r
2353 HandleCount = 0;\r
2354 HandleBuf = NULL;\r
2355 *DeferredImageExist = FALSE;\r
2356 Status = gBS->LocateHandleBuffer (\r
2357 ByProtocol,\r
2358 &gEfiDeferredImageLoadProtocolGuid,\r
2359 NULL,\r
2360 &HandleCount,\r
2361 &HandleBuf\r
2362 );\r
2363 if (EFI_ERROR (Status)) {\r
2364 return ;\r
2365 }\r
2366\r
2367 for (Index = 0; Index < HandleCount; Index++) {\r
2368 Status = gBS->HandleProtocol (\r
2369 HandleBuf[Index],\r
2370 &gEfiDeferredImageLoadProtocolGuid,\r
2371 (VOID **) &DeferredImage\r
2372 );\r
2373 if (!EFI_ERROR (Status)) {\r
2374 //\r
2375 // Find whether deferred image exists in this instance.\r
2376 //\r
2377 DriverIndex = 0;\r
2378 Status = DeferredImage->GetImageInfo(\r
2379 DeferredImage,\r
2380 DriverIndex,\r
2381 &ImageDevicePath,\r
2382 (VOID **) &DriverImage,\r
2383 &ImageSize,\r
2384 &BootOption\r
2385 );\r
2386 if (!EFI_ERROR (Status)) {\r
2387 //\r
2388 // The deferred image is found.\r
2389 //\r
2390 FreePool (HandleBuf);\r
2391 *DeferredImageExist = TRUE;\r
2392 return ;\r
2393 }\r
2394 }\r
2395 }\r
2396\r
2397 FreePool (HandleBuf);\r
2398}\r
2399\r
2400UINTN gHotKey = 0;\r
2401\r
2402\r
2403EFI_STATUS\r
2404ShowProgressHotKey (\r
2405 IN UINT16 TimeoutDefault\r
2406 )\r
2407{\r
2408 CHAR16 *TmpStr;\r
2409 UINT16 TimeoutRemain;\r
2410 EFI_STATUS Status;\r
2411 EFI_INPUT_KEY Key;\r
2412 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
2413 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
2414 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
2415 UINT32 GpioValue;\r
2416\r
2417 if (TimeoutDefault == 0) {\r
2418 return EFI_TIMEOUT;\r
2419 }\r
2420\r
c7d161de
DW
2421 gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
2422 \r
3cbfba02
DW
2423 if (DebugAssertEnabled())\r
2424 {\r
2425 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
2426 }\r
2427 else\r
2428 { \r
2429 #ifdef __GNUC__\r
2430 SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)[GCC]", 76);\r
2431 #else\r
2432 SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)", 71);\r
2433 #endif\r
2434 } \r
2435 SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
2436 SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
2437 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
2438\r
2439 //\r
2440 // Clear the progress status bar first\r
2441 //\r
2442 TmpStr = L"Start boot option, Press <F2> or <DEL> to enter setup page.";\r
2443 PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);\r
2444\r
2445 TimeoutRemain = TimeoutDefault;\r
2446 while (TimeoutRemain != 0) {\r
2447 if (DebugAssertEnabled())\r
2448 {\r
2449 DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));\r
2450 }\r
2451 else\r
2452 { \r
2453 SerialPortWrite ((UINT8 *)".", 1);\r
2454 }\r
2455 Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);\r
2456 if (Status != EFI_TIMEOUT) {\r
2457 break;\r
2458 }\r
2459 TimeoutRemain--;\r
2460\r
2461 //\r
2462 // Show progress\r
2463 //\r
2464 if (TmpStr != NULL) {\r
2465 PlatformBdsShowProgress (\r
2466 Foreground,\r
2467 Background,\r
2468 TmpStr,\r
2469 Color,\r
2470 ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),\r
2471 0\r
2472 );\r
2473 }\r
2474 }\r
2475\r
2476 //\r
2477 // Timeout expired\r
2478 //\r
2479 if (TimeoutRemain == 0) {\r
2480 if (DebugAssertEnabled())\r
2481 {\r
2482 }\r
2483 else\r
2484 { \r
2485 SerialPortWrite ((UINT8 *)"\r\n", 2);\r
2486 }\r
2487 return EFI_TIMEOUT;\r
2488 }\r
2489\r
2490 //\r
2491 // User pressed some key\r
2492 //\r
2493 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
2494 if (EFI_ERROR (Status)) {\r
2495 return Status;\r
2496 }\r
2497\r
2498 //\r
2499 // Check Volume Up Key to enter Setup\r
2500 //\r
2501 GpioValue = MmioRead32 (IO_BASE_ADDRESS + 0x0668); // The value of GPIOC_5\r
2502 if (((GpioValue & BIT0) == 0) && (Key.ScanCode == SCAN_UP)) {\r
2503 gHotKey = 0;\r
2504 return EFI_SUCCESS;\r
2505 }\r
2506\r
2507 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
2508 //\r
2509 // User pressed enter, equivalent to select "continue"\r
2510 //\r
2511 return EFI_TIMEOUT;\r
2512 }\r
2513\r
2514 //\r
2515 //F2 -- Front Page\r
2516 //F5 -- Device Manager\r
2517 //F7 -- Boot Manager\r
2518 // do not use F8. generally people assume it is windows safe mode key.\r
2519 //F9 -- Boot order\r
2520 //\r
2521 DEBUG ((EFI_D_INFO, "[Key Pressed]: ScanCode 0x%x\n", Key.ScanCode));\r
2522 switch(Key.ScanCode) {\r
2523 case SCAN_F2:\r
2524 gHotKey = 0;\r
2525 break;\r
2526\r
2527 case SCAN_DELETE:\r
2528 gHotKey = 0;\r
2529 break;\r
2530\r
2531 case SCAN_F5:\r
2532 gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;\r
2533 break;\r
2534\r
2535 case SCAN_F7:\r
2536 gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;\r
2537 break;\r
2538\r
2539 case SCAN_F9:\r
2540 gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;\r
2541 break;\r
2542\r
2543 default:\r
2544 //set gHotKey to continue so that flow will not go into CallFrontPage\r
2545 gHotKey = FRONT_PAGE_KEY_CONTINUE;\r
2546 return EFI_TIMEOUT;\r
2547 break;\r
2548 }\r
2549\r
2550 return EFI_SUCCESS;\r
2551}\r
2552\r
2553\r
2554\r
2555/**\r
2556 This function is the main entry of the platform setup entry.\r
2557 The function will present the main menu of the system setup,\r
2558 this is the platform reference part and can be customize.\r
2559\r
2560\r
2561 @param TimeoutDefault The fault time out value before the system\r
2562 continue to boot.\r
2563 @param ConnectAllHappened The indicater to check if the connect all have\r
2564 already happened.\r
2565\r
2566**/\r
2567VOID\r
2568PlatformBdsEnterFrontPageWithHotKey (\r
2569 IN UINT16 TimeoutDefault,\r
2570 IN BOOLEAN ConnectAllHappened\r
2571 )\r
2572{\r
2573 EFI_STATUS Status;\r
2574\r
2575 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
2576 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;\r
2577 UINTN BootTextColumn;\r
2578 UINTN BootTextRow;\r
2579\r
2580 GraphicsOutput = NULL;\r
2581 SimpleTextOut = NULL;\r
2582\r
2583 PERF_START (NULL, "BdsTimeOut", "BDS", 0);\r
2584\r
2585 //\r
2586 // Indicate if we need connect all in the platform setup\r
2587 //\r
2588 if (ConnectAllHappened) {\r
2589 gConnectAllHappened = TRUE;\r
2590 }\r
2591\r
2592 if (!mModeInitialized) {\r
2593 //\r
2594 // After the console is ready, get current video resolution\r
2595 // and text mode before launching setup at first time.\r
2596 //\r
2597 Status = gBS->HandleProtocol (\r
2598 gST->ConsoleOutHandle,\r
2599 &gEfiGraphicsOutputProtocolGuid,\r
2600 (VOID**)&GraphicsOutput\r
2601 );\r
2602 if (EFI_ERROR (Status)) {\r
2603 GraphicsOutput = NULL;\r
2604 }\r
2605\r
2606 Status = gBS->HandleProtocol (\r
2607 gST->ConsoleOutHandle,\r
2608 &gEfiSimpleTextOutProtocolGuid,\r
2609 (VOID**)&SimpleTextOut\r
2610 );\r
2611 if (EFI_ERROR (Status)) {\r
2612 SimpleTextOut = NULL;\r
2613 }\r
2614\r
2615 if (GraphicsOutput != NULL) {\r
2616 //\r
2617 // Get current video resolution and text mode.\r
2618 //\r
2619 mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
2620 mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
2621 }\r
2622\r
2623 if (SimpleTextOut != NULL) {\r
2624 Status = SimpleTextOut->QueryMode (\r
2625 SimpleTextOut,\r
2626 SimpleTextOut->Mode->Mode,\r
2627 &BootTextColumn,\r
2628 &BootTextRow\r
2629 );\r
2630 mBootTextModeColumn = (UINT32)BootTextColumn;\r
2631 mBootTextModeRow = (UINT32)BootTextRow;\r
2632 }\r
2633\r
2634 //\r
2635 // Get user defined text mode for setup.\r
2636 //\r
2637 mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);\r
2638 mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);\r
2639 mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);\r
2640 mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);\r
2641\r
2642 mModeInitialized = TRUE;\r
2643 }\r
2644\r
2645 if (TimeoutDefault != 0xffff) {\r
2646 Status = ShowProgressHotKey (TimeoutDefault);\r
2647\r
2648 //\r
2649 // Ensure screen is clear when switch Console from Graphics mode to Text mode\r
2650 //\r
2651 gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
2652 gST->ConOut->ClearScreen (gST->ConOut);\r
2653\r
2654 if (EFI_ERROR (Status)) {\r
2655 //\r
2656 // Timeout or user press enter to continue\r
2657 //\r
2658 goto Exit;\r
2659 }\r
2660 }\r
4139580d
SL
2661 //\r
2662 // Install BM HiiPackages. \r
2663 // Keep BootMaint HiiPackage, so that it can be covered by global setting. \r
2664 //\r
2665 InitBMPackage ();\r
3cbfba02
DW
2666 do {\r
2667\r
2668 BdsSetConsoleMode (TRUE);\r
2669\r
2670 InitializeFrontPage (FALSE);\r
2671\r
2672 //\r
2673 // Update Front Page strings\r
2674 //\r
2675 UpdateFrontPageStrings ();\r
2676\r
2677 Status = EFI_SUCCESS;\r
2678 gCallbackKey = 0;\r
2679 if (gHotKey == 0) {\r
2680 Status = CallFrontPage ();\r
2681 } else {\r
2682 gCallbackKey = gHotKey;\r
2683 gHotKey = 0;\r
2684 }\r
2685\r
2686 //\r
2687 // If gCallbackKey is greater than 1 and less or equal to 5,\r
2688 // it will launch configuration utilities.\r
2689 // 2 = set language\r
2690 // 3 = boot manager\r
2691 // 4 = device manager\r
2692 // 5 = boot maintenance manager\r
2693 //\r
2694 if (gCallbackKey != 0) {\r
2695 REPORT_STATUS_CODE (\r
2696 EFI_PROGRESS_CODE,\r
2697 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)\r
2698 );\r
2699 }\r
2700\r
2701 //\r
2702 // Based on the key that was set, we can determine what to do\r
2703 //\r
2704 switch (gCallbackKey) {\r
2705 //\r
2706 // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can\r
2707 // describe to their customers in documentation how to find their setup information (namely\r
2708 // under the device manager and specific buckets)\r
2709 //\r
2710 // These entries consist of the Continue, Select language, Boot Manager, and Device Manager\r
2711 //\r
2712 case FRONT_PAGE_KEY_CONTINUE:\r
2713\r
2714 //\r
2715 // User hit continue\r
2716 //\r
2717 break;\r
2718\r
2719 case FRONT_PAGE_KEY_LANGUAGE:\r
2720\r
2721 //\r
2722 // User made a language setting change - display front page again\r
2723 //\r
2724 break;\r
2725\r
2726 case FRONT_PAGE_KEY_BOOT_MANAGER:\r
4139580d
SL
2727 //\r
2728 // Remove the installed BootMaint HiiPackages when exit.\r
2729 //\r
2730 FreeBMPackage ();\r
3cbfba02
DW
2731\r
2732 //\r
2733 // User chose to run the Boot Manager\r
2734 //\r
2735 CallBootManager ();\r
4139580d
SL
2736 \r
2737 //\r
2738 // Reinstall BootMaint HiiPackages after exiting from Boot Manager.\r
2739 //\r
2740 InitBMPackage ();\r
3cbfba02
DW
2741 break;\r
2742\r
2743 case FRONT_PAGE_KEY_DEVICE_MANAGER:\r
2744\r
2745 //\r
2746 // Display the Device Manager\r
2747 //\r
2748 do {\r
2749 CallDeviceManager ();\r
2750 } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);\r
2751 break;\r
2752\r
2753 case FRONT_PAGE_KEY_BOOT_MAINTAIN:\r
2754\r
2755 //\r
2756 // Display the Boot Maintenance Manager\r
2757 //\r
2758 BdsStartBootMaint ();\r
2759 break;\r
2760 }\r
2761\r
2762 } while (((UINTN)gCallbackKey) != FRONT_PAGE_KEY_CONTINUE);\r
2763\r
2764 //\r
2765 //Will leave browser, check any reset required change is applied? if yes, reset system\r
2766 //\r
2767 SetupResetReminder ();\r
4139580d
SL
2768 //\r
2769 // Remove the installed BootMaint HiiPackages when exit.\r
2770 //\r
2771 FreeBMPackage ();\r
3cbfba02
DW
2772\r
2773Exit:\r
2774 //\r
2775 // Automatically load current entry\r
2776 // Note: The following lines of code only execute when Auto boot\r
2777 // takes affect\r
2778 //\r
2779 PERF_END (NULL, "BdsTimeOut", "BDS", 0);\r
2780}\r
2781\r
2782\r
2783VOID \r
2784BootIntoFirmwareInterface(\r
2785VOID\r
2786)\r
2787{\r
2788 EFI_STATUS Status;\r
2789 UINTN DataSize;\r
2790 UINT16 Timeout; \r
2791 UINT64 OsIndication;\r
2792\r
2793 \r
2794 OsIndication = 0;\r
2795 DataSize = sizeof(UINT64);\r
2796 Status = gRT->GetVariable (\r
2797 L"OsIndications",\r
2798 &gEfiGlobalVariableGuid,\r
2799 NULL,\r
2800 &DataSize,\r
2801 &OsIndication\r
2802 );\r
2803 \r
2804 DEBUG ((EFI_D_INFO, "OSIndication Variable Value %d\n", OsIndication));\r
2805 //\r
2806 //Goto FrontPage directly when bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted.\r
2807 // \r
2808 if (!EFI_ERROR(Status) && (OsIndication != 0)) { \r
2809 Timeout = 0xffff;\r
2810 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
2811 }\r
2812}\r
2813\r
2814\r
2815EFI_STATUS\r
2816PlatformBdsConnectSimpleConsole (\r
2817 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole\r
2818)\r
2819{\r
2820 EFI_STATUS Status;\r
2821 UINTN Index;\r
2822 EFI_DEVICE_PATH_PROTOCOL *VarConout;\r
2823 EFI_DEVICE_PATH_PROTOCOL *VarConin;\r
2824 UINTN DevicePathSize;\r
2825\r
2826\r
2827 Index = 0;\r
2828 Status = EFI_SUCCESS;\r
2829 DevicePathSize = 0;\r
2830 VarConout = BdsLibGetVariableAndSize (\r
2831 L"ConOut",\r
2832 &gEfiGlobalVariableGuid,\r
2833 &DevicePathSize\r
2834 );\r
2835 VarConin = BdsLibGetVariableAndSize (\r
2836 L"ConIn",\r
2837 &gEfiGlobalVariableGuid,\r
2838 &DevicePathSize\r
2839 );\r
2840 if (VarConout == NULL || VarConin == NULL) {\r
2841 //\r
2842 // Have chance to connect the platform default console,\r
2843 // the platform default console is the minimue device group\r
2844 // the platform should support\r
2845 //\r
2846 while (PlatformConsole[Index].DevicePath != NULL) {\r
2847\r
2848 //\r
2849 // Update the console variable with the connect type\r
2850 //\r
2851 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
2852 BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);\r
2853 }\r
2854\r
2855 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
2856 BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);\r
2857 }\r
2858\r
2859 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
2860 BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);\r
2861 }\r
2862\r
2863 Index ++;\r
2864 }\r
2865 }\r
2866\r
2867 //\r
2868 // Connect ConIn first to give keyboard time to parse hot key event.\r
2869 //\r
2870 Status = BdsLibConnectConsoleVariable (L"ConIn");\r
2871 if (EFI_ERROR (Status)) {\r
2872 return Status;\r
2873 }\r
2874\r
2875 //\r
2876 // Make sure we have at least one active VGA, and have the right\r
2877 // active VGA in console variable\r
2878 //\r
2879 Status = PlatformBdsForceActiveVga ();\r
2880\r
2881 //\r
2882 // It seems impossible not to have any ConOut device on platform,\r
2883 // so we check the status here.\r
2884 //\r
2885 Status = BdsLibConnectConsoleVariable (L"ConOut");\r
2886 if (EFI_ERROR (Status)) {\r
2887 return Status;\r
2888 }\r
2889\r
2890 return EFI_SUCCESS;\r
2891}\r
2892\r
2893\r
2894/**\r
2895 Timer handler to convert the key from USB.\r
2896\r
2897 @param Event Indicates the event that invoke this function.\r
2898 @param Context Indicates the calling context.\r
2899**/\r
2900VOID\r
2901EFIAPI\r
2902HotKeyTimerHandler (\r
2903 IN EFI_EVENT Event,\r
2904 IN VOID *Context\r
2905 )\r
2906{\r
2907 EFI_STATUS Status;\r
2908 EFI_INPUT_KEY Key;\r
2909\r
2910 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
2911 if (EFI_ERROR (Status)) {\r
2912 return;\r
2913 }\r
2914\r
2915 switch(Key.ScanCode) {\r
2916 case SCAN_F2:\r
2917 gHotKey = 0;\r
2918 mHotKeyPressed = TRUE;\r
2919 break;\r
2920\r
2921 case SCAN_F5:\r
2922 gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;\r
2923 mHotKeyPressed = TRUE;\r
2924 break;\r
2925\r
2926 case SCAN_F7:\r
2927 gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;\r
2928 mHotKeyPressed = TRUE;\r
2929 break;\r
2930\r
2931 case SCAN_F9:\r
2932 gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;\r
2933 mHotKeyPressed = TRUE;\r
2934 break;\r
2935 }\r
2936\r
2937 if (mHotKeyPressed) {\r
2938 gBS->SetTimer (\r
2939 mHotKeyTimerEvent,\r
2940 TimerCancel,\r
2941 0\r
2942 );\r
2943 gBS->CloseEvent (mHotKeyTimerEvent);\r
2944 mHotKeyTimerEvent = NULL;\r
2945 }\r
2946\r
2947 return;\r
2948}\r
2949\r
2950\r
2951/**\r
2952 Callback function for SimpleTextInEx protocol install events\r
2953\r
2954 @param Event the event that is signaled.\r
2955 @param Context not used here.\r
2956\r
2957**/\r
2958VOID\r
2959EFIAPI\r
2960HitHotkeyEvent (\r
2961 IN EFI_EVENT Event,\r
2962 IN VOID *Context\r
2963 )\r
2964{\r
2965 EFI_STATUS Status;\r
2966\r
2967 Status = gBS->CloseEvent(mHitHotkeyEvent);\r
2968 if (EFI_ERROR (Status)) {\r
2969 return;\r
2970 }\r
2971 Status = gBS->CreateEvent (\r
2972 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
2973 TPL_NOTIFY,\r
2974 HotKeyTimerHandler,\r
2975 NULL,\r
2976 &mHotKeyTimerEvent\r
2977 );\r
2978 if (EFI_ERROR (Status)) {\r
2979 return;\r
2980 }\r
2981 Status = gBS->SetTimer (\r
2982 mHotKeyTimerEvent,\r
2983 TimerPeriodic,\r
2984 KEYBOARD_TIMER_INTERVAL\r
2985 );\r
2986 if (EFI_ERROR (Status)) {\r
2987 return;\r
2988 }\r
2989\r
2990 return;\r
2991}\r
2992\r
2993\r
2994VOID\r
2995EFIAPI\r
2996PlatformBdsInitHotKeyEvent (\r
2997 VOID\r
2998 )\r
2999{\r
3000 EFI_STATUS Status;\r
3001\r
3002 //\r
3003 // Register Protocol notify for Hotkey service\r
3004 //\r
3005 Status = gBS->CreateEvent (\r
3006 EVT_NOTIFY_SIGNAL,\r
3007 TPL_CALLBACK,\r
3008 HitHotkeyEvent,\r
3009 NULL,\r
3010 &mHitHotkeyEvent\r
3011 );\r
3012 ASSERT_EFI_ERROR (Status);\r
3013\r
3014 //\r
3015 // Register for protocol notifications on this event\r
3016 //\r
3017 Status = gBS->RegisterProtocolNotify (\r
3018 &gEfiSimpleTextInputExProtocolGuid,\r
3019 mHitHotkeyEvent,\r
3020 &mHitHotkeyRegistration\r
3021 );\r
3022 ASSERT_EFI_ERROR (Status);\r
3023}\r