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

