OK I agree it will have more flexibility. Thanks for the comments.

Thanks,
Ray

> 在 2015年12月12日,12:58,Kinney, Michael D <[email protected]> 写道:
> 
> Ray,
> 
> I think this library instance should consume the PciLib class, not the 
> PciExpressLib class.  That way, the specific PCI access method can be 
> selected from the PciLib instance that this library is linked against.
> 
> The name should also be changed to BasePciSegmentLibPci
> 
> Thanks,
> 
> Mike
> 
>> -----Original Message-----
>> From: Ni, Ruiyu
>> Sent: Thursday, December 10, 2015 6:37 PM
>> To: [email protected]
>> Cc: Ni, Ruiyu <[email protected]>; Kinney, Michael D
>> <[email protected]>
>> Subject: [Patch] MdePkg: Add BasePciSegmentLibPciExpress
>> library.
>> 
>> This library only supports single segment access. If segment
>> number other
>> than 0 is passed into any API of this library, assertion
>> happens.
>> 
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Ruiyu Ni <[email protected]>
>> Cc: Michael Kinney <[email protected]>
>> ---
>> .../BasePciSegmentLibPciExpress.inf                |   43 +
>> .../BasePciSegmentLibPciExpress.uni                |  Bin 0 ->
>> 2080 bytes
>> .../BasePciSegmentLibPciExpress/PciSegmentLib.c    | 1286
>> ++++++++++++++++++++
>> MdePkg/MdePkg.dsc                                  |    1 +
>> 4 files changed, 1330 insertions(+)
>> create mode 100644
>> MdePkg/Library/BasePciSegmentLibPciExpress/BasePciSegmentLibPciE
>> xpress.inf
>> create mode 100644
>> MdePkg/Library/BasePciSegmentLibPciExpress/BasePciSegmentLibPciE
>> xpress.uni
>> create mode 100644
>> MdePkg/Library/BasePciSegmentLibPciExpress/PciSegmentLib.c
>> 
>> diff --git
>> a/MdePkg/Library/BasePciSegmentLibPciExpress/BasePciSegmentLibPc
>> iExpress.inf
>> b/MdePkg/Library/BasePciSegmentLibPciExpress/BasePciSegmentLibPc
>> iExpress.inf
>> new file mode 100644
>> index 0000000..dee9bbb
>> --- /dev/null
>> +++
>> b/MdePkg/Library/BasePciSegmentLibPciExpress/BasePciSegmentLibPc
>> iExpress.inf
>> @@ -0,0 +1,43 @@
>> +## @file
>> +# Instance of PCI Segment Library based on PCI Express Library.
>> +#
>> +# PCI Segment Library that layers on top of the PCI Express
>> Library which only
>> +#  supports segment 0 PCI configuration access.
>> +#
>> +# Copyright (c) 2015, Intel Corporation. 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                    = 0x00010005
>> +  BASE_NAME                      = BasePciSegmentLibPciExpress
>> +  MODULE_UNI_FILE                =
>> BasePciSegmentLibPciExpress.uni
>> +  FILE_GUID                      = AABF95D6-F40C-405F-8360-
>> 6A59794B8040
>> +  MODULE_TYPE                    = BASE
>> +  VERSION_STRING                 = 1.0
>> +  LIBRARY_CLASS                  = PciSegmentLib
>> +
>> +#
>> +# The following information is for reference only and not
>> required by the build tools.
>> +#
>> +#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
>> +#
>> +
>> +[Sources]
>> +  PciSegmentLib.c
>> +
>> +[Packages]
>> +  MdePkg/MdePkg.dec
>> +
>> +[LibraryClasses]
>> +  BaseLib
>> +  PciExpressLib
>> +  DebugLib
>> diff --git
>> a/MdePkg/Library/BasePciSegmentLibPciExpress/BasePciSegmentLibPc
>> iExpress.uni
>> b/MdePkg/Library/BasePciSegmentLibPciExpress/BasePciSegmentLibPc
>> iExpress.uni
>> new file mode 100644
>> index
>> 0000000000000000000000000000000000000000..8da9dc6e2b3928f0c2eac0
>> 96d9115b4721901c76
>> GIT binary patch
>> literal 2080
>> zcmc(gTW`}q5QXO%iT_}wFM!&lAn}3_B54g+KojMn!c&zrZ4xOrIWDdLJn)^}*z1
>> Nu
>> z`vNGk_cF6*&YYQze|&FP!y=w%{33g6mo~GxUD#uL#I9_KEp20&4H?g|M7F{!vW^
>> {L
>> zi>$}q#1_1lct!RJgpsBAr<SuGG237rGhg8oPR4d)YrHP7Z+<yhFF6D*4~?1Gl&E
>> 4e
>> zXUvI^x(Ggg29LF4qderRtP1Quvx@8*{~1b59m0|bdC4?lZ(~=WuZfX@t-
>> O?dRiVR5
>> zv~#D4RG)B8s%6YQ&mmEyxYW5zjU$&w&MBRqx_qB-
>> ;wktq?9iUuOWS9z3TEKUnd?lt
>> zWfx-
>> Au{5#EBcO@9ua5Nl2ErH~udQWWdsF5ds?&GM=#;9uf|K%DuvYJ={)N^)vlX_r
>> zv*l#4#6Mz3tQ2p?Y)<9@Umc}N&9O-r^`-Bt0$-
>> =c&SwbUA%3d=h_}vNITpeWOnj^b
>> zNP(rV$(YkcEoAjwUu4jt?~mD4w+AkPYqd*uvz@_4h{Bq=nPTaVDeDnDi@2(bR2B
>> P6
>> z_I-uK`39d|PPcXOTKXI4&#$%$DATN>t2!s660h8i*WK{i%0G44)m_(2u-
>> }fcVP^#M
>> zu^sGK>Yz+{Lf<Nr4;I6^L;tkxJ@2M{W}TpAgqj-
>> r>?U;BfLZJm9@q(E%zi)!>L+w`
>> zj7QHQx0$Jv^{z1rSEx0{mRoDJU&;LxyLh!-
>> #K=zZ>N;j8>?fcKqwS)1S&6&$6tj=7
>> zd=%Aty~9`0zcPNrBIde*@ivOjBDOCjPC!r4qC-
>> C^=5a;0&{O)4ZaD7R)3aB0jlVr!
>> zzcY~9U<^Qu?F>fJOUgD;s}G;w{r0G$?vnnChP>4`>V*Ta#Iy#x|MfMfm6<;*YxP
>> Wz
>> ieAQ2#vQBqpet*`*x8c5Too=-5*1!7h{JpP@SNkWZcuAK4
>> 
>> literal 0
>> HcmV?d00001
>> 
>> diff --git
>> a/MdePkg/Library/BasePciSegmentLibPciExpress/PciSegmentLib.c
>> b/MdePkg/Library/BasePciSegmentLibPciExpress/PciSegmentLib.c
>> new file mode 100644
>> index 0000000..1399116
>> --- /dev/null
>> +++ b/MdePkg/Library/BasePciSegmentLibPciExpress/PciSegmentLib.c
>> @@ -0,0 +1,1286 @@
>> +/** @file
>> +  PCI Segment Library that layers on top of the PCI Express
>> Library which only
>> +   supports segment 0 PCI configuration access.
>> +
>> +  Copyright (c) 2015, Intel Corporation. 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/PciExpressLib.h>
>> +#include <Library/PciSegmentLib.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) & (0xfffffffff0000000ULL | (M))) == 0)
>> +
>> +/**
>> +  Convert the PCI Segment address to PCI Express address.
>> +
>> +  @param A The address to convert.
>> +**/
>> +#define PCI_SEGMENT_TO_PCI_EXPRESS_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 PciExpressRegisterForRuntimeAccess
>> (PCI_SEGMENT_TO_PCI_EXPRESS_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   The 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 PciExpressRead8 (PCI_SEGMENT_TO_PCI_EXPRESS_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     The 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 PciExpressWrite8 (PCI_SEGMENT_TO_PCI_EXPRESS_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   The 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 PciSegmentWrite8 (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   The 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   The 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   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
>> +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   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
>> +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   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
>> +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   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
>> +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   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
>> +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   The 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 PciExpressRead16 (PCI_SEGMENT_TO_PCI_EXPRESS_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     The 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 PciExpressWrite16 (PCI_SEGMENT_TO_PCI_EXPRESS_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 The 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   The 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   The 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   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
>> +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   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
>> +PciSegmentBitFieldWrite16 (
>> +  IN UINT64                    Address,
>> +  IN UINTN                     StartBit,
>> +  IN UINTN                     EndBit,
>> +  IN UINT16                    Value
>> +  )
>> +{
>> +  return PciSegmentWrite16 (
>> +           Address,
>> +           BitFieldWrite16 (PciSegmentRead16 (Address),
>> StartBit, EndBit, 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.
>> +
>> +  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   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
>> +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, 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 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 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 address that encodes the PCI Segment,
>> Bus, Device, Function, and Register.
>> +  @param  StartBit  The ordinal of the least significant bit in
>> the bit field.
>> +                    The ordinal of the least significant bit in
>> a byte is bit 0.
>> +  @param  EndBit    The ordinal of the most significant bit in
>> the bit field.
>> +                    The ordinal of the most significant bit in
>> a byte is bit 7.
>> +  @param  AndData   The value to AND with the read value from
>> the PCI configuration register.
>> +
>> +  @return The value written 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   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
>> +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   The 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 PciExpressRead32 (PCI_SEGMENT_TO_PCI_EXPRESS_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     The 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 PciExpressWrite32 (PCI_SEGMENT_TO_PCI_EXPRESS_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   The 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   The 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   The 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   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
>> +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   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
>> +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   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
>> +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   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
>> +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   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
>> +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 StartAdress 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  The starting address that encodes the
>> PCI Segment, 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
>> +
>> +**/
>> +UINTN
>> +EFIAPI
>> +PciSegmentReadBuffer (
>> +  IN  UINT64                   StartAddress,
>> +  IN  UINTN                    Size,
>> +  OUT VOID                     *Buffer
>> +  )
>> +{
>> +  UINTN                                ReturnValue;
>> +
>> +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
>> +  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
>> +
>> +  if (Size == 0) {
>> +    return Size;
>> +  }
>> +
>> +  ASSERT (Buffer != NULL);
>> +
>> +  //
>> +  // Save Size for return
>> +  //
>> +  ReturnValue = Size;
>> +
>> +  if ((StartAddress & BIT0) != 0) {
>> +    //
>> +    // Read a byte if StartAddress is byte aligned
>> +    //
>> +    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
>> +    StartAddress += sizeof (UINT8);
>> +    Size -= sizeof (UINT8);
>> +    Buffer = (UINT8*)Buffer + 1;
>> +  }
>> +
>> +  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
>> +    //
>> +    // Read a word if StartAddress is word aligned
>> +    //
>> +    WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
>> +    StartAddress += sizeof (UINT16);
>> +    Size -= sizeof (UINT16);
>> +    Buffer = (UINT16*)Buffer + 1;
>> +  }
>> +
>> +  while (Size >= sizeof (UINT32)) {
>> +    //
>> +    // Read as many double words as possible
>> +    //
>> +    WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));
>> +    StartAddress += sizeof (UINT32);
>> +    Size -= sizeof (UINT32);
>> +    Buffer = (UINT32*)Buffer + 1;
>> +  }
>> +
>> +  if (Size >= sizeof (UINT16)) {
>> +    //
>> +    // Read the last remaining word if exist
>> +    //
>> +    WriteUnaligned16 (Buffer, PciSegmentRead16 (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 = PciSegmentRead8 (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 StartAdress 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  The starting address that encodes the
>> PCI Segment, 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 The parameter of Size.
>> +
>> +**/
>> +UINTN
>> +EFIAPI
>> +PciSegmentWriteBuffer (
>> +  IN UINT64                    StartAddress,
>> +  IN UINTN                     Size,
>> +  IN VOID                      *Buffer
>> +  )
>> +{
>> +  UINTN                                ReturnValue;
>> +
>> +  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
>> +  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
>> +
>> +  if (Size == 0) {
>> +    return 0;
>> +  }
>> +
>> +  ASSERT (Buffer != NULL);
>> +
>> +  //
>> +  // Save Size for return
>> +  //
>> +  ReturnValue = Size;
>> +
>> +  if ((StartAddress & BIT0) != 0) {
>> +    //
>> +    // Write a byte if StartAddress is byte aligned
>> +    //
>> +    PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);
>> +    StartAddress += sizeof (UINT8);
>> +    Size -= sizeof (UINT8);
>> +    Buffer = (UINT8*)Buffer + 1;
>> +  }
>> +
>> +  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
>> +    //
>> +    // Write a word if StartAddress is word aligned
>> +    //
>> +    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
>> +    StartAddress += sizeof (UINT16);
>> +    Size -= sizeof (UINT16);
>> +    Buffer = (UINT16*)Buffer + 1;
>> +  }
>> +
>> +  while (Size >= sizeof (UINT32)) {
>> +    //
>> +    // Write as many double words as possible
>> +    //
>> +    PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));
>> +    StartAddress += sizeof (UINT32);
>> +    Size -= sizeof (UINT32);
>> +    Buffer = (UINT32*)Buffer + 1;
>> +  }
>> +
>> +  if (Size >= sizeof (UINT16)) {
>> +    //
>> +    // Write the last remaining word if exist
>> +    //
>> +    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
>> +    StartAddress += sizeof (UINT16);
>> +    Size -= sizeof (UINT16);
>> +    Buffer = (UINT16*)Buffer + 1;
>> +  }
>> +
>> +  if (Size >= sizeof (UINT8)) {
>> +    //
>> +    // Write the last remaining byte if exist
>> +    //
>> +    PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);
>> +  }
>> +
>> +  return ReturnValue;
>> +}
>> diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
>> index 4ea367c..a36625f 100644
>> --- a/MdePkg/MdePkg.dsc
>> +++ b/MdePkg/MdePkg.dsc
>> @@ -68,6 +68,7 @@
>>   MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
>>   MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
>>   MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
>> +
>> MdePkg/Library/BasePciSegmentLibPciExpress/BasePciSegmentLibPciE
>> xpress.inf
>> 
>> MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPoin
>> tLib.inf
>>   MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
>> 
>> MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActio
>> nLibNull.inf
>> --
>> 1.9.5.msysgit.1
> 
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to