documentation on UGA for details on how to write a UGA driver that is able\r
to function both in the EFI pre-boot environment and from the OS runtime.\r
\r
- Copyright (c) 2006, Intel Corporation\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
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
EFI_STATUS Status;\r
EFI_PCI_IO_PROTOCOL *PciIo;\r
PCI_TYPE00 Pci;\r
+ EFI_DEV_PATH *Node;\r
\r
//\r
// Open the PCI I/O Protocol\r
//\r
// See if this is a 5430 or a 5446 PCI controller\r
//\r
- if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID) {\r
- Status = EFI_SUCCESS;\r
- }\r
-\r
- if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID) {\r
- Status = EFI_SUCCESS;\r
- }\r
-\r
- if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) {\r
+ if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID || \r
+ Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID ||\r
+ Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) {\r
+ \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
\r
BOOLEAN PciAttributesSaved;\r
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
ACPI_ADR_DEVICE_PATH AcpiDeviceNode;\r
+ UINT64 Supports;\r
\r
PciAttributesSaved = FALSE;\r
//\r
goto Error;\r
}\r
\r
+ //\r
+ // Get supported PCI attributes\r
+ //\r
+ Status = Private->PciIo->Attributes (\r
+ Private->PciIo,\r
+ EfiPciIoAttributeOperationSupported,\r
+ 0,\r
+ &Supports\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error;\r
+ }\r
+\r
+ Supports &= (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16);\r
+ if (Supports == 0 || Supports == (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) {\r
+ Status = EFI_UNSUPPORTED;\r
+ goto Error;\r
+ } \r
+\r
//\r
// Save original PCI attributes\r
//\r
PciAttributesSaved = TRUE;\r
\r
Status = Private->PciIo->Attributes (\r
- Private->PciIo,\r
- EfiPciIoAttributeOperationEnable,\r
- EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,\r
- NULL\r
- );\r
+ Private->PciIo,\r
+ EfiPciIoAttributeOperationEnable,\r
+ EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | Supports,\r
+ NULL\r
+ );\r
if (EFI_ERROR (Status)) {\r
goto Error;\r
}\r
ParentDevicePath,\r
(EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode\r
);\r
- } else {\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
+ } else {\r
+ //\r
+ // If RemainingDevicePath is the End of Device Path Node, \r
+ // don't create child device and return EFI_SUCCESS\r
+ //\r
+ Private->GopDevicePath = NULL;\r
+ }\r
+ \r
+ if (Private->GopDevicePath != NULL) {\r
+ //\r
+ // Creat child handle and device path protocol firstly\r
+ //\r
+ Private->Handle = NULL;\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &Private->Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ Private->GopDevicePath,\r
+ NULL\r
+ );\r
}\r
-\r
- //\r
- // Creat child handle and device path protocol firstly\r
- //\r
- Private->Handle = NULL;\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &Private->Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- Private->GopDevicePath,\r
- NULL\r
- );\r
}\r
\r
//\r
);\r
\r
} else if (FeaturePcdGet (PcdSupportGop)) {\r
- //\r
- // Start the GOP software stack.\r
- //\r
- Status = CirrusLogic5430GraphicsOutputConstructor (Private);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &Private->Handle,\r
- &gEfiGraphicsOutputProtocolGuid,\r
- &Private->GraphicsOutput,\r
- &gEfiEdidDiscoveredProtocolGuid,\r
- &Private->EdidDiscovered,\r
- &gEfiEdidActiveProtocolGuid,\r
- &Private->EdidActive,\r
- NULL\r
- );\r
-\r
+ if (Private->GopDevicePath == NULL) {\r
+ //\r
+ // If RemainingDevicePath is the End of Device Path Node, \r
+ // don't create child device and return EFI_SUCCESS\r
+ //\r
+ Status = EFI_SUCCESS;\r
+ } else {\r
+ \r
+ //\r
+ // Start the GOP software stack.\r
+ //\r
+ Status = CirrusLogic5430GraphicsOutputConstructor (Private);\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &Private->Handle,\r
+ &gEfiGraphicsOutputProtocolGuid,\r
+ &Private->GraphicsOutput,\r
+ &gEfiEdidDiscoveredProtocolGuid,\r
+ &Private->EdidDiscovered,\r
+ &gEfiEdidActiveProtocolGuid,\r
+ &Private->EdidActive,\r
+ NULL\r
+ );\r
+ }\r
} else {\r
//\r
// This driver must support eithor GOP or UGA or both.\r
UINT8 Byte;\r
UINTN Index;\r
UINT16 DeviceId;\r
-\r
+ EFI_STATUS Status;\r
+\r
+ Status = Private->PciIo->Pci.Read (\r
+ Private->PciIo,\r
+ EfiPciIoWidthUint16,\r
+ PCI_DEVICE_ID_OFFSET,\r
+ 1,\r
+ &DeviceId\r
+ );\r
//\r
// Read the PCI Configuration Header from the PCI Device\r
//\r
- ASSERT_EFI_ERROR (\r
- Private->PciIo->Pci.Read (\r
- Private->PciIo,\r
- EfiPciIoWidthUint16,\r
- PCI_DEVICE_ID_OFFSET,\r
- 1,\r
- &DeviceId\r
- )\r
- );\r
+ ASSERT_EFI_ERROR (Status);\r
\r
outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);\r
outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);\r