/** @file\r
Platform BDS customizations.\r
\r
- Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
- All rights reserved. This program and the accompanying materials\r
+ Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
**/\r
\r
#include "BdsPlatform.h"\r
+#include <Library/QemuBootOrderLib.h>\r
\r
\r
+//\r
+// Global data\r
+//\r
+\r
+VOID *mEfiDevPathNotifyReg;\r
+EFI_EVENT mEfiDevPathEvent;\r
+VOID *mEmuVariableEventReg;\r
+EFI_EVENT mEmuVariableEvent;\r
+BOOLEAN mDetectVgaOnly;\r
+UINT16 mHostBridgeDevId;\r
+\r
+//\r
+// Table of host IRQs matching PCI IRQs A-D\r
+// (for configuring PCI Interrupt Line register)\r
+//\r
+CONST UINT8 PciHostIrqs[] = {\r
+ 0x0a, 0x0a, 0x0b, 0x0b\r
+};\r
+\r
+//\r
+// Array Size macro\r
+//\r
+#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))\r
+\r
+//\r
+// Type definitions\r
+//\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *PROTOCOL_INSTANCE_CALLBACK)(\r
+ IN EFI_HANDLE Handle,\r
+ IN VOID *Instance,\r
+ IN VOID *Context\r
+ );\r
+\r
+/**\r
+ @param[in] Handle - Handle of PCI device instance\r
+ @param[in] PciIo - PCI IO protocol instance\r
+ @param[in] Pci - PCI Header register block\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)(\r
+ IN EFI_HANDLE Handle,\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN PCI_TYPE00 *Pci\r
+ );\r
+\r
+\r
+//\r
+// Function prototypes\r
+//\r
+\r
+EFI_STATUS\r
+VisitAllInstancesOfProtocol (\r
+ IN EFI_GUID *Id,\r
+ IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction,\r
+ IN VOID *Context\r
+ );\r
+\r
+EFI_STATUS\r
+VisitAllPciInstancesOfProtocol (\r
+ IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction\r
+ );\r
+\r
+VOID\r
+InstallDevicePathCallback (\r
+ VOID\r
+ );\r
+\r
//\r
// BDS Platform Functions\r
//\r
VOID\r
EFIAPI\r
PlatformBdsInit (\r
- IN EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData\r
+ VOID\r
)\r
/*++\r
\r
\r
Arguments:\r
\r
- PrivateData - The EFI_BDS_ARCH_PROTOCOL_INSTANCE instance\r
-\r
Returns:\r
\r
None.\r
--*/\r
{\r
DEBUG ((EFI_D_INFO, "PlatformBdsInit\n"));\r
+ InstallDevicePathCallback ();\r
}\r
\r
\r
EFI_STATUS\r
+EFIAPI\r
ConnectRootBridge (\r
- VOID\r
+ IN EFI_HANDLE RootBridgeHandle,\r
+ IN VOID *Instance,\r
+ IN VOID *Context\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Connect RootBridge\r
-\r
-Arguments:\r
-\r
- None.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Connect RootBridge successfully.\r
- EFI_STATUS - Connect RootBridge fail.\r
-\r
---*/\r
{\r
- EFI_STATUS Status;\r
- EFI_HANDLE RootHandle;\r
+ EFI_STATUS Status;\r
\r
//\r
- // Make all the PCI_IO protocols on PCI Seg 0 show up\r
+ // Make the PCI bus driver connect the root bridge, non-recursively. This\r
+ // will produce a number of child handles with PciIo on them.\r
//\r
- BdsLibConnectDevicePath (gPlatformRootBridges[0]);\r
-\r
- Status = gBS->LocateDevicePath (\r
- &gEfiDevicePathProtocolGuid,\r
- &gPlatformRootBridges[0],\r
- &RootHandle\r
+ Status = gBS->ConnectController (\r
+ RootBridgeHandle, // ControllerHandle\r
+ NULL, // DriverImageHandle\r
+ NULL, // RemainingDevicePath -- produce all\r
+ // children\r
+ FALSE // Recursive\r
);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = gBS->ConnectController (RootHandle, NULL, NULL, FALSE);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return EFI_SUCCESS;\r
+ return Status;\r
}\r
\r
\r
// Print Device Path\r
//\r
DevPathStr = DevicePathToStr(DevicePath);\r
- DEBUG((\r
- EFI_D_INFO,\r
- "BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
- __LINE__,\r
- gPnp16550ComPortDeviceNode.UID + 1,\r
- DevPathStr\r
- ));\r
- FreePool(DevPathStr);\r
+ if (DevPathStr != NULL) {\r
+ DEBUG((\r
+ EFI_D_INFO,\r
+ "BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
+ __LINE__,\r
+ gPnp16550ComPortDeviceNode.UID + 1,\r
+ DevPathStr\r
+ ));\r
+ FreePool(DevPathStr);\r
+ }\r
\r
BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
// Print Device Path\r
//\r
DevPathStr = DevicePathToStr(DevicePath);\r
- DEBUG((\r
- EFI_D_INFO,\r
- "BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
- __LINE__,\r
- gPnp16550ComPortDeviceNode.UID + 1,\r
- DevPathStr\r
- ));\r
- FreePool(DevPathStr);\r
+ if (DevPathStr != NULL) {\r
+ DEBUG((\r
+ EFI_D_INFO,\r
+ "BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
+ __LINE__,\r
+ gPnp16550ComPortDeviceNode.UID + 1,\r
+ DevPathStr\r
+ ));\r
+ FreePool(DevPathStr);\r
+ }\r
\r
BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;\r
\r
- DevicePath = NULL;\r
+ DevicePath = NULL;\r
+ GopDevicePath = NULL;\r
Status = gBS->HandleProtocol (\r
DeviceHandle,\r
&gEfiDevicePathProtocolGuid,\r
}\r
\r
EFI_STATUS\r
-DetectAndPreparePlatformPciDevicePath (\r
- BOOLEAN DetectVgaOnly\r
+VisitAllInstancesOfProtocol (\r
+ IN EFI_GUID *Id,\r
+ IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction,\r
+ IN VOID *Context\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
-\r
-Arguments:\r
-\r
- DetectVgaOnly - Only detect VGA device if it's TRUE.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
- EFI_STATUS - PCI Device check or Console variable update fail.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
UINTN HandleCount;\r
EFI_HANDLE *HandleBuffer;\r
UINTN Index;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- PCI_TYPE00 Pci;\r
+ VOID *Instance;\r
\r
//\r
// Start to check all the PciIo to find all possible device\r
HandleBuffer = NULL;\r
Status = gBS->LocateHandleBuffer (\r
ByProtocol,\r
- &gEfiPciIoProtocolGuid,\r
+ Id,\r
NULL,\r
&HandleCount,\r
&HandleBuffer\r
}\r
\r
for (Index = 0; Index < HandleCount; Index++) {\r
- Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID*)&PciIo);\r
+ Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance);\r
if (EFI_ERROR (Status)) {\r
continue;\r
}\r
\r
+ Status = (*CallBackFunction) (\r
+ HandleBuffer[Index],\r
+ Instance,\r
+ Context\r
+ );\r
+ }\r
+\r
+ gBS->FreePool (HandleBuffer);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+VisitingAPciInstance (\r
+ IN EFI_HANDLE Handle,\r
+ IN VOID *Instance,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ PCI_TYPE00 Pci;\r
+\r
+ PciIo = (EFI_PCI_IO_PROTOCOL*) Instance;\r
+\r
+ //\r
+ // Check for all PCI device\r
+ //\r
+ Status = PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ 0,\r
+ sizeof (Pci) / sizeof (UINT32),\r
+ &Pci\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return (*(VISIT_PCI_INSTANCE_CALLBACK)(UINTN) Context) (\r
+ Handle,\r
+ PciIo,\r
+ &Pci\r
+ );\r
+\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+VisitAllPciInstances (\r
+ IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction\r
+ )\r
+{\r
+ return VisitAllInstancesOfProtocol (\r
+ &gEfiPciIoProtocolGuid,\r
+ VisitingAPciInstance,\r
+ (VOID*)(UINTN) CallBackFunction\r
+ );\r
+}\r
+\r
+\r
+/**\r
+ Do platform specific PCI Device check and add them to\r
+ ConOut, ConIn, ErrOut.\r
+\r
+ @param[in] Handle - Handle of PCI device instance\r
+ @param[in] PciIo - PCI IO protocol instance\r
+ @param[in] Pci - PCI Header register block\r
+\r
+ @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
+ @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DetectAndPreparePlatformPciDevicePath (\r
+ IN EFI_HANDLE Handle,\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN PCI_TYPE00 *Pci\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = PciIo->Attributes (\r
+ PciIo,\r
+ EfiPciIoAttributeOperationEnable,\r
+ EFI_PCI_DEVICE_ENABLE,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ if (!mDetectVgaOnly) {\r
//\r
- // Check for all PCI device\r
+ // Here we decide whether it is LPC Bridge\r
//\r
- Status = PciIo->Pci.Read (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0,\r
- sizeof (Pci) / sizeof (UINT32),\r
- &Pci\r
- );\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- if (!DetectVgaOnly) {\r
- //\r
- // Here we decide whether it is LPC Bridge\r
- //\r
- if ((IS_PCI_LPC (&Pci)) ||\r
- ((IS_PCI_ISA_PDECODE (&Pci)) &&\r
- (Pci.Hdr.VendorId == 0x8086) &&\r
- (Pci.Hdr.DeviceId == 0x7000)\r
- )\r
- ) {\r
- Status = PciIo->Attributes (\r
- PciIo,\r
- EfiPciIoAttributeOperationEnable,\r
- EFI_PCI_DEVICE_ENABLE,\r
- NULL\r
- );\r
- //\r
- // Add IsaKeyboard to ConIn,\r
- // add IsaSerial to ConOut, ConIn, ErrOut\r
- //\r
- DEBUG ((EFI_D_INFO, "Find the LPC Bridge device\n"));\r
- PrepareLpcBridgeDevicePath (HandleBuffer[Index]);\r
- continue;\r
- }\r
+ if ((IS_PCI_LPC (Pci)) ||\r
+ ((IS_PCI_ISA_PDECODE (Pci)) &&\r
+ (Pci->Hdr.VendorId == 0x8086) &&\r
+ (Pci->Hdr.DeviceId == 0x7000)\r
+ )\r
+ ) {\r
//\r
- // Here we decide which Serial device to enable in PCI bus\r
+ // Add IsaKeyboard to ConIn,\r
+ // add IsaSerial to ConOut, ConIn, ErrOut\r
//\r
- if (IS_PCI_16550SERIAL (&Pci)) {\r
- //\r
- // Add them to ConOut, ConIn, ErrOut.\r
- //\r
- DEBUG ((EFI_D_INFO, "Find the 16550 SERIAL device\n"));\r
- PreparePciSerialDevicePath (HandleBuffer[Index]);\r
- continue;\r
- }\r
+ DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n"));\r
+ PrepareLpcBridgeDevicePath (Handle);\r
+ return EFI_SUCCESS;\r
}\r
-\r
- if ((Pci.Hdr.VendorId == 0x8086) &&\r
- (Pci.Hdr.DeviceId == 0x7010)\r
- ) {\r
- Status = PciIo->Attributes (\r
- PciIo,\r
- EfiPciIoAttributeOperationEnable,\r
- EFI_PCI_DEVICE_ENABLE,\r
- NULL\r
- );\r
- }\r
-\r
//\r
- // Here we decide which VGA device to enable in PCI bus\r
+ // Here we decide which Serial device to enable in PCI bus\r
//\r
- if (IS_PCI_VGA (&Pci)) {\r
+ if (IS_PCI_16550SERIAL (Pci)) {\r
//\r
- // Add them to ConOut.\r
+ // Add them to ConOut, ConIn, ErrOut.\r
//\r
- DEBUG ((EFI_D_INFO, "Find the VGA device\n"));\r
- PreparePciVgaDevicePath (HandleBuffer[Index]);\r
- continue;\r
+ DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n"));\r
+ PreparePciSerialDevicePath (Handle);\r
+ return EFI_SUCCESS;\r
}\r
}\r
\r
- gBS->FreePool (HandleBuffer);\r
+ //\r
+ // Here we decide which VGA device to enable in PCI bus\r
+ //\r
+ if (IS_PCI_VGA (Pci)) {\r
+ //\r
+ // Add them to ConOut.\r
+ //\r
+ DEBUG ((EFI_D_INFO, "Found PCI VGA device\n"));\r
+ PreparePciVgaDevicePath (Handle);\r
+ return EFI_SUCCESS;\r
+ }\r
\r
- return EFI_SUCCESS;\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
+\r
+ @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.\r
+\r
+ @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
+ @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
+\r
+**/\r
+EFI_STATUS\r
+DetectAndPreparePlatformPciDevicePaths (\r
+ BOOLEAN DetectVgaOnly\r
+ )\r
+{\r
+ mDetectVgaOnly = DetectVgaOnly;\r
+ return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);\r
}\r
\r
\r
//\r
// Connect RootBridge\r
//\r
- ConnectRootBridge ();\r
-\r
VarConout = BdsLibGetVariableAndSize (\r
VarConsoleOut,\r
&gEfiGlobalVariableGuid,\r
//\r
// Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
//\r
- DetectAndPreparePlatformPciDevicePath (FALSE);\r
+ DetectAndPreparePlatformPciDevicePaths (FALSE);\r
\r
//\r
// Have chance to connect the platform default console,\r
//\r
// Only detect VGA device and add them to ConOut\r
//\r
- DetectAndPreparePlatformPciDevicePath (TRUE);\r
+ DetectAndPreparePlatformPciDevicePaths (TRUE);\r
}\r
\r
//\r
}\r
\r
\r
+/**\r
+ Configure PCI Interrupt Line register for applicable devices\r
+ Ported from SeaBIOS, src/fw/pciinit.c, *_pci_slot_get_irq()\r
+\r
+ @param[in] Handle - Handle of PCI device instance\r
+ @param[in] PciIo - PCI IO protocol instance\r
+ @param[in] PciHdr - PCI Header register block\r
+\r
+ @retval EFI_SUCCESS - PCI Interrupt Line register configured successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SetPciIntLine (\r
+ IN EFI_HANDLE Handle,\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN PCI_TYPE00 *PciHdr\r
+ )\r
+{\r
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
+ UINTN RootSlot;\r
+ UINTN Idx;\r
+ UINT8 IrqLine;\r
+ EFI_STATUS Status;\r
+ UINT32 RootBusNumber;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (PciHdr->Device.InterruptPin != 0) {\r
+\r
+ DevPathNode = DevicePathFromHandle (Handle);\r
+ ASSERT (DevPathNode != NULL);\r
+ DevPath = DevPathNode;\r
+\r
+ RootBusNumber = 0;\r
+ if (DevicePathType (DevPathNode) == ACPI_DEVICE_PATH &&\r
+ DevicePathSubType (DevPathNode) == ACPI_DP &&\r
+ ((ACPI_HID_DEVICE_PATH *)DevPathNode)->HID == EISA_PNP_ID(0x0A03)) {\r
+ RootBusNumber = ((ACPI_HID_DEVICE_PATH *)DevPathNode)->UID;\r
+ }\r
+\r
+ //\r
+ // Compute index into PciHostIrqs[] table by walking\r
+ // the device path and adding up all device numbers\r
+ //\r
+ Status = EFI_NOT_FOUND;\r
+ RootSlot = 0;\r
+ Idx = PciHdr->Device.InterruptPin - 1;\r
+ while (!IsDevicePathEnd (DevPathNode)) {\r
+ if (DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH &&\r
+ DevicePathSubType (DevPathNode) == HW_PCI_DP) {\r
+\r
+ Idx += ((PCI_DEVICE_PATH *)DevPathNode)->Device;\r
+\r
+ //\r
+ // Unlike SeaBIOS, which starts climbing from the leaf device\r
+ // up toward the root, we traverse the device path starting at\r
+ // the root moving toward the leaf node.\r
+ // The slot number of the top-level parent bridge is needed for\r
+ // Q35 cases with more than 24 slots on the root bus.\r
+ //\r
+ if (Status != EFI_SUCCESS) {\r
+ Status = EFI_SUCCESS;\r
+ RootSlot = ((PCI_DEVICE_PATH *)DevPathNode)->Device;\r
+ }\r
+ }\r
+\r
+ DevPathNode = NextDevicePathNode (DevPathNode);\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ if (RootBusNumber == 0 && RootSlot == 0) {\r
+ DEBUG((\r
+ EFI_D_ERROR,\r
+ "%a: PCI host bridge (00:00.0) should have no interrupts!\n",\r
+ __FUNCTION__\r
+ ));\r
+ ASSERT (FALSE);\r
+ }\r
+\r
+ //\r
+ // Final PciHostIrqs[] index calculation depends on the platform\r
+ // and should match SeaBIOS src/fw/pciinit.c *_pci_slot_get_irq()\r
+ //\r
+ switch (mHostBridgeDevId) {\r
+ case INTEL_82441_DEVICE_ID:\r
+ Idx -= 1;\r
+ break;\r
+ case INTEL_Q35_MCH_DEVICE_ID:\r
+ //\r
+ // SeaBIOS contains the following comment:\r
+ // "Slots 0-24 rotate slot:pin mapping similar to piix above, but\r
+ // with a different starting index - see q35-acpi-dsdt.dsl.\r
+ //\r
+ // Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H)"\r
+ //\r
+ if (RootSlot > 24) {\r
+ //\r
+ // in this case, subtract back out RootSlot from Idx\r
+ // (SeaBIOS never adds it to begin with, but that would make our\r
+ // device path traversal loop above too awkward)\r
+ //\r
+ Idx -= RootSlot;\r
+ }\r
+ break;\r
+ default:\r
+ ASSERT (FALSE); // should never get here\r
+ }\r
+ Idx %= ARRAY_SIZE (PciHostIrqs);\r
+ IrqLine = PciHostIrqs[Idx];\r
+\r
+ DEBUG_CODE_BEGIN ();\r
+ {\r
+ CHAR16 *DevPathString;\r
+ STATIC CHAR16 Fallback[] = L"<failed to convert>";\r
+ UINTN Segment, Bus, Device, Function;\r
+\r
+ DevPathString = ConvertDevicePathToText (DevPath, FALSE, FALSE);\r
+ if (DevPathString == NULL) {\r
+ DevPathString = Fallback;\r
+ }\r
+ Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ DEBUG ((EFI_D_VERBOSE, "%a: [%02x:%02x.%x] %s -> 0x%02x\n", __FUNCTION__,\r
+ (UINT32)Bus, (UINT32)Device, (UINT32)Function, DevPathString,\r
+ IrqLine));\r
+\r
+ if (DevPathString != Fallback) {\r
+ FreePool (DevPathString);\r
+ }\r
+ }\r
+ DEBUG_CODE_END ();\r
+\r
+ //\r
+ // Set PCI Interrupt Line register for this device to PciHostIrqs[Idx]\r
+ //\r
+ Status = PciIo->Pci.Write (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ PCI_INT_LINE_OFFSET,\r
+ 1,\r
+ &IrqLine\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+\r
VOID\r
-PciInitialization (\r
+PciAcpiInitialization (\r
)\r
{\r
- //\r
- // Device 0 Function 0\r
- //\r
- PciWrite8 (PCI_LIB_ADDRESS (0,0,0,0x3c), 0x00);\r
+ UINTN Pmba;\r
\r
//\r
- // Device 1 Function 0\r
+ // Query Host Bridge DID to determine platform type\r
//\r
- PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x3c), 0x00);\r
- PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x60), 0x8b);\r
- PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x61), 0x89);\r
- PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x62), 0x0a);\r
- PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x63), 0x89);\r
- //PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x82), 0x02);\r
+ mHostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId);\r
+ switch (mHostBridgeDevId) {\r
+ case INTEL_82441_DEVICE_ID:\r
+ Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);\r
+ //\r
+ // 00:01.0 ISA Bridge (PIIX4) LNK routing targets\r
+ //\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // A\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // B\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // C\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // D\r
+ break;\r
+ case INTEL_Q35_MCH_DEVICE_ID:\r
+ Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);\r
+ //\r
+ // 00:1f.0 LPC Bridge (Q35) LNK routing targets\r
+ //\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), 0x0a); // A\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), 0x0a); // B\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), 0x0b); // C\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), 0x0b); // D\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), 0x0a); // E\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), 0x0a); // F\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H\r
+ break;\r
+ default:\r
+ DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",\r
+ __FUNCTION__, mHostBridgeDevId));\r
+ ASSERT (FALSE);\r
+ return;\r
+ }\r
\r
//\r
- // Device 1 Function 1\r
+ // Initialize PCI_INTERRUPT_LINE for applicable present PCI devices\r
//\r
- PciWrite8 (PCI_LIB_ADDRESS (0,1,1,0x3c), 0x00);\r
+ VisitAllPciInstances (SetPciIntLine);\r
\r
//\r
- // Device 1 Function 3\r
+ // Set ACPI SCI_EN bit in PMCNTRL\r
//\r
- PciWrite8 (PCI_LIB_ADDRESS (0,1,3,0x3c), 0x0b);\r
- PciWrite8 (PCI_LIB_ADDRESS (0,1,3,0x3d), 0x01);\r
- PciWrite8 (PCI_LIB_ADDRESS (0,1,3,0x5f), 0x90);\r
+ IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0);\r
+}\r
\r
- //\r
- // Device 2 Function 0\r
- //\r
- PciWrite8 (PCI_LIB_ADDRESS (0,2,0,0x3c), 0x00);\r
\r
- //\r
- // Device 3 Function 0\r
- //\r
- PciWrite8 (PCI_LIB_ADDRESS (0,3,0,0x3c), 0x0b);\r
- PciWrite8 (PCI_LIB_ADDRESS (0,3,0,0x3d), 0x01);\r
+EFI_STATUS\r
+EFIAPI\r
+ConnectRecursivelyIfPciMassStorage (\r
+ IN EFI_HANDLE Handle,\r
+ IN EFI_PCI_IO_PROTOCOL *Instance,\r
+ IN PCI_TYPE00 *PciHeader\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ CHAR16 *DevPathStr;\r
+\r
+ if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) {\r
+ DevicePath = NULL;\r
+ Status = gBS->HandleProtocol (\r
+ Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID*)&DevicePath\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Print Device Path\r
+ //\r
+ DevPathStr = DevicePathToStr (DevicePath);\r
+ if (DevPathStr != NULL) {\r
+ DEBUG((\r
+ EFI_D_INFO,\r
+ "Found Mass Storage device: %s\n",\r
+ DevPathStr\r
+ ));\r
+ FreePool(DevPathStr);\r
+ }\r
+\r
+ Status = gBS->ConnectController (Handle, NULL, NULL, TRUE);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ This notification function is invoked when the\r
+ EMU Variable FVB has been changed.\r
+\r
+ @param Event The event that occured\r
+ @param Context For EFI compatiblity. Not used.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EmuVariablesUpdatedCallback (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ DEBUG ((EFI_D_INFO, "EmuVariablesUpdatedCallback\n"));\r
+ UpdateNvVarsOnFileSystem ();\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+VisitingFileSystemInstance (\r
+ IN EFI_HANDLE Handle,\r
+ IN VOID *Instance,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ STATIC BOOLEAN ConnectedToFileSystem = FALSE;\r
+\r
+ if (ConnectedToFileSystem) {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+\r
+ Status = ConnectNvVarsToFileSystem (Handle);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ ConnectedToFileSystem = TRUE;\r
+ mEmuVariableEvent =\r
+ EfiCreateProtocolNotifyEvent (\r
+ &gEfiDevicePathProtocolGuid,\r
+ TPL_CALLBACK,\r
+ EmuVariablesUpdatedCallback,\r
+ NULL,\r
+ &mEmuVariableEventReg\r
+ );\r
+ PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+VOID\r
+PlatformBdsRestoreNvVarsFromHardDisk (\r
+ )\r
+{\r
+ VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage);\r
+ VisitAllInstancesOfProtocol (\r
+ &gEfiSimpleFileSystemProtocolGuid,\r
+ VisitingFileSystemInstance,\r
+ NULL\r
+ );\r
+\r
}\r
\r
\r
//\r
BdsLibConnectAll ();\r
\r
- PciInitialization ();\r
+ PciAcpiInitialization ();\r
+\r
+ //\r
+ // Clear the logo after all devices are connected.\r
+ //\r
+ gST->ConOut->ClearScreen (gST->ConOut);\r
}\r
\r
VOID\r
VOID\r
PlatformBdsDiagnostics (\r
IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,\r
- IN BOOLEAN QuietBoot\r
+ IN BOOLEAN QuietBoot,\r
+ IN BASEM_MEMORY_TEST BaseMemoryTest\r
)\r
/*++\r
\r
\r
QuietBoot - Indicate if need to enable the quiet boot\r
\r
+ BaseMemoryTest - A pointer to BaseMemoryTest()\r
+\r
Returns:\r
\r
None.\r
// from the graphic lib\r
//\r
if (QuietBoot) {\r
- EnableQuietBoot (&gEfiDefaultBmpLogoGuid);\r
+ EnableQuietBoot (PcdGetPtr(PcdLogoFile));\r
//\r
// Perform system diagnostic\r
//\r
- Status = BdsMemoryTest (MemoryTestLevel);\r
+ Status = BaseMemoryTest (MemoryTestLevel);\r
if (EFI_ERROR (Status)) {\r
DisableQuietBoot ();\r
}\r
//\r
// Perform system diagnostic\r
//\r
- Status = BdsMemoryTest (MemoryTestLevel);\r
+ Status = BaseMemoryTest (MemoryTestLevel);\r
+}\r
+\r
+\r
+/**\r
+ Empty callback function executed when the EndOfDxe event group is signaled.\r
+\r
+ We only need this function because we'd like to signal EndOfDxe, and for that\r
+ we need to create an event, with a callback function.\r
+\r
+ @param[in] Event Event whose notification function is being invoked.\r
+ @param[in] Context The pointer to the notification function's context, which\r
+ is implementation-dependent.\r
+**/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+OnEndOfDxe (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+}\r
+\r
+\r
+/**\r
+ Save the S3 boot script.\r
+\r
+ Note that we trigger DxeSmmReadyToLock here -- otherwise the script wouldn't\r
+ be saved actually. Triggering this protocol installation event in turn locks\r
+ down SMM, so no further changes to LockBoxes or SMRAM are possible\r
+ afterwards.\r
+**/\r
+STATIC\r
+VOID\r
+SaveS3BootScript (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_S3_SAVE_STATE_PROTOCOL *BootScript;\r
+ EFI_HANDLE Handle;\r
+ STATIC CONST UINT8 Info[] = { 0xDE, 0xAD, 0xBE, 0xEF };\r
+\r
+ Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid, NULL,\r
+ (VOID **) &BootScript);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Despite the opcode documentation in the PI spec, the protocol\r
+ // implementation embeds a deep copy of the info in the boot script, rather\r
+ // than storing just a pointer to runtime or NVS storage.\r
+ //\r
+ Status = BootScript->Write(BootScript, EFI_BOOT_SCRIPT_INFORMATION_OPCODE,\r
+ (UINT32) sizeof Info,\r
+ (EFI_PHYSICAL_ADDRESS)(UINTN) &Info);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Handle = NULL;\r
+ Status = gBS->InstallProtocolInterface (&Handle,\r
+ &gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE,\r
+ NULL);\r
+ ASSERT_EFI_ERROR (Status);\r
}\r
\r
\r
VOID\r
EFIAPI\r
PlatformBdsPolicyBehavior (\r
- IN EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData,\r
IN OUT LIST_ENTRY *DriverOptionList,\r
- IN OUT LIST_ENTRY *BootOptionList\r
+ IN OUT LIST_ENTRY *BootOptionList,\r
+ IN PROCESS_CAPSULES ProcessCapsules,\r
+ IN BASEM_MEMORY_TEST BaseMemoryTest\r
)\r
/*++\r
\r
\r
Arguments:\r
\r
- PrivateData - The EFI_BDS_ARCH_PROTOCOL_INSTANCE instance\r
-\r
DriverOptionList - The header of the driver option link list\r
\r
BootOptionList - The header of the boot option link list\r
\r
+ ProcessCapsules - A pointer to ProcessCapsules()\r
+\r
+ BaseMemoryTest - A pointer to BaseMemoryTest()\r
+\r
Returns:\r
\r
None.\r
--*/\r
{\r
EFI_STATUS Status;\r
- UINT16 Timeout;\r
- EFI_EVENT UserInputDurationTime;\r
- LIST_ENTRY *Link;\r
- BDS_COMMON_OPTION *BootOption;\r
- UINTN Index;\r
- EFI_INPUT_KEY Key;\r
- EFI_TPL OldTpl;\r
+ EFI_BOOT_MODE BootMode;\r
+ EFI_EVENT EndOfDxeEvent;\r
\r
DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior\n"));\r
\r
+ VisitAllInstancesOfProtocol (&gEfiPciRootBridgeIoProtocolGuid,\r
+ ConnectRootBridge, NULL);\r
+\r
//\r
- // Init the time out value\r
+ // We can't signal End-of-Dxe earlier than this. Namely, End-of-Dxe triggers\r
+ // the preparation of S3 system information. That logic has a hard dependency\r
+ // on the presence of the FACS ACPI table. Since our ACPI tables are only\r
+ // installed after PCI enumeration completes, we must not trigger the S3 save\r
+ // earlier, hence we can't signal End-of-Dxe earlier.\r
//\r
- Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
+ Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, OnEndOfDxe,\r
+ NULL /* NotifyContext */, &gEfiEndOfDxeEventGroupGuid,\r
+ &EndOfDxeEvent);\r
+ if (!EFI_ERROR (Status)) {\r
+ gBS->SignalEvent (EndOfDxeEvent);\r
+ gBS->CloseEvent (EndOfDxeEvent);\r
+ }\r
+\r
+ if (QemuFwCfgS3Enabled ()) {\r
+ //\r
+ // Save the boot script too. Note that this requires/includes emitting the\r
+ // DxeSmmReadyToLock event, which in turn locks down SMM.\r
+ //\r
+ SaveS3BootScript ();\r
+ }\r
+\r
+ if (PcdGetBool (PcdOvmfFlashVariablesEnable)) {\r
+ DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars "\r
+ "from disk since flash variables appear to be supported.\n"));\r
+ } else {\r
+ //\r
+ // Try to restore variables from the hard disk early so\r
+ // they can be used for the other BDS connect operations.\r
+ //\r
+ PlatformBdsRestoreNvVarsFromHardDisk ();\r
+ }\r
\r
//\r
// Load the driver option as the driver option list\r
//\r
// Get current Boot Mode\r
//\r
- Status = BdsLibGetBootMode (&PrivateData->BootMode);\r
- DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", PrivateData->BootMode));\r
+ Status = BdsLibGetBootMode (&BootMode);\r
+ DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));\r
\r
//\r
// Go the different platform policy with different boot mode\r
// Notes: this part code can be change with the table policy\r
//\r
- ASSERT (PrivateData->BootMode == BOOT_WITH_FULL_CONFIGURATION);\r
+ ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);\r
//\r
// Connect platform console\r
//\r
//\r
PlatformBdsNoConsoleAction ();\r
}\r
- //\r
- // Create a 300ms duration event to ensure user has enough input time to enter Setup\r
- //\r
- Status = gBS->CreateEvent (\r
- EVT_TIMER,\r
- 0,\r
- NULL,\r
- NULL,\r
- &UserInputDurationTime\r
- );\r
- ASSERT (Status == EFI_SUCCESS);\r
- Status = gBS->SetTimer (UserInputDurationTime, TimerRelative, 3000000);\r
- ASSERT (Status == EFI_SUCCESS);\r
+\r
//\r
// Memory test and Logo show\r
//\r
- PlatformBdsDiagnostics (IGNORE, TRUE);\r
+ PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);\r
\r
//\r
// Perform some platform specific connect sequence\r
PlatformBdsConnectSequence ();\r
\r
//\r
- // Give one chance to enter the setup if we\r
- // have the time out\r
+ // Process QEMU's -kernel command line option\r
//\r
- if (Timeout != 0) {\r
- //PlatformBdsEnterFrontPage (Timeout, FALSE);\r
- }\r
+ TryRunningQemuKernel ();\r
\r
DEBUG ((EFI_D_INFO, "BdsLibConnectAll\n"));\r
BdsLibConnectAll ();\r
BdsLibEnumerateAllBootOption (BootOptionList);\r
\r
+ SetBootOrderFromQemu (BootOptionList);\r
//\r
- // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot\r
- // checking code in real production tip.\r
- //\r
- // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device\r
- // and do enumerate all the default boot options. But in development system board, the boot mode\r
- // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box\r
- // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.\r
- //\r
- Status = BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
- if (EFI_ERROR(Status)) {\r
- //\r
- // If cannot find "BootOrder" variable, it may be first boot.\r
- // Try to connect all devices and enumerate all boot options here.\r
- //\r
- BdsLibConnectAll ();\r
- BdsLibEnumerateAllBootOption (BootOptionList);\r
- }\r
-\r
- //\r
- // To give the User a chance to enter Setup here, if user set TimeOut is 0.\r
- // BDS should still give user a chance to enter Setup\r
- //\r
- // Connect first boot option, and then check user input before exit\r
- //\r
- for (Link = BootOptionList->ForwardLink; Link != BootOptionList;Link = Link->ForwardLink) {\r
- BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
- if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {\r
- //\r
- // skip the header of the link list, becuase it has no boot option\r
- //\r
- continue;\r
- } else {\r
- //\r
- // Make sure the boot option device path connected, but ignore the BBS device path\r
- //\r
- if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {\r
- BdsLibConnectDevicePath (BootOption->DevicePath);\r
- }\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // Check whether the user input after the duration time has expired\r
+ // The BootOrder variable may have changed, reload the in-memory list with\r
+ // it.\r
//\r
- OldTpl = EfiGetCurrentTpl();\r
- gBS->RestoreTPL (TPL_APPLICATION);\r
- gBS->WaitForEvent (1, &UserInputDurationTime, &Index);\r
- gBS->CloseEvent (UserInputDurationTime);\r
- Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
- gBS->RaiseTPL (OldTpl);\r
-\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Enter Setup if user input\r
- //\r
- Timeout = 0xffff;\r
- PlatformBdsEnterFrontPage (Timeout, FALSE);\r
- }\r
+ BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
\r
- return ;\r
+ PlatformBdsEnterFrontPage (GetFrontPageTimeoutFromQemu(), TRUE);\r
}\r
\r
VOID\r
return EFI_SUCCESS;\r
}\r
\r
-EFI_STATUS\r
+VOID\r
EFIAPI\r
PlatformBdsLockNonUpdatableFlash (\r
VOID\r
)\r
{\r
DEBUG ((EFI_D_INFO, "PlatformBdsLockNonUpdatableFlash\n"));\r
- return EFI_SUCCESS;\r
+ return;\r
}\r
+\r
+\r
+/**\r
+ This notification function is invoked when an instance of the\r
+ EFI_DEVICE_PATH_PROTOCOL is produced.\r
+\r
+ @param Event The event that occured\r
+ @param Context For EFI compatiblity. Not used.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+NotifyDevPath (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_HANDLE Handle;\r
+ EFI_STATUS Status;\r
+ UINTN BufferSize;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode;\r
+ ATAPI_DEVICE_PATH *Atapi;\r
+\r
+ //\r
+ // Examine all new handles\r
+ //\r
+ for (;;) {\r
+ //\r
+ // Get the next handle\r
+ //\r
+ BufferSize = sizeof (Handle);\r
+ Status = gBS->LocateHandle (\r
+ ByRegisterNotify,\r
+ NULL,\r
+ mEfiDevPathNotifyReg,\r
+ &BufferSize,\r
+ &Handle\r
+ );\r
+\r
+ //\r
+ // If not found, we're done\r
+ //\r
+ if (EFI_NOT_FOUND == Status) {\r
+ break;\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Get the DevicePath protocol on that handle\r
+ //\r
+ Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPathNode);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ while (!IsDevicePathEnd (DevPathNode)) {\r
+ //\r
+ // Find the handler to dump this device path node\r
+ //\r
+ if (\r
+ (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) &&\r
+ (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP)\r
+ ) {\r
+ Atapi = (ATAPI_DEVICE_PATH*) DevPathNode;\r
+ PciOr16 (\r
+ PCI_LIB_ADDRESS (\r
+ 0,\r
+ 1,\r
+ 1,\r
+ (Atapi->PrimarySecondary == 1) ? 0x42: 0x40\r
+ ),\r
+ BIT15\r
+ );\r
+ }\r
+\r
+ //\r
+ // Next device path node\r
+ //\r
+ DevPathNode = NextDevicePathNode (DevPathNode);\r
+ }\r
+ }\r
+\r
+ return;\r
+}\r
+\r
+\r
+VOID\r
+InstallDevicePathCallback (\r
+ VOID\r
+ )\r
+{\r
+ DEBUG ((EFI_D_INFO, "Registered NotifyDevPath Event\n"));\r
+ mEfiDevPathEvent = EfiCreateProtocolNotifyEvent (\r
+ &gEfiDevicePathProtocolGuid,\r
+ TPL_CALLBACK,\r
+ NotifyDevPath,\r
+ NULL,\r
+ &mEfiDevPathNotifyReg\r
+ );\r
+}\r
+\r
+/**\r
+ Lock the ConsoleIn device in system table. All key\r
+ presses will be ignored until the Password is typed in. The only way to\r
+ disable the password is to type it in to a ConIn device.\r
+\r
+ @param Password Password used to lock ConIn device.\r
+\r
+ @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.\r
+ @retval EFI_UNSUPPORTED Password not found\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LockKeyboards (\r
+ IN CHAR16 *Password\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r