diff options
author | sudipto paul <sudipto.paul@arm.com> | 2019-10-13 21:43:14 +0100 |
---|---|---|
committer | sudipto paul <sudipto.paul@arm.com> | 2019-10-13 21:43:14 +0100 |
commit | d1e2762535d1c187436a040c5bd0d743d2739e38 (patch) | |
tree | 440d0f5be11c1e4d49b9da9cce6ffdc2687821ae | |
parent | 5fcb80efb242a6c23095935c3fcf80ea8c10dd77 (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>
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> |