2 Platform BDS customizations.
4 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "BdsPlatform.h"
16 #include "QemuBootOrder.h"
23 VOID
*mEfiDevPathNotifyReg
;
24 EFI_EVENT mEfiDevPathEvent
;
25 VOID
*mEmuVariableEventReg
;
26 EFI_EVENT mEmuVariableEvent
;
27 BOOLEAN mDetectVgaOnly
;
36 (EFIAPI
*PROTOCOL_INSTANCE_CALLBACK
)(
43 @param[in] Handle - Handle of PCI device instance
44 @param[in] PciIo - PCI IO protocol instance
45 @param[in] Pci - PCI Header register block
49 (EFIAPI
*VISIT_PCI_INSTANCE_CALLBACK
)(
51 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
57 // Function prototypes
61 VisitAllInstancesOfProtocol (
63 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
68 VisitAllPciInstancesOfProtocol (
69 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
73 InstallDevicePathCallback (
78 // BDS Platform Functions
89 Platform Bds init. Incude the platform firmware vendor, revision
100 DEBUG ((EFI_D_INFO
, "PlatformBdsInit\n"));
101 InstallDevicePathCallback ();
121 EFI_SUCCESS - Connect RootBridge successfully.
122 EFI_STATUS - Connect RootBridge fail.
127 EFI_HANDLE RootHandle
;
130 // Make all the PCI_IO protocols on PCI Seg 0 show up
132 BdsLibConnectDevicePath (gPlatformRootBridges
[0]);
134 Status
= gBS
->LocateDevicePath (
135 &gEfiDevicePathProtocolGuid
,
136 &gPlatformRootBridges
[0],
139 if (EFI_ERROR (Status
)) {
143 Status
= gBS
->ConnectController (RootHandle
, NULL
, NULL
, FALSE
);
144 if (EFI_ERROR (Status
)) {
153 PrepareLpcBridgeDevicePath (
154 IN EFI_HANDLE DeviceHandle
160 Add IsaKeyboard to ConIn,
161 add IsaSerial to ConOut, ConIn, ErrOut.
166 DeviceHandle - Handle of PCIIO protocol.
170 EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.
171 EFI_STATUS - No LPC bridge is added.
176 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
177 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
181 Status
= gBS
->HandleProtocol (
183 &gEfiDevicePathProtocolGuid
,
186 if (EFI_ERROR (Status
)) {
189 TempDevicePath
= DevicePath
;
194 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnpPs2KeyboardDeviceNode
);
196 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
201 DevicePath
= TempDevicePath
;
202 gPnp16550ComPortDeviceNode
.UID
= 0;
204 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
205 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
206 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
211 DevPathStr
= DevicePathToStr(DevicePath
);
212 if (DevPathStr
!= NULL
) {
215 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
217 gPnp16550ComPortDeviceNode
.UID
+ 1,
220 FreePool(DevPathStr
);
223 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
224 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
225 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
230 DevicePath
= TempDevicePath
;
231 gPnp16550ComPortDeviceNode
.UID
= 1;
233 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
234 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
235 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
240 DevPathStr
= DevicePathToStr(DevicePath
);
241 if (DevPathStr
!= NULL
) {
244 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
246 gPnp16550ComPortDeviceNode
.UID
+ 1,
249 FreePool(DevPathStr
);
252 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
253 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
254 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
261 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
262 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
267 EFI_HANDLE PciDeviceHandle
;
268 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
269 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
270 UINTN GopHandleCount
;
271 EFI_HANDLE
*GopHandleBuffer
;
273 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
274 return EFI_INVALID_PARAMETER
;
278 // Initialize the GopDevicePath to be PciDevicePath
280 *GopDevicePath
= PciDevicePath
;
281 TempPciDevicePath
= PciDevicePath
;
283 Status
= gBS
->LocateDevicePath (
284 &gEfiDevicePathProtocolGuid
,
288 if (EFI_ERROR (Status
)) {
293 // Try to connect this handle, so that GOP dirver could start on this
294 // device and create child handles with GraphicsOutput Protocol installed
295 // on them, then we get device paths of these child handles and select
296 // them as possible console device.
298 gBS
->ConnectController (PciDeviceHandle
, NULL
, NULL
, FALSE
);
300 Status
= gBS
->LocateHandleBuffer (
302 &gEfiGraphicsOutputProtocolGuid
,
307 if (!EFI_ERROR (Status
)) {
309 // Add all the child handles as possible Console Device
311 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
312 Status
= gBS
->HandleProtocol (GopHandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*)&TempDevicePath
);
313 if (EFI_ERROR (Status
)) {
319 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
322 // In current implementation, we only enable one of the child handles
323 // as console device, i.e. sotre one of the child handle's device
324 // path to variable "ConOut"
325 // In futhure, we could select all child handles to be console device
328 *GopDevicePath
= TempDevicePath
;
331 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
332 // Add the integrity GOP device path.
334 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, NULL
, PciDevicePath
);
335 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, TempDevicePath
, NULL
);
338 gBS
->FreePool (GopHandleBuffer
);
345 PreparePciVgaDevicePath (
346 IN EFI_HANDLE DeviceHandle
352 Add PCI VGA to ConOut.
357 DeviceHandle - Handle of PCIIO protocol.
361 EFI_SUCCESS - PCI VGA is added to ConOut.
362 EFI_STATUS - No PCI VGA device is added.
367 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
368 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
371 GopDevicePath
= NULL
;
372 Status
= gBS
->HandleProtocol (
374 &gEfiDevicePathProtocolGuid
,
377 if (EFI_ERROR (Status
)) {
381 GetGopDevicePath (DevicePath
, &GopDevicePath
);
382 DevicePath
= GopDevicePath
;
384 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
390 PreparePciSerialDevicePath (
391 IN EFI_HANDLE DeviceHandle
397 Add PCI Serial to ConOut, ConIn, ErrOut.
402 DeviceHandle - Handle of PCIIO protocol.
406 EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
407 EFI_STATUS - No PCI Serial device is added.
412 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
415 Status
= gBS
->HandleProtocol (
417 &gEfiDevicePathProtocolGuid
,
420 if (EFI_ERROR (Status
)) {
424 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
425 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
427 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
428 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
429 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
435 VisitAllInstancesOfProtocol (
437 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
443 EFI_HANDLE
*HandleBuffer
;
448 // Start to check all the PciIo to find all possible device
452 Status
= gBS
->LocateHandleBuffer (
459 if (EFI_ERROR (Status
)) {
463 for (Index
= 0; Index
< HandleCount
; Index
++) {
464 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], Id
, &Instance
);
465 if (EFI_ERROR (Status
)) {
469 Status
= (*CallBackFunction
) (
476 gBS
->FreePool (HandleBuffer
);
484 VisitingAPciInstance (
485 IN EFI_HANDLE Handle
,
491 EFI_PCI_IO_PROTOCOL
*PciIo
;
494 PciIo
= (EFI_PCI_IO_PROTOCOL
*) Instance
;
497 // Check for all PCI device
499 Status
= PciIo
->Pci
.Read (
503 sizeof (Pci
) / sizeof (UINT32
),
506 if (EFI_ERROR (Status
)) {
510 return (*(VISIT_PCI_INSTANCE_CALLBACK
)(UINTN
) Context
) (
521 VisitAllPciInstances (
522 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
525 return VisitAllInstancesOfProtocol (
526 &gEfiPciIoProtocolGuid
,
527 VisitingAPciInstance
,
528 (VOID
*)(UINTN
) CallBackFunction
534 Do platform specific PCI Device check and add them to
535 ConOut, ConIn, ErrOut.
537 @param[in] Handle - Handle of PCI device instance
538 @param[in] PciIo - PCI IO protocol instance
539 @param[in] Pci - PCI Header register block
541 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
542 @retval EFI_STATUS - PCI Device check or Console variable update fail.
547 DetectAndPreparePlatformPciDevicePath (
548 IN EFI_HANDLE Handle
,
549 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
555 Status
= PciIo
->Attributes (
557 EfiPciIoAttributeOperationEnable
,
558 EFI_PCI_DEVICE_ENABLE
,
561 ASSERT_EFI_ERROR (Status
);
563 if (!mDetectVgaOnly
) {
565 // Here we decide whether it is LPC Bridge
567 if ((IS_PCI_LPC (Pci
)) ||
568 ((IS_PCI_ISA_PDECODE (Pci
)) &&
569 (Pci
->Hdr
.VendorId
== 0x8086) &&
570 (Pci
->Hdr
.DeviceId
== 0x7000)
574 // Add IsaKeyboard to ConIn,
575 // add IsaSerial to ConOut, ConIn, ErrOut
577 DEBUG ((EFI_D_INFO
, "Found LPC Bridge device\n"));
578 PrepareLpcBridgeDevicePath (Handle
);
582 // Here we decide which Serial device to enable in PCI bus
584 if (IS_PCI_16550SERIAL (Pci
)) {
586 // Add them to ConOut, ConIn, ErrOut.
588 DEBUG ((EFI_D_INFO
, "Found PCI 16550 SERIAL device\n"));
589 PreparePciSerialDevicePath (Handle
);
595 // Here we decide which VGA device to enable in PCI bus
597 if (IS_PCI_VGA (Pci
)) {
599 // Add them to ConOut.
601 DEBUG ((EFI_D_INFO
, "Found PCI VGA device\n"));
602 PreparePciVgaDevicePath (Handle
);
611 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
613 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
615 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
616 @retval EFI_STATUS - PCI Device check or Console variable update fail.
620 DetectAndPreparePlatformPciDevicePaths (
621 BOOLEAN DetectVgaOnly
624 mDetectVgaOnly
= DetectVgaOnly
;
625 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath
);
630 PlatformBdsConnectConsole (
631 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
637 Connect the predefined platform default console device. Always try to find
638 and enable the vga device if have.
642 PlatformConsole - Predfined platform default console device array.
646 EFI_SUCCESS - Success connect at least one ConIn and ConOut
647 device, there must have one ConOut device is
650 EFI_STATUS - Return the status of
651 BdsLibConnectAllDefaultConsoles ()
657 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
658 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
659 UINTN DevicePathSize
;
662 // Connect RootBridge
664 VarConout
= BdsLibGetVariableAndSize (
666 &gEfiGlobalVariableGuid
,
669 VarConin
= BdsLibGetVariableAndSize (
671 &gEfiGlobalVariableGuid
,
675 if (VarConout
== NULL
|| VarConin
== NULL
) {
677 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
679 DetectAndPreparePlatformPciDevicePaths (FALSE
);
682 // Have chance to connect the platform default console,
683 // the platform default console is the minimue device group
684 // the platform should support
686 for (Index
= 0; PlatformConsole
[Index
].DevicePath
!= NULL
; ++Index
) {
688 // Update the console variable with the connect type
690 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
691 BdsLibUpdateConsoleVariable (VarConsoleInp
, PlatformConsole
[Index
].DevicePath
, NULL
);
693 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
694 BdsLibUpdateConsoleVariable (VarConsoleOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
696 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
697 BdsLibUpdateConsoleVariable (VarErrorOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
702 // Only detect VGA device and add them to ConOut
704 DetectAndPreparePlatformPciDevicePaths (TRUE
);
708 // Connect the all the default console with current cosole variable
710 Status
= BdsLibConnectAllDefaultConsoles ();
711 if (EFI_ERROR (Status
)) {
720 PciAcpiInitialization (
723 UINT16 HostBridgeDevId
;
727 // Query Host Bridge DID to determine platform type
729 HostBridgeDevId
= PcdGet16 (PcdOvmfHostBridgePciDevId
);
730 switch (HostBridgeDevId
) {
731 case INTEL_82441_DEVICE_ID
:
732 Pmba
= POWER_MGMT_REGISTER_PIIX4 (0x40);
734 // 00:01.0 ISA Bridge (PIIX4) LNK routing targets
736 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // A
737 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // B
738 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // C
739 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // D
741 case INTEL_Q35_MCH_DEVICE_ID
:
742 Pmba
= POWER_MGMT_REGISTER_Q35 (0x40);
744 // 00:1f.0 LPC Bridge (Q35) LNK routing targets
746 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), 0x0a); // A
747 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), 0x0a); // B
748 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), 0x0b); // C
749 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), 0x0b); // D
750 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), 0x0a); // E
751 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), 0x0a); // F
752 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G
753 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H
756 DEBUG ((EFI_D_ERROR
, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
757 __FUNCTION__
, HostBridgeDevId
));
763 // Set ACPI SCI_EN bit in PMCNTRL
765 IoOr16 ((PciRead32 (Pmba
) & ~BIT0
) + 4, BIT0
);
768 // Initialize PCI_INTERRUPT_LINE for commonly encountered devices and slots
770 // FIXME: This should instead be accomplished programmatically by
771 // ennumerating all PCI devices present in the system and
772 // computing PCI_INTERRUPT_LINE from PCI_INTERRUPT_PIN, the
773 // slot/position of the device, and the available host IRQs
774 // (for an example, see SeaBIOS pci_bios_init_devices() in
777 switch (HostBridgeDevId
) {
778 case INTEL_82441_DEVICE_ID
:
779 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 2, 0x3c), 0x0b); // usb (northbr.)
780 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3c), 0x0a); // acpi (northbr.)
781 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0b);
782 PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3c), 0x0b);
783 PciWrite8 (PCI_LIB_ADDRESS (0, 5, 0, 0x3c), 0x0a);
784 PciWrite8 (PCI_LIB_ADDRESS (0, 6, 0, 0x3c), 0x0a);
785 PciWrite8 (PCI_LIB_ADDRESS (0, 7, 0, 0x3c), 0x0b);
786 PciWrite8 (PCI_LIB_ADDRESS (0, 8, 0, 0x3c), 0x0b);
788 case INTEL_Q35_MCH_DEVICE_ID
:
789 PciWrite8 (PCI_LIB_ADDRESS (0, 2, 0, 0x3c), 0x0b);
790 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0b);
791 PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3c), 0x0a);
792 PciWrite8 (PCI_LIB_ADDRESS (0, 5, 0, 0x3c), 0x0a);
793 PciWrite8 (PCI_LIB_ADDRESS (0, 6, 0, 0x3c), 0x0b);
794 PciWrite8 (PCI_LIB_ADDRESS (0, 7, 0, 0x3c), 0x0b);
795 PciWrite8 (PCI_LIB_ADDRESS (0, 8, 0, 0x3c), 0x0a);
796 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1d, 0, 0x3c), 0x0a); // uhci1
797 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1d, 1, 0x3c), 0x0a); // uhci2
798 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1d, 2, 0x3c), 0x0b); // uhci3
799 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1d, 7, 0x3c), 0x0b); // ehci1
800 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 2, 0x3c), 0x0a); // ahci (northbr.)
801 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 3, 0x3c), 0x0a); // smbus (northbr.)
804 ASSERT (FALSE
); // should never be reached
811 ConnectRecursivelyIfPciMassStorage (
812 IN EFI_HANDLE Handle
,
813 IN EFI_PCI_IO_PROTOCOL
*Instance
,
814 IN PCI_TYPE00
*PciHeader
818 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
821 if (IS_CLASS1 (PciHeader
, PCI_CLASS_MASS_STORAGE
)) {
823 Status
= gBS
->HandleProtocol (
825 &gEfiDevicePathProtocolGuid
,
828 if (EFI_ERROR (Status
)) {
835 DevPathStr
= DevicePathToStr (DevicePath
);
836 if (DevPathStr
!= NULL
) {
839 "Found Mass Storage device: %s\n",
842 FreePool(DevPathStr
);
845 Status
= gBS
->ConnectController (Handle
, NULL
, NULL
, TRUE
);
846 if (EFI_ERROR (Status
)) {
857 This notification function is invoked when the
858 EMU Variable FVB has been changed.
860 @param Event The event that occured
861 @param Context For EFI compatiblity. Not used.
866 EmuVariablesUpdatedCallback (
871 DEBUG ((EFI_D_INFO
, "EmuVariablesUpdatedCallback\n"));
872 UpdateNvVarsOnFileSystem ();
878 VisitingFileSystemInstance (
879 IN EFI_HANDLE Handle
,
885 STATIC BOOLEAN ConnectedToFileSystem
= FALSE
;
887 if (ConnectedToFileSystem
) {
888 return EFI_ALREADY_STARTED
;
891 Status
= ConnectNvVarsToFileSystem (Handle
);
892 if (EFI_ERROR (Status
)) {
896 ConnectedToFileSystem
= TRUE
;
898 EfiCreateProtocolNotifyEvent (
899 &gEfiDevicePathProtocolGuid
,
901 EmuVariablesUpdatedCallback
,
903 &mEmuVariableEventReg
905 PcdSet64 (PcdEmuVariableEvent
, (UINT64
)(UINTN
) mEmuVariableEvent
);
912 PlatformBdsRestoreNvVarsFromHardDisk (
915 VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage
);
916 VisitAllInstancesOfProtocol (
917 &gEfiSimpleFileSystemProtocolGuid
,
918 VisitingFileSystemInstance
,
926 PlatformBdsConnectSequence (
933 Connect with predeined platform connect sequence,
934 the OEM/IBV can customize with their own connect sequence.
948 DEBUG ((EFI_D_INFO
, "PlatformBdsConnectSequence\n"));
953 // Here we can get the customized platform connect sequence
954 // Notes: we can connect with new variable which record the
955 // last time boots connect device path sequence
957 while (gPlatformConnectSequence
[Index
] != NULL
) {
959 // Build the platform boot option
961 BdsLibConnectDevicePath (gPlatformConnectSequence
[Index
]);
966 // Just use the simple policy to connect all devices
970 PciAcpiInitialization ();
973 // Clear the logo after all devices are connected.
975 gST
->ConOut
->ClearScreen (gST
->ConOut
);
979 PlatformBdsGetDriverOption (
980 IN OUT LIST_ENTRY
*BdsDriverLists
986 Load the predefined driver option, OEM/IBV can customize this
987 to load their own drivers
991 BdsDriverLists - The header of the driver option link list.
999 DEBUG ((EFI_D_INFO
, "PlatformBdsGetDriverOption\n"));
1004 PlatformBdsDiagnostics (
1005 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
1006 IN BOOLEAN QuietBoot
,
1007 IN BASEM_MEMORY_TEST BaseMemoryTest
1011 Routine Description:
1013 Perform the platform diagnostic, such like test memory. OEM/IBV also
1014 can customize this fuction to support specific platform diagnostic.
1018 MemoryTestLevel - The memory test intensive level
1020 QuietBoot - Indicate if need to enable the quiet boot
1022 BaseMemoryTest - A pointer to BaseMemoryTest()
1032 DEBUG ((EFI_D_INFO
, "PlatformBdsDiagnostics\n"));
1035 // Here we can decide if we need to show
1036 // the diagnostics screen
1037 // Notes: this quiet boot code should be remove
1038 // from the graphic lib
1041 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
1043 // Perform system diagnostic
1045 Status
= BaseMemoryTest (MemoryTestLevel
);
1046 if (EFI_ERROR (Status
)) {
1047 DisableQuietBoot ();
1053 // Perform system diagnostic
1055 Status
= BaseMemoryTest (MemoryTestLevel
);
1061 PlatformBdsPolicyBehavior (
1062 IN OUT LIST_ENTRY
*DriverOptionList
,
1063 IN OUT LIST_ENTRY
*BootOptionList
,
1064 IN PROCESS_CAPSULES ProcessCapsules
,
1065 IN BASEM_MEMORY_TEST BaseMemoryTest
1069 Routine Description:
1071 The function will excute with as the platform policy, current policy
1072 is driven by boot mode. IBV/OEM can customize this code for their specific
1077 DriverOptionList - The header of the driver option link list
1079 BootOptionList - The header of the boot option link list
1081 ProcessCapsules - A pointer to ProcessCapsules()
1083 BaseMemoryTest - A pointer to BaseMemoryTest()
1093 EFI_BOOT_MODE BootMode
;
1095 DEBUG ((EFI_D_INFO
, "PlatformBdsPolicyBehavior\n"));
1097 ConnectRootBridge ();
1099 if (PcdGetBool (PcdOvmfFlashVariablesEnable
)) {
1100 DEBUG ((EFI_D_INFO
, "PlatformBdsPolicyBehavior: not restoring NvVars "
1101 "from disk since flash variables appear to be supported.\n"));
1104 // Try to restore variables from the hard disk early so
1105 // they can be used for the other BDS connect operations.
1107 PlatformBdsRestoreNvVarsFromHardDisk ();
1111 // Init the time out value
1113 Timeout
= PcdGet16 (PcdPlatformBootTimeOut
);
1116 // Load the driver option as the driver option list
1118 PlatformBdsGetDriverOption (DriverOptionList
);
1121 // Get current Boot Mode
1123 Status
= BdsLibGetBootMode (&BootMode
);
1124 DEBUG ((EFI_D_ERROR
, "Boot Mode:%x\n", BootMode
));
1127 // Go the different platform policy with different boot mode
1128 // Notes: this part code can be change with the table policy
1130 ASSERT (BootMode
== BOOT_WITH_FULL_CONFIGURATION
);
1132 // Connect platform console
1134 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
1135 if (EFI_ERROR (Status
)) {
1137 // Here OEM/IBV can customize with defined action
1139 PlatformBdsNoConsoleAction ();
1143 // Memory test and Logo show
1145 PlatformBdsDiagnostics (IGNORE
, TRUE
, BaseMemoryTest
);
1148 // Perform some platform specific connect sequence
1150 PlatformBdsConnectSequence ();
1153 // Process QEMU's -kernel command line option
1155 TryRunningQemuKernel ();
1157 DEBUG ((EFI_D_INFO
, "BdsLibConnectAll\n"));
1158 BdsLibConnectAll ();
1159 BdsLibEnumerateAllBootOption (BootOptionList
);
1161 SetBootOrderFromQemu (BootOptionList
);
1163 // The BootOrder variable may have changed, reload the in-memory list with
1166 BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
1168 PlatformBdsEnterFrontPage (Timeout
, TRUE
);
1173 PlatformBdsBootSuccess (
1174 IN BDS_COMMON_OPTION
*Option
1178 Routine Description:
1180 Hook point after a boot attempt succeeds. We don't expect a boot option to
1181 return, so the EFI 1.0 specification defines that you will default to an
1182 interactive mode and stop processing the BootOrder list in this case. This
1183 is alos a platform implementation and can be customized by IBV/OEM.
1187 Option - Pointer to Boot Option that succeeded to boot.
1197 DEBUG ((EFI_D_INFO
, "PlatformBdsBootSuccess\n"));
1199 // If Boot returned with EFI_SUCCESS and there is not in the boot device
1200 // select loop then we need to pop up a UI and wait for user input.
1202 TmpStr
= Option
->StatusString
;
1203 if (TmpStr
!= NULL
) {
1204 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1211 PlatformBdsBootFail (
1212 IN BDS_COMMON_OPTION
*Option
,
1213 IN EFI_STATUS Status
,
1214 IN CHAR16
*ExitData
,
1215 IN UINTN ExitDataSize
1219 Routine Description:
1221 Hook point after a boot attempt fails.
1225 Option - Pointer to Boot Option that failed to boot.
1227 Status - Status returned from failed boot.
1229 ExitData - Exit data returned from failed boot.
1231 ExitDataSize - Exit data size returned from failed boot.
1241 DEBUG ((EFI_D_INFO
, "PlatformBdsBootFail\n"));
1244 // If Boot returned with failed status then we need to pop up a UI and wait
1247 TmpStr
= Option
->StatusString
;
1248 if (TmpStr
!= NULL
) {
1249 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1255 PlatformBdsNoConsoleAction (
1260 Routine Description:
1262 This function is remained for IBV/OEM to do some platform action,
1263 if there no console device can be connected.
1271 EFI_SUCCESS - Direct return success now.
1275 DEBUG ((EFI_D_INFO
, "PlatformBdsNoConsoleAction\n"));
1281 PlatformBdsLockNonUpdatableFlash (
1285 DEBUG ((EFI_D_INFO
, "PlatformBdsLockNonUpdatableFlash\n"));
1291 This notification function is invoked when an instance of the
1292 EFI_DEVICE_PATH_PROTOCOL is produced.
1294 @param Event The event that occured
1295 @param Context For EFI compatiblity. Not used.
1308 EFI_DEVICE_PATH_PROTOCOL
*DevPathNode
;
1309 ATAPI_DEVICE_PATH
*Atapi
;
1312 // Examine all new handles
1316 // Get the next handle
1318 BufferSize
= sizeof (Handle
);
1319 Status
= gBS
->LocateHandle (
1322 mEfiDevPathNotifyReg
,
1328 // If not found, we're done
1330 if (EFI_NOT_FOUND
== Status
) {
1334 if (EFI_ERROR (Status
)) {
1339 // Get the DevicePath protocol on that handle
1341 Status
= gBS
->HandleProtocol (Handle
, &gEfiDevicePathProtocolGuid
, (VOID
**)&DevPathNode
);
1342 ASSERT_EFI_ERROR (Status
);
1344 while (!IsDevicePathEnd (DevPathNode
)) {
1346 // Find the handler to dump this device path node
1349 (DevicePathType(DevPathNode
) == MESSAGING_DEVICE_PATH
) &&
1350 (DevicePathSubType(DevPathNode
) == MSG_ATAPI_DP
)
1352 Atapi
= (ATAPI_DEVICE_PATH
*) DevPathNode
;
1358 (Atapi
->PrimarySecondary
== 1) ? 0x42: 0x40
1365 // Next device path node
1367 DevPathNode
= NextDevicePathNode (DevPathNode
);
1376 InstallDevicePathCallback (
1380 DEBUG ((EFI_D_INFO
, "Registered NotifyDevPath Event\n"));
1381 mEfiDevPathEvent
= EfiCreateProtocolNotifyEvent (
1382 &gEfiDevicePathProtocolGuid
,
1386 &mEfiDevPathNotifyReg
1391 Lock the ConsoleIn device in system table. All key
1392 presses will be ignored until the Password is typed in. The only way to
1393 disable the password is to type it in to a ConIn device.
1395 @param Password Password used to lock ConIn device.
1397 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
1398 @retval EFI_UNSUPPORTED Password not found
1407 return EFI_UNSUPPORTED
;