2 Platform BDS customizations.
4 Copyright (c) 2004 - 2008, Intel Corporation. <BR>
5 All rights reserved. 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"
22 VOID
*mEfiDevPathNotifyReg
;
23 EFI_EVENT mEfiDevPathEvent
;
24 BOOLEAN mDetectVgaOnly
;
33 (EFIAPI
*PROTOCOL_INSTANCE_CALLBACK
)(
40 @param[in] Handle - Handle of PCI device instance
41 @param[in] PciIo - PCI IO protocol instance
42 @param[in] Pci - PCI Header register block
46 (EFIAPI
*VISIT_PCI_INSTANCE_CALLBACK
)(
48 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
54 // Function prototypes
58 VisitAllInstancesOfProtocol (
60 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
65 VisitAllPciInstancesOfProtocol (
66 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
70 InstallDevicePathCallback (
82 PciRomLoadEfiDriversFromRomImage (
83 IN EFI_PHYSICAL_ADDRESS Rom
,
88 // BDS Platform Functions
99 Platform Bds init. Incude the platform firmware vendor, revision
110 DEBUG ((EFI_D_INFO
, "PlatformBdsInit\n"));
111 InstallDevicePathCallback ();
132 EFI_SUCCESS - Connect RootBridge successfully.
133 EFI_STATUS - Connect RootBridge fail.
138 EFI_HANDLE RootHandle
;
141 // Make all the PCI_IO protocols on PCI Seg 0 show up
143 BdsLibConnectDevicePath (gPlatformRootBridges
[0]);
145 Status
= gBS
->LocateDevicePath (
146 &gEfiDevicePathProtocolGuid
,
147 &gPlatformRootBridges
[0],
150 if (EFI_ERROR (Status
)) {
154 Status
= gBS
->ConnectController (RootHandle
, NULL
, NULL
, FALSE
);
155 if (EFI_ERROR (Status
)) {
164 PrepareLpcBridgeDevicePath (
165 IN EFI_HANDLE DeviceHandle
171 Add IsaKeyboard to ConIn,
172 add IsaSerial to ConOut, ConIn, ErrOut.
177 DeviceHandle - Handle of PCIIO protocol.
181 EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.
182 EFI_STATUS - No LPC bridge is added.
187 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
188 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
192 Status
= gBS
->HandleProtocol (
194 &gEfiDevicePathProtocolGuid
,
197 if (EFI_ERROR (Status
)) {
200 TempDevicePath
= DevicePath
;
205 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnpPs2KeyboardDeviceNode
);
207 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
212 DevicePath
= TempDevicePath
;
213 gPnp16550ComPortDeviceNode
.UID
= 0;
215 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
216 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
217 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
222 DevPathStr
= DevicePathToStr(DevicePath
);
225 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
227 gPnp16550ComPortDeviceNode
.UID
+ 1,
230 FreePool(DevPathStr
);
232 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
233 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
234 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
239 DevicePath
= TempDevicePath
;
240 gPnp16550ComPortDeviceNode
.UID
= 1;
242 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
243 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
244 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
249 DevPathStr
= DevicePathToStr(DevicePath
);
252 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
254 gPnp16550ComPortDeviceNode
.UID
+ 1,
257 FreePool(DevPathStr
);
259 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
260 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
261 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
268 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
269 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
274 EFI_HANDLE PciDeviceHandle
;
275 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
276 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
277 UINTN GopHandleCount
;
278 EFI_HANDLE
*GopHandleBuffer
;
280 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
281 return EFI_INVALID_PARAMETER
;
285 // Initialize the GopDevicePath to be PciDevicePath
287 *GopDevicePath
= PciDevicePath
;
288 TempPciDevicePath
= PciDevicePath
;
290 Status
= gBS
->LocateDevicePath (
291 &gEfiDevicePathProtocolGuid
,
295 if (EFI_ERROR (Status
)) {
300 // Try to connect this handle, so that GOP dirver could start on this
301 // device and create child handles with GraphicsOutput Protocol installed
302 // on them, then we get device paths of these child handles and select
303 // them as possible console device.
305 gBS
->ConnectController (PciDeviceHandle
, NULL
, NULL
, FALSE
);
307 Status
= gBS
->LocateHandleBuffer (
309 &gEfiGraphicsOutputProtocolGuid
,
314 if (!EFI_ERROR (Status
)) {
316 // Add all the child handles as possible Console Device
318 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
319 Status
= gBS
->HandleProtocol (GopHandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*)&TempDevicePath
);
320 if (EFI_ERROR (Status
)) {
326 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
329 // In current implementation, we only enable one of the child handles
330 // as console device, i.e. sotre one of the child handle's device
331 // path to variable "ConOut"
332 // In futhure, we could select all child handles to be console device
335 *GopDevicePath
= TempDevicePath
;
338 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
339 // Add the integrity GOP device path.
341 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, NULL
, PciDevicePath
);
342 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, TempDevicePath
, NULL
);
345 gBS
->FreePool (GopHandleBuffer
);
352 PreparePciVgaDevicePath (
353 IN EFI_HANDLE DeviceHandle
359 Add PCI VGA to ConOut.
364 DeviceHandle - Handle of PCIIO protocol.
368 EFI_SUCCESS - PCI VGA is added to ConOut.
369 EFI_STATUS - No PCI VGA device is added.
374 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
375 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
378 Status
= gBS
->HandleProtocol (
380 &gEfiDevicePathProtocolGuid
,
383 if (EFI_ERROR (Status
)) {
387 GetGopDevicePath (DevicePath
, &GopDevicePath
);
388 DevicePath
= GopDevicePath
;
390 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
396 PreparePciSerialDevicePath (
397 IN EFI_HANDLE DeviceHandle
403 Add PCI Serial to ConOut, ConIn, ErrOut.
408 DeviceHandle - Handle of PCIIO protocol.
412 EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
413 EFI_STATUS - No PCI Serial device is added.
418 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
421 Status
= gBS
->HandleProtocol (
423 &gEfiDevicePathProtocolGuid
,
426 if (EFI_ERROR (Status
)) {
430 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
431 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
433 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
434 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
435 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
441 VisitAllInstancesOfProtocol (
443 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
449 EFI_HANDLE
*HandleBuffer
;
454 // Start to check all the PciIo to find all possible device
458 Status
= gBS
->LocateHandleBuffer (
465 if (EFI_ERROR (Status
)) {
469 for (Index
= 0; Index
< HandleCount
; Index
++) {
470 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], Id
, &Instance
);
471 if (EFI_ERROR (Status
)) {
475 Status
= (*CallBackFunction
) (
482 gBS
->FreePool (HandleBuffer
);
490 VisitingAPciInstance (
491 IN EFI_HANDLE Handle
,
497 EFI_PCI_IO_PROTOCOL
*PciIo
;
500 PciIo
= (EFI_PCI_IO_PROTOCOL
*) Instance
;
503 // Check for all PCI device
505 Status
= PciIo
->Pci
.Read (
509 sizeof (Pci
) / sizeof (UINT32
),
512 if (EFI_ERROR (Status
)) {
516 return (*(VISIT_PCI_INSTANCE_CALLBACK
) Context
) (
527 VisitAllPciInstances (
528 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
531 return VisitAllInstancesOfProtocol (
532 &gEfiPciIoProtocolGuid
,
533 VisitingAPciInstance
,
534 (VOID
*) CallBackFunction
540 Do platform specific PCI Device check and add them to
541 ConOut, ConIn, ErrOut.
543 @param[in] Handle - Handle of PCI device instance
544 @param[in] PciIo - PCI IO protocol instance
545 @param[in] Pci - PCI Header register block
547 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
548 @retval EFI_STATUS - PCI Device check or Console variable update fail.
552 DetectAndPreparePlatformPciDevicePath (
553 IN EFI_HANDLE Handle
,
554 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
560 Status
= PciIo
->Attributes (
562 EfiPciIoAttributeOperationEnable
,
563 EFI_PCI_DEVICE_ENABLE
,
566 ASSERT_EFI_ERROR (Status
);
568 if (!mDetectVgaOnly
) {
570 // Here we decide whether it is LPC Bridge
572 if ((IS_PCI_LPC (Pci
)) ||
573 ((IS_PCI_ISA_PDECODE (Pci
)) &&
574 (Pci
->Hdr
.VendorId
== 0x8086) &&
575 (Pci
->Hdr
.DeviceId
== 0x7000)
579 // Add IsaKeyboard to ConIn,
580 // add IsaSerial to ConOut, ConIn, ErrOut
582 DEBUG ((EFI_D_INFO
, "Found LPC Bridge device\n"));
583 PrepareLpcBridgeDevicePath (Handle
);
587 // Here we decide which Serial device to enable in PCI bus
589 if (IS_PCI_16550SERIAL (Pci
)) {
591 // Add them to ConOut, ConIn, ErrOut.
593 DEBUG ((EFI_D_INFO
, "Found PCI 16550 SERIAL device\n"));
594 PreparePciSerialDevicePath (Handle
);
600 // Here we decide which VGA device to enable in PCI bus
602 if (IS_PCI_VGA (Pci
)) {
604 // Add them to ConOut.
606 DEBUG ((EFI_D_INFO
, "Found PCI VGA device\n"));
607 PreparePciVgaDevicePath (Handle
);
616 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
618 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
620 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
621 @retval EFI_STATUS - PCI Device check or Console variable update fail.
625 DetectAndPreparePlatformPciDevicePaths (
626 BOOLEAN DetectVgaOnly
629 mDetectVgaOnly
= DetectVgaOnly
;
630 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath
);
635 PlatformBdsConnectConsole (
636 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
642 Connect the predefined platform default console device. Always try to find
643 and enable the vga device if have.
647 PlatformConsole - Predfined platform default console device array.
651 EFI_SUCCESS - Success connect at least one ConIn and ConOut
652 device, there must have one ConOut device is
655 EFI_STATUS - Return the status of
656 BdsLibConnectAllDefaultConsoles ()
662 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
663 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
664 UINTN DevicePathSize
;
667 // Connect RootBridge
669 ConnectRootBridge ();
671 VarConout
= BdsLibGetVariableAndSize (
673 &gEfiGlobalVariableGuid
,
676 VarConin
= BdsLibGetVariableAndSize (
678 &gEfiGlobalVariableGuid
,
682 if (VarConout
== NULL
|| VarConin
== NULL
) {
684 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
686 DetectAndPreparePlatformPciDevicePaths (FALSE
);
689 // Have chance to connect the platform default console,
690 // the platform default console is the minimue device group
691 // the platform should support
693 for (Index
= 0; PlatformConsole
[Index
].DevicePath
!= NULL
; ++Index
) {
695 // Update the console variable with the connect type
697 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
698 BdsLibUpdateConsoleVariable (VarConsoleInp
, PlatformConsole
[Index
].DevicePath
, NULL
);
700 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
701 BdsLibUpdateConsoleVariable (VarConsoleOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
703 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
704 BdsLibUpdateConsoleVariable (VarErrorOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
709 // Only detect VGA device and add them to ConOut
711 DetectAndPreparePlatformPciDevicePaths (TRUE
);
715 // Connect the all the default console with current cosole variable
717 Status
= BdsLibConnectAllDefaultConsoles ();
718 if (EFI_ERROR (Status
)) {
731 // Bus 0, Device 0, Function 0 - Host to PCI Bridge
733 PciWrite8 (PCI_LIB_ADDRESS (0, 0, 0, 0x3c), 0x00);
736 // Bus 0, Device 1, Function 0 - PCI to ISA Bridge
738 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x3c), 0x00);
739 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b);
740 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x09);
741 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0b);
742 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x09);
745 // Bus 0, Device 1, Function 1 - IDE Controller
747 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x3c), 0x00);
748 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x0d), 0x40);
751 // Bus 0, Device 1, Function 3 - Power Managment Controller
753 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3c), 0x0b);
754 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3d), 0x01);
757 // Bus 0, Device 2, Function 0 - Video Controller
759 PciWrite8 (PCI_LIB_ADDRESS (0, 2, 0, 0x3c), 0x00);
762 // Bus 0, Device 3, Function 0 - Network Controller
764 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0b);
765 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3d), 0x01);
768 // Bus 0, Device 4, Function 0 - RAM Memory
770 PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3c), 0x09);
771 PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3d), 0x01);
776 PlatformBdsConnectSequence (
783 Connect with predeined platform connect sequence,
784 the OEM/IBV can customize with their own connect sequence.
798 DEBUG ((EFI_D_INFO
, "PlatformBdsConnectSequence\n"));
803 // Here we can get the customized platform connect sequence
804 // Notes: we can connect with new variable which record the
805 // last time boots connect device path sequence
807 while (gPlatformConnectSequence
[Index
] != NULL
) {
809 // Build the platform boot option
811 BdsLibConnectDevicePath (gPlatformConnectSequence
[Index
]);
816 // Just use the simple policy to connect all devices
820 PciInitialization ();
823 // Clear the logo after all devices are connected.
825 gST
->ConOut
->ClearScreen (gST
->ConOut
);
829 PlatformBdsGetDriverOption (
830 IN OUT LIST_ENTRY
*BdsDriverLists
836 Load the predefined driver option, OEM/IBV can customize this
837 to load their own drivers
841 BdsDriverLists - The header of the driver option link list.
849 DEBUG ((EFI_D_INFO
, "PlatformBdsGetDriverOption\n"));
854 PlatformBdsDiagnostics (
855 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
856 IN BOOLEAN QuietBoot
,
857 IN BASEM_MEMORY_TEST BaseMemoryTest
863 Perform the platform diagnostic, such like test memory. OEM/IBV also
864 can customize this fuction to support specific platform diagnostic.
868 MemoryTestLevel - The memory test intensive level
870 QuietBoot - Indicate if need to enable the quiet boot
872 BaseMemoryTest - A pointer to BaseMemoryTest()
882 DEBUG ((EFI_D_INFO
, "PlatformBdsDiagnostics\n"));
885 // Here we can decide if we need to show
886 // the diagnostics screen
887 // Notes: this quiet boot code should be remove
888 // from the graphic lib
891 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
893 // Perform system diagnostic
895 Status
= BaseMemoryTest (MemoryTestLevel
);
896 if (EFI_ERROR (Status
)) {
903 // Perform system diagnostic
905 Status
= BaseMemoryTest (MemoryTestLevel
);
911 PlatformBdsPolicyBehavior (
912 IN OUT LIST_ENTRY
*DriverOptionList
,
913 IN OUT LIST_ENTRY
*BootOptionList
,
914 IN PROCESS_CAPSULES ProcessCapsules
,
915 IN BASEM_MEMORY_TEST BaseMemoryTest
921 The function will excute with as the platform policy, current policy
922 is driven by boot mode. IBV/OEM can customize this code for their specific
927 DriverOptionList - The header of the driver option link list
929 BootOptionList - The header of the boot option link list
931 ProcessCapsules - A pointer to ProcessCapsules()
933 BaseMemoryTest - A pointer to BaseMemoryTest()
943 EFI_EVENT UserInputDurationTime
;
945 BDS_COMMON_OPTION
*BootOption
;
949 EFI_BOOT_MODE BootMode
;
951 DEBUG ((EFI_D_INFO
, "PlatformBdsPolicyBehavior\n"));
954 // Init the time out value
956 Timeout
= PcdGet16 (PcdPlatformBootTimeOut
);
959 // Load the driver option as the driver option list
961 PlatformBdsGetDriverOption (DriverOptionList
);
964 // Get current Boot Mode
966 Status
= BdsLibGetBootMode (&BootMode
);
967 DEBUG ((EFI_D_ERROR
, "Boot Mode:%x\n", BootMode
));
970 // Go the different platform policy with different boot mode
971 // Notes: this part code can be change with the table policy
973 ASSERT (BootMode
== BOOT_WITH_FULL_CONFIGURATION
);
975 // Connect platform console
977 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
978 if (EFI_ERROR (Status
)) {
980 // Here OEM/IBV can customize with defined action
982 PlatformBdsNoConsoleAction ();
985 // Create a 300ms duration event to ensure user has enough input time to enter Setup
987 Status
= gBS
->CreateEvent (
992 &UserInputDurationTime
994 ASSERT (Status
== EFI_SUCCESS
);
995 Status
= gBS
->SetTimer (UserInputDurationTime
, TimerRelative
, 3000000);
996 ASSERT (Status
== EFI_SUCCESS
);
998 // Memory test and Logo show
1000 PlatformBdsDiagnostics (IGNORE
, TRUE
, BaseMemoryTest
);
1003 // Perform some platform specific connect sequence
1005 PlatformBdsConnectSequence ();
1008 // Give one chance to enter the setup if we
1009 // have the time out
1012 //PlatformBdsEnterFrontPage (Timeout, FALSE);
1015 DEBUG ((EFI_D_INFO
, "BdsLibConnectAll\n"));
1016 BdsLibConnectAll ();
1017 BdsLibEnumerateAllBootOption (BootOptionList
);
1020 // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot
1021 // checking code in real production tip.
1023 // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device
1024 // and do enumerate all the default boot options. But in development system board, the boot mode
1025 // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box
1026 // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.
1028 Status
= BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
1029 if (EFI_ERROR(Status
)) {
1031 // If cannot find "BootOrder" variable, it may be first boot.
1032 // Try to connect all devices and enumerate all boot options here.
1034 BdsLibConnectAll ();
1035 BdsLibEnumerateAllBootOption (BootOptionList
);
1039 // To give the User a chance to enter Setup here, if user set TimeOut is 0.
1040 // BDS should still give user a chance to enter Setup
1042 // Connect first boot option, and then check user input before exit
1044 for (Link
= BootOptionList
->ForwardLink
; Link
!= BootOptionList
;Link
= Link
->ForwardLink
) {
1045 BootOption
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
1046 if (!IS_LOAD_OPTION_TYPE (BootOption
->Attribute
, LOAD_OPTION_ACTIVE
)) {
1048 // skip the header of the link list, becuase it has no boot option
1053 // Make sure the boot option device path connected, but ignore the BBS device path
1055 if (DevicePathType (BootOption
->DevicePath
) != BBS_DEVICE_PATH
) {
1056 BdsLibConnectDevicePath (BootOption
->DevicePath
);
1063 // Check whether the user input after the duration time has expired
1065 OldTpl
= EfiGetCurrentTpl();
1066 gBS
->RestoreTPL (TPL_APPLICATION
);
1067 gBS
->WaitForEvent (1, &UserInputDurationTime
, &Index
);
1068 gBS
->CloseEvent (UserInputDurationTime
);
1069 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
1070 gBS
->RaiseTPL (OldTpl
);
1072 if (!EFI_ERROR (Status
)) {
1074 // Enter Setup if user input
1077 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
1085 PlatformBdsBootSuccess (
1086 IN BDS_COMMON_OPTION
*Option
1090 Routine Description:
1092 Hook point after a boot attempt succeeds. We don't expect a boot option to
1093 return, so the EFI 1.0 specification defines that you will default to an
1094 interactive mode and stop processing the BootOrder list in this case. This
1095 is alos a platform implementation and can be customized by IBV/OEM.
1099 Option - Pointer to Boot Option that succeeded to boot.
1109 DEBUG ((EFI_D_INFO
, "PlatformBdsBootSuccess\n"));
1111 // If Boot returned with EFI_SUCCESS and there is not in the boot device
1112 // select loop then we need to pop up a UI and wait for user input.
1114 TmpStr
= Option
->StatusString
;
1115 if (TmpStr
!= NULL
) {
1116 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1123 PlatformBdsBootFail (
1124 IN BDS_COMMON_OPTION
*Option
,
1125 IN EFI_STATUS Status
,
1126 IN CHAR16
*ExitData
,
1127 IN UINTN ExitDataSize
1131 Routine Description:
1133 Hook point after a boot attempt fails.
1137 Option - Pointer to Boot Option that failed to boot.
1139 Status - Status returned from failed boot.
1141 ExitData - Exit data returned from failed boot.
1143 ExitDataSize - Exit data size returned from failed boot.
1153 DEBUG ((EFI_D_INFO
, "PlatformBdsBootFail\n"));
1156 // If Boot returned with failed status then we need to pop up a UI and wait
1159 TmpStr
= Option
->StatusString
;
1160 if (TmpStr
!= NULL
) {
1161 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1167 PlatformBdsNoConsoleAction (
1172 Routine Description:
1174 This function is remained for IBV/OEM to do some platform action,
1175 if there no console device can be connected.
1183 EFI_SUCCESS - Direct return success now.
1187 DEBUG ((EFI_D_INFO
, "PlatformBdsNoConsoleAction\n"));
1193 PlatformBdsLockNonUpdatableFlash (
1197 DEBUG ((EFI_D_INFO
, "PlatformBdsLockNonUpdatableFlash\n"));
1203 This notification function is invoked when an instance of the
1204 EFI_DEVICE_PATH_PROTOCOL is produced.
1206 @param Event The event that occured
1207 @param Context For EFI compatiblity. Not used.
1220 EFI_DEVICE_PATH_PROTOCOL
*DevPathNode
;
1221 ATAPI_DEVICE_PATH
*Atapi
;
1224 // Examine all new handles
1228 // Get the next handle
1230 BufferSize
= sizeof (Handle
);
1231 Status
= gBS
->LocateHandle (
1234 mEfiDevPathNotifyReg
,
1240 // If not found, we're done
1242 if (EFI_NOT_FOUND
== Status
) {
1246 if (EFI_ERROR (Status
)) {
1251 // Get the DevicePath protocol on that handle
1253 Status
= gBS
->HandleProtocol (Handle
, &gEfiDevicePathProtocolGuid
, (VOID
**)&DevPathNode
);
1254 ASSERT_EFI_ERROR (Status
);
1256 while (!IsDevicePathEnd (DevPathNode
)) {
1258 // Find the handler to dump this device path node
1261 (DevicePathType(DevPathNode
) == MESSAGING_DEVICE_PATH
) &&
1262 (DevicePathSubType(DevPathNode
) == MSG_ATAPI_DP
)
1264 Atapi
= (ATAPI_DEVICE_PATH
*) DevPathNode
;
1270 (Atapi
->PrimarySecondary
== 1) ? 0x42: 0x40
1277 // Next device path node
1279 DevPathNode
= NextDevicePathNode (DevPathNode
);
1288 InstallDevicePathCallback (
1292 DEBUG ((EFI_D_INFO
, "Registered NotifyDevPath Event\n"));
1293 mEfiDevPathEvent
= EfiCreateProtocolNotifyEvent (
1294 &gEfiDevicePathProtocolGuid
,
1298 &mEfiDevPathNotifyReg
1303 Lock the ConsoleIn device in system table. All key
1304 presses will be ignored until the Password is typed in. The only way to
1305 disable the password is to type it in to a ConIn device.
1307 @param Password Password used to lock ConIn device.
1309 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
1310 @retval EFI_UNSUPPORTED Password not found
1319 return EFI_UNSUPPORTED
;
1329 PCI_DATA_STRUCTURE
*Pcir
;
1333 // The virtual machines sometimes load the video rom image
1334 // directly at the legacy video BIOS location of C000:0000,
1335 // and do not implement the PCI expansion ROM feature.
1337 Pcir
= (PCI_DATA_STRUCTURE
*) (UINTN
) 0xc0000;
1338 RomSize
= Pcir
->ImageLength
* 512;
1339 PciRomLoadEfiDriversFromRomImage (0xc0000, RomSize
);
1345 PciRomLoadEfiDriversFromRomImage (
1346 IN EFI_PHYSICAL_ADDRESS Rom
,
1351 EFI_PCI_EXPANSION_ROM_HEADER
*EfiRomHeader
;
1352 PCI_DATA_STRUCTURE
*Pcir
;
1357 EFI_HANDLE ImageHandle
;
1359 EFI_STATUS retStatus
;
1360 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
1362 UINT32 DestinationSize
;
1366 VOID
*DecompressedImageBuffer
;
1368 EFI_DECOMPRESS_PROTOCOL
*Decompress
;
1370 FileName
= L
"PciRomInMemory";
1372 //FileName = L"PciRom Addr=0000000000000000";
1373 //HexToString (&FileName[12], Rom, 16);
1376 retStatus
= EFI_NOT_FOUND
;
1377 RomOffset
= (UINTN
) Rom
;
1381 EfiRomHeader
= (EFI_PCI_EXPANSION_ROM_HEADER
*) (UINTN
) RomOffset
;
1383 if (EfiRomHeader
->Signature
!= 0xaa55) {
1387 Pcir
= (PCI_DATA_STRUCTURE
*) (UINTN
) (RomOffset
+ EfiRomHeader
->PcirOffset
);
1388 ImageSize
= Pcir
->ImageLength
* 512;
1390 if ((Pcir
->CodeType
== PCI_CODE_TYPE_EFI_IMAGE
) &&
1391 (EfiRomHeader
->EfiSignature
== EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE
) ) {
1393 if ((EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
) ||
1394 (EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
) ) {
1396 ImageOffset
= EfiRomHeader
->EfiImageHeaderOffset
;
1397 ImageSize
= EfiRomHeader
->InitializationSize
* 512;
1399 ImageBuffer
= (VOID
*) (UINTN
) (RomOffset
+ ImageOffset
);
1400 ImageLength
= ImageSize
- ImageOffset
;
1401 DecompressedImageBuffer
= NULL
;
1404 // decompress here if needed
1407 if (EfiRomHeader
->CompressionType
> EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
1411 if (EfiRomHeader
->CompressionType
== EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
1412 Status
= gBS
->LocateProtocol (&gEfiDecompressProtocolGuid
, NULL
, (VOID
**) &Decompress
);
1413 if (EFI_ERROR (Status
)) {
1417 Status
= Decompress
->GetInfo (
1424 if (!EFI_ERROR (Status
)) {
1425 DecompressedImageBuffer
= NULL
;
1426 DecompressedImageBuffer
= AllocatePool (DestinationSize
);
1427 if (DecompressedImageBuffer
!= NULL
) {
1428 Scratch
= AllocatePool (ScratchSize
);
1429 if (Scratch
!= NULL
) {
1430 Status
= Decompress
->Decompress (
1434 DecompressedImageBuffer
,
1439 if (!EFI_ERROR (Status
)) {
1440 ImageBuffer
= DecompressedImageBuffer
;
1441 ImageLength
= DestinationSize
;
1445 gBS
->FreePool (Scratch
);
1455 // load image and start image
1458 FilePath
= FileDevicePath (NULL
, FileName
);
1460 Status
= gBS
->LoadImage (
1468 if (!EFI_ERROR (Status
)) {
1469 Status
= gBS
->StartImage (ImageHandle
, NULL
, NULL
);
1470 if (!EFI_ERROR (Status
)) {
1474 if (FilePath
!= NULL
) {
1475 gBS
->FreePool (FilePath
);
1479 if (DecompressedImageBuffer
!= NULL
) {
1480 gBS
->FreePool (DecompressedImageBuffer
);
1486 RomOffset
= RomOffset
+ ImageSize
;
1488 } while (((Pcir
->Indicator
& 0x80) == 0x00) && ((RomOffset
- (UINTN
) Rom
) < RomSize
));