X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdePkg%2FLibrary%2FBasePciExpressLib%2FPciLib.c;h=f7deedd6420015f5c85b5db69a26d514740a12a1;hb=3683e55034409db9b43758ee9ebf8fe3d897fbd7;hp=de33bf30555a5b4d89623b3d63777e26706a90ec;hpb=9a462b415d8c9636bfb29a2cfb141e69c3c092b7;p=mirror_edk2.git diff --git a/MdePkg/Library/BasePciExpressLib/PciLib.c b/MdePkg/Library/BasePciExpressLib/PciLib.c index de33bf3055..f7deedd642 100644 --- a/MdePkg/Library/BasePciExpressLib/PciLib.c +++ b/MdePkg/Library/BasePciExpressLib/PciLib.c @@ -31,13 +31,21 @@ ASSERT (((A) & ~0xfffffff) == 0) -UINTN -EFIAPI +/** + Gets the base address of PCI Express. + + This internal functions retrieves PCI Express Base Address via a PCD entry + PcdPciExpressBaseAddress. + + @return The base address of PCI Express. + +**/ +volatile VOID* GetPciExpressBaseAddress ( VOID ) { - return (UINTN)PcdGet64 (PcdPciExpressBaseAddress); + return (VOID*)(UINTN) PcdGet64 (PcdPciExpressBaseAddress); } /** @@ -62,7 +70,7 @@ PciExpressRead8 ( ) { ASSERT_INVALID_PCI_ADDRESS (Address); - return MmioRead8 (GetPciExpressBaseAddress () + Address); + return MmioRead8 ((UINTN) GetPciExpressBaseAddress () + Address); } /** @@ -89,7 +97,7 @@ PciExpressWrite8 ( ) { ASSERT_INVALID_PCI_ADDRESS (Address); - return MmioWrite8 (GetPciExpressBaseAddress () + Address, Value); + return MmioWrite8 ((UINTN) GetPciExpressBaseAddress () + Address, Value); } /** @@ -120,7 +128,7 @@ PciExpressOr8 ( ) { ASSERT_INVALID_PCI_ADDRESS (Address); - return MmioOr8 (GetPciExpressBaseAddress () + Address, OrData); + return MmioOr8 ((UINTN) GetPciExpressBaseAddress () + Address, OrData); } /** @@ -151,7 +159,7 @@ PciExpressAnd8 ( ) { ASSERT_INVALID_PCI_ADDRESS (Address); - return MmioAnd8 (GetPciExpressBaseAddress () + Address, AndData); + return MmioAnd8 ((UINTN) GetPciExpressBaseAddress () + Address, AndData); } /** @@ -186,7 +194,7 @@ PciExpressAndThenOr8 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioAndThenOr8 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, AndData, OrData ); @@ -202,7 +210,7 @@ PciExpressAndThenOr8 ( If Address > 0x0FFFFFFF, then ASSERT(). If StartBit is greater than 7, then ASSERT(). If EndBit is greater than 7, then ASSERT(). - If EndBit is less than or equal to StartBit, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). @param Address PCI configuration register to read. @param StartBit The ordinal of the least significant bit in the bit field. @@ -223,7 +231,7 @@ PciExpressBitFieldRead8 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioBitFieldRead8 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, StartBit, EndBit ); @@ -240,7 +248,7 @@ PciExpressBitFieldRead8 ( If Address > 0x0FFFFFFF, then ASSERT(). If StartBit is greater than 7, then ASSERT(). If EndBit is greater than 7, then ASSERT(). - If EndBit is less than or equal to StartBit, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). @param Address PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. @@ -263,7 +271,7 @@ PciExpressBitFieldWrite8 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioBitFieldWrite8 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, StartBit, EndBit, Value @@ -284,7 +292,7 @@ PciExpressBitFieldWrite8 ( If Address > 0x0FFFFFFF, then ASSERT(). If StartBit is greater than 7, then ASSERT(). If EndBit is greater than 7, then ASSERT(). - If EndBit is less than or equal to StartBit, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). @param Address PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. @@ -307,7 +315,7 @@ PciExpressBitFieldOr8 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioBitFieldOr8 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, StartBit, EndBit, OrData @@ -328,7 +336,7 @@ PciExpressBitFieldOr8 ( If Address > 0x0FFFFFFF, then ASSERT(). If StartBit is greater than 7, then ASSERT(). If EndBit is greater than 7, then ASSERT(). - If EndBit is less than or equal to StartBit, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). @param Address PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. @@ -351,7 +359,7 @@ PciExpressBitFieldAnd8 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioBitFieldAnd8 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, StartBit, EndBit, AndData @@ -374,7 +382,7 @@ PciExpressBitFieldAnd8 ( If Address > 0x0FFFFFFF, then ASSERT(). If StartBit is greater than 7, then ASSERT(). If EndBit is greater than 7, then ASSERT(). - If EndBit is less than or equal to StartBit, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). @param Address PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. @@ -399,7 +407,7 @@ PciExpressBitFieldAndThenOr8 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioBitFieldAndThenOr8 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, StartBit, EndBit, AndData, @@ -430,7 +438,7 @@ PciExpressRead16 ( ) { ASSERT_INVALID_PCI_ADDRESS (Address); - return MmioRead16 (GetPciExpressBaseAddress () + Address); + return MmioRead16 ((UINTN) GetPciExpressBaseAddress () + Address); } /** @@ -458,7 +466,7 @@ PciExpressWrite16 ( ) { ASSERT_INVALID_PCI_ADDRESS (Address); - return MmioWrite16 (GetPciExpressBaseAddress () + Address, Value); + return MmioWrite16 ((UINTN) GetPciExpressBaseAddress () + Address, Value); } /** @@ -490,7 +498,7 @@ PciExpressOr16 ( ) { ASSERT_INVALID_PCI_ADDRESS (Address); - return MmioOr16 (GetPciExpressBaseAddress () + Address, OrData); + return MmioOr16 ((UINTN) GetPciExpressBaseAddress () + Address, OrData); } /** @@ -522,7 +530,7 @@ PciExpressAnd16 ( ) { ASSERT_INVALID_PCI_ADDRESS (Address); - return MmioAnd16 (GetPciExpressBaseAddress () + Address, AndData); + return MmioAnd16 ((UINTN) GetPciExpressBaseAddress () + Address, AndData); } /** @@ -558,7 +566,7 @@ PciExpressAndThenOr16 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioAndThenOr16 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, AndData, OrData ); @@ -575,7 +583,7 @@ PciExpressAndThenOr16 ( If Address is not aligned on a 16-bit boundary, then ASSERT(). If StartBit is greater than 15, then ASSERT(). If EndBit is greater than 15, then ASSERT(). - If EndBit is less than or equal to StartBit, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). @param Address PCI configuration register to read. @param StartBit The ordinal of the least significant bit in the bit field. @@ -596,7 +604,7 @@ PciExpressBitFieldRead16 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioBitFieldRead16 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, StartBit, EndBit ); @@ -614,7 +622,7 @@ PciExpressBitFieldRead16 ( If Address is not aligned on a 16-bit boundary, then ASSERT(). If StartBit is greater than 15, then ASSERT(). If EndBit is greater than 15, then ASSERT(). - If EndBit is less than or equal to StartBit, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). @param Address PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. @@ -637,7 +645,7 @@ PciExpressBitFieldWrite16 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioBitFieldWrite16 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, StartBit, EndBit, Value @@ -659,7 +667,7 @@ PciExpressBitFieldWrite16 ( If Address is not aligned on a 16-bit boundary, then ASSERT(). If StartBit is greater than 15, then ASSERT(). If EndBit is greater than 15, then ASSERT(). - If EndBit is less than or equal to StartBit, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). @param Address PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. @@ -682,7 +690,7 @@ PciExpressBitFieldOr16 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioBitFieldOr16 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, StartBit, EndBit, OrData @@ -704,7 +712,7 @@ PciExpressBitFieldOr16 ( If Address is not aligned on a 16-bit boundary, then ASSERT(). If StartBit is greater than 15, then ASSERT(). If EndBit is greater than 15, then ASSERT(). - If EndBit is less than or equal to StartBit, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). @param Address PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. @@ -727,7 +735,7 @@ PciExpressBitFieldAnd16 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioBitFieldAnd16 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, StartBit, EndBit, AndData @@ -751,7 +759,7 @@ PciExpressBitFieldAnd16 ( If Address is not aligned on a 16-bit boundary, then ASSERT(). If StartBit is greater than 15, then ASSERT(). If EndBit is greater than 15, then ASSERT(). - If EndBit is less than or equal to StartBit, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). @param Address PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. @@ -776,7 +784,7 @@ PciExpressBitFieldAndThenOr16 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioBitFieldAndThenOr16 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, StartBit, EndBit, AndData, @@ -807,7 +815,7 @@ PciExpressRead32 ( ) { ASSERT_INVALID_PCI_ADDRESS (Address); - return MmioRead32 (GetPciExpressBaseAddress () + Address); + return MmioRead32 ((UINTN) GetPciExpressBaseAddress () + Address); } /** @@ -835,7 +843,7 @@ PciExpressWrite32 ( ) { ASSERT_INVALID_PCI_ADDRESS (Address); - return MmioWrite32 (GetPciExpressBaseAddress () + Address, Value); + return MmioWrite32 ((UINTN) GetPciExpressBaseAddress () + Address, Value); } /** @@ -867,7 +875,7 @@ PciExpressOr32 ( ) { ASSERT_INVALID_PCI_ADDRESS (Address); - return MmioOr32 (GetPciExpressBaseAddress () + Address, OrData); + return MmioOr32 ((UINTN) GetPciExpressBaseAddress () + Address, OrData); } /** @@ -899,7 +907,7 @@ PciExpressAnd32 ( ) { ASSERT_INVALID_PCI_ADDRESS (Address); - return MmioAnd32 (GetPciExpressBaseAddress () + Address, AndData); + return MmioAnd32 ((UINTN) GetPciExpressBaseAddress () + Address, AndData); } /** @@ -935,7 +943,7 @@ PciExpressAndThenOr32 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioAndThenOr32 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, AndData, OrData ); @@ -952,7 +960,7 @@ PciExpressAndThenOr32 ( If Address is not aligned on a 32-bit boundary, then ASSERT(). If StartBit is greater than 31, then ASSERT(). If EndBit is greater than 31, then ASSERT(). - If EndBit is less than or equal to StartBit, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). @param Address PCI configuration register to read. @param StartBit The ordinal of the least significant bit in the bit field. @@ -973,7 +981,7 @@ PciExpressBitFieldRead32 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioBitFieldRead32 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, StartBit, EndBit ); @@ -991,7 +999,7 @@ PciExpressBitFieldRead32 ( If Address is not aligned on a 32-bit boundary, then ASSERT(). If StartBit is greater than 31, then ASSERT(). If EndBit is greater than 31, then ASSERT(). - If EndBit is less than or equal to StartBit, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). @param Address PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. @@ -1014,7 +1022,7 @@ PciExpressBitFieldWrite32 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioBitFieldWrite32 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, StartBit, EndBit, Value @@ -1036,7 +1044,7 @@ PciExpressBitFieldWrite32 ( If Address is not aligned on a 32-bit boundary, then ASSERT(). If StartBit is greater than 31, then ASSERT(). If EndBit is greater than 31, then ASSERT(). - If EndBit is less than or equal to StartBit, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). @param Address PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. @@ -1059,7 +1067,7 @@ PciExpressBitFieldOr32 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioBitFieldOr32 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, StartBit, EndBit, OrData @@ -1081,7 +1089,7 @@ PciExpressBitFieldOr32 ( If Address is not aligned on a 32-bit boundary, then ASSERT(). If StartBit is greater than 31, then ASSERT(). If EndBit is greater than 31, then ASSERT(). - If EndBit is less than or equal to StartBit, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). @param Address PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. @@ -1104,7 +1112,7 @@ PciExpressBitFieldAnd32 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioBitFieldAnd32 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, StartBit, EndBit, AndData @@ -1128,7 +1136,7 @@ PciExpressBitFieldAnd32 ( If Address is not aligned on a 32-bit boundary, then ASSERT(). If StartBit is greater than 31, then ASSERT(). If EndBit is greater than 31, then ASSERT(). - If EndBit is less than or equal to StartBit, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). @param Address PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. @@ -1153,7 +1161,7 @@ PciExpressBitFieldAndThenOr32 ( { ASSERT_INVALID_PCI_ADDRESS (Address); return MmioBitFieldAndThenOr32 ( - GetPciExpressBaseAddress () + Address, + (UINTN) GetPciExpressBaseAddress () + Address, StartBit, EndBit, AndData, @@ -1174,8 +1182,7 @@ PciExpressBitFieldAndThenOr32 ( If StartAddress > 0x0FFFFFFF, then ASSERT(). If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT(). - If (StartAddress + Size - 1) > 0x0FFFFFFF, then ASSERT(). - If Buffer is NULL, then ASSERT(). + If Size > 0 and Buffer is NULL, then ASSERT(). @param StartAddress Starting address that encodes the PCI Bus, Device, Function and Register. @@ -1193,59 +1200,70 @@ PciExpressReadBuffer ( OUT VOID *Buffer ) { - UINTN EndAddress; + UINTN ReturnValue; ASSERT_INVALID_PCI_ADDRESS (StartAddress); ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000); - ASSERT ((StartAddress + Size - 1) <= 0x0FFFFFFF); + + if (Size == 0) { + return Size; + } + ASSERT (Buffer != NULL); - EndAddress = StartAddress + Size; + // + // Save Size for return + // + ReturnValue = Size; - if (StartAddress < EndAddress && (StartAddress & 1)) { + if ((StartAddress & 1) != 0) { // // Read a byte if StartAddress is byte aligned // - *(UINT8*)Buffer = PciExpressRead8 (StartAddress); + *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress); StartAddress += sizeof (UINT8); + Size -= sizeof (UINT8); Buffer = (UINT8*)Buffer + 1; } - if (StartAddress < EndAddress && (StartAddress & 2)) { + if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) { // // Read a word if StartAddress is word aligned // - *(UINT16*)Buffer = PciExpressRead16 (StartAddress); + *(volatile UINT16 *)Buffer = PciExpressRead16 (StartAddress); StartAddress += sizeof (UINT16); + Size -= sizeof (UINT16); Buffer = (UINT16*)Buffer + 1; } - while (EndAddress - StartAddress >= 4) { + while (Size >= sizeof (UINT32)) { // // Read as many double words as possible // - *(UINT32*)Buffer = PciExpressRead32 (StartAddress); + *(volatile UINT32 *)Buffer = PciExpressRead32 (StartAddress); StartAddress += sizeof (UINT32); + Size -= sizeof (UINT32); Buffer = (UINT32*)Buffer + 1; } - if ((EndAddress & 2) != 0) { + if (Size >= sizeof (UINT16)) { // // Read the last remaining word if exist // - *(UINT16*)Buffer = PciExpressRead16 (StartAddress); + *(volatile UINT16 *)Buffer = PciExpressRead16 (StartAddress); StartAddress += sizeof (UINT16); + Size -= sizeof (UINT16); Buffer = (UINT16*)Buffer + 1; } - if (EndAddress & 1) { + if (Size >= sizeof (UINT8)) { // // Read the last remaining byte if exist // - *(UINT8*)Buffer = PciExpressRead8 (StartAddress); + *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress); } - return Size; + return ReturnValue; } /** @@ -1262,8 +1280,7 @@ PciExpressReadBuffer ( If StartAddress > 0x0FFFFFFF, then ASSERT(). If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT(). - If (StartAddress + Size - 1) > 0x0FFFFFFF, then ASSERT(). - If Buffer is NULL, then ASSERT(). + If Size > 0 and Buffer is NULL, then ASSERT(). @param StartAddress Starting address that encodes the PCI Bus, Device, Function and Register. @@ -1281,57 +1298,68 @@ PciExpressWriteBuffer ( IN VOID *Buffer ) { - UINTN EndAddress; + UINTN ReturnValue; ASSERT_INVALID_PCI_ADDRESS (StartAddress); ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000); - ASSERT ((StartAddress + Size - 1) <= 0x0FFFFFFF); + + if (Size == 0) { + return 0; + } + ASSERT (Buffer != NULL); - EndAddress = StartAddress + Size; + // + // Save Size for return + // + ReturnValue = Size; - if ((StartAddress < EndAddress) && ((StartAddress & 1)!= 0)) { + if ((StartAddress & 1) != 0) { // // Write a byte if StartAddress is byte aligned // PciExpressWrite8 (StartAddress, *(UINT8*)Buffer); StartAddress += sizeof (UINT8); + Size -= sizeof (UINT8); Buffer = (UINT8*)Buffer + 1; } - if (StartAddress < EndAddress && (StartAddress & 2)) { + if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) { // // Write a word if StartAddress is word aligned // PciExpressWrite16 (StartAddress, *(UINT16*)Buffer); StartAddress += sizeof (UINT16); + Size -= sizeof (UINT16); Buffer = (UINT16*)Buffer + 1; } - while (EndAddress - StartAddress >= 4) { + while (Size >= sizeof (UINT32)) { // // Write as many double words as possible // PciExpressWrite32 (StartAddress, *(UINT32*)Buffer); StartAddress += sizeof (UINT32); + Size -= sizeof (UINT32); Buffer = (UINT32*)Buffer + 1; } - if (EndAddress & 2) { + if (Size >= sizeof (UINT16)) { // // Write the last remaining word if exist // PciExpressWrite16 (StartAddress, *(UINT16*)Buffer); StartAddress += sizeof (UINT16); + Size -= sizeof (UINT16); Buffer = (UINT16*)Buffer + 1; } - if (EndAddress & 1) { + if (Size >= sizeof (UINT8)) { // // Write the last remaining byte if exist // PciExpressWrite8 (StartAddress, *(UINT8*)Buffer); } - return Size; + return ReturnValue; }