czw., 16 maj 2019 o 16:02 Ard Biesheuvel <ard.biesheu...@linaro.org> napisaĆ(a): > > On Thu, 9 May 2019 at 11:54, Marcin Wojtas <m...@semihalf.com> wrote: > > > > From: Ard Biesheuvel <ard.biesheu...@linaro.org> > > > > Implement a special version of PciExpressLib that takes the quirky > > nature of the Synopsys Designware PCIe IP into account. In particular, > > we need to ignores config space accesses to all devices on the first > > ignore > > > > bus except device 0, because the broadcast nature of type 0 configuration > > cycles will result in whatever device is in the slot to appear at each > > of the 32 device positions. > > > > Contributed-under: TianoCore Contribution Agreement 1.1 > > Signed-off-by: Marcin Wojtas <m...@semihalf.com> > > --- > > > > Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib/PciExpressLib.inf > > | 42 + > > Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib/PciExpressLib.c > > | 1529 ++++++++++++++++++++ > > 2 files changed, 1571 insertions(+) > > create mode 100644 > > Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib/PciExpressLib.inf > > create mode 100644 > > Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib/PciExpressLib.c > > > > diff --git > > a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib/PciExpressLib.inf > > > > b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib/PciExpressLib.inf > > new file mode 100644 > > index 0000000..8f09820 > > --- /dev/null > > +++ > > b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib/PciExpressLib.inf > > @@ -0,0 +1,42 @@ > > +## @file > > +# > > +# Copyright (c) 2017, Linaro, Ltd. All rights reserved.<BR> > > +# Copyright (c) 2019 Marvell International Ltd. All rights reserved.<BR> > > +# > > +# 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. > > +# > > +# > > +## > > + > > +[Defines] > > + INF_VERSION = 0x0001001B > > + BASE_NAME = Armada7k8kPciExpressLib > > + FILE_GUID = f0926204-3061-40ed-8261-2aeccc7914c9 > > + MODULE_TYPE = BASE > > + VERSION_STRING = 1.0 > > + LIBRARY_CLASS = PciExpressLib > > + > > +[Sources] > > + PciExpressLib.c > > + > > +[Packages] > > + ArmPkg/ArmPkg.dec > > + MdePkg/MdePkg.dec > > + > > +[LibraryClasses] > > + BaseLib > > + DebugLib > > + IoLib > > + PcdLib > > + > > +[Pcd] > > + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## CONSUMES > > + > > +[FixedPcd] > > + gArmTokenSpaceGuid.PcdPciBusMin > > + gArmTokenSpaceGuid.PcdPciBusMax > > diff --git > > a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib/PciExpressLib.c > > > > b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib/PciExpressLib.c > > new file mode 100644 > > index 0000000..8fa2eb6 > > --- /dev/null > > +++ > > b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib/PciExpressLib.c > > @@ -0,0 +1,1529 @@ > > +/** @file > > + > > + Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR> > > + Copyright (c) 2019 Marvell International Ltd. All rights reserved.<BR> > > + > > + 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. > > + > > +**/ > > + > > + > > +#include <Base.h> > > + > > +#include <Library/BaseLib.h> > > +#include <Library/DebugLib.h> > > +#include <Library/IoLib.h> > > +#include <Library/PcdLib.h> > > +#include <Library/PciExpressLib.h> > > + > > +/** > > + Assert the validity of a PCI address. A valid PCI address should contain > > 1's > > + only in the low 28 bits. > > + > > + @param A The address to validate. > > + > > +**/ > > +#define ASSERT_INVALID_PCI_ADDRESS(A) \ > > + ASSERT (((A) & ~0xfffffff) == 0) > > + > > +/** > > + 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 associated with that PCI device may be accessed after > > SetVirtualAddressMap() > > + is called. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + > > + @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 > > + after ExitBootServices(). > > + @retval RETURN_UNSUPPORTED The resources required to access the > > PCI device > > + at runtime could not be mapped. > > + @retval RETURN_OUT_OF_RESOURCES There are not enough resources > > available to > > + complete the registration. > > + > > +**/ > > +RETURN_STATUS > > +EFIAPI > > +PciExpressRegisterForRuntimeAccess ( > > + IN UINTN Address > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + return RETURN_UNSUPPORTED; > > +} > > + > > +#define ECAM_BUS_SIZE SIZE_1MB > > +#define ECAM_DEV_SIZE SIZE_32KB > > + > > +STATIC > > +BOOLEAN > > +IgnoreBusDeviceFunction ( > > + IN UINTN Address > > + ) > > +{ > > + ASSERT (Address >= FixedPcdGet32 (PcdPciBusMin) * ECAM_BUS_SIZE); > > + ASSERT (Address < (FixedPcdGet32 (PcdPciBusMax) + 1) * ECAM_BUS_SIZE); > > + > > + // > > + // Type 0 configuration cycles don't contain a b/d/f specifier, and so it > > + // is up to the bus that delivers them to ensure they only end up at the > > + // correct device/function. Sadly, the Synopsys IP does not implement > > this, > > + // and so we have to ignore config space accesses for all devices on the > > + // first bus except device 0. > > + // > > This is not entirely true. Type 0 PCIe config TLPs (as opposed to > legacy PCI bus cycles) do contain b/d/f specifiers, but the endpoint > doesn't know its own device number, and so it responds to all of them. >
Ok, I will update the original comment. Thanks, Marcin > > + return (Address >= (FixedPcdGet32 (PcdPciBusMin) * ECAM_BUS_SIZE + > > + ECAM_DEV_SIZE) && > > + Address < (FixedPcdGet32 (PcdPciBusMin) + 1) * ECAM_BUS_SIZE); > > +} > > + > > +/** > > + 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. > > + > > +**/ > > +VOID* > > +GetPciExpressBaseAddress ( > > + VOID > > + ) > > +{ > > + return (VOID*)(UINTN) PcdGet64 (PcdPciExpressBaseAddress); > > +} > > + > > +/** > > + Reads an 8-bit PCI configuration register. > > + > > + Reads and returns the 8-bit PCI configuration register specified by > > Address. > > + This function must guarantee that all PCI read and write operations are > > + serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Function > > and > > + Register. > > + > > + @return The read value from the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressRead8 ( > > + IN UINTN Address > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioRead8 ((UINTN) GetPciExpressBaseAddress () + Address); > > +} > > + > > +/** > > + Writes an 8-bit PCI configuration register. > > + > > + Writes the 8-bit PCI configuration register specified by Address with the > > + value specified by Value. Value is returned. This function must guarantee > > + that all PCI read and write operations are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Function > > and > > + Register. > > + @param Value The value to write. > > + > > + @return The value written to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressWrite8 ( > > + IN UINTN Address, > > + IN UINT8 Value > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioWrite8 ((UINTN) GetPciExpressBaseAddress () + Address, Value); > > +} > > + > > +/** > > + Performs a bitwise OR of an 8-bit PCI configuration register with > > + an 8-bit value. > > + > > + Reads the 8-bit PCI configuration register specified by Address, > > performs a > > + bitwise OR between the read result and the value specified by > > + OrData, and writes the result to the 8-bit PCI configuration register > > + specified by Address. The value written to the PCI configuration > > register is > > + returned. This function must guarantee that all PCI read and write > > operations > > + are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Function > > and > > + Register. > > + @param OrData The value to OR with the PCI configuration register. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressOr8 ( > > + IN UINTN Address, > > + IN UINT8 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioOr8 ((UINTN) GetPciExpressBaseAddress () + Address, OrData); > > +} > > + > > +/** > > + Performs a bitwise AND of an 8-bit PCI configuration register with an > > 8-bit > > + value. > > + > > + Reads the 8-bit PCI configuration register specified by Address, > > performs a > > + bitwise AND between the read result and the value specified by AndData, > > and > > + writes the result to the 8-bit PCI configuration register specified by > > + Address. The value written to the PCI configuration register is returned. > > + This function must guarantee that all PCI read and write operations are > > + serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Function > > and > > + Register. > > + @param AndData The value to AND with the PCI configuration register. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressAnd8 ( > > + IN UINTN Address, > > + IN UINT8 AndData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioAnd8 ((UINTN) GetPciExpressBaseAddress () + Address, AndData); > > +} > > + > > +/** > > + Performs a bitwise AND of an 8-bit PCI configuration register with an > > 8-bit > > + value, followed a bitwise OR with another 8-bit value. > > + > > + Reads the 8-bit PCI configuration register specified by Address, > > performs a > > + bitwise AND between the read result and the value specified by AndData, > > + performs a bitwise OR between the result of the AND operation and > > + the value specified by OrData, and writes the result to the 8-bit PCI > > + configuration register specified by Address. The value written to the PCI > > + configuration register is returned. This function must guarantee that > > all PCI > > + read and write operations are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + > > + @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. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressAndThenOr8 ( > > + IN UINTN Address, > > + IN UINT8 AndData, > > + IN UINT8 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioAndThenOr8 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + AndData, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a bit field of a PCI configuration register. > > + > > + Reads the bit field in an 8-bit PCI configuration register. The bit > > field is > > + specified by the StartBit and the EndBit. The value of the bit field is > > + returned. > > + > > + 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 StartBit, then ASSERT(). > > + > > + @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. > > + Range 0..7. > > + > > + @return The value of the bit field read from the PCI configuration > > register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressBitFieldRead8 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioBitFieldRead8 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit > > + ); > > +} > > + > > +/** > > + Writes a bit field to a PCI configuration register. > > + > > + Writes Value to the bit field of the PCI configuration register. The bit > > + field is specified by the StartBit and the EndBit. All other bits in the > > + destination PCI configuration register are preserved. The new value of > > the > > + 8-bit register is returned. > > + > > + 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 StartBit, then ASSERT(). > > + If Value is larger than the bitmask value range specified by StartBit > > and EndBit, then ASSERT(). > > + > > + @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 The new value of the bit field. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressBitFieldWrite8 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT8 Value > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioBitFieldWrite8 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + Value > > + ); > > +} > > + > > +/** > > + Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, > > and > > + writes the result back to the bit field in the 8-bit port. > > + > > + Reads the 8-bit PCI configuration register specified by Address, > > performs a > > + bitwise OR between the read result and the value specified by > > + OrData, and writes the result to the 8-bit PCI configuration register > > + specified by Address. The value written to the PCI configuration > > register is > > + returned. This function must guarantee that all PCI read and write > > operations > > + are serialized. Extra left bits in OrData are stripped. > > + > > + 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 StartBit, then ASSERT(). > > + If OrData is larger than the bitmask value range specified by StartBit > > and EndBit, then ASSERT(). > > + > > + @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 OrData The value to OR with the PCI configuration register. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressBitFieldOr8 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT8 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioBitFieldOr8 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a bit field in an 8-bit PCI configuration register, performs a > > bitwise > > + AND, and writes the result back to the bit field in the 8-bit register. > > + > > + Reads the 8-bit PCI configuration register specified by Address, > > performs a > > + bitwise AND between the read result and the value specified by AndData, > > and > > + writes the result to the 8-bit PCI configuration register specified by > > + Address. The value written to the PCI configuration register is returned. > > + This function must guarantee that all PCI read and write operations are > > + serialized. Extra left bits in AndData are stripped. > > + > > + 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 StartBit, then ASSERT(). > > + If AndData is larger than the bitmask value range specified by StartBit > > and EndBit, then ASSERT(). > > + > > + @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 AndData The value to AND with the PCI configuration register. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressBitFieldAnd8 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT8 AndData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioBitFieldAnd8 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + AndData > > + ); > > +} > > + > > +/** > > + Reads a bit field in an 8-bit port, performs a bitwise AND followed by a > > + bitwise OR, and writes the result back to the bit field in the > > + 8-bit port. > > + > > + Reads the 8-bit PCI configuration register specified by Address, > > performs a > > + bitwise AND followed by a bitwise OR between the read result and > > + the value specified by AndData, and writes the result to the 8-bit PCI > > + configuration register specified by Address. The value written to the PCI > > + configuration register is returned. This function must guarantee that > > all PCI > > + read and write operations are serialized. Extra left bits in both > > AndData and > > + OrData are stripped. > > + > > + 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 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 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 AndData The value to AND with the PCI configuration register. > > + @param OrData The value to OR with the result of the AND operation. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressBitFieldAndThenOr8 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT8 AndData, > > + IN UINT8 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioBitFieldAndThenOr8 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + AndData, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a 16-bit PCI configuration register. > > + > > + Reads and returns the 16-bit PCI configuration register specified by > > Address. > > + This function must guarantee that all PCI read and write operations are > > + serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Function > > and > > + Register. > > + > > + @return The read value from the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressRead16 ( > > + IN UINTN Address > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioRead16 ((UINTN) GetPciExpressBaseAddress () + Address); > > +} > > + > > +/** > > + Writes a 16-bit PCI configuration register. > > + > > + Writes the 16-bit PCI configuration register specified by Address with > > the > > + value specified by Value. Value is returned. This function must guarantee > > + that all PCI read and write operations are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Function > > and > > + Register. > > + @param Value The value to write. > > + > > + @return The value written to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressWrite16 ( > > + IN UINTN Address, > > + IN UINT16 Value > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioWrite16 ((UINTN) GetPciExpressBaseAddress () + Address, > > Value); > > +} > > + > > +/** > > + Performs a bitwise OR of a 16-bit PCI configuration register with > > + a 16-bit value. > > + > > + Reads the 16-bit PCI configuration register specified by Address, > > performs a > > + bitwise OR between the read result and the value specified by > > + OrData, and writes the result to the 16-bit PCI configuration register > > + specified by Address. The value written to the PCI configuration > > register is > > + returned. This function must guarantee that all PCI read and write > > operations > > + are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Function > > and > > + Register. > > + @param OrData The value to OR with the PCI configuration register. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressOr16 ( > > + IN UINTN Address, > > + IN UINT16 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioOr16 ((UINTN) GetPciExpressBaseAddress () + Address, OrData); > > +} > > + > > +/** > > + Performs a bitwise AND of a 16-bit PCI configuration register with a > > 16-bit > > + value. > > + > > + Reads the 16-bit PCI configuration register specified by Address, > > performs a > > + bitwise AND between the read result and the value specified by AndData, > > and > > + writes the result to the 16-bit PCI configuration register specified by > > + Address. The value written to the PCI configuration register is returned. > > + This function must guarantee that all PCI read and write operations are > > + serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Function > > and > > + Register. > > + @param AndData The value to AND with the PCI configuration register. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressAnd16 ( > > + IN UINTN Address, > > + IN UINT16 AndData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioAnd16 ((UINTN) GetPciExpressBaseAddress () + Address, > > AndData); > > +} > > + > > +/** > > + Performs a bitwise AND of a 16-bit PCI configuration register with a > > 16-bit > > + value, followed a bitwise OR with another 16-bit value. > > + > > + Reads the 16-bit PCI configuration register specified by Address, > > performs a > > + bitwise AND between the read result and the value specified by AndData, > > + performs a bitwise OR between the result of the AND operation and > > + the value specified by OrData, and writes the result to the 16-bit PCI > > + configuration register specified by Address. The value written to the PCI > > + configuration register is returned. This function must guarantee that > > all PCI > > + read and write operations are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > > + > > + @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. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressAndThenOr16 ( > > + IN UINTN Address, > > + IN UINT16 AndData, > > + IN UINT16 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioAndThenOr16 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + AndData, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a bit field of a PCI configuration register. > > + > > + Reads the bit field in a 16-bit PCI configuration register. The bit > > field is > > + specified by the StartBit and the EndBit. The value of the bit field is > > + returned. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + 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 StartBit, then ASSERT(). > > + > > + @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. > > + Range 0..15. > > + > > + @return The value of the bit field read from the PCI configuration > > register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressBitFieldRead16 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioBitFieldRead16 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit > > + ); > > +} > > + > > +/** > > + Writes a bit field to a PCI configuration register. > > + > > + Writes Value to the bit field of the PCI configuration register. The bit > > + field is specified by the StartBit and the EndBit. All other bits in the > > + destination PCI configuration register are preserved. The new value of > > the > > + 16-bit register is returned. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + 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 StartBit, then ASSERT(). > > + If Value is larger than the bitmask value range specified by StartBit > > and EndBit, then ASSERT(). > > + > > + @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 The new value of the bit field. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressBitFieldWrite16 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT16 Value > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioBitFieldWrite16 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + Value > > + ); > > +} > > + > > +/** > > + Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, > > and > > + writes the result back to the bit field in the 16-bit port. > > + > > + Reads the 16-bit PCI configuration register specified by Address, > > performs a > > + bitwise OR between the read result and the value specified by > > + OrData, and writes the result to the 16-bit PCI configuration register > > + specified by Address. The value written to the PCI configuration > > register is > > + returned. This function must guarantee that all PCI read and write > > operations > > + are serialized. Extra left bits in OrData are stripped. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + 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 StartBit, then ASSERT(). > > + If OrData is larger than the bitmask value range specified by StartBit > > and EndBit, then ASSERT(). > > + > > + @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 OrData The value to OR with the PCI configuration register. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressBitFieldOr16 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT16 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioBitFieldOr16 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a bit field in a 16-bit PCI configuration register, performs a > > bitwise > > + AND, and writes the result back to the bit field in the 16-bit register. > > + > > + Reads the 16-bit PCI configuration register specified by Address, > > performs a > > + bitwise AND between the read result and the value specified by AndData, > > and > > + writes the result to the 16-bit PCI configuration register specified by > > + Address. The value written to the PCI configuration register is returned. > > + This function must guarantee that all PCI read and write operations are > > + serialized. Extra left bits in AndData are stripped. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + 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 StartBit, then ASSERT(). > > + If AndData is larger than the bitmask value range specified by StartBit > > and EndBit, then ASSERT(). > > + > > + @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 AndData The value to AND with the PCI configuration register. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressBitFieldAnd16 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT16 AndData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioBitFieldAnd16 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + AndData > > + ); > > +} > > + > > +/** > > + Reads a bit field in a 16-bit port, performs a bitwise AND followed by a > > + bitwise OR, and writes the result back to the bit field in the > > + 16-bit port. > > + > > + Reads the 16-bit PCI configuration register specified by Address, > > performs a > > + bitwise AND followed by a bitwise OR between the read result and > > + the value specified by AndData, and writes the result to the 16-bit PCI > > + configuration register specified by Address. The value written to the PCI > > + configuration register is returned. This function must guarantee that > > all PCI > > + read and write operations are serialized. Extra left bits in both > > AndData and > > + OrData are stripped. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + 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 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 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 AndData The value to AND with the PCI configuration register. > > + @param OrData The value to OR with the result of the AND operation. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressBitFieldAndThenOr16 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT16 AndData, > > + IN UINT16 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioBitFieldAndThenOr16 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + AndData, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a 32-bit PCI configuration register. > > + > > + Reads and returns the 32-bit PCI configuration register specified by > > Address. > > + This function must guarantee that all PCI read and write operations are > > + serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Function > > and > > + Register. > > + > > + @return The read value from the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressRead32 ( > > + IN UINTN Address > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioRead32 ((UINTN) GetPciExpressBaseAddress () + Address); > > +} > > + > > +/** > > + Writes a 32-bit PCI configuration register. > > + > > + Writes the 32-bit PCI configuration register specified by Address with > > the > > + value specified by Value. Value is returned. This function must guarantee > > + that all PCI read and write operations are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Function > > and > > + Register. > > + @param Value The value to write. > > + > > + @return The value written to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressWrite32 ( > > + IN UINTN Address, > > + IN UINT32 Value > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioWrite32 ((UINTN) GetPciExpressBaseAddress () + Address, > > Value); > > +} > > + > > +/** > > + Performs a bitwise OR of a 32-bit PCI configuration register with > > + a 32-bit value. > > + > > + Reads the 32-bit PCI configuration register specified by Address, > > performs a > > + bitwise OR between the read result and the value specified by > > + OrData, and writes the result to the 32-bit PCI configuration register > > + specified by Address. The value written to the PCI configuration > > register is > > + returned. This function must guarantee that all PCI read and write > > operations > > + are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Function > > and > > + Register. > > + @param OrData The value to OR with the PCI configuration register. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressOr32 ( > > + IN UINTN Address, > > + IN UINT32 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioOr32 ((UINTN) GetPciExpressBaseAddress () + Address, OrData); > > +} > > + > > +/** > > + Performs a bitwise AND of a 32-bit PCI configuration register with a > > 32-bit > > + value. > > + > > + Reads the 32-bit PCI configuration register specified by Address, > > performs a > > + bitwise AND between the read result and the value specified by AndData, > > and > > + writes the result to the 32-bit PCI configuration register specified by > > + Address. The value written to the PCI configuration register is returned. > > + This function must guarantee that all PCI read and write operations are > > + serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Function > > and > > + Register. > > + @param AndData The value to AND with the PCI configuration register. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressAnd32 ( > > + IN UINTN Address, > > + IN UINT32 AndData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > +return MmioAnd32 ((UINTN) GetPciExpressBaseAddress () + Address, AndData); > > +} > > + > > +/** > > + Performs a bitwise AND of a 32-bit PCI configuration register with a > > 32-bit > > + value, followed a bitwise OR with another 32-bit value. > > + > > + Reads the 32-bit PCI configuration register specified by Address, > > performs a > > + bitwise AND between the read result and the value specified by AndData, > > + performs a bitwise OR between the result of the AND operation and > > + the value specified by OrData, and writes the result to the 32-bit PCI > > + configuration register specified by Address. The value written to the PCI > > + configuration register is returned. This function must guarantee that > > all PCI > > + read and write operations are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > > + > > + @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. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressAndThenOr32 ( > > + IN UINTN Address, > > + IN UINT32 AndData, > > + IN UINT32 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioAndThenOr32 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + AndData, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a bit field of a PCI configuration register. > > + > > + Reads the bit field in a 32-bit PCI configuration register. The bit > > field is > > + specified by the StartBit and the EndBit. The value of the bit field is > > + returned. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + 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 StartBit, then ASSERT(). > > + > > + @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. > > + Range 0..31. > > + > > + @return The value of the bit field read from the PCI configuration > > register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressBitFieldRead32 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioBitFieldRead32 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit > > + ); > > +} > > + > > +/** > > + Writes a bit field to a PCI configuration register. > > + > > + Writes Value to the bit field of the PCI configuration register. The bit > > + field is specified by the StartBit and the EndBit. All other bits in the > > + destination PCI configuration register are preserved. The new value of > > the > > + 32-bit register is returned. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + 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 StartBit, then ASSERT(). > > + If Value is larger than the bitmask value range specified by StartBit > > and EndBit, then ASSERT(). > > + > > + @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 The new value of the bit field. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressBitFieldWrite32 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT32 Value > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioBitFieldWrite32 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + Value > > + ); > > +} > > + > > +/** > > + Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, > > and > > + writes the result back to the bit field in the 32-bit port. > > + > > + Reads the 32-bit PCI configuration register specified by Address, > > performs a > > + bitwise OR between the read result and the value specified by > > + OrData, and writes the result to the 32-bit PCI configuration register > > + specified by Address. The value written to the PCI configuration > > register is > > + returned. This function must guarantee that all PCI read and write > > operations > > + are serialized. Extra left bits in OrData are stripped. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + 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 StartBit, then ASSERT(). > > + If OrData is larger than the bitmask value range specified by StartBit > > and EndBit, then ASSERT(). > > + > > + @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 OrData The value to OR with the PCI configuration register. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressBitFieldOr32 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT32 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioBitFieldOr32 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a bit field in a 32-bit PCI configuration register, performs a > > bitwise > > + AND, and writes the result back to the bit field in the 32-bit register. > > + > > + Reads the 32-bit PCI configuration register specified by Address, > > performs a > > + bitwise AND between the read result and the value specified by AndData, > > and > > + writes the result to the 32-bit PCI configuration register specified by > > + Address. The value written to the PCI configuration register is returned. > > + This function must guarantee that all PCI read and write operations are > > + serialized. Extra left bits in AndData are stripped. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + 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 StartBit, then ASSERT(). > > + If AndData is larger than the bitmask value range specified by StartBit > > and EndBit, then ASSERT(). > > + > > + @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 AndData The value to AND with the PCI configuration register. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressBitFieldAnd32 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT32 AndData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioBitFieldAnd32 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + AndData > > + ); > > +} > > + > > +/** > > + Reads a bit field in a 32-bit port, performs a bitwise AND followed by a > > + bitwise OR, and writes the result back to the bit field in the > > + 32-bit port. > > + > > + Reads the 32-bit PCI configuration register specified by Address, > > performs a > > + bitwise AND followed by a bitwise OR between the read result and > > + the value specified by AndData, and writes the result to the 32-bit PCI > > + configuration register specified by Address. The value written to the PCI > > + configuration register is returned. This function must guarantee that > > all PCI > > + read and write operations are serialized. Extra left bits in both > > AndData and > > + OrData are stripped. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + 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 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 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 AndData The value to AND with the PCI configuration register. > > + @param OrData The value to OR with the result of the AND operation. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressBitFieldAndThenOr32 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT32 AndData, > > + IN UINT32 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioBitFieldAndThenOr32 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + AndData, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a range of PCI configuration registers into a caller supplied > > buffer. > > + > > + Reads the range of PCI configuration registers specified by StartAddress > > and > > + Size into the buffer specified by Buffer. This function only allows the > > PCI > > + configuration registers from a single PCI function to be read. Size is > > + returned. When possible 32-bit PCI configuration read cycles are used to > > read > > + from StartAddress to StartAddress + Size. Due to alignment restrictions, > > 8-bit > > + and 16-bit PCI configuration read cycles may be used at the beginning > > and the > > + end of the range. > > + > > + If StartAddress > 0x0FFFFFFF, then ASSERT(). > > + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT(). > > + If Size > 0 and Buffer is NULL, then ASSERT(). > > + > > + @param StartAddress The starting address that encodes the PCI Bus, > > Device, > > + Function and Register. > > + @param Size The size in bytes of the transfer. > > + @param Buffer The pointer to a buffer receiving the data read. > > + > > + @return Size read data from StartAddress. > > + > > +**/ > > +UINTN > > +EFIAPI > > +PciExpressReadBuffer ( > > + IN UINTN StartAddress, > > + IN UINTN Size, > > + OUT VOID *Buffer > > + ) > > +{ > > + UINTN ReturnValue; > > + > > + ASSERT_INVALID_PCI_ADDRESS (StartAddress); > > + ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000); > > + > > + if (Size == 0) { > > + return Size; > > + } > > + > > + ASSERT (Buffer != NULL); > > + > > + // > > + // Save Size for return > > + // > > + ReturnValue = Size; > > + > > + if ((StartAddress & 1) != 0) { > > + // > > + // Read a byte if StartAddress is byte aligned > > + // > > + *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress); > > + StartAddress += sizeof (UINT8); > > + Size -= sizeof (UINT8); > > + Buffer = (UINT8*)Buffer + 1; > > + } > > + > > + if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) { > > + // > > + // Read a word if StartAddress is word aligned > > + // > > + WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 > > (StartAddress)); > > + > > + StartAddress += sizeof (UINT16); > > + Size -= sizeof (UINT16); > > + Buffer = (UINT16*)Buffer + 1; > > + } > > + > > + while (Size >= sizeof (UINT32)) { > > + // > > + // Read as many double words as possible > > + // > > + WriteUnaligned32 ((UINT32 *) Buffer, (UINT32) PciExpressRead32 > > (StartAddress)); > > + > > + StartAddress += sizeof (UINT32); > > + Size -= sizeof (UINT32); > > + Buffer = (UINT32*)Buffer + 1; > > + } > > + > > + if (Size >= sizeof (UINT16)) { > > + // > > + // Read the last remaining word if exist > > + // > > + WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 > > (StartAddress)); > > + StartAddress += sizeof (UINT16); > > + Size -= sizeof (UINT16); > > + Buffer = (UINT16*)Buffer + 1; > > + } > > + > > + if (Size >= sizeof (UINT8)) { > > + // > > + // Read the last remaining byte if exist > > + // > > + *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress); > > + } > > + > > + return ReturnValue; > > +} > > + > > +/** > > + Copies the data in a caller supplied buffer to a specified range of PCI > > + configuration space. > > + > > + Writes the range of PCI configuration registers specified by > > StartAddress and > > + Size from the buffer specified by Buffer. This function only allows the > > PCI > > + configuration registers from a single PCI function to be written. Size is > > + returned. When possible 32-bit PCI configuration write cycles are used to > > + write from StartAddress to StartAddress + Size. Due to alignment > > restrictions, > > + 8-bit and 16-bit PCI configuration write cycles may be used at the > > beginning > > + and the end of the range. > > + > > + If StartAddress > 0x0FFFFFFF, then ASSERT(). > > + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT(). > > + If Size > 0 and Buffer is NULL, then ASSERT(). > > + > > + @param StartAddress The starting address that encodes the PCI Bus, > > Device, > > + Function and Register. > > + @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. > > + > > +**/ > > +UINTN > > +EFIAPI > > +PciExpressWriteBuffer ( > > + IN UINTN StartAddress, > > + IN UINTN Size, > > + IN VOID *Buffer > > + ) > > +{ > > + UINTN ReturnValue; > > + > > + ASSERT_INVALID_PCI_ADDRESS (StartAddress); > > + ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000); > > + > > + if (Size == 0) { > > + return 0; > > + } > > + > > + ASSERT (Buffer != NULL); > > + > > + // > > + // Save Size for return > > + // > > + ReturnValue = Size; > > + > > + 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 (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) { > > + // > > + // Write a word if StartAddress is word aligned > > + // > > + PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer)); > > + StartAddress += sizeof (UINT16); > > + Size -= sizeof (UINT16); > > + Buffer = (UINT16*)Buffer + 1; > > + } > > + > > + while (Size >= sizeof (UINT32)) { > > + // > > + // Write as many double words as possible > > + // > > + PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer)); > > + StartAddress += sizeof (UINT32); > > + Size -= sizeof (UINT32); > > + Buffer = (UINT32*)Buffer + 1; > > + } > > + > > + if (Size >= sizeof (UINT16)) { > > + // > > + // Write the last remaining word if exist > > + // > > + PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer)); > > + StartAddress += sizeof (UINT16); > > + Size -= sizeof (UINT16); > > + Buffer = (UINT16*)Buffer + 1; > > + } > > + > > + if (Size >= sizeof (UINT8)) { > > + // > > + // Write the last remaining byte if exist > > + // > > + PciExpressWrite8 (StartAddress, *(UINT8*)Buffer); > > + } > > + > > + return ReturnValue; > > +} > > -- > > 2.7.4 > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#40804): https://edk2.groups.io/g/devel/message/40804 Mute This Topic: https://groups.io/mt/31553479/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-