#include "BdsPlatform.h"\r
\r
\r
+//\r
+// Global data\r
+//\r
+\r
+VOID *mEfiDevPathNotifyReg;\r
+EFI_EVENT mEfiDevPathEvent;\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) 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*) 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
+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
+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
+ 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