mirror of https://github.com/acidanthera/audk.git
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/trunk/edk2@11016 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
8835954602
commit
aeeb84bab4
|
@ -101,6 +101,7 @@
|
|||
[FeaturePcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPciBridgeIoAlignmentProbe
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdUnalignedPciIoEnable
|
||||
|
||||
[Pcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize
|
||||
|
|
|
@ -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 &= (~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 &= (~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 &= (~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 &= (~0x03);
|
||||
Count *= (UINTN)(1 << (Width & 0x03));
|
||||
}
|
||||
}
|
||||
|
||||
Status = PciIoDevice->PciRootBridgeIo->Io.Write (
|
||||
PciIoDevice->PciRootBridgeIo,
|
||||
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
||||
|
@ -627,6 +734,16 @@ PciIoConfigRead (
|
|||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// If request is not aligned, then convert request to EfiPciIoWithXXXUint8
|
||||
//
|
||||
if (FeaturePcdGet (PcdUnalignedPciIoEnable)) {
|
||||
if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) {
|
||||
Width &= (~0x03);
|
||||
Count *= (UINTN)(1 << (Width & 0x03));
|
||||
}
|
||||
}
|
||||
|
||||
Status = PciIoDevice->PciRootBridgeIo->Pci.Read (
|
||||
PciIoDevice->PciRootBridgeIo,
|
||||
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
||||
|
@ -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 &= (~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 &= (~0x03);
|
||||
Count *= (UINTN)(1 << (Width & 0x03));
|
||||
}
|
||||
}
|
||||
|
||||
Status = PciIoDevice->PciRootBridgeIo->CopyMem (
|
||||
PciIoDevice->PciRootBridgeIo,
|
||||
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
||||
|
|
|
@ -269,6 +269,11 @@
|
|||
## This PCD specified whether ACPI SDT protocol is installed.
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|FALSE|BOOLEAN|0x0001004d
|
||||
|
||||
## 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, PcdsFeatureFlag.X64]
|
||||
##
|
||||
# This feature flag specifies whether DxeIpl switches to long mode to enter DXE phase.
|
||||
|
|
Loading…
Reference in New Issue