From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=40.107.0.77; helo=eur02-am5-obe.outbound.protection.outlook.com; envelope-from=meenakshi.aggarwal@nxp.com; receiver=edk2-devel@lists.01.org Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00077.outbound.protection.outlook.com [40.107.0.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id A461C223230CB for ; Fri, 16 Feb 2018 00:49:16 -0800 (PST) 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=FaiKnuLgA5xR8H0D0eqCu1HWVshhuhNISAJbvStbbsU=; b=Z32I2yx1xPZ0gzmTGkJYpZ8xVMjyvXKokU7yw12PLZJW5Bys4eT4F8Go1DZ5o/J072Rb+W+/j4c5lSsjeycGjW48JqPSS9MiTpGJA3qCOpLo3qwRzSgM5oMsM72pfe1S8kR7FG4nJDES9pO7xm9ArcQfpGy5GikvyYVDi/ZYNbg= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=meenakshi.aggarwal@nxp.com; Received: from idcbfarm.ap.freescale.net (192.88.169.1) by VI1PR04MB1008.eurprd04.prod.outlook.com (2a01:111:e400:5090::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.485.10; Fri, 16 Feb 2018 08:55:03 +0000 From: Meenakshi To: ard.biesheuvel@linaro.org, leif.lindholm@linaro.org, michael.d.kinney@intel.com, edk2-devel@lists.01.org Date: Fri, 16 Feb 2018 14:20:30 +0530 Message-Id: <1518771035-6733-35-git-send-email-meenakshi.aggarwal@nxp.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1518771035-6733-1-git-send-email-meenakshi.aggarwal@nxp.com> References: <1518771035-6733-1-git-send-email-meenakshi.aggarwal@nxp.com> MIME-Version: 1.0 X-Originating-IP: [192.88.169.1] X-ClientProxiedBy: HK2PR02CA0172.apcprd02.prod.outlook.com (2603:1096:201:1f::32) To VI1PR04MB1008.eurprd04.prod.outlook.com (2a01:111:e400:5090::28) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 26d851dd-bef7-452f-81d5-08d5751afa40 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(48565401081)(5600026)(4604075)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603307)(7153060)(7193020); SRVR:VI1PR04MB1008; X-Microsoft-Exchange-Diagnostics: 1; VI1PR04MB1008; 3:0tPCb4kgRhdDHbmMd9VBk8hjNDhfXMt3QtEozfni7VWGoIZE/48bbjdb5IQhEy6gmhwmBbSu7/ZvN1ZG1SdJXyoFx39cuIIkV16dop0++aKW1MeOzpZq07qw8cU4wAPTGgL/rZMXh4cfNSfc95sUMKagpY9HbEF9CFdIUCjua2ItKeAWx6LIuHsL4xW0lZNXA0dyL4TdpB0hxGO8wiy+7GzXGsujGlKwYMRIJWdeXicrJwW8MkZfwhtn8sBYmCeI; 25:D/jPytpqXUagG7NoxXmqlY5PFRh8gDCiOcTzpQVRP7a3RFCwa5DxoPTDYljQp3orolx6CFCdsWy0P8gW/F+jAomE1qEgmLCj6tFOpg7Cl+0DTojfgsiXTP3WjF8fR8ZpXpDt6FfrSxXIcGuY/cPwVNbRWxMS0Szd59qP/PgBy6+HMZV7XG4BiVzWTjV5ORBKMgWKcK7bEEwlcJlhx7WrUL2oIFGv/avUebditCqSqtSXqgKRx/dzByPKgvDU8W4gjBIjZRdkLmIEhLe/HnRoVjnkjddqr1LxUIK7fssFQGeHIi+1Uc2v2H+4To9ucY7PLpmHu3tvPp05orcNCWH0hw==; 31:cbeXn96AuUXHyi2q1rxBNt2OBs5hS/Nu7Qz308wHHNOOG/gKQuaOLlsqI1HRdDnZSrdy7tovzlKMZz2f3uY8fApW/+VZ8/gTrHy4oweZ2RUPi85NjDPJrbghlrCBoJ7n3WViix3dSKWUrOrx8B8jEEVKY5brj/brG5Xx6lWjoS8/xGkrPYAbaHBSiV+hTalb7oMdAiloegK7bs3Lbq2Z4o7mE0yP4Z1flYtC2JdfDKE= X-MS-TrafficTypeDiagnostic: VI1PR04MB1008: X-Microsoft-Exchange-Diagnostics: 1; VI1PR04MB1008; 20:an5NqtX6mxTGqB0YMMz+N1Ianr04cVdzttmqt+PVdoW03ByexiwCzbV0x71jq75bTWQBTJO+4nq7oM8ScgV7HHzlcG+MWhvlJf49aoI7sSqk7tLKbspsOJtZcP2PEyQWTuwklGT+ItMtTDv365YNbgR73nf/SAdo0gRg9Dg9OJic2NhmJE+Q2eXHfq5X/v7X9aNGrPepCaAtk1xN8amgYOYlm2O5nPm5IPnTEyfQh1c4YOrBhFR20+jFfE8aLBXNhInJuH5Sygr53RMgmN5GxlCr0wYlBJf7DoydtyNcpYX9SePDuubUnZ89ZB0HkgR0zwETyk6ucQ4ystGfzxIra4NzFdZJuagzApDKBfQncMOjs78NVYce2p/BjC0u4et28ytOz8w8gqtJxtWrmNDYLCui3SG9T4YMq1+qlljKr7HpygWycspJafRlmRKgX3R4X9EhMmFfYb72JaEd3THfGfk/RO0+O3iTXTZDmteFSfq7uyEgQlDKBG/chncl/EcY; 4:4z0hFTMAtRTvYp10SMeCptj7whC9v8Gv4QEFkktl/RJ+SaOxkIafvWgAJ6FixyiqJiEoq5HsuCaZ1HJf/7duIgQd5mXqOj4M/5d4Yp3X7Wp3mF/p3MSGM95OZOja4cdoeAThVSzd1ZpNgKCcXmDGosifvrQkc/Gie+edDH5rPzLaXcZruBOjF/kcGo/ZRIvHwGwuaZHv/6ERCM3J9KG1tRrTgcTLDv3zQDAe1nmmA6Ju0TJR25memISAa0Y7eIPK92KYcJxVypcqEUyf7cvluXtGUifBoTZygYD49xMjrS06OG86g3E4IoMg2EgroCAG X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040501)(2401047)(8121501046)(5005006)(93006095)(93001095)(10201501046)(3002001)(3231101)(944501161)(6055026)(6041288)(20161123558120)(20161123564045)(20161123560045)(20161123562045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(6072148)(201708071742011); SRVR:VI1PR04MB1008; BCL:0; PCL:0; RULEID:; SRVR:VI1PR04MB1008; X-Forefront-PRVS: 0585417D7B X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(346002)(376002)(39380400002)(396003)(39860400002)(366004)(199004)(189003)(86362001)(6486002)(8676002)(76176011)(36756003)(53376002)(966005)(4326008)(6116002)(15188155005)(16799955002)(7736002)(386003)(68736007)(186003)(26005)(53936002)(305945005)(16526019)(81156014)(3846002)(6506007)(478600001)(15760500003)(50226002)(16586007)(8936002)(2950100002)(316002)(2906002)(59450400001)(25786009)(97736004)(50466002)(48376002)(105586002)(52116002)(47776003)(81166006)(51416003)(5660300001)(6666003)(106356001)(66066001)(54906003)(6306002)(6512007)(44824005)(19627235001); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR04MB1008; H:idcbfarm.ap.freescale.net; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; VI1PR04MB1008; 23:VLy9FAm4ejrfLpvGkWdyMrlITSOZAiZWpyVdWzHtQ?= =?us-ascii?Q?NmQHQNNSozOh50dwfzIH9fHrLzib4whOgYKaK9esN70T89kv2tMdNDj2Rtt5?= =?us-ascii?Q?OTDCsGN8tZ6lWYKQ6N7139mqYB50BgTD7SgxTRLN5uQJvaRR9uGQgkxNAFI7?= =?us-ascii?Q?MqvqxSebLwb391UMET3Kwt3RGT5T1yfAgB9GNoF/HVEXVq6G+1l9PUXTfw9+?= =?us-ascii?Q?BwttmfoO9MvJuukY2si1xClmw0r1gek25iAeYCbfpasnJqpJCGpkoWMDiMuB?= =?us-ascii?Q?O0rnZ4eYKRTu7OIaROj9dAHqwiA5oO6HiLYlKJe4juFcuHttyvbze4JnBKgm?= =?us-ascii?Q?/M3qMadBqQuTZTuKzZmEnVclwwRg42ruuk2S56d1ZzHIm/eZJ224tGzApoAk?= =?us-ascii?Q?1lvqKSyKBSKldIc/0nmnigypuDZv2oW7SzuwBjFELjn5Cbzf0vDRqnOkFd4X?= =?us-ascii?Q?Kt/RMfLAiOhkUF/hUf+GhrRYsv4fbrnxyTgTLQgReINU/uYuaNWYu6s0wont?= =?us-ascii?Q?CVv6ons9ywc3zISDl7y5p5NAe/yn6UeSzvFkqXt7D/RQjq/C2ap5DL4Ba/7t?= =?us-ascii?Q?TC8o0hsVW8YuwOd5cTLJpX4RuNQAUnw9RAiTFqiNdjz5AwabPL+LrE8ueX5S?= =?us-ascii?Q?DUF9gPJUg3Ip5aEayQmg1izTxDFXmobKUZn6o/5w4RDDy0rGCoabEGfZf1g0?= =?us-ascii?Q?MsYFFWmFj7d/rMK9IrZ3827wvfRTCSfDuYlBlllzJwH0TakftflF3HPyEmAl?= =?us-ascii?Q?EXN66FZc+IHg8n56u3/I+lFlCGikPldoX3NHGX9MZVux0S1gfV3c3OhQ62RE?= =?us-ascii?Q?HtjRBCm23Oy8OPJKr16HtCfOBJGSqeV4G5lEr8OCQsnEQkBZhr86QH+WRtoF?= =?us-ascii?Q?qpg02nC/Uxzdj0TiyauGAEwcmjAFe4GW0auLYqwov1rNFsyEtGlGZNNFep+m?= =?us-ascii?Q?EoUk56UmvEaB7U53MoP5WsdYEzyMn9R0QY5Qzy90CRVSUmxYyGysezX/vZK8?= =?us-ascii?Q?x07l2Lic8oDdu3u9RT9tcvJoU9lEFlPCmR2XQRtFzoD8leGM2Dz+T5xNmA4h?= =?us-ascii?Q?7O35XUfU/T5OBjZU62vGa1UaR+96XbMx1aGHc2C/HLn+HP8B4Q4bwhTAMQtI?= =?us-ascii?Q?M0TmbeOmWNW7DEu1nKB0Jky0XKpoEcvMsjyDnpiJZ3QLMCc9j4g4oFQcPHBr?= =?us-ascii?Q?rkfajbAK82McvBNMy1oCFIWjJu0lVHQXOSQtxu0GQJy488px1mcV6S7hvcsi?= =?us-ascii?Q?SK86TXVxvNfnOriXoez2P6sqP/sr60jfK5/fVqEO53LF4yDbB/81g6nYxBDP?= =?us-ascii?Q?All/w9MBcgkVfcc97ng43k=3D?= X-Microsoft-Exchange-Diagnostics: 1; VI1PR04MB1008; 6:2pJMZIee770mBAgUDI4MgI0rCz86sUQgvJff5jaRdY3yPZbX0tkKn94du82IJp+ODZomVLe9eUIMyXqQQxmBNavpH8MmNnT0xXwWEp6K44mD8aBqWS8zTwdVMfdUM4kuFXgiuerG4KJf8Ka7ttdy1PP0eY/JAj8ov7v/FBr+UkklW1ge3BIa1CPjiMusWXCXng5FiqdqSgsr+8tT87BuxC15ICj8kdak4CzmrStROJM/VyzDK14xhPWuS5KbAJiSTrvKIVlKUjXcrEO69xqWP2kvZ5NVmMJ/yr9QPZxG57rmecjrj2RlyJGmwzjmMsGvPyO6qkVBxf8TOd05AQZjQ6+F+YQaCiIWFDV5UReDOBo=; 5:xQ9I/sqDi7pgYvXN9/nvaXGinI1jrcvDSLKLyBRZAqZNzGg6JLtfJrtQjfK+i8mHrx7u4q5hoRITjhXsfiQaZdRMAMykJMBfIkQKsYyVCq9ZdacDnuToxXlEj5sp0nnQLl7XP8DzW+6IG68NsimvrthAMGFb+QoJxHV0FwmaNyo=; 24:BtAdXHN0TNKqOwu98lcGJt3lr6KRoa+LZDlhEYpnd3VPG7v0Wf3M4GWA8rydwgnpOURPsuwUhPSAHKI13ZNnX530eZMboF5JZ4Cl/z3yK3Q=; 7:LDoTptAZ+TIr0RjSjle+ef1leWZYwMBCpOwHVQaNUaKBwyYoDM5V7xTc4rap192U5xgMGQM+5nYCkrnPuj0NM0h0NryDvEfbORPPOU0wJj+ocA5LNq6A7YsTaIoAzD/UUN039c4N90Se3Z87WwRnZGcl2npz2q+eG4vKQK1DPN+fTE1BfcuIZhP9W2xIIiP/Sz7Bax9DRlJuwmO0/8whoAUzRQ3x/Z0TuQHaMRDbMWpiUSASnb2ART6e20u5xOI5 SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Feb 2018 08:55:03.8111 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 26d851dd-bef7-452f-81d5-08d5751afa40 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR04MB1008 Subject: [PATCH edk2-platforms 34/39] Silicon/NXP: Implement EFI_CPU_IO2_PROTOCOL X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Feb 2018 08:49:17 -0000 Content-Type: text/plain 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 + http://opensource.org/licenses/bsd-license.php + + 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 +# http://opensource.org/licenses/bsd-license.php +# +# 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