From c51cec25606163ee3cc478f5d4598227558195c5 Mon Sep 17 00:00:00 2001 From: cwu11 Date: Fri, 13 Oct 2006 04:12:23 +0000 Subject: [PATCH] The reasons for the changes made are: 1)PciCommand.h: Add some macro constants definitions that will be used by other changes. 2)PciDeviceSupport.c: a)Fix the bug that programs Non-Bridge Devices' Interrupt Line Register to 0x00. Although this register is rarely used in modern OS (actually, only Dos still uses it), it is good practice to modify it so it will align the spec. Please refer to PCI 3.0 Spec for the chapter on Interrupt line register. b) Change the way used to detect VGA device. The old method will fail. 3)PciEnumeratorSupport.c: Make changes so Pci Driver will preserve those bits in Command & Bridge Control Register that were set by Customer's Chipset initialization code. Pci Driver is supposed to only touch those bits that are generic. Problems will arise if we destroy some initializations already done. 4)PciIo.c: PollIo() is not conformant to EFI spec so fix it. Also, some fixes are introduced to better support VGA card. These modifications are supposed to work with fixes in PciDeviceSupport.c. 5) PciOptionromSupport.c:Add the fix to enhance the logic working with OptionRom. Some legacy cards do not report correct imagelength so we add double check. And add EFI_MIN and EFI_MAX macro definition since they are not currently defined in global files. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1738 6f19259b-4bc3-4df7-8a09-765794883524 --- EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.h | 41 +++++++++++++++++++ .../Bus/Pci/PciBus/Dxe/PciDeviceSupport.c | 9 +++- .../Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c | 17 +++++--- EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c | 39 ++++++++++++------ .../Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c | 20 +++++++++ 5 files changed, 106 insertions(+), 20 deletions(-) diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.h b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.h index 56f632e8da..e63d0d1525 100644 --- a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.h +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciCommand.h @@ -24,6 +24,47 @@ Revision History #ifndef _EFI_PCI_COMMAND_H #define _EFI_PCI_COMMAND_H +// +// The PCI Command register bits owned by PCI Bus driver. +// +// They should be cleared at the beginning. The other registers +// are owned by chipset, we should not touch them. +// +#define EFI_PCI_COMMAND_BITS_OWNED ( \ + EFI_PCI_COMMAND_IO_SPACE | \ + EFI_PCI_COMMAND_MEMORY_SPACE | \ + EFI_PCI_COMMAND_BUS_MASTER | \ + EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE | \ + EFI_PCI_COMMAND_VGA_PALETTE_SNOOP | \ + EFI_PCI_COMMAND_FAST_BACK_TO_BACK \ + ) + +// +// The PCI Bridge Control register bits owned by PCI Bus driver. +// +// They should be cleared at the beginning. The other registers +// are owned by chipset, we should not touch them. +// +#define EFI_PCI_BRIDGE_CONTROL_BITS_OWNED ( \ + EFI_PCI_BRIDGE_CONTROL_ISA | \ + EFI_PCI_BRIDGE_CONTROL_VGA | \ + EFI_PCI_BRIDGE_CONTROL_VGA_16 | \ + EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \ + ) + +// +// The PCCard Bridge Control register bits owned by PCI Bus driver. +// +// They should be cleared at the beginning. The other registers +// are owned by chipset, we should not touch them. +// +#define EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED ( \ + EFI_PCI_BRIDGE_CONTROL_ISA | \ + EFI_PCI_BRIDGE_CONTROL_VGA | \ + EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \ + ) + + #define EFI_GET_REGISTER 1 #define EFI_SET_REGISTER 2 #define EFI_ENABLE_REGISTER 3 diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.c index 54a7fe7452..77e7cbaa82 100644 --- a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.c +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciDeviceSupport.c @@ -305,6 +305,7 @@ Returns: UINTN PlatformOpRomSize; UINT8 PciExpressCapRegOffset; EFI_PCI_IO_PROTOCOL *PciIo; + UINT8 Data8; // // Install the pciio protocol, device path protocol @@ -339,7 +340,8 @@ Returns: // Force Interrupt line to zero for cards that come up randomly // PciIo = &(PciIoDevice->PciIo); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero); + Data8 = 0xFF; + PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &Data8); // // Process Platform OpRom // @@ -1149,7 +1151,10 @@ Returns: Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); if (IS_PCI_VGA(&Temp->Pci) && - (Temp->Attributes & (EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_IO))) { + (Temp->Attributes & + (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | + EFI_PCI_IO_ATTRIBUTE_VGA_IO | + EFI_PCI_IO_ATTRIBUTE_VGA_IO_16))) { return Temp; } diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c index 80bc7d4daf..ce605cc813 100644 --- a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciEnumeratorSupport.c @@ -394,7 +394,7 @@ Returns: // if (gFullEnumeration) { - PciSetCommandRegister (PciIoDevice, 0); + PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED); } @@ -462,12 +462,12 @@ Returns: ); if (gFullEnumeration) { - PciSetCommandRegister (PciIoDevice, 0); + PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED); // // Initalize the bridge control register // - PciSetBridgeControlRegister (PciIoDevice, 0); + PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED); } @@ -586,12 +586,12 @@ Returns: ); if (gFullEnumeration) { - PciSetCommandRegister (PciIoDevice, 0); + PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED); // // Initalize the bridge control register // - PciSetBridgeControlRegister (PciIoDevice, 0); + PciDisableBridgeControlRegister (PciIoDevice, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED); } // @@ -871,6 +871,11 @@ Returns: Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO; } + if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA_16) { + Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO_16; + Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16; + } + if (Option == EFI_SET_SUPPORTS) { Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE | @@ -1066,7 +1071,7 @@ Returns: EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_VGA_PALETTE_SNOOP; - BridgeControl = EFI_PCI_BRIDGE_CONTROL_ISA | EFI_PCI_BRIDGE_CONTROL_VGA; + BridgeControl = EFI_PCI_BRIDGE_CONTROL_ISA | EFI_PCI_BRIDGE_CONTROL_VGA | EFI_PCI_BRIDGE_CONTROL_VGA_16; // // Test whether the device can support attributes above diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c index 28fbaca67a..e01d6aa7f0 100644 --- a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciIo.c @@ -369,7 +369,7 @@ Returns: PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - if (Width < 0 || Width >= EfiPciIoWidthMaximum) { + if (Width < 0 || Width > EfiPciIoWidthUint64) { return EFI_INVALID_PARAMETER; } @@ -378,10 +378,6 @@ Returns: return EFI_UNSUPPORTED; } - if (Width > EfiPciIoWidthUint64) { - return EFI_INVALID_PARAMETER; - } - Status = PciIoDevice->PciRootBridgeIo->PollIo ( PciIoDevice->PciRootBridgeIo, (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, @@ -1509,12 +1505,26 @@ Returns: Command = 0; BridgeControl = 0; + // + // Check VGA and VGA16, they can not be set at the same time + // + if (((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) && + (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) || + ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) && + (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) || + ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) && + (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) || + ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) && + (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) ) { + return EFI_UNSUPPORTED; + } + // // For PPB & P2C, set relevant attribute bits // if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { - if (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) { + if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) { BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA; } @@ -1522,18 +1532,23 @@ Returns: BridgeControl |= EFI_PCI_BRIDGE_CONTROL_ISA; } - if (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) { + if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) { Command |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO; } + if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) { + BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA_16; + } + } else { // // Do with the attributes on VGA + // Only for VGA's legacy resource, we just can enable once. // - if ((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) || - (IS_PCI_VGA(&PciIoDevice->Pci) && - ((Attributes & EFI_PCI_IO_ATTRIBUTE_IO) || - (Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY)))) { + if (Attributes & + (EFI_PCI_IO_ATTRIBUTE_VGA_IO | + EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 | + EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY)) { // // Check if a VGA has been enabled before enabling a new one // @@ -1554,7 +1569,7 @@ Returns: // // Do with the attributes on GFX // - if (Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) { + if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) { if (Operation == EfiPciIoAttributeOperationEnable) { // diff --git a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c index 5819fd6e37..3ec76989a5 100644 --- a/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c +++ b/EdkModulePkg/Bus/Pci/PciBus/Dxe/PciOptionRomSupport.c @@ -24,6 +24,13 @@ Revision History #include "pcibus.h" #include "PciResourceSupport.h" +// +// Min Max +// +#define EFI_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define EFI_MAX(a, b) (((a) > (b)) ? (a) : (b)) + + EFI_STATUS GetOpRomInfo ( IN PCI_IO_DEVICE *PciIoDevice @@ -152,6 +159,7 @@ Returns: UINT64 RomSize; UINT64 RomImageSize; UINT8 *RomInMemory; + UINT8 CodeType; RomSize = PciDevice->RomSize; @@ -159,6 +167,7 @@ Returns: RomImageSize = 0; RomInMemory = NULL; Temp = 0; + CodeType = 0xFF; // // Get the RomBarIndex @@ -231,11 +240,22 @@ Returns: sizeof (PCI_DATA_STRUCTURE), (UINT8 *) RomPcir ); + if (RomPcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) { + CodeType = PCI_CODE_TYPE_PCAT_IMAGE; + } Indicator = RomPcir->Indicator; RomImageSize = RomImageSize + RomPcir->ImageLength * 512; RomBarOffset = RomBarOffset + RomPcir->ImageLength * 512; } while (((Indicator & 0x80) == 0x00) && ((RomBarOffset - RomBar) < RomSize)); + // + // Some Legacy Cards do not report the correct ImageLength so used the maximum + // of the legacy length and the PCIR Image Length + // + if (CodeType == PCI_CODE_TYPE_PCAT_IMAGE) { + RomImageSize = EFI_MAX(RomImageSize, (((EFI_LEGACY_EXPANSION_ROM_HEADER *)RomHeader)->Size512 * 512)); + } + if (RomImageSize > 0) { retStatus = EFI_SUCCESS; Image = AllocatePool ((UINT32) RomImageSize); -- 2.39.2