On 24 April 2018 at 15:36, Vabhav Sharma <[email protected]> wrote: > > >>-----Original Message----- >>From: Ard Biesheuvel [mailto:[email protected]] >>Sent: Tuesday, April 24, 2018 6:04 PM >>To: Vabhav Sharma <[email protected]> >>Cc: Meenakshi Aggarwal <[email protected]>; Leif Lindholm >><[email protected]>; Kinney, Michael D <[email protected]>; >>[email protected]; Udit Kumar <[email protected]>; Varun Sethi >><[email protected]> >>Subject: Re: [PATCH edk2-platforms 34/39] Silicon/NXP: Implement >>EFI_CPU_IO2_PROTOCOL >> >>On 24 April 2018 at 14:26, Vabhav Sharma <[email protected]> wrote: >>> >>> >>>>-----Original Message----- >>>>From: Ard Biesheuvel [mailto:[email protected]] >>>>Sent: Friday, April 20, 2018 2:11 PM >>>>To: Meenakshi Aggarwal <[email protected]> >>>>Cc: Leif Lindholm <[email protected]>; Kinney, Michael D >>>><[email protected]>; [email protected]; Udit Kumar >>>><[email protected]>; Varun Sethi <[email protected]>; Vabhav Sharma >>>><[email protected]> >>>>Subject: Re: [PATCH edk2-platforms 34/39] Silicon/NXP: Implement >>>>EFI_CPU_IO2_PROTOCOL >>>> >>>>On 16 February 2018 at 09:50, Meenakshi <[email protected]> >>>>wrote: >>>>> From: Vabhav <[email protected]> >>>>> >>>>> 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 <[email protected]> >>>>> Signed-off-by: Meenakshi Aggarwal <[email protected]> >>>> >>>>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. >>> >> >>You cannot implement this only in the EFI_CPU_IO2_PROTOCOL driver. >>That way, EFI_PCI_IO_PROTOCOL.GetBarAttributes() will return resource >>descriptors with untranslated addresses, breaking drivers that rely on this >>information. >> >>If your PCIe implementation relies on MMIO translation, please refer to the >>recently merged code in EDK2 and edk2-platforms implementing this for >>Socionext SynQuacer. > Ok, PciIo->GetBarAttributes is expected to return CPU view address.
Yes > Are you referring to edk2 commit 74d0a33(Address translation support added to > generic PciHostBridge driver)? Submitted patch development is done prior to > this commit. I understand. But that does not make your code correct. > I will refer the commits for Socionext SynQuacer in edk2-platforms for MMIO > translation. Yes please. And I/O translation needs to be implemented as well. >>>> >>>>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%2F >>>>> + op >>>>> + ensource.org%2Flicenses%2Fbsd- >>license.php&data=02%7C01%7Cvabhav.sh >>>>> + ar >>>>> + >>>>ma%40nxp.com%7C4507c0726b244ad6476d08d5a69a64ee%7C686ea1d3bc2b >>4c >>>>6fa9 >>>>> + >>>>2cd99c5c301635%7C0%7C0%7C636598104414046440&sdata=IFSU0%2FeTdW >>rw >>>>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%2Fo >>>>> +pe >>>>> +nsource.org%2Flicenses%2Fbsd- >>>>license.php&data=02%7C01%7Cvabhav.sharma >>>>> >>>>+%40nxp.com%7C4507c0726b244ad6476d08d5a69a64ee%7C686ea1d3bc2b4c >>6f >>>>a92cd >>>>> >>>>+99c5c301635%7C0%7C0%7C636598104414046440&sdata=IFSU0%2FeTdWrw >>gg >>>>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 [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

