public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Leif Lindholm" <leif@nuviainc.com>
To: Ard Biesheuvel <ardb@kernel.org>
Cc: Nhi Pham <nhi@os.amperecomputing.com>,
	edk2-devel-groups-io <devel@edk2.groups.io>,
	patches@amperecomputing.com,
	Vu Nguyen <vunguyen@os.amperecomputing.com>,
	Thang Nguyen <thang@os.amperecomputing.com>,
	Chuong Tran <chuong@os.amperecomputing.com>,
	Phong Vo <phong@os.amperecomputing.com>,
	Michael D Kinney <michael.d.kinney@intel.com>,
	Ard Biesheuvel <ardb+tianocore@kernel.org>,
	Nate DeSimone <nathaniel.l.desimone@intel.com>,
	Liming Gao <gaoliming@byosoft.com.cn>,
	Zhiguang Liu <zhiguang.liu@intel.com>
Subject: Re: [PATCH v3 15/28] Ampere: PCIe: Add PciSegmentLib library instance
Date: Tue, 28 Sep 2021 11:26:40 +0100	[thread overview]
Message-ID: <20210928102640.3oik7dgojwta2xql@leviathan> (raw)
In-Reply-To: <CAMj1kXELxuPZfFCiBP1KH4KjEzXDvf=P3xrZpN0CWmMKHfUn0w@mail.gmail.com>

+Liming, Zhiguang

On Fri, Sep 24, 2021 at 15:16:05 +0200, Ard Biesheuvel wrote:
> On Wed, 15 Sept 2021 at 18:00, Nhi Pham <nhi@os.amperecomputing.com> wrote:
> >
> > From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> >
> > Provides wrapper calls to the Ac01PcieLib to handle the PCIe access.
> > As Ampere Altra processor supports upto 16 PCIe Root Complexs, the
> > target Root Complex will depend on the segment number parsed from the
> > input address.
> >
> > Cc: Thang Nguyen <thang@os.amperecomputing.com>
> > Cc: Chuong Tran <chuong@os.amperecomputing.com>
> > Cc: Phong Vo <phong@os.amperecomputing.com>
> > Cc: Leif Lindholm <leif@nuviainc.com>
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> > Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> >
> > Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> OK, this is not your fault, but this file is 99% boilerplate, with the
> only platform specific piece being the calls to Ac01PcieConfigRW(),
> right?
> 
> Leif, Michael, do you see any avenues here to improve this situation?
> I don't think it should hold up this patch, but I have seen this
> pattern a few times now (and I am responsible for at least one of
> them)

I'm likely to be adding my own in the not too distant future...

Diffing this one against
MdePkg/Library/BasePciSegmentLibPci/PciSegmentLib.c,
the differences seems to be:
- The mask used in ASSERT_INVALID_PCI_SEGMENT_ADDRESS macro.
  (This is blatantly not portable in the first place, so ought to change)
- Whitespace fixes after cast operations.
- Change UINTN ReturnValue to EFI_STATUS. Hmm, that's actually wrong
  for a BASE library, isn't it?
- Use of friendly SIZE_4KB #define instead of live-coded 0x1000.
- Two patterns for dealing with unaligned accesses for read/write
  separately, with unaligned address support.

If this last one was broken out, and the first macro made use of a
function call to retreive the mask to use, we should be able to get
rid of the code duplication. (There could be additional abstractions
needed for other platforms, but that can be addressed at a later
point.)

So Nhi, aside from comments made directly on that library, I think
Ac01PcieConfigRW should return RETURN_STATUS rather than EFI_STATUS.
Umm, and looking more at it, I think Ac01PcieLib needs to be broken up
into smaller components. Ac01PcieConfigRW itself would be a prime
candidate to be in a BASE library with Ac01PcieCfgIn/Out#, which would
also be a good opportunity to align those function names.

I'm afraid that looking at Ac01PcieLib again, I found another item I
need to comment on there, coming up directly after this.

/
    Leif

> For the change itself,
> 
> Acked-by: Ard Biesheuvel <ardb@kernel.org>
> 
> > ---
> >  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                        |    1 +
> >  Silicon/Ampere/AmpereAltraPkg/Library/PciSegmentLibPci/PciSegmentLibPci.inf |   28 +
> >  Silicon/Ampere/AmpereAltraPkg/Library/PciSegmentLibPci/PciSegmentLib.c      | 1189 ++++++++++++++++++++
> >  3 files changed, 1218 insertions(+)
> >
> > diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> > index dc66b711aba8..dbcd1c9acaa2 100644
> > --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> > +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> > @@ -229,6 +229,7 @@ [LibraryClasses.common.DXE_DRIVER]
> >    MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> >    FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
> >    PciHostBridgeLib|Silicon/Ampere/AmpereAltraPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> > +  PciSegmentLib|Silicon/Ampere/AmpereAltraPkg/Library/PciSegmentLibPci/PciSegmentLibPci.inf
> >
> >  [LibraryClasses.common.UEFI_APPLICATION]
> >    UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiTianoCustomDecompressLib.inf
> > diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PciSegmentLibPci/PciSegmentLibPci.inf b/Silicon/Ampere/AmpereAltraPkg/Library/PciSegmentLibPci/PciSegmentLibPci.inf
> > new file mode 100644
> > index 000000000000..64897653e126
> > --- /dev/null
> > +++ b/Silicon/Ampere/AmpereAltraPkg/Library/PciSegmentLibPci/PciSegmentLibPci.inf
> > @@ -0,0 +1,28 @@
> > +## @file
> > +#
> > +# Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x0001001B
> > +  BASE_NAME                      = PciSegmentLibPci
> > +  FILE_GUID                      = 0AF5E76D-D31E-492B-AE69-A7B441FF62D9
> > +  MODULE_TYPE                    = BASE
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = PciSegmentLib
> > +
> > +[Sources]
> > +  PciSegmentLib.c
> > +
> > +[Packages]
q> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> > +
> > +[LibraryClasses]
> > +  Ac01PcieLib
> > +  BaseLib
> > +  DebugLib
> > diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PciSegmentLibPci/PciSegmentLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/PciSegmentLibPci/PciSegmentLib.c
> > new file mode 100644
> > index 000000000000..c893c56dfadf
> > --- /dev/null
> > +++ b/Silicon/Ampere/AmpereAltraPkg/Library/PciSegmentLibPci/PciSegmentLib.c
> > @@ -0,0 +1,1189 @@
> > +/** @file
> > +
> > +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Uefi.h>
> > +
> > +#include <Library/Ac01PcieLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/DevicePathLib.h>
> > +#include <Library/PciLib.h>
> > +#include <Library/PciSegmentLib.h>
> > +#include <Protocol/PciRootBridgeIo.h>
> > +
> > +#include <Ac01PcieCommon.h>
> > +
> > +/**
> > +  Assert the validity of a PCI Segment address.
> > +  A valid PCI Segment address should not contain 1's in bits 28..31 and 48..63
> > +  and the segment should be 0.
> > +
> > +  @param  A The address to validate.
> > +  @param  M Additional bits to assert to be zero.
> > +
> > +**/
> > +#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
> > +  ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
> > +
> > +/**
> > +  Convert the PCI Segment library address to PCI library address.
> > +
> > +  @param A The address to convert.
> > +**/
> > +#define PCI_SEGMENT_TO_PCI_ADDRESS(A) ((UINTN)(UINT32)A)
> > +
> > +/**
> > +  Register a PCI device so PCI configuration registers may be accessed after
> > +  SetVirtualAddressMap().
> > +
> > +  If any reserved bits in Address are set, 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
> > +PciSegmentRegisterForRuntimeAccess (
> > +  IN UINTN  Address
> > +  )
> > +{
> > +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> > +  return PciRegisterForRuntimeAccess (PCI_SEGMENT_TO_PCI_ADDRESS (Address));
> > +}
> > +
> > +/**
> > +  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 any reserved bits in Address are set, then ASSERT().
> > +
> > +  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +
> > +  @return The 8-bit PCI configuration register specified by Address.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciSegmentRead8 (
> > +  IN UINT64                    Address
> > +  )
> > +{
> > +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> > +
> > +  return PciRead8 (PCI_SEGMENT_TO_PCI_ADDRESS (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 any reserved bits in Address are set, then ASSERT().
> > +
> > +  @param  Address     Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +  @param  Value       The value to write.
> > +
> > +  @return The value written to the PCI configuration register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciSegmentWrite8 (
> > +  IN UINT64                    Address,
> > +  IN UINT8                     Value
> > +  )
> > +{
> > +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
> > +
> > +  return PciWrite8 (PCI_SEGMENT_TO_PCI_ADDRESS (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 any reserved bits in Address are set, then ASSERT().
> > +
> > +  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +  @param  OrData    The value to OR with the PCI configuration register.
> > +
> > +  @return The value written to the PCI configuration register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciSegmentOr8 (
> > +  IN UINT64                    Address,
> > +  IN UINT8                     OrData
> > +  )
> > +{
> > +  return PciWrite8 (PCI_SEGMENT_TO_PCI_ADDRESS (Address), (UINT8)(PciSegmentRead8 (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 any reserved bits in Address are set, then ASSERT().
> > +
> > +  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +  @param  AndData   The value to AND with the PCI configuration register.
> > +
> > +  @return The value written to the PCI configuration register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciSegmentAnd8 (
> > +  IN UINT64                    Address,
> > +  IN UINT8                     AndData
> > +  )
> > +{
> > +  return PciSegmentWrite8 (Address, (UINT8)(PciSegmentRead8 (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 any reserved bits in Address are set, then ASSERT().
> > +
> > +  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +  @param  AndData   The value to AND with the PCI configuration register.
> > +  @param  OrData    The value to OR with the PCI configuration register.
> > +
> > +  @return The value written to the PCI configuration register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciSegmentAndThenOr8 (
> > +  IN UINT64                    Address,
> > +  IN UINT8                     AndData,
> > +  IN UINT8                     OrData
> > +  )
> > +{
> > +  return PciSegmentWrite8 (Address, (UINT8)((PciSegmentRead8 (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 any reserved bits in Address are set, 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   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
> > +PciSegmentBitFieldRead8 (
> > +  IN UINT64                    Address,
> > +  IN UINTN                     StartBit,
> > +  IN UINTN                     EndBit
> > +  )
> > +{
> > +  return BitFieldRead8 (PciSegmentRead8 (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 any reserved bits in Address are set, 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   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.
> > +
> > +  @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciSegmentBitFieldWrite8 (
> > +  IN UINT64                    Address,
> > +  IN UINTN                     StartBit,
> > +  IN UINTN                     EndBit,
> > +  IN UINT8                     Value
> > +  )
> > +{
> > +  return PciSegmentWrite8 (
> > +           Address,
> > +           BitFieldWrite8 (PciSegmentRead8 (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 any reserved bits in Address are set, 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   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
> > +PciSegmentBitFieldOr8 (
> > +  IN UINT64                    Address,
> > +  IN UINTN                     StartBit,
> > +  IN UINTN                     EndBit,
> > +  IN UINT8                     OrData
> > +  )
> > +{
> > +  return PciSegmentWrite8 (
> > +           Address,
> > +           BitFieldOr8 (PciSegmentRead8 (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 any reserved bits in Address are set, 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   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
> > +PciSegmentBitFieldAnd8 (
> > +  IN UINT64                    Address,
> > +  IN UINTN                     StartBit,
> > +  IN UINTN                     EndBit,
> > +  IN UINT8                     AndData
> > +  )
> > +{
> > +  return PciSegmentWrite8 (
> > +           Address,
> > +           BitFieldAnd8 (PciSegmentRead8 (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 any reserved bits in Address are set, 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   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
> > +PciSegmentBitFieldAndThenOr8 (
> > +  IN UINT64                    Address,
> > +  IN UINTN                     StartBit,
> > +  IN UINTN                     EndBit,
> > +  IN UINT8                     AndData,
> > +  IN UINT8                     OrData
> > +  )
> > +{
> > +  return PciSegmentWrite8 (
> > +           Address,
> > +           BitFieldAndThenOr8 (PciSegmentRead8 (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 any reserved bits in Address are set, then ASSERT().
> > +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> > +
> > +  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +
> > +  @return The 16-bit PCI configuration register specified by Address.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciSegmentRead16 (
> > +  IN UINT64                    Address
> > +  )
> > +{
> > +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
> > +
> > +  return PciRead16 (PCI_SEGMENT_TO_PCI_ADDRESS (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 any reserved bits in Address are set, then ASSERT().
> > +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> > +
> > +  @param  Address     Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +  @param  Value       The value to write.
> > +
> > +  @return The parameter of Value.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciSegmentWrite16 (
> > +  IN UINT64                    Address,
> > +  IN UINT16                    Value
> > +  )
> > +{
> > +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
> > +
> > +  return PciWrite16 (PCI_SEGMENT_TO_PCI_ADDRESS (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 any reserved bits in Address are set, then ASSERT().
> > +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> > +
> > +  @param  Address Address that encodes the PCI Segment, 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
> > +PciSegmentOr16 (
> > +  IN UINT64                    Address,
> > +  IN UINT16                    OrData
> > +  )
> > +{
> > +  return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (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 any reserved bits in Address are set, then ASSERT().
> > +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> > +
> > +  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +  @param  AndData   The value to AND with the PCI configuration register.
> > +
> > +  @return The value written to the PCI configuration register.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciSegmentAnd16 (
> > +  IN UINT64                    Address,
> > +  IN UINT16                    AndData
> > +  )
> > +{
> > +  return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (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 any reserved bits in Address are set, then ASSERT().
> > +  If Address is not aligned on a 16-bit boundary, then ASSERT().
> > +
> > +  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +  @param  AndData   The value to AND with the PCI configuration register.
> > +  @param  OrData    The value to OR with the PCI configuration register.
> > +
> > +  @return The value written to the PCI configuration register.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciSegmentAndThenOr16 (
> > +  IN UINT64                    Address,
> > +  IN UINT16                    AndData,
> > +  IN UINT16                    OrData
> > +  )
> > +{
> > +  return PciSegmentWrite16 (Address, (UINT16) ((PciSegmentRead16 (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 any reserved bits in Address are set, 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   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
> > +PciSegmentBitFieldRead16 (
> > +  IN UINT64                    Address,
> > +  IN UINTN                     StartBit,
> > +  IN UINTN                     EndBit
> > +  )
> > +{
> > +  return BitFieldRead16 (PciSegmentRead16 (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 any reserved bits in Address are set, 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   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.
> > +
> > +  @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciSegmentBitFieldWrite16 (
> > +  IN UINT64                    Address,
> > +  IN UINTN                     StartBit,
> > +  IN UINTN                     EndBit,
> > +  IN UINT16                    Value
> > +  )
> > +{
> > +  return PciSegmentWrite16 (
> > +           Address,
> > +           BitFieldWrite16 (PciSegmentRead16 (Address), StartBit, EndBit, Value)
> > +           );
> > +}
> > +
> > +/**
> > +  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, 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 any reserved bits in Address are set, 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   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
> > +PciSegmentBitFieldOr16 (
> > +  IN UINT64                    Address,
> > +  IN UINTN                     StartBit,
> > +  IN UINTN                     EndBit,
> > +  IN UINT16                    OrData
> > +  )
> > +{
> > +  return PciSegmentWrite16 (
> > +           Address,
> > +           BitFieldOr16 (PciSegmentRead16 (Address), StartBit, EndBit, OrData)
> > +           );
> > +}
> > +
> > +/**
> > +  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
> > +  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 any reserved bits in Address are set, 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   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +  @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
> > +PciSegmentBitFieldAnd16 (
> > +  IN UINT64                    Address,
> > +  IN UINTN                     StartBit,
> > +  IN UINTN                     EndBit,
> > +  IN UINT16                    AndData
> > +  )
> > +{
> > +  return PciSegmentWrite16 (
> > +           Address,
> > +           BitFieldAnd16 (PciSegmentRead16 (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 any reserved bits in Address are set, 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   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
> > +PciSegmentBitFieldAndThenOr16 (
> > +  IN UINT64                    Address,
> > +  IN UINTN                     StartBit,
> > +  IN UINTN                     EndBit,
> > +  IN UINT16                    AndData,
> > +  IN UINT16                    OrData
> > +  )
> > +{
> > +  return PciSegmentWrite16 (
> > +           Address,
> > +           BitFieldAndThenOr16 (PciSegmentRead16 (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 any reserved bits in Address are set, then ASSERT().
> > +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> > +
> > +  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +
> > +  @return The 32-bit PCI configuration register specified by Address.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciSegmentRead32 (
> > +  IN UINT64                    Address
> > +  )
> > +{
> > +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
> > +
> > +  return PciRead32 (PCI_SEGMENT_TO_PCI_ADDRESS (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 any reserved bits in Address are set, then ASSERT().
> > +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> > +
> > +  @param  Address     Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +  @param  Value       The value to write.
> > +
> > +  @return The parameter of Value.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciSegmentWrite32 (
> > +  IN UINT64                    Address,
> > +  IN UINT32                    Value
> > +  )
> > +{
> > +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
> > +
> > +  return PciWrite32 (PCI_SEGMENT_TO_PCI_ADDRESS (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 any reserved bits in Address are set, then ASSERT().
> > +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> > +
> > +  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +  @param  OrData    The value to OR with the PCI configuration register.
> > +
> > +  @return The value written to the PCI configuration register.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciSegmentOr32 (
> > +  IN UINT64                    Address,
> > +  IN UINT32                    OrData
> > +  )
> > +{
> > +  return PciSegmentWrite32 (Address, PciSegmentRead32 (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 any reserved bits in Address are set, then ASSERT().
> > +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> > +
> > +  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +  @param  AndData   The value to AND with the PCI configuration register.
> > +
> > +  @return The value written to the PCI configuration register.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciSegmentAnd32 (
> > +  IN UINT64                    Address,
> > +  IN UINT32                    AndData
> > +  )
> > +{
> > +  return PciSegmentWrite32 (Address, PciSegmentRead32 (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 any reserved bits in Address are set, then ASSERT().
> > +  If Address is not aligned on a 32-bit boundary, then ASSERT().
> > +
> > +  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +  @param  AndData   The value to AND with the PCI configuration register.
> > +  @param  OrData    The value to OR with the PCI configuration register.
> > +
> > +  @return The value written to the PCI configuration register.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciSegmentAndThenOr32 (
> > +  IN UINT64                    Address,
> > +  IN UINT32                    AndData,
> > +  IN UINT32                    OrData
> > +  )
> > +{
> > +  return PciSegmentWrite32 (Address, (PciSegmentRead32 (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 any reserved bits in Address are set, 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   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
> > +PciSegmentBitFieldRead32 (
> > +  IN UINT64                    Address,
> > +  IN UINTN                     StartBit,
> > +  IN UINTN                     EndBit
> > +  )
> > +{
> > +  return BitFieldRead32 (PciSegmentRead32 (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 any reserved bits in Address are set, 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   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.
> > +
> > +  @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciSegmentBitFieldWrite32 (
> > +  IN UINT64                    Address,
> > +  IN UINTN                     StartBit,
> > +  IN UINTN                     EndBit,
> > +  IN UINT32                    Value
> > +  )
> > +{
> > +  return PciSegmentWrite32 (
> > +           Address,
> > +           BitFieldWrite32 (PciSegmentRead32 (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 any reserved bits in Address are set, 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   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
> > +PciSegmentBitFieldOr32 (
> > +  IN UINT64                    Address,
> > +  IN UINTN                     StartBit,
> > +  IN UINTN                     EndBit,
> > +  IN UINT32                    OrData
> > +  )
> > +{
> > +  return PciSegmentWrite32 (
> > +           Address,
> > +           BitFieldOr32 (PciSegmentRead32 (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 any reserved bits in Address are set, 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   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
> > +  @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
> > +PciSegmentBitFieldAnd32 (
> > +  IN UINT64                    Address,
> > +  IN UINTN                     StartBit,
> > +  IN UINTN                     EndBit,
> > +  IN UINT32                    AndData
> > +  )
> > +{
> > +  return PciSegmentWrite32 (
> > +           Address,
> > +           BitFieldAnd32 (PciSegmentRead32 (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 any reserved bits in Address are set, 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   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
> > +PciSegmentBitFieldAndThenOr32 (
> > +  IN UINT64                    Address,
> > +  IN UINTN                     StartBit,
> > +  IN UINTN                     EndBit,
> > +  IN UINT32                    AndData,
> > +  IN UINT32                    OrData
> > +  )
> > +{
> > +  return PciSegmentWrite32 (
> > +           Address,
> > +           BitFieldAndThenOr32 (PciSegmentRead32 (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 any reserved bits in StartAddress are set, then ASSERT().
> > +  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> > +  If Size > 0 and Buffer is NULL, then ASSERT().
> > +
> > +  @param  StartAddress  Starting address that encodes the PCI Segment, Bus, Device,
> > +                        Function and Register.
> > +  @param  Size          Size in bytes of the transfer.
> > +  @param  Buffer        Pointer to a buffer receiving the data read.
> > +
> > +  @return Size
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +PciSegmentReadBuffer (
> > +  IN  UINT64                   StartAddress,
> > +  IN  UINTN                    Size,
> > +  OUT VOID                     *Buffer
> > +  )
> > +{
> > +  EFI_STATUS Status;
> > +
> > +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
> > +  ASSERT (((StartAddress & 0xFFF) + Size) <= SIZE_4KB);
> > +
> > +  if (Size == 0) {
> > +    return Size;
> > +  }
> > +
> > +  ASSERT (Buffer != NULL);
> > +
> > +  Status = Ac01PcieConfigRW (NULL, StartAddress, FALSE, Size, Buffer);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  return Size;
> > +}
> > +
> > +/**
> > +  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 any reserved bits in StartAddress are set, then ASSERT().
> > +  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> > +  If Size > 0 and Buffer is NULL, then ASSERT().
> > +
> > +  @param  StartAddress  Starting address that encodes the PCI Segment, Bus, Device,
> > +                        Function and Register.
> > +  @param  Size          Size in bytes of the transfer.
> > +  @param  Buffer        Pointer to a buffer containing the data to write.
> > +
> > +  @return The parameter of Size.
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +PciSegmentWriteBuffer (
> > +  IN UINT64                    StartAddress,
> > +  IN UINTN                     Size,
> > +  IN VOID                      *Buffer
> > +  )
> > +{
> > +  EFI_STATUS Status;
> > +
> > +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
> > +  ASSERT (((StartAddress & 0xFFF) + Size) <= SIZE_4KB);
> > +
> > +  if (Size == 0) {
> > +    return Size;
> > +  }
> > +
> > +  ASSERT (Buffer != NULL);
> > +
> > +  Status = Ac01PcieConfigRW (NULL, StartAddress, TRUE, Size, Buffer);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  return Size;
> > +}
> > --
> > 2.17.1
> >

  reply	other threads:[~2021-09-28 10:26 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-15 15:54 [PATCH v3 00/28] Add new Ampere Mt. Jade platform Nhi Pham
2021-09-15 15:55 ` [PATCH v3 01/28] Ampere: Initial support for Ampere Altra processor and " Nhi Pham
2021-09-16 10:40   ` Leif Lindholm
2021-09-16 10:46     ` Leif Lindholm
2021-09-17  6:19       ` Nhi Pham
2021-09-23 13:54   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 02/28] AmpereAltraPkg: Add MmCommunication modules Nhi Pham
2021-09-15 15:55 ` [PATCH v3 03/28] AmperePlatformPkg: Implement FailSafe library Nhi Pham
2021-09-15 15:55 ` [PATCH v3 04/28] AmperePlatformPkg: Add FailSafe and WDT support Nhi Pham
2021-09-16 11:22   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 05/28] AmpereAltraPkg: Add DwI2cLib library Nhi Pham
2021-09-15 15:55 ` [PATCH v3 06/28] AmpereAltraPkg: Add DwGpioLib library Nhi Pham
2021-09-15 15:55 ` [PATCH v3 07/28] JadePkg: Implement RealTimeClockLib for PCF85063 Nhi Pham
2021-09-15 15:55 ` [PATCH v3 08/28] AmpereAltraPkg: Add BootProgress support Nhi Pham
2021-09-15 15:55 ` [PATCH v3 09/28] AmpereAltraPkg: Support UEFI non-volatile variable Nhi Pham
2021-09-23 11:49   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 10/28] AmpereSiliconPkg: Add PlatformManagerUiLib library instance Nhi Pham
2021-09-15 15:55 ` [PATCH v3 11/28] AmpereAltraPkg, JadePkg: Add ACPI support Nhi Pham
2021-09-15 15:55 ` [PATCH v3 12/28] AmpereAltraPkg: Add Ac01PcieLib library instance Nhi Pham
2021-09-23 13:49   ` Leif Lindholm
2021-09-27 14:33     ` Nhi Pham
2021-10-04 12:03     ` Nhi Pham
2021-10-05 19:59       ` Leif Lindholm
2021-10-06 12:55         ` [edk2-devel] " Nhi Pham
2021-10-07  9:06           ` Leif Lindholm
2021-10-07  9:13             ` Nhi Pham
2021-09-28 10:34   ` Leif Lindholm
2021-10-04 11:36     ` Nhi Pham
2021-09-15 15:55 ` [PATCH v3 13/28] JadePkg: Add BoardPcieLib " Nhi Pham
2021-09-24 12:35   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 14/28] Ampere: PCIe: Add PciHostBridgeLib " Nhi Pham
2021-09-24 13:12   ` Ard Biesheuvel
2021-09-15 15:55 ` [PATCH v3 15/28] Ampere: PCIe: Add PciSegmentLib " Nhi Pham
2021-09-24 13:16   ` Ard Biesheuvel
2021-09-28 10:26     ` Leif Lindholm [this message]
2021-09-15 15:55 ` [PATCH v3 16/28] JadePkg: Enable PCIe-related libraries and device drivers Nhi Pham
2021-09-15 15:55 ` [PATCH v3 17/28] JadePkg: Add ASpeed GOP driver Nhi Pham
2021-09-15 15:55 ` [PATCH v3 18/28] Ampere: PCIe: Add PciPlatformDxe driver Nhi Pham
2021-09-24 12:59   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 19/28] AmpereAltraPkg: Add Random Number Generator Support Nhi Pham
2021-09-15 15:55 ` [PATCH v3 20/28] JadePkg: Add SMBIOS tables support Nhi Pham
2021-09-15 15:55 ` [PATCH v3 21/28] AmpereAltraPkg: Add DebugInfoPei module Nhi Pham
2021-09-24 12:43   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 22/28] AmpereAltraPkg: Add platform info screen Nhi Pham
2021-09-15 15:55 ` [PATCH v3 23/28] AmpereAltraPkg: Add configuration screen for memory Nhi Pham
2021-09-24 12:50   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 24/28] AmpereAltraPkg: Add configuration screen for CPU Nhi Pham
2021-09-24 12:51   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 25/28] AmpereAltraPkg: Add configuration screen for ACPI Nhi Pham
2021-09-24 12:53   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 26/28] AmpereAltraPkg: Add configuration screen for RAS Nhi Pham
2021-09-24 12:54   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 27/28] AmpereAltraPkg: Add configuration screen for Watchdog timer Nhi Pham
2021-09-24 12:55   ` Leif Lindholm
2021-09-15 15:55 ` [PATCH v3 28/28] AmpereAltraPkg: Add configuration screen for Pcie Devices Nhi Pham
2021-09-24 12:57   ` Leif Lindholm
2021-09-16 10:09 ` [PATCH v3 00/28] Add new Ampere Mt. Jade platform Leif Lindholm
2021-09-17  6:10   ` Nhi Pham

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210928102640.3oik7dgojwta2xql@leviathan \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox