From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=104.47.0.62; helo=eur01-he1-obe.outbound.protection.outlook.com; envelope-from=vabhav.sharma@nxp.com; receiver=edk2-devel@lists.01.org Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-he1eur01on0062.outbound.protection.outlook.com [104.47.0.62]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id E48AC2041B295 for ; Tue, 24 Apr 2018 05:40:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=iO0hvAWA5Tg3CRvS+52dKN2Mc6QfscE2ft65ErmdVDs=; b=abrcL4ovXXtB/dXs0I2y9QfO7jGr1px0IzvsYo8YSK30W+1Gy0KofNjFsW4FJf1rMjNrM3uV5HMU6XMyMFcSUhXnfQEFzM63/NhQIv3Gaj4vCZPb0z0+0JbxCycGAJr9jF5MIkt0ES1/TF3/B1/5c41cw/dyl92rUrvd7JoO2fU= Received: from DB4PR04MB299.eurprd04.prod.outlook.com (10.141.239.21) by DB4PR04MB0670.eurprd04.prod.outlook.com (10.141.42.140) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.696.15; Tue, 24 Apr 2018 12:40:11 +0000 Received: from DB4PR04MB299.eurprd04.prod.outlook.com ([fe80::2dcd:1bc7:8d4e:5dc2]) by DB4PR04MB299.eurprd04.prod.outlook.com ([fe80::2dcd:1bc7:8d4e:5dc2%15]) with mapi id 15.20.0696.017; Tue, 24 Apr 2018 12:40:11 +0000 From: Vabhav Sharma To: Leif Lindholm , Meenakshi Aggarwal CC: "ard.biesheuvel@linaro.org" , "edk2-devel@lists.01.org" , Udit Kumar , Varun Sethi Thread-Topic: [PATCH edk2-platforms 34/39] Silicon/NXP: Implement EFI_CPU_IO2_PROTOCOL Thread-Index: AQHTpwPYw6QaPQSm1Ea9jfLwpmKD0qQKJukAgAYb0SA= Date: Tue, 24 Apr 2018 12:40:11 +0000 Message-ID: References: <1518771035-6733-1-git-send-email-meenakshi.aggarwal@nxp.com> <1518771035-6733-35-git-send-email-meenakshi.aggarwal@nxp.com> <20180420151552.uujprnny4oae3g6o@bivouac.eciton.net> In-Reply-To: <20180420151552.uujprnny4oae3g6o@bivouac.eciton.net> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=vabhav.sharma@nxp.com; x-originating-ip: [14.142.187.166] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; DB4PR04MB0670; 7:dbE90unvVuhX9a5EJh67vlz85Rig0pgMBfqMKkbg/1QnBTKfrBkRcXHI2B9VRsQAzOJ8i0eUvCMfbgSV/C7oY9NN6la0V29T55J1mfOvaUQLGby6mSAwgKknVkK3YMwGZq8VFiwBdj+7LVrtDbV7PDDi2KKSB3h+VlGHYWH7PDGgjHfkrukIvfBfgUPlELHCHhrWvW57cjFcqOya3XEuOt3+nODWQ2Z5L90e06rHmzpqqHQGmtZahFr410uL0m6v x-ms-exchange-antispam-srfa-diagnostics: SOS; x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4534165)(7168020)(4627221)(201703031133081)(201702281549075)(48565401081)(2017052603328)(7153060)(7193020); SRVR:DB4PR04MB0670; x-ms-traffictypediagnostic: DB4PR04MB0670: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(189930954265078)(185117386973197)(162533806227266)(45079756050767); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(3231232)(944501410)(52105095)(10201501046)(93006095)(93001095)(3002001)(6055026)(6041310)(20161123562045)(20161123564045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123560045)(6072148)(201708071742011); SRVR:DB4PR04MB0670; BCL:0; PCL:0; RULEID:; SRVR:DB4PR04MB0670; x-forefront-prvs: 0652EA5565 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(39860400002)(39380400002)(366004)(346002)(376002)(396003)(13464003)(189003)(199004)(55016002)(54906003)(110136005)(6636002)(86362001)(229853002)(44832011)(3660700001)(6246003)(26005)(53936002)(8936002)(99286004)(8676002)(7736002)(68736007)(5250100002)(81156014)(966005)(81166006)(102836004)(305945005)(4326008)(476003)(5660300001)(6436002)(6116002)(55236004)(2906002)(105586002)(59450400001)(53946003)(6306002)(11346002)(9686003)(2900100001)(76176011)(6506007)(14454004)(3846002)(25786009)(3280700002)(316002)(97736004)(7696005)(74316002)(33656002)(486006)(16799955002)(45080400002)(106356001)(446003)(66066001)(478600001)(15760500003)(186003)(579004)(559001)(44824005)(19627235001); DIR:OUT; SFP:1101; SCL:1; SRVR:DB4PR04MB0670; H:DB4PR04MB299.eurprd04.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: 8fzl9Rr9nHFPQLcQL0B+HH7mIiqbeIFSAXEspVgV5KLBwa6rGhSy4zYzupMkTVkvKdQBZCz9rhgs5n/btl40I+9l7DS9K5gIgCjY5wJdeAWK15XFilK3N+hCRxr5/xzK1UYmc63I5ivb2yxd8cTx2zNE/jg0vzjsKN0lyb2l6OEqkKdL1zEcNAEOqxzdEqi2 spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: e9d10221-aa03-4e06-1600-08d5a9e0851a X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: e9d10221-aa03-4e06-1600-08d5a9e0851a X-MS-Exchange-CrossTenant-originalarrivaltime: 24 Apr 2018 12:40:11.2078 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB4PR04MB0670 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 12:40:16 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable >-----Original Message----- >From: Leif Lindholm [mailto:leif.lindholm@linaro.org] >Sent: Friday, April 20, 2018 8:46 PM >To: Meenakshi Aggarwal >Cc: ard.biesheuvel@linaro.org; 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 Fri, Feb 16, 2018 at 02:20:30PM +0530, 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 >> --- >> 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=3Dhttp%3A%2F%2Fop >> + ensource.org%2Flicenses%2Fbsd-license.php&data=3D02%7C01%7Cvabhav.shar >> + >ma%40nxp.com%7C42500fab2cd1447bbe6308d5a6d19d8b%7C686ea1d3bc2b4c >6fa9 >> + >2cd99c5c301635%7C0%7C0%7C636598341623135085&sdata=3DZo6s2LhxPSElw4F >XsV >> + 7%2Bx3Veb5yptglf1UQiA%2FNRRc4%3D&reserved=3D0 >> + >> + 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[] =3D { >> + 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[] =3D { >> + 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 op= eration. >> + @param[in] Address The base address of the I/O operation. >> + @param[in] Count The number of I/O operations to perform. Th= e >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 fro= m which to write >data. >> + >> + @retval EFI_SUCCESS The parameters for this request pass t= he 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 give= n Width. >> + @retval EFI_UNSUPPORTED The address range specified by Address= , >Width, >> + and Count is not valid for this PI sys= tem. >> + >> +**/ >> +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 =3D=3D NULL) { >> + ASSERT (FALSE); >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + // >> + // Check to see if Width is in the valid range // if >> + ((UINT32)Width >=3D 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 >=3D >> + EfiCpuIoWidthFifoUint8 && Width <=3D EfiCpuIoWidthFifoUint64) { >> + Count =3D 1; >> + } >> + >> + // >> + // Check to see if Width is in the valid range for I/O Port >> + operations // Width =3D (EFI_CPU_IO_PROTOCOL_WIDTH)(Width & 0x03); >> + if (!MmioOperation && (Width =3D=3D EfiCpuIoWidthUint64)) { >> + ASSERT (FALSE); >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + // >> + // Check to see if Address is aligned // if ((Address & >> + (UINT64)(mInStride[Width] - 1)) !=3D 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 suppor= ted. >> + // >> + // 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 a= ll >oveflow conditions. >> + // >> + Limit =3D (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS); if >> + (Count =3D=3D 0) { >> + if (Address > Limit) { >> + ASSERT (FALSE); >> + return EFI_UNSUPPORTED; >> + } >> + } else { >> + MaxCount =3D 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))) !=3D 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 perfo= rmed. >> + >> + 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 th= e >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 operati= on. >> + @param[in] Address The base address of the I/O operation. >> + @param[in] Count The number of I/O operations to perform. The num= ber >of >> + bytes moved is Width size * Count, starting at A= ddress. >> + @param[out] Buffer For read operations, the destination buffer to s= tore the >results. >> + For write operations, the source buffer from whi= ch to write data. >> + >> + @retval EFI_SUCCESS The data was read from or written to t= he 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 give= n Width. >> + @retval EFI_UNSUPPORTED The address range specified by Address= , >Width, >> + and Count is not valid for this PI sys= tem. >> + >> +**/ >> +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 =3D CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); >> + if (EFI_ERROR (Status)) { >> + return Status; >> + } >> + >> + if ((Address >=3D PCI_SEG0_MMIO32_MIN) && >> + (Address <=3D PCI_SEG0_MMIO32_MAX)) { >> + Address +=3D PCI_SEG0_MMIO_MEMBASE; } else if ((Address >=3D >> + PCI_SEG1_MMIO32_MIN) && >> + (Address <=3D PCI_SEG1_MMIO32_MAX)) { >> + Address +=3D PCI_SEG1_MMIO_MEMBASE; } else if ((Address >=3D >> + PCI_SEG2_MMIO32_MIN) && >> + (Address <=3D PCI_SEG2_MMIO32_MAX)) { >> + Address +=3D PCI_SEG2_MMIO_MEMBASE; } else if ((Address >=3D >> + PCI_SEG3_MMIO32_MIN) && >> + (Address <=3D PCI_SEG3_MMIO32_MAX)) { >> + Address +=3D PCI_SEG3_MMIO_MEMBASE; } else { >> + ASSERT (FALSE); >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + // >> + // Select loop based on the width of the transfer // InStride =3D >> + mInStride[Width]; OutStride =3D mOutStride[Width]; OperationWidth = =3D >> + (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03); for (Uint8Buffer =3D >> + Buffer; Count > 0; Address +=3D InStride, Uint8Buffer +=3D OutStride, >> + Count--) { > >Could you move the Address and Uint8Buffer updates to the end of the loop,= in >order to get the line length down? Ok, I will update > >> + if (OperationWidth =3D=3D EfiCpuIoWidthUint8) { >> + *Uint8Buffer =3D MmioRead8 ((UINTN)Address); >> + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint16) { >> + *((UINT16 *)Uint8Buffer) =3D MmioRead16 ((UINTN)Address); >> + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint32) { >> + *((UINT32 *)Uint8Buffer) =3D MmioRead32 ((UINTN)Address); >> + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint64) { >> + *((UINT64 *)Uint8Buffer) =3D 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 perfo= rmed. >> + >> + 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 th= e >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 operati= on. >> + @param[in] Address The base address of the I/O operation. >> + @param[in] Count The number of I/O operations to perform. The num= ber >of >> + bytes moved is Width size * Count, starting at A= ddress. >> + @param[in] Buffer For read operations, the destination buffer to s= tore the >results. >> + For write operations, the source buffer from whi= ch to write data. >> + >> + @retval EFI_SUCCESS The data was read from or written to t= he 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 give= n Width. >> + @retval EFI_UNSUPPORTED The address range specified by Address= , >Width, >> + and Count is not valid for this PI sys= tem. >> + >> +**/ >> +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 =3D CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer); >> + if (EFI_ERROR (Status)) { >> + return Status; >> + } >> + >> + if ((Address >=3D PCI_SEG0_MMIO32_MIN) && >> + (Address <=3D PCI_SEG0_MMIO32_MAX)) { >> + Address +=3D PCI_SEG0_MMIO_MEMBASE; } else if ((Address >=3D >> + PCI_SEG1_MMIO32_MIN) && >> + (Address <=3D PCI_SEG1_MMIO32_MAX)) { >> + Address +=3D PCI_SEG1_MMIO_MEMBASE; } else if ((Address >=3D >> + PCI_SEG2_MMIO32_MIN) && >> + (Address <=3D PCI_SEG2_MMIO32_MAX)) { >> + Address +=3D PCI_SEG2_MMIO_MEMBASE; } else if ((Address >=3D >> + PCI_SEG3_MMIO32_MIN) && >> + (Address <=3D PCI_SEG3_MMIO32_MAX)) { >> + Address +=3D PCI_SEG3_MMIO_MEMBASE; } else { >> + ASSERT (FALSE); >> + return EFI_INVALID_PARAMETER; >> + } > >The block above looks identical with the previous function. >Break out as a separate helper function? Ok, Yes sure. > >> + >> + // >> + // Select loop based on the width of the transfer // InStride =3D >> + mInStride[Width]; OutStride =3D mOutStride[Width]; OperationWidth = =3D >> + (EFI_CPU_IO_PROTOCOL_WIDTH) (Width & 0x03); for (Uint8Buffer =3D >> + Buffer; Count > 0; Address +=3D InStride, Uint8Buffer +=3D OutStride, >> + Count--) { > >Move Address/Uint8Buffer updates to end of loop? >(I think the use of Uint8Buffer is completely redundant here. Buffer could= be used >directly.) > >/ > Leif Ok, Reference is taken from Socionext, I will update it. > >> + if (OperationWidth =3D=3D EfiCpuIoWidthUint8) { >> + MmioWrite8 ((UINTN)Address, *Uint8Buffer); >> + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint16) { >> + MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer)); >> + } else if (OperationWidth =3D=3D EfiCpuIoWidthUint32) { >> + MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer)); >> + } else if (OperationWidth =3D=3D 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 perfo= rmed. >> + >> + 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 th= e >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 operati= on. >> + @param[in] Address The base address of the I/O operation. >> + @param[in] Count The number of I/O operations to perform. The num= ber >of >> + bytes moved is Width size * Count, starting at A= ddress. >> + @param[out] Buffer For read operations, the destination buffer to s= tore the >results. >> + For write operations, the source buffer from whi= ch to write data. >> + >> + @retval EFI_SUCCESS The data was read from or written to t= he 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 give= n Width. >> + @retval EFI_UNSUPPORTED The address range specified by Address= , >Width, >> + and Count is not valid for this PI sys= tem. >> + >> +**/ >> +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 perfo= rmed. >> + >> + 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 th= e >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 operati= on. >> + @param[in] Address The base address of the I/O operation. >> + @param[in] Count The number of I/O operations to perform. The num= ber >of >> + bytes moved is Width size * Count, starting at A= ddress. >> + @param[in] Buffer For read operations, the destination buffer to s= tore the >results. >> + For write operations, the source buffer from whi= ch to write data. >> + >> + @retval EFI_SUCCESS The data was read from or written to t= he 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 give= n Width. >> + @retval EFI_UNSUPPORTED The address range specified by Address= , >Width, >> + and Count is not valid for this PI sys= tem. >> + >> +**/ >> +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 =3D { >> + { >> + 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 i= mage. >> + @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 =3D 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 Lib= rary. >> +# >> +# 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=3Dhttp%3A%2F%2Fope >> +nsource.org%2Flicenses%2Fbsd- >license.php&data=3D02%7C01%7Cvabhav.sharma >> >+%40nxp.com%7C42500fab2cd1447bbe6308d5a6d19d8b%7C686ea1d3bc2b4c6f >a92cd >> >+99c5c301635%7C0%7C0%7C636598341623135085&sdata=3DZo6s2LhxPSElw4FXs >V7%2B >> +x3Veb5yptglf1UQiA%2FNRRc4%3D&reserved=3D0 >> +# >> +# 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 =3D 0x0001001A >> + BASE_NAME =3D PciCpuIo2Dxe >> + FILE_GUID =3D 7bff18d7-9aae-434b-9c06-f10a7e157e= ac >> + MODULE_TYPE =3D DXE_DRIVER >> + VERSION_STRING =3D 1.0 >> + ENTRY_POINT =3D 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 >>