/** @file\r
Platform BDS customizations.\r
\r
- Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
+ Copyright (c) 2004 - 2009, Intel Corporation. <BR>\r
All rights reserved. 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
#include "BdsPlatform.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
+\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
+STATIC\r
+VOID\r
+LoadVideoRom (\r
+ VOID\r
+ );\r
+\r
+STATIC\r
+EFI_STATUS\r
+PciRomLoadEfiDriversFromRomImage (\r
+ IN EFI_PHYSICAL_ADDRESS Rom,\r
+ IN UINTN RomSize\r
+ );\r
+\r
//\r
// BDS Platform Functions\r
//\r
--*/\r
{\r
DEBUG ((EFI_D_INFO, "PlatformBdsInit\n"));\r
+ InstallDevicePathCallback ();\r
+ LoadVideoRom ();\r
}\r
\r
\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
- // Device 0 Function 0\r
+ // Bus 0, Device 0, Function 0 - Host to PCI Bridge\r
//\r
- PciWrite8 (PCI_LIB_ADDRESS (0,0,0,0x3c), 0x00);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0, 0, 0x3c), 0x00);\r
\r
//\r
- // Device 1 Function 0\r
+ // Bus 0, Device 1, Function 0 - PCI to ISA Bridge\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
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x3c), 0x00);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x09);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0b);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x09);\r
\r
//\r
- // Device 1 Function 1\r
+ // Bus 0, Device 1, Function 1 - IDE Controller\r
//\r
- PciWrite8 (PCI_LIB_ADDRESS (0,1,1,0x3c), 0x00);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x3c), 0x00);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x0d), 0x40);\r
\r
//\r
- // Device 1 Function 3\r
+ // Bus 0, Device 1, Function 3 - Power Managment Controller\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
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3c), 0x0b);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3d), 0x01);\r
\r
//\r
- // Device 2 Function 0\r
+ // Bus 0, Device 2, Function 0 - Video Controller\r
//\r
- PciWrite8 (PCI_LIB_ADDRESS (0,2,0,0x3c), 0x00);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 2, 0, 0x3c), 0x00);\r
\r
//\r
- // Device 3 Function 0\r
+ // Bus 0, Device 3, Function 0 - Network Controller\r
//\r
- PciWrite8 (PCI_LIB_ADDRESS (0,3,0,0x3c), 0x0b);\r
- PciWrite8 (PCI_LIB_ADDRESS (0,3,0,0x3d), 0x01);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0b);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3d), 0x01);\r
+\r
+ //\r
+ // Bus 0, Device 4, Function 0 - RAM Memory\r
+ //\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3c), 0x09);\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3d), 0x01);\r
+}\r
+\r
+\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
+ DEBUG((\r
+ EFI_D_INFO,\r
+ "Found Mass Storage device: %s\n",\r
+ DevPathStr\r
+ ));\r
+ FreePool(DevPathStr);\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
BdsLibConnectAll ();\r
\r
PciInitialization ();\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
EFIAPI\r
PlatformBdsPolicyBehavior (\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
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
DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior\n"));\r
\r
+ ConnectRootBridge ();\r
+\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
// Init the time out value\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
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
+\r
+STATIC\r
+VOID\r
+LoadVideoRom (\r
+ VOID\r
+ )\r
+{\r
+ PCI_DATA_STRUCTURE *Pcir;\r
+ UINTN RomSize;\r
+\r
+ //\r
+ // The virtual machines sometimes load the video rom image\r
+ // directly at the legacy video BIOS location of C000:0000,\r
+ // and do not implement the PCI expansion ROM feature.\r
+ //\r
+ Pcir = (PCI_DATA_STRUCTURE *) (UINTN) 0xc0000;\r
+ RomSize = Pcir->ImageLength * 512;\r
+ PciRomLoadEfiDriversFromRomImage (0xc0000, RomSize);\r
+}\r
+\r
+\r
+STATIC\r
+EFI_STATUS\r
+PciRomLoadEfiDriversFromRomImage (\r
+ IN EFI_PHYSICAL_ADDRESS Rom,\r
+ IN UINTN RomSize\r
+ )\r
+{\r
+ CHAR16 *FileName;\r
+ EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;\r
+ PCI_DATA_STRUCTURE *Pcir;\r
+ UINTN ImageIndex;\r
+ UINTN RomOffset;\r
+ UINT32 ImageSize;\r
+ UINT16 ImageOffset;\r
+ EFI_HANDLE ImageHandle;\r
+ EFI_STATUS Status;\r
+ EFI_STATUS retStatus;\r
+ EFI_DEVICE_PATH_PROTOCOL *FilePath;\r
+ BOOLEAN SkipImage;\r
+ UINT32 DestinationSize;\r
+ UINT32 ScratchSize;\r
+ UINT8 *Scratch;\r
+ VOID *ImageBuffer;\r
+ VOID *DecompressedImageBuffer;\r
+ UINT32 ImageLength;\r
+ EFI_DECOMPRESS_PROTOCOL *Decompress;\r
+\r
+ FileName = L"PciRomInMemory";\r
+\r
+ //FileName = L"PciRom Addr=0000000000000000";\r
+ //HexToString (&FileName[12], Rom, 16);\r
+\r
+ ImageIndex = 0;\r
+ retStatus = EFI_NOT_FOUND;\r
+ RomOffset = (UINTN) Rom;\r
+\r
+ do {\r
+\r
+ EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomOffset;\r
+\r
+ if (EfiRomHeader->Signature != 0xaa55) {\r
+ return retStatus;\r
+ }\r
+\r
+ Pcir = (PCI_DATA_STRUCTURE *) (UINTN) (RomOffset + EfiRomHeader->PcirOffset);\r
+ ImageSize = Pcir->ImageLength * 512;\r
+\r
+ if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&\r
+ (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) ) {\r
+\r
+ if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
+ (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) ) {\r
+\r
+ ImageOffset = EfiRomHeader->EfiImageHeaderOffset;\r
+ ImageSize = EfiRomHeader->InitializationSize * 512;\r
+\r
+ ImageBuffer = (VOID *) (UINTN) (RomOffset + ImageOffset);\r
+ ImageLength = ImageSize - ImageOffset;\r
+ DecompressedImageBuffer = NULL;\r
+\r
+ //\r
+ // decompress here if needed\r
+ //\r
+ SkipImage = FALSE;\r
+ if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
+ SkipImage = TRUE;\r
+ }\r
+\r
+ if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
+ Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);\r
+ if (EFI_ERROR (Status)) {\r
+ SkipImage = TRUE;\r
+ } else {\r
+ SkipImage = TRUE;\r
+ Status = Decompress->GetInfo (\r
+ Decompress,\r
+ ImageBuffer,\r
+ ImageLength,\r
+ &DestinationSize,\r
+ &ScratchSize\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ DecompressedImageBuffer = NULL;\r
+ DecompressedImageBuffer = AllocatePool (DestinationSize);\r
+ if (DecompressedImageBuffer != NULL) {\r
+ Scratch = AllocatePool (ScratchSize);\r
+ if (Scratch != NULL) {\r
+ Status = Decompress->Decompress (\r
+ Decompress,\r
+ ImageBuffer,\r
+ ImageLength,\r
+ DecompressedImageBuffer,\r
+ DestinationSize,\r
+ Scratch,\r
+ ScratchSize\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ ImageBuffer = DecompressedImageBuffer;\r
+ ImageLength = DestinationSize;\r
+ SkipImage = FALSE;\r
+ }\r
+\r
+ gBS->FreePool (Scratch);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!SkipImage) {\r
+\r
+ //\r
+ // load image and start image\r
+ //\r
+\r
+ FilePath = FileDevicePath (NULL, FileName);\r
+\r
+ Status = gBS->LoadImage (\r
+ FALSE,\r
+ gImageHandle,\r
+ FilePath,\r
+ ImageBuffer,\r
+ ImageLength,\r
+ &ImageHandle\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
+ if (!EFI_ERROR (Status)) {\r
+ retStatus = Status;\r
+ }\r
+ }\r
+ if (FilePath != NULL) {\r
+ gBS->FreePool (FilePath);\r
+ }\r
+ }\r
+\r
+ if (DecompressedImageBuffer != NULL) {\r
+ gBS->FreePool (DecompressedImageBuffer);\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+ RomOffset = RomOffset + ImageSize;\r
+ ImageIndex++;\r
+ } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomOffset - (UINTN) Rom) < RomSize));\r
+\r
+ return retStatus;\r
+}\r
+\r
+\r