From 8191cd5efd9209a8dd8c9e60f042ed9e67f9bb32 Mon Sep 17 00:00:00 2001 From: lgao4 Date: Thu, 18 Dec 2008 07:41:58 +0000 Subject: Enhance PciCfg2 driver to handle unaligned Pci access according to PI spec. Remove the undefined logic to process gEfiStatusCodeSpecificDataGuid status code data. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7078 6f19259b-4bc3-4df7-8a09-765794883524 --- .../PcatSingleSegmentPciCfgPei.inf | 7 - .../Universal/PcatSingleSegmentPciCfgPei/PciCfg.c | 156 +++++++++++++++------ .../Universal/PcatSingleSegmentPciCfgPei/PciCfg2.c | 115 +++++++++++++-- 3 files changed, 220 insertions(+), 58 deletions(-) (limited to 'IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei') diff --git a/IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PcatSingleSegmentPciCfgPei.inf b/IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PcatSingleSegmentPciCfgPei.inf index eb29457ebd..010d840210 100644 --- a/IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PcatSingleSegmentPciCfgPei.inf +++ b/IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PcatSingleSegmentPciCfgPei.inf @@ -55,13 +55,6 @@ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPciCfgDisable gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPciCfg2Disable -[FixedPcd.common] - ## - # Disable ASSERT for unalign PCI IO access according to PI Volume 1 and PeiCis Spec - # Spec has not this requirement. - ## - gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0E - [Depex] TRUE diff --git a/IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PciCfg.c b/IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PciCfg.c index 5becfe4701..aaabfbb58a 100644 --- a/IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PciCfg.c +++ b/IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PciCfg.c @@ -54,22 +54,47 @@ PciCfgRead ( UINTN PciLibAddress; PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address); - switch (Width) { - case EfiPeiPciCfgWidthUint8: - * (UINT8 *) Buffer = PciRead8 (PciLibAddress); - break; - case EfiPeiPciCfgWidthUint16: - * (UINT16 *) Buffer = PciRead16 (PciLibAddress); - break; - - case EfiPeiPciCfgWidthUint32: - * (UINT32 *) Buffer = PciRead32 (PciLibAddress); - break; - - default: - return EFI_INVALID_PARAMETER; + if (Width == EfiPeiPciCfgWidthUint8) { + *((UINT8 *) Buffer) = PciRead8 (PciLibAddress); + } else if (Width == EfiPeiPciCfgWidthUint16) { + 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) { + 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; } + return EFI_SUCCESS; } @@ -104,22 +129,47 @@ PciCfgWrite ( UINTN PciLibAddress; PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address); - switch (Width) { - case EfiPeiPciCfgWidthUint8: - PciWrite8 (PciLibAddress, *(UINT8 *) Buffer); - break; - - case EfiPeiPciCfgWidthUint16: - PciWrite16 (PciLibAddress, *(UINT16 *) Buffer); - break; - case EfiPeiPciCfgWidthUint32: - PciWrite32 (PciLibAddress, *(UINT32 *) Buffer); - break; - - default: - return EFI_INVALID_PARAMETER; + if (Width == EfiPeiPciCfgWidthUint8) { + PciWrite8 (PciLibAddress, *((UINT8 *) Buffer)); + } else if (Width == EfiPeiPciCfgWidthUint16) { + 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) { + 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; } + return EFI_SUCCESS; } @@ -154,22 +204,46 @@ PciCfgModify ( UINTN PciLibAddress; PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address); - switch (Width) { - case EfiPeiPciCfgWidthUint8: - PciAndThenOr8 (PciLibAddress, (UINT8)~ClearBits, (UINT8)SetBits); - break; - - case EfiPeiPciCfgWidthUint16: + if (Width == EfiPeiPciCfgWidthUint8) { + PciAndThenOr8 (PciLibAddress, (UINT8)~ClearBits, (UINT8)SetBits); + } else if (Width == EfiPeiPciCfgWidthUint16) { + if ((PciLibAddress & 0x01) == 0) { + // + // Aligned Pci address access + // PciAndThenOr16 (PciLibAddress, (UINT16)~ClearBits, (UINT16)SetBits); - break; - - case EfiPeiPciCfgWidthUint32: + } else { + // + // Unaligned Pci address access, break up the request into byte by byte. + // + PciAndThenOr8 (PciLibAddress, (UINT8)~ClearBits, (UINT8)SetBits); + PciAndThenOr8 (PciLibAddress + 1, (UINT8)~(ClearBits >> 8), (UINT8)(SetBits >> 8)); + } + } else if (Width == EfiPeiPciCfgWidthUint32) { + if ((PciLibAddress & 0x03) == 0) { + // + // Aligned Pci address access + // PciAndThenOr32 (PciLibAddress, (UINT32)~ClearBits, (UINT32)SetBits); - break; - - default: - return EFI_INVALID_PARAMETER; + } else if ((PciLibAddress & 0x01) == 0) { + // + // Unaligned Pci address access, break up the request into word by word. + // + PciAndThenOr16 (PciLibAddress, (UINT16)~ClearBits, (UINT16)SetBits); + PciAndThenOr16 (PciLibAddress + 2, (UINT16)~(ClearBits >> 16), (UINT16)(SetBits >> 16)); + } else { + // + // Unaligned Pci address access, break up the request into byte by byte. + // + PciAndThenOr8 (PciLibAddress, (UINT8)~ClearBits, (UINT8)SetBits); + PciAndThenOr8 (PciLibAddress + 1, (UINT8)~(ClearBits >> 8), (UINT8)(SetBits >> 8)); + PciAndThenOr8 (PciLibAddress + 2, (UINT8)~(ClearBits >> 16), (UINT8)(SetBits >> 16)); + PciAndThenOr8 (PciLibAddress + 3, (UINT8)~(ClearBits >> 24), (UINT8)(SetBits >> 24)); + } + } else { + return EFI_INVALID_PARAMETER; } + return EFI_SUCCESS; } diff --git a/IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PciCfg2.c b/IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PciCfg2.c index 6dd47324ca..852476ddd0 100644 --- a/IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PciCfg2.c +++ b/IntelFrameworkModulePkg/Universal/PcatSingleSegmentPciCfgPei/PciCfg2.c @@ -134,9 +134,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; } @@ -185,9 +215,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; } @@ -247,13 +307,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; } -- cgit v1.2.3