From: lgao4 Date: Thu, 18 Dec 2008 07:40:19 +0000 (+0000) Subject: Enhance PciCfg2 driver to handle unaligned Pci access according to PI spec. X-Git-Tag: edk2-stable201903~19170 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=8501ba4c6d1264c70951735d5d134d13fcccb3c2 Enhance PciCfg2 driver to handle unaligned Pci access according to PI spec. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7077 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf b/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf index 2894e75b70..e46a1c32c8 100644 --- a/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf +++ b/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf @@ -47,10 +47,3 @@ [Depex] TRUE - -[FixedPcd.common] - ## - # Disable ASSERT for unalign PCI IO access according to PI Spec Volume 1 - # Spec has not this requirement. - ## - gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0E diff --git a/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PciCfg2.c b/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PciCfg2.c index 6ea2cfb8e8..fdd67f7abb 100644 --- a/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PciCfg2.c +++ b/MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PciCfg2.c @@ -227,9 +227,39 @@ PciCfg2Read ( if (Width == EfiPeiPciCfgWidthUint8) { *((UINT8 *) Buffer) = PciRead8 (PciLibAddress); } else if (Width == EfiPeiPciCfgWidthUint16) { - *((UINT16 *) Buffer) = PciRead16 (PciLibAddress); + if ((PciLibAddress & 0x01) == 0) { + // + // Aligned Pci address access + // + WriteUnaligned16 (((UINT16 *) Buffer), PciRead16 (PciLibAddress)); + } else { + // + // Unaligned Pci address access, break up the request into byte by byte. + // + *((UINT8 *) Buffer) = PciRead8 (PciLibAddress); + *((UINT8 *) Buffer + 1) = PciRead8 (PciLibAddress + 1); + } } else if (Width == EfiPeiPciCfgWidthUint32) { - *((UINT32 *) Buffer) = PciRead32 (PciLibAddress); + if ((PciLibAddress & 0x03) == 0) { + // + // Aligned Pci address access + // + WriteUnaligned32 (((UINT32 *) Buffer), PciRead32 (PciLibAddress)); + } else if ((PciLibAddress & 0x01) == 0) { + // + // Unaligned Pci address access, break up the request into word by word. + // + WriteUnaligned16 (((UINT16 *) Buffer), PciRead16 (PciLibAddress)); + WriteUnaligned16 (((UINT16 *) Buffer + 1), PciRead16 (PciLibAddress + 2)); + } else { + // + // Unaligned Pci address access, break up the request into byte by byte. + // + *((UINT8 *) Buffer) = PciRead8 (PciLibAddress); + *((UINT8 *) Buffer + 1) = PciRead8 (PciLibAddress + 1); + *((UINT8 *) Buffer + 2) = PciRead8 (PciLibAddress + 2); + *((UINT8 *) Buffer + 3) = PciRead8 (PciLibAddress + 3); + } } else { return EFI_INVALID_PARAMETER; } @@ -278,9 +308,39 @@ PciCfg2Write ( if (Width == EfiPeiPciCfgWidthUint8) { PciWrite8 (PciLibAddress, *((UINT8 *) Buffer)); } else if (Width == EfiPeiPciCfgWidthUint16) { - PciWrite16 (PciLibAddress, *((UINT16 *) Buffer)); + if ((PciLibAddress & 0x01) == 0) { + // + // Aligned Pci address access + // + PciWrite16 (PciLibAddress, ReadUnaligned16 ((UINT16 *) Buffer)); + } else { + // + // Unaligned Pci address access, break up the request into byte by byte. + // + PciWrite8 (PciLibAddress, *((UINT8 *) Buffer)); + PciWrite8 (PciLibAddress + 1, *((UINT8 *) Buffer + 1)); + } } else if (Width == EfiPeiPciCfgWidthUint32) { - PciWrite32 (PciLibAddress, *((UINT32 *) Buffer)); + if ((PciLibAddress & 0x03) == 0) { + // + // Aligned Pci address access + // + PciWrite32 (PciLibAddress, ReadUnaligned32 ((UINT32 *) Buffer)); + } else if ((PciLibAddress & 0x01) == 0) { + // + // Unaligned Pci address access, break up the request into word by word. + // + PciWrite16 (PciLibAddress, ReadUnaligned16 ((UINT16 *) Buffer)); + PciWrite16 (PciLibAddress + 2, ReadUnaligned16 ((UINT16 *) Buffer + 1)); + } else { + // + // Unaligned Pci address access, break up the request into byte by byte. + // + PciWrite8 (PciLibAddress, *((UINT8 *) Buffer)); + PciWrite8 (PciLibAddress + 1, *((UINT8 *) Buffer + 1)); + PciWrite8 (PciLibAddress + 2, *((UINT8 *) Buffer + 2)); + PciWrite8 (PciLibAddress + 3, *((UINT8 *) Buffer + 3)); + } } else { return EFI_INVALID_PARAMETER; } @@ -340,13 +400,48 @@ PciCfg2Modify ( if (Width == EfiPeiPciCfgWidthUint8) { PciAndThenOr8 (PciLibAddress, (UINT8) (~(*(UINT8 *) ClearBits)), *((UINT8 *) SetBits)); } else if (Width == EfiPeiPciCfgWidthUint16) { - ClearValue16 = (UINT16) (~ReadUnaligned16 ((UINT16 *) ClearBits)); - SetValue16 = ReadUnaligned16 ((UINT16 *) SetBits); - PciAndThenOr16 (PciLibAddress, ClearValue16, SetValue16); + if ((PciLibAddress & 0x01) == 0) { + // + // Aligned Pci address access + // + ClearValue16 = (UINT16) (~ReadUnaligned16 ((UINT16 *) ClearBits)); + SetValue16 = ReadUnaligned16 ((UINT16 *) SetBits); + PciAndThenOr16 (PciLibAddress, ClearValue16, SetValue16); + } else { + // + // Unaligned Pci address access, break up the request into byte by byte. + // + PciAndThenOr8 (PciLibAddress, (UINT8) (~(*(UINT8 *) ClearBits)), *((UINT8 *) SetBits)); + PciAndThenOr8 (PciLibAddress + 1, (UINT8) (~(*((UINT8 *) ClearBits + 1))), *((UINT8 *) SetBits + 1)); + } } else if (Width == EfiPeiPciCfgWidthUint32) { - ClearValue32 = (UINT32) (~ReadUnaligned32 ((UINT32 *) ClearBits)); - SetValue32 = ReadUnaligned32 ((UINT32 *) SetBits); - PciAndThenOr32 (PciLibAddress, ClearValue32, SetValue32); + if ((PciLibAddress & 0x03) == 0) { + // + // Aligned Pci address access + // + ClearValue32 = (UINT32) (~ReadUnaligned32 ((UINT32 *) ClearBits)); + SetValue32 = ReadUnaligned32 ((UINT32 *) SetBits); + PciAndThenOr32 (PciLibAddress, ClearValue32, SetValue32); + } else if ((PciLibAddress & 0x01) == 0) { + // + // Unaligned Pci address access, break up the request into word by word. + // + ClearValue16 = (UINT16) (~ReadUnaligned16 ((UINT16 *) ClearBits)); + SetValue16 = ReadUnaligned16 ((UINT16 *) SetBits); + PciAndThenOr16 (PciLibAddress, ClearValue16, SetValue16); + + ClearValue16 = (UINT16) (~ReadUnaligned16 ((UINT16 *) ClearBits + 1)); + SetValue16 = ReadUnaligned16 ((UINT16 *) SetBits + 1); + PciAndThenOr16 (PciLibAddress + 2, ClearValue16, SetValue16); + } else { + // + // Unaligned Pci address access, break up the request into byte by byte. + // + PciAndThenOr8 (PciLibAddress, (UINT8) (~(*(UINT8 *) ClearBits)), *((UINT8 *) SetBits)); + PciAndThenOr8 (PciLibAddress + 1, (UINT8) (~(*((UINT8 *) ClearBits + 1))), *((UINT8 *) SetBits + 1)); + PciAndThenOr8 (PciLibAddress + 2, (UINT8) (~(*((UINT8 *) ClearBits + 2))), *((UINT8 *) SetBits + 2)); + PciAndThenOr8 (PciLibAddress + 3, (UINT8) (~(*((UINT8 *) ClearBits + 3))), *((UINT8 *) SetBits + 3)); + } } else { return EFI_INVALID_PARAMETER; }