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
This commit is contained in:
lgao4
2008-12-18 07:41:58 +00:00
parent 8501ba4c6d
commit 8191cd5efd
9 changed files with 227 additions and 87 deletions

View File

@ -422,7 +422,7 @@ ReportStatusCodeWithExtendedData (
is responsible for allocating a buffer large enough for the standard header and is responsible for allocating a buffer large enough for the standard header and
the extended data passed into this function. The standard header is filled in the extended data passed into this function. The standard header is filled in
with a GUID specified by ExtendedDataGuid. If ExtendedDataGuid is NULL, then a with a GUID specified by ExtendedDataGuid. If ExtendedDataGuid is NULL, then a
GUID of gEfiStatusCodeSpecificDatauid is used. The status code is reported with GUID of gEfiStatusCodeSpecificDataGuid is used. The status code is reported with
an instance specified by Instance and a caller ID specified by CallerId. If an instance specified by Instance and a caller ID specified by CallerId. If
CallerId is NULL, then a caller ID of gEfiCallerIdGuid is used. CallerId is NULL, then a caller ID of gEfiCallerIdGuid is used.

View File

@ -163,9 +163,12 @@ DebugAssert (
// //
AsciiStrCpy (Temp + AsciiStrLen (FileName) + 1, Description); AsciiStrCpy (Temp + AsciiStrLen (FileName) + 1, Description);
REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( REPORT_STATUS_CODE_EX (
(EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED), (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),
(EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE), (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE),
0,
NULL,
&gEfiStatusCodeDataTypeAssertGuid,
AssertData, AssertData,
TotalSize TotalSize
); );

View File

@ -53,4 +53,6 @@
[Guids.common] [Guids.common]
gEfiStatusCodeDataTypeDebugGuid gEfiStatusCodeDataTypeDebugGuid
gEfiStatusCodeDataTypeAssertGuid

View File

@ -55,13 +55,6 @@
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPciCfgDisable gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPciCfgDisable
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPciCfg2Disable 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] [Depex]
TRUE TRUE

View File

@ -54,22 +54,47 @@ PciCfgRead (
UINTN PciLibAddress; UINTN PciLibAddress;
PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address); PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);
switch (Width) {
case EfiPeiPciCfgWidthUint8:
* (UINT8 *) Buffer = PciRead8 (PciLibAddress);
break;
case EfiPeiPciCfgWidthUint16: if (Width == EfiPeiPciCfgWidthUint8) {
* (UINT16 *) Buffer = PciRead16 (PciLibAddress); *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);
break; } else if (Width == EfiPeiPciCfgWidthUint16) {
if ((PciLibAddress & 0x01) == 0) {
case EfiPeiPciCfgWidthUint32: //
* (UINT32 *) Buffer = PciRead32 (PciLibAddress); // Aligned Pci address access
break; //
WriteUnaligned16 (((UINT16 *) Buffer), PciRead16 (PciLibAddress));
default: } else {
return EFI_INVALID_PARAMETER; //
// 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; return EFI_SUCCESS;
} }
@ -104,22 +129,47 @@ PciCfgWrite (
UINTN PciLibAddress; UINTN PciLibAddress;
PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address); PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);
switch (Width) {
case EfiPeiPciCfgWidthUint8:
PciWrite8 (PciLibAddress, *(UINT8 *) Buffer);
break;
case EfiPeiPciCfgWidthUint16: if (Width == EfiPeiPciCfgWidthUint8) {
PciWrite16 (PciLibAddress, *(UINT16 *) Buffer); PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));
break; } else if (Width == EfiPeiPciCfgWidthUint16) {
if ((PciLibAddress & 0x01) == 0) {
case EfiPeiPciCfgWidthUint32: //
PciWrite32 (PciLibAddress, *(UINT32 *) Buffer); // Aligned Pci address access
break; //
PciWrite16 (PciLibAddress, ReadUnaligned16 ((UINT16 *) Buffer));
default: } else {
return EFI_INVALID_PARAMETER; //
// 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; return EFI_SUCCESS;
} }
@ -154,22 +204,46 @@ PciCfgModify (
UINTN PciLibAddress; UINTN PciLibAddress;
PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address); PciLibAddress = PciCfgAddressConvert ((EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *) &Address);
switch (Width) { if (Width == EfiPeiPciCfgWidthUint8) {
case EfiPeiPciCfgWidthUint8: PciAndThenOr8 (PciLibAddress, (UINT8)~ClearBits, (UINT8)SetBits);
PciAndThenOr8 (PciLibAddress, (UINT8)~ClearBits, (UINT8)SetBits); } else if (Width == EfiPeiPciCfgWidthUint16) {
break; if ((PciLibAddress & 0x01) == 0) {
//
case EfiPeiPciCfgWidthUint16: // Aligned Pci address access
//
PciAndThenOr16 (PciLibAddress, (UINT16)~ClearBits, (UINT16)SetBits); PciAndThenOr16 (PciLibAddress, (UINT16)~ClearBits, (UINT16)SetBits);
break; } else {
//
case EfiPeiPciCfgWidthUint32: // 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); PciAndThenOr32 (PciLibAddress, (UINT32)~ClearBits, (UINT32)SetBits);
break; } else if ((PciLibAddress & 0x01) == 0) {
//
default: // Unaligned Pci address access, break up the request into word by word.
return EFI_INVALID_PARAMETER; //
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; return EFI_SUCCESS;
} }

View File

@ -134,9 +134,39 @@ PciCfg2Read (
if (Width == EfiPeiPciCfgWidthUint8) { if (Width == EfiPeiPciCfgWidthUint8) {
*((UINT8 *) Buffer) = PciRead8 (PciLibAddress); *((UINT8 *) Buffer) = PciRead8 (PciLibAddress);
} else if (Width == EfiPeiPciCfgWidthUint16) { } 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) { } 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 { } else {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
@ -185,9 +215,39 @@ PciCfg2Write (
if (Width == EfiPeiPciCfgWidthUint8) { if (Width == EfiPeiPciCfgWidthUint8) {
PciWrite8 (PciLibAddress, *((UINT8 *) Buffer)); PciWrite8 (PciLibAddress, *((UINT8 *) Buffer));
} else if (Width == EfiPeiPciCfgWidthUint16) { } 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) { } 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 { } else {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
@ -247,13 +307,48 @@ PciCfg2Modify (
if (Width == EfiPeiPciCfgWidthUint8) { if (Width == EfiPeiPciCfgWidthUint8) {
PciAndThenOr8 (PciLibAddress, (UINT8) (~(*(UINT8 *) ClearBits)), *((UINT8 *) SetBits)); PciAndThenOr8 (PciLibAddress, (UINT8) (~(*(UINT8 *) ClearBits)), *((UINT8 *) SetBits));
} else if (Width == EfiPeiPciCfgWidthUint16) { } else if (Width == EfiPeiPciCfgWidthUint16) {
ClearValue16 = (UINT16) (~ReadUnaligned16 ((UINT16 *) ClearBits)); if ((PciLibAddress & 0x01) == 0) {
SetValue16 = ReadUnaligned16 ((UINT16 *) SetBits); //
PciAndThenOr16 (PciLibAddress, ClearValue16, SetValue16); // 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) { } else if (Width == EfiPeiPciCfgWidthUint32) {
ClearValue32 = (UINT32) (~ReadUnaligned32 ((UINT32 *) ClearBits)); if ((PciLibAddress & 0x03) == 0) {
SetValue32 = ReadUnaligned32 ((UINT32 *) SetBits); //
PciAndThenOr32 (PciLibAddress, ClearValue32, SetValue32); // 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 { } else {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }

View File

@ -78,7 +78,6 @@
[Guids] [Guids]
gEfiDataHubStatusCodeRecordGuid # SOMETIMES_CONSUMED gEfiDataHubStatusCodeRecordGuid # SOMETIMES_CONSUMED
gMemoryStatusCodeRecordGuid # SOMETIMES_CONSUMED gMemoryStatusCodeRecordGuid # SOMETIMES_CONSUMED
gEfiStatusCodeSpecificDataGuid # SOMETIMES_CONSUMED
gEfiStatusCodeDataTypeDebugGuid # PROTOCOL ALWAYS_CONSUMED gEfiStatusCodeDataTypeDebugGuid # PROTOCOL ALWAYS_CONSUMED
[Protocols] [Protocols]

View File

@ -13,7 +13,6 @@
**/ **/
#include "DxeStatusCode.h" #include "DxeStatusCode.h"
#include "DebugInfo.h"
EFI_SERIAL_IO_PROTOCOL *mSerialIoProtocol; EFI_SERIAL_IO_PROTOCOL *mSerialIoProtocol;
@ -88,7 +87,6 @@ SerialStatusCodeReportWorker (
UINT32 LineNumber; UINT32 LineNumber;
UINTN CharCount; UINTN CharCount;
VA_LIST Marker; VA_LIST Marker;
EFI_DEBUG_INFO *DebugInfo;
EFI_TPL CurrentTpl; EFI_TPL CurrentTpl;
@ -130,17 +128,6 @@ SerialStatusCodeReportWorker (
Format, Format,
Marker Marker
); );
} else if (Data != NULL &&
CompareGuid (&Data->Type, &gEfiStatusCodeSpecificDataGuid) &&
(CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {
//
// Print specific data into output buffer.
//
DebugInfo = (EFI_DEBUG_INFO *) (Data + 1);
Marker = (VA_LIST) (DebugInfo + 1);
Format = (CHAR8 *) (((UINT64 *) Marker) + 12);
CharCount = AsciiVSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, Marker);
} else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) { } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
// //
// Print ERROR information into output buffer. // Print ERROR information into output buffer.

View File

@ -12,7 +12,6 @@
**/ **/
#include "PeiStatusCode.h" #include "PeiStatusCode.h"
#include "DebugInfo.h"
/** /**
Convert status code value and extended data to readable ASCII string, send string to serial I/O device. Convert status code value and extended data to readable ASCII string, send string to serial I/O device.
@ -59,7 +58,6 @@ SerialStatusCodeReportWorker (
UINT32 LineNumber; UINT32 LineNumber;
UINTN CharCount; UINTN CharCount;
VA_LIST Marker; VA_LIST Marker;
EFI_DEBUG_INFO *DebugInfo;
Buffer[0] = '\0'; Buffer[0] = '\0';
@ -87,17 +85,6 @@ SerialStatusCodeReportWorker (
Format, Format,
Marker Marker
); );
} else if (Data != NULL &&
CompareGuid (&Data->Type, &gEfiStatusCodeSpecificDataGuid) &&
(CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {
//
// Print specific data into output buffer.
//
DebugInfo = (EFI_DEBUG_INFO *) (Data + 1);
Marker = (VA_LIST) (DebugInfo + 1);
Format = (CHAR8 *) (((UINT64 *) Marker) + 12);
CharCount = AsciiVSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, Marker);
} else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) { } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
// //
// Print ERROR information into output buffer. // Print ERROR information into output buffer.