summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>2010-11-11 06:04:53 +0000
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>2010-11-11 06:04:53 +0000
commit8a046ef0ddf05a379eca74cea4b081e294d229fb (patch)
treeb8e796a5cf55bbf86e863fd24c2b7818f81de100
parentf8cd218b22e3811d83e60e863208fccee2a9176a (diff)
downloadedk2-8a046ef0ddf05a379eca74cea4b081e294d229fb.tar.gz
sync patch r11016, r11020 from main trunk.
Some existing PCI adapters with UEFI option ROMs make unaligned requests through the PCI I/O Protocol. Add support for unaligned requests in the PCI IO protocol implementation in the PCI Bus driver to be compatible with those UEFI option ROMs. This solution defines a PCD Feature Flag to enabled support for unaligned requests through the PCI I/O Protocol. This flag is disabled by default. Platforms that do want to support such EFI/UEFI drivers that make unaligned PCI I/O requests should enable this feature. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/branches/UDK2008@11038 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf1
-rw-r--r--IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.c137
-rw-r--r--MdeModulePkg/MdeModulePkg.dec5
3 files changed, 143 insertions, 0 deletions
diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
index 79981de21b..12ee97c9e2 100644
--- a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
@@ -102,6 +102,7 @@
[FeaturePcd.common]
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPciBridgeIoAlignmentProbe
+ gEfiMdeModulePkgTokenSpaceGuid.PcdUnalignedPciIoEnable
# [Event]
# ##
diff --git a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.c b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.c
index 5cc5967245..840f7e8371 100644
--- a/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.c
+++ b/IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/PciIo.c
@@ -248,6 +248,39 @@ PciIoPollMem (
return EFI_INVALID_PARAMETER;
}
+ //
+ // If request is not aligned, then convert request to EfiPciIoWithXXXUint8
+ //
+ if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {
+ if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {
+ Status = PciIoMemRead (This, Width, BarIndex, Offset, 1, Result);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if ((*Result & Mask) == Value || Delay == 0) {
+ return EFI_SUCCESS;
+ }
+ do {
+ //
+ // Stall 10 us = 100 * 100ns
+ //
+ gBS->Stall (10);
+
+ Status = PciIoMemRead (This, Width, BarIndex, Offset, 1, Result);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if ((*Result & Mask) == Value) {
+ return EFI_SUCCESS;
+ }
+ if (Delay <= 100) {
+ return EFI_TIMEOUT;
+ }
+ Delay -= 100;
+ } while (TRUE);
+ }
+ }
+
Status = PciIoDevice->PciRootBridgeIo->PollMem (
PciIoDevice->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
@@ -314,6 +347,39 @@ PciIoPollIo (
return EFI_UNSUPPORTED;
}
+ //
+ // If request is not aligned, then convert request to EfiPciIoWithXXXUint8
+ //
+ if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {
+ if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {
+ Status = PciIoIoRead (This, Width, BarIndex, Offset, 1, Result);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if ((*Result & Mask) == Value || Delay == 0) {
+ return EFI_SUCCESS;
+ }
+ do {
+ //
+ // Stall 10 us = 100 * 100ns
+ //
+ gBS->Stall (10);
+
+ Status = PciIoIoRead (This, Width, BarIndex, Offset, 1, Result);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if ((*Result & Mask) == Value) {
+ return EFI_SUCCESS;
+ }
+ if (Delay <= 100) {
+ return EFI_TIMEOUT;
+ }
+ Delay -= 100;
+ } while (TRUE);
+ }
+ }
+
Status = PciIoDevice->PciRootBridgeIo->PollIo (
PciIoDevice->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
@@ -380,6 +446,17 @@ PciIoMemRead (
return EFI_UNSUPPORTED;
}
+ //
+ // If request is not aligned, then convert request to EfiPciIoWithXXXUint8
+ //
+ if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {
+ if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {
+ Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));
+ Count *= (UINTN)(1 << (Width & 0x03));
+ }
+ }
+
+
Status = PciIoDevice->PciRootBridgeIo->Mem.Read (
PciIoDevice->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
@@ -444,6 +521,16 @@ PciIoMemWrite (
return EFI_UNSUPPORTED;
}
+ //
+ // If request is not aligned, then convert request to EfiPciIoWithXXXUint8
+ //
+ if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {
+ if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {
+ Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));
+ Count *= (UINTN)(1 << (Width & 0x03));
+ }
+ }
+
Status = PciIoDevice->PciRootBridgeIo->Mem.Write (
PciIoDevice->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
@@ -508,6 +595,16 @@ PciIoIoRead (
return EFI_UNSUPPORTED;
}
+ //
+ // If request is not aligned, then convert request to EfiPciIoWithXXXUint8
+ //
+ if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {
+ if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {
+ Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));
+ Count *= (UINTN)(1 << (Width & 0x03));
+ }
+ }
+
Status = PciIoDevice->PciRootBridgeIo->Io.Read (
PciIoDevice->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
@@ -572,6 +669,16 @@ PciIoIoWrite (
return EFI_UNSUPPORTED;
}
+ //
+ // If request is not aligned, then convert request to EfiPciIoWithXXXUint8
+ //
+ if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {
+ if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {
+ Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));
+ Count *= (UINTN)(1 << (Width & 0x03));
+ }
+ }
+
Status = PciIoDevice->PciRootBridgeIo->Io.Write (
PciIoDevice->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
@@ -626,6 +733,16 @@ PciIoConfigRead (
if (EFI_ERROR (Status)) {
return Status;
}
+
+ //
+ // If request is not aligned, then convert request to EfiPciIoWithXXXUint8
+ //
+ if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {
+ if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {
+ Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));
+ Count *= (UINTN)(1 << (Width & 0x03));
+ }
+ }
Status = PciIoDevice->PciRootBridgeIo->Pci.Read (
PciIoDevice->PciRootBridgeIo,
@@ -682,6 +799,16 @@ PciIoConfigWrite (
return Status;
}
+ //
+ // If request is not aligned, then convert request to EfiPciIoWithXXXUint8
+ //
+ if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {
+ if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {
+ Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));
+ Count *= (UINTN)(1 << (Width & 0x03));
+ }
+ }
+
Status = PciIoDevice->PciRootBridgeIo->Pci.Write (
PciIoDevice->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
@@ -767,6 +894,16 @@ PciIoCopyMem (
return EFI_UNSUPPORTED;
}
+ //
+ // If request is not aligned, then convert request to EfiPciIoWithXXXUint8
+ //
+ if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {
+ if ((SrcOffset & ((1 << (Width & 0x03)) - 1)) != 0 || (DestOffset & ((1 << (Width & 0x03)) - 1)) != 0) {
+ Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03));
+ Count *= (UINTN)(1 << (Width & 0x03));
+ }
+ }
+
Status = PciIoDevice->PciRootBridgeIo->CopyMem (
PciIoDevice->PciRootBridgeIo,
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index e890dacfbe..4db4773efa 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -221,6 +221,11 @@
# If FALSE, DXE IPL will not support UEFI decompression to save space.
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress|TRUE|BOOLEAN|0x0001200c
+ ## If TRUE, then unaligned I/O, MMIO, and PCI Configuration cycles through the PCI I/O Protocol are enabled.
+ # If FALSE, then unaligned I/O, MMIO, and PCI Configuration cycles through the PCI I/O Protocol are disabled.
+ # The default value for this PCD is to disable support for unaligned PCI I/O Protocol requests.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdUnalignedPciIoEnable|FALSE|BOOLEAN|0x0001003e
+
[PcdsFeatureFlag.IA32]
##
# This feature flag specifies whether DxeIpl switches to long mode to enter DXE phase.