aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsudipto paul <sudipto.paul@arm.com>2019-10-13 21:43:14 +0100
committersudipto paul <sudipto.paul@arm.com>2019-10-13 21:43:14 +0100
commitd1e2762535d1c187436a040c5bd0d743d2739e38 (patch)
tree440d0f5be11c1e4d49b9da9cce6ffdc2687821ae
parent5fcb80efb242a6c23095935c3fcf80ea8c10dd77 (diff)
update quirk patches for scp,linux and edk2-platforms
- linux - move to 5.3.4 - edk2-platforms rebase - scp rebase Signed-off-by: sudipto paul <sudipto.paul@arm.com>
-rwxr-xr-xedk2-platforms/0001-Platform-ARM-N1Sdp-fix-to-prevent-PCIe-SLVERR.patch3310
-rwxr-xr-xlinux/0001-N1SDP-PCIe-Enablement-Quirks-for-N1SDP-PCie-controll.patch70
-rwxr-xr-xpatch_apply.sh2
-rw-r--r--scp/0001-n1sdp-add-workaround-for-PCIe-to-avoid-SLVERR-fault.patch74
4 files changed, 1752 insertions, 1704 deletions
diff --git a/edk2-platforms/0001-Platform-ARM-N1Sdp-fix-to-prevent-PCIe-SLVERR.patch b/edk2-platforms/0001-Platform-ARM-N1Sdp-fix-to-prevent-PCIe-SLVERR.patch
index 64b37bf..8ce7815 100755
--- a/edk2-platforms/0001-Platform-ARM-N1Sdp-fix-to-prevent-PCIe-SLVERR.patch
+++ b/edk2-platforms/0001-Platform-ARM-N1Sdp-fix-to-prevent-PCIe-SLVERR.patch
@@ -1,4 +1,4 @@
-From c13ba44c98e75f864768c1b417c84767f2b17bd7 Mon Sep 17 00:00:00 2001
+From 18cd517924c91e1d3e5d6865ab09a8e0a4ed3f12 Mon Sep 17 00:00:00 2001
From: Deepak Pandey <Deepak.Pandey@arm.com>
Date: Fri, 16 Nov 2018 18:00:03 +0530
Subject: [PATCH] Platform/ARM/N1Sdp: fix to prevent PCIe SLVERR
@@ -9,13 +9,13 @@ non-available device / unimplemented function in a given bus.
This patch returns 0xFFFFFFFF in software for such
devices/functions.
-Change-Id: I4880e7354253fc98aaa33e6645e5496fb3782bc3
+Change-Id: I38caf566b18be90976610174bc8e43a9a4c4f1fd
Signed-off-by: Deepak Pandey <Deepak.Pandey@arm.com>
---
- .../N1SdpPkg/Library/PciExpressLib/PciExpressLib.c | 1570 ++++++++++++++++++++
- .../Library/PciExpressLib/PciExpressLib.inf | 48 +
- .../Library/PciExpressLib/PciExpressLib.uni | 17 +
- Platform/ARM/N1SdpPkg/N1SdpPlatform.dsc | 2 +-
+ .../Library/PciExpressLib/PciExpressLib.c | 1570 +++++++++++++++++
+ .../Library/PciExpressLib/PciExpressLib.inf | 48 +
+ .../Library/PciExpressLib/PciExpressLib.uni | 17 +
+ Platform/ARM/N1SdpPkg/N1SdpPlatform.dsc | 2 +-
4 files changed, 1636 insertions(+), 1 deletion(-)
create mode 100644 Platform/ARM/N1SdpPkg/Library/PciExpressLib/PciExpressLib.c
create mode 100644 Platform/ARM/N1SdpPkg/Library/PciExpressLib/PciExpressLib.inf
@@ -23,1670 +23,1670 @@ Signed-off-by: Deepak Pandey <Deepak.Pandey@arm.com>
diff --git a/Platform/ARM/N1SdpPkg/Library/PciExpressLib/PciExpressLib.c b/Platform/ARM/N1SdpPkg/Library/PciExpressLib/PciExpressLib.c
new file mode 100644
-index 0000000..30c4538
+index 00000000..f3eaae63
--- /dev/null
+++ b/Platform/ARM/N1SdpPkg/Library/PciExpressLib/PciExpressLib.c
@@ -0,0 +1,1570 @@
-+/** @file
-+ Functions in this library instance make use of MMIO functions in IoLib to
-+ access memory mapped PCI configuration space.
-+
-+ All assertions for I/O operations are handled in MMIO functions in the IoLib
-+ Library.
-+
-+ Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
-+
-+ SPDX-License-Identifier: BSD-2-Clause-Patent
-+
-+**/
-+
-+
-+#include <Base.h>
-+
-+#include <Library/BaseLib.h>
-+#include <Library/PciExpressLib.h>
-+#include <Library/IoLib.h>
-+#include <Library/DebugLib.h>
-+#include <Library/PcdLib.h>
-+#include <N1SdpPlatform.h>
-+
-+
-+/**
-+ Assert the validity of a PCI address. A valid PCI address should contain 1's
-+ only in the low 32 bits.
-+
-+ @param A The address to validate.
-+
-+**/
-+#define ASSERT_INVALID_PCI_ADDRESS(A) \
-+ ASSERT (((A) & ~0xffffffff) == 0)
-+
-+#define EFI_PCIE_ADDRESS(bus, dev, func, reg) \
-+ (UINT64) ( \
-+ (((UINTN) bus) << 20) | \
-+ (((UINTN) dev) << 15) | \
-+ (((UINTN) func) << 12) | \
-+ (((UINTN) (reg)) < 4096 ? ((UINTN) (reg)) : (UINT64) (LShiftU64 ((UINT64) (reg), 32))))
-+
-+#define GET_PCIE_BASE_ADDRESS(Address) (Address & 0xF8000000)
-+
-+/* Root port Entry,BDF Entries Count */
-+#define BDF_TABLE_ENTRY_SIZE 4
-+#define BDF_TABLE_HEADER_COUNT 2
-+
-+/* BDF table offsets for PCIe & Ccix Controllers */
-+#define PCIE_BDF_TABLE_OFFSET 0
-+#define CCIX_BDF_TABLE_OFFSET (16 * 1024)
-+
-+#define GET_BUS_NUM(Address) ((Address>>20) & 0x7f)
-+#define GET_DEV_NUM(Address) ((Address>>15) & 0x1f)
-+#define GET_FUNC_NUM(Address) ((Address>>12) & 0x07)
-+#define GET_REG_NUM(Address) ((Address) & 0xFFF)
-+
-+/**
-+ BDF Table structure : (Header + BDF Entries)
-+ -------------------
-+ ROOT PORT ADDRESS
-+ BDF ENTRIES COUNT
-+ BDF ENTRY 0
-+ BDF ENTRY 1
-+ BDF ENTRY 2
-+ BDF ENTRY 3
-+ BDF ENTRY 4...
-+ ------------------
-+**/
-+
-+
-+UINTN DummyPciData = 0xffffffff;
-+
-+/**
-+ Registers a PCI device so PCI configuration registers may be accessed after
-+ SetVirtualAddressMap().
-+
-+ Registers the PCI device specified by Address so all the PCI configuration
-+ registers associated with that PCI device may be accessed after SetVirtualAddressMap()
-+ is called.
-+
-+ If Address > 0x0FFFFFFF, then ASSERT().
-+
-+ @param Address The address that encodes the PCI Bus, Device, Function and
-+ Register.
-+
-+ @retval RETURN_SUCCESS The PCI device was registered for runtime access.
-+ @retval RETURN_UNSUPPORTED An attempt was made to call this function
-+ after ExitBootServices().
-+ @retval RETURN_UNSUPPORTED The resources required to access the PCI device
-+ at runtime could not be mapped.
-+ @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
-+ complete the registration.
-+
-+**/
-+RETURN_STATUS
-+EFIAPI
-+PciExpressRegisterForRuntimeAccess (
-+ IN UINTN Address
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return RETURN_UNSUPPORTED;
-+}
-+
-+/**
-+ Checks if the incoming PCI address is a valid BDF address.
-+
-+ SCP performs the initial bus scan and prepares a table of valid BDF addresses
-+ and shares them through non-trusted SRAM. This function validates if the PCI
-+ address from any PCI request falls within the table of valid entries. If not,
-+ this function will return 0xFFFFFFFF. This is a workaround to avoid bus fault
-+ that happens when accessing unavailable PCI device due to RTL bug.
-+
-+ @return The base address of PCI Express.
-+
-+**/
-+UINTN
-+CheckBdfValidity (
-+ IN UINTN Address
-+ )
-+{
-+ UINT8 Bus, Device, Function;
-+ UINTN BdfCount, BdfValue;
-+ UINTN Count;
-+ UINTN TableBase;
-+ UINTN PciAddress;
-+
-+ Bus = GET_BUS_NUM(Address);
-+ Device = GET_DEV_NUM(Address);
-+ Function = GET_FUNC_NUM(Address);
-+
-+ PciAddress = EFI_PCIE_ADDRESS(Bus, Device, Function, 0);
-+
-+ if (GET_PCIE_BASE_ADDRESS(Address) == FixedPcdGet32(PcdPcieExpressBaseAddress)) {
-+ TableBase = N1SDP_NON_SECURE_SRAM_BASE + PCIE_BDF_TABLE_OFFSET;
-+ } else {
-+ TableBase = N1SDP_NON_SECURE_SRAM_BASE + CCIX_BDF_TABLE_OFFSET;
-+ }
-+
-+ BdfCount = MmioRead32(TableBase + BDF_TABLE_ENTRY_SIZE);
-+
-+ /* Start from the second entry */
-+ for (Count = BDF_TABLE_HEADER_COUNT; Count < (BdfCount + BDF_TABLE_HEADER_COUNT); Count++) {
-+ BdfValue = MmioRead32(TableBase + (Count * BDF_TABLE_ENTRY_SIZE));
-+ if (BdfValue == PciAddress)
-+ break;
-+ }
-+
-+ if (Count == (BdfCount + BDF_TABLE_HEADER_COUNT))
-+ return DummyPciData;
-+ else
-+ return PciAddress;
-+}
-+
-+/**
-+ Gets the base address of PCI Express.
-+
-+ This internal functions retrieves PCI Express Base Address via a PCD entry.
-+
-+ @return The base address of PCI Express.
-+
-+**/
-+VOID*
-+GetPciExpressAddress (
-+ IN UINTN Address
-+ )
-+{
-+
-+ UINT8 Bus, Device, Function;
-+ UINT16 Register;
-+ UINTN ConvAddress;
-+
-+ // Get the EFI notation
-+ Bus = GET_BUS_NUM(Address);
-+ Device = GET_DEV_NUM(Address);
-+ Function = GET_FUNC_NUM(Address);
-+ Register = GET_REG_NUM(Address);
-+
-+ ConvAddress = (UINTN) ((GET_PCIE_BASE_ADDRESS(Address) == FixedPcdGet32(PcdPcieExpressBaseAddress)) ?
-+ (((Bus == 0) && (Device == 0) && (Function == 0)) ?
-+ PcdGet32(PcdPcieRootPortConfigBaseAddress + EFI_PCIE_ADDRESS(Bus, Device, Function, Register)):
-+ PcdGet32(PcdPcieExpressBaseAddress + EFI_PCIE_ADDRESS(Bus, Device, Function, Register))) :
-+ (((Bus == 0) && (Device == 0) && (Function == 0)) ?
-+ PcdGet32(PcdCcixRootPortConfigBaseAddress + EFI_PCIE_ADDRESS(Bus, Device, Function, Register)):
-+ PcdGet32(PcdCcixExpressBaseAddress + EFI_PCIE_ADDRESS(Bus, Device, Function, Register))));
-+
-+ if (!((Bus == 0) && (Device == 0) && (Function == 0))) {
-+ if (CheckBdfValidity(Address) == DummyPciData)
-+ ConvAddress = (UINTN) &DummyPciData;
-+ }
-+
-+ return (VOID*)ConvAddress;
-+}
-+
-+/**
-+ 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, Function and
-+ Register.
-+
-+ @return The read value from the PCI configuration register.
-+
-+**/
-+UINT8
-+EFIAPI
-+PciExpressRead8 (
-+ IN UINTN Address
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioRead8 ((UINTN) GetPciExpressAddress (Address));
-+}
-+
-+/**
-+ Writes an 8-bit PCI configuration register.
-+
-+ Writes the 8-bit PCI configuration register specified by Address with the
-+ value specified by Value. Value is returned. This function must guarantee
-+ that all PCI read and write operations are serialized.
-+
-+ If Address > 0x0FFFFFFF, then ASSERT().
-+
-+ @param Address The address that encodes the PCI Bus, Device, Function 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
-+ )
-+{
-+ UINT32 Data;
-+ UINT8 Offset;
-+ UINT8 Bus;
-+ UINT8 Device;
-+ UINT8 Function;
-+
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+
-+ // Get the EFI notation
-+ Bus = GET_BUS_NUM(Address);
-+ Device = GET_DEV_NUM(Address);
-+ Function = GET_FUNC_NUM(Address);
-+
-+ if( (Bus == 0) && (Device == 0) && (Function == 0) ) {
-+ Data = MmioRead32((UINTN) GetPciExpressAddress (Address & 0xFFFFFFFC));
-+ Offset = Address & 0x3;
-+ Data |= (Value << (8 * Offset));
-+ MmioWrite32 ((UINTN) GetPciExpressAddress (Address & 0xFFFFFFFC), Data);
-+ } else {
-+ MmioWrite8 ((UINTN) GetPciExpressAddress (Address), Value);
-+ }
-+ return Value;
-+}
-+
-+/**
-+ Performs a bitwise OR of an 8-bit PCI configuration register with
-+ an 8-bit value.
-+
-+ Reads the 8-bit PCI configuration register specified by Address, performs a
-+ bitwise OR between the read result and the value specified by
-+ OrData, and writes the result to the 8-bit PCI configuration register
-+ specified by Address. The value written to the PCI configuration register is
-+ returned. This function must guarantee that all PCI read and write operations
-+ are serialized.
-+
-+ If Address > 0x0FFFFFFF, then ASSERT().
-+
-+ @param Address The address that encodes the PCI Bus, Device, Function and
-+ Register.
-+ @param OrData The value to OR with the PCI configuration register.
-+
-+ @return The value written back to the PCI configuration register.
-+
-+**/
-+UINT8
-+EFIAPI
-+PciExpressOr8 (
-+ IN UINTN Address,
-+ IN UINT8 OrData
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioOr8 ((UINTN) GetPciExpressAddress (Address), OrData);
-+}
-+
-+/**
-+ Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
-+ value.
-+
-+ Reads the 8-bit PCI configuration register specified by Address, performs a
-+ bitwise AND between the read result and the value specified by AndData, and
-+ writes the result to the 8-bit PCI configuration register specified by
-+ Address. The value written to the PCI configuration register is returned.
-+ This function must guarantee that all PCI read and write operations are
-+ serialized.
-+
-+ If Address > 0x0FFFFFFF, then ASSERT().
-+
-+ @param Address The address that encodes the PCI Bus, Device, Function 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);
-+ return MmioAnd8 ((UINTN) GetPciExpressAddress (Address), AndData);
-+}
-+
-+/**
-+ Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
-+ value, followed a bitwise OR with another 8-bit value.
-+
-+ Reads the 8-bit PCI configuration register specified by Address, performs a
-+ bitwise AND between the read result and the value specified by AndData,
-+ performs a bitwise OR between the result of the AND operation and
-+ the value specified by OrData, and writes the result to the 8-bit PCI
-+ configuration register specified by Address. The value written to the PCI
-+ configuration register is returned. This function must guarantee that all PCI
-+ read and write operations are serialized.
-+
-+ If Address > 0x0FFFFFFF, then ASSERT().
-+
-+ @param Address The address that encodes the PCI Bus, Device, Function 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);
-+ return MmioAndThenOr8 (
-+ (UINTN) GetPciExpressAddress (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 bit field.
-+ Range 0..7.
-+ @param EndBit The ordinal of the most significant bit in the bit field.
-+ Range 0..7.
-+
-+ @return The value of the bit field read from the PCI configuration register.
-+
-+**/
-+UINT8
-+EFIAPI
-+PciExpressBitFieldRead8 (
-+ IN UINTN Address,
-+ IN UINTN StartBit,
-+ IN UINTN EndBit
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioBitFieldRead8 (
-+ (UINTN) GetPciExpressAddress (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 StartBit and EndBit, then ASSERT().
-+
-+ @param Address The PCI configuration register to write.
-+ @param StartBit The ordinal of the least significant bit in the bit field.
-+ Range 0..7.
-+ @param EndBit The ordinal of the most significant bit in the bit field.
-+ Range 0..7.
-+ @param Value The new value of the bit field.
-+
-+ @return The value written back to the PCI configuration register.
-+
-+**/
-+UINT8
-+EFIAPI
-+PciExpressBitFieldWrite8 (
-+ IN UINTN Address,
-+ IN UINTN StartBit,
-+ IN UINTN EndBit,
-+ IN UINT8 Value
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioBitFieldWrite8 (
-+ (UINTN) GetPciExpressAddress (Address),
-+ StartBit,
-+ EndBit,
-+ Value
-+ );
-+}
-+
-+/**
-+ Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
-+ writes the result back to the bit field in the 8-bit port.
-+
-+ Reads the 8-bit PCI configuration register specified by Address, performs a
-+ bitwise OR between the read result and the value specified by
-+ OrData, and writes the result to the 8-bit PCI configuration register
-+ specified by Address. The value written to the PCI configuration register is
-+ returned. This function must guarantee that all PCI read and write operations
-+ are serialized. Extra left bits in OrData are stripped.
-+
-+ If 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 StartBit and EndBit, then ASSERT().
-+
-+ @param Address The PCI configuration register to write.
-+ @param StartBit The ordinal of the least significant bit in the bit field.
-+ Range 0..7.
-+ @param EndBit The ordinal of the most significant bit in the bit field.
-+ Range 0..7.
-+ @param OrData The value to OR with the PCI configuration register.
-+
-+ @return The value written back to the PCI configuration register.
-+
-+**/
-+UINT8
-+EFIAPI
-+PciExpressBitFieldOr8 (
-+ IN UINTN Address,
-+ IN UINTN StartBit,
-+ IN UINTN EndBit,
-+ IN UINT8 OrData
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioBitFieldOr8 (
-+ (UINTN) GetPciExpressAddress (Address),
-+ StartBit,
-+ EndBit,
-+ OrData
-+ );
-+}
-+
-+/**
-+ Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
-+ AND, and writes the result back to the bit field in the 8-bit register.
-+
-+ Reads the 8-bit PCI configuration register specified by Address, performs a
-+ bitwise AND between the read result and the value specified by AndData, and
-+ writes the result to the 8-bit PCI configuration register specified by
-+ Address. The value written to the PCI configuration register is returned.
-+ This function must guarantee that all PCI read and write operations are
-+ serialized. Extra left bits in AndData are stripped.
-+
-+ If 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 StartBit and EndBit, then ASSERT().
-+
-+ @param Address The PCI configuration register to write.
-+ @param StartBit The ordinal of the least significant bit in the bit field.
-+ Range 0..7.
-+ @param EndBit The ordinal of the most significant bit in the bit field.
-+ Range 0..7.
-+ @param AndData The value to AND with the PCI configuration register.
-+
-+ @return The value written back to the PCI configuration register.
-+
-+**/
-+UINT8
-+EFIAPI
-+PciExpressBitFieldAnd8 (
-+ IN UINTN Address,
-+ IN UINTN StartBit,
-+ IN UINTN EndBit,
-+ IN UINT8 AndData
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioBitFieldAnd8 (
-+ (UINTN) GetPciExpressAddress (Address),
-+ StartBit,
-+ EndBit,
-+ AndData
-+ );
-+}
-+
-+/**
-+ Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
-+ bitwise OR, and writes the result back to the bit field in the
-+ 8-bit port.
-+
-+ Reads the 8-bit PCI configuration register specified by Address, performs a
-+ bitwise AND followed by a bitwise OR between the read result and
-+ the value specified by AndData, and writes the result to the 8-bit PCI
-+ configuration register specified by Address. The value written to the PCI
-+ configuration register is returned. This function must guarantee that all PCI
-+ read and write operations are serialized. Extra left bits in both AndData and
-+ OrData are stripped.
-+
-+ If 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 StartBit and EndBit, then ASSERT().
-+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
-+
-+ @param Address The PCI configuration register to write.
-+ @param StartBit The ordinal of the least significant bit in the bit field.
-+ Range 0..7.
-+ @param EndBit The ordinal of the most significant bit in the bit field.
-+ Range 0..7.
-+ @param AndData The value to AND with the PCI configuration register.
-+ @param OrData The value to OR with the result of the AND operation.
-+
-+ @return The value written back to the PCI configuration register.
-+
-+**/
-+UINT8
-+EFIAPI
-+PciExpressBitFieldAndThenOr8 (
-+ IN UINTN Address,
-+ IN UINTN StartBit,
-+ IN UINTN EndBit,
-+ IN UINT8 AndData,
-+ IN UINT8 OrData
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioBitFieldAndThenOr8 (
-+ (UINTN) GetPciExpressAddress (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, Function and
-+ Register.
-+
-+ @return The read value from the PCI configuration register.
-+
-+**/
-+UINT16
-+EFIAPI
-+PciExpressRead16 (
-+ IN UINTN Address
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioRead16 ((UINTN) GetPciExpressAddress (Address));
-+}
-+
-+/**
-+ Writes a 16-bit PCI configuration register.
-+
-+ Writes the 16-bit PCI configuration register specified by Address with the
-+ value specified by Value. Value is returned. This function must guarantee
-+ that all PCI read and write operations are serialized.
-+
-+ If 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, Function 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
-+ )
-+{
-+ UINT32 Data;
-+ UINT8 Offset;
-+ UINT8 Bus;
-+ UINT8 Device;
-+ UINT8 Function;
-+
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+
-+ // Get the EFI notation
-+ Bus = GET_BUS_NUM(Address);
-+ Device = GET_DEV_NUM(Address);
-+ Function = GET_FUNC_NUM(Address);
-+
-+ if( (Bus == 0) && (Device == 0) && (Function == 0) ) {
-+ Data = MmioRead32((UINTN) GetPciExpressAddress (Address & 0xFFFFFFFC));
-+ Offset = Address & 0x3;
-+ Data |= (Value << (8 * Offset));
-+ MmioWrite32 ((UINTN) GetPciExpressAddress (Address & 0xFFFFFFFC), Data);
-+ } else {
-+ MmioWrite16 ((UINTN) GetPciExpressAddress (Address), Value);
-+ }
-+ return Value;
-+}
-+
-+/**
-+ Performs a bitwise OR of a 16-bit PCI configuration register with
-+ a 16-bit value.
-+
-+ Reads the 16-bit PCI configuration register specified by Address, performs a
-+ bitwise OR between the read result and the value specified by
-+ OrData, and writes the result to the 16-bit PCI configuration register
-+ specified by Address. The value written to the PCI configuration register is
-+ returned. This function must guarantee that all PCI read and write operations
-+ are serialized.
-+
-+ If 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, Function and
-+ Register.
-+ @param OrData The value to OR with the PCI configuration register.
-+
-+ @return The value written back to the PCI configuration register.
-+
-+**/
-+UINT16
-+EFIAPI
-+PciExpressOr16 (
-+ IN UINTN Address,
-+ IN UINT16 OrData
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioOr16 ((UINTN) GetPciExpressAddress (Address), OrData);
-+}
-+
-+/**
-+ Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
-+ value.
-+
-+ Reads the 16-bit PCI configuration register specified by Address, performs a
-+ bitwise AND between the read result and the value specified by AndData, and
-+ writes the result to the 16-bit PCI configuration register specified by
-+ Address. The value written to the PCI configuration register is returned.
-+ This function must guarantee that all PCI read and write operations are
-+ serialized.
-+
-+ If 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, Function 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);
-+ return MmioAnd16 ((UINTN) GetPciExpressAddress (Address), AndData);
-+}
-+
-+/**
-+ Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
-+ value, followed a bitwise OR with another 16-bit value.
-+
-+ Reads the 16-bit PCI configuration register specified by Address, performs a
-+ bitwise AND between the read result and the value specified by AndData,
-+ performs a bitwise OR between the result of the AND operation and
-+ the value specified by OrData, and writes the result to the 16-bit PCI
-+ configuration register specified by Address. The value written to the PCI
-+ configuration register is returned. This function must guarantee that all PCI
-+ read and write operations are serialized.
-+
-+ If 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, Function 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);
-+ return MmioAndThenOr16 (
-+ (UINTN) GetPciExpressAddress (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 bit field.
-+ Range 0..15.
-+ @param EndBit The ordinal of the most significant bit in the bit field.
-+ Range 0..15.
-+
-+ @return The value of the bit field read from the PCI configuration register.
-+
-+**/
-+UINT16
-+EFIAPI
-+PciExpressBitFieldRead16 (
-+ IN UINTN Address,
-+ IN UINTN StartBit,
-+ IN UINTN EndBit
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioBitFieldRead16 (
-+ (UINTN) GetPciExpressAddress (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 StartBit and EndBit, then ASSERT().
-+
-+ @param Address The PCI configuration register to write.
-+ @param StartBit The ordinal of the least significant bit in the bit field.
-+ Range 0..15.
-+ @param EndBit The ordinal of the most significant bit in the bit field.
-+ Range 0..15.
-+ @param Value The new value of the bit field.
-+
-+ @return The value written back to the PCI configuration register.
-+
-+**/
-+UINT16
-+EFIAPI
-+PciExpressBitFieldWrite16 (
-+ IN UINTN Address,
-+ IN UINTN StartBit,
-+ IN UINTN EndBit,
-+ IN UINT16 Value
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioBitFieldWrite16 (
-+ (UINTN) GetPciExpressAddress (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, performs a
-+ bitwise OR between the read result and the value specified by
-+ OrData, and writes the result to the 16-bit PCI configuration register
-+ specified by Address. The value written to the PCI configuration register is
-+ returned. This function must guarantee that all PCI read and write operations
-+ are serialized. Extra left bits in OrData are stripped.
-+
-+ If 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 StartBit and EndBit, then ASSERT().
-+
-+ @param Address The PCI configuration register to write.
-+ @param StartBit The ordinal of the least significant bit in the bit field.
-+ Range 0..15.
-+ @param EndBit The ordinal of the most significant bit in the bit field.
-+ Range 0..15.
-+ @param OrData The value to OR with the PCI configuration register.
-+
-+ @return The value written back to the PCI configuration register.
-+
-+**/
-+UINT16
-+EFIAPI
-+PciExpressBitFieldOr16 (
-+ IN UINTN Address,
-+ IN UINTN StartBit,
-+ IN UINTN EndBit,
-+ IN UINT16 OrData
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioBitFieldOr16 (
-+ (UINTN) GetPciExpressAddress (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 register.
-+
-+ Reads the 16-bit PCI configuration register specified by Address, performs a
-+ bitwise AND between the read result and the value specified by AndData, and
-+ writes the result to the 16-bit PCI configuration register specified by
-+ Address. The value written to the PCI configuration register is returned.
-+ This function must guarantee that all PCI read and write operations are
-+ serialized. Extra left bits in AndData are stripped.
-+
-+ If 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 StartBit and EndBit, then ASSERT().
-+
-+ @param Address The PCI configuration register to write.
-+ @param StartBit The ordinal of the least significant bit in the bit field.
-+ Range 0..15.
-+ @param EndBit The ordinal of the most significant bit in the bit field.
-+ Range 0..15.
-+ @param AndData The value to AND with the PCI configuration register.
-+
-+ @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);
-+ return MmioBitFieldAnd16 (
-+ (UINTN) GetPciExpressAddress (Address),
-+ StartBit,
-+ EndBit,
-+ AndData
-+ );
-+}
-+
-+/**
-+ Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
-+ bitwise OR, and writes the result back to the bit field in the
-+ 16-bit port.
-+
-+ Reads the 16-bit PCI configuration register specified by Address, performs a
-+ bitwise AND followed by a bitwise OR between the read result and
-+ the value specified by AndData, and writes the result to the 16-bit PCI
-+ configuration register specified by Address. The value written to the PCI
-+ configuration register is returned. This function must guarantee that all PCI
-+ read and write operations are serialized. Extra left bits in both AndData and
-+ OrData are stripped.
-+
-+ If 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 StartBit and EndBit, then ASSERT().
-+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
-+
-+ @param Address The PCI configuration register to write.
-+ @param StartBit The ordinal of the least significant bit in the bit field.
-+ Range 0..15.
-+ @param EndBit The ordinal of the most significant bit in the bit field.
-+ Range 0..15.
-+ @param AndData The value to AND with the PCI configuration register.
-+ @param OrData The value to OR with the result of the AND operation.
-+
-+ @return The value written back to the PCI configuration register.
-+
-+**/
-+UINT16
-+EFIAPI
-+PciExpressBitFieldAndThenOr16 (
-+ IN UINTN Address,
-+ IN UINTN StartBit,
-+ IN UINTN EndBit,
-+ IN UINT16 AndData,
-+ IN UINT16 OrData
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioBitFieldAndThenOr16 (
-+ (UINTN) GetPciExpressAddress (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, Function and
-+ Register.
-+
-+ @return The read value from the PCI configuration register.
-+
-+**/
-+UINT32
-+EFIAPI
-+PciExpressRead32 (
-+ IN UINTN Address
-+ )
-+{
-+ UINTN address;
-+ UINT32 value;
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ address = (UINTN) GetPciExpressAddress (Address);
-+ value = MmioRead32 (address);
-+ return value;
-+}
-+
-+/**
-+ Writes a 32-bit PCI configuration register.
-+
-+ Writes the 32-bit PCI configuration register specified by Address with the
-+ value specified by Value. Value is returned. This function must guarantee
-+ that all PCI read and write operations are serialized.
-+
-+ If 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, Function 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);
-+ return MmioWrite32 ((UINTN) GetPciExpressAddress (Address), Value);
-+}
-+
-+/**
-+ Performs a bitwise OR of a 32-bit PCI configuration register with
-+ a 32-bit value.
-+
-+ Reads the 32-bit PCI configuration register specified by Address, performs a
-+ bitwise OR between the read result and the value specified by
-+ OrData, and writes the result to the 32-bit PCI configuration register
-+ specified by Address. The value written to the PCI configuration register is
-+ returned. This function must guarantee that all PCI read and write operations
-+ are serialized.
-+
-+ If 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, Function 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);
-+ return MmioOr32 ((UINTN) GetPciExpressAddress (Address), OrData);
-+}
-+
-+/**
-+ Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
-+ value.
-+
-+ Reads the 32-bit PCI configuration register specified by Address, performs a
-+ bitwise AND between the read result and the value specified by AndData, and
-+ writes the result to the 32-bit PCI configuration register specified by
-+ Address. The value written to the PCI configuration register is returned.
-+ This function must guarantee that all PCI read and write operations are
-+ serialized.
-+
-+ If 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, Function 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);
-+ return MmioAnd32 ((UINTN) GetPciExpressAddress (Address), AndData);
-+}
-+
-+/**
-+ Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
-+ value, followed a bitwise OR with another 32-bit value.
-+
-+ Reads the 32-bit PCI configuration register specified by Address, performs a
-+ bitwise AND between the read result and the value specified by AndData,
-+ performs a bitwise OR between the result of the AND operation and
-+ the value specified by OrData, and writes the result to the 32-bit PCI
-+ configuration register specified by Address. The value written to the PCI
-+ configuration register is returned. This function must guarantee that all PCI
-+ read and write operations are serialized.
-+
-+ If 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, Function 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);
-+ return MmioAndThenOr32 (
-+ (UINTN) GetPciExpressAddress (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 bit field.
-+ Range 0..31.
-+ @param EndBit The ordinal of the most significant bit in the bit field.
-+ Range 0..31.
-+
-+ @return The value of the bit field read from the PCI configuration register.
-+
-+**/
-+UINT32
-+EFIAPI
-+PciExpressBitFieldRead32 (
-+ IN UINTN Address,
-+ IN UINTN StartBit,
-+ IN UINTN EndBit
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioBitFieldRead32 (
-+ (UINTN) GetPciExpressAddress (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 StartBit and EndBit, then ASSERT().
-+
-+ @param Address The PCI configuration register to write.
-+ @param StartBit The ordinal of the least significant bit in the bit field.
-+ Range 0..31.
-+ @param EndBit The ordinal of the most significant bit in the bit field.
-+ Range 0..31.
-+ @param Value The new value of the bit field.
-+
-+ @return The value written back to the PCI configuration register.
-+
-+**/
-+UINT32
-+EFIAPI
-+PciExpressBitFieldWrite32 (
-+ IN UINTN Address,
-+ IN UINTN StartBit,
-+ IN UINTN EndBit,
-+ IN UINT32 Value
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioBitFieldWrite32 (
-+ (UINTN) GetPciExpressAddress (Address),
-+ StartBit,
-+ EndBit,
-+ Value
-+ );
-+}
-+
-+/**
-+ Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
-+ writes the result back to the bit field in the 32-bit port.
-+
-+ Reads the 32-bit PCI configuration register specified by Address, performs a
-+ bitwise OR between the read result and the value specified by
-+ OrData, and writes the result to the 32-bit PCI configuration register
-+ specified by Address. The value written to the PCI configuration register is
-+ returned. This function must guarantee that all PCI read and write operations
-+ are serialized. Extra left bits in OrData are stripped.
-+
-+ If 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 StartBit and EndBit, then ASSERT().
-+
-+ @param Address The PCI configuration register to write.
-+ @param StartBit The ordinal of the least significant bit in the bit field.
-+ Range 0..31.
-+ @param EndBit The ordinal of the most significant bit in the bit field.
-+ Range 0..31.
-+ @param OrData The value to OR with the PCI configuration register.
-+
-+ @return The value written back to the PCI configuration register.
-+
-+**/
-+UINT32
-+EFIAPI
-+PciExpressBitFieldOr32 (
-+ IN UINTN Address,
-+ IN UINTN StartBit,
-+ IN UINTN EndBit,
-+ IN UINT32 OrData
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioBitFieldOr32 (
-+ (UINTN) GetPciExpressAddress (Address),
-+ StartBit,
-+ EndBit,
-+ OrData
-+ );
-+}
-+
-+/**
-+ Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
-+ AND, and writes the result back to the bit field in the 32-bit register.
-+
-+ Reads the 32-bit PCI configuration register specified by Address, performs a
-+ bitwise AND between the read result and the value specified by AndData, and
-+ writes the result to the 32-bit PCI configuration register specified by
-+ Address. The value written to the PCI configuration register is returned.
-+ This function must guarantee that all PCI read and write operations are
-+ serialized. Extra left bits in AndData are stripped.
-+
-+ If 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 StartBit and EndBit, then ASSERT().
-+
-+ @param Address The PCI configuration register to write.
-+ @param StartBit The ordinal of the least significant bit in the bit field.
-+ Range 0..31.
-+ @param EndBit The ordinal of the most significant bit in the bit field.
-+ Range 0..31.
-+ @param AndData The value to AND with the PCI configuration register.
-+
-+ @return The value written back to the PCI configuration register.
-+
-+**/
-+UINT32
-+EFIAPI
-+PciExpressBitFieldAnd32 (
-+ IN UINTN Address,
-+ IN UINTN StartBit,
-+ IN UINTN EndBit,
-+ IN UINT32 AndData
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioBitFieldAnd32 (
-+ (UINTN) GetPciExpressAddress (Address),
-+ StartBit,
-+ EndBit,
-+ AndData
-+ );
-+}
-+
-+/**
-+ Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
-+ bitwise OR, and writes the result back to the bit field in the
-+ 32-bit port.
-+
-+ Reads the 32-bit PCI configuration register specified by Address, performs a
-+ bitwise AND followed by a bitwise OR between the read result and
-+ the value specified by AndData, and writes the result to the 32-bit PCI
-+ configuration register specified by Address. The value written to the PCI
-+ configuration register is returned. This function must guarantee that all PCI
-+ read and write operations are serialized. Extra left bits in both AndData and
-+ OrData are stripped.
-+
-+ If 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 StartBit and EndBit, then ASSERT().
-+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
-+
-+ @param Address The PCI configuration register to write.
-+ @param StartBit The ordinal of the least significant bit in the bit field.
-+ Range 0..31.
-+ @param EndBit The ordinal of the most significant bit in the bit field.
-+ Range 0..31.
-+ @param AndData The value to AND with the PCI configuration register.
-+ @param OrData The value to OR with the result of the AND operation.
-+
-+ @return The value written back to the PCI configuration register.
-+
-+**/
-+UINT32
-+EFIAPI
-+PciExpressBitFieldAndThenOr32 (
-+ IN UINTN Address,
-+ IN UINTN StartBit,
-+ IN UINTN EndBit,
-+ IN UINT32 AndData,
-+ IN UINT32 OrData
-+ )
-+{
-+ ASSERT_INVALID_PCI_ADDRESS (Address);
-+ return MmioBitFieldAndThenOr32 (
-+ (UINTN) GetPciExpressAddress (Address),
-+ StartBit,
-+ EndBit,
-+ AndData,
-+ OrData
-+ );
-+}
-+
-+/**
-+ Reads a range of PCI configuration registers into a caller supplied buffer.
-+
-+ Reads the range of PCI configuration registers specified by StartAddress and
-+ Size into the buffer specified by Buffer. This function only allows the PCI
-+ configuration registers from a single PCI function to be read. Size is
-+ returned. When possible 32-bit PCI configuration read cycles are used to read
-+ from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
-+ and 16-bit PCI configuration read cycles may be used at the beginning and the
-+ end of the range.
-+
-+ If 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 read.
-+
-+ @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) <= 0x1000);
-+
-+ if (Size == 0) {
-+ return Size;
-+ }
-+
-+ ASSERT (Buffer != NULL);
-+
-+ //
-+ // Save Size for return
-+ //
-+ ReturnValue = Size;
-+
-+ if ((StartAddress & 1) != 0) {
-+ //
-+ // Read a byte if StartAddress is byte aligned
-+ //
-+ *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);
-+ StartAddress += sizeof (UINT8);
-+ Size -= sizeof (UINT8);
-+ Buffer = (UINT8*)Buffer + 1;
-+ }
-+
-+ if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
-+ //
-+ // Read a word if StartAddress is word aligned
-+ //
-+ WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress));
-+
-+ StartAddress += sizeof (UINT16);
-+ Size -= sizeof (UINT16);
-+ Buffer = (UINT16*)Buffer + 1;
-+ }
-+
-+ while (Size >= sizeof (UINT32)) {
-+ //
-+ // Read as many double words as possible
-+ //
-+ WriteUnaligned32 ((UINT32 *) Buffer, (UINT32) PciExpressRead32 (StartAddress));
-+
-+ StartAddress += sizeof (UINT32);
-+ Size -= sizeof (UINT32);
-+ Buffer = (UINT32*)Buffer + 1;
-+ }
-+
-+ if (Size >= sizeof (UINT16)) {
-+ //
-+ // Read the last remaining word if exist
-+ //
-+ WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress));
-+ StartAddress += sizeof (UINT16);
-+ Size -= sizeof (UINT16);
-+ Buffer = (UINT16*)Buffer + 1;
-+ }
-+
-+ if (Size >= sizeof (UINT8)) {
-+ //
-+ // Read the last remaining byte if exist
-+ //
-+ *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);
-+ }
-+
-+ return ReturnValue;
-+}
-+
-+/**
-+ Copies the data in a caller supplied buffer to a specified range of PCI
-+ configuration space.
-+
-+ Writes the range of PCI configuration registers specified by StartAddress and
-+ Size from the buffer specified by Buffer. This function only allows the PCI
-+ configuration registers from a single PCI function to be written. Size is
-+ returned. When possible 32-bit PCI configuration write cycles are used to
-+ write from StartAdress to StartAddress + Size. Due to alignment restrictions,
-+ 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
-+ and the end of the range.
-+
-+ If 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) <= 0x1000);
-+
-+ if (Size == 0) {
-+ return 0;
-+ }
-+
-+ ASSERT (Buffer != NULL);
-+
-+ //
-+ // Save Size for return
-+ //
-+ ReturnValue = Size;
-+
-+ if ((StartAddress & 1) != 0) {
-+ //
-+ // Write a byte if StartAddress is byte aligned
-+ //
-+ PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);
-+ StartAddress += sizeof (UINT8);
-+ Size -= sizeof (UINT8);
-+ Buffer = (UINT8*)Buffer + 1;
-+ }
-+
-+ if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
-+ //
-+ // Write a word if StartAddress is word aligned
-+ //
-+ PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));
-+ StartAddress += sizeof (UINT16);
-+ Size -= sizeof (UINT16);
-+ Buffer = (UINT16*)Buffer + 1;
-+ }
-+
-+ while (Size >= sizeof (UINT32)) {
-+ //
-+ // Write as many double words as possible
-+ //
-+ PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer));
-+ StartAddress += sizeof (UINT32);
-+ Size -= sizeof (UINT32);
-+ Buffer = (UINT32*)Buffer + 1;
-+ }
-+
-+ if (Size >= sizeof (UINT16)) {
-+ //
-+ // Write the last remaining word if exist
-+ //
-+ PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));
-+ StartAddress += sizeof (UINT16);
-+ Size -= sizeof (UINT16);
-+ Buffer = (UINT16*)Buffer + 1;
-+ }
-+
-+ if (Size >= sizeof (UINT8)) {
-+ //
-+ // Write the last remaining byte if exist
-+ //
-+ PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);
-+ }
-+
-+ return ReturnValue;
-+}
++/** @file
++ Functions in this library instance make use of MMIO functions in IoLib to
++ access memory mapped PCI configuration space.
++
++ All assertions for I/O operations are handled in MMIO functions in the IoLib
++ Library.
++
++ Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
++
++ SPDX-License-Identifier: BSD-2-Clause-Patent
++
++**/
++
++
++#include <Base.h>
++
++#include <Library/BaseLib.h>
++#include <Library/PciExpressLib.h>
++#include <Library/IoLib.h>
++#include <Library/DebugLib.h>
++#include <Library/PcdLib.h>
++#include <N1SdpPlatform.h>
++
++
++/**
++ Assert the validity of a PCI address. A valid PCI address should contain 1's
++ only in the low 32 bits.
++
++ @param A The address to validate.
++
++**/
++#define ASSERT_INVALID_PCI_ADDRESS(A) \
++ ASSERT (((A) & ~0xffffffff) == 0)
++
++#define EFI_PCIE_ADDRESS(bus, dev, func, reg) \
++ (UINT64) ( \
++ (((UINTN) bus) << 20) | \
++ (((UINTN) dev) << 15) | \
++ (((UINTN) func) << 12) | \
++ (((UINTN) (reg)) < 4096 ? ((UINTN) (reg)) : (UINT64) (LShiftU64 ((UINT64) (reg), 32))))
++
++#define GET_PCIE_BASE_ADDRESS(Address) (Address & 0xF8000000)
++
++/* Root port Entry,BDF Entries Count */
++#define BDF_TABLE_ENTRY_SIZE 4
++#define BDF_TABLE_HEADER_COUNT 2
++
++/* BDF table offsets for PCIe & Ccix Controllers */
++#define PCIE_BDF_TABLE_OFFSET 0
++#define CCIX_BDF_TABLE_OFFSET (16 * 1024)
++
++#define GET_BUS_NUM(Address) ((Address>>20) & 0x7f)
++#define GET_DEV_NUM(Address) ((Address>>15) & 0x1f)
++#define GET_FUNC_NUM(Address) ((Address>>12) & 0x07)
++#define GET_REG_NUM(Address) ((Address) & 0xFFF)
++
++/**
++ BDF Table structure : (Header + BDF Entries)
++ -------------------
++ ROOT PORT ADDRESS
++ BDF ENTRIES COUNT
++ BDF ENTRY 0
++ BDF ENTRY 1
++ BDF ENTRY 2
++ BDF ENTRY 3
++ BDF ENTRY 4...
++ ------------------
++**/
++
++
++UINTN DummyPciData = 0xffffffff;
++
++/**
++ Registers a PCI device so PCI configuration registers may be accessed after
++ SetVirtualAddressMap().
++
++ Registers the PCI device specified by Address so all the PCI configuration
++ registers associated with that PCI device may be accessed after SetVirtualAddressMap()
++ is called.
++
++ If Address > 0x0FFFFFFF, then ASSERT().
++
++ @param Address The address that encodes the PCI Bus, Device, Function and
++ Register.
++
++ @retval RETURN_SUCCESS The PCI device was registered for runtime access.
++ @retval RETURN_UNSUPPORTED An attempt was made to call this function
++ after ExitBootServices().
++ @retval RETURN_UNSUPPORTED The resources required to access the PCI device
++ at runtime could not be mapped.
++ @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
++ complete the registration.
++
++**/
++RETURN_STATUS
++EFIAPI
++PciExpressRegisterForRuntimeAccess (
++ IN UINTN Address
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return RETURN_UNSUPPORTED;
++}
++
++/**
++ Checks if the incoming PCI address is a valid BDF address.
++
++ SCP performs the initial bus scan and prepares a table of valid BDF addresses
++ and shares them through non-trusted SRAM. This function validates if the PCI
++ address from any PCI request falls within the table of valid entries. If not,
++ this function will return 0xFFFFFFFF. This is a workaround to avoid bus fault
++ that happens when accessing unavailable PCI device due to RTL bug.
++
++ @return The base address of PCI Express.
++
++**/
++UINTN
++CheckBdfValidity (
++ IN UINTN Address
++ )
++{
++ UINT8 Bus, Device, Function;
++ UINTN BdfCount, BdfValue;
++ UINTN Count;
++ UINTN TableBase;
++ UINTN PciAddress;
++
++ Bus = GET_BUS_NUM(Address);
++ Device = GET_DEV_NUM(Address);
++ Function = GET_FUNC_NUM(Address);
++
++ PciAddress = EFI_PCIE_ADDRESS(Bus, Device, Function, 0);
++
++ if (GET_PCIE_BASE_ADDRESS(Address) == FixedPcdGet32(PcdPcieExpressBaseAddress)) {
++ TableBase = N1SDP_NON_SECURE_SRAM_BASE + PCIE_BDF_TABLE_OFFSET;
++ } else {
++ TableBase = N1SDP_NON_SECURE_SRAM_BASE + CCIX_BDF_TABLE_OFFSET;
++ }
++
++ BdfCount = MmioRead32(TableBase + BDF_TABLE_ENTRY_SIZE);
++
++ /* Start from the second entry */
++ for (Count = BDF_TABLE_HEADER_COUNT; Count < (BdfCount + BDF_TABLE_HEADER_COUNT); Count++) {
++ BdfValue = MmioRead32(TableBase + (Count * BDF_TABLE_ENTRY_SIZE));
++ if (BdfValue == PciAddress)
++ break;
++ }
++
++ if (Count == (BdfCount + BDF_TABLE_HEADER_COUNT))
++ return DummyPciData;
++ else
++ return PciAddress;
++}
++
++/**
++ Gets the base address of PCI Express.
++
++ This internal functions retrieves PCI Express Base Address via a PCD entry.
++
++ @return The base address of PCI Express.
++
++**/
++VOID*
++GetPciExpressAddress (
++ IN UINTN Address
++ )
++{
++
++ UINT8 Bus, Device, Function;
++ UINT16 Register;
++ UINTN ConvAddress;
++
++ // Get the EFI notation
++ Bus = GET_BUS_NUM(Address);
++ Device = GET_DEV_NUM(Address);
++ Function = GET_FUNC_NUM(Address);
++ Register = GET_REG_NUM(Address);
++
++ ConvAddress = (UINTN) ((GET_PCIE_BASE_ADDRESS(Address) == FixedPcdGet32(PcdPcieExpressBaseAddress)) ?
++ (((Bus == 0) && (Device == 0) && (Function == 0)) ?
++ PcdGet32(PcdPcieRootPortConfigBaseAddress + EFI_PCIE_ADDRESS(Bus, Device, Function, Register)):
++ PcdGet32(PcdPcieExpressBaseAddress + EFI_PCIE_ADDRESS(Bus, Device, Function, Register))) :
++ (((Bus == 0) && (Device == 0) && (Function == 0)) ?
++ PcdGet32(PcdCcixRootPortConfigBaseAddress + EFI_PCIE_ADDRESS(Bus, Device, Function, Register)):
++ PcdGet32(PcdCcixExpressBaseAddress + EFI_PCIE_ADDRESS(Bus, Device, Function, Register))));
++
++ if (!((Bus == 0) && (Device == 0) && (Function == 0))) {
++ if (CheckBdfValidity(Address) == DummyPciData)
++ ConvAddress = (UINTN) &DummyPciData;
++ }
++
++ return (VOID*)ConvAddress;
++}
++
++/**
++ 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, Function and
++ Register.
++
++ @return The read value from the PCI configuration register.
++
++**/
++UINT8
++EFIAPI
++PciExpressRead8 (
++ IN UINTN Address
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioRead8 ((UINTN) GetPciExpressAddress (Address));
++}
++
++/**
++ Writes an 8-bit PCI configuration register.
++
++ Writes the 8-bit PCI configuration register specified by Address with the
++ value specified by Value. Value is returned. This function must guarantee
++ that all PCI read and write operations are serialized.
++
++ If Address > 0x0FFFFFFF, then ASSERT().
++
++ @param Address The address that encodes the PCI Bus, Device, Function 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
++ )
++{
++ UINT32 Data;
++ UINT8 Offset;
++ UINT8 Bus;
++ UINT8 Device;
++ UINT8 Function;
++
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++
++ // Get the EFI notation
++ Bus = GET_BUS_NUM(Address);
++ Device = GET_DEV_NUM(Address);
++ Function = GET_FUNC_NUM(Address);
++
++ if( (Bus == 0) && (Device == 0) && (Function == 0) ) {
++ Data = MmioRead32((UINTN) GetPciExpressAddress (Address & 0xFFFFFFFC));
++ Offset = Address & 0x3;
++ Data |= (Value << (8 * Offset));
++ MmioWrite32 ((UINTN) GetPciExpressAddress (Address & 0xFFFFFFFC), Data);
++ } else {
++ MmioWrite8 ((UINTN) GetPciExpressAddress (Address), Value);
++ }
++ return Value;
++}
++
++/**
++ Performs a bitwise OR of an 8-bit PCI configuration register with
++ an 8-bit value.
++
++ Reads the 8-bit PCI configuration register specified by Address, performs a
++ bitwise OR between the read result and the value specified by
++ OrData, and writes the result to the 8-bit PCI configuration register
++ specified by Address. The value written to the PCI configuration register is
++ returned. This function must guarantee that all PCI read and write operations
++ are serialized.
++
++ If Address > 0x0FFFFFFF, then ASSERT().
++
++ @param Address The address that encodes the PCI Bus, Device, Function and
++ Register.
++ @param OrData The value to OR with the PCI configuration register.
++
++ @return The value written back to the PCI configuration register.
++
++**/
++UINT8
++EFIAPI
++PciExpressOr8 (
++ IN UINTN Address,
++ IN UINT8 OrData
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioOr8 ((UINTN) GetPciExpressAddress (Address), OrData);
++}
++
++/**
++ Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
++ value.
++
++ Reads the 8-bit PCI configuration register specified by Address, performs a
++ bitwise AND between the read result and the value specified by AndData, and
++ writes the result to the 8-bit PCI configuration register specified by
++ Address. The value written to the PCI configuration register is returned.
++ This function must guarantee that all PCI read and write operations are
++ serialized.
++
++ If Address > 0x0FFFFFFF, then ASSERT().
++
++ @param Address The address that encodes the PCI Bus, Device, Function 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);
++ return MmioAnd8 ((UINTN) GetPciExpressAddress (Address), AndData);
++}
++
++/**
++ Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
++ value, followed a bitwise OR with another 8-bit value.
++
++ Reads the 8-bit PCI configuration register specified by Address, performs a
++ bitwise AND between the read result and the value specified by AndData,
++ performs a bitwise OR between the result of the AND operation and
++ the value specified by OrData, and writes the result to the 8-bit PCI
++ configuration register specified by Address. The value written to the PCI
++ configuration register is returned. This function must guarantee that all PCI
++ read and write operations are serialized.
++
++ If Address > 0x0FFFFFFF, then ASSERT().
++
++ @param Address The address that encodes the PCI Bus, Device, Function 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);
++ return MmioAndThenOr8 (
++ (UINTN) GetPciExpressAddress (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 bit field.
++ Range 0..7.
++ @param EndBit The ordinal of the most significant bit in the bit field.
++ Range 0..7.
++
++ @return The value of the bit field read from the PCI configuration register.
++
++**/
++UINT8
++EFIAPI
++PciExpressBitFieldRead8 (
++ IN UINTN Address,
++ IN UINTN StartBit,
++ IN UINTN EndBit
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioBitFieldRead8 (
++ (UINTN) GetPciExpressAddress (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 StartBit and EndBit, then ASSERT().
++
++ @param Address The PCI configuration register to write.
++ @param StartBit The ordinal of the least significant bit in the bit field.
++ Range 0..7.
++ @param EndBit The ordinal of the most significant bit in the bit field.
++ Range 0..7.
++ @param Value The new value of the bit field.
++
++ @return The value written back to the PCI configuration register.
++
++**/
++UINT8
++EFIAPI
++PciExpressBitFieldWrite8 (
++ IN UINTN Address,
++ IN UINTN StartBit,
++ IN UINTN EndBit,
++ IN UINT8 Value
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioBitFieldWrite8 (
++ (UINTN) GetPciExpressAddress (Address),
++ StartBit,
++ EndBit,
++ Value
++ );
++}
++
++/**
++ Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
++ writes the result back to the bit field in the 8-bit port.
++
++ Reads the 8-bit PCI configuration register specified by Address, performs a
++ bitwise OR between the read result and the value specified by
++ OrData, and writes the result to the 8-bit PCI configuration register
++ specified by Address. The value written to the PCI configuration register is
++ returned. This function must guarantee that all PCI read and write operations
++ are serialized. Extra left bits in OrData are stripped.
++
++ If 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 StartBit and EndBit, then ASSERT().
++
++ @param Address The PCI configuration register to write.
++ @param StartBit The ordinal of the least significant bit in the bit field.
++ Range 0..7.
++ @param EndBit The ordinal of the most significant bit in the bit field.
++ Range 0..7.
++ @param OrData The value to OR with the PCI configuration register.
++
++ @return The value written back to the PCI configuration register.
++
++**/
++UINT8
++EFIAPI
++PciExpressBitFieldOr8 (
++ IN UINTN Address,
++ IN UINTN StartBit,
++ IN UINTN EndBit,
++ IN UINT8 OrData
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioBitFieldOr8 (
++ (UINTN) GetPciExpressAddress (Address),
++ StartBit,
++ EndBit,
++ OrData
++ );
++}
++
++/**
++ Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
++ AND, and writes the result back to the bit field in the 8-bit register.
++
++ Reads the 8-bit PCI configuration register specified by Address, performs a
++ bitwise AND between the read result and the value specified by AndData, and
++ writes the result to the 8-bit PCI configuration register specified by
++ Address. The value written to the PCI configuration register is returned.
++ This function must guarantee that all PCI read and write operations are
++ serialized. Extra left bits in AndData are stripped.
++
++ If 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 StartBit and EndBit, then ASSERT().
++
++ @param Address The PCI configuration register to write.
++ @param StartBit The ordinal of the least significant bit in the bit field.
++ Range 0..7.
++ @param EndBit The ordinal of the most significant bit in the bit field.
++ Range 0..7.
++ @param AndData The value to AND with the PCI configuration register.
++
++ @return The value written back to the PCI configuration register.
++
++**/
++UINT8
++EFIAPI
++PciExpressBitFieldAnd8 (
++ IN UINTN Address,
++ IN UINTN StartBit,
++ IN UINTN EndBit,
++ IN UINT8 AndData
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioBitFieldAnd8 (
++ (UINTN) GetPciExpressAddress (Address),
++ StartBit,
++ EndBit,
++ AndData
++ );
++}
++
++/**
++ Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
++ bitwise OR, and writes the result back to the bit field in the
++ 8-bit port.
++
++ Reads the 8-bit PCI configuration register specified by Address, performs a
++ bitwise AND followed by a bitwise OR between the read result and
++ the value specified by AndData, and writes the result to the 8-bit PCI
++ configuration register specified by Address. The value written to the PCI
++ configuration register is returned. This function must guarantee that all PCI
++ read and write operations are serialized. Extra left bits in both AndData and
++ OrData are stripped.
++
++ If 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 StartBit and EndBit, then ASSERT().
++ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
++
++ @param Address The PCI configuration register to write.
++ @param StartBit The ordinal of the least significant bit in the bit field.
++ Range 0..7.
++ @param EndBit The ordinal of the most significant bit in the bit field.
++ Range 0..7.
++ @param AndData The value to AND with the PCI configuration register.
++ @param OrData The value to OR with the result of the AND operation.
++
++ @return The value written back to the PCI configuration register.
++
++**/
++UINT8
++EFIAPI
++PciExpressBitFieldAndThenOr8 (
++ IN UINTN Address,
++ IN UINTN StartBit,
++ IN UINTN EndBit,
++ IN UINT8 AndData,
++ IN UINT8 OrData
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioBitFieldAndThenOr8 (
++ (UINTN) GetPciExpressAddress (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, Function and
++ Register.
++
++ @return The read value from the PCI configuration register.
++
++**/
++UINT16
++EFIAPI
++PciExpressRead16 (
++ IN UINTN Address
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioRead16 ((UINTN) GetPciExpressAddress (Address));
++}
++
++/**
++ Writes a 16-bit PCI configuration register.
++
++ Writes the 16-bit PCI configuration register specified by Address with the
++ value specified by Value. Value is returned. This function must guarantee
++ that all PCI read and write operations are serialized.
++
++ If 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, Function 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
++ )
++{
++ UINT32 Data;
++ UINT8 Offset;
++ UINT8 Bus;
++ UINT8 Device;
++ UINT8 Function;
++
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++
++ // Get the EFI notation
++ Bus = GET_BUS_NUM(Address);
++ Device = GET_DEV_NUM(Address);
++ Function = GET_FUNC_NUM(Address);
++
++ if( (Bus == 0) && (Device == 0) && (Function == 0) ) {
++ Data = MmioRead32((UINTN) GetPciExpressAddress (Address & 0xFFFFFFFC));
++ Offset = Address & 0x3;
++ Data |= (Value << (8 * Offset));
++ MmioWrite32 ((UINTN) GetPciExpressAddress (Address & 0xFFFFFFFC), Data);
++ } else {
++ MmioWrite16 ((UINTN) GetPciExpressAddress (Address), Value);
++ }
++ return Value;
++}
++
++/**
++ Performs a bitwise OR of a 16-bit PCI configuration register with
++ a 16-bit value.
++
++ Reads the 16-bit PCI configuration register specified by Address, performs a
++ bitwise OR between the read result and the value specified by
++ OrData, and writes the result to the 16-bit PCI configuration register
++ specified by Address. The value written to the PCI configuration register is
++ returned. This function must guarantee that all PCI read and write operations
++ are serialized.
++
++ If 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, Function and
++ Register.
++ @param OrData The value to OR with the PCI configuration register.
++
++ @return The value written back to the PCI configuration register.
++
++**/
++UINT16
++EFIAPI
++PciExpressOr16 (
++ IN UINTN Address,
++ IN UINT16 OrData
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioOr16 ((UINTN) GetPciExpressAddress (Address), OrData);
++}
++
++/**
++ Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
++ value.
++
++ Reads the 16-bit PCI configuration register specified by Address, performs a
++ bitwise AND between the read result and the value specified by AndData, and
++ writes the result to the 16-bit PCI configuration register specified by
++ Address. The value written to the PCI configuration register is returned.
++ This function must guarantee that all PCI read and write operations are
++ serialized.
++
++ If 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, Function 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);
++ return MmioAnd16 ((UINTN) GetPciExpressAddress (Address), AndData);
++}
++
++/**
++ Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
++ value, followed a bitwise OR with another 16-bit value.
++
++ Reads the 16-bit PCI configuration register specified by Address, performs a
++ bitwise AND between the read result and the value specified by AndData,
++ performs a bitwise OR between the result of the AND operation and
++ the value specified by OrData, and writes the result to the 16-bit PCI
++ configuration register specified by Address. The value written to the PCI
++ configuration register is returned. This function must guarantee that all PCI
++ read and write operations are serialized.
++
++ If 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, Function 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);
++ return MmioAndThenOr16 (
++ (UINTN) GetPciExpressAddress (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 bit field.
++ Range 0..15.
++ @param EndBit The ordinal of the most significant bit in the bit field.
++ Range 0..15.
++
++ @return The value of the bit field read from the PCI configuration register.
++
++**/
++UINT16
++EFIAPI
++PciExpressBitFieldRead16 (
++ IN UINTN Address,
++ IN UINTN StartBit,
++ IN UINTN EndBit
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioBitFieldRead16 (
++ (UINTN) GetPciExpressAddress (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 StartBit and EndBit, then ASSERT().
++
++ @param Address The PCI configuration register to write.
++ @param StartBit The ordinal of the least significant bit in the bit field.
++ Range 0..15.
++ @param EndBit The ordinal of the most significant bit in the bit field.
++ Range 0..15.
++ @param Value The new value of the bit field.
++
++ @return The value written back to the PCI configuration register.
++
++**/
++UINT16
++EFIAPI
++PciExpressBitFieldWrite16 (
++ IN UINTN Address,
++ IN UINTN StartBit,
++ IN UINTN EndBit,
++ IN UINT16 Value
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioBitFieldWrite16 (
++ (UINTN) GetPciExpressAddress (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, performs a
++ bitwise OR between the read result and the value specified by
++ OrData, and writes the result to the 16-bit PCI configuration register
++ specified by Address. The value written to the PCI configuration register is
++ returned. This function must guarantee that all PCI read and write operations
++ are serialized. Extra left bits in OrData are stripped.
++
++ If 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 StartBit and EndBit, then ASSERT().
++
++ @param Address The PCI configuration register to write.
++ @param StartBit The ordinal of the least significant bit in the bit field.
++ Range 0..15.
++ @param EndBit The ordinal of the most significant bit in the bit field.
++ Range 0..15.
++ @param OrData The value to OR with the PCI configuration register.
++
++ @return The value written back to the PCI configuration register.
++
++**/
++UINT16
++EFIAPI
++PciExpressBitFieldOr16 (
++ IN UINTN Address,
++ IN UINTN StartBit,
++ IN UINTN EndBit,
++ IN UINT16 OrData
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioBitFieldOr16 (
++ (UINTN) GetPciExpressAddress (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 register.
++
++ Reads the 16-bit PCI configuration register specified by Address, performs a
++ bitwise AND between the read result and the value specified by AndData, and
++ writes the result to the 16-bit PCI configuration register specified by
++ Address. The value written to the PCI configuration register is returned.
++ This function must guarantee that all PCI read and write operations are
++ serialized. Extra left bits in AndData are stripped.
++
++ If 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 StartBit and EndBit, then ASSERT().
++
++ @param Address The PCI configuration register to write.
++ @param StartBit The ordinal of the least significant bit in the bit field.
++ Range 0..15.
++ @param EndBit The ordinal of the most significant bit in the bit field.
++ Range 0..15.
++ @param AndData The value to AND with the PCI configuration register.
++
++ @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);
++ return MmioBitFieldAnd16 (
++ (UINTN) GetPciExpressAddress (Address),
++ StartBit,
++ EndBit,
++ AndData
++ );
++}
++
++/**
++ Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
++ bitwise OR, and writes the result back to the bit field in the
++ 16-bit port.
++
++ Reads the 16-bit PCI configuration register specified by Address, performs a
++ bitwise AND followed by a bitwise OR between the read result and
++ the value specified by AndData, and writes the result to the 16-bit PCI
++ configuration register specified by Address. The value written to the PCI
++ configuration register is returned. This function must guarantee that all PCI
++ read and write operations are serialized. Extra left bits in both AndData and
++ OrData are stripped.
++
++ If 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 StartBit and EndBit, then ASSERT().
++ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
++
++ @param Address The PCI configuration register to write.
++ @param StartBit The ordinal of the least significant bit in the bit field.
++ Range 0..15.
++ @param EndBit The ordinal of the most significant bit in the bit field.
++ Range 0..15.
++ @param AndData The value to AND with the PCI configuration register.
++ @param OrData The value to OR with the result of the AND operation.
++
++ @return The value written back to the PCI configuration register.
++
++**/
++UINT16
++EFIAPI
++PciExpressBitFieldAndThenOr16 (
++ IN UINTN Address,
++ IN UINTN StartBit,
++ IN UINTN EndBit,
++ IN UINT16 AndData,
++ IN UINT16 OrData
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioBitFieldAndThenOr16 (
++ (UINTN) GetPciExpressAddress (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, Function and
++ Register.
++
++ @return The read value from the PCI configuration register.
++
++**/
++UINT32
++EFIAPI
++PciExpressRead32 (
++ IN UINTN Address
++ )
++{
++ UINTN address;
++ UINT32 value;
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ address = (UINTN) GetPciExpressAddress (Address);
++ value = MmioRead32 (address);
++ return value;
++}
++
++/**
++ Writes a 32-bit PCI configuration register.
++
++ Writes the 32-bit PCI configuration register specified by Address with the
++ value specified by Value. Value is returned. This function must guarantee
++ that all PCI read and write operations are serialized.
++
++ If 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, Function 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);
++ return MmioWrite32 ((UINTN) GetPciExpressAddress (Address), Value);
++}
++
++/**
++ Performs a bitwise OR of a 32-bit PCI configuration register with
++ a 32-bit value.
++
++ Reads the 32-bit PCI configuration register specified by Address, performs a
++ bitwise OR between the read result and the value specified by
++ OrData, and writes the result to the 32-bit PCI configuration register
++ specified by Address. The value written to the PCI configuration register is
++ returned. This function must guarantee that all PCI read and write operations
++ are serialized.
++
++ If 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, Function 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);
++ return MmioOr32 ((UINTN) GetPciExpressAddress (Address), OrData);
++}
++
++/**
++ Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
++ value.
++
++ Reads the 32-bit PCI configuration register specified by Address, performs a
++ bitwise AND between the read result and the value specified by AndData, and
++ writes the result to the 32-bit PCI configuration register specified by
++ Address. The value written to the PCI configuration register is returned.
++ This function must guarantee that all PCI read and write operations are
++ serialized.
++
++ If 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, Function 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);
++ return MmioAnd32 ((UINTN) GetPciExpressAddress (Address), AndData);
++}
++
++/**
++ Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
++ value, followed a bitwise OR with another 32-bit value.
++
++ Reads the 32-bit PCI configuration register specified by Address, performs a
++ bitwise AND between the read result and the value specified by AndData,
++ performs a bitwise OR between the result of the AND operation and
++ the value specified by OrData, and writes the result to the 32-bit PCI
++ configuration register specified by Address. The value written to the PCI
++ configuration register is returned. This function must guarantee that all PCI
++ read and write operations are serialized.
++
++ If 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, Function 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);
++ return MmioAndThenOr32 (
++ (UINTN) GetPciExpressAddress (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 bit field.
++ Range 0..31.
++ @param EndBit The ordinal of the most significant bit in the bit field.
++ Range 0..31.
++
++ @return The value of the bit field read from the PCI configuration register.
++
++**/
++UINT32
++EFIAPI
++PciExpressBitFieldRead32 (
++ IN UINTN Address,
++ IN UINTN StartBit,
++ IN UINTN EndBit
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioBitFieldRead32 (
++ (UINTN) GetPciExpressAddress (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 StartBit and EndBit, then ASSERT().
++
++ @param Address The PCI configuration register to write.
++ @param StartBit The ordinal of the least significant bit in the bit field.
++ Range 0..31.
++ @param EndBit The ordinal of the most significant bit in the bit field.
++ Range 0..31.
++ @param Value The new value of the bit field.
++
++ @return The value written back to the PCI configuration register.
++
++**/
++UINT32
++EFIAPI
++PciExpressBitFieldWrite32 (
++ IN UINTN Address,
++ IN UINTN StartBit,
++ IN UINTN EndBit,
++ IN UINT32 Value
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioBitFieldWrite32 (
++ (UINTN) GetPciExpressAddress (Address),
++ StartBit,
++ EndBit,
++ Value
++ );
++}
++
++/**
++ Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
++ writes the result back to the bit field in the 32-bit port.
++
++ Reads the 32-bit PCI configuration register specified by Address, performs a
++ bitwise OR between the read result and the value specified by
++ OrData, and writes the result to the 32-bit PCI configuration register
++ specified by Address. The value written to the PCI configuration register is
++ returned. This function must guarantee that all PCI read and write operations
++ are serialized. Extra left bits in OrData are stripped.
++
++ If 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 StartBit and EndBit, then ASSERT().
++
++ @param Address The PCI configuration register to write.
++ @param StartBit The ordinal of the least significant bit in the bit field.
++ Range 0..31.
++ @param EndBit The ordinal of the most significant bit in the bit field.
++ Range 0..31.
++ @param OrData The value to OR with the PCI configuration register.
++
++ @return The value written back to the PCI configuration register.
++
++**/
++UINT32
++EFIAPI
++PciExpressBitFieldOr32 (
++ IN UINTN Address,
++ IN UINTN StartBit,
++ IN UINTN EndBit,
++ IN UINT32 OrData
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioBitFieldOr32 (
++ (UINTN) GetPciExpressAddress (Address),
++ StartBit,
++ EndBit,
++ OrData
++ );
++}
++
++/**
++ Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
++ AND, and writes the result back to the bit field in the 32-bit register.
++
++ Reads the 32-bit PCI configuration register specified by Address, performs a
++ bitwise AND between the read result and the value specified by AndData, and
++ writes the result to the 32-bit PCI configuration register specified by
++ Address. The value written to the PCI configuration register is returned.
++ This function must guarantee that all PCI read and write operations are
++ serialized. Extra left bits in AndData are stripped.
++
++ If 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 StartBit and EndBit, then ASSERT().
++
++ @param Address The PCI configuration register to write.
++ @param StartBit The ordinal of the least significant bit in the bit field.
++ Range 0..31.
++ @param EndBit The ordinal of the most significant bit in the bit field.
++ Range 0..31.
++ @param AndData The value to AND with the PCI configuration register.
++
++ @return The value written back to the PCI configuration register.
++
++**/
++UINT32
++EFIAPI
++PciExpressBitFieldAnd32 (
++ IN UINTN Address,
++ IN UINTN StartBit,
++ IN UINTN EndBit,
++ IN UINT32 AndData
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioBitFieldAnd32 (
++ (UINTN) GetPciExpressAddress (Address),
++ StartBit,
++ EndBit,
++ AndData
++ );
++}
++
++/**
++ Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
++ bitwise OR, and writes the result back to the bit field in the
++ 32-bit port.
++
++ Reads the 32-bit PCI configuration register specified by Address, performs a
++ bitwise AND followed by a bitwise OR between the read result and
++ the value specified by AndData, and writes the result to the 32-bit PCI
++ configuration register specified by Address. The value written to the PCI
++ configuration register is returned. This function must guarantee that all PCI
++ read and write operations are serialized. Extra left bits in both AndData and
++ OrData are stripped.
++
++ If 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 StartBit and EndBit, then ASSERT().
++ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
++
++ @param Address The PCI configuration register to write.
++ @param StartBit The ordinal of the least significant bit in the bit field.
++ Range 0..31.
++ @param EndBit The ordinal of the most significant bit in the bit field.
++ Range 0..31.
++ @param AndData The value to AND with the PCI configuration register.
++ @param OrData The value to OR with the result of the AND operation.
++
++ @return The value written back to the PCI configuration register.
++
++**/
++UINT32
++EFIAPI
++PciExpressBitFieldAndThenOr32 (
++ IN UINTN Address,
++ IN UINTN StartBit,
++ IN UINTN EndBit,
++ IN UINT32 AndData,
++ IN UINT32 OrData
++ )
++{
++ ASSERT_INVALID_PCI_ADDRESS (Address);
++ return MmioBitFieldAndThenOr32 (
++ (UINTN) GetPciExpressAddress (Address),
++ StartBit,
++ EndBit,
++ AndData,
++ OrData
++ );
++}
++
++/**
++ Reads a range of PCI configuration registers into a caller supplied buffer.
++
++ Reads the range of PCI configuration registers specified by StartAddress and
++ Size into the buffer specified by Buffer. This function only allows the PCI
++ configuration registers from a single PCI function to be read. Size is
++ returned. When possible 32-bit PCI configuration read cycles are used to read
++ from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
++ and 16-bit PCI configuration read cycles may be used at the beginning and the
++ end of the range.
++
++ If 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 read.
++
++ @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) <= 0x1000);
++
++ if (Size == 0) {
++ return Size;
++ }
++
++ ASSERT (Buffer != NULL);
++
++ //
++ // Save Size for return
++ //
++ ReturnValue = Size;
++
++ if ((StartAddress & 1) != 0) {
++ //
++ // Read a byte if StartAddress is byte aligned
++ //
++ *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);
++ StartAddress += sizeof (UINT8);
++ Size -= sizeof (UINT8);
++ Buffer = (UINT8*)Buffer + 1;
++ }
++
++ if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
++ //
++ // Read a word if StartAddress is word aligned
++ //
++ WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress));
++
++ StartAddress += sizeof (UINT16);
++ Size -= sizeof (UINT16);
++ Buffer = (UINT16*)Buffer + 1;
++ }
++
++ while (Size >= sizeof (UINT32)) {
++ //
++ // Read as many double words as possible
++ //
++ WriteUnaligned32 ((UINT32 *) Buffer, (UINT32) PciExpressRead32 (StartAddress));
++
++ StartAddress += sizeof (UINT32);
++ Size -= sizeof (UINT32);
++ Buffer = (UINT32*)Buffer + 1;
++ }
++
++ if (Size >= sizeof (UINT16)) {
++ //
++ // Read the last remaining word if exist
++ //
++ WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress));
++ StartAddress += sizeof (UINT16);
++ Size -= sizeof (UINT16);
++ Buffer = (UINT16*)Buffer + 1;
++ }
++
++ if (Size >= sizeof (UINT8)) {
++ //
++ // Read the last remaining byte if exist
++ //
++ *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);
++ }
++
++ return ReturnValue;
++}
++
++/**
++ Copies the data in a caller supplied buffer to a specified range of PCI
++ configuration space.
++
++ Writes the range of PCI configuration registers specified by StartAddress and
++ Size from the buffer specified by Buffer. This function only allows the PCI
++ configuration registers from a single PCI function to be written. Size is
++ returned. When possible 32-bit PCI configuration write cycles are used to
++ write from StartAdress to StartAddress + Size. Due to alignment restrictions,
++ 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
++ and the end of the range.
++
++ If 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) <= 0x1000);
++
++ if (Size == 0) {
++ return 0;
++ }
++
++ ASSERT (Buffer != NULL);
++
++ //
++ // Save Size for return
++ //
++ ReturnValue = Size;
++
++ if ((StartAddress & 1) != 0) {
++ //
++ // Write a byte if StartAddress is byte aligned
++ //
++ PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);
++ StartAddress += sizeof (UINT8);
++ Size -= sizeof (UINT8);
++ Buffer = (UINT8*)Buffer + 1;
++ }
++
++ if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
++ //
++ // Write a word if StartAddress is word aligned
++ //
++ PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));
++ StartAddress += sizeof (UINT16);
++ Size -= sizeof (UINT16);
++ Buffer = (UINT16*)Buffer + 1;
++ }
++
++ while (Size >= sizeof (UINT32)) {
++ //
++ // Write as many double words as possible
++ //
++ PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer));
++ StartAddress += sizeof (UINT32);
++ Size -= sizeof (UINT32);
++ Buffer = (UINT32*)Buffer + 1;
++ }
++
++ if (Size >= sizeof (UINT16)) {
++ //
++ // Write the last remaining word if exist
++ //
++ PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));
++ StartAddress += sizeof (UINT16);
++ Size -= sizeof (UINT16);
++ Buffer = (UINT16*)Buffer + 1;
++ }
++
++ if (Size >= sizeof (UINT8)) {
++ //
++ // Write the last remaining byte if exist
++ //
++ PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);
++ }
++
++ return ReturnValue;
++}
diff --git a/Platform/ARM/N1SdpPkg/Library/PciExpressLib/PciExpressLib.inf b/Platform/ARM/N1SdpPkg/Library/PciExpressLib/PciExpressLib.inf
new file mode 100644
-index 0000000..5de84a4
+index 00000000..71b3a5c6
--- /dev/null
+++ b/Platform/ARM/N1SdpPkg/Library/PciExpressLib/PciExpressLib.inf
@@ -0,0 +1,48 @@
-+## @file
-+# Instance of PCI Express Library using the 256 MB PCI Express MMIO window.
-+#
-+# PCI Express Library that uses the 256 MB PCI Express MMIO window to perform
-+# PCI Configuration cycles. Layers on top of an I/O Library instance.
-+#
-+# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
-+#
-+# SPDX-License-Identifier: BSD-2-Clause-Patent
-+#
-+##
-+
-+[Defines]
-+ INF_VERSION = 0x00010005
-+ BASE_NAME = BasePciExpressLib
-+ MODULE_UNI_FILE = BasePciExpressLib.uni
-+ FILE_GUID = 52c06b64-a45e-4906-b9ee-abe1acc286bb
-+ MODULE_TYPE = BASE
-+ VERSION_STRING = 1.0
-+ LIBRARY_CLASS = PciExpressLib
-+
-+#
-+# VALID_ARCHITECTURES = IA32 X64 EBC
-+#
-+
-+[Sources]
-+ PciExpressLib.c
-+
-+[Packages]
-+ MdePkg/MdePkg.dec
-+ Platform/ARM/N1SdpPkg/N1SdpPlatform.dec
-+
-+[FixedPcd]
-+ gArmN1SdpTokenSpaceGuid.PcdPcieRootPortConfigBaseAddress
-+ gArmN1SdpTokenSpaceGuid.PcdPcieRootPortConfigBaseSize
-+ gArmN1SdpTokenSpaceGuid.PcdCcixRootPortConfigBaseAddress
-+ gArmN1SdpTokenSpaceGuid.PcdCcixRootPortConfigBaseSize
-+
-+[LibraryClasses]
-+ BaseLib
-+ PcdLib
-+ DebugLib
-+ IoLib
-+
-+[Pcd]
-+ gArmN1SdpTokenSpaceGuid.PcdPcieExpressBaseAddress ## CONSUMES
-+ gArmN1SdpTokenSpaceGuid.PcdCcixExpressBaseAddress ## CONSUMES
-+
++## @file
++# Instance of PCI Express Library using the 256 MB PCI Express MMIO window.
++#
++# PCI Express Library that uses the 256 MB PCI Express MMIO window to perform
++# PCI Configuration cycles. Layers on top of an I/O Library instance.
++#
++# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
++#
++# SPDX-License-Identifier: BSD-2-Clause-Patent
++#
++##
++
++[Defines]
++ INF_VERSION = 0x00010005
++ BASE_NAME = BasePciExpressLib
++ MODULE_UNI_FILE = BasePciExpressLib.uni
++ FILE_GUID = 52c06b64-a45e-4906-b9ee-abe1acc286bb
++ MODULE_TYPE = BASE
++ VERSION_STRING = 1.0
++ LIBRARY_CLASS = PciExpressLib
++
++#
++# VALID_ARCHITECTURES = IA32 X64 EBC
++#
++
++[Sources]
++ PciExpressLib.c
++
++[Packages]
++ MdePkg/MdePkg.dec
++ Platform/ARM/N1SdpPkg/N1SdpPlatform.dec
++
++[FixedPcd]
++ gArmN1SdpTokenSpaceGuid.PcdPcieRootPortConfigBaseAddress
++ gArmN1SdpTokenSpaceGuid.PcdPcieRootPortConfigBaseSize
++ gArmN1SdpTokenSpaceGuid.PcdCcixRootPortConfigBaseAddress
++ gArmN1SdpTokenSpaceGuid.PcdCcixRootPortConfigBaseSize
++
++[LibraryClasses]
++ BaseLib
++ PcdLib
++ DebugLib
++ IoLib
++
++[Pcd]
++ gArmN1SdpTokenSpaceGuid.PcdPcieExpressBaseAddress ## CONSUMES
++ gArmN1SdpTokenSpaceGuid.PcdCcixExpressBaseAddress ## CONSUMES
++
diff --git a/Platform/ARM/N1SdpPkg/Library/PciExpressLib/PciExpressLib.uni b/Platform/ARM/N1SdpPkg/Library/PciExpressLib/PciExpressLib.uni
new file mode 100644
-index 0000000..be39290
+index 00000000..5c57bb40
--- /dev/null
+++ b/Platform/ARM/N1SdpPkg/Library/PciExpressLib/PciExpressLib.uni
@@ -0,0 +1,17 @@
-+// /** @file
-+// Instance of PCI Express Library using the 256 MB PCI Express MMIO window.
-+//
-+// PCI Express Library that uses the 256 MB PCI Express MMIO window to perform
-+// PCI Configuration cycles. Layers on top of an I/O Library instance.
-+//
-+// Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
-+//
-+// SPDX-License-Identifier: BSD-2-Clause-Patent
-+//
-+// **/
-+
-+
-+#string STR_MODULE_ABSTRACT #language en-US "Instance of PCI Express Library using the 256 MB PCI Express MMIO window"
-+
-+#string STR_MODULE_DESCRIPTION #language en-US "PCI Express Library that uses the 256 MB PCI Express MMIO window to perform PCI Configuration cycles. Layers on top of an I/O Library instance."
-+
++// /** @file
++// Instance of PCI Express Library using the 256 MB PCI Express MMIO window.
++//
++// PCI Express Library that uses the 256 MB PCI Express MMIO window to perform
++// PCI Configuration cycles. Layers on top of an I/O Library instance.
++//
++// Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
++//
++// SPDX-License-Identifier: BSD-2-Clause-Patent
++//
++// **/
++
++
++#string STR_MODULE_ABSTRACT #language en-US "Instance of PCI Express Library using the 256 MB PCI Express MMIO window"
++
++#string STR_MODULE_DESCRIPTION #language en-US "PCI Express Library that uses the 256 MB PCI Express MMIO window to perform PCI Configuration cycles. Layers on top of an I/O Library instance."
++
diff --git a/Platform/ARM/N1SdpPkg/N1SdpPlatform.dsc b/Platform/ARM/N1SdpPkg/N1SdpPlatform.dsc
-index b801115..99db3f1 100644
+index 15ce0342..94cff4e7 100644
--- a/Platform/ARM/N1SdpPkg/N1SdpPlatform.dsc
+++ b/Platform/ARM/N1SdpPkg/N1SdpPlatform.dsc
-@@ -83,7 +83,7 @@
- PciHostBridgeLib|Platform/ARM/N1SdpPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
- PciSegmentLib|Platform/ARM/N1SdpPkg/Library/PciSegmentLib/PciSegmentLib.inf
- PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
-- PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
-+ PciExpressLib|Platform/ARM/N1SdpPkg/Library/PciExpressLib/PciExpressLib.inf
-
- [LibraryClasses.common.DXE_RUNTIME_DRIVER]
- BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+@@ -86,7 +86,7 @@
+ PciHostBridgeLib|Platform/ARM/N1SdpPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
+ PciSegmentLib|Platform/ARM/N1SdpPkg/Library/PciSegmentLib/PciSegmentLib.inf
+ PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
+- PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
++ PciExpressLib|Platform/ARM/N1SdpPkg/Library/PciExpressLib/PciExpressLib.inf
+
+ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
--
-2.7.4
+2.17.1
diff --git a/linux/0001-N1SDP-PCIe-Enablement-Quirks-for-N1SDP-PCie-controll.patch b/linux/0001-N1SDP-PCIe-Enablement-Quirks-for-N1SDP-PCie-controll.patch
index 40aafb4..e6fde95 100755
--- a/linux/0001-N1SDP-PCIe-Enablement-Quirks-for-N1SDP-PCie-controll.patch
+++ b/linux/0001-N1SDP-PCIe-Enablement-Quirks-for-N1SDP-PCie-controll.patch
@@ -1,7 +1,7 @@
-From fdcf69aa74601372ac906f9eb85f8a66365f8e14 Mon Sep 17 00:00:00 2001
+From 7d0912ff159407f47c8ce2ec30024e6611cedd50 Mon Sep 17 00:00:00 2001
From: Sudipto Paul <sudipto.paul@arm.com>
Date: Wed, 21 Nov 2018 18:53:12 +0000
-Subject: [PATCH 3/5] N1SDP PCIe Enablement: Quirks for N1SDP PCie controller
+Subject: [PATCH] N1SDP PCIe Enablement: Quirks for N1SDP PCie controller
-PCIe Host Controller with MCFG quirk for Bus Map
-PCIe Slave Error Mitigation
@@ -13,37 +13,49 @@ extend the quirk for the ccix root port
Signed-off-by: Deepak Pandey <Deepak.Pandey@arm.com>
---
- arch/arm64/configs/defconfig | 2 +
- drivers/acpi/pci_mcfg.c | 6 ++
+ arch/arm64/configs/defconfig | 21 ++++
+ drivers/acpi/pci_mcfg.c | 6 +
drivers/pci/controller/Kconfig | 8 ++
drivers/pci/controller/Makefile | 1 +
- drivers/pci/controller/pcie-n1sdp.c | 167 ++++++++++++++++++++++++++++++++++++
+ drivers/pci/controller/pcie-n1sdp.c | 167 ++++++++++++++++++++++++++++
include/linux/pci-ecam.h | 1 +
- 6 files changed, 185 insertions(+)
+ 6 files changed, 204 insertions(+)
create mode 100644 drivers/pci/controller/pcie-n1sdp.c
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
-index ba96527..328b0f3 100644
+index 3795e5dc386c..0896b4010ef6 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
-@@ -172,6 +172,7 @@ CONFIG_NET_9P=y
- CONFIG_NET_9P_VIRTIO=y
- CONFIG_PCI=y
- CONFIG_PCIEPORTBUS=y
+@@ -60,6 +60,27 @@ CONFIG_ARCH_VEXPRESS=y
+ CONFIG_ARCH_XGENE=y
+ CONFIG_ARCH_ZX=y
+ CONFIG_ARCH_ZYNQMP=y
++CONFIG_PCI=y
++CONFIG_PCIEPORTBUS=y
+CONFIG_PCI_QUIRKS=y
- CONFIG_PCI_IOV=y
- CONFIG_HOTPLUG_PCI=y
- CONFIG_HOTPLUG_PCI_ACPI=y
-@@ -191,6 +192,7 @@ CONFIG_PCIE_QCOM=y
- CONFIG_PCIE_ARMADA_8K=y
- CONFIG_PCIE_KIRIN=y
- CONFIG_PCIE_HISI_STB=y
++CONFIG_PCI_IOV=y
++CONFIG_HOTPLUG_PCI=y
++CONFIG_HOTPLUG_PCI_ACPI=y
++CONFIG_PCI_AARDVARK=y
++CONFIG_PCI_TEGRA=y
++CONFIG_PCIE_RCAR=y
++CONFIG_PCI_HOST_GENERIC=y
++CONFIG_PCI_XGENE=y
++CONFIG_PCI_HOST_THUNDER_PEM=y
++CONFIG_PCI_HOST_THUNDER_ECAM=y
++CONFIG_PCIE_ROCKCHIP_HOST=m
++CONFIG_PCI_LAYERSCAPE=y
++CONFIG_PCI_HISI=y
++CONFIG_PCIE_QCOM=y
++CONFIG_PCIE_ARMADA_8K=y
++CONFIG_PCIE_KIRIN=y
++CONFIG_PCIE_HISI_STB=y
+CONFIG_PCIE_HOST_N1SDP_ECAM=y
- CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
- CONFIG_DEVTMPFS=y
- CONFIG_DEVTMPFS_MOUNT=y
+ CONFIG_ARM64_VA_BITS_48=y
+ CONFIG_SCHED_MC=y
+ CONFIG_NUMA=y
diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
-index 6b347d9..2245430c 100644
+index 6b347d9920cc..078cf5b948ae 100644
--- a/drivers/acpi/pci_mcfg.c
+++ b/drivers/acpi/pci_mcfg.c
@@ -142,6 +142,12 @@ static struct mcfg_fixup mcfg_quirks[] = {
@@ -52,7 +64,7 @@ index 6b347d9..2245430c 100644
XGENE_V2_ECAM_MCFG(4, 2),
+
+#define N1SDP_ECAM_MCFG(rev, seg, ops) \
-+ {"ARMLTD", "ARMN1SDP", rev, seg, MCFG_BUS_ANY, ops }
++ {"ARMLTD", "ARMN1SDP", rev, seg, MCFG_BUS_ANY, ops }
+ /* N1SDP SoC with v1 PCIe controller */
+ N1SDP_ECAM_MCFG(0x20181101, 0, &pci_n1sdp_ecam_ops),
+ N1SDP_ECAM_MCFG(0x20181101, 1, &pci_n1sdp_ecam_ops),
@@ -60,7 +72,7 @@ index 6b347d9..2245430c 100644
static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
-index 011c57c..bb823bf 100644
+index fe9f9f13ce11..1ca4878080e2 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -65,6 +65,14 @@ config PCI_FTPCI100
@@ -79,7 +91,7 @@ index 011c57c..bb823bf 100644
bool "NVIDIA Tegra PCIe controller"
depends on ARCH_TEGRA || COMPILE_TEST
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
-index d56a507..1531d90 100644
+index d56a507495c5..1531d9085386 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
@@ -92,7 +104,7 @@ index d56a507..1531d90 100644
diff --git a/drivers/pci/controller/pcie-n1sdp.c b/drivers/pci/controller/pcie-n1sdp.c
new file mode 100644
-index 0000000..ea98580
+index 000000000000..ea98580f1fb7
--- /dev/null
+++ b/drivers/pci/controller/pcie-n1sdp.c
@@ -0,0 +1,167 @@
@@ -264,17 +276,17 @@ index 0000000..ea98580
+};
+#endif
diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
-index a73164c..704e787 100644
+index a73164c85e78..ffcc3f2b2bad 100644
--- a/include/linux/pci-ecam.h
+++ b/include/linux/pci-ecam.h
@@ -57,6 +57,7 @@ extern struct pci_ecam_ops pci_thunder_ecam_ops; /* Cavium ThunderX 1.x */
extern struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 */
extern struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */
extern struct pci_ecam_ops al_pcie_ops; /* Amazon Annapurna Labs PCIe */
-+extern struct pci_ecam_ops pci_n1sdp_ecam_ops; /* ARM N1SDP PCIe */
++extern struct pci_ecam_ops pci_n1sdp_ecam_ops; /* APM N1SDP PCIe */
#endif
#ifdef CONFIG_PCI_HOST_COMMON
--
-2.7.4
+2.17.1
diff --git a/patch_apply.sh b/patch_apply.sh
index 9126967..45b0ad7 100755
--- a/patch_apply.sh
+++ b/patch_apply.sh
@@ -4,7 +4,7 @@ echo "******************************************"
echo "Applying the PCIe quirks in edk2-platforms"
echo "******************************************"
pushd ../uefi/edk2/edk2-platforms/
-git am ../../../n1sdp-pcie-quirk/edk2-platforms/*.patch
+git am --keep-cr ../../../n1sdp-pcie-quirk/edk2-platforms/*.patch
popd
echo "******************************************"
echo "Applying the PCIe quirks in linux"
diff --git a/scp/0001-n1sdp-add-workaround-for-PCIe-to-avoid-SLVERR-fault.patch b/scp/0001-n1sdp-add-workaround-for-PCIe-to-avoid-SLVERR-fault.patch
index f694045..0b424a3 100644
--- a/scp/0001-n1sdp-add-workaround-for-PCIe-to-avoid-SLVERR-fault.patch
+++ b/scp/0001-n1sdp-add-workaround-for-PCIe-to-avoid-SLVERR-fault.patch
@@ -1,4 +1,4 @@
-From 14f583c6ec444b1d3ec3e1f78631039b2a86d057 Mon Sep 17 00:00:00 2001
+From cf7c1f427075900cbed6a8c6cde51713b66d6235 Mon Sep 17 00:00:00 2001
From: Manoj Kumar <manoj.kumar3@arm.com>
Date: Thu, 23 May 2019 17:38:25 +0100
Subject: [PATCH] n1sdp: add workaround for PCIe to avoid SLVERR fault
@@ -11,29 +11,54 @@ application software for further PCIe enumeration/setup.
Change-Id: Ibbfc572f194fa405f3145bb834107f78d8e3923a
Signed-off-by: Manoj Kumar <manoj.kumar3@arm.com>
---
- arch/src/armv7-m/exceptions.c | 34 ++-
+ arch/src/armv7-m/exceptions.c | 61 ++++
+ arch/src/armv7-m/exceptions.h | 2 +-
product/n1sdp/module/n1sdp_pcie/src/Makefile | 2 +-
.../module/n1sdp_pcie/src/mod_n1sdp_pcie.c | 6 +
- .../module/n1sdp_pcie/src/pcie_enumeration.c | 271 ++++++++++++++++++
- 4 files changed, 309 insertions(+), 4 deletions(-)
+ .../module/n1sdp_pcie/src/pcie_enumeration.c | 270 ++++++++++++++++++
+ 5 files changed, 339 insertions(+), 2 deletions(-)
create mode 100755 product/n1sdp/module/n1sdp_pcie/src/pcie_enumeration.c
diff --git a/arch/src/armv7-m/exceptions.c b/arch/src/armv7-m/exceptions.c
-index 46469e6..db068d1 100644
+index fc18f1e..50dcae1 100644
--- a/arch/src/armv7-m/exceptions.c
+++ b/arch/src/armv7-m/exceptions.c
-@@ -60,10 +60,38 @@ noreturn void arm_exception_reset(void)
- #endif
+@@ -35,6 +35,67 @@ void software_init_hook(void)
}
+ #endif
--noreturn void arm_exception_invalid(void)
++
++noreturn void arm_exception_reset(void)
++{
++ /*
++ * When entering the firmware, before the framework is entered the following
++ * things happen:
++ * 1. The toolchain-specific C runtime is initialized
++ * For Arm Compiler:
++ * 1. Zero-initialized data is zeroed
++ * 2. Initialized data is decompressed and copied
++ * For GCC/Newlib:
++ * 1. Zero-initialized data is zeroed
++ * 2. Initialized data is copied by software_init_hook()
++ * 2. The main() function is called by the C runtime
++ */
++
++#ifdef __ARMCC_VERSION
++ extern noreturn void __main(void);
++
++ __main();
++#else
++ extern noreturn void _start(void);
++
++ _start();
++#endif
++}
++
+static volatile uint32_t exception_count = 0;
+volatile bool return_from_exception = false;
+
+uint32_t get_exception_count(void)
- {
-- while (true)
-- __WFI();
++{
+ return exception_count;
+}
+
@@ -61,9 +86,21 @@ index 46469e6..db068d1 100644
+ while (true)
+ __WFI();
+ }
- }
-
++}
++
enum {
+ EXCEPTION_RESET,
+ EXCEPTION_NMI,
+diff --git a/arch/src/armv7-m/exceptions.h b/arch/src/armv7-m/exceptions.h
+index f61da82..3d63ce4 100644
+--- a/arch/src/armv7-m/exceptions.h
++++ b/arch/src/armv7-m/exceptions.h
+@@ -20,4 +20,4 @@ noreturn void arm_exception_reset(void);
+ * \details This handler is used as the default in order to catch exceptions
+ * that have not been configured with a handler of their own.
+ */
+-noreturn void arm_exception_invalid(void);
++void arm_exception_invalid(void);
diff --git a/product/n1sdp/module/n1sdp_pcie/src/Makefile b/product/n1sdp/module/n1sdp_pcie/src/Makefile
index d3b06f2..6061a9d 100644
--- a/product/n1sdp/module/n1sdp_pcie/src/Makefile
@@ -77,7 +114,7 @@ index d3b06f2..6061a9d 100644
include $(BS_DIR)/lib.mk
diff --git a/product/n1sdp/module/n1sdp_pcie/src/mod_n1sdp_pcie.c b/product/n1sdp/module/n1sdp_pcie/src/mod_n1sdp_pcie.c
-index 362040d..5de48ca 100644
+index 999ab42..003c853 100644
--- a/product/n1sdp/module/n1sdp_pcie/src/mod_n1sdp_pcie.c
+++ b/product/n1sdp/module/n1sdp_pcie/src/mod_n1sdp_pcie.c
@@ -24,6 +24,9 @@
@@ -90,7 +127,7 @@ index 362040d..5de48ca 100644
/*
* Device context
*/
-@@ -176,6 +179,7 @@ static int n1sdp_pcie_setup(struct n1sdp_pcie_dev_ctx *dev_ctx)
+@@ -218,6 +221,7 @@ static int n1sdp_pcie_setup(struct n1sdp_pcie_dev_ctx *dev_ctx)
gen_speed);
if (status != FWK_SUCCESS) {
pcie_ctx.log_api->log(MOD_LOG_GROUP_INFO, "Timeout!\n");
@@ -98,7 +135,7 @@ index 362040d..5de48ca 100644
return dev_ctx->config->ccix_capable ? FWK_SUCCESS : status;
}
pcie_ctx.log_api->log(MOD_LOG_GROUP_INFO, "Done\n");
-@@ -329,6 +333,8 @@ static int n1sdp_pcie_setup(struct n1sdp_pcie_dev_ctx *dev_ctx)
+@@ -408,6 +412,8 @@ ctrl_plane_init:
pcie_ctx.timer_api->delay(FWK_ID_ELEMENT(FWK_MODULE_IDX_TIMER, 0),
PCIE_LINK_TRAINING_TIMEOUT);
@@ -109,10 +146,10 @@ index 362040d..5de48ca 100644
diff --git a/product/n1sdp/module/n1sdp_pcie/src/pcie_enumeration.c b/product/n1sdp/module/n1sdp_pcie/src/pcie_enumeration.c
new file mode 100755
-index 0000000..667d659
+index 0000000..f5ad359
--- /dev/null
+++ b/product/n1sdp/module/n1sdp_pcie/src/pcie_enumeration.c
-@@ -0,0 +1,271 @@
+@@ -0,0 +1,270 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
@@ -123,7 +160,6 @@ index 0000000..667d659
+#include <stddef.h>
+#include <stdint.h>
+#include <fwk_assert.h>
-+#include <fwk_errno.h>
+#include <fwk_macros.h>
+#include <mod_n1sdp_pcie.h>
+#include <n1sdp_pcie.h>