EFI_STATUS Status;\r
EFI_PCI_IO_PROTOCOL *PciIo;\r
PCI_TYPE00 Pci;\r
- EFI_DEV_PATH *Node;\r
QEMU_VIDEO_CARD *Card;\r
\r
//\r
}\r
\r
Status = EFI_UNSUPPORTED;\r
- //\r
- // See if the I/O enable is on. Most systems only allow one VGA device to be turned on\r
- // at a time, so see if this is one that is turned on.\r
- //\r
- // if (((Pci.Hdr.Command & 0x01) == 0x01)) {\r
- //\r
- // See if this is a Cirrus Logic PCI controller\r
- //\r
Card = QemuVideoDetect(Pci.Hdr.VendorId, Pci.Hdr.DeviceId);\r
if (Card != NULL) {\r
DEBUG ((EFI_D_INFO, "QemuVideo: %s detected\n", Card->Name));\r
Status = EFI_SUCCESS;\r
- //\r
- // If this is an Intel 945 graphics controller,\r
- // go further check RemainingDevicePath validation\r
- //\r
- if (RemainingDevicePath != NULL) {\r
- Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
- //\r
- // Check if RemainingDevicePath is the End of Device Path Node, \r
- // if yes, return EFI_SUCCESS\r
- //\r
- if (!IsDevicePathEnd (Node)) {\r
- //\r
- // If RemainingDevicePath isn't the End of Device Path Node,\r
- // check its validation\r
- //\r
- if (Node->DevPath.Type != ACPI_DEVICE_PATH ||\r
- Node->DevPath.SubType != ACPI_ADR_DP ||\r
- DevicePathNodeLength(&Node->DevPath) != sizeof(ACPI_ADR_DEVICE_PATH)) {\r
- Status = EFI_UNSUPPORTED;\r
- }\r
- }\r
- }\r
}\r
\r
Done:\r
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
)\r
{\r
+ EFI_TPL OldTpl;\r
EFI_STATUS Status;\r
QEMU_VIDEO_PRIVATE_DATA *Private;\r
+ BOOLEAN IsQxl;\r
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ ACPI_ADR_DEVICE_PATH AcpiDeviceNode;\r
PCI_TYPE00 Pci;\r
QEMU_VIDEO_CARD *Card;\r
EFI_PCI_IO_PROTOCOL *ChildPciIo;\r
\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
//\r
// Allocate Private context data for GOP inteface.\r
//\r
Private = AllocateZeroPool (sizeof (QEMU_VIDEO_PRIVATE_DATA));\r
if (Private == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto RestoreTpl;\r
}\r
\r
//\r
}\r
Private->Variant = Card->Variant;\r
\r
+ //\r
+ // IsQxl is based on the detected Card->Variant, which at a later point might\r
+ // not match Private->Variant.\r
+ //\r
+ IsQxl = (BOOLEAN)(Card->Variant == QEMU_VIDEO_BOCHS);\r
+\r
//\r
// Save original PCI attributes\r
//\r
//\r
// Set Gop Device Path\r
//\r
- if (RemainingDevicePath == NULL) {\r
- ACPI_ADR_DEVICE_PATH AcpiDeviceNode;\r
-\r
- ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));\r
- AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;\r
- AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;\r
- AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);\r
- SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));\r
-\r
- Private->GopDevicePath = AppendDevicePathNode (\r
- ParentDevicePath,\r
- (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode\r
- );\r
- if (Private->GopDevicePath == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto RestoreAttributes;\r
- }\r
- } else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
- //\r
- // If RemainingDevicePath isn't the End of Device Path Node, \r
- // only scan the specified device by RemainingDevicePath\r
- //\r
- Private->GopDevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath);\r
- if (Private->GopDevicePath == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto RestoreAttributes;\r
- }\r
+ ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));\r
+ AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;\r
+ AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;\r
+ AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);\r
+ SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));\r
+\r
+ Private->GopDevicePath = AppendDevicePathNode (\r
+ ParentDevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode\r
+ );\r
+ if (Private->GopDevicePath == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto RestoreAttributes;\r
}\r
\r
//\r
- // Create new child handle and install the device path protocol on it only if\r
- // RemainingDevicePath equals NULL, or doesn't point to the End of Device\r
- // Path Node.\r
+ // Create new child handle and install the device path protocol on it.\r
//\r
- if (Private->GopDevicePath != NULL) {\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &Private->Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- Private->GopDevicePath,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto FreeGopDevicePath;\r
- }\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &Private->Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ Private->GopDevicePath,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto FreeGopDevicePath;\r
}\r
\r
//\r
break;\r
case QEMU_VIDEO_BOCHS_MMIO:\r
case QEMU_VIDEO_BOCHS:\r
- Status = QemuVideoBochsModeSetup (Private);\r
+ Status = QemuVideoBochsModeSetup (Private, IsQxl);\r
break;\r
default:\r
ASSERT (FALSE);\r
goto UninstallGopDevicePath;\r
}\r
\r
- //\r
- // If RemainingDevicePath points to the End of Device Path Node, then we\r
- // haven't created a child handle, and we're done.\r
- //\r
- if (Private->GopDevicePath == NULL) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
//\r
// Start the GOP software stack.\r
//\r
goto UninstallGop;\r
}\r
\r
+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO ||\r
+ Private->Variant == QEMU_VIDEO_BOCHS) {\r
+ InstallVbeShim (Card->Name, Private->GraphicsOutput.Mode->FrameBufferBase);\r
+ }\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
return EFI_SUCCESS;\r
\r
UninstallGop:\r
FreePool (Private->ModeData);\r
\r
UninstallGopDevicePath:\r
- //\r
- // Handles the case transparently when Private->Handle and\r
- // Private->GopDevicePath are NULL.\r
- //\r
gBS->UninstallProtocolInterface (Private->Handle,\r
&gEfiDevicePathProtocolGuid, Private->GopDevicePath);\r
\r
FreeGopDevicePath:\r
- if (Private->GopDevicePath != NULL) {\r
- FreePool (Private->GopDevicePath);\r
- }\r
+ FreePool (Private->GopDevicePath);\r
\r
RestoreAttributes:\r
Private->PciIo->Attributes (Private->PciIo, EfiPciIoAttributeOperationSet,\r
FreePrivate:\r
FreePool (Private);\r
\r
+RestoreTpl:\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
return Status;\r
}\r
\r
EFI_STATUS Status;\r
QEMU_VIDEO_PRIVATE_DATA *Private;\r
\r
+ if (NumberOfChildren == 0) {\r
+ //\r
+ // Close the PCI I/O Protocol\r
+ //\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // free all resources for whose access we need the child handle, because the\r
+ // child handle is going away\r
+ //\r
+ ASSERT (NumberOfChildren == 1);\r
Status = gBS->OpenProtocol (\r
- Controller,\r
+ ChildHandleBuffer[0],\r
&gEfiGraphicsOutputProtocolGuid,\r
(VOID **) &GraphicsOutput,\r
This->DriverBindingHandle,\r
// Get our private context information\r
//\r
Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);\r
+ ASSERT (Private->Handle == ChildHandleBuffer[0]);\r
\r
QemuVideoGraphicsOutputDestructor (Private);\r
//\r
NULL\r
);\r
\r
- //\r
- // Close the PCI I/O Protocol\r
- //\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
gBS->CloseProtocol (\r
Controller,\r
&gEfiPciIoProtocolGuid,\r
Private->Handle\r
);\r
\r
+ FreePool (Private->ModeData);\r
+ gBS->UninstallProtocolInterface (Private->Handle,\r
+ &gEfiDevicePathProtocolGuid, Private->GopDevicePath);\r
+ FreePool (Private->GopDevicePath);\r
+\r
//\r
// Free our instance data\r
//\r