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