From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from zg8tmtyylji0my4xnjqunzqa.icoremail.net (zg8tmtyylji0my4xnjqunzqa.icoremail.net [162.243.164.74]) by mx.groups.io with SMTP id smtpd.web12.52441.1629279652167590333 for ; Wed, 18 Aug 2021 02:40:52 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: phytium.com.cn, ip: 162.243.164.74, mailfrom: jialing@phytium.com.cn) Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-2 (Coremail) with SMTP id AQAAfwBHbMy91RxhsNNtAQ--.34020S2; Wed, 18 Aug 2021 17:41:17 +0800 (CST) Received: from localhost.localdomain (unknown [223.104.21.14]) by mail (Coremail) with SMTP id AQAAfwCXMX2V1RxhgDMAAA--.1385S6; Wed, 18 Aug 2021 17:40:45 +0800 (CST) From: "Ling Jia" To: devel@edk2.groups.io Cc: Leif Lindholm , Ling Jia Subject: [PATCH v4 04/10] Silicon/Phytium: Added PciSegmentLib to FT2000/4 Date: Wed, 18 Aug 2021 17:40:18 +0800 Message-Id: <20210818094024.40104-5-jialing@phytium.com.cn> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210818094024.40104-1-jialing@phytium.com.cn> References: <20210818094024.40104-1-jialing@phytium.com.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAfwCXMX2V1RxhgDMAAA--.1385S6 X-CM-SenderInfo: xmldzxdqj61x51wl3zoofrzhdfq/ Authentication-Results: hzbj-icmmx-2; spf=neutral smtp.mail=jialing@ph ytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvAXoWDJF1UXF17uF1Dtr1kZFy3CFg_yoW7Jr17Go ZYvFy8Xr1vqw1xKF1xt3sxXw4fWFZ2kr1xArWFqrW5X3WvqFsa9a4Iqa1DJr97G3W7Kryk Xr95Za97JFWrt3Wrn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3UbIjqfuFe4nvWSU8nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UU UUUUUUU== Content-Transfer-Encoding: quoted-printable The PCI Segment Library for Phytium platform. with multiple RCs. Signed-off-by: Ling Jia --- Platform/Phytium/DurianPkg/DurianPkg.dsc | 9= +- Silicon/Phytium/FT2000-4Pkg/Library/PciSegmentLib/PciSegmentLib.inf | 28= + Silicon/Phytium/FT2000-4Pkg/Library/PciSegmentLib/PciSegmentLib.c | 1434= ++++++++++++++++++++ 3 files changed, 1464 insertions(+), 7 deletions(-) diff --git a/Platform/Phytium/DurianPkg/DurianPkg.dsc b/Platform/Phytium/Du= rianPkg/DurianPkg.dsc index 28e52e15e3..093b2cd9db 100644 --- a/Platform/Phytium/DurianPkg/DurianPkg.dsc +++ b/Platform/Phytium/DurianPkg/DurianPkg.dsc @@ -35,7 +35,8 @@ PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf=0D =0D [LibraryClasses.common.DXE_DRIVER]=0D -=0D + # Pci dependencies=0D + PciSegmentLib|Silicon/Phytium/FT2000-4Pkg/Library/PciSegmentLib/PciSegme= ntLib.inf=0D =0D ##########################################################################= ######=0D #=0D @@ -262,12 +263,6 @@ MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf=0D MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf=0D =0D - #=0D - # PCI Support=0D - #=0D - ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf=0D - MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDevic= eDxe.inf=0D -=0D #=0D # The following 2 module perform the same work except one operate variab= le.=0D # Only one of both should be put into fdf.=0D diff --git a/Silicon/Phytium/FT2000-4Pkg/Library/PciSegmentLib/PciSegmentLi= b.inf b/Silicon/Phytium/FT2000-4Pkg/Library/PciSegmentLib/PciSegmentLib.inf new file mode 100644 index 0000000000..67360016ef --- /dev/null +++ b/Silicon/Phytium/FT2000-4Pkg/Library/PciSegmentLib/PciSegmentLib.inf @@ -0,0 +1,28 @@ +#/** @file=0D +# PCI Segment Library for Phytium platform with multiple RCs.=0D +#=0D +# Copyright (C) 2020, Phytium Technology Co, Ltd. All rights reserved.=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +#**/=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x0001001b=0D + BASE_NAME =3D PciSegmentLib=0D + FILE_GUID =3D fa5173d2-40fe-11eb-9b2f-cb20dc669fd3= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D PciSegmentLib=0D +=0D +[Sources]=0D + PciSegmentLib.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + Silicon/Phytium/PhytiumCommonPkg/PhytiumCommonPkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + DebugLib=0D + IoLib=0D diff --git a/Silicon/Phytium/FT2000-4Pkg/Library/PciSegmentLib/PciSegmentLi= b.c b/Silicon/Phytium/FT2000-4Pkg/Library/PciSegmentLib/PciSegmentLib.c new file mode 100644 index 0000000000..c10b152e0d --- /dev/null +++ b/Silicon/Phytium/FT2000-4Pkg/Library/PciSegmentLib/PciSegmentLib.c @@ -0,0 +1,1434 @@ +/** @file=0D + PCI Segment Library for SoC with multiple RCs.=0D +=0D + Copyright (C) 2020, Phytium Technology Co Ltd. All rights reserved.
= =0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +#define PCI_SEG_CONFIG_BASE 0x40000000=0D +#define PCIE_BIF_MODE 0x29100800=0D +=0D +typedef enum {=0D + PciCfgWidthUint8 =3D 0,=0D + PciCfgWidthUint16,=0D + PciCfgWidthUint32,=0D + PciCfgWidthMax=0D +} PCI_CFG_WIDTH;=0D +=0D +/**=0D + Assert the validity of a PCI Segment address.=0D + A valid PCI Segment address should not contain 1's in bits 28..31 and 48= ..63=0D +=0D + @param[in] A The address to validate.=0D + @param[in] M Additional bits to assert to be zero.=0D +=0D +**/=0D +#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \=0D +ASSERT (((A) & (0xffff0000f0000000ULL | (M))) =3D=3D 0)=0D +=0D +=0D +#define EXTRACT_PCIE_ADDRESS(Address, Bus, Device, Function) \=0D +{ \=0D + (Bus) =3D (((Address) >> 20) & 0xff); \=0D + (Device) =3D (((Address) >> 15) & 0x1f); \=0D + (Function) =3D (((Address) >> 12) & 0x07); \=0D +}=0D +=0D +=0D +/**=0D + This function geted the config base of PCI device.=0D + @param[in] Address The address that encodes the PCI Bus, Device, Funct= ion and=0D + Register.=0D +=0D + @return The value of the config base of PCI device.=0D +=0D +**/=0D +STATIC=0D +UINT64=0D +PciSegmentLibGetConfigBase (=0D + IN UINT64 Address=0D + )=0D +{=0D + UINT8 Bus;=0D + UINT8 Device;=0D + UINT8 Function;=0D + UINT8 RootPortCount;=0D + UINT8 Peu0RootPortCount;=0D + UINT8 Peu1RootPortCount;=0D + UINT32 BifMode;=0D + UINT32 Peu0BifMode;=0D + UINT32 Peu1BifMode;=0D +=0D + EXTRACT_PCIE_ADDRESS (Address, Bus, Device, Function);=0D + BifMode =3D MmioRead32 (PCIE_BIF_MODE);=0D + Peu0BifMode =3D BifMode & 0x3;=0D + Peu1BifMode =3D (BifMode >> 2) & 0x3;=0D +=0D + if ((Peu0BifMode =3D=3D 1)) {=0D + Peu0RootPortCount =3D 3;=0D + } else {=0D + Peu0RootPortCount =3D 2;=0D + }=0D +=0D + if ((Peu1BifMode =3D=3D 1)) {=0D + Peu1RootPortCount =3D 3;=0D + } else {=0D + Peu1RootPortCount =3D 2;=0D + }=0D + RootPortCount =3D Peu0RootPortCount + Peu1RootPortCount;=0D + //ignore device > 0 or function > 0 on root port=0D + if (RootPortCount =3D=3D 4) {=0D + if ((Bus =3D=3D 1) || (Bus =3D=3D 2) || (Bus =3D=3D 3) || (Bus =3D=3D = 4)) {=0D + if (Device !=3D 0 || Function !=3D 0) {=0D + return 0xFFFFFFFF;=0D + }=0D + return PCI_SEG_CONFIG_BASE;=0D + }=0D + } else if (RootPortCount =3D=3D 5) {=0D + if ((Bus =3D=3D 1) || (Bus =3D=3D 2) || (Bus =3D=3D 3) || (Bus =3D=3D = 4) || (Bus =3D=3D 5)) {=0D + if (Device !=3D 0 || Function !=3D 0) {=0D + return 0xFFFFFFFF;=0D + }=0D + return PCI_SEG_CONFIG_BASE;=0D + }=0D + } else if (RootPortCount =3D=3D 6) {=0D + if ((Bus =3D=3D 1) || (Bus =3D=3D 2) || (Bus =3D=3D 3) || (Bus =3D=3D = 4) || (Bus =3D=3D 5) || (Bus =3D=3D 6)) {=0D + if (Device !=3D 0 || Function !=3D 0) {=0D + return 0xFFFFFFFF;=0D + }=0D + return PCI_SEG_CONFIG_BASE;=0D + }=0D + }=0D +=0D + return PCI_SEG_CONFIG_BASE;=0D +}=0D +=0D +/**=0D + Internal worker function to read a PCI configuration register.=0D +=0D + @param[in] Address The address that encodes the PCI Bus, Device, Functi= on and=0D + Register.=0D + @param[in] Width The width of data to read=0D +=0D + @return The value read from the PCI configuration register.=0D +=0D +**/=0D +STATIC=0D +UINT32=0D +PciSegmentLibReadWorker (=0D + IN UINT64 Address,=0D + IN PCI_CFG_WIDTH Width=0D + )=0D +{=0D + UINT64 Base;=0D +=0D + Base =3D PciSegmentLibGetConfigBase (Address);=0D + if (Base =3D=3D 0xFFFFFFFF) {=0D + return 0xFFFFFFFF;=0D + }=0D +=0D + switch (Width) {=0D + case PciCfgWidthUint8:=0D + return MmioRead8 (Base + (UINT32)Address);=0D + case PciCfgWidthUint16:=0D + return MmioRead16 (Base + (UINT32)Address);=0D + case PciCfgWidthUint32:=0D + return MmioRead32 (Base + (UINT32)Address);=0D + default:=0D + ASSERT (FALSE);=0D + }=0D +=0D + return 0;=0D +}=0D +=0D +=0D +/**=0D + Internal worker function to writes a PCI configuration register.=0D +=0D + @param[in] Address The address that encodes the PCI Bus, Device, Functi= on and=0D + Register.=0D + @param[in] Width The width of data to write=0D + @param[in] Data The value to write.=0D +=0D + @return The value written to the PCI configuration register.=0D +=0D +**/=0D +STATIC=0D +UINT32=0D +PciSegmentLibWriteWorker (=0D + IN UINT64 Address,=0D + IN PCI_CFG_WIDTH Width,=0D + IN UINT32 Data=0D + )=0D +{=0D + UINT64 Base;=0D +=0D + Base =3D PciSegmentLibGetConfigBase (Address);=0D + if (Base =3D=3D 0xFFFFFFFF) {=0D + return 0xFFFFFFFF;=0D + }=0D +=0D + switch (Width) {=0D + case PciCfgWidthUint8:=0D + MmioWrite8 (Base + (UINT32)Address, Data);=0D + break;=0D + case PciCfgWidthUint16:=0D + MmioWrite16 (Base + (UINT32)Address, Data);=0D + break;=0D + case PciCfgWidthUint32:=0D + MmioWrite32 (Base + (UINT32)Address, Data);=0D + break;=0D + default:=0D + ASSERT (FALSE);=0D + }=0D +=0D + return Data;=0D +}=0D +=0D +/**=0D + Register a PCI device so PCI configuration registers may be accessed aft= er=0D + SetVirtualAddressMap().=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Bus, D= evice, Function and=0D + Register.=0D +=0D + @retval RETURN_SUCCESS The PCI device was registered for runti= me access.=0D + @retval RETURN_UNSUPPORTED An attempt was made to call this functi= on=0D + after ExitBootServices().=0D + @retval RETURN_UNSUPPORTED The resources required to access the PC= I device=0D + at runtime could not be mapped.=0D + @retval RETURN_OUT_OF_RESOURCES There are not enough resources availabl= e to=0D + complete the registration.=0D +=0D +**/=0D +RETURN_STATUS=0D +EFIAPI=0D +PciSegmentRegisterForRuntimeAccess (=0D + IN UINTN Address=0D + )=0D +{=0D + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);=0D +=0D + return RETURN_UNSUPPORTED;=0D +}=0D +=0D +/**=0D + Reads an 8-bit PCI configuration register.=0D +=0D + Reads and returns the 8-bit PCI configuration register specified by Addr= ess.=0D + This function must guarantee that all PCI read and write operations are = serialized.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, Dev= ice, Function,=0D + and Register.=0D +=0D + @return The 8-bit PCI configuration register specified by Address.=0D +=0D +**/=0D +UINT8=0D +EFIAPI=0D +PciSegmentRead8 (=0D + IN UINT64 Address=0D + )=0D +{=0D + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);=0D +=0D + return (UINT8) PciSegmentLibReadWorker (Address, PciCfgWidthUint8);=0D +}=0D +=0D +/**=0D + Writes an 8-bit PCI configuration register.=0D +=0D + Writes the 8-bit PCI configuration register specified by Address with th= e value specified by Value.=0D + Value is returned. This function must guarantee that all PCI read and w= rite operations are serialized.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, D= evice, Function, and Register.=0D + @param[in] Value The value to write.=0D +=0D + @return The value written to the PCI configuration register.=0D +=0D +**/=0D +UINT8=0D +EFIAPI=0D +PciSegmentWrite8 (=0D + IN UINT64 Address,=0D + IN UINT8 Value=0D + )=0D +{=0D + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);=0D +=0D + return (UINT8) PciSegmentLibWriteWorker (Address, PciCfgWidthUint8, Valu= e);=0D +}=0D +=0D +/**=0D + Performs a bitwise OR of an 8-bit PCI configuration register with an 8-b= it value.=0D +=0D + Reads the 8-bit PCI configuration register specified by Address,=0D + performs a bitwise OR between the read result and the value specified by= OrData,=0D + and writes the result to the 8-bit PCI configuration register specified = by Address.=0D + The value written to the PCI configuration register is returned.=0D + This function must guarantee that all PCI read and write operations are = serialized.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, Dev= ice, Function, and Register.=0D + @param[in] OrData The value to OR with the PCI configuration registe= r.=0D +=0D + @return The value written to the PCI configuration register.=0D +=0D +**/=0D +UINT8=0D +EFIAPI=0D +PciSegmentOr8 (=0D + IN UINT64 Address,=0D + IN UINT8 OrData=0D + )=0D +{=0D + return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) | O= rData));=0D +}=0D +=0D +/**=0D + Performs a bitwise AND of an 8-bit PCI configuration register with an 8-= bit value.=0D +=0D + Reads the 8-bit PCI configuration register specified by Address,=0D + performs a bitwise AND between the read result and the value specified b= y AndData,=0D + and writes the result to the 8-bit PCI configuration register specified = by Address.=0D + The value written to the PCI configuration register is returned.=0D + This function must guarantee that all PCI read and write operations are = serialized.=0D + If any reserved bits in Address are set, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, Dev= ice, Function, and Register.=0D + @param[in] AndData The value to AND with the PCI configuration regist= er.=0D +=0D + @return The value written to the PCI configuration register.=0D +=0D +**/=0D +UINT8=0D +EFIAPI=0D +PciSegmentAnd8 (=0D + IN UINT64 Address,=0D + IN UINT8 AndData=0D + )=0D +{=0D + return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) & A= ndData));=0D +}=0D +=0D +/**=0D + Performs a bitwise AND of an 8-bit PCI configuration register with an 8-= bit value,=0D + followed a bitwise OR with another 8-bit value.=0D +=0D + Reads the 8-bit PCI configuration register specified by Address,=0D + performs a bitwise AND between the read result and the value specified b= y AndData,=0D + performs a bitwise OR between the result of the AND operation and the va= lue specified by OrData,=0D + and writes the result to the 8-bit PCI configuration register specified = by Address.=0D + The value written to the PCI configuration register is returned.=0D + This function must guarantee that all PCI read and write operations are = serialized.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, Dev= ice, Function, and Register.=0D + @param[in] AndData The value to AND with the PCI configuration regis= ter.=0D + @param[in] OrData The value to OR with the PCI configuration registe= r.=0D +=0D + @return The value written to the PCI configuration register.=0D +=0D +**/=0D +UINT8=0D +EFIAPI=0D +PciSegmentAndThenOr8 (=0D + IN UINT64 Address,=0D + IN UINT8 AndData,=0D + IN UINT8 OrData=0D + )=0D +{=0D + return PciSegmentWrite8 (Address, (UINT8) ((PciSegmentRead8 (Address) & = AndData) | OrData));=0D +}=0D +=0D +/**=0D + Reads a bit field of a PCI configuration register.=0D +=0D + Reads the bit field in an 8-bit PCI configuration register. The bit fiel= d is=0D + specified by the StartBit and the EndBit. The value of the bit field is= =0D + returned.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If StartBit is greater than 7, then ASSERT().=0D + If EndBit is greater than 7, then ASSERT().=0D + If EndBit is less than StartBit, then ASSERT().=0D +=0D + @param[in] Address The PCI configuration register to read.=0D + @param[in] StartBit The ordinal of the least significant bit in the bi= t field.=0D + Range 0..7.=0D + @param[in] EndBit The ordinal of the most significant bit in the bit= field.=0D + Range 0..7.=0D +=0D + @return The value of the bit field read from the PCI configuration regis= ter.=0D +=0D +**/=0D +UINT8=0D +EFIAPI=0D +PciSegmentBitFieldRead8 (=0D + IN UINT64 Address,=0D + IN UINTN StartBit,=0D + IN UINTN EndBit=0D + )=0D +{=0D + return BitFieldRead8 (PciSegmentRead8 (Address), StartBit, EndBit);=0D +}=0D +=0D +/**=0D + Writes a bit field to a PCI configuration register.=0D +=0D + Writes Value to the bit field of the PCI configuration register. The bit= =0D + field is specified by the StartBit and the EndBit. All other bits in the= =0D + destination PCI configuration register are preserved. The new value of t= he=0D + 8-bit register is returned.=0D +=0D + @param[in] Address The PCI configuration register to write.=0D + @param[in] StartBit The ordinal of the least significant bit in the bi= t field.=0D + Range 0..7.=0D + @param[in] EndBit The ordinal of the most significant bit in the bit= field.=0D + Range 0..7.=0D + @param[in] Value The new value of the bit field.=0D +=0D + @return The value written back to the PCI configuration register.=0D +=0D +**/=0D +UINT8=0D +EFIAPI=0D +PciSegmentBitFieldWrite8 (=0D + IN UINT64 Address,=0D + IN UINTN StartBit,=0D + IN UINTN EndBit,=0D + IN UINT8 Value=0D + )=0D +{=0D + return PciSegmentWrite8 (=0D + Address,=0D + BitFieldWrite8 (PciSegmentRead8 (Address), StartBit, EndBit, Va= lue)=0D + );=0D +}=0D +=0D +/**=0D + Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, = and=0D + writes the result back to the bit field in the 8-bit port.=0D +=0D + Reads the 8-bit PCI configuration register specified by Address, perform= s a=0D + bitwise OR between the read result and the value specified by=0D + OrData, and writes the result to the 8-bit PCI configuration register=0D + specified by Address. The value written to the PCI configuration registe= r is=0D + returned. This function must guarantee that all PCI read and write opera= tions=0D + are serialized. Extra left bits in OrData are stripped.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If StartBit is greater than 7, then ASSERT().=0D + If EndBit is greater than 7, then ASSERT().=0D + If EndBit is less than StartBit, then ASSERT().=0D + If OrData is larger than the bitmask value range specified by StartBit a= nd EndBit, then ASSERT().=0D +=0D + @param[in] Address The PCI configuration register to write.=0D + @param[in] StartBit The ordinal of the least significant bit in the bi= t field.=0D + Range 0..7.=0D + @param[in] EndBit The ordinal of the most significant bit in the bit= field.=0D + Range 0..7.=0D + @param[in] OrData The value to OR with the PCI configuration registe= r.=0D +=0D + @return The value written back to the PCI configuration register.=0D +=0D +**/=0D +UINT8=0D +EFIAPI=0D +PciSegmentBitFieldOr8 (=0D + IN UINT64 Address,=0D + IN UINTN StartBit,=0D + IN UINTN EndBit,=0D + IN UINT8 OrData=0D + )=0D +{=0D + return PciSegmentWrite8 (=0D + Address,=0D + BitFieldOr8 (PciSegmentRead8 (Address), StartBit, EndBit, OrDat= a)=0D + );=0D +}=0D +=0D +/**=0D + Reads a bit field in an 8-bit PCI configuration register, performs a bit= wise=0D + AND, and writes the result back to the bit field in the 8-bit register.= =0D +=0D + Reads the 8-bit PCI configuration register specified by Address, perform= s a=0D + bitwise AND between the read result and the value specified by AndData, = and=0D + writes the result to the 8-bit PCI configuration register specified by=0D + Address. The value written to the PCI configuration register is returned= .=0D + This function must guarantee that all PCI read and write operations are= =0D + serialized. Extra left bits in AndData are stripped.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If StartBit is greater than 7, then ASSERT().=0D + If EndBit is greater than 7, then ASSERT().=0D + If EndBit is less than StartBit, then ASSERT().=0D + If AndData is larger than the bitmask value range specified by StartBit = and EndBit, then ASSERT().=0D +=0D + @param[in] Address The PCI configuration register to write.=0D + @param[in] StartBit The ordinal of the least significant bit in the bi= t field.=0D + Range 0..7.=0D + @param[in] EndBit The ordinal of the most significant bit in the bit= field.=0D + Range 0..7.=0D + @param[in] AndData The value to AND with the PCI configuration regist= er.=0D +=0D + @return The value written back to the PCI configuration register.=0D +=0D +**/=0D +UINT8=0D +EFIAPI=0D +PciSegmentBitFieldAnd8 (=0D + IN UINT64 Address,=0D + IN UINTN StartBit,=0D + IN UINTN EndBit,=0D + IN UINT8 AndData=0D + )=0D +{=0D + return PciSegmentWrite8 (=0D + Address,=0D + BitFieldAnd8 (PciSegmentRead8 (Address), StartBit, EndBit, AndD= ata)=0D + );=0D +}=0D +=0D +/**=0D + Reads a bit field in an 8-bit port, performs a bitwise AND followed by a= =0D + bitwise OR, and writes the result back to the bit field in the=0D + 8-bit port.=0D +=0D + Reads the 8-bit PCI configuration register specified by Address, perform= s a=0D + bitwise AND followed by a bitwise OR between the read result and=0D + the value specified by AndData, and writes the result to the 8-bit PCI=0D + configuration register specified by Address. The value written to the PC= I=0D + configuration register is returned. This function must guarantee that al= l PCI=0D + read and write operations are serialized. Extra left bits in both AndDat= a and=0D + OrData are stripped.=0D +=0D + @param[in] Address The PCI configuration register to write.=0D + @param[in] StartBit The ordinal of the least significant bit in the bi= t field.=0D + Range 0..7.=0D + @param[in] EndBit The ordinal of the most significant bit in the bit= field.=0D + Range 0..7.=0D + @param[in] AndData The value to AND with the PCI configuration regist= er.=0D + @param[in] OrData The value to OR with the result of the AND operati= on.=0D +=0D + @return The value written back to the PCI configuration register.=0D +=0D +**/=0D +UINT8=0D +EFIAPI=0D +PciSegmentBitFieldAndThenOr8 (=0D + IN UINT64 Address,=0D + IN UINTN StartBit,=0D + IN UINTN EndBit,=0D + IN UINT8 AndData,=0D + IN UINT8 OrData=0D + )=0D +{=0D + return PciSegmentWrite8 (=0D + Address,=0D + BitFieldAndThenOr8 (PciSegmentRead8 (Address), StartBit, EndBit= , AndData, OrData)=0D + );=0D +}=0D +=0D +/**=0D + Reads a 16-bit PCI configuration register.=0D +=0D + Reads and returns the 16-bit PCI configuration register specified by Add= ress.=0D + This function must guarantee that all PCI read and write operations are = serialized.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 16-bit boundary, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, Dev= ice, Function, and Register.=0D +=0D + @return The 16-bit PCI configuration register specified by Address.=0D +=0D +**/=0D +UINT16=0D +EFIAPI=0D +PciSegmentRead16 (=0D + IN UINT64 Address=0D + )=0D +{=0D + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);=0D +=0D + return (UINT16) PciSegmentLibReadWorker (Address, PciCfgWidthUint16);=0D +}=0D +=0D +/**=0D + Writes a 16-bit PCI configuration register.=0D +=0D + Writes the 16-bit PCI configuration register specified by Address with t= he value specified by Value.=0D + Value is returned. This function must guarantee that all PCI read and w= rite operations are serialized.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 16-bit boundary, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, D= evice, Function, and Register.=0D + @param[in] Value The value to write.=0D +=0D + @return The parameter of Value.=0D +=0D +**/=0D +UINT16=0D +EFIAPI=0D +PciSegmentWrite16 (=0D + IN UINT64 Address,=0D + IN UINT16 Value=0D + )=0D +{=0D + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);=0D +=0D + return (UINT16) PciSegmentLibWriteWorker (Address, PciCfgWidthUint16, Va= lue);=0D +}=0D +=0D +/**=0D + Performs a bitwise OR of a 16-bit PCI configuration register with=0D + a 16-bit value.=0D +=0D + Reads the 16-bit PCI configuration register specified by Address, perfor= ms a=0D + bitwise OR between the read result and the value specified by=0D + OrData, and writes the result to the 16-bit PCI configuration register=0D + specified by Address. The value written to the PCI configuration registe= r is=0D + returned. This function must guarantee that all PCI read and write opera= tions=0D + are serialized.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 16-bit boundary, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, Devic= e, Function and=0D + Register.=0D + @param[in] OrData The value to OR with the PCI configuration register.= =0D +=0D + @return The value written back to the PCI configuration register.=0D +=0D +**/=0D +UINT16=0D +EFIAPI=0D +PciSegmentOr16 (=0D + IN UINT64 Address,=0D + IN UINT16 OrData=0D + )=0D +{=0D + return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) = | OrData));=0D +}=0D +=0D +/**=0D + Performs a bitwise AND of a 16-bit PCI configuration register with a 16-= bit value.=0D +=0D + Reads the 16-bit PCI configuration register specified by Address,=0D + performs a bitwise AND between the read result and the value specified b= y AndData,=0D + and writes the result to the 16-bit PCI configuration register specified= by Address.=0D + The value written to the PCI configuration register is returned.=0D + This function must guarantee that all PCI read and write operations are = serialized.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 16-bit boundary, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, Dev= ice, Function, and Register.=0D + @param[in] AndData The value to AND with the PCI configuration regist= er.=0D +=0D + @return The value written to the PCI configuration register.=0D +=0D +**/=0D +UINT16=0D +EFIAPI=0D +PciSegmentAnd16 (=0D + IN UINT64 Address,=0D + IN UINT16 AndData=0D + )=0D +{=0D + return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) = & AndData));=0D +}=0D +=0D +/**=0D + Performs a bitwise AND of a 16-bit PCI configuration register with a 16-= bit value,=0D + followed a bitwise OR with another 16-bit value.=0D +=0D + Reads the 16-bit PCI configuration register specified by Address,=0D + performs a bitwise AND between the read result and the value specified b= y AndData,=0D + performs a bitwise OR between the result of the AND operation and the va= lue specified by OrData,=0D + and writes the result to the 16-bit PCI configuration register specified= by Address.=0D + The value written to the PCI configuration register is returned.=0D + This function must guarantee that all PCI read and write operations are = serialized.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 16-bit boundary, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, Dev= ice, Function, and Register.=0D + @param[in] AndData The value to AND with the PCI configuration regist= er.=0D + @param[in] OrData The value to OR with the PCI configuration registe= r.=0D +=0D + @return The value written to the PCI configuration register.=0D +=0D +**/=0D +UINT16=0D +EFIAPI=0D +PciSegmentAndThenOr16 (=0D + IN UINT64 Address,=0D + IN UINT16 AndData,=0D + IN UINT16 OrData=0D + )=0D +{=0D + return PciSegmentWrite16 (Address, (UINT16) ((PciSegmentRead16 (Address)= & AndData) | OrData));=0D +}=0D +=0D +/**=0D + Reads a bit field of a PCI configuration register.=0D +=0D + Reads the bit field in a 16-bit PCI configuration register. The bit fiel= d is=0D + specified by the StartBit and the EndBit. The value of the bit field is= =0D + returned.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 16-bit boundary, then ASSERT().=0D + If StartBit is greater than 15, then ASSERT().=0D + If EndBit is greater than 15, then ASSERT().=0D + If EndBit is less than StartBit, then ASSERT().=0D +=0D + @param[in] Address The PCI configuration register to read.=0D + @param[in] StartBit The ordinal of the least significant bit in the bi= t field.=0D + Range 0..15.=0D + @param[in] EndBit The ordinal of the most significant bit in the bit= field.=0D + Range 0..15.=0D +=0D + @return The value of the bit field read from the PCI configuration regis= ter.=0D +=0D +**/=0D +UINT16=0D +EFIAPI=0D +PciSegmentBitFieldRead16 (=0D + IN UINT64 Address,=0D + IN UINTN StartBit,=0D + IN UINTN EndBit=0D + )=0D +{=0D + return BitFieldRead16 (PciSegmentRead16 (Address), StartBit, EndBit);=0D +}=0D +=0D +/**=0D + Writes a bit field to a PCI configuration register.=0D +=0D + Writes Value to the bit field of the PCI configuration register. The bit= =0D + field is specified by the StartBit and the EndBit. All other bits in the= =0D + destination PCI configuration register are preserved. The new value of t= he=0D + 16-bit register is returned.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 16-bit boundary, then ASSERT().=0D + If StartBit is greater than 15, then ASSERT().=0D + If EndBit is greater than 15, then ASSERT().=0D + If EndBit is less than StartBit, then ASSERT().=0D + If Value is larger than the bitmask value range specified by StartBit an= d EndBit, then ASSERT().=0D +=0D + @param[in] Address The PCI configuration register to write.=0D + @param[in] StartBit The ordinal of the least significant bit in the bi= t field.=0D + Range 0..15.=0D + @param[in] EndBit The ordinal of the most significant bit in the bit= field.=0D + Range 0..15.=0D + @param[in] Value The new value of the bit field.=0D +=0D + @return The value written back to the PCI configuration register.=0D +=0D +**/=0D +UINT16=0D +EFIAPI=0D +PciSegmentBitFieldWrite16 (=0D + IN UINT64 Address,=0D + IN UINTN StartBit,=0D + IN UINTN EndBit,=0D + IN UINT16 Value=0D + )=0D +{=0D + return PciSegmentWrite16 (=0D + Address,=0D + BitFieldWrite16 (PciSegmentRead16 (Address), StartBit, EndBit, = Value)=0D + );=0D +}=0D +=0D +/**=0D + Reads the 16-bit PCI configuration register specified by Address,=0D + performs a bitwise OR between the read result and the value specified by= OrData,=0D + and writes the result to the 16-bit PCI configuration register specified= by Address.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 16-bit boundary, then ASSERT().=0D + If StartBit is greater than 15, then ASSERT().=0D + If EndBit is greater than 15, then ASSERT().=0D + If EndBit is less than StartBit, then ASSERT().=0D + If OrData is larger than the bitmask value range specified by StartBit a= nd EndBit, then ASSERT().=0D +=0D + @param[in] Address The PCI configuration register to write.=0D + @param[in] StartBit The ordinal of the least significant bit in the bi= t field.=0D + Range 0..15.=0D + @param[in] EndBit The ordinal of the most significant bit in the bit= field.=0D + Range 0..15.=0D + @param[in] OrData The value to OR with the PCI configuration registe= r.=0D +=0D + @return The value written back to the PCI configuration register.=0D +=0D +**/=0D +UINT16=0D +EFIAPI=0D +PciSegmentBitFieldOr16 (=0D + IN UINT64 Address,=0D + IN UINTN StartBit,=0D + IN UINTN EndBit,=0D + IN UINT16 OrData=0D + )=0D +{=0D + return PciSegmentWrite16 (=0D + Address,=0D + BitFieldOr16 (PciSegmentRead16 (Address), StartBit, EndBit, OrD= ata)=0D + );=0D +}=0D +=0D +/**=0D + Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,= =0D + and writes the result back to the bit field in the 16-bit port.=0D +=0D + Reads the 16-bit PCI configuration register specified by Address,=0D + performs a bitwise OR between the read result and the value specified by= OrData,=0D + and writes the result to the 16-bit PCI configuration register specified= by Address.=0D + The value written to the PCI configuration register is returned.=0D + This function must guarantee that all PCI read and write operations are = serialized.=0D + Extra left bits in OrData are stripped.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 16-bit boundary, then ASSERT().=0D + If StartBit is greater than 7, then ASSERT().=0D + If EndBit is greater than 7, then ASSERT().=0D + If EndBit is less than StartBit, then ASSERT().=0D + If AndData is larger than the bitmask value range specified by StartBit = and EndBit, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, Dev= ice, Function, and Register.=0D + @param[in] StartBit The ordinal of the least significant bit in the bi= t field.=0D + The ordinal of the least significant bit in a byte is = bit 0.=0D + @param[in] EndBit The ordinal of the most significant bit in the bit= field.=0D + The ordinal of the most significant bit in a byte is b= it 7.=0D + @param[in] AndData The value to AND with the read value from the PCI = configuration register.=0D +=0D + @return The value written to the PCI configuration register.=0D +=0D +**/=0D +UINT16=0D +EFIAPI=0D +PciSegmentBitFieldAnd16 (=0D + IN UINT64 Address,=0D + IN UINTN StartBit,=0D + IN UINTN EndBit,=0D + IN UINT16 AndData=0D + )=0D +{=0D + return PciSegmentWrite16 (=0D + Address,=0D + BitFieldAnd16 (PciSegmentRead16 (Address), StartBit, EndBit, An= dData)=0D + );=0D +}=0D +=0D +/**=0D + Reads a bit field in a 16-bit port, performs a bitwise AND followed by a= =0D + bitwise OR, and writes the result back to the bit field in the=0D + 16-bit port.=0D +=0D + Reads the 16-bit PCI configuration register specified by Address, perfor= ms a=0D + bitwise AND followed by a bitwise OR between the read result and=0D + the value specified by AndData, and writes the result to the 16-bit PCI= =0D + configuration register specified by Address. The value written to the PC= I=0D + configuration register is returned. This function must guarantee that al= l PCI=0D + read and write operations are serialized. Extra left bits in both AndDat= a and=0D + OrData are stripped.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If StartBit is greater than 15, then ASSERT().=0D + If EndBit is greater than 15, then ASSERT().=0D + If EndBit is less than StartBit, then ASSERT().=0D + If AndData is larger than the bitmask value range specified by StartBit = and EndBit, then ASSERT().=0D + If OrData is larger than the bitmask value range specified by StartBit a= nd EndBit, then ASSERT().=0D +=0D + @param[in] Address The PCI configuration register to write.=0D + @param[in] StartBit The ordinal of the least significant bit in the bi= t field.=0D + Range 0..15.=0D + @param[in] EndBit The ordinal of the most significant bit in the bit= field.=0D + Range 0..15.=0D + @param[in] AndData The value to AND with the PCI configuration regist= er.=0D + @param[in] OrData The value to OR with the result of the AND operati= on.=0D +=0D + @return The value written back to the PCI configuration register.=0D +=0D +**/=0D +UINT16=0D +EFIAPI=0D +PciSegmentBitFieldAndThenOr16 (=0D + IN UINT64 Address,=0D + IN UINTN StartBit,=0D + IN UINTN EndBit,=0D + IN UINT16 AndData,=0D + IN UINT16 OrData=0D + )=0D +{=0D + return PciSegmentWrite16 (=0D + Address,=0D + BitFieldAndThenOr16 (PciSegmentRead16 (Address), StartBit, EndB= it, AndData, OrData)=0D + );=0D +}=0D +=0D +/**=0D + Reads a 32-bit PCI configuration register.=0D +=0D + Reads and returns the 32-bit PCI configuration register specified by Add= ress.=0D + This function must guarantee that all PCI read and write operations are = serialized.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 32-bit boundary, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, Dev= ice, Function,=0D + and Register.=0D +=0D + @return The 32-bit PCI configuration register specified by Address.=0D +=0D +**/=0D +UINT32=0D +EFIAPI=0D +PciSegmentRead32 (=0D + IN UINT64 Address=0D + )=0D +{=0D + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);=0D +=0D + return PciSegmentLibReadWorker (Address, PciCfgWidthUint32);=0D +}=0D +=0D +/**=0D + Writes a 32-bit PCI configuration register.=0D +=0D + Writes the 32-bit PCI configuration register specified by Address with t= he value specified by Value.=0D + Value is returned. This function must guarantee that all PCI read and w= rite operations are serialized.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 32-bit boundary, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, D= evice,=0D + Function, and Register.=0D + @param[in] Value The value to write.=0D +=0D + @return The parameter of Value.=0D +=0D +**/=0D +UINT32=0D +EFIAPI=0D +PciSegmentWrite32 (=0D + IN UINT64 Address,=0D + IN UINT32 Value=0D + )=0D +{=0D + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);=0D +=0D + return PciSegmentLibWriteWorker (Address, PciCfgWidthUint32, Value);=0D +}=0D +=0D +/**=0D + Performs a bitwise OR of a 32-bit PCI configuration register with a 32-b= it value.=0D +=0D + Reads the 32-bit PCI configuration register specified by Address,=0D + performs a bitwise OR between the read result and the value specified by= OrData,=0D + and writes the result to the 32-bit PCI configuration register specified= by Address.=0D + The value written to the PCI configuration register is returned.=0D + This function must guarantee that all PCI read and write operations are = serialized.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 32-bit boundary, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, Dev= ice, Function, and Register.=0D + @param[in] OrData The value to OR with the PCI configuration registe= r.=0D +=0D + @return The value written to the PCI configuration register.=0D +=0D +**/=0D +UINT32=0D +EFIAPI=0D +PciSegmentOr32 (=0D + IN UINT64 Address,=0D + IN UINT32 OrData=0D + )=0D +{=0D + return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) | OrData);= =0D +}=0D +=0D +/**=0D + Performs a bitwise AND of a 32-bit PCI configuration register with a 32-= bit value.=0D +=0D + Reads the 32-bit PCI configuration register specified by Address,=0D + performs a bitwise AND between the read result and the value specified b= y AndData,=0D + and writes the result to the 32-bit PCI configuration register specified= by Address.=0D + The value written to the PCI configuration register is returned.=0D + This function must guarantee that all PCI read and write operations are = serialized.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 32-bit boundary, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, Dev= ice, Function,=0D + and Register.=0D + @param[in] AndData The value to AND with the PCI configuration regist= er.=0D +=0D + @return The value written to the PCI configuration register.=0D +=0D +**/=0D +UINT32=0D +EFIAPI=0D +PciSegmentAnd32 (=0D + IN UINT64 Address,=0D + IN UINT32 AndData=0D + )=0D +{=0D + return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) & AndData)= ;=0D +}=0D +=0D +/**=0D + Performs a bitwise AND of a 32-bit PCI configuration register with a 32-= bit value,=0D + followed a bitwise OR with another 32-bit value.=0D +=0D + Reads the 32-bit PCI configuration register specified by Address,=0D + performs a bitwise AND between the read result and the value specified b= y AndData,=0D + performs a bitwise OR between the result of the AND operation and the va= lue specified by OrData,=0D + and writes the result to the 32-bit PCI configuration register specified= by Address.=0D + The value written to the PCI configuration register is returned.=0D + This function must guarantee that all PCI read and write operations are = serialized.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 32-bit boundary, then ASSERT().=0D +=0D + @param[in] Address The address that encodes the PCI Segment, Bus, Dev= ice, Function,=0D + and Register.=0D + @param[in] AndData The value to AND with the PCI configuration regist= er.=0D + @param[in] OrData The value to OR with the PCI configuration registe= r.=0D +=0D + @return The value written to the PCI configuration register.=0D +=0D +**/=0D +UINT32=0D +EFIAPI=0D +PciSegmentAndThenOr32 (=0D + IN UINT64 Address,=0D + IN UINT32 AndData,=0D + IN UINT32 OrData=0D + )=0D +{=0D + return PciSegmentWrite32 (Address, (PciSegmentRead32 (Address) & AndData= ) | OrData);=0D +}=0D +=0D +/**=0D + Reads a bit field of a PCI configuration register.=0D +=0D + Reads the bit field in a 32-bit PCI configuration register. The bit fiel= d is=0D + specified by the StartBit and the EndBit. The value of the bit field is = returned.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 32-bit boundary, then ASSERT().=0D + If StartBit is greater than 31, then ASSERT().=0D + If EndBit is greater than 31, then ASSERT().=0D + If EndBit is less than StartBit, then ASSERT().=0D +=0D + @param[in] Address The PCI configuration register to read.=0D + @param[in] StartBit The ordinal of the least significant bit in the bi= t field.=0D + Range 0..31.=0D + @param[in] EndBit The ordinal of the most significant bit in the bit= field.=0D + Range 0..31.=0D +=0D + @return The value of the bit field read from the PCI configuration regis= ter.=0D +=0D +**/=0D +UINT32=0D +EFIAPI=0D +PciSegmentBitFieldRead32 (=0D + IN UINT64 Address,=0D + IN UINTN StartBit,=0D + IN UINTN EndBit=0D + )=0D +{=0D + return BitFieldRead32 (PciSegmentRead32 (Address), StartBit, EndBit);=0D +}=0D +=0D +/**=0D + Writes a bit field to a PCI configuration register.=0D +=0D + Writes Value to the bit field of the PCI configuration register. The bit= =0D + field is specified by the StartBit and the EndBit. All other bits in the= =0D + destination PCI configuration register are preserved. The new value of t= he=0D + 32-bit register is returned.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 32-bit boundary, then ASSERT().=0D + If StartBit is greater than 31, then ASSERT().=0D + If EndBit is greater than 31, then ASSERT().=0D + If EndBit is less than StartBit, then ASSERT().=0D + If Value is larger than the bitmask value range specified by StartBit an= d EndBit, then ASSERT().=0D +=0D + @param[in] Address The PCI configuration register to write.=0D + @param[in] StartBit The ordinal of the least significant bit in the bi= t field.=0D + Range 0..31.=0D + @param[in] EndBit The ordinal of the most significant bit in the bit= field.=0D + Range 0..31.=0D + @param[in] Value The new value of the bit field.=0D +=0D + @return The value written back to the PCI configuration register.=0D +=0D +**/=0D +UINT32=0D +EFIAPI=0D +PciSegmentBitFieldWrite32 (=0D + IN UINT64 Address,=0D + IN UINTN StartBit,=0D + IN UINTN EndBit,=0D + IN UINT32 Value=0D + )=0D +{=0D + return PciSegmentWrite32 (=0D + Address,=0D + BitFieldWrite32 (PciSegmentRead32 (Address), StartBit, EndBit, = Value)=0D + );=0D +}=0D +=0D +/**=0D + Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, = and=0D + writes the result back to the bit field in the 32-bit port.=0D +=0D + Reads the 32-bit PCI configuration register specified by Address, perfor= ms a=0D + bitwise OR between the read result and the value specified by=0D + OrData, and writes the result to the 32-bit PCI configuration register=0D + specified by Address. The value written to the PCI configuration registe= r is=0D + returned. This function must guarantee that all PCI read and write opera= tions=0D + are serialized. Extra left bits in OrData are stripped.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If StartBit is greater than 31, then ASSERT().=0D + If EndBit is greater than 31, then ASSERT().=0D + If EndBit is less than StartBit, then ASSERT().=0D + If OrData is larger than the bitmask value range specified by StartBit a= nd EndBit, then ASSERT().=0D +=0D + @param[in] Address The PCI configuration register to write.=0D + @param[in] StartBit The ordinal of the least significant bit in the bi= t field.=0D + Range 0..31.=0D + @param[in] EndBit The ordinal of the most significant bit in the bit= field.=0D + Range 0..31.=0D + @param[in] OrData The value to OR with the PCI configuration registe= r.=0D +=0D + @return The value written back to the PCI configuration register.=0D +=0D +**/=0D +UINT32=0D +EFIAPI=0D +PciSegmentBitFieldOr32 (=0D + IN UINT64 Address,=0D + IN UINTN StartBit,=0D + IN UINTN EndBit,=0D + IN UINT32 OrData=0D + )=0D +{=0D + return PciSegmentWrite32 (=0D + Address,=0D + BitFieldOr32 (PciSegmentRead32 (Address), StartBit, EndBit, OrD= ata)=0D + );=0D +}=0D +=0D +/**=0D + Reads a bit field in a 32-bit PCI configuration register, performs a bit= wise=0D + AND, and writes the result back to the bit field in the 32-bit register.= =0D +=0D +=0D + Reads the 32-bit PCI configuration register specified by Address, perfor= ms a bitwise=0D + AND between the read result and the value specified by AndData, and writ= es the result=0D + to the 32-bit PCI configuration register specified by Address. The value= written to=0D + the PCI configuration register is returned. This function must guarante= e that all PCI=0D + read and write operations are serialized. Extra left bits in AndData ar= e stripped.=0D + If any reserved bits in Address are set, then ASSERT().=0D + If Address is not aligned on a 32-bit boundary, then ASSERT().=0D + If StartBit is greater than 31, then ASSERT().=0D + If EndBit is greater than 31, then ASSERT().=0D + If EndBit is less than StartBit, then ASSERT().=0D + If AndData is larger than the bitmask value range specified by StartBit = and EndBit, then ASSERT().=0D +=0D + @param[in] Address The PCI configuration register to write.=0D + @param[in] StartBit The ordinal of the least significant bit in the bi= t field.=0D + Range 0..31.=0D + @param[in] EndBit The ordinal of the most significant bit in the bit= field.=0D + Range 0..31.=0D + @param[in] AndData The value to AND with the PCI configuration regist= er.=0D +=0D + @return The value written back to the PCI configuration register.=0D +=0D +**/=0D +UINT32=0D +EFIAPI=0D +PciSegmentBitFieldAnd32 (=0D + IN UINT64 Address,=0D + IN UINTN StartBit,=0D + IN UINTN EndBit,=0D + IN UINT32 AndData=0D + )=0D +{=0D + return PciSegmentWrite32 (=0D + Address,=0D + BitFieldAnd32 (PciSegmentRead32 (Address), StartBit, EndBit, An= dData)=0D + );=0D +}=0D +=0D +/**=0D + Reads a bit field in a 32-bit port, performs a bitwise AND followed by a= =0D + bitwise OR, and writes the result back to the bit field in the=0D + 32-bit port.=0D +=0D + Reads the 32-bit PCI configuration register specified by Address, perfor= ms a=0D + bitwise AND followed by a bitwise OR between the read result and=0D + the value specified by AndData, and writes the result to the 32-bit PCI= =0D + configuration register specified by Address. The value written to the PC= I=0D + configuration register is returned. This function must guarantee that al= l PCI=0D + read and write operations are serialized. Extra left bits in both AndDat= a and=0D + OrData are stripped.=0D +=0D + If any reserved bits in Address are set, then ASSERT().=0D + If StartBit is greater than 31, then ASSERT().=0D + If EndBit is greater than 31, then ASSERT().=0D + If EndBit is less than StartBit, then ASSERT().=0D + If AndData is larger than the bitmask value range specified by StartBit = and EndBit, then ASSERT().=0D + If OrData is larger than the bitmask value range specified by StartBit a= nd EndBit, then ASSERT().=0D +=0D + @param[in] Address The PCI configuration register to write.=0D + @param[in] StartBit The ordinal of the least significant bit in the bi= t field.=0D + Range 0..31.=0D + @param[in] EndBit The ordinal of the most significant bit in the bit= field.=0D + Range 0..31.=0D + @param[in] AndData The value to AND with the PCI configuration regist= er.=0D + @param[in] OrData The value to OR with the result of the AND operati= on.=0D +=0D + @return The value written back to the PCI configuration register.=0D +=0D +**/=0D +UINT32=0D +EFIAPI=0D +PciSegmentBitFieldAndThenOr32 (=0D + IN UINT64 Address,=0D + IN UINTN StartBit,=0D + IN UINTN EndBit,=0D + IN UINT32 AndData,=0D + IN UINT32 OrData=0D + )=0D +{=0D + return PciSegmentWrite32 (=0D + Address,=0D + BitFieldAndThenOr32 (PciSegmentRead32 (Address), StartBit, EndB= it, AndData, OrData)=0D + );=0D +}=0D +=0D +/**=0D + Reads a range of PCI configuration registers into a caller supplied buff= er.=0D +=0D + Reads the range of PCI configuration registers specified by StartAddress= and=0D + Size into the buffer specified by Buffer. This function only allows the = PCI=0D + configuration registers from a single PCI function to be read. Size is=0D + returned. When possible 32-bit PCI configuration read cycles are used to= read=0D + from StartAdress to StartAddress + Size. Due to alignment restrictions, = 8-bit=0D + and 16-bit PCI configuration read cycles may be used at the beginning an= d the=0D + end of the range.=0D +=0D + If any reserved bits in StartAddress are set, then ASSERT().=0D + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().=0D + If Size > 0 and Buffer is NULL, then ASSERT().=0D +=0D + @param[in] StartAddress The starting address that encodes the PCI Segm= ent, Bus,=0D + Device, Function and Register.=0D + @param[in] Size The size in bytes of the transfer.=0D + @param[in] Buffer The pointer to a buffer receiving the data rea= d.=0D +=0D + @return Size=0D +=0D +**/=0D +UINTN=0D +EFIAPI=0D +PciSegmentReadBuffer (=0D + IN UINT64 StartAddress,=0D + IN UINTN Size,=0D + OUT VOID *Buffer=0D + )=0D +{=0D + UINTN ReturnValue;=0D +=0D + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);=0D + ASSERT (((StartAddress & 0xFFF) + Size) <=3D 0x1000);=0D +=0D + if (Size =3D=3D 0) {=0D + return Size;=0D + }=0D +=0D + ASSERT (Buffer !=3D NULL);=0D +=0D + //=0D + // Save Size for return=0D + //=0D + ReturnValue =3D Size;=0D +=0D + if ((StartAddress & BIT0) !=3D 0) {=0D + //=0D + // Read a byte if StartAddress is byte aligned,=0D + // Volatile ensure that the latest values are read every time.=0D + //=0D + *(volatile UINT8 *)Buffer =3D PciSegmentRead8 (StartAddress);=0D + StartAddress +=3D sizeof (UINT8);=0D + Size -=3D sizeof (UINT8);=0D + Buffer =3D (UINT8 *)Buffer + 1;=0D + }=0D +=0D + if (Size >=3D sizeof (UINT16) && (StartAddress & BIT1) !=3D 0) {=0D + //=0D + // Read a word if StartAddress is word aligned=0D + //=0D + WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));=0D + StartAddress +=3D sizeof (UINT16);=0D + Size -=3D sizeof (UINT16);=0D + Buffer =3D (UINT16 *)Buffer + 1;=0D + }=0D +=0D + while (Size >=3D sizeof (UINT32)) {=0D + //=0D + // Read as many double words as possible=0D + //=0D + WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));=0D + StartAddress +=3D sizeof (UINT32);=0D + Size -=3D sizeof (UINT32);=0D + Buffer =3D (UINT32 *)Buffer + 1;=0D + }=0D +=0D + if (Size >=3D sizeof (UINT16)) {=0D + //=0D + // Read the last remaining word if exist=0D + //=0D + WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));=0D + StartAddress +=3D sizeof (UINT16);=0D + Size -=3D sizeof (UINT16);=0D + Buffer =3D (UINT16 *)Buffer + 1;=0D + }=0D +=0D + if (Size >=3D sizeof (UINT8)) {=0D + //=0D + // Read the last remaining byte if exist=0D + //=0D + *(volatile UINT8 *)Buffer =3D PciSegmentRead8 (StartAddress);=0D + }=0D +=0D + return ReturnValue;=0D +}=0D +=0D +=0D +/**=0D + Copies the data in a caller supplied buffer to a specified range of PCI= =0D + configuration space.=0D +=0D + Writes the range of PCI configuration registers specified by StartAddres= s and=0D + Size from the buffer specified by Buffer. This function only allows the = PCI=0D + configuration registers from a single PCI function to be written. Size i= s=0D + returned. When possible 32-bit PCI configuration write cycles are used t= o=0D + write from StartAdress to StartAddress + Size. Due to alignment restrict= ions,=0D + 8-bit and 16-bit PCI configuration write cycles may be used at the begin= ning=0D + and the end of the range.=0D +=0D + If any reserved bits in StartAddress are set, then ASSERT().=0D + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().=0D + If Size > 0 and Buffer is NULL, then ASSERT().=0D +=0D + @param[in] StartAddress The starting address that encodes the PCI Segm= ent, Bus,=0D + Device, Function and Register.=0D + @param[in] Size The size in bytes of the transfer.=0D + @param[in] Buffer The pointer to a buffer containing the data to= write.=0D +=0D + @return The parameter of Size.=0D +=0D +**/=0D +UINTN=0D +EFIAPI=0D +PciSegmentWriteBuffer (=0D + IN UINT64 StartAddress,=0D + IN UINTN Size,=0D + IN VOID *Buffer=0D + )=0D +{=0D + UINTN ReturnValue;=0D +=0D + ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);=0D + ASSERT (((StartAddress & 0xFFF) + Size) <=3D 0x1000);=0D +=0D + if (Size =3D=3D 0) {=0D + return 0;=0D + }=0D +=0D + ASSERT (Buffer !=3D NULL);=0D +=0D + //=0D + // Save Size for return=0D + //=0D + ReturnValue =3D Size;=0D +=0D + if ((StartAddress & BIT0) !=3D 0) {=0D + //=0D + // Write a byte if StartAddress is byte aligned=0D + //=0D + PciSegmentWrite8 (StartAddress, *(UINT8 *)Buffer);=0D + StartAddress +=3D sizeof (UINT8);=0D + Size -=3D sizeof (UINT8);=0D + Buffer =3D (UINT8 *)Buffer + 1;=0D + }=0D +=0D + if (Size >=3D sizeof (UINT16) && (StartAddress & BIT1) !=3D 0) {=0D + //=0D + // Write a word if StartAddress is word aligned=0D + //=0D + PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));=0D + StartAddress +=3D sizeof (UINT16);=0D + Size -=3D sizeof (UINT16);=0D + Buffer =3D (UINT16 *)Buffer + 1;=0D + }=0D +=0D + while (Size >=3D sizeof (UINT32)) {=0D + //=0D + // Write as many double words as possible=0D + //=0D + PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));=0D + StartAddress +=3D sizeof (UINT32);=0D + Size -=3D sizeof (UINT32);=0D + Buffer =3D (UINT32 *)Buffer + 1;=0D + }=0D +=0D + if (Size >=3D sizeof (UINT16)) {=0D + //=0D + // Write the last remaining word if exist=0D + //=0D + PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));=0D + StartAddress +=3D sizeof (UINT16);=0D + Size -=3D sizeof (UINT16);=0D + Buffer =3D (UINT16 *)Buffer + 1;=0D + }=0D +=0D + if (Size >=3D sizeof (UINT8)) {=0D + //=0D + // Write the last remaining byte if exist=0D + //=0D + PciSegmentWrite8 (StartAddress, *(UINT8 *)Buffer);=0D + }=0D +=0D + return ReturnValue;=0D +}=0D --=20 2.25.1