X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdePkg%2FLibrary%2FBasePciCf8Lib%2FPciCf8Lib.c;h=ba4190ab686cb9235fb7a9616799586d2f9ee3ee;hp=a9af173783042db65862eeed7947d0d28f7e06b7;hb=9344f0921518309295da89c221d10cbead8531aa;hpb=62991af27f84e5f20e55dee6e1f90eb77ec5325e diff --git a/MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c b/MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c index a9af173783..ba4190ab68 100644 --- a/MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c +++ b/MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c @@ -2,14 +2,8 @@ PCI CF8 Library functions that use I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles. Layers on top of an I/O Library instance. - Copyright (c) 2006 - 2008, Intel Corporation
- All rights reserved. This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -61,19 +55,20 @@ ASSERT (((A) & (~0xffff0ff | (M))) == 0) /** - Registers a PCI device so PCI configuration registers may be accessed after + Registers a PCI device so PCI configuration registers may be accessed after SetVirtualAddressMap(). - - Registers the PCI device specified by Address so all the PCI configuration registers + + Registers the PCI device specified by Address so all the PCI configuration registers associated with that PCI device may be accessed after SetVirtualAddressMap() is called. - + If Address > 0x0FFFFFFF, then ASSERT(). + If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. - + @retval RETURN_SUCCESS The PCI device was registered for runtime access. - @retval RETURN_UNSUPPORTED An attempt was made to call this function + @retval RETURN_UNSUPPORTED An attempt was made to call this function after ExitBootServices(). @retval RETURN_UNSUPPORTED The resources required to access the PCI device at runtime could not be mapped. @@ -87,6 +82,7 @@ PciCf8RegisterForRuntimeAccess ( IN UINTN Address ) { + ASSERT_INVALID_PCI_ADDRESS (Address, 0); return RETURN_SUCCESS; } @@ -100,7 +96,7 @@ PciCf8RegisterForRuntimeAccess ( If Address > 0x0FFFFFFF, then ASSERT(). If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. @return The read value from the PCI configuration register. @@ -112,9 +108,18 @@ PciCf8Read8 ( IN UINTN Address ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT8 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 0); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoRead8 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3)); + Result = IoRead8 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3)); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -127,7 +132,7 @@ PciCf8Read8 ( If Address > 0x0FFFFFFF, then ASSERT(). If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. @param Value The value to write. @@ -141,12 +146,21 @@ PciCf8Write8 ( IN UINT8 Value ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT8 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 0); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoWrite8 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), - Value - ); + Result = IoWrite8 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), + Value + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -163,7 +177,7 @@ PciCf8Write8 ( If Address > 0x0FFFFFFF, then ASSERT(). If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. @param OrData The value to OR with the PCI configuration register. @@ -177,12 +191,21 @@ PciCf8Or8 ( IN UINT8 OrData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT8 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 0); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoOr8 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), - OrData - ); + Result = IoOr8 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), + OrData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -199,7 +222,7 @@ PciCf8Or8 ( If Address > 0x0FFFFFFF, then ASSERT(). If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. @param AndData The value to AND with the PCI configuration register. @@ -213,12 +236,21 @@ PciCf8And8 ( IN UINT8 AndData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT8 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 0); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoAnd8 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), - AndData - ); + Result = IoAnd8 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), + AndData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -236,7 +268,7 @@ PciCf8And8 ( If Address > 0x0FFFFFFF, then ASSERT(). If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. @param AndData The value to AND with the PCI configuration register. @param OrData The value to OR with the result of the AND operation. @@ -252,13 +284,22 @@ PciCf8AndThenOr8 ( IN UINT8 OrData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT8 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 0); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoAndThenOr8 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), - AndData, - OrData - ); + Result = IoAndThenOr8 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), + AndData, + OrData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -274,7 +315,7 @@ PciCf8AndThenOr8 ( If EndBit is greater than 7, then ASSERT(). If EndBit is less than StartBit, then ASSERT(). - @param Address PCI configuration register to read. + @param Address The PCI configuration register to read. @param StartBit The ordinal of the least significant bit in the bit field. Range 0..7. @param EndBit The ordinal of the most significant bit in the bit field. @@ -291,13 +332,22 @@ PciCf8BitFieldRead8 ( IN UINTN EndBit ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT8 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 0); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoBitFieldRead8 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), - StartBit, - EndBit - ); + Result = IoBitFieldRead8 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), + StartBit, + EndBit + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -313,13 +363,14 @@ PciCf8BitFieldRead8 ( If StartBit is greater than 7, then ASSERT(). If EndBit is greater than 7, then ASSERT(). If EndBit is less than StartBit, then ASSERT(). + If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). - @param Address PCI configuration register to write. + @param Address The PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. Range 0..7. @param EndBit The ordinal of the most significant bit in the bit field. Range 0..7. - @param Value New value of the bit field. + @param Value The new value of the bit field. @return The value written back to the PCI configuration register. @@ -333,14 +384,23 @@ PciCf8BitFieldWrite8 ( IN UINT8 Value ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT8 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 0); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoBitFieldWrite8 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), - StartBit, - EndBit, - Value - ); + Result = IoBitFieldWrite8 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), + StartBit, + EndBit, + Value + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -359,8 +419,9 @@ PciCf8BitFieldWrite8 ( If StartBit is greater than 7, then ASSERT(). If EndBit is greater than 7, then ASSERT(). If EndBit is less than StartBit, then ASSERT(). + If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). - @param Address PCI configuration register to write. + @param Address The PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. Range 0..7. @param EndBit The ordinal of the most significant bit in the bit field. @@ -379,14 +440,23 @@ PciCf8BitFieldOr8 ( IN UINT8 OrData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT8 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 0); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoBitFieldOr8 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), - StartBit, - EndBit, - OrData - ); + Result = IoBitFieldOr8 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), + StartBit, + EndBit, + OrData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -405,8 +475,9 @@ PciCf8BitFieldOr8 ( If StartBit is greater than 7, then ASSERT(). If EndBit is greater than 7, then ASSERT(). If EndBit is less than StartBit, then ASSERT(). + If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). - @param Address PCI configuration register to write. + @param Address The PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. Range 0..7. @param EndBit The ordinal of the most significant bit in the bit field. @@ -425,14 +496,23 @@ PciCf8BitFieldAnd8 ( IN UINT8 AndData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT8 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 0); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoBitFieldAnd8 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), - StartBit, - EndBit, - AndData - ); + Result = IoBitFieldAnd8 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), + StartBit, + EndBit, + AndData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -453,8 +533,10 @@ PciCf8BitFieldAnd8 ( If StartBit is greater than 7, then ASSERT(). If EndBit is greater than 7, then ASSERT(). If EndBit is less than StartBit, then ASSERT(). + If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). - @param Address PCI configuration register to write. + @param Address The PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. Range 0..7. @param EndBit The ordinal of the most significant bit in the bit field. @@ -475,15 +557,24 @@ PciCf8BitFieldAndThenOr8( IN UINT8 OrData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT8 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 0); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoBitFieldAndThenOr8 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), - StartBit, - EndBit, - AndData, - OrData - ); + Result = IoBitFieldAndThenOr8 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3), + StartBit, + EndBit, + AndData, + OrData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -497,7 +588,7 @@ PciCf8BitFieldAndThenOr8( If Address is not aligned on a 16-bit boundary, then ASSERT(). If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. @return The read value from the PCI configuration register. @@ -509,9 +600,18 @@ PciCf8Read16 ( IN UINTN Address ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT16 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 1); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoRead16 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2)); + Result = IoRead16 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2)); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -525,7 +625,7 @@ PciCf8Read16 ( If Address is not aligned on a 16-bit boundary, then ASSERT(). If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. @param Value The value to write. @@ -539,12 +639,21 @@ PciCf8Write16 ( IN UINT16 Value ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT16 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 1); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoWrite16 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), - Value - ); + Result = IoWrite16 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), + Value + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -562,7 +671,7 @@ PciCf8Write16 ( If Address is not aligned on a 16-bit boundary, then ASSERT(). If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. @param OrData The value to OR with the PCI configuration register. @@ -576,12 +685,21 @@ PciCf8Or16 ( IN UINT16 OrData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT16 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 1); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoOr16 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), - OrData - ); + Result = IoOr16 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), + OrData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -599,7 +717,7 @@ PciCf8Or16 ( If Address is not aligned on a 16-bit boundary, then ASSERT(). If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. @param AndData The value to AND with the PCI configuration register. @@ -613,12 +731,21 @@ PciCf8And16 ( IN UINT16 AndData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT16 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 1); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoAnd16 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), - AndData - ); + Result = IoAnd16 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), + AndData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -637,7 +764,7 @@ PciCf8And16 ( If Address is not aligned on a 16-bit boundary, then ASSERT(). If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. @param AndData The value to AND with the PCI configuration register. @param OrData The value to OR with the result of the AND operation. @@ -653,13 +780,22 @@ PciCf8AndThenOr16 ( IN UINT16 OrData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT16 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 1); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoAndThenOr16 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), - AndData, - OrData - ); + Result = IoAndThenOr16 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), + AndData, + OrData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -676,7 +812,7 @@ PciCf8AndThenOr16 ( If EndBit is greater than 15, then ASSERT(). If EndBit is less than StartBit, then ASSERT(). - @param Address PCI configuration register to read. + @param Address The PCI configuration register to read. @param StartBit The ordinal of the least significant bit in the bit field. Range 0..15. @param EndBit The ordinal of the most significant bit in the bit field. @@ -693,13 +829,22 @@ PciCf8BitFieldRead16 ( IN UINTN EndBit ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT16 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 1); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoBitFieldRead16 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), - StartBit, - EndBit - ); + Result = IoBitFieldRead16 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), + StartBit, + EndBit + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -716,13 +861,14 @@ PciCf8BitFieldRead16 ( If StartBit is greater than 15, then ASSERT(). If EndBit is greater than 15, then ASSERT(). If EndBit is less than StartBit, then ASSERT(). + If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). - @param Address PCI configuration register to write. + @param Address The PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. Range 0..15. @param EndBit The ordinal of the most significant bit in the bit field. Range 0..15. - @param Value New value of the bit field. + @param Value The new value of the bit field. @return The value written back to the PCI configuration register. @@ -736,14 +882,23 @@ PciCf8BitFieldWrite16 ( IN UINT16 Value ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT16 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 1); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoBitFieldWrite16 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), - StartBit, - EndBit, - Value - ); + Result = IoBitFieldWrite16 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), + StartBit, + EndBit, + Value + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -763,8 +918,9 @@ PciCf8BitFieldWrite16 ( If StartBit is greater than 15, then ASSERT(). If EndBit is greater than 15, then ASSERT(). If EndBit is less than StartBit, then ASSERT(). + If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). - @param Address PCI configuration register to write. + @param Address The PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. Range 0..15. @param EndBit The ordinal of the most significant bit in the bit field. @@ -783,14 +939,23 @@ PciCf8BitFieldOr16 ( IN UINT16 OrData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT16 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 1); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoBitFieldOr16 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), - StartBit, - EndBit, - OrData - ); + Result = IoBitFieldOr16 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), + StartBit, + EndBit, + OrData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -810,8 +975,9 @@ PciCf8BitFieldOr16 ( If StartBit is greater than 15, then ASSERT(). If EndBit is greater than 15, then ASSERT(). If EndBit is less than StartBit, then ASSERT(). + If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). - @param Address PCI configuration register to write. + @param Address The PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. Range 0..15. @param EndBit The ordinal of the most significant bit in the bit field. @@ -830,14 +996,23 @@ PciCf8BitFieldAnd16 ( IN UINT16 AndData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT16 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 1); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoBitFieldAnd16 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), - StartBit, - EndBit, - AndData - ); + Result = IoBitFieldAnd16 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), + StartBit, + EndBit, + AndData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -859,8 +1034,10 @@ PciCf8BitFieldAnd16 ( If StartBit is greater than 15, then ASSERT(). If EndBit is greater than 15, then ASSERT(). If EndBit is less than StartBit, then ASSERT(). + If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). - @param Address PCI configuration register to write. + @param Address The PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. Range 0..15. @param EndBit The ordinal of the most significant bit in the bit field. @@ -881,15 +1058,24 @@ PciCf8BitFieldAndThenOr16( IN UINT16 OrData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT16 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 1); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoBitFieldAndThenOr16 ( - PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), - StartBit, - EndBit, - AndData, - OrData - ); + Result = IoBitFieldAndThenOr16 ( + PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2), + StartBit, + EndBit, + AndData, + OrData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -903,7 +1089,7 @@ PciCf8BitFieldAndThenOr16( If Address is not aligned on a 32-bit boundary, then ASSERT(). If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. @return The read value from the PCI configuration register. @@ -915,9 +1101,18 @@ PciCf8Read32 ( IN UINTN Address ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT32 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 3); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoRead32 (PCI_CONFIGURATION_DATA_PORT); + Result = IoRead32 (PCI_CONFIGURATION_DATA_PORT); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -931,7 +1126,7 @@ PciCf8Read32 ( If Address is not aligned on a 32-bit boundary, then ASSERT(). If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. @param Value The value to write. @@ -945,12 +1140,21 @@ PciCf8Write32 ( IN UINT32 Value ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT32 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 3); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoWrite32 ( - PCI_CONFIGURATION_DATA_PORT, - Value - ); + Result = IoWrite32 ( + PCI_CONFIGURATION_DATA_PORT, + Value + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -968,7 +1172,7 @@ PciCf8Write32 ( If Address is not aligned on a 32-bit boundary, then ASSERT(). If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. @param OrData The value to OR with the PCI configuration register. @@ -982,12 +1186,21 @@ PciCf8Or32 ( IN UINT32 OrData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT32 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 3); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoOr32 ( - PCI_CONFIGURATION_DATA_PORT, - OrData - ); + Result = IoOr32 ( + PCI_CONFIGURATION_DATA_PORT, + OrData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -1005,7 +1218,7 @@ PciCf8Or32 ( If Address is not aligned on a 32-bit boundary, then ASSERT(). If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. @param AndData The value to AND with the PCI configuration register. @@ -1019,12 +1232,21 @@ PciCf8And32 ( IN UINT32 AndData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT32 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 3); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoAnd32 ( - PCI_CONFIGURATION_DATA_PORT, - AndData - ); + Result = IoAnd32 ( + PCI_CONFIGURATION_DATA_PORT, + AndData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -1043,7 +1265,7 @@ PciCf8And32 ( If Address is not aligned on a 32-bit boundary, then ASSERT(). If the register specified by Address >= 0x100, then ASSERT(). - @param Address Address that encodes the PCI Bus, Device, Function and + @param Address The address that encodes the PCI Bus, Device, Function and Register. @param AndData The value to AND with the PCI configuration register. @param OrData The value to OR with the result of the AND operation. @@ -1059,13 +1281,22 @@ PciCf8AndThenOr32 ( IN UINT32 OrData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT32 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 3); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoAndThenOr32 ( - PCI_CONFIGURATION_DATA_PORT, - AndData, - OrData - ); + Result = IoAndThenOr32 ( + PCI_CONFIGURATION_DATA_PORT, + AndData, + OrData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -1082,7 +1313,7 @@ PciCf8AndThenOr32 ( If EndBit is greater than 31, then ASSERT(). If EndBit is less than StartBit, then ASSERT(). - @param Address PCI configuration register to read. + @param Address The PCI configuration register to read. @param StartBit The ordinal of the least significant bit in the bit field. Range 0..31. @param EndBit The ordinal of the most significant bit in the bit field. @@ -1099,13 +1330,22 @@ PciCf8BitFieldRead32 ( IN UINTN EndBit ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT32 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 3); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoBitFieldRead32 ( - PCI_CONFIGURATION_DATA_PORT, - StartBit, - EndBit - ); + Result = IoBitFieldRead32 ( + PCI_CONFIGURATION_DATA_PORT, + StartBit, + EndBit + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -1122,13 +1362,14 @@ PciCf8BitFieldRead32 ( If StartBit is greater than 31, then ASSERT(). If EndBit is greater than 31, then ASSERT(). If EndBit is less than StartBit, then ASSERT(). + If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). - @param Address PCI configuration register to write. + @param Address The PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. Range 0..31. @param EndBit The ordinal of the most significant bit in the bit field. Range 0..31. - @param Value New value of the bit field. + @param Value The new value of the bit field. @return The value written back to the PCI configuration register. @@ -1142,14 +1383,23 @@ PciCf8BitFieldWrite32 ( IN UINT32 Value ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT32 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 3); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoBitFieldWrite32 ( - PCI_CONFIGURATION_DATA_PORT, - StartBit, - EndBit, - Value - ); + Result = IoBitFieldWrite32 ( + PCI_CONFIGURATION_DATA_PORT, + StartBit, + EndBit, + Value + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -1169,8 +1419,9 @@ PciCf8BitFieldWrite32 ( If StartBit is greater than 31, then ASSERT(). If EndBit is greater than 31, then ASSERT(). If EndBit is less than StartBit, then ASSERT(). + If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). - @param Address PCI configuration register to write. + @param Address The PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. Range 0..31. @param EndBit The ordinal of the most significant bit in the bit field. @@ -1189,14 +1440,23 @@ PciCf8BitFieldOr32 ( IN UINT32 OrData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT32 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 3); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoBitFieldOr32 ( - PCI_CONFIGURATION_DATA_PORT, - StartBit, - EndBit, - OrData - ); + Result = IoBitFieldOr32 ( + PCI_CONFIGURATION_DATA_PORT, + StartBit, + EndBit, + OrData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -1216,8 +1476,9 @@ PciCf8BitFieldOr32 ( If StartBit is greater than 31, then ASSERT(). If EndBit is greater than 31, then ASSERT(). If EndBit is less than StartBit, then ASSERT(). + If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). - @param Address PCI configuration register to write. + @param Address The PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. Range 0..31. @param EndBit The ordinal of the most significant bit in the bit field. @@ -1236,14 +1497,23 @@ PciCf8BitFieldAnd32 ( IN UINT32 AndData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT32 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 3); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoBitFieldAnd32 ( - PCI_CONFIGURATION_DATA_PORT, - StartBit, - EndBit, - AndData - ); + Result = IoBitFieldAnd32 ( + PCI_CONFIGURATION_DATA_PORT, + StartBit, + EndBit, + AndData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -1265,8 +1535,10 @@ PciCf8BitFieldAnd32 ( If StartBit is greater than 31, then ASSERT(). If EndBit is greater than 31, then ASSERT(). If EndBit is less than StartBit, then ASSERT(). + If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). + If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT(). - @param Address PCI configuration register to write. + @param Address The PCI configuration register to write. @param StartBit The ordinal of the least significant bit in the bit field. Range 0..31. @param EndBit The ordinal of the most significant bit in the bit field. @@ -1287,15 +1559,24 @@ PciCf8BitFieldAndThenOr32( IN UINT32 OrData ) { + BOOLEAN InterruptState; + UINT32 AddressPort; + UINT32 Result; + ASSERT_INVALID_PCI_ADDRESS (Address, 3); + InterruptState = SaveAndDisableInterrupts (); + AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT); IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address)); - return IoBitFieldAndThenOr32 ( - PCI_CONFIGURATION_DATA_PORT, - StartBit, - EndBit, - AndData, - OrData - ); + Result = IoBitFieldAndThenOr32 ( + PCI_CONFIGURATION_DATA_PORT, + StartBit, + EndBit, + AndData, + OrData + ); + IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort); + SetInterruptState (InterruptState); + return Result; } /** @@ -1314,10 +1595,10 @@ PciCf8BitFieldAndThenOr32( If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT(). If Size > 0 and Buffer is NULL, then ASSERT(). - @param StartAddress Starting address that encodes the PCI Bus, Device, + @param StartAddress The starting address that encodes the PCI Bus, Device, Function and Register. - @param Size Size in bytes of the transfer. - @param Buffer Pointer to a buffer receiving the data read. + @param Size The size in bytes of the transfer. + @param Buffer The pointer to a buffer receiving the data read. @return Size read from StartAddress. @@ -1414,10 +1695,10 @@ PciCf8ReadBuffer ( If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT(). If Size > 0 and Buffer is NULL, then ASSERT(). - @param StartAddress Starting address that encodes the PCI Bus, Device, + @param StartAddress The starting address that encodes the PCI Bus, Device, Function and Register. - @param Size Size in bytes of the transfer. - @param Buffer Pointer to a buffer containing the data to write. + @param Size The size in bytes of the transfer. + @param Buffer The pointer to a buffer containing the data to write. @return Size written to StartAddress.