>-----Original Message----- >From: Ard Biesheuvel [mailto:ard.biesheu...@linaro.org] >Sent: Friday, April 20, 2018 2:11 PM >To: Meenakshi Aggarwal <meenakshi.aggar...@nxp.com> >Cc: Leif Lindholm <leif.lindh...@linaro.org>; Kinney, Michael D ><michael.d.kin...@intel.com>; edk2-devel@lists.01.org; Udit Kumar ><udit.ku...@nxp.com>; Varun Sethi <v.se...@nxp.com>; Vabhav Sharma ><vabhav.sha...@nxp.com> >Subject: Re: [PATCH edk2-platforms 34/39] Silicon/NXP: Implement >EFI_CPU_IO2_PROTOCOL > >On 16 February 2018 at 09:50, Meenakshi <meenakshi.aggar...@nxp.com> >wrote: >> From: Vabhav <vabhav.sha...@nxp.com> >> >> NXP SOC has mutiple PCIe RCs,Adding respective implementation of >> EFI_CPU_IO2_PROTOCOL to provide Memory Space Read/Write functions used >> by generic Host Bridge Driver including correct value for the >> translation offset during MMIO accesses >> >> Contributed-under: TianoCore Contribution Agreement 1.1 >> Signed-off-by: Vabhav <vabhav.sha...@nxp.com> >> Signed-off-by: Meenakshi Aggarwal <meenakshi.aggar...@nxp.com> > >This driver looks completely wrong to me: MMIO access is memory mapped, and >given that you don't implement PCI to CPU translation of MMIO accesses, the >memory read and write functions should not perform any translation at all, and >just relay the accesses. On the other hand, the I/O accessors are not >implemented at all, and these are the ones that require translation, given >that the >I/O port addresses in the CPU space need translation to MMIO addressess.
On NXP SoC, Mapping between CPU view and PCIe view is not 1:1 and require CPU view translation for MMIO regions access, Accordingly translation is added during memory read/write services. Bus driver relays the address range where PCIe device Bar region is split from, Translation is required for relaying it to correct PCIe controller cpu view address. > >Also, you don't seem to be using the PcdPciExp?BaseAddr PCDs anywhere, so you >can drop them from the .dsc No, It's used for checking the access to MMIO32 region and CPU view base address varies between different NXP SoCs > >> --- >> Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c | 529 >++++++++++++++++++++++ >> Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf | 48 ++ >> 2 files changed, 577 insertions(+) >> create mode 100644 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c >> create mode 100644 Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf >> >> diff --git a/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c >> b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c >> new file mode 100644 >> index 0000000..b5fb72c >> --- /dev/null >> +++ b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.c >> @@ -0,0 +1,529 @@ >> +/** @file >> + Produces the CPU I/O 2 Protocol. >> + >> + Copyright (c) 2009 - 2012, Intel Corporation. All rights >> + reserved.<BR> Copyright (c) 2016, Linaro Ltd. All rights >> + reserved.<BR> Copyright 2018 NXP >> + >> + This program and the accompanying materials are licensed and made >> + available under the terms and conditions of the BSD License which >> + accompanies this distribution. The full text of the license may be >> + found at >> + >> + https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fop >> + ensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Cvabhav.shar >> + >ma%40nxp.com%7C4507c0726b244ad6476d08d5a69a64ee%7C686ea1d3bc2b4c >6fa9 >> + >2cd99c5c301635%7C0%7C0%7C636598104414046440&sdata=IFSU0%2FeTdWrw >gg0f >> + 0Lq2qSVGgogG68tYZevrRmC%2BkV8%3D&reserved=0 >> + >> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >> + BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER >EXPRESS OR IMPLIED. >> + >> +**/ >> + >> +#include <Library/BaseLib.h> >> +#include <Library/DebugLib.h> >> +#include <Library/IoLib.h> >> +#include <Library/PcdLib.h> >> +#include <Library/UefiBootServicesTableLib.h> >> +#include <Pcie.h> >> +#include <Protocol/CpuIo2.h> >> + >> +#define MAX_IO_PORT_ADDRESS PCI_SEG2_PORTIO_MAX >> + >> +// >> +// Handle for the CPU I/O 2 Protocol >> +// >> +STATIC EFI_HANDLE mHandle; >> + >> +// >> +// Lookup table for increment values based on transfer widths // >> +STATIC CONST UINT8 mInStride[] = { >> + 1, // EfiCpuIoWidthUint8 >> + 2, // EfiCpuIoWidthUint16 >> + 4, // EfiCpuIoWidthUint32 >> + 8, // EfiCpuIoWidthUint64 >> + 0, // EfiCpuIoWidthFifoUint8 >> + 0, // EfiCpuIoWidthFifoUint16 >> + 0, // EfiCpuIoWidthFifoUint32 >> + 0, // EfiCpuIoWidthFifoUint64 >> + 1, // EfiCpuIoWidthFillUint8 >> + 2, // EfiCpuIoWidthFillUint16 >> + 4, // EfiCpuIoWidthFillUint32 >> + 8 // EfiCpuIoWidthFillUint64 >> +}; >> + >> +// >> +// Lookup table for increment values based on transfer widths // >> +STATIC CONST UINT8 mOutStride[] = { >> + 1, // EfiCpuIoWidthUint8 >> + 2, // EfiCpuIoWidthUint16 >> + 4, // EfiCpuIoWidthUint32 >> + 8, // EfiCpuIoWidthUint64 >> + 1, // EfiCpuIoWidthFifoUint8 >> + 2, // EfiCpuIoWidthFifoUint16 >> + 4, // EfiCpuIoWidthFifoUint32 >> + 8, // EfiCpuIoWidthFifoUint64 >> + 0, // EfiCpuIoWidthFillUint8 >> + 0, // EfiCpuIoWidthFillUint16 >> + 0, // EfiCpuIoWidthFillUint32 >> + 0 // EfiCpuIoWidthFillUint64 >> +}; >> + >> +/** >> + Check parameters to a CPU I/O 2 Protocol service request. >> + >> + The I/O operations are carried out exactly as requested. The caller >> + is responsible for satisfying any alignment and I/O width >> + restrictions that a PI System on a platform might require. For >> + example on some platforms, width requests of >> + EfiCpuIoWidthUint64 do not work. >> + >> + @param[in] MmioOperation TRUE for an MMIO operation, FALSE for I/O >Port operation. >> + @param[in] Width Signifies the width of the I/O or Memory >> operation. >> + @param[in] Address The base address of the I/O operation. >> + @param[in] Count The number of I/O operations to perform. The >number of >> + bytes moved is Width size * Count, starting at >> Address. >> + @param[in] Buffer For read operations, the destination buffer to >> store >the results. >> + For write operations, the source buffer from >> which to write >data. >> + >> + @retval EFI_SUCCESS The parameters for this request pass the >> checks. >> + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. >> + @retval EFI_INVALID_PARAMETER Buffer is NULL. >> + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given >> Width. >> + @retval EFI_UNSUPPORTED The address range specified by Address, >Width, >> + and Count is not valid for this PI system. >> + >> +**/ >> +STATIC >> +EFI_STATUS >> +CpuIoCheckParameter ( >> + IN BOOLEAN MmioOperation, >> + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, >> + IN UINT64 Address, >> + IN UINTN Count, >> + IN VOID *Buffer >> + ) >> +{ >> + UINT64 MaxCount; >> + UINT64 Limit; >> + >> + // >> + // Check to see if Buffer is NULL >> + // >> + if (Buffer == NULL) { >> + ASSERT (FALSE); >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + // >> + // Check to see if Width is in the valid range // if >> + ((UINT32)Width >= EfiCpuIoWidthMaximum) { >> + ASSERT (FALSE); >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + // >> + // For FIFO type, the target address won't increase during the >> + access, // so treat Count as 1 // if (Width >= >> + EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) { >> + Count = 1; >> + } >> + >> + // >> + // Check to see if Width is in the valid range for I/O Port >> + operations // Width = (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03); >> + if (!MmioOperation && (Width == EfiCpuIoWidthUint64)) { >> + ASSERT (FALSE); >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + // >> + // Check to see if Address is aligned // if ((Address & >> + (UINT64)(mInStride[Width] - 1)) != 0) { >> + ASSERT (FALSE); >> + return EFI_UNSUPPORTED; >> + } >> + >> + // >> + // Check to see if any address associated with this transfer >> + exceeds the maximum // allowed address. The maximum address >> + implied by the parameters passed in is // Address + Size * Count. >> + If the following condition is met, then the transfer // is not supported. >> + // >> + // Address + Size * Count > (MmioOperation ? MAX_ADDRESS : >MAX_IO_PORT_ADDRESS) + 1 >> + // >> + // Since MAX_ADDRESS can be the maximum integer value supported by >> + the CPU and Count // can also be the maximum integer value >> + supported by the CPU, this range // check must be adjusted to avoid all >oveflow conditions. >> + // >> + Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS); if >> + (Count == 0) { >> + if (Address > Limit) { >> + ASSERT (FALSE); >> + return EFI_UNSUPPORTED; >> + } >> + } else { >> + MaxCount = RShiftU64 (Limit, Width); >> + if (MaxCount < (Count - 1)) { >> + ASSERT (FALSE); >> + return EFI_UNSUPPORTED; >> + } >> + if (Address > LShiftU64 (MaxCount - Count + 1, Width)) { >> + ASSERT (FALSE); >> + return EFI_UNSUPPORTED; >> + } >> + } >> + >> + // >> + // Check to see if Buffer is aligned // if (((UINTN)Buffer & >> + ((MIN (sizeof (UINTN), mInStride[Width]) - 1))) != 0) { >> + ASSERT (FALSE); >> + return EFI_UNSUPPORTED; >> + } >> + >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + Reads memory-mapped registers. >> + >> + The I/O operations are carried out exactly as requested. The caller >> + is responsible for satisfying any alignment and I/O width >> + restrictions that a PI System on a platform might require. For >> + example on some platforms, width requests of >> + EfiCpuIoWidthUint64 do not work. >> + >> + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, >> + EfiCpuIoWidthUint32, or EfiCpuIoWidthUint64, then both Address and >> + Buffer are incremented for each of the Count operations that is performed. >> + >> + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, >> + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only >> + Buffer is incremented for each of the Count operations that is >> + performed. The read or write operation is performed Count times on the >same Address. >> + >> + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, >> + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only >> + Address is incremented for each of the Count operations that is >> + performed. The read or write operation is performed Count times from the >first element of Buffer. >> + >> + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. >> + @param[in] Width Signifies the width of the I/O or Memory operation. >> + @param[in] Address The base address of the I/O operation. >> + @param[in] Count The number of I/O operations to perform. The number >of >> + bytes moved is Width size * Count, starting at >> Address. >> + @param[out] Buffer For read operations, the destination buffer to store >> the >results. >> + For write operations, the source buffer from which >> to write data. >> + >> + @retval EFI_SUCCESS The data was read from or written to the PI >system. >> + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. >> + @retval EFI_INVALID_PARAMETER Buffer is NULL. >> + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given >> Width. >> + @retval EFI_UNSUPPORTED The address range specified by Address, >Width, >> + and Count is not valid for this PI system. >> + >> +**/ >> +STATIC >> +EFI_STATUS >> +EFIAPI >> +CpuMemoryServiceRead ( >> + IN EFI_CPU_IO2_PROTOCOL *This, >> + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, >> + IN UINT64 Address, >> + IN UINTN Count, >> + OUT VOID *Buffer >> + ) >> +{ >> + EFI_STATUS Status; >> + UINT8 InStride; >> + UINT8 OutStride; >> + EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth; >> + UINT8 *Uint8Buffer; >> + >> + Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); >> + if (EFI_ERROR (Status)) { >> + return Status; >> + } >> + >> + if ((Address >= PCI_SEG0_MMIO32_MIN) && >> + (Address <= PCI_SEG0_MMIO32_MAX)) { >> + Address += PCI_SEG0_MMIO_MEMBASE; } else if ((Address >= >> + PCI_SEG1_MMIO32_MIN) && >> + (Address <= PCI_SEG1_MMIO32_MAX)) { >> + Address += PCI_SEG1_MMIO_MEMBASE; } else if ((Address >= >> + PCI_SEG2_MMIO32_MIN) && >> + (Address <= PCI_SEG2_MMIO32_MAX)) { >> + Address += PCI_SEG2_MMIO_MEMBASE; } else if ((Address >= >> + PCI_SEG3_MMIO32_MIN) && >> + (Address <= PCI_SEG3_MMIO32_MAX)) { >> + Address += PCI_SEG3_MMIO_MEMBASE; } else { >> + ASSERT (FALSE); >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + // >> + // Select loop based on the width of the transfer >> + // >> + InStride = mInStride[Width]; >> + OutStride = mOutStride[Width]; >> + OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03); >> + for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += >OutStride, Count--) { >> + if (OperationWidth == EfiCpuIoWidthUint8) { >> + *Uint8Buffer = MmioRead8 ((UINTN)Address); >> + } else if (OperationWidth == EfiCpuIoWidthUint16) { >> + *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address); >> + } else if (OperationWidth == EfiCpuIoWidthUint32) { >> + *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address); >> + } else if (OperationWidth == EfiCpuIoWidthUint64) { >> + *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address); >> + } >> + } >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + Writes memory-mapped registers. >> + >> + The I/O operations are carried out exactly as requested. The caller >> + is responsible for satisfying any alignment and I/O width >> + restrictions that a PI System on a platform might require. For >> + example on some platforms, width requests of >> + EfiCpuIoWidthUint64 do not work. >> + >> + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, >> + EfiCpuIoWidthUint32, or EfiCpuIoWidthUint64, then both Address and >> + Buffer are incremented for each of the Count operations that is performed. >> + >> + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, >> + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only >> + Buffer is incremented for each of the Count operations that is >> + performed. The read or write operation is performed Count times on the >same Address. >> + >> + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, >> + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only >> + Address is incremented for each of the Count operations that is >> + performed. The read or write operation is performed Count times from the >first element of Buffer. >> + >> + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. >> + @param[in] Width Signifies the width of the I/O or Memory operation. >> + @param[in] Address The base address of the I/O operation. >> + @param[in] Count The number of I/O operations to perform. The number >of >> + bytes moved is Width size * Count, starting at >> Address. >> + @param[in] Buffer For read operations, the destination buffer to store >> the >results. >> + For write operations, the source buffer from which >> to write data. >> + >> + @retval EFI_SUCCESS The data was read from or written to the PI >system. >> + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. >> + @retval EFI_INVALID_PARAMETER Buffer is NULL. >> + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given >> Width. >> + @retval EFI_UNSUPPORTED The address range specified by Address, >Width, >> + and Count is not valid for this PI system. >> + >> +**/ >> +STATIC >> +EFI_STATUS >> +EFIAPI >> +CpuMemoryServiceWrite ( >> + IN EFI_CPU_IO2_PROTOCOL *This, >> + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, >> + IN UINT64 Address, >> + IN UINTN Count, >> + IN VOID *Buffer >> + ) >> +{ >> + EFI_STATUS Status; >> + UINT8 InStride; >> + UINT8 OutStride; >> + EFI_CPU_IO_PROTOCOL_WIDTH OperationWidth; >> + UINT8 *Uint8Buffer; >> + >> + Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); >> + if (EFI_ERROR (Status)) { >> + return Status; >> + } >> + >> + if ((Address >= PCI_SEG0_MMIO32_MIN) && >> + (Address <= PCI_SEG0_MMIO32_MAX)) { >> + Address += PCI_SEG0_MMIO_MEMBASE; } else if ((Address >= >> + PCI_SEG1_MMIO32_MIN) && >> + (Address <= PCI_SEG1_MMIO32_MAX)) { >> + Address += PCI_SEG1_MMIO_MEMBASE; } else if ((Address >= >> + PCI_SEG2_MMIO32_MIN) && >> + (Address <= PCI_SEG2_MMIO32_MAX)) { >> + Address += PCI_SEG2_MMIO_MEMBASE; } else if ((Address >= >> + PCI_SEG3_MMIO32_MIN) && >> + (Address <= PCI_SEG3_MMIO32_MAX)) { >> + Address += PCI_SEG3_MMIO_MEMBASE; } else { >> + ASSERT (FALSE); >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + // >> + // Select loop based on the width of the transfer >> + // >> + InStride = mInStride[Width]; >> + OutStride = mOutStride[Width]; >> + OperationWidth = (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03); >> + for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += >OutStride, Count--) { >> + if (OperationWidth == EfiCpuIoWidthUint8) { >> + MmioWrite8 ((UINTN)Address, *Uint8Buffer); >> + } else if (OperationWidth == EfiCpuIoWidthUint16) { >> + MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer)); >> + } else if (OperationWidth == EfiCpuIoWidthUint32) { >> + MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer)); >> + } else if (OperationWidth == EfiCpuIoWidthUint64) { >> + MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer)); >> + } >> + } >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + Reads I/O registers. >> + >> + The I/O operations are carried out exactly as requested. The caller >> + is responsible for satisfying any alignment and I/O width >> + restrictions that a PI System on a platform might require. For >> + example on some platforms, width requests of >> + EfiCpuIoWidthUint64 do not work. >> + >> + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, >> + EfiCpuIoWidthUint32, or EfiCpuIoWidthUint64, then both Address and >> + Buffer are incremented for each of the Count operations that is performed. >> + >> + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, >> + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only >> + Buffer is incremented for each of the Count operations that is >> + performed. The read or write operation is performed Count times on the >same Address. >> + >> + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, >> + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only >> + Address is incremented for each of the Count operations that is >> + performed. The read or write operation is performed Count times from the >first element of Buffer. >> + >> + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. >> + @param[in] Width Signifies the width of the I/O or Memory operation. >> + @param[in] Address The base address of the I/O operation. >> + @param[in] Count The number of I/O operations to perform. The number >of >> + bytes moved is Width size * Count, starting at >> Address. >> + @param[out] Buffer For read operations, the destination buffer to store >> the >results. >> + For write operations, the source buffer from which >> to write data. >> + >> + @retval EFI_SUCCESS The data was read from or written to the PI >system. >> + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. >> + @retval EFI_INVALID_PARAMETER Buffer is NULL. >> + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given >> Width. >> + @retval EFI_UNSUPPORTED The address range specified by Address, >Width, >> + and Count is not valid for this PI system. >> + >> +**/ >> +STATIC >> +EFI_STATUS >> +EFIAPI >> +CpuIoServiceRead ( >> + IN EFI_CPU_IO2_PROTOCOL *This, >> + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, >> + IN UINT64 Address, >> + IN UINTN Count, >> + OUT VOID *Buffer >> + ) >> +{ >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + Write I/O registers. >> + >> + The I/O operations are carried out exactly as requested. The caller >> + is responsible for satisfying any alignment and I/O width >> + restrictions that a PI System on a platform might require. For >> + example on some platforms, width requests of >> + EfiCpuIoWidthUint64 do not work. >> + >> + If Width is EfiCpuIoWidthUint8, EfiCpuIoWidthUint16, >> + EfiCpuIoWidthUint32, or EfiCpuIoWidthUint64, then both Address and >> + Buffer are incremented for each of the Count operations that is performed. >> + >> + If Width is EfiCpuIoWidthFifoUint8, EfiCpuIoWidthFifoUint16, >> + EfiCpuIoWidthFifoUint32, or EfiCpuIoWidthFifoUint64, then only >> + Buffer is incremented for each of the Count operations that is >> + performed. The read or write operation is performed Count times on the >same Address. >> + >> + If Width is EfiCpuIoWidthFillUint8, EfiCpuIoWidthFillUint16, >> + EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64, then only >> + Address is incremented for each of the Count operations that is >> + performed. The read or write operation is performed Count times from the >first element of Buffer. >> + >> + @param[in] This A pointer to the EFI_CPU_IO2_PROTOCOL instance. >> + @param[in] Width Signifies the width of the I/O or Memory operation. >> + @param[in] Address The base address of the I/O operation. >> + @param[in] Count The number of I/O operations to perform. The number >of >> + bytes moved is Width size * Count, starting at >> Address. >> + @param[in] Buffer For read operations, the destination buffer to store >> the >results. >> + For write operations, the source buffer from which >> to write data. >> + >> + @retval EFI_SUCCESS The data was read from or written to the PI >system. >> + @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. >> + @retval EFI_INVALID_PARAMETER Buffer is NULL. >> + @retval EFI_UNSUPPORTED The Buffer is not aligned for the given >> Width. >> + @retval EFI_UNSUPPORTED The address range specified by Address, >Width, >> + and Count is not valid for this PI system. >> + >> +**/ >> +STATIC >> +EFI_STATUS >> +EFIAPI >> +CpuIoServiceWrite ( >> + IN EFI_CPU_IO2_PROTOCOL *This, >> + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, >> + IN UINT64 Address, >> + IN UINTN Count, >> + IN VOID *Buffer >> + ) >> +{ >> + return EFI_SUCCESS; >> +} >> + >> +// >> +// CPU I/O 2 Protocol instance >> +// >> +STATIC EFI_CPU_IO2_PROTOCOL mCpuIo2 = { >> + { >> + CpuMemoryServiceRead, >> + CpuMemoryServiceWrite >> + }, >> + { >> + CpuIoServiceRead, >> + CpuIoServiceWrite >> + } >> +}; >> + >> + >> +/** >> + The user Entry Point for module CpuIo2Dxe. The user code starts with this >function. >> + >> + @param[in] ImageHandle The firmware allocated handle for the EFI image. >> + @param[in] SystemTable A pointer to the EFI System Table. >> + >> + @retval EFI_SUCCESS The entry point is executed successfully. >> + @retval other Some error occurs when executing this entry >> point. >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +PciCpuIo2Initialize ( >> + IN EFI_HANDLE ImageHandle, >> + IN EFI_SYSTEM_TABLE *SystemTable >> + ) >> +{ >> + EFI_STATUS Status; >> + >> + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiCpuIo2ProtocolGuid); >> + Status = gBS->InstallMultipleProtocolInterfaces ( >> + &mHandle, >> + &gEfiCpuIo2ProtocolGuid, &mCpuIo2, >> + NULL >> + ); >> + ASSERT_EFI_ERROR (Status); >> + >> + return Status; >> +} >> diff --git a/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf >> b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf >> new file mode 100644 >> index 0000000..25a1db1 >> --- /dev/null >> +++ b/Silicon/NXP/Drivers/PciCpuIo2Dxe/PciCpuIo2Dxe.inf >> @@ -0,0 +1,48 @@ >> +## @file >> +# Produces the CPU I/O 2 Protocol by using the services of the I/O Library. >> +# >> +# Copyright 2018 NXP >> +# >> +# This program and the accompanying materials # are licensed and made >> +available under the terms and conditions of the BSD License # which >> +accompanies this distribution. The full text of the license may be >> +found at # >> +https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fope >> +nsource.org%2Flicenses%2Fbsd- >license.php&data=02%7C01%7Cvabhav.sharma >> >+%40nxp.com%7C4507c0726b244ad6476d08d5a69a64ee%7C686ea1d3bc2b4c6f >a92cd >> >+99c5c301635%7C0%7C0%7C636598104414046440&sdata=IFSU0%2FeTdWrwgg >0f0Lq2 >> +qSVGgogG68tYZevrRmC%2BkV8%3D&reserved=0 >> +# >> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >> +BASIS, # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER >EXPRESS OR IMPLIED. >> +# >> +## >> + >> +[Defines] >> + INF_VERSION = 0x0001001A >> + BASE_NAME = PciCpuIo2Dxe >> + FILE_GUID = 7bff18d7-9aae-434b-9c06-f10a7e157eac >> + MODULE_TYPE = DXE_DRIVER >> + VERSION_STRING = 1.0 >> + ENTRY_POINT = PciCpuIo2Initialize >> + >> +[Sources] >> + PciCpuIo2Dxe.c >> + >> +[Packages] >> + MdePkg/MdePkg.dec >> + Silicon/NXP/NxpQoriqLs.dec >> + >> +[LibraryClasses] >> + BaseLib >> + DebugLib >> + IoLib >> + UefiBootServicesTableLib >> + UefiDriverEntryPoint >> + >> +[Pcd] >> + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr >> + gNxpQoriqLsTokenSpaceGuid.PcdPciExp2BaseAddr >> + gNxpQoriqLsTokenSpaceGuid.PcdPciExp3BaseAddr >> + gNxpQoriqLsTokenSpaceGuid.PcdPciExp4BaseAddr >> + >> +[Protocols] >> + gEfiCpuIo2ProtocolGuid ## PRODUCES >> + >> +[Depex] >> + TRUE >> -- >> 1.9.1 >> _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel