From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2607:f8b0:4001:c06::229; helo=mail-io0-x229.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-io0-x229.google.com (mail-io0-x229.google.com [IPv6:2607:f8b0:4001:c06::229]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 2D20E21E08183 for ; Tue, 24 Apr 2018 07:02:47 -0700 (PDT) Received: by mail-io0-x229.google.com with SMTP id c26-v6so22802484iob.3 for ; Tue, 24 Apr 2018 07:02:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=c92niiZCjmukk0yfCgkfyocSeAGX0uRQghokWHbpnds=; b=UYT0UBB5JI47u27cPWm/LGe+WaG3JSR9S3Fy1jC3QWShO8wGLUeNlHpKcI7fzgB89a 2Tr7jaQ7OH8GgIkSDw8k1tFLD9qCHYVFLNqHv3NG/K+Gte+r+YL0qjY6BY1z96Tdr04R oFlA+HTZcO7KAXR28F0QU1zaGVZ7UXv5tIjlM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=c92niiZCjmukk0yfCgkfyocSeAGX0uRQghokWHbpnds=; b=Qc9INdj0dn3DdMVb1a12nUS6RB/QpgSRFP9enEE0+d+pFMQQ4g9tB2mra5iL0BvIX7 +vogegMakxpOtEiKNfQwR8GDm9epXroExGI0ZgK7a66lBkE/gGfdcUJ7XVqr5bN04JPN /+87iMsioJICGwGNEfaqW2AC9GZPW4IsicNkEkeQc3DQwOMaljBr3N1OlbEcVHVU8ZXM 2uAAYVtMaWbnc7QRemJp37jKb9BBwJ07JpPAVJU7JcDgsBs+aozMaI64fXCVeaxp2Ehd sVdSjnQFn4ipq9bgiyTZS7/M6QKNDgQEPUtDq8R3ciB/ShCSa+YIYbH1l/DOA3jTmu7I YiOQ== X-Gm-Message-State: ALQs6tBV0gLOAH1bP/h12DW1n9feG/PqWbISG47MrtyGBulgNlMypDqn iejIgW+7ODHpKgYZ57AjIOEB5GKR9Bwxb5oihgzKRw== X-Google-Smtp-Source: AB8JxZocbjgWd5Ku6AKYh7onIbSlM6YMDEFYrt1XCJZ3LGBa8z3rLQLZBEWXlPt9p88JFYTpltKDtqWyHh8U/UN8l0Q= X-Received: by 2002:a6b:970d:: with SMTP id z13-v6mr24304718iod.277.1524578565810; Tue, 24 Apr 2018 07:02:45 -0700 (PDT) MIME-Version: 1.0 Received: by 10.107.187.67 with HTTP; Tue, 24 Apr 2018 07:02:45 -0700 (PDT) In-Reply-To: References: <1518771035-6733-1-git-send-email-meenakshi.aggarwal@nxp.com> <1518771035-6733-35-git-send-email-meenakshi.aggarwal@nxp.com> From: Ard Biesheuvel Date: Tue, 24 Apr 2018 16:02:45 +0200 Message-ID: To: Vabhav Sharma Cc: Meenakshi Aggarwal , Leif Lindholm , "Kinney, Michael D" , "edk2-devel@lists.01.org" , Udit Kumar , Varun Sethi Subject: Re: [PATCH edk2-platforms 34/39] Silicon/NXP: Implement EFI_CPU_IO2_PROTOCOL X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Apr 2018 14:02:48 -0000 Content-Type: text/plain; charset="UTF-8" On 24 April 2018 at 15:36, Vabhav Sharma wrote: > > >>-----Original Message----- >>From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org] >>Sent: Tuesday, April 24, 2018 6:04 PM >>To: Vabhav Sharma >>Cc: Meenakshi Aggarwal ; Leif Lindholm >>; Kinney, Michael D ; >>edk2-devel@lists.01.org; Udit Kumar ; Varun Sethi >> >>Subject: Re: [PATCH edk2-platforms 34/39] Silicon/NXP: Implement >>EFI_CPU_IO2_PROTOCOL >> >>On 24 April 2018 at 14:26, Vabhav Sharma wrote: >>> >>> >>>>-----Original Message----- >>>>From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org] >>>>Sent: Friday, April 20, 2018 2:11 PM >>>>To: Meenakshi Aggarwal >>>>Cc: Leif Lindholm ; Kinney, Michael D >>>>; edk2-devel@lists.01.org; Udit Kumar >>>>; Varun Sethi ; Vabhav Sharma >>>> >>>>Subject: Re: [PATCH edk2-platforms 34/39] Silicon/NXP: Implement >>>>EFI_CPU_IO2_PROTOCOL >>>> >>>>On 16 February 2018 at 09:50, Meenakshi >>>>wrote: >>>>> From: Vabhav >>>>> >>>>> 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 >>>>> Signed-off-by: Meenakshi Aggarwal >>>> >>>>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.
Copyright (c) 2016, Linaro Ltd. All rights >>>>> + reserved.
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 >>>>> +#include >>>>> +#include >>>>> +#include >>>>> +#include >>>>> +#include >>>>> +#include >>>>> + >>>>> +#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 >>>>>