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