]> git.proxmox.com Git - mirror_edk2.git/blame - CorebootPayloadPkg/Library/PlatformBdsLib/BdsPlatform.c
Pkg-Module: CorebootPayloadPkg
[mirror_edk2.git] / CorebootPayloadPkg / Library / PlatformBdsLib / BdsPlatform.c
CommitLineData
9c228fb0
MM
1/** @file\r
2 This file include all platform action which can be customized by IBV/OEM.\r
3\r
4Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "BdsPlatform.h"\r
16\r
17//\r
18// Global data\r
19//\r
20BOOLEAN mDetectVgaOnly;\r
21\r
22\r
23//\r
24// Type definitions\r
25//\r
26\r
27typedef\r
28EFI_STATUS\r
29(EFIAPI *PROTOCOL_INSTANCE_CALLBACK)(\r
30 IN EFI_HANDLE Handle,\r
31 IN VOID *Instance,\r
32 IN VOID *Context\r
33 );\r
34\r
35/**\r
36 @param[in] Handle - Handle of PCI device instance\r
37 @param[in] PciIo - PCI IO protocol instance\r
38 @param[in] Pci - PCI Header register block\r
39**/\r
40typedef\r
41EFI_STATUS\r
42(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)(\r
43 IN EFI_HANDLE Handle,\r
44 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
45 IN PCI_TYPE00 *Pci\r
46 );\r
47\r
48\r
49//\r
50// Function prototypes\r
51//\r
52\r
53EFI_STATUS\r
54VisitAllInstancesOfProtocol (\r
55 IN EFI_GUID *Id,\r
56 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction,\r
57 IN VOID *Context\r
58 );\r
59\r
60EFI_STATUS\r
61VisitAllPciInstancesOfProtocol (\r
62 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction\r
63 );\r
64 \r
65 \r
66//\r
67// BDS Platform Functions\r
68//\r
69\r
70/**\r
71 Platform Bds init. Include the platform firmware vendor, revision\r
72 and so crc check.\r
73\r
74**/\r
75VOID\r
76EFIAPI\r
77PlatformBdsInit (\r
78 VOID\r
79 )\r
80{\r
81}\r
82\r
83\r
84EFI_STATUS\r
85PrepareLpcBridgeDevicePath (\r
86 IN EFI_HANDLE DeviceHandle\r
87 )\r
88/*++\r
89\r
90Routine Description:\r
91\r
92 Add IsaKeyboard to ConIn,\r
93 add IsaSerial to ConOut, ConIn, ErrOut.\r
94 LPC Bridge: 06 01 00\r
95\r
96Arguments:\r
97\r
98 DeviceHandle - Handle of PCIIO protocol.\r
99\r
100Returns:\r
101\r
102 EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.\r
103 EFI_STATUS - No LPC bridge is added.\r
104\r
105--*/\r
106{\r
107 EFI_STATUS Status;\r
108 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
109 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
110 CHAR16 *DevPathStr;\r
111\r
112 DevicePath = NULL;\r
113 Status = gBS->HandleProtocol (\r
114 DeviceHandle,\r
115 &gEfiDevicePathProtocolGuid,\r
116 (VOID*)&DevicePath\r
117 );\r
118 if (EFI_ERROR (Status)) {\r
119 return Status;\r
120 }\r
121 TempDevicePath = DevicePath;\r
122\r
123 //\r
124 // Register COM1\r
125 // \r
126 DevicePath = AppendDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *)NULL, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceVenderNode);\r
127 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
128 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
129\r
130 //\r
131 // Print Device Path\r
132 //\r
133 DevPathStr = DevicePathToStr(DevicePath);\r
134 DEBUG((\r
135 EFI_D_INFO,\r
136 "BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
137 __LINE__,\r
138 gPnp16550ComPortDeviceNode.UID + 1,\r
139 DevPathStr\r
140 ));\r
141 FreePool(DevPathStr);\r
142\r
143 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
144 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
145 BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);\r
146\r
147 return EFI_SUCCESS;\r
148}\r
149\r
150EFI_STATUS\r
151GetGopDevicePath (\r
152 IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,\r
153 OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath\r
154 )\r
155{\r
156 UINTN Index;\r
157 EFI_STATUS Status;\r
158 EFI_HANDLE PciDeviceHandle;\r
159 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
160 EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath;\r
161 UINTN GopHandleCount;\r
162 EFI_HANDLE *GopHandleBuffer;\r
163\r
164 if (PciDevicePath == NULL || GopDevicePath == NULL) {\r
165 return EFI_INVALID_PARAMETER;\r
166 }\r
167\r
168 //\r
169 // Initialize the GopDevicePath to be PciDevicePath\r
170 //\r
171 *GopDevicePath = PciDevicePath;\r
172 TempPciDevicePath = PciDevicePath;\r
173\r
174 Status = gBS->LocateDevicePath (\r
175 &gEfiDevicePathProtocolGuid,\r
176 &TempPciDevicePath,\r
177 &PciDeviceHandle\r
178 );\r
179 if (EFI_ERROR (Status)) {\r
180 return Status;\r
181 }\r
182\r
183 //\r
184 // Try to connect this handle, so that GOP dirver could start on this\r
185 // device and create child handles with GraphicsOutput Protocol installed\r
186 // on them, then we get device paths of these child handles and select\r
187 // them as possible console device.\r
188 //\r
189#if 0\r
190 gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE);\r
191#else \r
192 {\r
193 ACPI_ADR_DEVICE_PATH AcpiAdr;\r
194 EFI_DEVICE_PATH_PROTOCOL *MyDevicePath = NULL; \r
195 \r
196 AcpiAdr.Header.Type = ACPI_DEVICE_PATH;\r
197 AcpiAdr.Header.SubType = ACPI_ADR_DP;\r
198 //AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 6, 0); //on bayleybay, CRT Device\r
199 AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, 8, 0); ; // on rambi, eDP C\r
200\r
201 SetDevicePathNodeLength (&AcpiAdr.Header, sizeof (ACPI_ADR_DEVICE_PATH));\r
202\r
203 MyDevicePath = AppendDevicePathNode(MyDevicePath, (EFI_DEVICE_PATH_PROTOCOL*)&AcpiAdr);\r
204\r
205 gBS->ConnectController (PciDeviceHandle, NULL, MyDevicePath, FALSE);\r
206 \r
207 FreePool(MyDevicePath);\r
208 }\r
209#endif\r
210\r
211 Status = gBS->LocateHandleBuffer (\r
212 ByProtocol,\r
213 &gEfiGraphicsOutputProtocolGuid,\r
214 NULL,\r
215 &GopHandleCount,\r
216 &GopHandleBuffer\r
217 );\r
218 if (!EFI_ERROR (Status)) {\r
219 //\r
220 // Add all the child handles as possible Console Device\r
221 //\r
222 for (Index = 0; Index < GopHandleCount; Index++) {\r
223 Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);\r
224 if (EFI_ERROR (Status)) {\r
225 continue;\r
226 }\r
227 if (CompareMem (\r
228 PciDevicePath,\r
229 TempDevicePath,\r
230 GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH\r
231 ) == 0) {\r
232 //\r
233 // In current implementation, we only enable one of the child handles\r
234 // as console device, i.e. sotre one of the child handle's device\r
235 // path to variable "ConOut"\r
236 // In futhure, we could select all child handles to be console device\r
237 //\r
238\r
239 *GopDevicePath = TempDevicePath;\r
240\r
241 //\r
242 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()\r
243 // Add the integrity GOP device path.\r
244 //\r
245 BdsLibUpdateConsoleVariable (VarConsoleOutDev, NULL, PciDevicePath);\r
246 BdsLibUpdateConsoleVariable (VarConsoleOutDev, TempDevicePath, NULL);\r
247 }\r
248 }\r
249 gBS->FreePool (GopHandleBuffer);\r
250 }\r
251\r
252 return EFI_SUCCESS;\r
253}\r
254\r
255EFI_STATUS\r
256PreparePciVgaDevicePath (\r
257 IN EFI_HANDLE DeviceHandle\r
258 )\r
259/*++\r
260\r
261Routine Description:\r
262\r
263 Add PCI VGA to ConOut.\r
264 PCI VGA: 03 00 00\r
265\r
266Arguments:\r
267\r
268 DeviceHandle - Handle of PCIIO protocol.\r
269\r
270Returns:\r
271\r
272 EFI_SUCCESS - PCI VGA is added to ConOut.\r
273 EFI_STATUS - No PCI VGA device is added.\r
274\r
275--*/\r
276{\r
277 EFI_STATUS Status;\r
278 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
279 EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;\r
280\r
281 DevicePath = NULL;\r
282 Status = gBS->HandleProtocol (\r
283 DeviceHandle,\r
284 &gEfiDevicePathProtocolGuid,\r
285 (VOID*)&DevicePath\r
286 );\r
287 if (EFI_ERROR (Status)) {\r
288 return Status;\r
289 }\r
290\r
291 GetGopDevicePath (DevicePath, &GopDevicePath);\r
292 DevicePath = GopDevicePath;\r
293\r
294 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
295\r
296 return EFI_SUCCESS;\r
297}\r
298\r
299EFI_STATUS\r
300PreparePciSerialDevicePath (\r
301 IN EFI_HANDLE DeviceHandle\r
302 )\r
303/*++\r
304\r
305Routine Description:\r
306\r
307 Add PCI Serial to ConOut, ConIn, ErrOut.\r
308 PCI Serial: 07 00 02\r
309\r
310Arguments:\r
311\r
312 DeviceHandle - Handle of PCIIO protocol.\r
313\r
314Returns:\r
315\r
316 EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.\r
317 EFI_STATUS - No PCI Serial device is added.\r
318\r
319--*/\r
320{\r
321 EFI_STATUS Status;\r
322 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
323\r
324 DevicePath = NULL;\r
325 Status = gBS->HandleProtocol (\r
326 DeviceHandle,\r
327 &gEfiDevicePathProtocolGuid,\r
328 (VOID*)&DevicePath\r
329 );\r
330 if (EFI_ERROR (Status)) {\r
331 return Status;\r
332 }\r
333\r
334 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
335 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
336\r
337 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
338 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
339 BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);\r
340\r
341 return EFI_SUCCESS;\r
342}\r
343\r
344EFI_STATUS\r
345VisitAllInstancesOfProtocol (\r
346 IN EFI_GUID *Id,\r
347 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction,\r
348 IN VOID *Context\r
349 )\r
350{\r
351 EFI_STATUS Status;\r
352 UINTN HandleCount;\r
353 EFI_HANDLE *HandleBuffer;\r
354 UINTN Index;\r
355 VOID *Instance;\r
356\r
357 //\r
358 // Start to check all the PciIo to find all possible device\r
359 //\r
360 HandleCount = 0;\r
361 HandleBuffer = NULL;\r
362 Status = gBS->LocateHandleBuffer (\r
363 ByProtocol,\r
364 Id,\r
365 NULL,\r
366 &HandleCount,\r
367 &HandleBuffer\r
368 );\r
369 if (EFI_ERROR (Status)) {\r
370 return Status;\r
371 }\r
372\r
373 for (Index = 0; Index < HandleCount; Index++) {\r
374 Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance);\r
375 if (EFI_ERROR (Status)) {\r
376 continue;\r
377 }\r
378\r
379 Status = (*CallBackFunction) (\r
380 HandleBuffer[Index],\r
381 Instance,\r
382 Context\r
383 );\r
384 }\r
385\r
386 gBS->FreePool (HandleBuffer);\r
387\r
388 return EFI_SUCCESS;\r
389}\r
390\r
391\r
392EFI_STATUS\r
393EFIAPI\r
394VisitingAPciInstance (\r
395 IN EFI_HANDLE Handle,\r
396 IN VOID *Instance,\r
397 IN VOID *Context\r
398 )\r
399{\r
400 EFI_STATUS Status;\r
401 EFI_PCI_IO_PROTOCOL *PciIo;\r
402 PCI_TYPE00 Pci;\r
403\r
404 PciIo = (EFI_PCI_IO_PROTOCOL*) Instance;\r
405\r
406 //\r
407 // Check for all PCI device\r
408 //\r
409 Status = PciIo->Pci.Read (\r
410 PciIo,\r
411 EfiPciIoWidthUint32,\r
412 0,\r
413 sizeof (Pci) / sizeof (UINT32),\r
414 &Pci\r
415 );\r
416 if (EFI_ERROR (Status)) {\r
417 return Status;\r
418 }\r
419\r
420 return (*(VISIT_PCI_INSTANCE_CALLBACK)(UINTN) Context) (\r
421 Handle,\r
422 PciIo,\r
423 &Pci\r
424 );\r
425\r
426}\r
427\r
428\r
429\r
430EFI_STATUS\r
431VisitAllPciInstances (\r
432 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction\r
433 )\r
434{\r
435 return VisitAllInstancesOfProtocol (\r
436 &gEfiPciIoProtocolGuid,\r
437 VisitingAPciInstance,\r
438 (VOID*)(UINTN) CallBackFunction\r
439 );\r
440}\r
441\r
442\r
443/**\r
444 Do platform specific PCI Device check and add them to\r
445 ConOut, ConIn, ErrOut.\r
446\r
447 @param[in] Handle - Handle of PCI device instance\r
448 @param[in] PciIo - PCI IO protocol instance\r
449 @param[in] Pci - PCI Header register block\r
450\r
451 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
452 @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
453\r
454**/\r
455EFI_STATUS\r
456EFIAPI\r
457DetectAndPreparePlatformPciDevicePath (\r
458 IN EFI_HANDLE Handle,\r
459 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
460 IN PCI_TYPE00 *Pci\r
461 )\r
462{\r
463 EFI_STATUS Status;\r
464\r
465 Status = PciIo->Attributes (\r
466 PciIo,\r
467 EfiPciIoAttributeOperationEnable,\r
468 EFI_PCI_DEVICE_ENABLE,\r
469 NULL\r
470 );\r
471 ASSERT_EFI_ERROR (Status);\r
472\r
473 if (!mDetectVgaOnly) {\r
474 //\r
475 // Here we decide whether it is LPC Bridge\r
476 //\r
477 if ((IS_PCI_LPC (Pci)) ||\r
478 ((IS_PCI_ISA_PDECODE (Pci)) &&\r
479 (Pci->Hdr.VendorId == 0x8086) \r
480 )\r
481 ) {\r
482 //\r
483 // Add IsaKeyboard to ConIn,\r
484 // add IsaSerial to ConOut, ConIn, ErrOut\r
485 //\r
486 DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n"));\r
487 PrepareLpcBridgeDevicePath (Handle);\r
488 return EFI_SUCCESS;\r
489 }\r
490 //\r
491 // Here we decide which Serial device to enable in PCI bus\r
492 //\r
493 if (IS_PCI_16550SERIAL (Pci)) {\r
494 //\r
495 // Add them to ConOut, ConIn, ErrOut.\r
496 //\r
497 DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n"));\r
498 PreparePciSerialDevicePath (Handle);\r
499 return EFI_SUCCESS;\r
500 }\r
501 }\r
502\r
503 //\r
504 // Here we decide which VGA device to enable in PCI bus\r
505 //\r
506 if (IS_PCI_VGA (Pci)) {\r
507 //\r
508 // Add them to ConOut.\r
509 //\r
510 DEBUG ((EFI_D_INFO, "Found PCI VGA device\n"));\r
511 PreparePciVgaDevicePath (Handle);\r
512 return EFI_SUCCESS;\r
513 }\r
514\r
515 return Status;\r
516}\r
517\r
518\r
519/**\r
520 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
521\r
522 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.\r
523\r
524 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
525 @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
526\r
527**/\r
528EFI_STATUS\r
529DetectAndPreparePlatformPciDevicePaths (\r
530 BOOLEAN DetectVgaOnly\r
531 )\r
532{\r
533 mDetectVgaOnly = DetectVgaOnly;\r
534 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);\r
535}\r
536\r
537/**\r
538 Connect the predefined platform default console device. Always try to find\r
539 and enable the vga device if have.\r
540\r
541 @param PlatformConsole Predefined platform default console device array.\r
542\r
543 @retval EFI_SUCCESS Success connect at least one ConIn and ConOut\r
544 device, there must have one ConOut device is\r
545 active vga device.\r
546 @return Return the status of BdsLibConnectAllDefaultConsoles ()\r
547\r
548**/\r
549EFI_STATUS\r
550PlatformBdsConnectConsole (\r
551 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole\r
552 )\r
553{\r
554 EFI_STATUS Status;\r
555 UINTN Index;\r
556 EFI_DEVICE_PATH_PROTOCOL *VarConout;\r
557 EFI_DEVICE_PATH_PROTOCOL *VarConin;\r
558 UINTN DevicePathSize;\r
559\r
560 //\r
561 // Connect RootBridge\r
562 //\r
563 VarConout = BdsLibGetVariableAndSize (\r
564 VarConsoleOut,\r
565 &gEfiGlobalVariableGuid,\r
566 &DevicePathSize\r
567 );\r
568 VarConin = BdsLibGetVariableAndSize (\r
569 VarConsoleInp,\r
570 &gEfiGlobalVariableGuid,\r
571 &DevicePathSize\r
572 );\r
573\r
574 if (VarConout == NULL || VarConin == NULL) {\r
575 //\r
576 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
577 //\r
578 DetectAndPreparePlatformPciDevicePaths (FALSE);\r
579\r
580 //\r
581 // Have chance to connect the platform default console,\r
582 // the platform default console is the minimue device group\r
583 // the platform should support\r
584 //\r
585 for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {\r
586 //\r
587 // Update the console variable with the connect type\r
588 //\r
589 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
590 BdsLibUpdateConsoleVariable (VarConsoleInp, PlatformConsole[Index].DevicePath, NULL);\r
591 }\r
592 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
593 BdsLibUpdateConsoleVariable (VarConsoleOut, PlatformConsole[Index].DevicePath, NULL);\r
594 }\r
595 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
596 BdsLibUpdateConsoleVariable (VarErrorOut, PlatformConsole[Index].DevicePath, NULL);\r
597 }\r
598 }\r
599 } else {\r
600 //\r
601 // Only detect VGA device and add them to ConOut\r
602 //\r
603 DetectAndPreparePlatformPciDevicePaths (TRUE);\r
604 }\r
605\r
606 //\r
607 // Connect the all the default console with current cosole variable\r
608 //\r
609 Status = BdsLibConnectAllDefaultConsoles ();\r
610 if (EFI_ERROR (Status)) {\r
611 return Status;\r
612 }\r
613\r
614 return EFI_SUCCESS;\r
615}\r
616\r
617/**\r
618 Connect with predefined platform connect sequence,\r
619 the OEM/IBV can customize with their own connect sequence.\r
620**/\r
621VOID\r
622PlatformBdsConnectSequence (\r
623 VOID\r
624 )\r
625{\r
626 UINTN Index;\r
627 \r
628 DEBUG ((EFI_D_INFO, "PlatformBdsConnectSequence\n"));\r
629 Index = 0;\r
630\r
631 //\r
632 // Here we can get the customized platform connect sequence\r
633 // Notes: we can connect with new variable which record the\r
634 // last time boots connect device path sequence\r
635 //\r
636 while (gPlatformConnectSequence[Index] != NULL) {\r
637 //\r
638 // Build the platform boot option\r
639 //\r
640 BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);\r
641 Index++;\r
642 }\r
643}\r
644\r
645/**\r
646 Load the predefined driver option, OEM/IBV can customize this\r
647 to load their own drivers\r
648\r
649 @param BdsDriverLists - The header of the driver option link list.\r
650\r
651**/\r
652VOID\r
653PlatformBdsGetDriverOption (\r
654 IN OUT LIST_ENTRY *BdsDriverLists\r
655 )\r
656{\r
657 UINTN Index;\r
658 \r
659 Index = 0;\r
660 \r
661 DEBUG ((EFI_D_INFO, "PlatformBdsGetDriverOption\n"));\r
662\r
663 \r
664 //\r
665 // Here we can get the customized platform driver option\r
666 //\r
667 while (gPlatformDriverOption[Index] != NULL) {\r
668\r
669 //\r
670 // Build the platform boot option\r
671 //\r
672 BdsLibRegisterNewOption (BdsDriverLists, gPlatformDriverOption[Index], NULL, L"DriverOrder");\r
673 Index ++;\r
674 }\r
675}\r
676\r
677/**\r
678 Perform the platform diagnostic, such like test memory. OEM/IBV also\r
679 can customize this function to support specific platform diagnostic.\r
680\r
681 @param MemoryTestLevel The memory test intensive level\r
682 @param QuietBoot Indicate if need to enable the quiet boot\r
683 @param BaseMemoryTest A pointer to BdsMemoryTest()\r
684\r
685**/\r
686VOID\r
687PlatformBdsDiagnostics (\r
688 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,\r
689 IN BOOLEAN QuietBoot,\r
690 IN BASEM_MEMORY_TEST BaseMemoryTest\r
691 )\r
692{\r
693 EFI_STATUS Status;\r
694 \r
695 DEBUG ((EFI_D_INFO, "PlatformBdsDiagnostics\n"));\r
696 //\r
697 // Here we can decide if we need to show\r
698 // the diagnostics screen\r
699 // Notes: this quiet boot code should be remove\r
700 // from the graphic lib\r
701 //\r
702 if (QuietBoot) {\r
703 EnableQuietBoot (PcdGetPtr(PcdLogoFile));\r
704\r
705 //\r
706 // Perform system diagnostic\r
707 //\r
708 Status = BaseMemoryTest (MemoryTestLevel);\r
709 if (EFI_ERROR (Status)) {\r
710 DisableQuietBoot ();\r
711 }\r
712\r
713 return;\r
714 }\r
715 \r
716 //\r
717 // Perform system diagnostic\r
718 //\r
719 Status = BaseMemoryTest (MemoryTestLevel);\r
720}\r
721\r
722\r
723/**\r
724 The function will connect root bridge\r
725\r
726 @return EFI_SUCCESS Connect RootBridge successfully.\r
727\r
728**/\r
729EFI_STATUS\r
730ConnectRootBridge (\r
731 VOID\r
732 )\r
733{\r
734 EFI_STATUS Status;\r
735 EFI_HANDLE RootHandle;\r
736\r
737 //\r
738 // Make all the PCI_IO protocols on PCI Seg 0 show up\r
739 //\r
740 BdsLibConnectDevicePath (gPlatformRootBridges[0]);\r
741\r
742 Status = gBS->LocateDevicePath (\r
743 &gEfiDevicePathProtocolGuid,\r
744 &gPlatformRootBridges[0],\r
745 &RootHandle\r
746 );\r
747 if (EFI_ERROR (Status)) {\r
748 return Status;\r
749 }\r
750\r
751 Status = gBS->ConnectController (RootHandle, NULL, NULL, FALSE);\r
752 if (EFI_ERROR (Status)) {\r
753 return Status;\r
754 }\r
755\r
756 return EFI_SUCCESS;\r
757}\r
758\r
759/**\r
760 The function will execute with as the platform policy, current policy\r
761 is driven by boot mode. IBV/OEM can customize this code for their specific\r
762 policy action.\r
763\r
764 @param DriverOptionList The header of the driver option link list\r
765 @param BootOptionList The header of the boot option link list\r
766 @param ProcessCapsules A pointer to ProcessCapsules()\r
767 @param BaseMemoryTest A pointer to BaseMemoryTest()\r
768\r
769**/\r
770VOID\r
771EFIAPI\r
772PlatformBdsPolicyBehavior (\r
773 IN LIST_ENTRY *DriverOptionList,\r
774 IN LIST_ENTRY *BootOptionList,\r
775 IN PROCESS_CAPSULES ProcessCapsules,\r
776 IN BASEM_MEMORY_TEST BaseMemoryTest\r
777 )\r
778{\r
779 EFI_STATUS Status;\r
780 UINT16 Timeout;\r
781 EFI_EVENT UserInputDurationTime;\r
782 LIST_ENTRY *Link;\r
783 BDS_COMMON_OPTION *BootOption;\r
784 UINTN Index;\r
785 EFI_INPUT_KEY Key;\r
786 EFI_TPL OldTpl;\r
787 EFI_BOOT_MODE BootMode;\r
788\r
789 DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior\n"));\r
790 \r
791 ConnectRootBridge ();\r
792\r
793 //\r
794 // Init the time out value\r
795 //\r
796 Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
797\r
798 //\r
799 // Load the driver option as the driver option list\r
800 //\r
801 PlatformBdsGetDriverOption (DriverOptionList);\r
802\r
803 //\r
804 // Get current Boot Mode\r
805 //\r
806 Status = BdsLibGetBootMode (&BootMode);\r
807 DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));\r
808\r
809 //\r
810 // Go the different platform policy with different boot mode\r
811 // Notes: this part code can be change with the table policy\r
812 //\r
813 ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);\r
814 //\r
815 // Connect platform console\r
816 //\r
817 Status = PlatformBdsConnectConsole (gPlatformConsole);\r
818 if (EFI_ERROR (Status)) {\r
819 //\r
820 // Here OEM/IBV can customize with defined action\r
821 //\r
822 PlatformBdsNoConsoleAction ();\r
823 }\r
824 //\r
825 // Create a 300ms duration event to ensure user has enough input time to enter Setup\r
826 //\r
827 Status = gBS->CreateEvent (\r
828 EVT_TIMER,\r
829 0,\r
830 NULL,\r
831 NULL,\r
832 &UserInputDurationTime\r
833 );\r
834 ASSERT (Status == EFI_SUCCESS);\r
835 Status = gBS->SetTimer (UserInputDurationTime, TimerRelative, 3000000);\r
836 ASSERT (Status == EFI_SUCCESS);\r
837 //\r
838 // Memory test and Logo show\r
839 //\r
840 PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);\r
841\r
842 //\r
843 // Perform some platform specific connect sequence\r
844 //\r
845 PlatformBdsConnectSequence ();\r
846\r
847 //\r
848 // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device\r
849 // and do enumerate all the default boot options. But in development system board, the boot mode\r
850 // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box\r
851 // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.\r
852 //\r
853 Status = BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
854 if (EFI_ERROR(Status)) {\r
855 //\r
856 // If cannot find "BootOrder" variable, it may be first boot.\r
857 // Try to connect all devices and enumerate all boot options here.\r
858 //\r
859 BdsLibConnectAll ();\r
860 BdsLibEnumerateAllBootOption (BootOptionList);\r
861 }\r
862\r
863 //\r
864 // To give the User a chance to enter Setup here, if user set TimeOut is 0.\r
865 // BDS should still give user a chance to enter Setup\r
866 //\r
867 // Connect first boot option, and then check user input before exit\r
868 //\r
869 for (Link = BootOptionList->ForwardLink; Link != BootOptionList;Link = Link->ForwardLink) {\r
870 BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
871 if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {\r
872 //\r
873 // skip the header of the link list, becuase it has no boot option\r
874 //\r
875 continue;\r
876 } else {\r
877 //\r
878 // Make sure the boot option device path connected, but ignore the BBS device path\r
879 //\r
880 if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {\r
881 BdsLibConnectDevicePath (BootOption->DevicePath);\r
882 }\r
883 break;\r
884 }\r
885 }\r
886\r
887 //\r
888 // Check whether the user input after the duration time has expired\r
889 //\r
890 OldTpl = EfiGetCurrentTpl();\r
891 gBS->RestoreTPL (TPL_APPLICATION);\r
892 gBS->WaitForEvent (1, &UserInputDurationTime, &Index);\r
893 gBS->CloseEvent (UserInputDurationTime);\r
894 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
895 gBS->RaiseTPL (OldTpl);\r
896\r
897 if (!EFI_ERROR (Status)) {\r
898 //\r
899 // Enter Setup if user input\r
900 //\r
901 Timeout = 0xffff;\r
902 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
903 }\r
904}\r
905\r
906/**\r
907 Hook point after a boot attempt succeeds. We don't expect a boot option to\r
908 return, so the UEFI 2.0 specification defines that you will default to an\r
909 interactive mode and stop processing the BootOrder list in this case. This\r
910 is also a platform implementation and can be customized by IBV/OEM.\r
911\r
912 @param Option Pointer to Boot Option that succeeded to boot.\r
913\r
914**/\r
915VOID\r
916EFIAPI\r
917PlatformBdsBootSuccess (\r
918 IN BDS_COMMON_OPTION *Option\r
919 )\r
920{\r
921 CHAR16 *TmpStr;\r
922 DEBUG ((EFI_D_INFO, "PlatformBdsBootSuccess\n"));\r
923 \r
924 //\r
925 // If Boot returned with EFI_SUCCESS and there is not in the boot device\r
926 // select loop then we need to pop up a UI and wait for user input.\r
927 //\r
928 TmpStr = Option->StatusString;\r
929 if (TmpStr != NULL) {\r
930 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
931 FreePool (TmpStr);\r
932 }\r
933}\r
934\r
935/**\r
936 Hook point after a boot attempt fails.\r
937\r
938 @param Option Pointer to Boot Option that failed to boot.\r
939 @param Status Status returned from failed boot.\r
940 @param ExitData Exit data returned from failed boot.\r
941 @param ExitDataSize Exit data size returned from failed boot.\r
942\r
943**/\r
944VOID\r
945EFIAPI\r
946PlatformBdsBootFail (\r
947 IN BDS_COMMON_OPTION *Option,\r
948 IN EFI_STATUS Status,\r
949 IN CHAR16 *ExitData,\r
950 IN UINTN ExitDataSize\r
951 )\r
952{\r
953 CHAR16 *TmpStr;\r
954 DEBUG ((EFI_D_INFO, "PlatformBdsBootFail\n"));\r
955\r
956 //\r
957 // If Boot returned with failed status then we need to pop up a UI and wait\r
958 // for user input.\r
959 //\r
960 TmpStr = Option->StatusString;\r
961 if (TmpStr != NULL) {\r
962 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
963 FreePool (TmpStr);\r
964 }\r
965}\r
966\r
967/**\r
968 This function is remained for IBV/OEM to do some platform action,\r
969 if there no console device can be connected.\r
970\r
971 @return EFI_SUCCESS Direct return success now.\r
972\r
973**/\r
974EFI_STATUS\r
975PlatformBdsNoConsoleAction (\r
976 VOID\r
977 )\r
978{\r
979 DEBUG ((EFI_D_INFO, "PlatformBdsNoConsoleAction\n"));\r
980 return EFI_SUCCESS;\r
981}\r
982\r
983/**\r
984 This function locks platform flash that is not allowed to be updated during normal boot path.\r
985 The flash layout is platform specific.\r
986**/\r
987VOID\r
988EFIAPI\r
989PlatformBdsLockNonUpdatableFlash (\r
990 VOID\r
991 )\r
992{\r
993 DEBUG ((EFI_D_INFO, "PlatformBdsLockNonUpdatableFlash\n"));\r
994 return ;\r
995}\r
996\r
997\r
998/**\r
999 Lock the ConsoleIn device in system table. All key\r
1000 presses will be ignored until the Password is typed in. The only way to\r
1001 disable the password is to type it in to a ConIn device.\r
1002\r
1003 @param Password Password used to lock ConIn device.\r
1004\r
1005 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.\r
1006 @retval EFI_UNSUPPORTED Password not found\r
1007\r
1008**/\r
1009EFI_STATUS\r
1010EFIAPI\r
1011LockKeyboards (\r
1012 IN CHAR16 *Password\r
1013 )\r
1014{\r
1015 return EFI_UNSUPPORTED;\r
1016}\r