From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=pass header.i=@semihalf-com.20150623.gappssmtp.com header.s=20150623 header.b=sFdx+Goe; spf=none, err=SPF record not found (domain: semihalf.com, ip: 209.85.160.195, mailfrom: mw@semihalf.com) Received: from mail-qt1-f195.google.com (mail-qt1-f195.google.com [209.85.160.195]) by groups.io with SMTP; Fri, 10 May 2019 08:29:50 -0700 Received: by mail-qt1-f195.google.com with SMTP id y42so7037468qtk.6 for ; Fri, 10 May 2019 08:29:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=jl7yKlIK8N+9TF3D2tEj2xreZ9Vvq8gqtl0OnFPmnP0=; b=sFdx+GoejV+bFJmQojzFGW1InoFMjnxEji+LQe2VhU+JbhABY3S/qzO7ga7UVaXyie 6FxfrnVkF6pYbm6H4+pW7uYYwgEqxkbOhO1fu4NwM3bXyJBAd57SafN8gDSQ7k1kEDyo jw6CJB8kRf+xuAFjWLjzeFhoXxSZYMcC54wXLTUEX7796I9Wv7VmSUsc3ccIGAgQM3m0 uxonQqbvGmC32ae1lP9QZbSwC3ozEKrytCFqPm/CD83VeYYVodbqQZTg0M391bQG/EgU bxgh5aJfmPzD0TeZ/PWuQDrSiYJMYvnHUHb/AJoP6h9DsfoNsvKy05hstwC4NKoo6tQq YurQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=jl7yKlIK8N+9TF3D2tEj2xreZ9Vvq8gqtl0OnFPmnP0=; b=iBxYTLG456Y5R0/0fIQpHPV/+OrydNXO0AiG+KUqk1iFi87b0yGsKcmqY0GTQI5LdZ hLg4KLHxkbW/K1BrAD0ayLWW3DVvIpLqu6Oxl/+3v/agLvb8/C9VETVQkRrMfGmMvEVX 7mIK65zM+ur6Ls1mpFitSvjXw2oAzz13h+Iq1ODUlbDQmRyCKkZACF6AkFpw56LoS94o j3+AG3tceUEwI4X3s9019kknYlrMKnRSeLlN7pzu03rRGrSpZv3c7KFtJFFp906OoGQs 4pKFOWmGlBOktz7xEKVEYXaLKMHhHkfd5bkEOgVh+75Nw5OWYJW4s8qBkG3PtI8ChfZ6 mFFw== X-Gm-Message-State: APjAAAXz7fcTdjdmuG7k+3QTNlKEYEHQnleaQzqYQB3bZ/B37VpA01Fn +h04raFE3kFoPFGfCH0jCJe7V36JHVCRPdQDLDRmQw== X-Google-Smtp-Source: APXvYqyon25ARMiuHGjpV6ZcTJchT2mioR2SvqIWgo/liIBki7lV1vE05uuI6ukPBk1gCxPUfOZb5THaacEMgyiUnDA= X-Received: by 2002:ac8:66d6:: with SMTP id m22mr9952771qtp.323.1557502188502; Fri, 10 May 2019 08:29:48 -0700 (PDT) MIME-Version: 1.0 References: <1557395622-32425-1-git-send-email-mw@semihalf.com> <1557395622-32425-7-git-send-email-mw@semihalf.com> <20190510152506.iqrt72vly7m6ehv6@bivouac.eciton.net> In-Reply-To: <20190510152506.iqrt72vly7m6ehv6@bivouac.eciton.net> From: "Marcin Wojtas" Date: Fri, 10 May 2019 17:29:37 +0200 Message-ID: Subject: Re: [edk2-platforms: PATCH 06/14] Marvell/Armada7k8k: Add PciExpressLib implementation To: Leif Lindholm Cc: edk2-devel-groups-io , Ard Biesheuvel , "jsd@semihalf.com" , Grzegorz Jaszczyk , Kostya Porotchkin , Jici Gao , Rebecca Cran , Mark Kettenis Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Leif, pt., 10 maj 2019 o 17:25 Leif Lindholm napisa=C5= =82(a): > > On Thu, May 09, 2019 at 11:53:34AM +0200, Marcin Wojtas wrote: > > From: Ard Biesheuvel > > > > Implement a special version of PciExpressLib that takes the quirky > > nature of the Synopsys Designware PCIe IP into account. In particular, > > we need to ignores config space accesses to all devices on the first > > bus except device 0, because the broadcast nature of type 0 configurati= on > > cycles will result in whatever device is in the slot to appear at each > > of the 32 device positions. > > > > Contributed-under: TianoCore Contribution Agreement 1.1 > > Signed-off-by: Marcin Wojtas > > --- > > Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib/PciExpressL= ib.inf | 42 + > > Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib/PciExpressL= ib.c | 1529 ++++++++++++++++++++ > > 2 files changed, 1571 insertions(+) > > create mode 100644 Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExp= ressLib/PciExpressLib.inf > > create mode 100644 Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExp= ressLib/PciExpressLib.c > > > > diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib= /PciExpressLib.inf b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpres= sLib/PciExpressLib.inf > > new file mode 100644 > > index 0000000..8f09820 > > --- /dev/null > > +++ b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib/PciExp= ressLib.inf > > @@ -0,0 +1,42 @@ > > +## @file > > +# > > +# Copyright (c) 2017, Linaro, Ltd. All rights reserved.
> > +# Copyright (c) 2019 Marvell International Ltd. All rights reserved.<= BR> > > +# > > +# This program and the accompanying materials > > +# are licensed and made available under the terms and conditions of t= he BSD License > > +# which accompanies this distribution. The full text of the license m= ay be found at > > +# http://opensource.org/licenses/bsd-license.php. > > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASI= S, > > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS O= R IMPLIED. > > +# > > +# > > +## > > + > > +[Defines] > > + INF_VERSION =3D 0x0001001B > > + BASE_NAME =3D Armada7k8kPciExpressLib > > + FILE_GUID =3D f0926204-3061-40ed-8261-2aeccc791= 4c9 > > + MODULE_TYPE =3D BASE > > + VERSION_STRING =3D 1.0 > > + LIBRARY_CLASS =3D PciExpressLib > > + > > +[Sources] > > + PciExpressLib.c > > + > > +[Packages] > > + ArmPkg/ArmPkg.dec > > + MdePkg/MdePkg.dec > > + > > +[LibraryClasses] > > + BaseLib > > + DebugLib > > + IoLib > > + PcdLib > > + > > +[Pcd] > > + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## CONSUMES > > + > > +[FixedPcd] > > + gArmTokenSpaceGuid.PcdPciBusMin > > + gArmTokenSpaceGuid.PcdPciBusMax > > diff --git a/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib= /PciExpressLib.c b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressL= ib/PciExpressLib.c > > new file mode 100644 > > index 0000000..8fa2eb6 > > --- /dev/null > > +++ b/Silicon/Marvell/Armada7k8k/Library/Armada7k8kPciExpressLib/PciExp= ressLib.c > > @@ -0,0 +1,1529 @@ > > +/** @file > > + > > + Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved. > > + Copyright (c) 2019 Marvell International Ltd. All rights reserved. > > If Ard is the author of this patch, should there not be Linaro > copyright here as well? > > > + > > + This program and the accompanying materials > > + are licensed and made available under the terms and conditions of th= e BSD License > > + which accompanies this distribution. The full text of the license m= ay 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 > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +/** > > + Assert the validity of a PCI address. A valid PCI address should con= tain 1's > > + only in the low 28 bits. > > + > > + @param A The address to validate. > > + > > +**/ > > +#define ASSERT_INVALID_PCI_ADDRESS(A) \ > > + ASSERT (((A) & ~0xfffffff) =3D=3D 0) > > + > > +/** > > + Registers a PCI device so PCI configuration registers may be accesse= d after > > + SetVirtualAddressMap(). > > + > > + Registers the PCI device specified by Address so all the PCI configu= ration > > + registers associated with that PCI device may be accessed after SetV= irtualAddressMap() > > + is called. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + > > + @retval RETURN_SUCCESS The PCI device was registered for r= untime access. > > + @retval RETURN_UNSUPPORTED An attempt was made to call this fu= nction > > + after ExitBootServices(). > > + @retval RETURN_UNSUPPORTED The resources required to access th= e PCI device > > + at runtime could not be mapped. > > + @retval RETURN_OUT_OF_RESOURCES There are not enough resources avai= lable to > > + complete the registration. > > + > > +**/ > > +RETURN_STATUS > > +EFIAPI > > +PciExpressRegisterForRuntimeAccess ( > > + IN UINTN Address > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + return RETURN_UNSUPPORTED; > > +} > > + > > +#define ECAM_BUS_SIZE SIZE_1MB > > +#define ECAM_DEV_SIZE SIZE_32KB > > + > > +STATIC > > +BOOLEAN > > +IgnoreBusDeviceFunction ( > > + IN UINTN Address > > + ) > > +{ > > + ASSERT (Address >=3D FixedPcdGet32 (PcdPciBusMin) * ECAM_BUS_SIZE); > > + ASSERT (Address < (FixedPcdGet32 (PcdPciBusMax) + 1) * ECAM_BUS_SIZE= ); > > + > > + // > > + // Type 0 configuration cycles don't contain a b/d/f specifier, and = so it > > + // is up to the bus that delivers them to ensure they only end up at= the > > + // correct device/function. Sadly, the Synopsys IP does not implemen= t this, > > + // and so we have to ignore config space accesses for all devices on= the > > + // first bus except device 0. > > + // > > + return (Address >=3D (FixedPcdGet32 (PcdPciBusMin) * ECAM_BUS_SIZE + > > + ECAM_DEV_SIZE) && > > + Address < (FixedPcdGet32 (PcdPciBusMin) + 1) * ECAM_BUS_SIZE= ); > > +} > > + > > +/** > > + Gets the base address of PCI Express. > > + > > + This internal functions retrieves PCI Express Base Address via a PCD= entry > > + PcdPciExpressBaseAddress. > > + > > + @return The base address of PCI Express. > > + > > +**/ > > +VOID* > > +GetPciExpressBaseAddress ( > > + VOID > > + ) > > +{ > > + return (VOID*)(UINTN) PcdGet64 (PcdPciExpressBaseAddress); > > Drop space before PcdGet64. > > > +} > > + > > +/** > > + Reads an 8-bit PCI configuration register. > > + > > + Reads and returns the 8-bit PCI configuration register specified by = Address. > > + This function must guarantee that all PCI read and write operations = are > > + serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + > > + @return The read value from the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressRead8 ( > > + IN UINTN Address > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > Bikeshedding time: could/should we replace these with MAX_UINT8, > MAX_UINT16, MAX_UINT32? > > > + } > > + return MmioRead8 ((UINTN) GetPciExpressBaseAddress () + Address); > > Drop space after (UINTN). > > > +} > > + > > +/** > > + Writes an 8-bit PCI configuration register. > > + > > + Writes the 8-bit PCI configuration register specified by Address wit= h the > > + value specified by Value. Value is returned. This function must guar= antee > > + that all PCI read and write operations are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + @param Value The value to write. > > + > > + @return The value written to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressWrite8 ( > > + IN UINTN Address, > > + IN UINT8 Value > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioWrite8 ((UINTN) GetPciExpressBaseAddress () + Address, Va= lue); > > Drop space after (UINTN). > (There are more below, please address throughout.) > > > +} > > + > > +/** > > + 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, per= forms a > > + bitwise OR between the read result and the value specified by > > + OrData, and writes the result to the 8-bit PCI configuration registe= r > > + specified by Address. The value written to the PCI configuration reg= ister is > > + returned. This function must guarantee that all PCI read and write o= perations > > + are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + @param OrData The value to OR with the PCI configuration register. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressOr8 ( > > + IN UINTN Address, > > + IN UINT8 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioOr8 ((UINTN) GetPciExpressBaseAddress () + Address, OrDat= a); > > +} > > + > > +/** > > + Performs a bitwise AND of an 8-bit PCI configuration register with a= n 8-bit > > + value. > > + > > + Reads the 8-bit PCI configuration register specified by Address, per= forms a > > + bitwise AND between the read result and the value specified by AndDa= ta, and > > + writes the result to the 8-bit PCI configuration register specified = by > > + Address. The value written to the PCI configuration register is retu= rned. > > + This function must guarantee that all PCI read and write operations = are > > + serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + @param AndData The value to AND with the PCI configuration register= . > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressAnd8 ( > > + IN UINTN Address, > > + IN UINT8 AndData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioAnd8 ((UINTN) GetPciExpressBaseAddress () + Address, AndD= ata); > > +} > > + > > +/** > > + Performs a bitwise AND of an 8-bit PCI configuration register with a= n 8-bit > > + value, followed a bitwise OR with another 8-bit value. > > + > > + Reads the 8-bit PCI configuration register specified by Address, per= forms a > > + bitwise AND between the read result and the value specified by AndDa= ta, > > + 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 PC= I > > + configuration register specified by Address. The value written to th= e PCI > > + configuration register is returned. This function must guarantee tha= t all PCI > > + read and write operations are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + @param AndData The value to AND with the PCI configuration register= . > > + @param OrData The value to OR with the result of the AND operation= . > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressAndThenOr8 ( > > + IN UINTN Address, > > + IN UINT8 AndData, > > + IN UINT8 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioAndThenOr8 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + AndData, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a bit field of a PCI configuration register. > > + > > + Reads the bit field in an 8-bit PCI configuration register. The bit = field is > > + specified by the StartBit and the EndBit. The value of the bit field= is > > + returned. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If StartBit is greater than 7, then ASSERT(). > > + If EndBit is greater than 7, then ASSERT(). > > + If EndBit is less than StartBit, then ASSERT(). > > + > > + @param Address The PCI configuration register to read. > > + @param StartBit The ordinal of the least significant bit in the bi= t 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 r= egister. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressBitFieldRead8 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioBitFieldRead8 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit > > + ); > > +} > > + > > +/** > > + Writes a bit field to a PCI configuration register. > > + > > + Writes Value to the bit field of the PCI configuration register. The= bit > > + field is specified by the StartBit and the EndBit. All other bits in= the > > + destination PCI configuration register are preserved. The new value = of the > > + 8-bit register is returned. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If StartBit is greater than 7, then ASSERT(). > > + If EndBit is greater than 7, then ASSERT(). > > + If EndBit is less than StartBit, then ASSERT(). > > + If Value is larger than the bitmask value range specified by StartBi= t and EndBit, then ASSERT(). > > + > > + @param Address The PCI configuration register to write. > > + @param StartBit The ordinal of the least significant bit in the bi= t field. > > + Range 0..7. > > + @param EndBit The ordinal of the most significant bit in the bit= field. > > + Range 0..7. > > + @param Value The new value of the bit field. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressBitFieldWrite8 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT8 Value > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioBitFieldWrite8 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + Value > > + ); > > +} > > + > > +/** > > + Reads a bit field in an 8-bit PCI configuration, performs a bitwise = OR, and > > + writes the result back to the bit field in the 8-bit port. > > + > > + Reads the 8-bit PCI configuration register specified by Address, per= forms a > > + bitwise OR between the read result and the value specified by > > + OrData, and writes the result to the 8-bit PCI configuration registe= r > > + specified by Address. The value written to the PCI configuration reg= ister is > > + returned. This function must guarantee that all PCI read and write o= perations > > + are serialized. Extra left bits in OrData are stripped. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If StartBit is greater than 7, then ASSERT(). > > + If EndBit is greater than 7, then ASSERT(). > > + If EndBit is less than StartBit, then ASSERT(). > > + If OrData is larger than the bitmask value range specified by StartB= it and EndBit, then ASSERT(). > > + > > + @param Address The PCI configuration register to write. > > + @param StartBit The ordinal of the least significant bit in the bi= t 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 registe= r. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressBitFieldOr8 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT8 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioBitFieldOr8 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a bit field in an 8-bit PCI configuration register, performs a= bitwise > > + AND, and writes the result back to the bit field in the 8-bit regist= er. > > + > > + Reads the 8-bit PCI configuration register specified by Address, per= forms a > > + bitwise AND between the read result and the value specified by AndDa= ta, and > > + writes the result to the 8-bit PCI configuration register specified = by > > + Address. The value written to the PCI configuration register is retu= rned. > > + This function must guarantee that all PCI read and write operations = are > > + serialized. Extra left bits in AndData are stripped. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If StartBit is greater than 7, then ASSERT(). > > + If EndBit is greater than 7, then ASSERT(). > > + If EndBit is less than StartBit, then ASSERT(). > > + If AndData is larger than the bitmask value range specified by Start= Bit and EndBit, then ASSERT(). > > + > > + @param Address The PCI configuration register to write. > > + @param StartBit The ordinal of the least significant bit in the bi= t 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 regist= er. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressBitFieldAnd8 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT8 AndData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioBitFieldAnd8 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + AndData > > + ); > > +} > > + > > +/** > > + Reads a bit field in an 8-bit port, performs a bitwise AND followed = by a > > + bitwise OR, and writes the result back to the bit field in the > > + 8-bit port. > > + > > + Reads the 8-bit PCI configuration register specified by Address, per= forms 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 P= CI > > + configuration register specified by Address. The value written to th= e PCI > > + configuration register is returned. This function must guarantee tha= t all PCI > > + read and write operations are serialized. Extra left bits in both An= dData and > > + OrData are stripped. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If StartBit is greater than 7, then ASSERT(). > > + If EndBit is greater than 7, then ASSERT(). > > + If EndBit is less than StartBit, then ASSERT(). > > + If AndData is larger than the bitmask value range specified by Start= Bit and EndBit, then ASSERT(). > > + If OrData is larger than the bitmask value range specified by StartB= it and EndBit, then ASSERT(). > > + > > + @param Address The PCI configuration register to write. > > + @param StartBit The ordinal of the least significant bit in the bi= t 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 regist= er. > > + @param OrData The value to OR with the result of the AND operati= on. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT8 > > +EFIAPI > > +PciExpressBitFieldAndThenOr8 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT8 AndData, > > + IN UINT8 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xff; > > + } > > + return MmioBitFieldAndThenOr8 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + AndData, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a 16-bit PCI configuration register. > > + > > + Reads and returns the 16-bit PCI configuration register specified by= Address. > > + This function must guarantee that all PCI read and write operations = are > > + serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + > > + @return The read value from the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressRead16 ( > > + IN UINTN Address > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioRead16 ((UINTN) GetPciExpressBaseAddress () + Address); > > +} > > + > > +/** > > + Writes a 16-bit PCI configuration register. > > + > > + Writes the 16-bit PCI configuration register specified by Address wi= th the > > + value specified by Value. Value is returned. This function must guar= antee > > + that all PCI read and write operations are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + @param Value The value to write. > > + > > + @return The value written to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressWrite16 ( > > + IN UINTN Address, > > + IN UINT16 Value > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioWrite16 ((UINTN) GetPciExpressBaseAddress () + Address, V= alue); > > +} > > + > > +/** > > + 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, pe= rforms a > > + bitwise OR between the read result and the value specified by > > + OrData, and writes the result to the 16-bit PCI configuration regist= er > > + specified by Address. The value written to the PCI configuration reg= ister is > > + returned. This function must guarantee that all PCI read and write o= perations > > + are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + @param OrData The value to OR with the PCI configuration register. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressOr16 ( > > + IN UINTN Address, > > + IN UINT16 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioOr16 ((UINTN) GetPciExpressBaseAddress () + Address, OrDa= ta); > > +} > > + > > +/** > > + 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, pe= rforms a > > + bitwise AND between the read result and the value specified by AndDa= ta, and > > + writes the result to the 16-bit PCI configuration register specified= by > > + Address. The value written to the PCI configuration register is retu= rned. > > + This function must guarantee that all PCI read and write operations = are > > + serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + @param AndData The value to AND with the PCI configuration register= . > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressAnd16 ( > > + IN UINTN Address, > > + IN UINT16 AndData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioAnd16 ((UINTN) GetPciExpressBaseAddress () + Address, And= Data); > > +} > > + > > +/** > > + 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, pe= rforms a > > + bitwise AND between the read result and the value specified by AndDa= ta, > > + 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 P= CI > > + configuration register specified by Address. The value written to th= e PCI > > + configuration register is returned. This function must guarantee tha= t all PCI > > + read and write operations are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + @param AndData The value to AND with the PCI configuration register= . > > + @param OrData The value to OR with the result of the AND operation= . > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressAndThenOr16 ( > > + IN UINTN Address, > > + IN UINT16 AndData, > > + IN UINT16 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioAndThenOr16 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + AndData, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a bit field of a PCI configuration register. > > + > > + Reads the bit field in a 16-bit PCI configuration register. The bit = field is > > + specified by the StartBit and the EndBit. The value of the bit field= is > > + returned. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > > + If StartBit is greater than 15, then ASSERT(). > > + If EndBit is greater than 15, then ASSERT(). > > + If EndBit is less than StartBit, then ASSERT(). > > + > > + @param Address The PCI configuration register to read. > > + @param StartBit The ordinal of the least significant bit in the bi= t 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 r= egister. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressBitFieldRead16 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioBitFieldRead16 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit > > + ); > > +} > > + > > +/** > > + Writes a bit field to a PCI configuration register. > > + > > + Writes Value to the bit field of the PCI configuration register. The= bit > > + field is specified by the StartBit and the EndBit. All other bits in= the > > + destination PCI configuration register are preserved. The new value = of the > > + 16-bit register is returned. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > > + If StartBit is greater than 15, then ASSERT(). > > + If EndBit is greater than 15, then ASSERT(). > > + If EndBit is less than StartBit, then ASSERT(). > > + If Value is larger than the bitmask value range specified by StartBi= t and EndBit, then ASSERT(). > > + > > + @param Address The PCI configuration register to write. > > + @param StartBit The ordinal of the least significant bit in the bi= t field. > > + Range 0..15. > > + @param EndBit The ordinal of the most significant bit in the bit= field. > > + Range 0..15. > > + @param Value The new value of the bit field. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressBitFieldWrite16 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT16 Value > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioBitFieldWrite16 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + Value > > + ); > > +} > > + > > +/** > > + Reads a bit field in a 16-bit PCI configuration, performs a bitwise = OR, and > > + writes the result back to the bit field in the 16-bit port. > > + > > + Reads the 16-bit PCI configuration register specified by Address, pe= rforms a > > + bitwise OR between the read result and the value specified by > > + OrData, and writes the result to the 16-bit PCI configuration regist= er > > + specified by Address. The value written to the PCI configuration reg= ister is > > + returned. This function must guarantee that all PCI read and write o= perations > > + are serialized. Extra left bits in OrData are stripped. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > > + If StartBit is greater than 15, then ASSERT(). > > + If EndBit is greater than 15, then ASSERT(). > > + If EndBit is less than StartBit, then ASSERT(). > > + If OrData is larger than the bitmask value range specified by StartB= it and EndBit, then ASSERT(). > > + > > + @param Address The PCI configuration register to write. > > + @param StartBit The ordinal of the least significant bit in the bi= t 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 registe= r. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressBitFieldOr16 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT16 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioBitFieldOr16 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a bit field in a 16-bit PCI configuration register, performs a= bitwise > > + AND, and writes the result back to the bit field in the 16-bit regis= ter. > > + > > + Reads the 16-bit PCI configuration register specified by Address, pe= rforms a > > + bitwise AND between the read result and the value specified by AndDa= ta, and > > + writes the result to the 16-bit PCI configuration register specified= by > > + Address. The value written to the PCI configuration register is retu= rned. > > + This function must guarantee that all PCI read and write operations = are > > + serialized. Extra left bits in AndData are stripped. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > > + If StartBit is greater than 15, then ASSERT(). > > + If EndBit is greater than 15, then ASSERT(). > > + If EndBit is less than StartBit, then ASSERT(). > > + If AndData is larger than the bitmask value range specified by Start= Bit and EndBit, then ASSERT(). > > + > > + @param Address The PCI configuration register to write. > > + @param StartBit The ordinal of the least significant bit in the bi= t 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 regist= er. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressBitFieldAnd16 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT16 AndData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioBitFieldAnd16 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + AndData > > + ); > > +} > > + > > +/** > > + Reads a bit field in a 16-bit port, performs a bitwise AND followed = by a > > + bitwise OR, and writes the result back to the bit field in the > > + 16-bit port. > > + > > + Reads the 16-bit PCI configuration register specified by Address, pe= rforms 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 th= e PCI > > + configuration register is returned. This function must guarantee tha= t all PCI > > + read and write operations are serialized. Extra left bits in both An= dData and > > + OrData are stripped. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 16-bit boundary, then ASSERT(). > > + If StartBit is greater than 15, then ASSERT(). > > + If EndBit is greater than 15, then ASSERT(). > > + If EndBit is less than StartBit, then ASSERT(). > > + If AndData is larger than the bitmask value range specified by Start= Bit and EndBit, then ASSERT(). > > + If OrData is larger than the bitmask value range specified by StartB= it and EndBit, then ASSERT(). > > + > > + @param Address The PCI configuration register to write. > > + @param StartBit The ordinal of the least significant bit in the bi= t 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 regist= er. > > + @param OrData The value to OR with the result of the AND operati= on. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT16 > > +EFIAPI > > +PciExpressBitFieldAndThenOr16 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT16 AndData, > > + IN UINT16 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffff; > > + } > > + return MmioBitFieldAndThenOr16 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + AndData, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a 32-bit PCI configuration register. > > + > > + Reads and returns the 32-bit PCI configuration register specified by= Address. > > + This function must guarantee that all PCI read and write operations = are > > + serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + > > + @return The read value from the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressRead32 ( > > + IN UINTN Address > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioRead32 ((UINTN) GetPciExpressBaseAddress () + Address); > > +} > > + > > +/** > > + Writes a 32-bit PCI configuration register. > > + > > + Writes the 32-bit PCI configuration register specified by Address wi= th the > > + value specified by Value. Value is returned. This function must guar= antee > > + that all PCI read and write operations are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + @param Value The value to write. > > + > > + @return The value written to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressWrite32 ( > > + IN UINTN Address, > > + IN UINT32 Value > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioWrite32 ((UINTN) GetPciExpressBaseAddress () + Address, V= alue); > > +} > > + > > +/** > > + 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, pe= rforms a > > + bitwise OR between the read result and the value specified by > > + OrData, and writes the result to the 32-bit PCI configuration regist= er > > + specified by Address. The value written to the PCI configuration reg= ister is > > + returned. This function must guarantee that all PCI read and write o= perations > > + are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + @param OrData The value to OR with the PCI configuration register. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressOr32 ( > > + IN UINTN Address, > > + IN UINT32 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioOr32 ((UINTN) GetPciExpressBaseAddress () + Address, OrDa= ta); > > +} > > + > > +/** > > + 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, pe= rforms a > > + bitwise AND between the read result and the value specified by AndDa= ta, and > > + writes the result to the 32-bit PCI configuration register specified= by > > + Address. The value written to the PCI configuration register is retu= rned. > > + This function must guarantee that all PCI read and write operations = are > > + serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + @param AndData The value to AND with the PCI configuration register= . > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressAnd32 ( > > + IN UINTN Address, > > + IN UINT32 AndData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > +return MmioAnd32 ((UINTN) GetPciExpressBaseAddress () + Address, AndDa= ta); > > +} > > + > > +/** > > + 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, pe= rforms a > > + bitwise AND between the read result and the value specified by AndDa= ta, > > + 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 P= CI > > + configuration register specified by Address. The value written to th= e PCI > > + configuration register is returned. This function must guarantee tha= t all PCI > > + read and write operations are serialized. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > > + > > + @param Address The address that encodes the PCI Bus, Device, Functi= on and > > + Register. > > + @param AndData The value to AND with the PCI configuration register= . > > + @param OrData The value to OR with the result of the AND operation= . > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressAndThenOr32 ( > > + IN UINTN Address, > > + IN UINT32 AndData, > > + IN UINT32 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioAndThenOr32 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + AndData, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a bit field of a PCI configuration register. > > + > > + Reads the bit field in a 32-bit PCI configuration register. The bit = field is > > + specified by the StartBit and the EndBit. The value of the bit field= is > > + returned. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > > + If StartBit is greater than 31, then ASSERT(). > > + If EndBit is greater than 31, then ASSERT(). > > + If EndBit is less than StartBit, then ASSERT(). > > + > > + @param Address The PCI configuration register to read. > > + @param StartBit The ordinal of the least significant bit in the bi= t 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 r= egister. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressBitFieldRead32 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioBitFieldRead32 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit > > + ); > > +} > > + > > +/** > > + Writes a bit field to a PCI configuration register. > > + > > + Writes Value to the bit field of the PCI configuration register. The= bit > > + field is specified by the StartBit and the EndBit. All other bits in= the > > + destination PCI configuration register are preserved. The new value = of the > > + 32-bit register is returned. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > > + If StartBit is greater than 31, then ASSERT(). > > + If EndBit is greater than 31, then ASSERT(). > > + If EndBit is less than StartBit, then ASSERT(). > > + If Value is larger than the bitmask value range specified by StartBi= t and EndBit, then ASSERT(). > > + > > + @param Address The PCI configuration register to write. > > + @param StartBit The ordinal of the least significant bit in the bi= t field. > > + Range 0..31. > > + @param EndBit The ordinal of the most significant bit in the bit= field. > > + Range 0..31. > > + @param Value The new value of the bit field. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressBitFieldWrite32 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT32 Value > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioBitFieldWrite32 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + Value > > + ); > > +} > > + > > +/** > > + Reads a bit field in a 32-bit PCI configuration, performs a bitwise = OR, and > > + writes the result back to the bit field in the 32-bit port. > > + > > + Reads the 32-bit PCI configuration register specified by Address, pe= rforms a > > + bitwise OR between the read result and the value specified by > > + OrData, and writes the result to the 32-bit PCI configuration regist= er > > + specified by Address. The value written to the PCI configuration reg= ister is > > + returned. This function must guarantee that all PCI read and write o= perations > > + are serialized. Extra left bits in OrData are stripped. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > > + If StartBit is greater than 31, then ASSERT(). > > + If EndBit is greater than 31, then ASSERT(). > > + If EndBit is less than StartBit, then ASSERT(). > > + If OrData is larger than the bitmask value range specified by StartB= it and EndBit, then ASSERT(). > > + > > + @param Address The PCI configuration register to write. > > + @param StartBit The ordinal of the least significant bit in the bi= t 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 registe= r. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressBitFieldOr32 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT32 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioBitFieldOr32 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a bit field in a 32-bit PCI configuration register, performs a= bitwise > > + AND, and writes the result back to the bit field in the 32-bit regis= ter. > > + > > + Reads the 32-bit PCI configuration register specified by Address, pe= rforms a > > + bitwise AND between the read result and the value specified by AndDa= ta, and > > + writes the result to the 32-bit PCI configuration register specified= by > > + Address. The value written to the PCI configuration register is retu= rned. > > + This function must guarantee that all PCI read and write operations = are > > + serialized. Extra left bits in AndData are stripped. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > > + If StartBit is greater than 31, then ASSERT(). > > + If EndBit is greater than 31, then ASSERT(). > > + If EndBit is less than StartBit, then ASSERT(). > > + If AndData is larger than the bitmask value range specified by Start= Bit and EndBit, then ASSERT(). > > + > > + @param Address The PCI configuration register to write. > > + @param StartBit The ordinal of the least significant bit in the bi= t 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 regist= er. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressBitFieldAnd32 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT32 AndData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioBitFieldAnd32 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + AndData > > + ); > > +} > > + > > +/** > > + Reads a bit field in a 32-bit port, performs a bitwise AND followed = by a > > + bitwise OR, and writes the result back to the bit field in the > > + 32-bit port. > > + > > + Reads the 32-bit PCI configuration register specified by Address, pe= rforms 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 th= e PCI > > + configuration register is returned. This function must guarantee tha= t all PCI > > + read and write operations are serialized. Extra left bits in both An= dData and > > + OrData are stripped. > > + > > + If Address > 0x0FFFFFFF, then ASSERT(). > > + If Address is not aligned on a 32-bit boundary, then ASSERT(). > > + If StartBit is greater than 31, then ASSERT(). > > + If EndBit is greater than 31, then ASSERT(). > > + If EndBit is less than StartBit, then ASSERT(). > > + If AndData is larger than the bitmask value range specified by Start= Bit and EndBit, then ASSERT(). > > + If OrData is larger than the bitmask value range specified by StartB= it and EndBit, then ASSERT(). > > + > > + @param Address The PCI configuration register to write. > > + @param StartBit The ordinal of the least significant bit in the bi= t 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 regist= er. > > + @param OrData The value to OR with the result of the AND operati= on. > > + > > + @return The value written back to the PCI configuration register. > > + > > +**/ > > +UINT32 > > +EFIAPI > > +PciExpressBitFieldAndThenOr32 ( > > + IN UINTN Address, > > + IN UINTN StartBit, > > + IN UINTN EndBit, > > + IN UINT32 AndData, > > + IN UINT32 OrData > > + ) > > +{ > > + ASSERT_INVALID_PCI_ADDRESS (Address); > > + if (IgnoreBusDeviceFunction (Address)) { > > + return 0xffffffff; > > + } > > + return MmioBitFieldAndThenOr32 ( > > + (UINTN) GetPciExpressBaseAddress () + Address, > > + StartBit, > > + EndBit, > > + AndData, > > + OrData > > + ); > > +} > > + > > +/** > > + Reads a range of PCI configuration registers into a caller supplied = buffer. > > + > > + Reads the range of PCI configuration registers specified by StartAdd= ress 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 use= d to read > > + from StartAddress to StartAddress + Size. Due to alignment restricti= ons, 8-bit > > + and 16-bit PCI configuration read cycles may be used at the beginnin= g and the > > + end of the range. > > + > > + If StartAddress > 0x0FFFFFFF, then ASSERT(). > > + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT(). > > + If Size > 0 and Buffer is NULL, then ASSERT(). > > + > > + @param StartAddress The starting address that encodes the PCI Bus,= Device, > > + Function and Register. > > + @param Size The size in bytes of the transfer. > > + @param Buffer The pointer to a buffer receiving the data rea= d. > > + > > + @return Size read data from StartAddress. > > + > > +**/ > > +UINTN > > +EFIAPI > > +PciExpressReadBuffer ( > > + IN UINTN StartAddress, > > + IN UINTN Size, > > + OUT VOID *Buffer > > + ) > > +{ > > + UINTN ReturnValue; > > + > > + ASSERT_INVALID_PCI_ADDRESS (StartAddress); > > + ASSERT (((StartAddress & 0xFFF) + Size) <=3D 0x1000); > > + > > + if (Size =3D=3D 0) { > > + return Size; > > + } > > + > > + ASSERT (Buffer !=3D NULL); > > + > > + // > > + // Save Size for return > > + // > > + ReturnValue =3D Size; > > + > > + if ((StartAddress & 1) !=3D 0) { > > + // > > + // Read a byte if StartAddress is byte aligned > > + // > > + *(volatile UINT8 *)Buffer =3D PciExpressRead8 (StartAddress); > > *eep* > Inline volatile casts? > Well, I guess inherited from the original. > > We already have a dependency on IoLib (and include the header), can we > use MmioWrite8 instead? > > > + StartAddress +=3D sizeof (UINT8); > > + Size -=3D sizeof (UINT8); > > + Buffer =3D (UINT8*)Buffer + 1; > > + } > > + > > + if (Size >=3D sizeof (UINT16) && (StartAddress & 2) !=3D 0) { > > + // > > + // Read a word if StartAddress is word aligned > > + // > > + WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (St= artAddress)); > > + > > + StartAddress +=3D sizeof (UINT16); > > + Size -=3D sizeof (UINT16); > > + Buffer =3D (UINT16*)Buffer + 1; > > + } > > + > > + while (Size >=3D sizeof (UINT32)) { > > + // > > + // Read as many double words as possible > > + // > > + WriteUnaligned32 ((UINT32 *) Buffer, (UINT32) PciExpressRead32 (St= artAddress)); > > + > > + StartAddress +=3D sizeof (UINT32); > > + Size -=3D sizeof (UINT32); > > + Buffer =3D (UINT32*)Buffer + 1; > > + } > > + > > + if (Size >=3D sizeof (UINT16)) { > > + // > > + // Read the last remaining word if exist > > + // > > + WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (St= artAddress)); > > + StartAddress +=3D sizeof (UINT16); > > + Size -=3D sizeof (UINT16); > > + Buffer =3D (UINT16*)Buffer + 1; > > + } > > + > > + if (Size >=3D sizeof (UINT8)) { > > + // > > + // Read the last remaining byte if exist > > + // > > + *(volatile UINT8 *)Buffer =3D PciExpressRead8 (StartAddress); > > Same again. > Yes, it's inherited. Will try MmioWrite8 instead. Also ok to all remarks above. Thanks, Marcin > / > Leif > > > + } > > + > > + 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 StartAd= dress and > > + Size from the buffer specified by Buffer. This function only allows = the PCI > > + configuration registers from a single PCI function to be written. Si= ze is > > + returned. When possible 32-bit PCI configuration write cycles are us= ed to > > + write from StartAddress to StartAddress + Size. Due to alignment res= trictions, > > + 8-bit and 16-bit PCI configuration write cycles may be used at the b= eginning > > + and the end of the range. > > + > > + If StartAddress > 0x0FFFFFFF, then ASSERT(). > > + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT(). > > + If Size > 0 and Buffer is NULL, then ASSERT(). > > + > > + @param StartAddress The starting address that encodes the PCI Bus,= Device, > > + Function and Register. > > + @param Size The size in bytes of the transfer. > > + @param Buffer The pointer to a buffer containing the data to= write. > > + > > + @return Size written to StartAddress. > > + > > +**/ > > +UINTN > > +EFIAPI > > +PciExpressWriteBuffer ( > > + IN UINTN StartAddress, > > + IN UINTN Size, > > + IN VOID *Buffer > > + ) > > +{ > > + UINTN ReturnValue; > > + > > + ASSERT_INVALID_PCI_ADDRESS (StartAddress); > > + ASSERT (((StartAddress & 0xFFF) + Size) <=3D 0x1000); > > + > > + if (Size =3D=3D 0) { > > + return 0; > > + } > > + > > + ASSERT (Buffer !=3D NULL); > > + > > + // > > + // Save Size for return > > + // > > + ReturnValue =3D Size; > > + > > + if ((StartAddress & 1) !=3D 0) { > > + // > > + // Write a byte if StartAddress is byte aligned > > + // > > + PciExpressWrite8 (StartAddress, *(UINT8*)Buffer); > > + StartAddress +=3D sizeof (UINT8); > > + Size -=3D sizeof (UINT8); > > + Buffer =3D (UINT8*)Buffer + 1; > > + } > > + > > + if (Size >=3D sizeof (UINT16) && (StartAddress & 2) !=3D 0) { > > + // > > + // Write a word if StartAddress is word aligned > > + // > > + PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer)= ); > > + StartAddress +=3D sizeof (UINT16); > > + Size -=3D sizeof (UINT16); > > + Buffer =3D (UINT16*)Buffer + 1; > > + } > > + > > + while (Size >=3D sizeof (UINT32)) { > > + // > > + // Write as many double words as possible > > + // > > + PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer)= ); > > + StartAddress +=3D sizeof (UINT32); > > + Size -=3D sizeof (UINT32); > > + Buffer =3D (UINT32*)Buffer + 1; > > + } > > + > > + if (Size >=3D sizeof (UINT16)) { > > + // > > + // Write the last remaining word if exist > > + // > > + PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer)= ); > > + StartAddress +=3D sizeof (UINT16); > > + Size -=3D sizeof (UINT16); > > + Buffer =3D (UINT16*)Buffer + 1; > > + } > > + > > + if (Size >=3D sizeof (UINT8)) { > > + // > > + // Write the last remaining byte if exist > > + // > > + PciExpressWrite8 (StartAddress, *(UINT8*)Buffer); > > + } > > + > > + return ReturnValue; > > +} > > -- > > 2.7.4 > >