From nobody Fri May 3 07:57:59 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1513925430852932.8052862497166; Thu, 21 Dec 2017 22:50:30 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 11A65222CB311; Thu, 21 Dec 2017 22:45:40 -0800 (PST) Received: from NAM02-SN1-obe.outbound.protection.outlook.com (mail-sn1nam02on0078.outbound.protection.outlook.com [104.47.36.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id C9446222CB309 for ; Thu, 21 Dec 2017 22:45:38 -0800 (PST) Received: from CY1PR03CA0011.namprd03.prod.outlook.com (10.174.128.21) by CY4PR03MB2694.namprd03.prod.outlook.com (10.173.43.137) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.323.15; Fri, 22 Dec 2017 06:50:25 +0000 Received: from BN1BFFO11FD044.protection.gbl (2a01:111:f400:7c10::1:142) by CY1PR03CA0011.outlook.office365.com (2603:10b6:600::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.345.14 via Frontend Transport; Fri, 22 Dec 2017 06:50:25 +0000 Received: from tx30smr01.am.freescale.net (192.88.168.50) by BN1BFFO11FD044.mail.protection.outlook.com (10.58.144.107) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.20.302.6 via Frontend Transport; Fri, 22 Dec 2017 06:50:10 +0000 Received: from uefi-OptiPlex-790.ap.freescale.net ([10.232.132.56]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id vBM6oHF2022495; Thu, 21 Dec 2017 23:50:22 -0700 X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=104.47.36.78; helo=nam02-sn1-obe.outbound.protection.outlook.com; envelope-from=vabhav.sharma@nxp.com; receiver=edk2-devel@lists.01.org Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=nxp.com; nxp.com; dkim=none (message not signed) header.d=none;nxp.com; dmarc=fail action=none header.from=nxp.com; Received-SPF: Fail (protection.outlook.com: domain of nxp.com does not designate 192.88.168.50 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.168.50; helo=tx30smr01.am.freescale.net; From: Vabhav To: , , , Date: Fri, 22 Dec 2017 00:18:27 +0530 Message-ID: <1513882109-14295-2-git-send-email-vabhav.sharma@nxp.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1513882109-14295-1-git-send-email-vabhav.sharma@nxp.com> References: <1513882109-14295-1-git-send-email-vabhav.sharma@nxp.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131583990108433390; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(336005)(7966004)(396003)(376002)(346002)(39380400002)(39860400002)(2980300002)(1110001)(1109001)(339900001)(199004)(189003)(68736007)(966005)(8936002)(5660300001)(6306002)(356003)(77096006)(59450400001)(104016004)(47776003)(4326008)(53376002)(53946003)(305945005)(15188155005)(8676002)(2906002)(36756003)(498600001)(53936002)(85426001)(2201001)(316002)(16799955002)(97736004)(106466001)(51416003)(81166006)(2950100002)(50466002)(50226002)(105606002)(48376002)(551934003)(16200700003)(110136005)(76176011)(86362001)(81156014)(575784001)(16586007)(54906003)(8656006)(559001)(579004)(569006); DIR:OUT; SFP:1101; SCL:1; SRVR:CY4PR03MB2694; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BN1BFFO11FD044; 1:/eA815DLMLRRS9FDmXnJMKziDwCX9S54zjRgr0InxriVT4BfFh3FZwC03LdRyLA8hROCGeYJwlPmqnx0t7qeWKP8iMnnzTheIKuAesRLE8rpV4MyUIXz97Q2PoxXz9pi MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d92b48c6-6ae4-4d41-abee-08d549083f01 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(5600026)(4604075)(4534020)(4628075)(201703131517081)(2017052603307); SRVR:CY4PR03MB2694; X-Microsoft-Exchange-Diagnostics: 1; CY4PR03MB2694; 3:HoTFEAA1UfVxLBxncaErQ8yoWfFcA4Om1GHFuiwVRZlK1ZYM7yiWKbC8jQcFmaD1QICi7QNPBaYRI972Hw4ibsBri4qK9trgpERuEXGEIG7iU3fUQmwTIKn1P4VLglkY/LPMRpKoMv3ujIL5GykHRiJzWumZtUh295kq+PaZ4yFaxQTs1ZT3v0aXnAVPRNZ94cpftoS9+DCje7J1lQw++0j6jsipAN5dM3LR4dNiOhv7ufKwqlcZN4S0gCytMYOpvbiceiMwUzN9I7vhTDUaiVTA2eDPeONO164TervL6jW0YFFQSyOVx2KKTN491fjxDbeVrDbZmF91C6KjO5duwPhzAPPYZWS0JGcUs0LKlFg=; 25://pTgf19gK5z5jg4BcVN8nCv9IVGh1wD37hLxDiWr/a53G4Hpg3UpIe4VEzi+yq434uwhJ9+We5S1qG6pq+QUH8/0e116nk2IsgKfP38whYioudHvw5fDdjzoIaVyUsVCr7cZksMdtYdNccDuLS2BRYB6ERb44u9oCzV83LsI7Uipdu0krm7QxYNIJcpQX6YWH2G0mMMvCFDPdjJDxUfacWaOZpXow3yK8NcJooEEuWh6QAZIPXFML0EaoCGxmApgyVgjQ2oPbP3dYzCLvXvk/Uhx069KiF9kmnM0lgnWoBbJUXLMy/3ST5Cqz3aU9mnZHgo5N1WAoYwmf448QZ2Cw== X-MS-TrafficTypeDiagnostic: CY4PR03MB2694: X-Microsoft-Exchange-Diagnostics: 1; CY4PR03MB2694; 31:H4LQ9w7DGvo+tlThNSRFOt3B5CvI17oxmozv6QSMyPcNPDGvReR4qvmszrTTgUkAGd4lgt7MDcWsvj6S1IcSAiGyVXZG4LZTcpaMY0tKpJaRhYaHxSi7uyp/H+SVj3kFZZo4yWzqGA8UXU2r5iYg4O95TY3L2nI3hUH5jSB0ycPNQTJUf2Brzs1zWQLmyIKPymEEqyb9AedDhdgcbENUbPTXQpskxk/tNVomVieSq4o=; 4:g63euF51MkC8c7sANcBL4znKgt0j8QdSDAF3DR5t1lf7EIR3pSz++kBPzw7iYNRrU0TO57EFwuzdV0gqC5BIDN378ENDwyTwNjUI2ECmvprNvScc08PcqSrk3C4ObzATgPbh7gw13X3r1sAfnWwLWpQsMwOiSgmF3RdqR0/pIVQNKiJiJyGPbfiyemAvwkEVnRTjR43hKBgAf5VNvU73LSjI2gBUHKdJzzPm3/lhp23MkcJLXCuuiXb8s4ArTbEpcP7DCT5p5ezuISwJRiJJl1Ob6prcUkSm6jTV0WhuWI2O4XCIl7V5hQdAoDU1Azdb X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6095135)(2401047)(8121501046)(5005006)(3231023)(93006095)(93001095)(10201501046)(3002001)(6055026)(6096035)(20161123563025)(201703131430075)(201703131433075)(201703131441075)(201703131448075)(201703161259150)(20161123559100)(20161123556025)(20161123561025)(20161123565025)(201708071742011); SRVR:CY4PR03MB2694; BCL:0; PCL:0; RULEID:(100000803101)(100110400095)(400006); SRVR:CY4PR03MB2694; X-Forefront-PRVS: 05299D545B X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CY4PR03MB2694; 23:JqJwAEIziqJGUAf1J5rK6d9Pkq41da9OsmsljTSgE?= =?us-ascii?Q?S9ze2I9cTEHHtRkS0osIsvhFaieG6lwmTRuRjYUNMVdZykebtdrlkXAGf1Ic?= =?us-ascii?Q?W1UlSY3L4HACEyB6auppa1S4cV+fv5PikgqWdRwBt2YH8r7kf2bo+xZ+hZFq?= =?us-ascii?Q?RKlQC0+7B7vsQ3ZW7PjHUfS3gepvmPKGFHNqjoJ5Dnn2d5xUjoh2i1OMENQF?= =?us-ascii?Q?aycVdwpAWr+tIjWGS/VrlbzoWMYLdeCufQ2qof4qDlpzfByZlBj6eCJ2PyOC?= =?us-ascii?Q?CKgvYZXIiXJ2m51JoJ/p0hOyeJUTG1yPu+G0VU4NlNAWqbL4yJn6tPsQqjys?= =?us-ascii?Q?7ETeJGgq8KfSxgZE0hUOV7ykLiF4nlnIgxOLsZMIucHfxt9q3Qw1h4YDRb49?= =?us-ascii?Q?OasW4ZRkw37MMsqXyKEEZptQxB3tolWPwQudwj9Tu4W38ryTZnbC+3u2fjVP?= =?us-ascii?Q?QpYr7ahMiCzhCkpufB0EGvKEraR/Lh0IBmWZYQ2T30nGOW6DejAQw+OB2jDf?= =?us-ascii?Q?E+R3r8WRjOFXx57w2Q1i6yWuHWQ9qpSUD9kakq8bf97CUim1bV1AIbsVZ6Fx?= =?us-ascii?Q?4PF18ANilmG8mdyRaAVYf55hNONfWHzWl++0r6QA2NmuABJ1URQGyseJ9Jzy?= =?us-ascii?Q?ci14Q0XvvO1x/v/p2lc0ZARrYXMcGrfhPHkG1jByZgkj5LCYMe7rzaRqaHam?= =?us-ascii?Q?N+x+4/Js6kUHBatcFVrgunJecclabJuPBE93XdFQqWPlbsI94HVmiHvwORuE?= =?us-ascii?Q?mKJ3OMe8o3RIhc14HzUriPj522tonZD1L2YmB8NxpQY+dwfWwoipA/ADoDKQ?= =?us-ascii?Q?IEE/qRlcmJHoRPEMoVYzYIeYXcrZhKzL/IieL0SYD3oqBT/wcQHcazPoQhIu?= =?us-ascii?Q?UrgnrXjbWMlgQ5n2xklzmVts45bzOYJ2Aq0o7fgr3z7l2hxSToEFIN0pDV3/?= =?us-ascii?Q?+WsAW/CMNlMHE3BlbsI+l95uiWu0TQqcLUaedbPbXKCQauNmdBnBeUoZE0lp?= =?us-ascii?Q?Cxy4KRGfGjtRfjcyOSbxF+k2BRJgVydGu+4EujB5w9qACltimYpKiGKHxMDJ?= =?us-ascii?Q?2v/XCLBDxqVFZCLweECNFIZMRJhpmxxiwkC+WNg64OV/+d7ZDbK5zrIP8X+8?= =?us-ascii?Q?ULZiJ3fm8MHPHtKcIfHxbA/0coFmbJYpNPumF8V68iXvRIA0hEhv2qwsNM6a?= =?us-ascii?Q?IL2JtEqltPPXrIfXzmM7jL4XAUjVgrm43YgO8Px/hvRM2UCdOM7VJLJkZtno?= =?us-ascii?Q?8Xfj9gThfbFVCh4ld1gjJTu487VR27Tw3yu0KaSdi1PhQi/w9fHqJJr9xjli?= =?us-ascii?Q?vL2vC6f8K8OlCJPfTkhbD57c8RnHrT/BeHenWudkEzhVRnci549x1vZifaEY?= =?us-ascii?Q?GDp6LjrHQ0JXr6GgQ9LcX2Nnok=3D?= X-Microsoft-Exchange-Diagnostics: 1; CY4PR03MB2694; 6:grssZUyUgAcb7kOuskT+aSW6agLTHfCQ+1bdouR5mPsBZXM/LYSFAnPcwQx22+7SWXWC204yRoCVJ6sHVZqXb5B2TY/svmwxg1YtJGtyy6rh/xVonz4ScLQmW+GhBNS0/mb+j1OJEx9ynLOYmrnlXc7Djwe2Jw8oqJ5KZf7dzUbr+bGR+i0r7sF2UkjAD+/B5Lv7HuiBUZMcCxcjZhuqJZs3KO22NEDlm79ilzufOgjnQLAJXbw7GOAYIKHnzYosiFtWaB1kPb2IfPFoFl68DTWBYuvKwb+QO8L9Y33goNw1aLVbIGIjoRnhdPtkxUttWv6aFkX4iwXgH1Cf6W6Wx1QybIH2J3JgnKoniiVhwEk=; 5:cDGAuxP9giNjid+Cp7IhNR/30rlM0DkYAjTP8XbjABG+/gCJ+lvLjZbs5++eGl7GvQGWOeUP9hHz+yLXoChsccAkCvXE7qU0OmWxlCZPh7PIhKRg0ZoSv2v6f6WZhTfFoOyPS/2AyrnAAnLUKngtpd1eZ1Ry4xicXC21lTncc+k=; 24:7IbyzMcytDRbYPI9V1+z7tFNkf3bcoW1SxepfjA1dLLDsiSBnZDE8xdTFzpygS32vYWAx7e+EjDatntw+ZM8W+B/KY9XvoBNgfScpjxV2To=; 7:ykgARpq1UX4jAAvHp68L7b8ZgdgDOwzuh+toEAErsyVwBlts3RkUf9jMnWoLSJlV3Lz3vOI8PwgkWmM2xLGdY6v0JOi/D5V7dWK7d2SsDZydCEQEoP9aoYJt7l2+ho+j66k3iPxKlUmj7NLzGt8j6+b1JAlbZk/XMm91co/MTFlDop8TPQLnyRVTuG/kRULUN4wR+NrUbjJNXW7r943vV4PTA2P33O+CH4s/T9fbjqSMcZSHfILGKsoEsHAYjUEq SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Dec 2017 06:50:10.6561 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: d92b48c6-6ae4-4d41-abee-08d549083f01 X-MS-Exchange-CrossTenant-Id: 5afe0b00-7697-4969-b663-5eab37d5f47e X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e; Ip=[192.88.168.50]; Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR03MB2694 Subject: [edk2] [PATCH edk2-platforms 1/3] Platform/NXP : Add PCI Host Bridge Libary 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: , Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Added PCIe Host Bridge Library to provide helper functions which will be used by PCIe Host bridge Dxe Driver Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Vabhav --- Platform/NXP/Include/PciCntrlLib.h | 323 +++++++++++ Platform/NXP/Include/PciLib.h | 414 ++++++++++++++ Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c | 628 +++++++++++++++++= ++++ .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 49 ++ Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c | 331 +++++++++++ 5 files changed, 1745 insertions(+) create mode 100644 Platform/NXP/Include/PciCntrlLib.h create mode 100644 Platform/NXP/Include/PciLib.h create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.= inf create mode 100644 Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c diff --git a/Platform/NXP/Include/PciCntrlLib.h b/Platform/NXP/Include/PciC= ntrlLib.h new file mode 100644 index 0000000..c8001d9 --- /dev/null +++ b/Platform/NXP/Include/PciCntrlLib.h @@ -0,0 +1,323 @@ +/** PciCntrlLib.c + The Header file of the Pci Controller Driver + + Some part of code is inspired from EDK II, file: + MdePkg/Include/Library/PciLib.h + + Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved + Copyright 2017 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 + 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 IMPL= IED. + +**/ + +#ifndef _PCI_CNTRL_H_ +#define _PCI_CNTRL_H_ + +#include +#include + +#define SDRAM_BASE 0x80000000 + +// LUT registers +#define LS_PCIE_LUT_BASE PcdGet64 (PcdPcieLutBase) +#define LS_PCIE_LUT_DBG PcdGet64 (PcdPcieLutDbg) +#define PCIE_LUT_UDR(n) (0x800 + (n) * 8) +#define PCIE_LUT_LDR(n) (0x804 + (n) * 8) +#define PCIE_LUT_ENABLE (1 << 31) + +#ifndef LS_PCI_MEMORY_BUS +#define LS_PCI_MEMORY_BUS SDRAM_BASE +#endif + +#ifndef LS_PCI_MEMORY_PHYS +#define LS_PCI_MEMORY_PHYS SDRAM_BASE +#endif + +#ifndef LS_PCI_MEMORY_SIZE +#define LS_PCI_MEMORY_SIZE (2 * 1024 * 1024 * 1024UL) +#endif + +/* iATU registers */ +#define LS_PCIE_ATU_VIEWPORT 0x900 +#define LS_PCIE_ATU_REGION_INBOUND (0x1 << 31) +#define LS_PCIE_ATU_REGION_OUTBOUND (0x0 << 31) +#define LS_PCIE_ATU_REGION_INDEX0 (0x0 << 0) +#define LS_PCIE_ATU_REGION_INDEX1 (0x1 << 0) +#define LS_PCIE_ATU_REGION_INDEX2 (0x2 << 0) +#define LS_PCIE_ATU_REGION_INDEX3 (0x3 << 0) +#define LS_PCIE_ATU_REGION_INDEX4 (0x4 << 0) +#define LS_PCIE_ATU_CR1 0x904 +#define LS_PCIE_ATU_TYPE_MEM (0x0 << 0) +#define LS_PCIE_ATU_TYPE_IO (0x2 << 0) +#define LS_PCIE_ATU_TYPE_CFG0 (0x4 << 0) +#define LS_PCIE_ATU_TYPE_CFG1 (0x5 << 0) +#define LS_PCIE_ATU_CR2 0x908 +#define LS_PCIE_ATU_ENABLE (0x1 << 31) +#define LS_PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30) +#define LS_PCIE_ATU_LOWER_BASE 0x90C +#define LS_PCIE_ATU_UPPER_BASE 0x910 +#define LS_PCIE_ATU_LIMIT 0x914 +#define LS_PCIE_ATU_LOWER_TARGET 0x918 +#define LS_PCIE_ATU_BUS(x) (((x) & 0xff) << 24) +#define LS_PCIE_ATU_DEV(x) (((x) & 0x1f) << 19) +#define LS_PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) +#define LS_PCIE_ATU_UPPER_TARGET 0x91C + +/** DBI Read-Only Write Enable Register: Pg 1518 RM rev B + Set bit 0 of this register as 1. + Write to RO Registers Using DBI. + When you set this field to "1", then some RO and HwInit bits are writa= ble + from the local application through the DBI. + **/ +#define LS_PCIE_DBI_RO_WR_EN 0x8bc + +#define LS_PCIE_LINK_CAP 0x7c +#define LS_PCIE_LINK_SPEED_MASK 0xf +#define LS_PCIE_LINK_STA 0x82 + +#define LS_LTSSM_STATE_MASK 0x3f +#define LS_LTSSM_PCIE_L0 0x11 // L0 state + +#define LS_PCIE_DBI_SIZE 0x100000 // 1M + +#define PCI_CLASS_REVISION 0x08 // High 24 bits are class,low 8 r= evision +#define PCI_REVISION_ID 0x08 // Revision ID +#define PCI_CLASS_PROG 0x09 // Reg. Level Programming Interfa= ce +#define PCI_CLASS_DEVICE 0x0a // Device class +#define PCI_CLASS_CODE 0x0b // Device class code +#define PCI_CLASS_BRIDGE_PCI 0x0604 + +/** + Macro that converts PCI Bus, PCI Device, PCI Function and PCI Register to= an + address that can be passed to the PCI Library functions. + + @param Bus PCI Bus number. Range 0..255. + @param Device PCI Device number. Range 0..31. + @param Function PCI Function number. Range 0..7. + @param Register PCI Register number. Range 0..255 for PCI. Range 0..4095 + for PCI Express. + + @return The encoded PCI address. + **/ +#define PCI_LIB_ADDRESS(Bus,Device,Function,Register) \ + (((Register) & 0xfff) | (((Function) & 0x07) << 12) | (((Device) & 0x1f)= << 15) | (((Bus) & 0xff) << 20)) + +#define PCI_BUS_DEV(Bus,Device,Function) \ + ((((Function) & 0x07) << 16) | (((Device) & 0x1f) << 19) | (((Bus) & 0xf= f) << 24)) + +/** + Function to set-up PCIe region +**/ +VOID +PciSetRegion ( + IN PciRegion *Reg, + IN PciAddrT BusStart, + IN PhysAddrT PhysStart, + IN PciSizeT Size, + IN UINTN Flags +); + +/** + Function to setup PCIe space(Mem,I/O,Configuration) +**/ +VOID +SetLSPcieInfo ( + IN LsPcieInfo *PcieInfo, + IN UINTN Num +); + +/** + Function to check PCIe link state +**/ +INTN +PcieLinkState ( + IN LsPcie *Pcie +); + +/** + Helper Function to check PCIe link state + Downgrade the speed to gen1 +**/ +INTN +PcieLinkUp ( + IN LsPcie *pcie +); + +/** + Function to set up PCIe (cfg0)configuration space +**/ +VOID +PcieCfg0SetBusdev ( + IN LsPcie *Pcie, + IN UINT32 BusDev +); + +/** + Function to set up PCIe (cfg1)configuration space +**/ +VOID +PcieCfg1SetBusdev ( + IN LsPcie *Pcie, + IN UINT32 BusDev +); + +/** + Function to set up iATU for outbound PCIe transactions +**/ +VOID +PcieIatuOutboundSet ( + IN LsPcie *Pcie, + IN UINT32 Idx, + IN UINT32 Type, + IN UINT64 Phys, + IN UINT64 BusAddr, + IN UINT64 Size +); + +EFI_STATUS +PciSkipDev ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev +); + +/** + Function to verify if PCIe address space is valid +**/ +EFI_STATUS +PcieAddrValid ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev +); + +/** + Function to read value(32-bit) from PCI space +**/ +EFI_STATUS +PcieReadConfig ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Where, + IN OUT UINT32 *Val +); + +/** + Function to read byte from PCI space +**/ +EFI_STATUS +PcieReadConfigByte ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + IN OUT UINT8 *Val +); + +/** + Function to read word from PCI space +**/ +EFI_STATUS +PcieReadConfigWord ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + IN OUT UINT16 *Val +); + +/** + Function to write byte in PCI space +**/ +EFI_STATUS +PcieWriteConfigByte ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + OUT UINT8 Val +); + +/** + Function to write word in PCI space +**/ +EFI_STATUS +PcieWriteConfigWord ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + OUT UINT16 Val +); + +/** + Function to write value(32-bit) in PCI space +**/ +EFI_STATUS +PcieWriteConfig ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Where, + IN UINT32 Val +); + +/** + Function for setting up internal Address translation unit(ATU) +**/ +VOID +PcieSetupAtu ( + IN LsPcie *Pcie, + IN LsPcieInfo *Info +); + +/** + Function for setting up PCI controller +**/ +VOID +PcieSetupCntrl ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN LsPcie *Pcie, + IN LsPcieInfo *Info +); + +/** + Internal Helper function for read and write memory space +**/ +EFI_STATUS +RootBridgeIoMemRW ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN BOOLEAN Write, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer +); + +/** + Internal Helper function for read and write PCI IO space +**/ +EFI_STATUS +RootBridgeIoIoRW ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN BOOLEAN Write, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer +); + +/** + Internal Helper function for read and write PCI configuration space +**/ +EFI_STATUS +RootBridgeIoPciRW ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN BOOLEAN Write, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer +); + +#endif diff --git a/Platform/NXP/Include/PciLib.h b/Platform/NXP/Include/PciLib.h new file mode 100644 index 0000000..873f0e7 --- /dev/null +++ b/Platform/NXP/Include/PciLib.h @@ -0,0 +1,414 @@ +/** PciLib.h + Pci Library containing Defines for Pci Controller configuration etc + + Copyright 2017 NXP + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e 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 IMP= LIED. + +**/ + +#ifndef __PCI_LIB_H__ +#define __PCI_LIB_H__ + +/* + In PCI, devices have 256 bytes of configuration address space, + of which the first 64 bytes are standardized as follows: + **/ +#define LS_PCI_VENDOR_ID 0x00 // 16 bits +#define LS_PCI_DEVICE_ID 0x02 // 16 bits +#define LS_PCI_COMMAND 0x04 // 16 bits +#define LS_PCI_COMMAND_IO 0x1 // Enable response in I/O space +#define LS_PCI_COMMAND_MEMORY 0x2 // Enable response in Memory s= pace +#define LS_PCI_COMMAND_MASTER 0x4 // Enable bus mastering +#define LS_PCI_COMMAND_SPECIAL 0x8 // Enable response to special = cycles +#define LS_PCI_COMMAND_INVALIDATE 0x10 // Use memory write and invali= date +#define LS_PCI_COMMAND_VGA_PALETTE 0x20 // Enable palette snooping +#define LS_PCI_COMMAND_PARITY 0x40 // Enable parity checking +#define LS_PCI_COMMAND_WAIT 0x80 // Enable address/data stepping +#define LS_PCI_COMMAND_SERR 0x100 // Enable SERR +#define LS_PCI_COMMAND_FAST_BACK 0x200 + +#define LS_PCI_STATUS 0x06 // 16 bits +#define LS_PCI_STATUS_CAP_LIST 0x10 // Support Capability List +#define LS_PCI_STATUS_66MHZ 0x20 +#define LS_PCI_STATUS_UDF 0x40 +#define LS_PCI_STATUS_FAST_BACK 0x80 +#define LS_PCI_STATUS_PARITY 0x100 +#define LS_PCI_STATUS_DEVSEL_MASK 0x600 +#define LS_PCI_STATUS_DEVSEL_FAST 0x000 +#define LS_PCI_STATUS_DEVSEL_MEDIUM 0x200 +#define LS_PCI_STATUS_DEVSEL_SLOW 0x400 +#define LS_PCI_STATUS_SIG_TARGET_ABORT 0x800 +#define LS_PCI_STATUS_REC_TARGET_ABORT 0x1000 +#define LS_PCI_STATUS_REC_MASTER_ABORT 0x2000 +#define LS_PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 +#define LS_PCI_STATUS_DETECTED_PARITY 0x8000 + +#define LS_PCI_CLASS_REVISION 0x08 +#define LS_PCI_REVISION_ID 0x08 // Revision ID +#define LS_PCI_CLASS_PROG 0x09 +#define LS_PCI_CLASS_DEVICE 0x0a // Device class +#define LS_PCI_CLASS_CODE 0x0b // Device class code +#define LS_PCI_CLASS_CODE_TOO_OLD 0x00 +#define LS_PCI_CLASS_CODE_STORAGE 0x01 +#define LS_PCI_CLASS_CODE_NETWORK 0x02 +#define LS_PCI_CLASS_CODE_DISPLAY 0x03 +#define LS_PCI_CLASS_CODE_MULTIMEDIA 0x04 +#define LS_PCI_CLASS_CODE_MEMORY 0x05 +#define LS_PCI_CLASS_CODE_BRIDGE 0x06 +#define LS_PCI_CLASS_CODE_COMM 0x07 +#define LS_PCI_CLASS_CODE_PERIPHERAL 0x08 +#define LS_PCI_CLASS_CODE_INPUT 0x09 +#define LS_PCI_CLASS_CODE_DOCKING 0x0A +#define LS_PCI_CLASS_CODE_PROCESSOR 0x0B +#define LS_PCI_CLASS_CODE_SERIAL 0x0C +#define LS_PCI_CLASS_CODE_WIRELESS 0x0D +#define LS_PCI_CLASS_CODE_I2O 0x0E +#define LS_PCI_CLASS_CODE_SATELLITE 0x0F +#define LS_PCI_CLASS_CODE_CRYPTO 0x10 +#define LS_PCI_CLASS_CODE_DATA 0x11 +// Base Class 0x12 - 0xFE is reserved +#define LS_PCI_CLASS_CODE_OTHER 0xFF + +#define LS_PCI_CLASS_SUB_CODE 0x0a // Device sub-clas= s code +#define LS_PCI_CLASS_SUB_CODE_TOO_OLD_NOTVGA 0x00 +#define LS_PCI_CLASS_SUB_CODE_TOO_OLD_VGA 0x01 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_SCSI 0x00 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_IDE 0x01 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_FLOPPY 0x02 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_IPIBUS 0x03 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_RAID 0x04 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_ATA 0x05 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_SATA 0x06 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_SAS 0x07 +#define LS_PCI_CLASS_SUB_CODE_STORAGE_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_ETHERNET 0x00 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_TOKENRING 0x01 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_FDDI 0x02 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_ATM 0x03 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_ISDN 0x04 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_WORLDFIP 0x05 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_PICMG 0x06 +#define LS_PCI_CLASS_SUB_CODE_NETWORK_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_DISPLAY_VGA 0x00 +#define LS_PCI_CLASS_SUB_CODE_DISPLAY_XGA 0x01 +#define LS_PCI_CLASS_SUB_CODE_DISPLAY_3D 0x02 +#define LS_PCI_CLASS_SUB_CODE_DISPLAY_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_MULTIMEDIA_VIDEO 0x00 +#define LS_PCI_CLASS_SUB_CODE_MULTIMEDIA_AUDIO 0x01 +#define LS_PCI_CLASS_SUB_CODE_MULTIMEDIA_PHONE 0x02 +#define LS_PCI_CLASS_SUB_CODE_MULTIMEDIA_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_MEMORY_RAM 0x00 +#define LS_PCI_CLASS_SUB_CODE_MEMORY_FLASH 0x01 +#define LS_PCI_CLASS_SUB_CODE_MEMORY_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_HOST 0x00 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_ISA 0x01 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_EISA 0x02 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_MCA 0x03 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_LS_PCI 0x04 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_PCMCIA 0x05 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_NUBUS 0x06 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_CARDBUS 0x07 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_RACEWAY 0x08 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_SEMI_LS_PCI 0x09 +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_INFINIBAND 0x0A +#define LS_PCI_CLASS_SUB_CODE_BRIDGE_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_COMM_SERIAL 0x00 +#define LS_PCI_CLASS_SUB_CODE_COMM_PARALLEL 0x01 +#define LS_PCI_CLASS_SUB_CODE_COMM_MULTIPORT 0x02 +#define LS_PCI_CLASS_SUB_CODE_COMM_MODEM 0x03 +#define LS_PCI_CLASS_SUB_CODE_COMM_GPIB 0x04 +#define LS_PCI_CLASS_SUB_CODE_COMM_SMARTCARD 0x05 +#define LS_PCI_CLASS_SUB_CODE_COMM_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_PIC 0x00 +#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_DMA 0x01 +#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_TIMER 0x02 +#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_RTC 0x03 +#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_HOTPLUG 0x04 +#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_SD 0x05 +#define LS_PCI_CLASS_SUB_CODE_PERIPHERAL_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_INPUT_KEYBOARD 0x00 +#define LS_PCI_CLASS_SUB_CODE_INPUT_DIGITIZER 0x01 +#define LS_PCI_CLASS_SUB_CODE_INPUT_MOUSE 0x02 +#define LS_PCI_CLASS_SUB_CODE_INPUT_SCANNER 0x03 +#define LS_PCI_CLASS_SUB_CODE_INPUT_GAMEPORT 0x04 +#define LS_PCI_CLASS_SUB_CODE_INPUT_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_DOCKING_GENERIC 0x00 +#define LS_PCI_CLASS_SUB_CODE_DOCKING_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_386 0x00 +#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_486 0x01 +#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_PENTIUM 0x02 +#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_ALPHA 0x10 +#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_POWERPC 0x20 +#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_MIPS 0x30 +#define LS_PCI_CLASS_SUB_CODE_PROCESSOR_COPROC 0x40 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_1394 0x00 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_ACCESSBUS 0x01 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_SSA 0x02 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_USB 0x03 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_FIBRECHAN 0x04 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_SMBUS 0x05 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_INFINIBAND 0x06 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_IPMI 0x07 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_SERCOS 0x08 +#define LS_PCI_CLASS_SUB_CODE_SERIAL_CANBUS 0x09 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_IRDA 0x00 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_IR 0x01 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_RF 0x10 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_BLUETOOTH 0x11 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_BROADBAND 0x12 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_80211A 0x20 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_80211B 0x21 +#define LS_PCI_CLASS_SUB_CODE_WIRELESS_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_I2O_V1_0 0x00 +#define LS_PCI_CLASS_SUB_CODE_SATELLITE_TV 0x01 +#define LS_PCI_CLASS_SUB_CODE_SATELLITE_AUDIO 0x02 +#define LS_PCI_CLASS_SUB_CODE_SATELLITE_VOICE 0x03 +#define LS_PCI_CLASS_SUB_CODE_SATELLITE_DATA 0x04 +#define LS_PCI_CLASS_SUB_CODE_CRYPTO_NETWORK 0x00 +#define LS_PCI_CLASS_SUB_CODE_CRYPTO_ENTERTAINMENT 0x10 +#define LS_PCI_CLASS_SUB_CODE_CRYPTO_OTHER 0x80 +#define LS_PCI_CLASS_SUB_CODE_DATA_DPIO 0x00 +#define LS_PCI_CLASS_SUB_CODE_DATA_PERFCNTR 0x01 +#define LS_PCI_CLASS_SUB_CODE_DATA_COMMSYNC 0x10 +#define LS_PCI_CLASS_SUB_CODE_DATA_MGMT 0x20 +#define LS_PCI_CLASS_SUB_CODE_DATA_OTHER 0x80 + +#define LS_PCI_CACHE_LINE_SIZE 0x0c // 8 bits +#define LS_PCI_LATENCY_TIMER 0x0d // 8 bits +#define LS_PCI_HEADER_TYPE 0x0e // 8 bits +#define LS_PCI_HEADER_TYPE_NORMAL 0 +#define LS_PCI_HEADER_TYPE_BRIDGE 1 +#define LS_PCI_HEADER_TYPE_CARDBUS 2 + +#define LS_PCI_BIST 0x0f // 8 bits +#define LS_PCI_BIST_CODE_MASK 0x0f // Return result +#define LS_PCI_BIST_START 0x40 +#define LS_PCI_BIST_CAPABLE 0x80 + +#define LS_PCI_BASE_ADDRESS_0 0x10 // 32 bits +#define LS_PCI_BASE_ADDRESS_1 0x14 +#define LS_PCI_BASE_ADDRESS_2 0x18 +#define LS_PCI_BASE_ADDRESS_3 0x1c // 32 bits +#define LS_PCI_BASE_ADDRESS_4 0x20 // 32 bits +#define LS_PCI_BASE_ADDRESS_5 0x24 // 32 bits +#define LS_PCI_BASE_ADDRESS_SPACE 0x01 +#define LS_PCI_BASE_ADDRESS_SPACE_IO 0x01 +#define LS_PCI_BASE_ADDRESS_SPACE_MEMORY 0x00 +#define LS_PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06 +#define LS_PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 // 32 bit address +#define LS_PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 // Below 1M [obsolete] +#define LS_PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 // 64 bit address +#define LS_PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 // prefetchable? +#define LS_PCI_BASE_ADDRESS_MEM_MASK (~0x0fULL) +#define LS_PCI_BASE_ADDRESS_IO_MASK (~0x03ULL) + +// Header type 0 (normal devices) +#define LS_PCI_CARDBUS_CIS 0x28 +#define LS_PCI_SUBSYSTEM_VENDOR_ID 0x2c +#define LS_PCI_SUBSYSTEM_ID 0x2e +#define LS_PCI_ROM_ADDRESS 0x30 +#define LS_PCI_ROM_ADDRESS_ENABLE 0x01 +#define LS_PCI_ROM_ADDRESS_MASK (~0x7ffULL) + +#define LS_PCI_CAPABILITY_LIST 0x34 // Offset of first capability l= ist entry + +#define LS_PCI_INTERRUPT_LINE 0x3c // 8 bits +#define LS_PCI_INTERRUPT_PIN 0x3d // 8 bits +#define LS_PCI_MIN_GNT 0x3e // 8 bits +#define LS_PCI_MAX_LAT 0x3f // 8 bits + +// Header type 1 (PCI-to-PCI bridges) +#define LS_PCI_PRIMARY_BUS 0x18 // Primary bus number +#define LS_PCI_SECONDARY_BUS 0x19 // Secondary bus number +#define LS_PCI_SUBORDINATE_BUS 0x1a +#define LS_PCI_SEC_LATENCY_TIMER 0x1b +#define LS_PCI_IO_BASE 0x1c // I/O range behind the bri= dge +#define LS_PCI_IO_LIMIT 0x1d +#define LS_PCI_IO_RANGE_TYPE_MASK 0x0f // I/O bridging type +#define LS_PCI_IO_RANGE_TYPE_16 0x00 +#define LS_PCI_IO_RANGE_TYPE_32 0x01 +#define LS_PCI_IO_RANGE_MASK ~0x0f +#define LS_PCI_SEC_STATUS 0x1e +#define LS_PCI_MEMORY_BASE 0x20 // Memory range behind +#define LS_PCI_MEMORY_LIMIT 0x22 +#define LS_PCI_MEMORY_RANGE_TYPE_MASK 0x0f +#define LS_PCI_MEMORY_RANGE_MASK ~0x0f +#define LS_PCI_PREF_MEMORY_BASE 0x24 // Prefetchable memory rang= e behind +#define LS_PCI_PREF_MEMORY_LIMIT 0x26 +#define LS_PCI_PREF_RANGE_TYPE_MASK 0x0f +#define LS_PCI_PREF_RANGE_TYPE_32 0x00 +#define LS_PCI_PREF_RANGE_TYPE_64 0x01 +#define LS_PCI_PREF_RANGE_MASK ~0x0f +#define LS_PCI_PREF_BASE_UPPER32 0x28 // Upper half of prefetchab= le memory range +#define LS_PCI_PREF_LIMIT_UPPER32 0x2c +#define LS_PCI_IO_BASE_UPPER16 0x30 // Upper half of I/O addres= ses +#define LS_PCI_IO_LIMIT_UPPER16 0x32 +#define LS_PCI_ROM_ADDRESS1 0x38 // Same as LS_PCI_ROM_ADDRE= SS, but for htype 1 +#define LS_PCI_BRIDGE_CONTROL 0x3e +#define LS_PCI_BRIDGE_CTL_PARITY 0x01 +#define LS_PCI_BRIDGE_CTL_SERR 0x02 +#define LS_PCI_BRIDGE_CTL_NO_ISA 0x04 +#define LS_PCI_BRIDGE_CTL_VGA 0x08 +#define LS_PCI_BRIDGE_CTL_MASTER_ABORT 0x20 // Report master aborts +#define LS_PCI_BRIDGE_CTL_BUS_RESET 0x40 // Secondary bus reset +#define LS_PCI_BRIDGE_CTL_FAST_BACK 0x80 + +#define LS_PCI_ERREN 0x48 // Error Enable +#define LS_PCI_ERRSTS 0x49 // Error Status +#define LS_PCI_BRDGOPT1 0x4A +#define LS_PCI_PLBSESR0 0x4C +#define LS_PCI_PLBSESR1 0x50 +#define LS_PCI_PLBSEAR 0x54 +#define LS_PCI_CAPID 0x58 +#define LS_PCI_NEXTITEMPTR 0x59 +#define LS_PCI_PMC 0x5A +#define LS_PCI_PMCSR 0x5C +#define LS_PCI_PMCSRBSE 0x5E +#define LS_PCI_BRDGOPT2 0x60 // PCI Bridge Options 2 +#define LS_PCI_PMSCRR 0x64 + +// Header type 2 (CardBus bridges) +#define LS_PCI_CB_CAPABILITY_LIST 0x14 +// 0x15 reserved +#define LS_PCI_CB_SEC_STATUS 0x16 // Secondary status +#define LS_PCI_CB_PRIMARY_BUS 0x18 // PCI bus number +#define LS_PCI_CB_CARD_BUS 0x19 +#define LS_PCI_CB_SUBORDINATE_BUS 0x1a // Subordinate bus numb= er +#define LS_PCI_CB_LATENCY_TIMER 0x1b +#define LS_PCI_CB_MEMORY_BASE_0 0x1c +#define LS_PCI_CB_MEMORY_LIMIT_0 0x20 +#define LS_PCI_CB_MEMORY_BASE_1 0x24 +#define LS_PCI_CB_MEMORY_LIMIT_1 0x28 +#define LS_PCI_CB_IO_BASE_0 0x2c +#define LS_PCI_CB_IO_BASE_0_HI 0x2e +#define LS_PCI_CB_IO_LIMIT_0 0x30 +#define LS_PCI_CB_IO_LIMIT_0_HI 0x32 +#define LS_PCI_CB_IO_BASE_1 0x34 +#define LS_PCI_CB_IO_BASE_1_HI 0x36 +#define LS_PCI_CB_IO_LIMIT_1 0x38 +#define LS_PCI_CB_IO_LIMIT_1_HI 0x3a +#define LS_PCI_CB_IO_RANGE_MASK ~0x03 +#define LS_PCI_CB_BRIDGE_CONTROL 0x3e +#define LS_PCI_CB_BRIDGE_CTL_PARITY 0x01 // Similar to standard = bridge control register +#define LS_PCI_CB_BRIDGE_CTL_SERR 0x02 +#define LS_PCI_CB_BRIDGE_CTL_ISA 0x04 +#define LS_PCI_CB_BRIDGE_CTL_VGA 0x08 +#define LS_PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20 +#define LS_PCI_CB_BRIDGE_CTL_CB_RESET 0x40 // CardBus reset +#define LS_PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 +#define LS_PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 // Prefetch enable for b= oth memory regions +#define LS_PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200 +#define LS_PCI_CB_BRIDGE_CTL_POST_WRITES 0x400 +#define LS_PCI_CB_SUBSYSTEM_VENDOR_ID 0x40 +#define LS_PCI_CB_SUBSYSTEM_ID 0x42 +#define LS_PCI_CB_LEGACY_MODE_BASE 0x44 // 16-bit PC Card legac= y mode base address (ExCa) + +// Defines of Capability lists +#define LS_PCI_CAP_LIST_ID 0 // Capability ID +#define LS_PCI_CAP_ID_PM 0x01 // Power Management +#define LS_PCI_CAP_ID_AGP 0x02 +#define LS_PCI_CAP_ID_VPD 0x03 +#define LS_PCI_CAP_ID_SLOTID 0x04 +#define LS_PCI_CAP_ID_MSI 0x05 +#define LS_PCI_CAP_ID_CHSWP 0x06 +#define LS_PCI_CAP_ID_EXP 0x10 +#define LS_PCI_CAP_LIST_NEXT 1 // Next capability in the list +#define LS_PCI_CAP_FLAGS 2 // Capability defined flags (16= bits) +#define LS_PCI_CAP_SIZEOF 4 + +// Power Management Registers +#define LS_PCI_PM_CAP_VER_MASK 0x0007 +#define LS_PCI_PM_CAP_PME_CLOCK 0x0008 +#define LS_PCI_PM_CAP_AUX_POWER 0x0010 +#define LS_PCI_PM_CAP_DSI 0x0020 +#define LS_PCI_PM_CAP_D1 0x0200 +#define LS_PCI_PM_CAP_D2 0x0400 +#define LS_PCI_PM_CAP_PME 0x0800 +#define LS_PCI_PM_CTRL 4 +#define LS_PCI_PM_CTRL_STATE_MASK 0x0003 +#define LS_PCI_PM_CTRL_PME_ENABLE 0x0100 +#define LS_PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 +#define LS_PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 +#define LS_PCI_PM_CTRL_PME_STATUS 0x8000 +#define LS_PCI_PM_PPB_EXTENSIONS 6 +#define LS_PCI_PM_PPB_B2_B3 0x40 +#define LS_PCI_PM_BPCC_ENABLE 0x80 +#define LS_PCI_PM_DATA_REGISTER 7 +#define LS_PCI_PM_SIZEOF 8 + +// AGP registers defines +#define LS_PCI_AGP_VERSION 2 +#define LS_PCI_AGP_RFU 3 +#define LS_PCI_AGP_STATUS 4 +#define LS_PCI_AGP_STATUS_RQ_MASK 0xff000000 +#define LS_PCI_AGP_STATUS_SBA 0x0200 +#define LS_PCI_AGP_STATUS_64BIT 0x0020 +#define LS_PCI_AGP_STATUS_FW 0x0010 +#define LS_PCI_AGP_STATUS_RATE4 0x0004 +#define LS_PCI_AGP_STATUS_RATE2 0x0002 +#define LS_PCI_AGP_STATUS_RATE1 0x0001 +#define LS_PCI_AGP_COMMAND 8 +#define LS_PCI_AGP_COMMAND_RQ_MASK 0xff000000 +#define LS_PCI_AGP_COMMAND_SBA 0x0200 +#define LS_PCI_AGP_COMMAND_AGP 0x0100 +#define LS_PCI_AGP_COMMAND_64BIT 0x0020 +#define LS_PCI_AGP_COMMAND_FW 0x0010 +#define LS_PCI_AGP_COMMAND_RATE4 0x0004 +#define LS_PCI_AGP_COMMAND_RATE2 0x0002 +#define LS_PCI_AGP_COMMAND_RATE1 0x0001 +#define LS_PCI_AGP_SIZEOF 12 + +// Defines for PCI-X registers +#define LS_PCI_X_CMD_DPERR_E 0x0001 +#define LS_PCI_X_CMD_ERO 0x0002 +#define LS_PCI_X_CMD_MAX_READ 0x0000 +#define LS_PCI_X_CMD_MAX_SPLIT 0x0030 +#define LS_PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) + +// Register of Slot Identification +#define LS_PCI_SID_ESR 2 // Expansion Slot Register +#define LS_PCI_SID_ESR_NSLOTS 0x1f // Number of expansion slots ava= ilable +#define LS_PCI_SID_ESR_FIC 0x20 // First In Chassis Flag +#define LS_PCI_SID_CHASSIS_NR 3 // Chassis Number + +#define LS_PCI_MSI_FLAGS 2 +#define LS_PCI_MSI_FLAGS_64BIT 0x80 +#define LS_PCI_MSI_FLAGS_QSIZE 0x70 +#define LS_PCI_MSI_FLAGS_QMASK 0x0e +#define LS_PCI_MSI_FLAGS_ENABLE 0x01 +#define LS_PCI_MSI_RFU 3 +#define LS_PCI_MSI_ADDRESS_LO 4 +#define PCI_MSI_ADDRESS_HI 8 +#define LS_PCI_MSI_DATA_32 8 +#define LS_PCI_MSI_DATA_64 12 + +#define LS_PCI_MAX_PCI_DEVICES 32 +#define LS_PCI_MAX_PCI_FUNCTIONS 8 + +#define LS_PCI_FIND_CAP_TTL 0x48 +#define CAP_START_POS 0x40 + +#define LS_PCI_REGION_MEM 0x00000000 // PCI memory space +#define LS_PCI_REGION_IO 0x00000001 // PCI IO space +#define LS_PCI_REGION_TYPE 0x00000001 +#define LS_PCI_REGION_PREFETCH 0x00000008 // prefetchable PCI memory +#define LS_PCI_REGION_SYS_MEMORY 0x00000100 // System memory +#define LS_PCI_REGION_RO 0x00000200 // Read-only memory + +#define PCI_BUS(Dev) (((Dev) >> 16) & 0xff) +#define PCI_DEV(Dev) (((Dev) >> 11) & 0x1f) +#define PCI_FUNC(Dev) (((Dev) >> 8) & 0x7) +#define PCI_BDF(B,D,F) ((B) << 16 | (D) << 11 | (F) << 8) + +#define PCI_ANY_ID (~0) + +#define INDIRECT_TYPE_NO_PCIE_LINK 1 + +#endif /* _PCI_LIB_H */ diff --git a/Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c b/Platform/NX= P/Library/PciHostBridgeLib/PciCntrl.c new file mode 100644 index 0000000..942e04e --- /dev/null +++ b/Platform/NXP/Library/PciHostBridgeLib/PciCntrl.c @@ -0,0 +1,628 @@ +/** PciCntrl.c + Provides the basic interfaces to be used by PCI Root Bridge IO protocol + + Copyright 2017 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 + 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 IMPL= IED. + +**/ +#include +#include "PciHostBridge.h" + +PCI_ROOT_BRIDGE_INSTANCE *RootBridgeHead; + +/** + Function for setting up PCI region +**/ +VOID +PciSetRegion ( + IN PciRegion *Reg, + IN PciAddrT BusStart, + IN PhysAddrT PhysStart, + IN PciSizeT Size, + IN UINTN Flags +) +{ + Reg->BusStart =3D BusStart; + Reg->PhysStart =3D PhysStart; + Reg->Size =3D Size; + Reg->Flags =3D Flags; +} + +/** + Function to set PCI Space + - Configuration space + - Memory Space + - I/O Space +**/ +VOID +SetLSPcieInfo ( + IN LsPcieInfo *PcieInfo, + IN UINTN Num +) +{ + UINTN pciePhyAddr, pcieSysaddr; + + pciePhyAddr=3D0; + pcieSysaddr=3D0; + + switch(Num){ + case 1: + pciePhyAddr =3D PcdGet64 (PcdPciExp1BaseAddr); + pcieSysaddr =3D PcdGet64 (PcdPciExp1SysAddr); + break; + case 2: + pciePhyAddr =3D PcdGet64 (PcdPciExp2BaseAddr); + pcieSysaddr =3D PcdGet64 (PcdPciExp2SysAddr); + break; + case 3: + pciePhyAddr =3D PcdGet64 (PcdPciExp3BaseAddr); + pcieSysaddr =3D PcdGet64 (PcdPciExp3SysAddr); + break; + case 4: + pciePhyAddr =3D PcdGet64 (PcdPciExp4BaseAddr); + pcieSysaddr =3D PcdGet64 (PcdPciExp4SysAddr); + break; + } + + PcieInfo->Regs =3D pcieSysaddr; + PcieInfo->Cfg0Phys =3D LS_PCIE_CFG0_PHYS_OFF + pciePhyAddr; + PcieInfo->Cfg0Size =3D LS_PCIE_CFG0_SIZE; + PcieInfo->Cfg1Phys =3D LS_PCIE_CFG1_PHYS_OFF + pciePhyAddr; + PcieInfo->Cfg1Size =3D LS_PCIE_CFG1_SIZE; + PcieInfo->MemBus =3D LS_PCIE_MEM_BUS; + PcieInfo->MemPhys =3D LS_PCIE_MEM_PHYS_OFF + pciePhyAddr; + PcieInfo->MemSize =3D LS_PCIE_MEM_SIZE; + PcieInfo->IoBus =3D LS_PCIE_IO_BUS; + PcieInfo->IoPhys =3D LS_PCIE_IO_PHYS_OFF + pciePhyAddr; + PcieInfo->IoSize =3D LS_PCIE_IO_SIZE; + PcieInfo->PciNum =3D Num; + + if (FeaturePcdGet (PcdPciDebug) =3D=3D TRUE) { + DEBUG ((DEBUG_INFO, "In SET_PCIE_INFO: %d\n", Num)); + DEBUG ((DEBUG_INFO, "PciNum:%d Info CFG Values: %016llx %016llx:%016ll= x %016llx %016llx\n", + (UINT64)PcieInfo->PciNum, + (UINT64)PcieInfo->Regs, + (UINT64)PcieInfo->Cfg0Phys, + (UINT64)PcieInfo->Cfg0Size, + (UINT64)PcieInfo->Cfg1Phys, + (UINT64)PcieInfo->Cfg1Size)); + DEBUG ((DEBUG_INFO, "Info Mem Values: %016llx:%016llx %016llx\n", + (UINT64)PcieInfo->MemBus, + (UINT64)PcieInfo->MemPhys, + (UINT64)PcieInfo->MemSize)); + DEBUG ((DEBUG_INFO, "Info IO Values: %016llx:%016llx %016llx\n", + (UINT64)PcieInfo->IoBus, + (UINT64)PcieInfo->IoPhys, + (UINT64)PcieInfo->IoSize)); + } +} + +/** + Function to check PCIe link state +**/ +INTN +PcieLinkState ( + IN LsPcie *Pcie +) +{ + UINT32 State; + if (FeaturePcdGet (PcdPciLutBigEndian)) { + State =3D BeMmioRead32 ((UINTN)(Pcie->Dbi) + LS_PCIE_LUT_BASE + LS_PCI= E_LUT_DBG) & + LS_LTSSM_STATE_MASK; + } + else { + State =3D MmioRead32 ((UINTN)(Pcie->Dbi) + LS_PCIE_LUT_BASE + LS_PCIE_L= UT_DBG) & + LS_LTSSM_STATE_MASK; + } + + if (State < LS_LTSSM_PCIE_L0) { + DEBUG ((DEBUG_INFO," Pcie Link error. LTSSM=3D0x%2x\n", + State)); + return EFI_SUCCESS; + } + + return EFI_UNSUPPORTED; +} + +/** + Helper function to check PCIe link is up + Download the speed to gen1 +**/ +INTN +PcieLinkUp ( + IN LsPcie *Pcie +) +{ + INTN State; + UINT32 Cap; + + State =3D PcieLinkState (Pcie); + if (State) { + return State; + } + + // Try to download speed to gen1 + Cap =3D MmioRead32 ((UINTN)(Pcie->Dbi) + LS_PCIE_LINK_CAP); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_LINK_CAP, (UINT32)(Cap & (~LS_PC= IE_LINK_SPEED_MASK)) | 1); + State =3D PcieLinkState (Pcie); + if (State) { + return State; + } + + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_LINK_CAP, Cap); + + return EFI_SUCCESS; +} + +/** + Function to set up PCI configuration(cfg0) space +**/ +VOID +PcieCfg0SetBusdev ( + IN LsPcie *Pcie, + IN UINT32 BusDev +) +{ + MmioWrite32 ((UINTN)(Pcie->Dbi + LS_PCIE_ATU_VIEWPORT), + LS_PCIE_ATU_REGION_OUTBOUND | LS_PCIE_ATU_REGION_INDEX0); + MmioWrite32 ((UINTN)(Pcie->Dbi + LS_PCIE_ATU_LOWER_TARGET), BusDev); +} + +/** + Function to set up PCI configuration(cfg1) space +**/ +VOID +PcieCfg1SetBusdev ( + IN LsPcie *Pcie, + IN UINT32 BusDev +) +{ + MmioWrite32 ((UINTN)(Pcie->Dbi + LS_PCIE_ATU_VIEWPORT), + LS_PCIE_ATU_REGION_OUTBOUND | LS_PCIE_ATU_REGION_INDEX1); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_TARGET, BusDev); +} + +/** + Function to set up internal address translation window for inbound + transaction +**/ +VOID +PcieIatuInboundSet ( + IN LsPcie *Pcie, + IN UINT32 Idx, + IN UINT32 Bar, + IN UINT64 Phys +) +{ + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_VIEWPORT, (UINT32)(LS_PCIE_A= TU_REGION_INBOUND | Idx)); + + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_BASE, Phys); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_BASE, (UINT32)(Phys >>= 32)); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_TARGET, (UINT32)Phys); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_TARGET, (UINT32)(Phys = >> 32)); + + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR1, LS_PCIE_ATU_TYPE_MEM); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR2, LS_PCIE_ATU_ENABLE); +} + +/** + Function to set up internal address translation window for outbound + transaction +**/ +VOID +PcieIatuOutboundSet ( + IN LsPcie *Pcie, + IN UINT32 Idx, + IN UINT32 Type, + IN UINT64 Phys, + IN UINT64 BusAddr, + IN UINT64 Size +) +{ + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_VIEWPORT, (UINT32)(LS_PCIE_A= TU_REGION_OUTBOUND | Idx)); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_BASE, Phys); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_BASE, (UINT32)(Phys >>= 32)); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LIMIT, (UINT32)(Phys + Size = -1)); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_TARGET, (UINT32)BusAdd= r); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_TARGET, (UINT32)(BusAd= dr >> 32)); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR1, (UINT32)Type); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR2, LS_PCIE_ATU_ENABLE); +} + +EFI_STATUS +PciSkipDev ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev +) +{ + // Do not skip controller + return EFI_SUCCESS; +} + +/** + Function to check whether PCIe address is valid +**/ +EFI_STATUS +PcieAddrValid ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev +) +{ + if ((((Dev >> 19)) & 0x1f) > 0) { + return EFI_DEVICE_ERROR; + } + + // No support for multi-function + if ((((Dev >> 16)) & 0x07) > 0) { + return EFI_DEVICE_ERROR; + } + + // Controller does not support multi-function in RC mode + if (((((Dev) >> 24) & 0xff) =3D=3D PrivateData->FirstBusno) && ((((Dev) = >> 16) & 0x7) > 0)) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Function to read from PCI config space + + @param Pointer to PCI_ROOT_BRIDGE_INSTANCE + + @return The value(32-bit) read + +**/ + +EFI_STATUS +PcieReadConfig ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Where, + IN OUT UINT32 *Val +) +{ + LsPcie *Pcie; + UINT32 BusDev, *Addr; + + *Val =3D 0x00000000; + Pcie =3D PrivateData->Pcie; + + if (PcieAddrValid (PrivateData, Dev)) { + *Val =3D 0xffffffff; + return EFI_DEVICE_ERROR; + } + + if ((((Dev) >> 24) & 0xff) =3D=3D PrivateData->FirstBusno) { + Addr =3D Pcie->Dbi + Where; + } else { + BusDev =3D Dev; + + if ((((Dev) >> 24) & 0xff) =3D=3D PrivateData->FirstBusno + 1) { + PcieCfg0SetBusdev (Pcie, BusDev); + Addr =3D (VOID *)Pcie->VaCfg0 + Where; + } else { + PcieCfg1SetBusdev (Pcie, BusDev); + Addr =3D (VOID *)Pcie->VaCfg1 + Where; + } + } + + *Val =3D MmioRead32 ((UINTN)Addr); + return EFI_SUCCESS; +} + +/** + Function to read byte from PCI config space + + @param Pointer to PCI_ROOT_BRIDGE_INSTANCE + + @return The value(8-bit) read + +**/ + +EFI_STATUS +PcieReadConfigByte ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + IN OUT UINT8 *Val +) +{ + UINT32 Val32; + + if (EFI_ERROR (PcieReadConfig (PrivateData, Dev, Offset & 0xfc, &Val32))= ) { + *Val =3D -1; + return EFI_DEVICE_ERROR; + } + + *Val =3D (Val32 >> ((Offset & (INT32)0x03) * 8)); + + return EFI_SUCCESS; +} + +/** + Function to read word(16-bit) from PCI config space + + @param Pointer to PCI_ROOT_BRIDGE_INSTANCE + + @return The value(16-bit) read + +**/ + +EFI_STATUS +PcieReadConfigWord ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + IN OUT UINT16 *Val +) +{ + UINT32 Val32; + + if (EFI_ERROR (PcieReadConfig (PrivateData, Dev, Offset & 0xfc, &Val32))= ) { + *Val =3D -1; + return EFI_DEVICE_ERROR; + } + + *Val =3D (UINT16)(Val32 >> ((Offset & (INT32)0x02) * 8)); + + return EFI_SUCCESS; +} + +/** + Function to write byte to PCI config space + + @param Pointer to PCI_ROOT_BRIDGE_INSTANCE + + @return EFI_SUCCESS (8-bit value written) + +**/ + +EFI_STATUS +PcieWriteConfigByte ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + OUT UINT8 Val +) +{ + UINT32 Val32, Mask, Ldata, Shift; + + if (EFI_ERROR (PcieReadConfig (PrivateData, Dev, Offset & 0xfc, &Val32))= ) { + return EFI_DEVICE_ERROR; + } + + Shift =3D ((Offset & (INT32)0x03) * 8); + Ldata =3D (((UINT32)Val) & 0x000000ff) << Shift; + Mask =3D 0x000000ff << Shift; + Val32 =3D (Val32 & ~Mask) | Ldata; + + if (EFI_ERROR (PcieWriteConfig (PrivateData, Dev, Offset & 0xfc, Val32))= ) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Function to write word to PCI config space + + @param Pointer to PCI_ROOT_BRIDGE_INSTANCE + + @return EFI_SUCCESS (16-bit value written) + +**/ + +EFI_STATUS +PcieWriteConfigWord ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Offset, + OUT UINT16 Val +) +{ + UINT32 Val32, Mask, Ldata, Shift; + + if (EFI_ERROR (PcieReadConfig (PrivateData, Dev, Offset & 0xfc, &Val32))= ) { + return EFI_DEVICE_ERROR; + } + + Shift =3D ((Offset & (INT32)0x02) * 8); + Ldata =3D (((UINT32)Val) & 0x0000ffff) << Shift; + Mask =3D 0x0000ffff << Shift; + Val32 =3D (Val32 & ~Mask) | Ldata; + + if (EFI_ERROR (PcieWriteConfig (PrivateData, Dev, Offset & 0xfc, Val32))= ) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Function to write to PCI config space + + @param Pointer to PCI_ROOT_BRIDGE_INSTANCE + + @return EFI_SUCCESS (32-bit value written) + +**/ + +EFI_STATUS +PcieWriteConfig ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN UINT32 Dev, + IN INT32 Where, + IN UINT32 Val +) +{ + LsPcie *Pcie; + UINT32 BusDev, *Addr; + + Pcie =3D PrivateData->Pcie; + + if (PcieAddrValid (PrivateData, Dev)) { + return EFI_DEVICE_ERROR; + } + + if ((((Dev) >> 24) & 0xff) =3D=3D PrivateData->FirstBusno) { + Addr =3D Pcie->Dbi + (Where & ~0x3); + } else { + BusDev =3D Dev; + + if ((((Dev) >> 24) & 0xff) =3D=3D PrivateData->FirstBusno + 1) { + PcieCfg0SetBusdev (Pcie, BusDev); + Addr =3D (VOID *)Pcie->VaCfg0 + (Where & ~0x3); + } else { + PcieCfg1SetBusdev (Pcie, BusDev); + Addr =3D (VOID *)Pcie->VaCfg1 + (Where & ~0x3); + } + } + + MmioWrite32 ((UINTN)Addr, (UINT32)Val); + return EFI_SUCCESS; +} + +/** + Function to set up address translation unit for PCI + inbound transactions +**/ +VOID +PcieSetupAtuInbound ( + IN LsPcie *Pcie, + IN LsPcieInfo *Info +) +{ + UINT32 ValIn; + UINT32 ValOut; + UINT32 *Addr; + + ValIn =3D 0x00000000; + ValOut =3D 0x28282828; + Addr =3D (UINT32 *)0x80080000; + + MmioWrite32 ((UINTN)Addr, (UINT32)ValOut); + DEBUG ((DEBUG_INFO,"\nValue: %08lx written on Addr: %08lx\n", ValOut, Ad= dr)); + ValIn =3D MmioRead32 ((UINTN)Addr); + DEBUG ((DEBUG_INFO, "Value Read: %08lx from Address: %llx\n", ValIn, Add= r)); + // ATU 2 : OUTBOUND : MEM + PcieIatuInboundSet (Pcie, LS_PCIE_ATU_REGION_INDEX2, 1, 0x80080000); + + Addr =3D (VOID *)Pcie->VaCfg0 + 0x40000000; + ValIn =3D MmioRead32 ((UINTN)Addr); + DEBUG ((DEBUG_INFO, "Inbound: Value Read: %08lx from Address: %llx\n", V= alIn, Addr)); + Addr =3D (VOID *)Pcie->VaCfg0 + 0x00000000; + ValIn =3D MmioRead32 ((UINTN)Addr); + DEBUG ((DEBUG_INFO, "Inbound: Value Read: %08lx from Address: %llx\n", V= alIn, Addr)); + Addr =3D (UINT32 *)0x80080000; + ValIn =3D MmioRead32((UINTN)Addr); + DEBUG ((DEBUG_INFO, "Inbound: Value Read: %08lx from Address: %llx\n", V= alIn, Addr)); + +} + +/** + Function to set up address translation unit for PCI + outbound transactions +**/ +VOID +PcieSetupAtu ( + IN LsPcie *Pcie, + IN LsPcieInfo *Info +) +{ + // ATU 0 : OUTBOUND : CFG0 + PcieIatuOutboundSet (Pcie, LS_PCIE_ATU_REGION_INDEX0, + LS_PCIE_ATU_TYPE_CFG0, + Info->Cfg0Phys, + 0, + Info->Cfg0Size); + + // ATU 1 : OUTBOUND : CFG1 + PcieIatuOutboundSet (Pcie, LS_PCIE_ATU_REGION_INDEX1, + LS_PCIE_ATU_TYPE_CFG1, + Info->Cfg1Phys, + 0, + Info->Cfg1Size); + + // ATU 2 : OUTBOUND : MEM + PcieIatuOutboundSet (Pcie, LS_PCIE_ATU_REGION_INDEX2, + LS_PCIE_ATU_TYPE_MEM, + Info->MemPhys, + Info->MemBus, + //0x10000000, + Info->MemSize); + + // ATU 3 : OUTBOUND : IO + PcieIatuOutboundSet (Pcie, LS_PCIE_ATU_REGION_INDEX3, + LS_PCIE_ATU_TYPE_IO, + Info->IoPhys, + Info->IoBus, + Info->IoSize); + + if (FeaturePcdGet (PcdPciDebug) =3D=3D TRUE) { + INTN Cnt; + UINTN AddrTemp; + for (Cnt =3D 0; Cnt <=3D LS_PCIE_ATU_REGION_INDEX3; Cnt++) { + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_VIEWPORT, + (UINT32)(LS_PCIE_ATU_REGION_OUTBOUND | Cnt)); + DEBUG ((DEBUG_INFO,"iATU%d:\n", Cnt)); + AddrTemp =3D (UINTN)((UINTN)Pcie->Dbi + LS_PCIE_ATU_VIEWPORT); + DEBUG((DEBUG_INFO,"iATU%d VIEWPORT REG Addr:%08lx Val:%08lx\n", + Cnt, AddrTemp, MmioRead32(AddrTemp))); + DEBUG ((DEBUG_INFO,"iATU%d VIEWPORT REG:%08lx\n", Cnt, + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_VIEWPORT))); + DEBUG ((DEBUG_INFO,"\tLOWER PHYS 0x%08x\n", + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_BASE))); + DEBUG ((DEBUG_INFO,"\tUPPER PHYS 0x%08x\n", + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_BASE))); + DEBUG ((DEBUG_INFO,"\tLOWER BUS 0x%08x\n", + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LOWER_TARGET))); + DEBUG ((DEBUG_INFO,"\tUPPER BUS 0x%08x\n", + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_UPPER_TARGET))); + DEBUG ((DEBUG_INFO,"\tLIMIT 0x%08x\n", + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_LIMIT))); + DEBUG ((DEBUG_INFO,"\tCR1 0x%08x\n", + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR1))); + DEBUG ((DEBUG_INFO,"\tCR2 0x%08x\n", + MmioRead32 ((UINTN)Pcie->Dbi + LS_PCIE_ATU_CR2))); + } + } +} + +/** + Function to set up PCI controller + -Setup ATU + -Setup Root complex class +**/ +VOID +PcieSetupCntrl ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN LsPcie *Pcie, + IN LsPcieInfo *Info +) +{ + UINTN Dev; + + Dev =3D ((PrivateData->FirstBusno) << 16 | (0) << 11 | (0) << 8); + + if (FeaturePcdGet (PcdPciDebug) =3D=3D TRUE) { + DEBUG ((DEBUG_INFO, "Going to SetUp IATU\n\n")); + } + + PcieSetupAtu (Pcie, Info); + + PcieWriteConfig (PrivateData, Dev, LS_PCI_BASE_ADDRESS_0, 0); + + // program correct class for RC + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_DBI_RO_WR_EN, (UINT32)1); + PcieWriteConfigWord (PrivateData, Dev, LS_PCI_CLASS_DEVICE, + PCI_CLASS_BRIDGE_PCI); + MmioWrite32 ((UINTN)Pcie->Dbi + LS_PCIE_DBI_RO_WR_EN, (UINT32)0); +} diff --git a/Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/P= latform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf new file mode 100644 index 0000000..f281357 --- /dev/null +++ b/Platform/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf @@ -0,0 +1,49 @@ +/* PciHostBridgeLib.inf +# +# Component description file for PCI root Bridge Library +# +# Copyright 2017 NXP +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may b= e 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 IM= PLIED. +# +# +*/ + +[Defines] + INF_VERSION =3D 0x0001001A + BASE_NAME =3D PciHostBridgeLib + FILE_GUID =3D c0f5dfa0-7599-11e0-9865-0002a5d5c61b + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D PciHostBridgeLib + +[Packages] + ArmPkg/ArmPkg.dec + MdePkg/MdePkg.dec + Platform/NXP/NxpQoriqLs.dec + Silicon/NXP/Chassis/Chassis2/Chassis2.dec + +[Sources.common] + PciCntrl.c + PciRbLib.c + +[FixedPcd] + gNxpQoriqLsTokenSpaceGuid.PcdPciDebug + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp2BaseAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp3BaseAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp4BaseAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1SysAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp2SysAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp3SysAddr + gNxpQoriqLsTokenSpaceGuid.PcdPciExp4SysAddr + gArmTokenSpaceGuid.PcdSystemMemoryBase + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg + gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian diff --git a/Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c b/Platform/NX= P/Library/PciHostBridgeLib/PciRbLib.c new file mode 100644 index 0000000..4ebfc73 --- /dev/null +++ b/Platform/NXP/Library/PciHostBridgeLib/PciRbLib.c @@ -0,0 +1,331 @@ +/** PciRbLib.c + Functions supporting PCI Root Bridge Io Protocol + + Some part of code is inspired from EDK II, file: + PcAtChipsetPkg/PciHostBridgeDxe/PciRootBridgeIo.c + + Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved. + Copyright 2017 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 + 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 IMPL= IED. + +**/ + +#include "PciHostBridge.h" + +// +// Lookup table for increment values based on transfer widths +// +UINT8 mInStride[] =3D { + 1, // EfiPciWidthUint8 + 2, // EfiPciWidthUint16 + 4, // EfiPciWidthUint32 + 8, // EfiPciWidthUint64 + 0, // EfiPciWidthFifoUint8 + 0, // EfiPciWidthFifoUint16 + 0, // EfiPciWidthFifoUint32 + 0, // EfiPciWidthFifoUint64 + 1, // EfiPciWidthFillUint8 + 2, // EfiPciWidthFillUint16 + 4, // EfiPciWidthFillUint32 + 8 // EfiPciWidthFillUint64 +}; + +// +// Lookup table for increment values based on transfer widths +// +UINT8 mOutStride[] =3D { + 1, // EfiPciWidthUint8 + 2, // EfiPciWidthUint16 + 4, // EfiPciWidthUint32 + 8, // EfiPciWidthUint64 + 1, // EfiPciWidthFifoUint8 + 2, // EfiPciWidthFifoUint16 + 4, // EfiPciWidthFifoUint32 + 8, // EfiPciWidthFifoUint64 + 0, // EfiPciWidthFillUint8 + 0, // EfiPciWidthFillUint16 + 0, // EfiPciWidthFillUint32 + 0 // EfiPciWidthFillUint64 +}; + +/** + Function to validate parameters(Operation type,Supported width) for + root bridge io operation + + @param This Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL + + @param OperationType Operation type(Mem,I/O,Config) + + @param Width Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH + + @return EFI_SUCCESS Paramters check is ok for operation + + @return EFI_INVALID_PARAMETER Inavlide parameters + +**/ +STATIC EFI_STATUS +RootBridgeIoCheckParameter ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN OPERATION_TYPE OperationType, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer + ) +{ + if ((Width >=3D EfiPciWidthMaximum) || (Width < EfiPciWidthUint8) || (NU= LL =3D=3D Buffer)) { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +/** + Internal help function for read and write memory space. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROT= OCOL. + @param[in] Write Switch value for Read or Write. + @param[in] Width Signifies the width of the memory operations. + @param[in] UserAddress The address within the PCI configuration spa= ce for the PCI controller. + @param[in] Count The number of PCI configuration operations t= o perform. Bytes + moved is Width size * Count, starting at Add= ress. + @param[in, out] UserBuffer For read operations, the destination buffer = to store the results. For + write operations, the source buffer to write= data from. + + @retval EFI_SUCCESS The data was read from or written to the= PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridg= e. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +RootBridgeIoMemRW ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN BOOLEAN Write, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + UINT8 InStride; + UINT8 OutStride; + UINT8 *Uint8Buffer; + PCI_ROOT_BRIDGE_INSTANCE *PrivateData; + + Status =3D RootBridgeIoCheckParameter (This, MemOperation, Width, Addres= s, Count, Buffer); + if (EFI_ERROR (Status)) { + return Status; + } + + if ((Address < LS_PCIE_MEM_PHYS_OFF) || + (Address >=3D ((UINT32)LS_PCIE_MEM_PHYS_OFF + + LS_PCIE_MEM_SIZE))) { + return EFI_INVALID_PARAMETER; + } + + PrivateData =3D DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This); + if (PrivateData =3D=3D NULL ) { + return EFI_INVALID_PARAMETER; + } + + Address +=3D PrivateData->PciBaseAddress64; + + InStride =3D mInStride[Width]; + OutStride =3D mOutStride[Width]; + + for (Uint8Buffer =3D Buffer; Count > 0; Address +=3D InStride, Uint8Buff= er +=3D OutStride, Count--) { + if (Write) { + switch (Width) { + case EfiPciWidthUint8: + MmioWrite8 ((UINTN)Address, *Uint8Buffer); + break; + case EfiPciWidthUint16: + MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer)); + break; + case EfiPciWidthUint32: + MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer)); + break; + case EfiPciWidthUint64: + MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer)); + break; + default: + // + // The RootBridgeIoCheckParameter call above will ensure that th= is + // path is not taken. + // + ASSERT (FALSE); + break; + } + } else { + switch (Width) { + case EfiPciWidthUint8: + *Uint8Buffer =3D MmioRead8 ((UINTN)Address); + break; + case EfiPciWidthUint16: + *((UINT16 *)Uint8Buffer) =3D MmioRead16 ((UINTN)Address); + break; + case EfiPciWidthUint32: + *((UINT32 *)Uint8Buffer) =3D MmioRead32 ((UINTN)Address); + break; + case EfiPciWidthUint64: + *((UINT64 *)Uint8Buffer) =3D MmioRead64 ((UINTN)Address); + break; + default: + // + // The RootBridgeIoCheckParameter call above will ensure that th= is + // path is not taken. + // + ASSERT (FALSE); + break; + } + } + } + return EFI_SUCCESS; +} + +/** + Internal help function for read and write IO space. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROT= OCOL. + @param[in] Write Switch value for Read or Write. + @param[in] Width Signifies the width of the memory operations. + @param[in] UserAddress The address within the PCI configuration spa= ce for the PCI controller. + @param[in] Count The number of PCI configuration operations t= o perform. Bytes + moved is Width size * Count, starting at Add= ress. + @param[in, out] UserBuffer For read operations, the destination buffer = to store the results. For + write operations, the source buffer to write= data from. + + @retval EFI_SUCCESS The data was read from or written to the= PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridg= e. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +RootBridgeIoIoRW ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN BOOLEAN Write, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + DEBUG ((DEBUG_INFO, "PCI Root Bridge Io Io Read/Write function is not im= plemented yet.\n")); + return EFI_SUCCESS; +} + +/** + Internal help function for read and write PCI configuration space. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROT= OCOL. + @param[in] Write Switch value for Read or Write. + @param[in] Width Signifies the width of the memory operations. + @param[in] UserAddress The address within the PCI configuration spa= ce for the PCI controller. + @param[in] Count The number of PCI configuration operations t= o perform. Bytes + moved is Width size * Count, starting at Add= ress. + @param[in, out] UserBuffer For read operations, the destination buffer = to store the results. For + write operations, the source buffer to write= data from. + + @retval EFI_SUCCESS The data was read from or written to the= PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridg= e. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +RootBridgeIoPciRW ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN BOOLEAN Write, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + INT32 Offset; + UINT32 BusDev; + UINT8 InStride; + UINT8 OutStride; + UINT8 *Uint8Buffer; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr; + PCI_ROOT_BRIDGE_INSTANCE *PrivateData; + + PrivateData =3D DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This); + Status =3D RootBridgeIoCheckParameter (This, PciOperation, Width, Addres= s, Count, Buffer); + if (EFI_ERROR (Status)) { + return Status; + } + + PciRbAddr =3D (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address; + + if (PciRbAddr->ExtendedRegister) { + Offset =3D (INT32) PciRbAddr->ExtendedRegister; + } + else { + Offset =3D (INT32) PciRbAddr->Register; + } + + BusDev =3D (UINT32)PCI_BUS_DEV ( + PciRbAddr->Bus, + PciRbAddr->Device, + PciRbAddr->Function + ); + + InStride =3D mInStride[Width]; + OutStride =3D mOutStride[Width]; + + for (Uint8Buffer =3D Buffer; Count > 0; Offset +=3D InStride, Uint8Buffe= r +=3D OutStride, Count--) { + if (Write) { + switch (Width) { + case EfiPciWidthUint8: + Status =3D PcieWriteConfigByte (PrivateData, (UINT32)BusDev, Off= set, *Uint8Buffer); + break; + case EfiPciWidthUint16: + Status =3D PcieWriteConfigWord (PrivateData, (UINT32)BusDev, Off= set, *(UINT16 *)Uint8Buffer); + break; + case EfiPciWidthUint32: + Status =3D PcieWriteConfig (PrivateData, (UINT32)BusDev, Offset,= *(UINT32 *)Uint8Buffer); + break; + default: + // + // The RootBridgeIoCheckParameter call above will ensure that th= is + // path is not taken. + // + ASSERT (FALSE); + break; + } + } else { + switch (Width) { + case EfiPciWidthUint8: + Status =3D PcieReadConfigByte (PrivateData, (UINT32)BusDev, Offs= et, Uint8Buffer); + break; + case EfiPciWidthUint16: + Status =3D PcieReadConfigWord (PrivateData, (UINT32)BusDev, Offs= et, (UINT16 *)Uint8Buffer); + break; + case EfiPciWidthUint32: + Status =3D PcieReadConfig (PrivateData, (UINT32)BusDev, Offset, = (UINT32 *)Uint8Buffer); + break; + default: + // + // The RootBridgeIoCheckParameter call above will ensure that th= is + // path is not taken. + // + ASSERT (FALSE); + break; + } + } + } + + return Status; +} --=20 1.9.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Fri May 3 07:57:59 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1513925434331444.05080356825204; Thu, 21 Dec 2017 22:50:34 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 7AC06222CB315; Thu, 21 Dec 2017 22:45:43 -0800 (PST) Received: from NAM03-CO1-obe.outbound.protection.outlook.com (mail-co1nam03on0058.outbound.protection.outlook.com [104.47.40.58]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 16A17222CB309 for ; Thu, 21 Dec 2017 22:45:41 -0800 (PST) Received: from BN3PR03CA0084.namprd03.prod.outlook.com (10.167.1.172) by CY4PR03MB2694.namprd03.prod.outlook.com (10.173.43.137) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.323.15; Fri, 22 Dec 2017 06:50:29 +0000 Received: from BN1AFFO11FD029.protection.gbl (2a01:111:f400:7c10::143) by BN3PR03CA0084.outlook.office365.com (2a01:111:e400:7a4d::44) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.345.14 via Frontend Transport; Fri, 22 Dec 2017 06:50:28 +0000 Received: from tx30smr01.am.freescale.net (192.88.168.50) by BN1AFFO11FD029.mail.protection.outlook.com (10.58.52.184) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.20.302.6 via Frontend Transport; Fri, 22 Dec 2017 06:50:13 +0000 Received: from uefi-OptiPlex-790.ap.freescale.net ([10.232.132.56]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id vBM6oHF3022495; Thu, 21 Dec 2017 23:50:25 -0700 X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=104.47.40.58; helo=nam03-co1-obe.outbound.protection.outlook.com; envelope-from=vabhav.sharma@nxp.com; receiver=edk2-devel@lists.01.org Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=nxp.com; nxp.com; dkim=none (message not signed) header.d=none;nxp.com; dmarc=fail action=none header.from=nxp.com; Received-SPF: Fail (protection.outlook.com: domain of nxp.com does not designate 192.88.168.50 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.168.50; helo=tx30smr01.am.freescale.net; From: Vabhav To: , , , Date: Fri, 22 Dec 2017 00:18:28 +0530 Message-ID: <1513882109-14295-3-git-send-email-vabhav.sharma@nxp.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1513882109-14295-1-git-send-email-vabhav.sharma@nxp.com> References: <1513882109-14295-1-git-send-email-vabhav.sharma@nxp.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131583990141151628; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(336005)(7966004)(396003)(376002)(346002)(39380400002)(39860400002)(2980300002)(1110001)(1109001)(339900001)(199004)(189003)(68736007)(966005)(8936002)(5660300001)(6306002)(356003)(77096006)(59450400001)(104016004)(47776003)(4326008)(53376002)(53946003)(305945005)(15188155005)(8676002)(2906002)(36756003)(498600001)(5890100001)(53936002)(85426001)(2201001)(316002)(16799955002)(97736004)(106466001)(51416003)(81166006)(2950100002)(50466002)(50226002)(105606002)(48376002)(551934003)(16200700003)(110136005)(76176011)(86362001)(81156014)(575784001)(16586007)(54906003)(8656006)(559001)(579004)(569006); DIR:OUT; SFP:1101; SCL:1; SRVR:CY4PR03MB2694; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BN1AFFO11FD029; 1:b0RempyeWoHRYFazewSQ6zrysdMOk0/NIipOrfQfySVAzQ8lS31nZ65YMnSGhLSEUtxis4k4hq3AXfcXsdDNYTbqZ1cfDisf+69r+aVTK7jeEAOxPyf1oxNhzNRJOC4y MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ea8767b5-9edf-4a46-e98c-08d5490840f4 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(5600026)(4604075)(4534020)(4628075)(201703131517081)(2017052603307); SRVR:CY4PR03MB2694; X-Microsoft-Exchange-Diagnostics: 1; CY4PR03MB2694; 3:q64CZz0C1gRKaZ4N4vx/huuFxrU2MpMDEHrrXVRdeM6Eov5nsQiuxUnuJc1AOTav5NWvwK84vP1bDazE1+7NM/iSeEkax8oyJTVFG8qG/6vRlKLNS4AfNoNbijomCs+Sum+1W0QGdseHv+tSKm9iyo3TD5qjwtT6dfNkkfD5f8c6act6fm33jSuj7pTAYr7q9JbjeNFiNmveFLMpa5kXY70wPxkpyptVyO2XdGFZSx8o1fzDKj3N2497m8p84rROR9a52pMVbpIpjOJKYIZrYs1WajslyMxqS4Ef9H7V1KKixfhnUHZGveQqOBxDmKKmCJw38/EtUIoRATUrJJ4QSKZXCmAdZaGwyAzQ9SSnARo=; 25:jajnetQGT+2yeDg7M8s650b7XNYPtZs3k9WhpoRAiePq06Ex/M1fYJyAZUOJdkZpBPVSvNWHGiUKAIUKzrk5esZ80BJy3Sr0MK5e6lvf9BDmXDKk3hVickU3fCktpLGOXdnPuxJHMp6hzm4OHnxtQfd7wVIm5mQzB31518RPh+NSHqCb/cyOweYq/RxhND6y3vJY4mco1o2CQJ6noHbeXPGQPuB8DETQPTIOi4sQYXHjvHNajyR4HQox0YRS8cf4FMrPCL1HVRhzwIrrAT4I/MunoLqyVWPHTieZKKZU6cqSgTSvocaHXPivbywgzdq7ZEUdXfPKUicSkqH9BS4Oig== X-MS-TrafficTypeDiagnostic: CY4PR03MB2694: X-Microsoft-Exchange-Diagnostics: 1; CY4PR03MB2694; 31:+CCHsQNnmAuI9AGWz0PUHIe1dnUnJvwYkgz/mjnJ1YaHyBbJjNbnoljvJdvWcdXfo1orUOTAH453p3MjoWVGsIDl2v0sC2+1ncr+QG4bCWa/Fn4xcXsm0O78ob7ogwux0JxFfdiOPD5tRw6SwqjZQSvfd649ZK4HzKrn1Kpcb/uwNkFgC8K/6iyEyknluTmgSgA/YQlunLZFzH6g437RolDhGvuzWwZPs/J2e0xKsJA=; 4:grb9E19B/49mB5V7+XIcTZokUgywB4X8b+8TisSZqtD+uz2lI3sDrtTYfBox1RkqP3b1J9/6GePsIOyC9r8pRbkskXTcNuE2nJ9wOPw3oF/40ra0rj1rHD25kZ5HH+C5kTHdNngfv72jzoK628EnPykkN98bWu814Y2Sj24fjr2XSfdNGPzJnBjoH426ONq3uXvQ+c52pbanoNa82WevngTpyeqlVL48QRIQbdNAxD+wX118jNIQ7S/msTdgDPGrqEUeGP+Ry8Qqu+yWGXRLgvU7Q1kpfgrpS1x/FhCB5zBwWcyJaBST76EitsOkZWZXATF2fL546xemndW/guxuF64341hNWBhH0NU2TBc4KGM= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197)(211171220733660); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6095135)(2401047)(8121501046)(5005006)(3231023)(93006095)(93001095)(10201501046)(3002001)(6055026)(6096035)(20161123563025)(201703131430075)(201703131433075)(201703131441075)(201703131448075)(201703161259150)(20161123559100)(20161123556025)(20161123561025)(20161123565025)(201708071742011); SRVR:CY4PR03MB2694; BCL:0; PCL:0; RULEID:(100000803101)(100110400095)(400006); SRVR:CY4PR03MB2694; X-Forefront-PRVS: 05299D545B X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CY4PR03MB2694; 23:awWRUih+v3e2aASsuZKePgF4JvtqII8X2xPRTTjoc?= =?us-ascii?Q?3JAwyDbc8xXgjJISr1GIS3e/H5ujrY4+VowqwZkwphIemw8brm1AGAb3TAOJ?= =?us-ascii?Q?LcgGXuMZXWy8WKKk8Eyb2Q1ppwy8C0klkAco8gUmruoNFKYdu5UzXuVH4Pmy?= =?us-ascii?Q?R6kGwx58R2QxwlTVhcaJqHN4qlI+SiLqL5HSIwpG2Mjsw8axB7d/rtjLnFUN?= =?us-ascii?Q?HKeTj3Tg8jTx6UJdswJRi+ik32KCEaOGFOo6xTTy4E09ULulC4A57NjZbChp?= =?us-ascii?Q?pVrqbOzMQUUDkfls+snSDSJ27Lb5pGd+EqqIt/ZRRfZy1qtmbj2stJyERFe2?= =?us-ascii?Q?nnzMRHxqxt3rMSmHlebYdnWcjaqSE2Bv25iVCbjITWP6Mt+Nl1iUugj/amIW?= =?us-ascii?Q?GjkyrtrKzCS8KnnArHuQD5BVZJjBH3kbrT1GC/AHBH5UQCbzwcBuWYMluwSX?= =?us-ascii?Q?f3sMyWTJ+rfelm8+oMtSPGBfJIQDAHnGV9t3CF5KhThNGytFOhRLKytp9iyW?= =?us-ascii?Q?3YZ2LKCKOuHxmH12eI5ye2SwdOl+FBr5pvKHB7tisVPHuGyn2/148gW6B3vJ?= =?us-ascii?Q?XjfAlgYZFy9ascYsHjncFOK+Mx/wY8kGRj3g20WSHt6x6DrvVMIhsCLvaLgJ?= =?us-ascii?Q?nenpMTcwmtjfYBHzzTa+yWopUbSYagjRR9Dv0qe39n2hNetLuPupUiUmeog+?= =?us-ascii?Q?llZplXYEG8N6DJaaSmRNSL8uKMFt1bPfML4ROg6d1vAfgCKzMmPqJcPc49/5?= =?us-ascii?Q?8XULVSGEy5AR9k2RITONmgKd12pSp3bjvk86hUIvQzPPxqmjGYgOP3DjabWq?= =?us-ascii?Q?vHMjMRBHXEd6BVVkGelV6+0kC+Bwz3K9MT3jEUhhCjX4KBfb9kkZ8/ogxy+L?= =?us-ascii?Q?2qx8i2Y2UU1eG8ILSzIIY/MVNWlLWG3Ro8K1N7Cjo1u7V8AuxH347jKyi3+i?= =?us-ascii?Q?ADavuasOK86bbefsndWyWrKyy8k+P7ORj+3I8VHnyGUTIxtTndL6Kt1phdH8?= =?us-ascii?Q?tJxxYRztY0veguGJdXy2w31Xiv4vWF+oUnNiTXxed8ssJWz6wtVEeznIKRlH?= =?us-ascii?Q?J4ScQ4HzJD/jmu2zEyX/UAOA/PHgCW8/bAIzttgcQFuRclcBiKw/C5/CYs93?= =?us-ascii?Q?VAGANmn72EcrE4t6v5dTGfYSbjaCp61KAPABcpEAx6l3NasU+wnKvBQDc/sj?= =?us-ascii?Q?7LBVNUs77ChV2JbmMdDyJSkmqlRzhSTu/JcMHEqpPIlUpK0c2xQG3eTWYCP1?= =?us-ascii?Q?xsOtv8ViIuMxGfiqdkGI6GjSFTaURKklWt1GQD3wSVpIJjuJePd4skkSzXYC?= =?us-ascii?Q?O0Sm0hz58YDGdbOLft8rPHJH6I/PknT2errsgKUFH/F/8BlH9ZHKr3Mq8joW?= =?us-ascii?Q?jRyPEWP2z6hdQvTUXvyp09mqxetsoiSdRak1WUPrW35oOep?= X-Microsoft-Exchange-Diagnostics: 1; CY4PR03MB2694; 6:P9GoRqmreM0DzR99ETyql79Pb9Kczxt98wjcWpgtOj7CLfZdsgJoHPLM7HE82qC4A+iXaaTSpNjNLvtdmZ9nEDADPKYFzQDEbf04442eZEwxksMCTauY9yFQvIdm+izabUN/D7PBLBR6f7gs3pI0ujQ3cjt+wFetgQcVSbqp9P/pJj9vHA3vdEhMe3ByD+tYNcFDSLcjGt3N/r6s9aepLP5cadaLXmc9YjzZrjXMNoj9MX4VQhCQcqORXcDxc1lTB1nVIha09H5LGjGdDOXojyvohM5LrTqjySV1C3x2a6AIh4+hTsLUQVX4WCZijM7JLyJtW81+D3NGTWl5oIyL0llfOx/f3aj6NRoFvhfGCWA=; 5:2pnf1F5rAlk7H4VG8cw3jjt49uxPX0oGBg+ymVqG7alDCBjJBmBmeefOwi8jeK0rs3CsWaCodsZhSjSph1tCxehOfJS8gKxsEWGY75idVcVdkmH7YAG7utAdz2ZbLcZP1YIBWlhsgJsfvlRcDNQY5BPh+7I4SyqM7iQqRWtTfiI=; 24:McQNdVoTvllyYzLK8YvnNrFeCEEAKbQ1mn9Qo/Z5QggSJr/wdgOT71UE0BS9D6oT9QjCuLn/aOAXEQoLTnYsSB+gMMSnkS38RpibJLVaewQ=; 7:fBFK6z6WWRdKh80q2qBmYIH4h/2sJ2hHwkdQueXARV9aq5CeSi1WTnPp32Coj6TsL0dgVcdenPAdrZinaEFSX9qwBgz5zRnTz6bDf7TXhAI63YbLrzjTto4boyP5fozKzW3ZXE11f/5maiZAwdeQouSR9o+LjX4lResFuJQgttOlB1OZyDyTox4U8MgPz02WJvi6A1O7/jNVjh1numlARcp+ycpN+hOAtejMR87GXVawQlqG0YqnhYboVFtPPyZb SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Dec 2017 06:50:13.9435 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ea8767b5-9edf-4a46-e98c-08d5490840f4 X-MS-Exchange-CrossTenant-Id: 5afe0b00-7697-4969-b663-5eab37d5f47e X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e; Ip=[192.88.168.50]; Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR03MB2694 Subject: [edk2] [PATCH edk2-platforms 2/3] Platform/NXP : Add PCI Host Bridge Driver 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: , Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Added NXP PCI host bridge Dxe driver which install host bridge resource allocation protocol,root bridge IO protocol,Device path protocol and consumes MetronomeArch Protocol. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Vabhav --- .../Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c | 967 ++++++++++++++++ .../Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf | 61 + .../NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c | 1193 ++++++++++++++++= ++++ Platform/NXP/Include/PciHostBridge.h | 466 ++++++++ Platform/NXP/Include/PciRootBridge.h | 674 +++++++++++ 5 files changed, 3361 insertions(+) create mode 100644 Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c create mode 100644 Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.= inf create mode 100644 Platform/NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c create mode 100644 Platform/NXP/Include/PciHostBridge.h create mode 100644 Platform/NXP/Include/PciRootBridge.h diff --git a/Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c b/Pla= tform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c new file mode 100644 index 0000000..e9e43bc --- /dev/null +++ b/Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.c @@ -0,0 +1,967 @@ +/** PciHostBridgeDxe.c + Provides all functions of PCI Host Bridge Resource Allocation Protocol + + Based on PCI HosttBridge implementation in + ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridgeResourceA= llocation.c + + Copyright (c) 2011-2015, ARM Ltd. All rights reserved. + Copyright 2017 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 + 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 IMPL= IED. + +**/ + +#include + +/** + Hard code: Root Bridge Number within the host bridge + Root Bridge's attribute + Root Bridge's device path + Root Bridge's resource aperture +**/ + +UINT64 PciMemBase[NUM_PCIE_CONTROLLER]; +UINT64 PciBaseAddr[NUM_PCIE_CONTROLLER]; + +PCI_HOST_BRIDGE_INSTANCE *HostBridge[NUM_PCIE_CONTROLLER]; +PCI_ROOT_BRIDGE_INSTANCE *PrivateData[NUM_PCIE_CONTROLLER]; + + +UINT64 RootBridgeAttribute[1][1] =3D { {EFI_PCI_HOST_BRIDGE_MEM64_DECODE |= EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM} }; + +EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath =3D { + { + { ACPI_DEVICE_PATH, + ACPI_DP, + { + (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), + (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) + } + }, + EISA_PNP_ID (0x0A03), + 0 + }, + + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } +}; + +EFI_HANDLE mPciDriverImageHandle; + +PCI_HOST_BRIDGE_INSTANCE gPciHostBridgeInstanceTemplate =3D { + PCI_HOST_BRIDGE_SIGNATURE, // Signature + NULL, // HostBridgeHandle + NULL, // ImageHandle + {0, 0, 0, 0}, // RootBridgeNumber + NULL, // RootBridgeInstance + {NULL, NULL}, // Head + FALSE, // ResourceSubiteed + TRUE, // CanRestarted + { // ResAlloc + PciNotifyPhase, + PciGetNextRootBridge, + PciGetAllocAttributes, + PciStartBusEnumeration, + PciSetBusNumbers, + PciSubmitResources, + PciGetProposedResources, + PciPreprocessController + } +}; + +/** + This function checks whether PCIe is enabled or not + depending upon board serdes protocol map + + @param PcieNum PCIe number + + @return The PCIe number enabled in map + @return FALSE PCIe number is disabled in map +**/ +STATIC +BOOLEAN +IsPcieNumEnabled( + IN UINTN PcieNum + ) +{ + UINT64 SerDes1ProtocolMap; + + SerDes1ProtocolMap =3D 0x0; + + GetSerdesProtocolMaps (&SerDes1ProtocolMap); + + if (PcieNum < NUM_PCIE_CONTROLLER) { + return IsSerDesLaneProtocolConfigured (SerDes1ProtocolMap, (PcieNum+1)= ); + } + else { + DEBUG ((DEBUG_ERROR, "Device not supported\n")); + } + + return FALSE; +} + +STATIC +EFI_STATUS +AddMemorySpace ( + IN UINT64 BaseAddress, + IN UINTN Size + ) +{ + EFI_STATUS Status; + Status =3D gDS->AddMemorySpace ( + EfiGcdMemoryTypeMemoryMappedIo, + BaseAddress, + Size, + 0 + ); + + return Status; +} + +/** + Entry point of this driver + + @param ImageHandle Handle of driver image + @param SystemTable Point to EFI_SYSTEM_TABLE + + @retval EFI_ABORTED PCI host bridge not present + @retval EFI_OUT_OF_RESOURCES Can not allocate memory resource + @retval EFI_DEVICE_ERROR Can not install the protocol instance + @retval EFI_SUCCESS Success to initialize the Pci host bridge. +**/ +EFI_STATUS +EFIAPI +PciHostBridgeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINTN Loop1; + + Status =3D EFI_OUT_OF_RESOURCES; // error + + for (Loop1 =3D 0; Loop1 < NUM_PCIE_CONTROLLER; Loop1++) { + PciMemBase[Loop1] =3D PcdGet64 (PcdPci1Mmio64Base) + + (PCI_MMIO64_BASE_DIFFERENCE * Loop1); + PciBaseAddr[Loop1] =3D PcdGet64 (PcdPciExp1BaseAddr) + + (PcdGet64 (PcdPciExp1BaseSize) * Loop1); + + DEBUG ((DEBUG_INFO, "PciMemBase %d : 0x%p\n", Loop1, PciMemBase[Loop1]= )); + DEBUG ((DEBUG_INFO, "PciBaseAddr %d : 0x%p\n", Loop1, PciBaseAddr[Loop= 1])); + } + + // + // Create Host Bridge Device Handle + // + for (Loop1 =3D 0; Loop1 < NUM_PCIE_CONTROLLER; Loop1++) { + if (!IsPcieNumEnabled (Loop1)) { + DEBUG ((DEBUG_ERROR, "PCIE%d is disabled\n", (Loop1 + 1))); + continue; + } + + DEBUG ((DEBUG_INFO, "PCIE%d is Enabled\n", (Loop1 + 1))); + + HostBridge[Loop1] =3D AllocateCopyPool (sizeof (PCI_HOST_BRIDGE_INSTAN= CE), &gPciHostBridgeInstanceTemplate); + if (HostBridge[Loop1] =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: Fail to Allocate HostBridge: %d\n", Loop= 1)); + continue; // Continue with other controllers + } + + HostBridge[Loop1]->RootBridgeNumber[Loop1] =3D TRUE; + InitializeListHead (&HostBridge[Loop1]->Head); + DEBUG ((DEBUG_INFO, "PCI : Install Protocol for HostBridge: %d\n", Loo= p1)); + + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &HostBridge[Loop1]->HostBridgeHandle, + &gEfiPciHostBridgeResourceAllocationProtocolGuid, &Hos= tBridge[Loop1]->ResAlloc, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to install resource alloc\n", __FUNCT= ION__)); + FreePool (HostBridge[Loop1]); + continue; // Continue with other controllers + } else { + DEBUG ((DEBUG_INFO, "%a: Succeed to install resource allocation prot= ocol\n", __FUNCTION__)); + } + + HostBridge[Loop1]->ImageHandle =3D ImageHandle; + // + // Create Root Bridge Device Handle in this Host Bridge + // + PrivateData[Loop1] =3D AllocateZeroPool (sizeof (PCI_ROOT_BRIDGE_INS= TANCE)); + if (PrivateData[Loop1] =3D=3D NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + HostBridge[Loop1]->HostBridgeHandle, + &gEfiPciHostBridgeResourceAllocationProtocolGuid, &H= ostBridge[Loop1]->ResAlloc, + NULL + ); // Uninstall Resource Allocation protocol + FreePool (HostBridge[Loop1]); // Unallocate previous memory, + continue; // Continue with other controllers + } + + PrivateData[Loop1]->Signature =3D PCI_ROOT_BRIDGE_SIGNATURE; + CopyMem (&(PrivateData[Loop1]->DevicePath), &mEfiPciRootBridgeDevice= Path, sizeof (EFI_PCI_ROOT_BRIDGE_DEVICE_PATH)); + // Set Device Path for this Root Bridge + + PrivateData[Loop1]->DevicePath.AcpiDevicePath.UID =3D Loop1; + PrivateData[Loop1]->PciMemBase64 =3D PciMemBase[Loop1]; + + PrivateData[Loop1]->Info =3D AllocateZeroPool (sizeof (LsPcieInfo)); + PrivateData[Loop1]->Pcie =3D AllocateZeroPool (sizeof (LsPcie)); + + SetLSPcieInfo(PrivateData[Loop1]->Info, (Loop1+1)); + + HostBridge[Loop1]->RootBridge =3D PrivateData[Loop1]; + + if (FeaturePcdGet (PcdPciDebug) =3D=3D TRUE) { + DEBUG ((DEBUG_INFO, "Installed Host Bridges successfully\n")); + } + + Status =3D PciRbInitialize ( + PrivateData[Loop1], + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *)&PrivateData[Loop1]->Io, + PrivateData[Loop1]->Info, + HostBridge[Loop1]->HostBridgeHandle, + RootBridgeAttribute[0][0], + (Loop1+1), + 0, + PciBaseAddr + ); + + if (EFI_ERROR (Status)) { + Status =3D gBS->UninstallMultipleProtocolInterfaces ( + HostBridge[Loop1]->HostBridgeHandle, + &gEfiPciHostBridgeResourceAllocationProtocolGuid, &H= ostBridge[Loop1]->ResAlloc, + NULL + ); + + FreePool (PrivateData[Loop1]->Info); + FreePool (PrivateData[Loop1]->Pcie); + FreePool (PrivateData[Loop1]); + FreePool (HostBridge[Loop1]); + DEBUG ((DEBUG_INFO, "UNInstalled HostBridge ResAlloc protocol and = Freed memory\n")); + continue; // Continue with other controllers + } + + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &PrivateData[Loop1]->Handle, + &gEfiDevicePathProtocolGuid, &PrivateData[Loop1]->De= vicePath, + &gEfiPciRootBridgeIoProtocolGuid, &PrivateData[Loop1= ]->Io, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to install RootBridgeIo and DevicePat= h protocols\n")); + FreePool (PrivateData[Loop1]); + return EFI_DEVICE_ERROR; + } + + DEBUG ((DEBUG_INFO, "Successfully Installed RootBridgeIo and DeviceP= ath protocols\n")); + InsertTailList (&HostBridge[Loop1]->Head, &PrivateData[Loop1]->Link); + Status =3D AddMemorySpace (PciMemBase[Loop1], PCI_MEM64_SIZE); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Memory Resource couldn't be added for PCI%d= _MEM64\n",Loop1)); + return EFI_DEVICE_ERROR; + } + + } + + return EFI_SUCCESS; +} + +/** + Functions declarations for Host Bridge Resource allocation protocol + + @param ImageHandle Handle of driver image + @param SystemTable Point to EFI_SYSTEM_TABLE + + @retval EFI_ABORTED PCI host bridge not present + @retval EFI_OUT_OF_RESOURCES Can not allocate memory resource + @retval EFI_DEVICE_ERROR Can not install the protocol instance + @retval EFI_SUCCESS Success to initialize the Pci host bridge. +**/ +EFI_STATUS +PciNotifyPhase ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase + ) +{ + PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance; + PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS BaseAddress; + UINT64 AddrLen; + UINTN BitsOfAlignment; + + BaseAddress =3D 0x0; + + HostBridgeInstance =3D INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This); + RootBridgeInstance =3D HostBridgeInstance->RootBridge; + + // Check RootBridge Signature + ASSERT (HostBridgeInstance->RootBridge->Signature =3D=3D PCI_ROOT_BRIDGE= _SIGNATURE); + + // The enumeration cannot be restarted after the process has been furthe= r than the first phase + if (Phase =3D=3D EfiPciHostBridgeBeginEnumeration) { + if (!HostBridgeInstance->CanRestarted) { + return EFI_NOT_READY; + } + } else { + HostBridgeInstance->CanRestarted =3D FALSE; + } + + switch (Phase) { + case EfiPciHostBridgeBeginEnumeration: + RootBridgeInstance =3D HostBridgeInstance->RootBridge; + break; + + case EfiPciHostBridgeBeginBusAllocation: + // The bus allocation phase is about to begin + break; + + case EfiPciHostBridgeEndBusAllocation: + // The bus allocation and bus programming phase is complete. All the P= CI-to-PCI bridges have been given and written back + // a bus number range into their configuration + break; + + case EfiPciHostBridgeBeginResourceAllocation: + // The resource allocation phase is about to begin. + break; + + case EfiPciHostBridgeAllocateResources: + // Allocates resources per previously submitted requests for all the P= CI root bridges. The resources have been submitted to + // PciHbRaSubmitResources() before. + + RootBridgeInstance =3D HostBridgeInstance->RootBridge; + if (RootBridgeInstance->ResAlloc[ResTypeIo].Length !=3D 0) { + BitsOfAlignment =3D HighBitSet64 (RootBridgeInstance->ResAlloc[ResTy= peIo].Alignment) + 1; // Get the number of '1' in Alignment + AddrLen =3D RootBridgeInstance->ResAlloc[ResTypeIo].Length; + + Status =3D gDS->AllocateIoSpace ( + EfiGcdAllocateAnySearchBottomUp, + EfiGcdIoTypeIo, + BitsOfAlignment, + AddrLen, + &BaseAddress, + HostBridgeInstance->ImageHandle, + NULL + ); + // If error then ResAlloc[n].Base =3D=3D0 + if (!EFI_ERROR (Status)) { + RootBridgeInstance->ResAlloc[ResTypeIo].Base =3D (UINTN)BaseAddr= ess; + } + } + + if (RootBridgeInstance->ResAlloc[ResTypeMem32].Length !=3D 0) { + BitsOfAlignment =3D HighBitSet64 (RootBridgeInstance->ResAlloc[ResTy= peMem32].Alignment) + 1; // Get the number of '1' in Alignment + AddrLen =3D RootBridgeInstance->ResAlloc[ResTypeMem32].Length; + + // Top of the 64bit PCI Memory space + BaseAddress =3D RootBridgeInstance->PciMemBase64 + PCI_MEM64_SIZE; + + Status =3D gDS->AllocateMemorySpace ( + EfiGcdAllocateMaxAddressSearchTopDown, + EfiGcdMemoryTypeMemoryMappedIo, + BitsOfAlignment, + AddrLen, + &BaseAddress, + HostBridgeInstance->ImageHandle, + NULL + ); + + // Ensure the allocation is in the 64bit PCI memory space + if (!EFI_ERROR (Status) && (BaseAddress >=3D RootBridgeInstance->Pci= MemBase64)) { + RootBridgeInstance->ResAlloc[ResTypeMem32].Base =3D (UINTN)(Base= Address - RootBridgeInstance->PciBaseAddress64); + } + } + + if (RootBridgeInstance->ResAlloc[ResTypePMem32].Length !=3D 0) { + BitsOfAlignment =3D HighBitSet64 (RootBridgeInstance->ResAlloc[ResTy= pePMem32].Alignment) + 1; // Get the number of '1' in Alignment + AddrLen =3D RootBridgeInstance->ResAlloc[ResTypePMem32].Length; + + // Top of the 64bit PCI Memory space + BaseAddress =3D RootBridgeInstance->PciMemBase64 + PCI_MEM64_SIZE; + + Status =3D gDS->AllocateMemorySpace ( + EfiGcdAllocateMaxAddressSearchTopDown, + EfiGcdMemoryTypeMemoryMappedIo, + BitsOfAlignment, + AddrLen, + &BaseAddress, + HostBridgeInstance->ImageHandle, + NULL + ); + + // Ensure the allocation is in the 64bit PCI memory space + if (!EFI_ERROR (Status) && (BaseAddress >=3D RootBridgeInstance->Pci= MemBase64)) { + RootBridgeInstance->ResAlloc[ResTypePMem32].Base =3D (UINTN)(BaseA= ddress - RootBridgeInstance->PciBaseAddress64); + } + } + + if (RootBridgeInstance->ResAlloc[ResTypeMem64].Length !=3D 0) { + BitsOfAlignment =3D HighBitSet64 (RootBridgeInstance->ResAlloc[ResTy= peMem64].Alignment) + 1; // Get the number of '1' in Alignment + AddrLen =3D RootBridgeInstance->ResAlloc[ResTypeMem64].Length; + // Top of the 64bit PCI Memory space + BaseAddress =3D RootBridgeInstance->PciMemBase64 + PCI_MEM64_SIZE; + + Status =3D gDS->AllocateMemorySpace ( + EfiGcdAllocateMaxAddressSearchTopDown, + EfiGcdMemoryTypeMemoryMappedIo, + BitsOfAlignment, + AddrLen, + &BaseAddress, + HostBridgeInstance->ImageHandle, + NULL + ); + + // Ensure the allocation is in the 64bit PCI memory space + if (!EFI_ERROR (Status) && (BaseAddress >=3D RootBridgeInstance->Pci= MemBase64)) { + RootBridgeInstance->ResAlloc[ResTypeMem64].Base =3D (UINTN)(Base= Address - RootBridgeInstance->PciBaseAddress64); + } + } + if (RootBridgeInstance->ResAlloc[ResTypePMem64].Length !=3D 0) { + BitsOfAlignment =3D HighBitSet64 (RootBridgeInstance->ResAlloc[ResTy= pePMem64].Alignment) + 1; //Get the number of '1' in Alignment + AddrLen =3D RootBridgeInstance->ResAlloc[ResTypePMem64].Length; + // Top of the 64bit PCI Memory space + BaseAddress =3D RootBridgeInstance->PciMemBase64 + PCI_MEM64_SIZE; + + Status =3D gDS->AllocateMemorySpace ( + EfiGcdAllocateMaxAddressSearchTopDown, + EfiGcdMemoryTypeMemoryMappedIo, + BitsOfAlignment, + AddrLen, + &BaseAddress, + HostBridgeInstance->ImageHandle, + NULL + ); + + // Ensure the allocation is in the 64bit PCI memory space + if (!EFI_ERROR (Status) && (BaseAddress >=3D RootBridgeInstance->Pci= MemBase64)) { + RootBridgeInstance->ResAlloc[ResTypePMem64].Base =3D (UINTN)(Bas= eAddress - RootBridgeInstance->PciBaseAddress64); + } + } + + break; + + case EfiPciHostBridgeSetResources: + // Programs the host bridge hardware to decode previously allocated re= sources (proposed resources) + // for all the PCI root bridges. The PCI bus driver will now program t= he resources + break; + + case EfiPciHostBridgeFreeResources: + // Deallocates resources that were previously allocated for all the PC= I root bridges and resets the + // I/O and memory apertures to their initial state.*/ + break; + + case EfiPciHostBridgeEndResourceAllocation: + break; + + case EfiPciHostBridgeEndEnumeration: + break; + + default: + DEBUG ((DEBUG_INFO, "PciHbRaNotifyPhase (Phase:%d)\n", Phase)); + ASSERT (0); + } + + return EFI_SUCCESS; + +} + +/** + This function returns the next root bridge attached to the + 'This' PCI Host Bridge. + There is only one PCI Root Bridge in this PCI interface, we + return either this root bridge if it the first time we call + this function (*RootBridgeHandle =3D=3D NULL) or return EFI_NOT_FOUND + **/ +EFI_STATUS +PciGetNextRootBridge ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN OUT EFI_HANDLE *RootBridgeHandle + ) +{ + PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance; + + HostBridgeInstance =3D INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This); + ASSERT (HostBridgeInstance->RootBridge !=3D NULL); + + //Check RootBridge Signature + ASSERT (HostBridgeInstance->RootBridge->Signature =3D=3D PCI_ROOT_BRIDGE= _SIGNATURE); + + if (*RootBridgeHandle =3D=3D NULL) { + *RootBridgeHandle =3D HostBridgeInstance->RootBridge->Handle; + return EFI_SUCCESS; + } else if (*RootBridgeHandle =3D=3D HostBridgeInstance->RootBridge->Hand= le) { + return EFI_NOT_FOUND; + } else { + return EFI_INVALID_PARAMETER; + } +} + +/** + This function returns the resource allocation attributes supported + by this PCI Root Bridge. + A PCI Root bridge could support these types : + - EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM : does not support separate + windows for nonprefetchable and prefetchable memory. + - EFI_PCI_HOST_BRIDGE_MEM64_DECODE : supports 64-bit memory windows + + @param This Pointer to host bridge resource allocation protocol + + @return Attributes Attribues supported by the PCI root bridge + **/ +EFI_STATUS +PciGetAllocAttributes ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + OUT UINT64 *Attributes + ) +{ + PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance; + + HostBridgeInstance =3D INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This); + + // Check if the RootBridgeHandle is the one managed by this PCI Host Bri= dge + ASSERT (HostBridgeInstance->RootBridge !=3D NULL); + if (HostBridgeInstance->RootBridge->Handle !=3D RootBridgeHandle) { + return EFI_INVALID_PARAMETER; + } + + *Attributes =3D HostBridgeInstance->RootBridge->RootBridgeAttrib; + return EFI_SUCCESS; +} + +/** + + This function sets up the specified PCI root bridge for the + bus enumeration process + + @param This pointer to host bridge resource allocation protocol +**/ +EFI_STATUS +PciStartBusEnumeration ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + OUT VOID **Configuration + ) +{ + VOID *Buffer; + UINT8 *Ptr; + PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance; + + HostBridgeInstance =3D INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This); + + Buffer =3D AllocateZeroPool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) = + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); + if (Buffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Ptr =3D (UINT8 *)Buffer; + + // Fill an ACPI descriptor table with the Bus Number Range. This informa= tion will be used by the PCI Bus driver + // to set bus numbers to PCI-to-PCI bridge. + + ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->Desc =3D ACPI_ADDRESS_SPACE_= DESCRIPTOR; // QWORD Address space Descriptor + ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->Len =3D 0x2B; // Length = of this descriptor in bytes not including the first two fields + ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType =3D ACPI_ADDRESS_SPA= CE_TYPE_BUS; // Resource Type Bus Number Range + ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->GenFlag =3D 0; + ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->SpecificFlag =3D 0; + ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrSpaceGranularity =3D 0; + ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMin =3D HostBridgeI= nstance->RootBridge->BusStart; // Bus Start + ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMax =3D 0; // Bu= s Max + ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrTranslationOffset =3D 0; + ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen =3D FixedPcdGet32 (P= cdPciBusMax) - FixedPcdGet32 (PcdPciBusMin) + 1; + + Ptr =3D Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR); + ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Desc =3D ACPI_END_TAG_DESCRIPTOR; + ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Checksum =3D 0x0; + + *Configuration =3D Buffer; + return EFI_SUCCESS; +} + +/** + This function set PCI bus number(start,end for this root bridge instance + -Checks if ACPI descriptor is passed for supported bus range +**/ +EFI_STATUS +PciSetBusNumbers ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + IN VOID *Configuration + ) +{ + PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance; + UINT8 *Ptr; + UINTN BusStart; + UINTN BusEnd; + UINTN BusLen; + + Ptr =3D Configuration; + if (*Ptr !=3D ACPI_ADDRESS_SPACE_DESCRIPTOR) { + return EFI_INVALID_PARAMETER; + } + + // Check if the passed ACPI descriptor table define a Bus Number Range + if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType !=3D ACPI_ADDRES= S_SPACE_TYPE_BUS) { + return EFI_INVALID_PARAMETER; + } + + // Check if the Configuration only passed one ACPI Descriptor (+ End Des= criptor) + if (*((UINT8*)(Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR))) !=3D A= CPI_END_TAG_DESCRIPTOR) { + return EFI_INVALID_PARAMETER; + } + + HostBridgeInstance =3D INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This); + ASSERT (HostBridgeInstance->RootBridge !=3D NULL); + if (HostBridgeInstance->RootBridge->Handle !=3D RootBridgeHandle) { + return EFI_INVALID_PARAMETER; + } + + BusStart =3D (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRang= eMin; + BusLen =3D (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen; + BusEnd =3D BusStart + BusLen - 1; + + ASSERT (BusStart <=3D BusEnd); // We should at least have PCI_BUS_ROOT a= nd PCI_SWITCH_BUS + ASSERT ((BusStart >=3D HostBridgeInstance->RootBridge->BusStart) && (Bus= Len <=3D HostBridgeInstance->RootBridge->BusLength)); + + HostBridgeInstance->RootBridge->BusStart =3D BusStart; + HostBridgeInstance->RootBridge->BusLength =3D BusLen; + + return EFI_SUCCESS; +} + +/** + This function is used to submit all the I/O and memory resources + that are required by the specified PCI root bridge. + **/ +EFI_STATUS +PciSubmitResources ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + IN VOID *Configuration + ) +{ + PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance; + PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance; + UINT8 *Ptr; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; + PCI_RESOURCE_TYPE ResType; + + HostBridgeInstance =3D INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This); + + if (Configuration =3D=3D NULL) { + DEBUG((DEBUG_ERROR, "PciHbRaSubmitResources(): NULL COnf\n")); + return EFI_INVALID_PARAMETER; + } + + // Check if the ACPI Descriptor tables is conformed + Ptr =3D (UINT8 *)Configuration; + while (*Ptr =3D=3D ACPI_ADDRESS_SPACE_DESCRIPTOR) { // QWORD Address Spa= ce descriptor + Ptr +=3D sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ; + } + if (*Ptr !=3D ACPI_END_TAG_DESCRIPTOR) { // End tag + DEBUG ((DEBUG_ERROR, "PciHbRaSubmitResources(): END tag issue\n")); + return EFI_INVALID_PARAMETER; + } + + // Check the RootBridgeHandle + RootBridgeInstance =3D HostBridgeInstance->RootBridge; + ASSERT (RootBridgeInstance !=3D NULL); + if (RootBridgeHandle !=3D HostBridgeInstance->RootBridge->Handle) { + DEBUG ((DEBUG_ERROR, "PciHbRaSubmitResources(): HB/RB dont match\n")); + return EFI_INVALID_PARAMETER; + } + + Ptr =3D (UINT8 *)Configuration; + while ( *Ptr =3D=3D ACPI_ADDRESS_SPACE_DESCRIPTOR) { // While the entry = is an ACPI Descriptor Table + Desc =3D (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr; + + // Check if the description is valid + if (Desc->AddrLen > 0xffffffff) { + DEBUG ((DEBUG_ERROR, "PciHbRaSubmitResources(): Invalid addr length\= n")); + return EFI_INVALID_PARAMETER; + } + + if ((Desc->AddrRangeMax >=3D 0xffffffff) || (Desc->AddrRangeMax !=3D (= GetPowerOfTwo64 (Desc->AddrRangeMax + 1) - 1))) { + DEBUG ((DEBUG_ERROR, "PciHbRaSubmitResources(): Invalid addr range\n= ")); + return EFI_INVALID_PARAMETER; + } + + switch (Desc->ResType) { + case ACPI_ADDRESS_SPACE_TYPE_MEM: + // Check invalid Address Space Granularity + if ((Desc->AddrSpaceGranularity !=3D 32) && (Desc->AddrSpaceGranular= ity !=3D 64)) { + DEBUG ((DEBUG_ERROR, "PciHbRaSubmitResources(): Invalid addr space= granul\n")); + return EFI_INVALID_PARAMETER; + } + + // check the memory resource request is supported by PCI root bridge + if (RootBridgeInstance->MemAllocAttributes =3D=3D EFI_PCI_HOST_BRIDG= E_COMBINE_MEM_PMEM && Desc->SpecificFlag =3D=3D 0x06) { + DEBUG ((DEBUG_ERROR, "PciHbRaSubmitResources(): Invalid memalloc a= ttri \n")); + return EFI_INVALID_PARAMETER; + } + + if (Desc->AddrSpaceGranularity =3D=3D 32) { + if (Desc->SpecificFlag =3D=3D ACPI_SPECFLAG_PREFETCHABLE) { + ResType =3D ResTypePMem32; + } else { + ResType =3D ResTypeMem32; + } + } else { + if (Desc->SpecificFlag =3D=3D ACPI_SPECFLAG_PREFETCHABLE) { + ResType =3D ResTypePMem64; + } else { + ResType =3D ResTypeMem64; + } + } + RootBridgeInstance->ResAlloc[ResType].Length =3D Desc->AddrLen; + RootBridgeInstance->ResAlloc[ResType].Alignment =3D Desc->AddrRangeM= ax; + RootBridgeInstance->ResAlloc[ResType].Base =3D Desc->AddrRangeMin; + break; + case ACPI_ADDRESS_SPACE_TYPE_IO: + RootBridgeInstance->ResAlloc[ResTypeIo].Length =3D Desc->AddrLen; + RootBridgeInstance->ResAlloc[ResTypeIo].Alignment =3D Desc->AddrRang= eMax; + RootBridgeInstance->ResAlloc[ResTypeIo].Base =3D 0; + break; + default: + ASSERT (0); // Could be the case Desc->ResType =3D=3D ACPI_ADDRESS_S= PACE_TYPE_BUS + break; + } + Ptr +=3D sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR); + } + + return EFI_SUCCESS; +} + +/** + This function Returns the proposed resource settings for the specified + PCI root bridge. The resources have been submitted by + PciHbRaSubmitResources() + + @param This Pointer to host bridge resource allocati= on + instance + @param RootBridgeHandle Pointer to this root bridge instance + + @return Configuration Pointer to resource settings + @return EFI_SUCCESS Successful returned requested resource + settings + @return EFI_INVALID_PARAMETER Invalid parameter for root bridge + @return EFI_OUT_OF_RESOURCES Resources can not be allocated + **/ +EFI_STATUS +PciGetProposedResources ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + OUT VOID **Configuration + ) +{ + PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance; + PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance; + UINT32 i; + UINT32 ResAllocCount; + VOID *Buffer; + UINT8 *Ptr; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; + + HostBridgeInstance =3D INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This); + + // Check the RootBridgeHandle + RootBridgeInstance =3D HostBridgeInstance->RootBridge; + ASSERT (RootBridgeInstance !=3D NULL); + if (RootBridgeHandle !=3D HostBridgeInstance->RootBridge->Handle) { + return EFI_INVALID_PARAMETER; + } + + // Count the number of Resource Allocated for this Root Bridge + ResAllocCount =3D 0; + for (i =3D 0; i < ResTypeMax; i++) { + if (RootBridgeInstance->ResAlloc[i].Length !=3D 0) ResAllocCount++; + } + + if (ResAllocCount =3D=3D 0) { + return EFI_INVALID_PARAMETER; + } + + Buffer =3D AllocateZeroPool (ResAllocCount * sizeof (EFI_ACPI_ADDRESS_SP= ACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); + if (Buffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Ptr =3D Buffer; + for (i =3D 0; i < ResTypeMax; i++) { + // Base !=3D 0 if the resource has been allocated + if (RootBridgeInstance->ResAlloc[i].Length !=3D 0) { + Desc =3D (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr; + + Desc->Desc =3D ACPI_ADDRESS_SPACE_DESCRIPTOR; + Desc->Len =3D 0x2B; + Desc->GenFlag =3D 0; + Desc->AddrRangeMax =3D 0; + + switch (i) { + case ResTypeIo: + Desc->Desc =3D 0x8A; + Desc->Len =3D 0x2B; + Desc->ResType =3D 1; + Desc->GenFlag =3D 0; + Desc->SpecificFlag =3D 0; + Desc->AddrSpaceGranularity =3D 0; + Desc->AddrRangeMin =3D RootBridgeInstance->ResAlloc[i].Base; + Desc->AddrLen =3D RootBridgeInstance->ResAlloc[i].Length; + break; + case ResTypeMem32: + Desc->ResType =3D ACPI_ADDRESS_SPACE_TYPE_MEM; + Desc->Desc =3D 0x8A; + Desc->Len =3D 0x2B; + Desc->ResType =3D 0; + Desc->GenFlag =3D 0; + Desc->SpecificFlag =3D 0; + Desc->AddrSpaceGranularity =3D 32; + Desc->AddrRangeMin =3D RootBridgeInstance->ResAlloc[i].Base; + Desc->AddrLen =3D RootBridgeInstance->ResAlloc[i].Length; + break; + case ResTypePMem32: + Desc->Desc =3D 0x8A; + Desc->Len =3D 0x2B; + Desc->ResType =3D ACPI_ADDRESS_SPACE_TYPE_MEM; + Desc->GenFlag =3D 0; + Desc->SpecificFlag =3D 6; + Desc->AddrSpaceGranularity =3D 32; + Desc->AddrRangeMin =3D 0; + Desc->AddrTranslationOffset =3D EFI_RESOURCE_NONEXISTENT; + Desc->AddrLen =3D 0; + break; + case ResTypeMem64: + Desc->Desc =3D 0x8A; + Desc->Len =3D 0x2B; + Desc->ResType =3D ACPI_ADDRESS_SPACE_TYPE_MEM; + Desc->GenFlag =3D 0; + Desc->SpecificFlag =3D 0; + Desc->AddrSpaceGranularity =3D 64; + Desc->AddrRangeMin =3D RootBridgeInstance->ResAlloc[i].Base; + Desc->AddrLen =3D RootBridgeInstance->ResAlloc[i].Length; + break; + case ResTypePMem64: + Desc->Desc =3D 0x8A; + Desc->Len =3D 0x2B; + Desc->ResType =3D ACPI_ADDRESS_SPACE_TYPE_MEM; + Desc->GenFlag =3D 0; + Desc->SpecificFlag =3D 6; + Desc->AddrSpaceGranularity =3D 64; + Desc->AddrRangeMin =3D 0; + Desc->AddrTranslationOffset =3D EFI_RESOURCE_NONEXISTENT; + Desc->AddrLen =3D 0; + break; + } + Desc->AddrRangeMin =3D RootBridgeInstance->ResAlloc[i].Base; + Desc->AddrTranslationOffset =3D EFI_RESOURCE_SATISFIED; + Desc->AddrLen =3D RootBridgeInstance->ResAlloc[i].Length; + Ptr +=3D sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR); + } + } + + ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Desc =3D ACPI_END_TAG_DESCRIPTOR; + ((EFI_ACPI_END_TAG_DESCRIPTOR *)Ptr)->Checksum =3D 0x0; + + *Configuration =3D Buffer; + return EFI_SUCCESS; +} + +/** + This function allow the host bridge driver to preinitialize individual + PCI controllers before enumeration +**/ +EFI_STATUS +PciPreprocessController ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress, + IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase + ) +{ + PCI_HOST_BRIDGE_INSTANCE* HostBridge; + PCI_ROOT_BRIDGE_INSTANCE* RootBridge; + UINT32 CapabilityPtr; + UINT32 CapabilityEntry; + UINT16 CapabilityID; + UINT32 DeviceCapability; + + if (FeaturePcdGet (PcdPciMaxPayloadFixup)) { + // Do Max payload fixup for every devices + if (Phase =3D=3D EfiPciBeforeResourceCollection) { + // Get RootBridge Instance from Host Bridge Instance + HostBridge =3D INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This); + RootBridge =3D HostBridge->RootBridge; + + // Get the first PCI Capability + CapabilityPtr =3D PCI_CAPBILITY_POINTER_OFFSET; + RootBridge->Io.Pci.Read ( + &RootBridge->Io, + EfiPciWidthUint8, + EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, PciAddress.F= unction, CapabilityPtr), + 1, + &CapabilityPtr + ); + CapabilityPtr &=3D 0x1FF; + + // Get Pci Express Capability + while (CapabilityPtr !=3D 0) { + RootBridge->Io.Pci.Read ( + &RootBridge->Io, + EfiPciWidthUint16, + EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, PciAddress= .Function, CapabilityPtr), + 1, + &CapabilityEntry + ); + + CapabilityID =3D (UINT8)CapabilityEntry; + + // Is PCIe capability ? + if (CapabilityID =3D=3D EFI_PCI_CAPABILITY_ID_PCIEXP) { + // Get PCIe Device Capabilities + RootBridge->Io.Pci.Read ( + &RootBridge->Io, + EfiPciWidthUint32, + EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, PciAddre= ss.Function, CapabilityPtr + 0x8), + 1, + &DeviceCapability + ); + + // Force the Max Payload to 128 Bytes (128 Bytes Max Payload Siz= e =3D 0) + DeviceCapability &=3D ~ ((UINT32)(0x7 << 5 )); + // Max Read Request Size to 128 Bytes (128 Bytes Max Read Reques= t Size =3D 0) + DeviceCapability &=3D ~ ((UINT32)(0x7 << 12)); + // Enable all error reporting + DeviceCapability |=3D 0xF; + + RootBridge->Io.Pci.Write ( + &RootBridge->Io, + EfiPciWidthUint32, + EFI_PCI_ADDRESS (PciAddress.Bus, PciAddress.Device, PciAddre= ss.Function, CapabilityPtr + 0x8), + 1, + &DeviceCapability + ); + + return EFI_SUCCESS; + } + CapabilityPtr =3D (CapabilityEntry >> 8) & 0xFF; + } + } + } + + return EFI_SUCCESS; +} diff --git a/Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf b/P= latform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf new file mode 100644 index 0000000..019cc63 --- /dev/null +++ b/Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf @@ -0,0 +1,61 @@ +/* PciHostBridgeDxe.inf +# +# Component description file for PCI Host Bridge driver +# +# Copyright (c) 2015, Freescale Semiconductor, Inc. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may b= e 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 IM= PLIED. +# +# +*/ + +[Defines] + INF_VERSION =3D 0x0001001A + BASE_NAME =3D PciHostBridge + FILE_GUID =3D C62F4B20-681E-11DF-8F0D-0002A5D5C51B + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D PciHostBridgeEntryPoint + +[Packages] + MdePkg/MdePkg.dec + Platform/NXP/NxpQoriqLs.dec + Silicon/NXP/Chassis/Chassis2/Chassis2.dec + +[LibraryClasses] + DxeServicesTableLib + PciHostBridgeLib + SocLib + UefiDriverEntryPoint + +[Sources] + PciHostBridgeDxe.c + PciRootBridgeIo.c + +[FixedPcd] + gNxpQoriqLsTokenSpaceGuid.PcdPciBusMin + gNxpQoriqLsTokenSpaceGuid.PcdPciBusMax + gNxpQoriqLsTokenSpaceGuid.PcdPci1Mmio64Base + gNxpQoriqLsTokenSpaceGuid.PcdPciMmio64Size + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseAddr + gNxpQoriqLsTokenSpaceGuid.PcdKludgeMapPciMmioAsCached + gNxpQoriqLsTokenSpaceGuid.PcdPciMaxPayloadFixup + gNxpQoriqLsTokenSpaceGuid.PcdPciDebug + gNxpQoriqLsTokenSpaceGuid.PcdNumPciController + gNxpQoriqLsTokenSpaceGuid.PcdPciMemOneTransaction + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1BaseSize + +[Protocols] + gEfiPciHostBridgeResourceAllocationProtocolGuid ## PRODUCES + gEfiPciRootBridgeIoProtocolGuid ## PRODUCES + gEfiMetronomeArchProtocolGuid ## CONSUMES + gEfiDevicePathProtocolGuid ## PRODUCES + +[Depex] + TRUE diff --git a/Platform/NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c b/Plat= form/NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c new file mode 100644 index 0000000..9a5c238 --- /dev/null +++ b/Platform/NXP/Drivers/PciHostBridgeDxe/PciRootBridgeIo.c @@ -0,0 +1,1193 @@ +/** PciRootBridgeIo.c + PCI Root Bridge Io Protocol implementation + + Based on PCI RootBridge implementation in + ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciRootBridge.c + + Copyright (c) 2011-2015, ARM Ltd. All rights reserved. + Copyright 2017 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 + 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 IMPL= IED. + +**/ + +#include + +typedef struct { + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR SpaceDesp[ResTypeMax+1]; + EFI_ACPI_END_TAG_DESCRIPTOR EndDesp; +} RESOURCE_CONFIGURATION; + +RESOURCE_CONFIGURATION Configuration =3D { + {{ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_IO , 0, = 0, 0, 0, 0, 0, 0}, + {ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_MEM, 0, = 0, 32, 0, 0, 0, 0}, + {ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_MEM, 0, = 6, 32, 0, 0, 0, 0}, + {ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_MEM, 0, = 0, 64, 0, 0, 0, 0}, + {ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_MEM, 0, = 6, 64, 0, 0, 0, 0}, + {ACPI_ADDRESS_SPACE_DESCRIPTOR, 0x2B, ACPI_ADDRESS_SPACE_TYPE_BUS, 0, = 0, 0, 0, 255, 0, 255}}, + {ACPI_END_TAG_DESCRIPTOR, 0} +}; + +// +// Memory Controller Pci Root Bridge Io Module Variables +// +EFI_METRONOME_ARCH_PROTOCOL *mMetronome; + +/** + + Initialize and create Pci Root Bridges for Board + + @param PrvateData Driver instance of this Root Bridge IO protocol + @param Protocol Point to protocol instance + @param Info Point to Info field of this driver instance + @param HostBridgeHandle Handle of host bridge + @param Attri Attribute of host bridge + @param HostNo HostNo for this Host Bridge + @param Busno Bus Number for the Host Bridge + + @retval EFI_SUCCESS Success to initialize the Pci Root Bridge. + +**/ +EFI_STATUS +PciRbInitialize ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Protocol, + IN LsPcieInfo *Info, + IN EFI_HANDLE HostBridgeHandle, + IN UINT64 Attri, + IN INTN HostNo, + IN INTN Busno, + IN UINT64 *PciBaseAddr + ) +{ + EFI_STATUS Status; + LsPcie *Pcie; + PciDevT Pdev; + INTN LinkUp, EpMode; + UINT8 HeaderType; + UINT16 Temp16; + UINT16 VendorID16; + UINT16 DeviceID16; + UINT16 Cntr; + + Pdev =3D ((Busno) << 16 | (0) << 11 | (0) << 8); + Pcie =3D PrivateData->Pcie; + + PrivateData->FirstBusno =3D Busno; + PrivateData->Pcie->Dbi =3D (VOID *)Info->Regs; + PrivateData->Pcie->VaCfg0 =3D (VOID *)Info->Cfg0Phys; + PrivateData->Pcie->VaCfg1 =3D (VOID *)Info->Cfg1Phys; + + LinkUp =3D PcieLinkUp(Pcie); + + if (!LinkUp) { + // Let the user know there's no PCIe link + DEBUG ((DEBUG_INFO,"no link, regs @ 0x%lx\n", Info->Regs)); + PrivateData->LastBusno =3D PrivateData->FirstBusno; + return EFI_ABORTED; + } + DEBUG ((DEBUG_INFO, "Passed Linkup Phase\n")); + + // outbound memory + PciSetRegion (&PrivateData->Regions[0], + (PciSizeT)Info->MemBus, + (PhysSizeT)Info->MemPhys, + (PciSizeT)Info->MemSize, + LS_PCI_REGION_MEM); + + // outbound io + PciSetRegion (&PrivateData->Regions[1], + (PciSizeT)Info->IoBus, + (PhysSizeT)Info->IoPhys, + (PciSizeT)Info->IoSize, + LS_PCI_REGION_IO); + + // System memory space + PciSetRegion (&PrivateData->Regions[2], + LS_PCI_MEMORY_BUS, + LS_PCI_MEMORY_PHYS, + LS_PCI_MEMORY_SIZE, + LS_PCI_REGION_SYS_MEMORY); + + PrivateData->RegionCnt =3D 3; + + if (FeaturePcdGet (PcdPciDebug) =3D=3D TRUE) { + for (Cntr =3D 0; Cntr < PrivateData->RegionCnt; Cntr++) { + DEBUG ((DEBUG_INFO, "PCI reg:%d %016llx:%016llx %016llx %08lx\n", + Cntr, + (UINT64)PrivateData->Regions[Cntr].PhysStart, + (UINT64)PrivateData->Regions[Cntr].BusStart, + (UINT64)PrivateData->Regions[Cntr].Size, + PrivateData->Regions[Cntr].Flags)); + } + } + + PcieReadConfigWord (PrivateData, Pdev, LS_PCI_VENDOR_ID, (UINT16 *)&Vend= orID16); + DEBUG ((DEBUG_INFO,"PCIe:VendorID: %04lx\n", VendorID16)); + PcieReadConfigWord (PrivateData, Pdev, LS_PCI_DEVICE_ID, (UINT16 *)&Devi= ceID16); + DEBUG ((DEBUG_INFO,"PCIe Device ID: %04lx\n", DeviceID16)); + PcieReadConfigByte (PrivateData, Pdev, LS_PCI_HEADER_TYPE, (UINT8 *)&Hea= derType); + DEBUG ((DEBUG_INFO,"PCIe Header Type: %02lx\n", HeaderType)); + EpMode =3D (HeaderType & 0x7f) =3D=3D LS_PCI_HEADER_TYPE_NORMAL; + DEBUG ((DEBUG_INFO,"EpMode: %d\n", EpMode)); + DEBUG ((DEBUG_INFO,"PCIe%d: %a\n", (UINT64)Info->PciNum, EpMode ? "Endpo= int" : "Root Complex")); + + // Print the negotiated PCIe link width + PcieReadConfigWord (PrivateData, Pdev, LS_PCIE_LINK_STA, (UINT16 *)&Temp= 16); + DEBUG ((DEBUG_INFO,"PCIe Link Status: %04lx\n", Temp16)); + DEBUG ((DEBUG_INFO,"x%d gen%d, regs @ 0x%lx\n", (Temp16 & 0x3f0) >> 4, + (Temp16 & 0xf), Info->Regs)); + + if (EpMode) { + DEBUG ((DEBUG_INFO, "EpMode: %d\n", Busno)); + return Busno; + } + + PrivateData->PciBaseAddress64 =3D PciBaseAddr[HostNo - 1]; + if (!PrivateData->PciBaseAddress64) { + DEBUG ((DEBUG_ERROR, "%a: PCI %d host bridge not present\n", __FUNCTIO= N__, HostNo)); + return EFI_ABORTED; + } + + PcieSetupCntrl (PrivateData, PrivateData->Pcie, PrivateData->Info); + + PrivateData->BusStart =3D FixedPcdGet32 (PcdPciBusMin); + PrivateData->BusLength =3D FixedPcdGet32 (PcdPciBusMax) - FixedPcdGet32 = (PcdPciBusMin) + 1; + + PrivateData->RootBridgeAttrib =3D Attri; + + PrivateData->Supports =3D EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_= ATTRIBUTE_IDE_SECONDARY_IO | \ + EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBU= TE_ISA_MOTHERBOARD_IO | \ + EFI_PCI_ATTRIBUTE_VGA_MEMORY | \ + EFI_PCI_ATTRIBUTE_VGA_IO_16 | EFI_PCI_ATTRIB= UTE_VGA_PALETTE_IO_16; + PrivateData->Attributes =3D PrivateData->Supports; + + Protocol->ParentHandle =3D HostBridgeHandle; + + Protocol->PollMem =3D RootBridgeIoPollMem; + Protocol->PollIo =3D RootBridgeIoPollIo; + + Protocol->Mem.Read =3D RootBridgeIoMemRead; + Protocol->Mem.Write =3D RootBridgeIoMemWrite; + + Protocol->Io.Read =3D RootBridgeIoIoRead; + Protocol->Io.Write =3D RootBridgeIoIoWrite; + + Protocol->CopyMem =3D RootBridgeIoCopyMem; + + Protocol->Pci.Read =3D RootBridgeIoPciRead; + Protocol->Pci.Write =3D RootBridgeIoPciWrite; + + Protocol->Map =3D RootBridgeIoMap; + Protocol->Unmap =3D RootBridgeIoUnmap; + + Protocol->AllocateBuffer =3D RootBridgeIoAllocateBuffer; + Protocol->FreeBuffer =3D RootBridgeIoFreeBuffer; + + Protocol->Flush =3D RootBridgeIoFlush; + + Protocol->GetAttributes =3D RootBridgeIoGetAttributes; + Protocol->SetAttributes =3D RootBridgeIoSetAttributes; + + Protocol->Configuration =3D RootBridgeIoConfiguration; + + Protocol->SegmentNumber =3D HostNo; + + Status =3D gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (V= OID **)&mMetronome); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + +/** + Polls an address in memory mapped I/O space until an exit condition is = met, or + a timeout occurs. + + This function provides a standard way to poll a PCI memory location. A = PCI memory read + operation is performed at the PCI memory address specified by Address f= or the width specified + by Width. The result of this PCI memory read operation is stored in Res= ult. This PCI memory + read operation is repeated until either a timeout of Delay 100 ns units= has expired, or (Result & + Mask) is equal to Value. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Width Signifies the width of the memory operations. + @param[in] Address The base address of the memory operations. The c= aller is + responsible for aligning Address if required. + @param[in] Mask Mask used for the polling criteria. Bytes above = Width in Mask + are ignored. The bits in the bytes below Width w= hich are zero in + Mask are ignored when polling the memory address. + @param[in] Value The comparison value used for the polling exit c= riteria. + @param[in] Delay The number of 100 ns units to poll. Note that ti= mer available may + be of poorer granularity. + @param[out] Result Pointer to the last value read from the memory l= ocation. + + @retval EFI_SUCCESS The last data returned from the access m= atched the poll exit criteria. + @retval EFI_INVALID_PARAMETER Width is invalid. + @retval EFI_INVALID_PARAMETER Result is NULL. + @retval EFI_TIMEOUT Delay expired before a match occurred. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoPollMem ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result + ) +{ + EFI_STATUS Status; + UINT64 NumberOfTicks; + UINT32 Remainder; + + if (Result =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Width > EfiPciWidthUint64) { + return EFI_INVALID_PARAMETER; + } + + // No matter what, always do a single poll. + Status =3D This->Mem.Read (This, Width, Address, 1, Result); + if (EFI_ERROR (Status)) { + return Status; + } + if ((*Result & Mask) =3D=3D Value) { + return EFI_SUCCESS; + } + + if (Delay =3D=3D 0) { + return EFI_SUCCESS; + } + + NumberOfTicks =3D DivU64x32Remainder (Delay, (UINT32) mMetronome->TickPe= riod, &Remainder); + if (Remainder !=3D 0) { + NumberOfTicks +=3D 1; + } + NumberOfTicks +=3D 1; + + while (NumberOfTicks) { + mMetronome->WaitForTick (mMetronome, 1); + + Status =3D This->Mem.Read (This, Width, Address, 1, Result); + if (EFI_ERROR (Status)) { + return Status; + } + + if ((*Result & Mask) =3D=3D Value) { + return EFI_SUCCESS; + } + + NumberOfTicks -=3D 1; + } + + return EFI_TIMEOUT; +} + +/** + Reads from the I/O space of a PCI Root Bridge. Returns when either the = polling exit criteria is + satisfied or after a defined duration. + + This function provides a standard way to poll a PCI I/O location. A PCI= I/O read operation is + performed at the PCI I/O address specified by Address for the width spe= cified by Width. + The result of this PCI I/O read operation is stored in Result. This PCI= I/O read operation is + repeated until either a timeout of Delay 100 ns units has expired, or (= Result & Mask) is equal + to Value. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Width Signifies the width of the I/O operations. + @param[in] Address The base address of the I/O operations. The caller= is responsible + for aligning Address if required. + @param[in] Mask Mask used for the polling criteria. Bytes above Wi= dth in Mask + are ignored. The bits in the bytes below Width whi= ch are zero in + Mask are ignored when polling the I/O address. + @param[in] Value The comparison value used for the polling exit cri= teria. + @param[in] Delay The number of 100 ns units to poll. Note that time= r available may + be of poorer granularity. + @param[out] Result Pointer to the last value read from the memory loc= ation. + + @retval EFI_SUCCESS The last data returned from the access m= atched the poll exit criteria. + @retval EFI_INVALID_PARAMETER Width is invalid. + @retval EFI_INVALID_PARAMETER Result is NULL. + @retval EFI_TIMEOUT Delay expired before a match occurred. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoPollIo ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result + ) +{ + EFI_STATUS Status; + UINT64 NumberOfTicks; + UINT32 Remainder; + + if (Result =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Width > EfiPciWidthUint64) { + return EFI_INVALID_PARAMETER; + } + + // No matter what, always do a single poll. + Status =3D This->Io.Read (This, Width, Address, 1, Result); + if (EFI_ERROR (Status)) { + return Status; + } + if ((*Result & Mask) =3D=3D Value) { + return EFI_SUCCESS; + } + + if (Delay =3D=3D 0) { + return EFI_SUCCESS; + } + + NumberOfTicks =3D DivU64x32Remainder (Delay, (UINT32) mMetronome->TickPe= riod, &Remainder); + if (Remainder !=3D 0) { + NumberOfTicks +=3D 1; + } + NumberOfTicks +=3D 1; + + while (NumberOfTicks) { + mMetronome->WaitForTick (mMetronome, 1); + + Status =3D This->Io.Read (This, Width, Address, 1, Result); + if (EFI_ERROR (Status)) { + return Status; + } + + if ((*Result & Mask) =3D=3D Value) { + return EFI_SUCCESS; + } + + NumberOfTicks -=3D 1; + } + + return EFI_TIMEOUT; +} + +/** + Enables a PCI driver to access PCI controller registers in the PCI root= bridge memory space. + + The Mem.Read(), and Mem.Write() functions enable a driver to access PCI= controller + registers in the PCI root bridge memory space. + The memory operations are carried out exactly as requested. The caller = is responsible for satisfying + any alignment and memory width restrictions that a PCI Root Bridge on a= platform might require. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Width Signifies the width of the memory operation. + @param[in] Address The base address of the memory operation. The ca= ller is + responsible for aligning the Address if required. + @param[in] Count The number of memory operations to perform. Byte= s moved is + Width size * Count, starting at Address. + @param[out] Buffer For read operations, the destination buffer to s= tore the results. For + write operations, the source buffer to write dat= a from. + + @retval EFI_SUCCESS The data was read from or written to the= PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridg= e. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoMemRead ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + OUT VOID *Buffer + ) +{ + return RootBridgeIoMemRW (This, FALSE, Width, Address, Count, Buffer); +} + +/** + Enables a PCI driver to access PCI controller registers in the PCI root= bridge memory space. + + The Mem.Read(), and Mem.Write() functions enable a driver to access PCI= controller + registers in the PCI root bridge memory space. + The memory operations are carried out exactly as requested. The caller = is responsible for satisfying + any alignment and memory width restrictions that a PCI Root Bridge on a= platform might require. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Width Signifies the width of the memory operation. + @param[in] Address The base address of the memory operation. The ca= ller is + responsible for aligning the Address if required. + @param[in] Count The number of memory operations to perform. Byte= s moved is + Width size * Count, starting at Address. + @param[in] Buffer For read operations, the destination buffer to s= tore the results. For + write operations, the source buffer to write dat= a from. + + @retval EFI_SUCCESS The data was read from or written to the= PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridg= e. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. +**/ +EFI_STATUS +EFIAPI +RootBridgeIoMemWrite ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer + ) +{ + return RootBridgeIoMemRW (This, TRUE, Width, Address, Count, Buffer); +} + +/** + Enables a PCI driver to access PCI controller registers in the PCI root= bridge I/O space. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOC= OL. + @param[in] Width Signifies the width of the memory operations. + @param[in] Address The base address of the I/O operation. The cal= ler is responsible for + aligning the Address if required. + @param[in] Count The number of I/O operations to perform. 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 to write d= ata from. + + @retval EFI_SUCCESS The data was read from or written to t= he PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bri= dge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due= to a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoIoRead ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + OUT VOID *Buffer + ) +{ + if (Buffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Width >=3D EfiPciWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + return RootBridgeIoIoRW (This, FALSE, Width, Address, Count, Buffer); +} + +/** + Enables a PCI driver to access PCI controller registers in the PCI root= bridge I/O space. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOC= OL. + @param[in] Width Signifies the width of the memory operations. + @param[in] Address The base address of the I/O operation. The cal= ler is responsible for + aligning the Address if required. + @param[in] Count The number of I/O operations to perform. Bytes= moved is Width + size * Count, starting at Address. + @param[in] Buffer For read operations, the destination buffer t= o store the results. For + write operations, the source buffer to write d= ata from. + + @retval EFI_SUCCESS The data was read from or written to t= he PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bri= dge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due= to a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoIoWrite ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer + ) +{ + if (Buffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Width >=3D EfiPciWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + return RootBridgeIoIoRW (This, TRUE, Width, Address, Count, Buffer); +} + +/** + Enables a PCI driver to copy one region of PCI root bridge memory space= to another region of PCI + root bridge memory space. + + The CopyMem() function enables a PCI driver to copy one region of PCI r= oot bridge memory + space to another region of PCI root bridge memory space. This is especi= ally useful for video scroll + operation on a memory mapped video buffer. + The memory operations are carried out exactly as requested. The caller = is responsible for satisfying + any alignment and memory width restrictions that a PCI root bridge on a= platform might require. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL= instance. + @param[in] Width Signifies the width of the memory operations. + @param[in] DestAddress The destination address of the memory operation.= The caller is + responsible for aligning the DestAddress if requ= ired. + @param[in] SrcAddress The source address of the memory operation. The = caller is + responsible for aligning the SrcAddress if requi= red. + @param[in] Count The number of memory operations to perform. Byte= s moved is + Width size * Count, starting at DestAddress and = SrcAddress. + + @retval EFI_SUCCESS The data was copied from one memory re= gion to another memory region. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bri= dge. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due= to a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoCopyMem ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 DestAddress, + IN UINT64 SrcAddress, + IN UINTN Count + ) +{ + EFI_STATUS Status; + BOOLEAN Direction; + UINTN Stride; + UINTN Index; + UINT64 Result; + + if (Width > EfiPciWidthUint64) { + return EFI_INVALID_PARAMETER; + } + + if (DestAddress =3D=3D SrcAddress) { + return EFI_SUCCESS; + } + + Stride =3D (UINTN)(1 << Width); + + Direction =3D TRUE; + if ((DestAddress > SrcAddress) && (DestAddress < (SrcAddress + Count * S= tride))) { + Direction =3D FALSE; + SrcAddress =3D SrcAddress + (Count-1) * Stride; + DestAddress =3D DestAddress + (Count-1) * Stride; + } + + for (Index =3D 0; Index < Count; Index++) { + Status =3D RootBridgeIoMemRead ( + This, + Width, + SrcAddress, + 1, + &Result + ); + if (EFI_ERROR (Status)) { + return Status; + } + Status =3D RootBridgeIoMemWrite ( + This, + Width, + DestAddress, + 1, + &Result + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Direction) { + SrcAddress +=3D Stride; + DestAddress +=3D Stride; + } else { + SrcAddress -=3D Stride; + DestAddress -=3D Stride; + } + } + return EFI_SUCCESS; +} + +/** + Enables a PCI driver to access PCI controller registers in a PCI root b= ridge's configuration space. + + The Pci.Read() and Pci.Write() functions enable a driver to access PCI = configuration + registers for a PCI controller. + The PCI Configuration operations are carried out exactly as requested. = The caller is responsible for + any alignment and PCI configuration width issues that a PCI Root Bridge= on a platform might + require. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Width Signifies the width of the memory operations. + @param[in] Address The address within the PCI configuration space f= or the PCI controller. + @param[in] Count The number of PCI configuration operations to pe= rform. Bytes + moved is Width size * Count, starting at Address. + @param[out] Buffer For read operations, the destination buffer to s= tore the results. For + write operations, the source buffer to write dat= a from. + + @retval EFI_SUCCESS The data was read from or written to the= PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridg= e. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoPciRead ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + OUT VOID *Buffer + ) +{ + return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer); +} + +/** + Enables a PCI driver to access PCI controller registers in a PCI root b= ridge's configuration space. + + The Pci.Read() and Pci.Write() functions enable a driver to access PCI = configuration + registers for a PCI controller. + The PCI Configuration operations are carried out exactly as requested. = The caller is responsible for + any alignment and PCI configuration width issues that a PCI Root Bridge= on a platform might + require. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Width Signifies the width of the memory operations. + @param[in] Address The address within the PCI configuration space f= or the PCI controller. + @param[in] Count The number of PCI configuration operations to pe= rform. Bytes + moved is Width size * Count, starting at Address. + @param[in] Buffer For read operations, the destination buffer to s= tore the results. For + write operations, the source buffer to write dat= a from. + + @retval EFI_SUCCESS The data was read from or written to the= PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridg= e. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoPciWrite ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer + ) +{ + return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer); +} + +/** + Provides the PCI controller-specific addresses required to access syste= m memory from a + DMA bus master. + + The Map() function provides the PCI controller specific addresses neede= d to access system + memory. This function is used to map system memory for PCI bus master D= MA accesses. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_I= O_PROTOCOL. + @param[in] Operation Indicates if the bus master is going t= o read or write to system memory. + @param[in] HostAddress The system memory address to map to th= e PCI controller. + @param[in, out] NumberOfBytes On input the number of bytes to map. O= n output the number of bytes that were mapped. + @param[out] DeviceAddress The resulting map address for the bus = master PCI controller to use + to access the system memory's HostAddr= ess. + @param[out] Mapping The value to pass to Unmap() when the = bus master DMA operation is complete. + + @retval EFI_SUCCESS The range was mapped for the returned Nu= mberOfBytes. + @retval EFI_INVALID_PARAMETER Operation is invalid. + @retval EFI_INVALID_PARAMETER HostAddress is NULL. + @retval EFI_INVALID_PARAMETER NumberOfBytes is NULL. + @retval EFI_INVALID_PARAMETER DeviceAddress is NULL. + @retval EFI_INVALID_PARAMETER Mapping is NULL. + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a co= mmon buffer. + @retval EFI_DEVICE_ERROR The system hardware could not map the re= quested address. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoMap ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS PhysicalAddress; + MAP_INFO *MapInfo; + + if (HostAddress =3D=3D NULL || NumberOfBytes =3D=3D NULL || DeviceAddres= s =3D=3D NULL || Mapping =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Initialize the return values to their defaults + // + *Mapping =3D NULL; + + // + // Make sure that Operation is valid + // + if ((UINT32)Operation >=3D EfiPciOperationMaximum) { + return EFI_INVALID_PARAMETER; + } + + if ((*NumberOfBytes) > PcdGet64 (PcdPciMemOneTransaction)) { + DEBUG((DEBUG_INFO, "Cannot map more than 0x%x at one transaction\n", + PcdGet64 (PcdPciMemOneTransaction))); + return EFI_INVALID_PARAMETER; + } + + // + // If any part of the DMA transfer being mapped is above 4GB, then + // map the DMA transfer to a buffer below 4GB + // + PhysicalAddress =3D (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress; + if ((PhysicalAddress + *NumberOfBytes) > 0x100000000ULL) { + + // + // Common Buffer operations can not be remapped. If the common buffer + // if above 4GB, then it is not possible to generate a mapping, so ret= urn + // an error. + // + if (Operation =3D=3D EfiPciOperationBusMasterCommonBuffer || Operation= =3D=3D EfiPciOperationBusMasterCommonBuffer64) { + return EFI_UNSUPPORTED; + } + + // + // Allocate a MAP_INFO structure to remember the mapping when Unmap() = is + // called later. + // + Status =3D gBS->AllocatePool ( + EfiBootServicesData, + sizeof (MAP_INFO), + (VOID **)&MapInfo + ); + if (EFI_ERROR (Status)) { + *NumberOfBytes =3D 0; + return Status; + } + + // + // Return a pointer to the MAP_INFO structure in Mapping + // + *Mapping =3D MapInfo; + + // + // Initialize the MAP_INFO structure + // + MapInfo->Operation =3D Operation; + MapInfo->NumberOfBytes =3D *NumberOfBytes; + MapInfo->NumberOfPages =3D EFI_SIZE_TO_PAGES (*NumberOfBytes); + MapInfo->HostAddress =3D PhysicalAddress; + MapInfo->MappedHostAddress =3D GetPciAddressSpaceMask (); + + // + // Allocate a buffer below 4GB to map the transfer to. + // + Status =3D gBS->AllocatePages ( + AllocateMaxAddress, + EfiBootServicesData, + MapInfo->NumberOfPages, + &MapInfo->MappedHostAddress + ); + if (EFI_ERROR (Status)) { + gBS->FreePool (MapInfo); + *NumberOfBytes =3D 0; + return Status; + } + + // + // If this is a read operation from the Bus Master's point of view, + // then copy the contents of the real buffer into the mapped buffer + // so the Bus Master can read the contents of the real buffer. + // + if (Operation =3D=3D EfiPciOperationBusMasterRead || Operation =3D=3D = EfiPciOperationBusMasterRead64) { + CopyMem ( + (VOID *)(UINTN)MapInfo->MappedHostAddress, + (VOID *)(UINTN)MapInfo->HostAddress, + MapInfo->NumberOfBytes + ); + } + + // + // The DeviceAddress is the address of the maped buffer below 4GB + // + *DeviceAddress =3D MapInfo->MappedHostAddress; + } else { + // + // The transfer is below 4GB, so the DeviceAddress is simply the HostA= ddress + // + *DeviceAddress =3D PhysicalAddress; + } + + return EFI_SUCCESS; +} + +/** + Completes the Map() operation and releases any corresponding resources. + + The Unmap() function completes the Map() operation and releases any cor= responding resources. + If the operation was an EfiPciOperationBusMasterWrite or + EfiPciOperationBusMasterWrite64, the data is committed to the target sy= stem memory. + Any resources used for the mapping are freed. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Mapping The mapping value returned from Map(). + + @retval EFI_SUCCESS The range was unmapped. + @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned= by Map(). + @retval EFI_DEVICE_ERROR The data was not committed to the target= system memory. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoUnmap ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN VOID *Mapping + ) +{ + MAP_INFO *MapInfo; + + // + // See if the Map() operation associated with this Unmap() required a ma= pping buffer. + // If a mapping buffer was not required, then this function simply retur= ns EFI_SUCCESS. + // + if (Mapping !=3D NULL) { + // + // Get the MAP_INFO structure from Mapping + // + MapInfo =3D (MAP_INFO *)Mapping; + + // + // If this is a write operation from the Bus Master's point of view, + // then copy the contents of the mapped buffer into the real buffer + // so the processor can read the contents of the real buffer. + // + if (MapInfo->Operation =3D=3D EfiPciOperationBusMasterWrite || MapInfo= ->Operation =3D=3D EfiPciOperationBusMasterWrite64) { + CopyMem ( + (VOID *)(UINTN)MapInfo->HostAddress, + (VOID *)(UINTN)MapInfo->MappedHostAddress, + MapInfo->NumberOfBytes + ); + } + + // + // Free the mapped buffer and the MAP_INFO structure. + // + gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages); + gBS->FreePool (Mapping); + } + return EFI_SUCCESS; +} + +/** + Allocates pages that are suitable for an EfiPciOperationBusMasterCommon= Buffer or + EfiPciOperationBusMasterCommonBuffer64 mapping. + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Type This parameter is not used and must be ignored. + @param MemoryType The type of memory to allocate, EfiBootServicesData = or EfiRuntimeServicesData. + @param Pages The number of pages to allocate. + @param HostAddress A pointer to store the base system memory address of= the allocated range. + @param Attributes The requested bit mask of attributes for the allocat= ed range. Only + the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBIN= E, EFI_PCI_ATTRIBUTE_MEMORY_CAC HED,and EFI_PCI_ATTRIB= UTE_DUAL_ADDRESS_CYCLE may be used with this function. + + @retval EFI_SUCCESS The requested memory pages were allocate= d. + @retval EFI_INVALID_PARAMETER MemoryType is invalid. + @retval EFI_INVALID_PARAMETER HostAddress is NULL. + @retval EFI_UNSUPPORTED Attributes is unsupported. The only lega= l attribute bits are + MEMORY_WRITE_COMBINE, MEMORY_CACHED, and= DUAL_ADDRESS_CYCLE. + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoAllocateBuffer ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT VOID **HostAddress, + IN UINT64 Attributes + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS PhysicalAddress; + + // + // Validate Attributes + // + if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) !=3D 0)= { + return EFI_UNSUPPORTED; + } + + // + // Check for invalid inputs + // + if (HostAddress =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // The only valid memory types are EfiBootServicesData and EfiRuntimeSer= vicesData + // + if (MemoryType !=3D EfiBootServicesData && MemoryType !=3D EfiRuntimeSer= vicesData) { + return EFI_INVALID_PARAMETER; + } + + // + // Limit allocations to memory below 4GB + // + PhysicalAddress =3D (EFI_PHYSICAL_ADDRESS)(GetPciAddressSpaceMask ()); + + Status =3D gBS->AllocatePages (AllocateMaxAddress, MemoryType, Pages, &P= hysicalAddress); + if (EFI_ERROR (Status)) { + return Status; + } + + *HostAddress =3D (VOID *)(UINTN)PhysicalAddress; + + return EFI_SUCCESS; +} + +/** + Frees memory that was allocated with AllocateBuffer(). + + The FreeBuffer() function frees memory that was allocated with Allocate= Buffer(). + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Pages The number of pages to free. + @param HostAddress The base system memory address of the allocated rang= e. + + @retval EFI_SUCCESS The requested memory pages were freed. + @retval EFI_INVALID_PARAMETER The memory range specified by HostAddres= s and Pages + was not allocated with AllocateBuffer(). + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoFreeBuffer ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN UINTN Pages, + OUT VOID *HostAddress + ) +{ + + return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages= ); +} + +/** + Flushes all PCI posted write transactions from a PCI host bridge to sys= tem memory. + + The Flush() function flushes any PCI posted write transactions from a P= CI host bridge to system + memory. Posted write transactions are generated by PCI bus masters when= they perform write + transactions to target addresses in system memory. + This function does not flush posted write transactions from any PCI bri= dges. A PCI controller + specific action must be taken to guarantee that the posted write transa= ctions have been flushed from + the PCI controller and from all the PCI bridges into the PCI host bridg= e. This is typically done with + a PCI read transaction from the PCI controller prior to calling Flush(). + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + + @retval EFI_SUCCESS The PCI posted write transactions were flush= ed from the PCI host + bridge to system memory. + @retval EFI_DEVICE_ERROR The PCI posted write transactions were not f= lushed from the PCI + host bridge due to a hardware error. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoFlush ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This + ) +{ + // + // not supported yet + // + return EFI_SUCCESS; +} + +/** + Gets the attributes that a PCI root bridge supports setting with SetAtt= ributes(), and the + attributes that a PCI root bridge is currently using. + + The GetAttributes() function returns the mask of attributes that this P= CI root bridge supports + and the mask of attributes that the PCI root bridge is currently using + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Supported A pointer to the mask of attributes that this PCI ro= ot bridge + supports setting with SetAttributes(). + @param Attributes A pointer to the mask of attributes that this PCI ro= ot bridge is + currently using. + + @retval EFI_SUCCESS If Supports is not NULL, then the attrib= utes that the PCI root + bridge supports is returned in Supports.= If Attributes is + not NULL, then the attributes that the P= CI root bridge is currently + using is returned in Attributes. + @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoGetAttributes ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + OUT UINT64 *Supported, + OUT UINT64 *Attributes + ) +{ + PCI_ROOT_BRIDGE_INSTANCE *PrivateData; + + PrivateData =3D DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This); + + if (Attributes =3D=3D NULL && Supported =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Set the return value for Supported and Attributes + // + if (Supported !=3D NULL) { + *Supported =3D PrivateData->Supports; + } + + if (Attributes !=3D NULL) { + *Attributes =3D PrivateData->Attributes; + } + + return EFI_SUCCESS; +} + +/** + Sets attributes for a resource range on a PCI root bridge. + + The SetAttributes() function sets the attributes specified in Attribute= s for the PCI root + bridge on the resource range specified by ResourceBase and ResourceLeng= th. Since the + granularity of setting these attributes may vary from resource type to = resource type, and from + platform to platform, the actual resource range and the one passed in b= y the caller may differ. As a + result, this function may set the attributes specified by Attributes on= a larger resource range + than the caller requested. The actual range is returned in ResourceBase= and + ResourceLength. The caller is responsible for verifying that the actual= range for which the + attributes were set is acceptable. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_I= O_PROTOCOL. + @param[in] Attributes The mask of attributes to set. If the = attribute bit + MEMORY_WRITE_COMBINE, MEMORY_CACHED, or + MEMORY_DISABLE is set, then the resour= ce range is specified by + ResourceBase and ResourceLength. If + MEMORY_WRITE_COMBINE, MEMORY_CACHED, a= nd + MEMORY_DISABLE are not set, then Resou= rceBase and + ResourceLength are ignored, and may be= NULL. + @param[in, out] ResourceBase A pointer to the base address of the r= esource range to be modified + by the attributes specified by Attribu= tes. + @param[in, out] ResourceLength A pointer to the length of the resourc= e range to be modified by the + attributes specified by Attributes. + + @retval EFI_SUCCESS The current configuration of this PCI root bri= dge was returned in Resources. + @retval EFI_UNSUPPORTED The current configuration of this PCI root bri= dge could not be retrieved. + @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_I= O_PROTOCOL + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoSetAttributes ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN UINT64 Attributes, + IN OUT UINT64 *ResourceBase, + IN OUT UINT64 *ResourceLength + ) +{ + PCI_ROOT_BRIDGE_INSTANCE *PrivateData; + + PrivateData =3D DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This); + + if (Attributes !=3D 0) { + if ((Attributes & (~(PrivateData->Supports))) !=3D 0) { + return EFI_UNSUPPORTED; + } + } + + // + // This is a generic driver for a PC-AT class system. It does not have = any + // chipset specific knowlegde, so none of the attributes can be set or + // cleared. Any attempt to set attribute that are already set will succ= eed, + // and any attempt to set an attribute that is not supported will fail. + // + if (Attributes & (~PrivateData->Attributes)) { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +/** + Retrieves the current resource settings of this PCI root bridge in the = form of a set of ACPI 2.0 + resource descriptors. + + There are only two resource descriptor types from the ACPI Specificatio= n that may be used to + describe the current resources allocated to a PCI root bridge. These ar= e the QWORD Address + Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.= 0 Section 6.4.2.8). The + QWORD Address Space Descriptor can describe memory, I/O, and bus number= ranges for dynamic + or fixed resources. The configuration of a PCI root bridge is described= with one or more QWORD + Address Space Descriptors followed by an End Tag. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOC= OL. + @param[out] Resources A pointer to the ACPI 2.0 resource descriptors= that describe the + current configuration of this PCI root bridge.= The storage for the + ACPI 2.0 resource descriptors is allocated by = this function. The + caller must treat the return buffer as read-on= ly data, and the buffer + must not be freed by the caller. + + @retval EFI_SUCCESS The current configuration of this PCI root bri= dge was returned in Resources. + @retval EFI_UNSUPPORTED The current configuration of this PCI root bri= dge could not be retrieved. + @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_I= O_PROTOCOL + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoConfiguration ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + OUT VOID **Resources +) +{ + PCI_ROOT_BRIDGE_INSTANCE *RootBridge; + UINTN Index; + + RootBridge =3D DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This); + + for (Index =3D 0; Index < ResTypeMax; Index++) { + if (RootBridge->ResAlloc[Index].Length !=3D 0) { + Configuration.SpaceDesp[Index].AddrRangeMin =3D RootBridge->ResAlloc= [Index].Base; + Configuration.SpaceDesp[Index].AddrRangeMax =3D RootBridge->ResAlloc= [Index].Base + RootBridge->ResAlloc[Index].Length - 1; + Configuration.SpaceDesp[Index].AddrLen =3D RootBridge->ResAlloc= [Index].Length; + } + } + + // Set up Configuration for the bus + Configuration.SpaceDesp[Index].AddrRangeMin =3D RootBridge->BusStart; + Configuration.SpaceDesp[Index].AddrLen =3D RootBridge->BusLength; + + *Resources =3D &Configuration; + return EFI_SUCCESS; +} diff --git a/Platform/NXP/Include/PciHostBridge.h b/Platform/NXP/Include/Pc= iHostBridge.h new file mode 100644 index 0000000..cfca971 --- /dev/null +++ b/Platform/NXP/Include/PciHostBridge.h @@ -0,0 +1,466 @@ +/** PciHostBridge.h + The Header file of the Pci Host Bridge Driver + + Some part of code is inspired from EDK II, File: + PcAtChipsetPkg/PciHostBridgeDxe/PciHostBridge.h + + Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.
+ Copyright 2017 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 + 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 IMPL= IED. + +**/ + +#ifndef _PCI_HOST_BRIDGE_H_ +#define _PCI_HOST_BRIDGE_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PciCntrlLib.h" + +#define MAX_PCI_DEVICE_NUMBER 31 +#define MAX_PCI_FUNCTION_NUMBER 7 +#define MAX_PCI_REG_ADDRESS (SIZE_4KB - 1) + +#define LS_PCIE_CFG0_PHYS_OFF 0x00000000 +#define LS_PCIE_CFG0_SIZE 0x00001000 /* 4k */ +#define LS_PCIE_CFG1_PHYS_OFF 0x00001000 +#define LS_PCIE_CFG1_SIZE 0x00001000 /* 4k */ + +#define LS_PCIE_IO_BUS 0x00000000 +#define LS_PCIE_IO_PHYS_OFF 0x00010000 +#define LS_PCIE_IO_SIZE 0x00010000 /* 64k */ + +#define LS_PCIE_MEM_BUS 0x40000000 +#define LS_PCIE_MEM_PHYS_OFF 0x40000000 +#define LS_PCIE_MEM_SIZE 0x40000000 /* 1 GB */ + +#define PCI_MEM64_SIZE FixedPcdGet64 (PcdPciMmio64Size) + +#define NUM_PCIE_CONTROLLER FixedPcdGet32 (PcdNumPciController) + +#define PCI_MMIO64_BASE_DIFFERENCE 0x800000000 + +typedef enum { + IoOperation, + MemOperation, + PciOperation +} OPERATION_TYPE; + +#define PCI_HOST_BRIDGE_SIGNATURE SIGNATURE_32('p', 'c', 'i', 'h') +typedef struct PCI_HOST_BRIDGE_INSTANCE_ST { + UINTN Signature; + EFI_HANDLE HostBridgeHandle; + EFI_HANDLE ImageHandle; + UINTN RootBridgeNumber[4]; + PCI_ROOT_BRIDGE_INSTANCE *RootBridge; + LIST_ENTRY Head; + BOOLEAN ResourceSubmited; + BOOLEAN CanRestarted; + EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL ResAlloc; +} PCI_HOST_BRIDGE_INSTANCE; + +#define INSTANCE_FROM_RESOURCE_ALLOCATION_THIS(a) \ + CR(a, PCI_HOST_BRIDGE_INSTANCE, ResAlloc, PCI_HOST_BRIDGE_SIGNATURE) + +// +// HostBridge Resource Allocation interface +// +/** + These are the notifications from the PCI bus driver that it is about to= enter a certain + phase of the PCI enumeration process. + + This member function can be used to notify the host bridge driver to pe= rform specific actions, + including any chipset-specific initialization, so that the chipset is r= eady to enter the next phase. + Eight notification points are defined at this time. See belows: + EfiPciHostBridgeBeginEnumeration Resets the host bridge PCI apert= ures and internal data + structures. The PCI enumerator s= hould issue this notification + before starting a fresh enumerat= ion process. Enumeration cannot + be restarted after sending any o= ther notification such as + EfiPciHostBridgeBeginBusAllocati= on. + EfiPciHostBridgeBeginBusAllocation The bus allocation phase is abou= t to begin. No specific action is + required here. This notification= can be used to perform any + chipset-specific programming. + EfiPciHostBridgeEndBusAllocation The bus allocation and bus progr= amming phase is complete. No + specific action is required here= . This notification can be used to + perform any chipset-specific pro= gramming. + EfiPciHostBridgeBeginResourceAllocation + The resource allocation phase is= about to begin. No specific + action is required here. This no= tification can be used to perform + any chipset-specific programming. + EfiPciHostBridgeAllocateResources Allocates resources per previous= ly submitted requests for all the PCI + root bridges. These resource set= tings are returned on the next call to + GetProposedResources(). Before c= alling NotifyPhase() with a Phase of + EfiPciHostBridgeAllocateResource= , the PCI bus enumerator is responsible + for gathering I/O and memory req= uests for + all the PCI root bridges and sub= mitting these requests using + SubmitResources(). This function= pads the resource amount + to suit the root bridge hardware= , takes care of dependencies between + the PCI root bridges, and calls = the Global Coherency Domain (GCD) + with the allocation request. In = the case of padding, the allocated range + could be bigger than what was re= quested. + EfiPciHostBridgeSetResources Programs the host bridge hardwar= e to decode previously allocated + resources (proposed resources) f= or all the PCI root bridges. After the + hardware is programmed, reassign= ing resources will not be supported. + The bus settings are not affecte= d. + EfiPciHostBridgeFreeResources Deallocates resources that were = previously allocated for all the PCI + root bridges and resets the I/O = and memory apertures to their initial + state. The bus settings are not = affected. If the request to allocate + resources fails, the PCI enumera= tor can use this notification to + deallocate previous resources, a= djust the requests, and retry + allocation. + EfiPciHostBridgeEndResourceAllocation The resource allocation phase is= completed. No specific action is + required here. This notification= can be used to perform any chipsetspecific + programming. + + @param[in] This The instance pointer of EFI_PCI_HOST_BRI= DGE_RESOURCE_ALLOCATION_PROTOCOL + @param[in] Phase The phase during enumeration + + @retval EFI_NOT_READY This phase cannot be entered at this tim= e. For example, this error + is valid for a Phase of EfiPciHostBridge= AllocateResources if + SubmitResources() has not been called fo= r one or more + PCI root bridges before this call + @retval EFI_DEVICE_ERROR Programming failed due to a hardware err= or. This error is valid + for a Phase of EfiPciHostBridgeSetResour= ces. + @retval EFI_INVALID_PARAMETER Invalid phase parameter + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + This error is valid for a Phase of EfiPc= iHostBridgeAllocateResources if the + previously submitted resource requests c= annot be fulfilled or + were only partially fulfilled. + @retval EFI_SUCCESS The notification was accepted without an= y errors. + +**/ +EFI_STATUS +EFIAPI +PciNotifyPhase( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase + ); + +/** + Return the device handle of the next PCI root bridge that is associated= with this Host Bridge. + + This function is called multiple times to retrieve the device handles o= f all the PCI root bridges that + are associated with this PCI host bridge. Each PCI host bridge is assoc= iated with one or more PCI + root bridges. On each call, the handle that was returned by the previou= s call is passed into the + interface, and on output the interface returns the device handle of the= next PCI root bridge. The + caller can use the handle to obtain the instance of the EFI_PCI_ROOT_BR= IDGE_IO_PROTOCOL + for that root bridge. When there are no more PCI root bridges to report= , the interface returns + EFI_NOT_FOUND. A PCI enumerator must enumerate the PCI root bridges in = the order that they + are returned by this function. + For D945 implementation, there is only one root bridge in PCI host brid= ge. + + @param[in] This The instance pointer of EFI_PCI_HOST= _BRIDGE_RESOURCE_ALLOCATION_PROTOCOL + @param[in, out] RootBridgeHandle Returns the device handle of the nex= t PCI root bridge. + + @retval EFI_SUCCESS If parameter RootBridgeHandle =3D NULL, = then return the first Rootbridge handle of the + specific Host bridge and return EFI_SUCC= ESS. + @retval EFI_NOT_FOUND Can not find the any more root bridge in= specific host bridge. + @retval EFI_INVALID_PARAMETER RootBridgeHandle is not an EFI_HANDLE th= at was + returned on a previous call to GetNextRo= otBridge(). +**/ +EFI_STATUS +EFIAPI +PciGetNextRootBridge( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN OUT EFI_HANDLE *RootBridgeHan= dle + ); + +/** + Returns the allocation attributes of a PCI root bridge. + + The function returns the allocation attributes of a specific PCI root b= ridge. The attributes can vary + from one PCI root bridge to another. These attributes are different fro= m the decode-related + attributes that are returned by the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Get= Attributes() member function. The + RootBridgeHandle parameter is used to specify the instance of the PCI r= oot bridge. The device + handles of all the root bridges that are associated with this host brid= ge must be obtained by calling + GetNextRootBridge(). The attributes are static in the sense that they d= o not change during or + after the enumeration process. The hardware may provide mechanisms to c= hange the attributes on + the fly, but such changes must be completed before EFI_PCI_HOST_BRIDGE_= RESOURCE_ALLOCATION_PROTOCOL is + installed. The permitted values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCAT= ION_ATTRIBUTES are defined in + "Related Definitions" below. The caller uses these attributes to combin= e multiple resource requests. + For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, t= he PCI bus enumerator needs to + include requests for the prefetchable memory in the nonprefetchable mem= ory pool and not request any + prefetchable memory. + Attribute Description + ------------------------------------ --------------------------= -------------------------------------------- + EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM If this bit is set, then t= he PCI root bridge does not support separate + windows for nonprefetchabl= e and prefetchable memory. A PCI bus + driver needs to include re= quests for prefetchable memory in the + nonprefetchable memory poo= l. + + EFI_PCI_HOST_BRIDGE_MEM64_DECODE If this bit is set, then t= he PCI root bridge supports 64-bit memory + windows. If this bit is no= t set, the PCI bus driver needs to include + requests for a 64-bit memo= ry address in the corresponding 32-bit + memory pool. + + @param[in] This The instance pointer of EFI_PCI_HOST_BR= IDGE_RESOURCE_ALLOCATION_PROTOCOL + @param[in] RootBridgeHandle The device handle of the PCI root bridg= e in which the caller is interested. Type + EFI_HANDLE is defined in InstallProtoco= lInterface() in the UEFI 2.0 Specification. + @param[out] Attributes The pointer to attribte of root bridge,= it is output parameter + + @retval EFI_INVALID_PARAMETER Attribute pointer is NULL + @retval EFI_INVALID_PARAMETER RootBridgehandle is invalid. + @retval EFI_SUCCESS Success to get attribute of interested = root bridge. + +**/ +EFI_STATUS +EFIAPI +PciGetAllocAttributes( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + OUT UINT64 *Attributes + ); + +/** + Sets up the specified PCI root bridge for the bus enumeration process. + + This member function sets up the root bridge for bus enumeration and re= turns the PCI bus range + over which the search should be performed in ACPI 2.0 resource descript= or format. + + @param[in] This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCAT= ION_ PROTOCOL instance. + @param[in] RootBridgeHandle The PCI Root Bridge to be set up. + @param[out] Configuration Pointer to the pointer to the PCI bus re= source descriptor. + + @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle + @retval EFI_OUT_OF_RESOURCES Fail to allocate ACPI resource descriptor= tag. + @retval EFI_SUCCESS Sucess to allocate ACPI resource descript= or. + +**/ +EFI_STATUS +EFIAPI +PciStartBusEnumeration( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + OUT VOID **Configuration + ); + +/** + Programs the PCI root bridge hardware so that it decodes the specified = PCI bus range. + + This member function programs the specified PCI root bridge to decode t= he bus range that is + specified by the input parameter Configuration. + The bus range information is specified in terms of the ACPI 2.0 resourc= e descriptor format. + + @param[in] This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATIO= N_ PROTOCOL instance + @param[in] RootBridgeHandle The PCI Root Bridge whose bus range is to = be programmed + @param[in] Configuration The pointer to the PCI bus resource descri= ptor + + @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bri= dge handle. + @retval EFI_INVALID_PARAMETER Configuration is NULL. + @retval EFI_INVALID_PARAMETER Configuration does not point to a valid = ACPI 2.0 resource descriptor. + @retval EFI_INVALID_PARAMETER Configuration does not include a valid A= CPI 2.0 bus resource descriptor. + @retval EFI_INVALID_PARAMETER Configuration includes valid ACPI 2.0 re= source descriptors other than + bus descriptors. + @retval EFI_INVALID_PARAMETER Configuration contains one or more inval= id ACPI resource descriptors. + @retval EFI_INVALID_PARAMETER "Address Range Minimum" is invalid for t= his root bridge. + @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for th= is root bridge. + @retval EFI_DEVICE_ERROR Programming failed due to a hardware err= or. + @retval EFI_SUCCESS The bus range for the PCI root bridge wa= s programmed. + +**/ +EFI_STATUS +EFIAPI +PciSetBusNumbers( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + IN VOID *Configuration + ); + +/** + Submits the I/O and memory resource requirements for the specified PCI = root bridge. + + This function is used to submit all the I/O and memory resources that a= re required by the specified + PCI root bridge. The input parameter Configuration is used to specify t= he following: + - The various types of resources that are required + - The associated lengths in terms of ACPI 2.0 resource descriptor format + + @param[in] This Pointer to the EFI_PCI_HOST_BRIDGE_RESOURC= E_ALLOCATION_PROTOCOL instance. + @param[in] RootBridgeHandle The PCI root bridge whose I/O and memory r= esource requirements are being submitted. + @param[in] Configuration The pointer to the PCI I/O and PCI memory = resource descriptor. + + @retval EFI_SUCCESS The I/O and memory resource requests for= a PCI root bridge were accepted. + @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bri= dge handle. + @retval EFI_INVALID_PARAMETER Configuration is NULL. + @retval EFI_INVALID_PARAMETER Configuration does not point to a valid = ACPI 2.0 resource descriptor. + @retval EFI_INVALID_PARAMETER Configuration includes requests for one = or more resource types that are + not supported by this PCI root bridge. T= his error will happen if the caller + did not combine resources according to A= ttributes that were returned by + GetAllocAttributes(). + @retval EFI_INVALID_PARAMETER Address Range Maximum" is invalid. + @retval EFI_INVALID_PARAMETER "Address Range Length" is invalid for th= is PCI root bridge. + @retval EFI_INVALID_PARAMETER "Address Space Granularity" is invalid f= or this PCI root bridge. + +**/ +EFI_STATUS +EFIAPI +PciSubmitResources( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + IN VOID *Configuration + ); + +/** + Returns the proposed resource settings for the specified PCI root bridg= e. + + This member function returns the proposed resource settings for the spe= cified PCI root bridge. The + proposed resource settings are prepared when NotifyPhase() is called wi= th a Phase of + EfiPciHostBridgeAllocateResources. The output parameter Configuration + specifies the following: + - The various types of resources, excluding bus resources, that are all= ocated + - The associated lengths in terms of ACPI 2.0 resource descriptor format + + @param[in] This Pointer to the EFI_PCI_HOST_BRIDGE_RESOUR= CE_ALLOCATION_PROTOCOL instance. + @param[in] RootBridgeHandle The PCI root bridge handle. Type EFI_HAND= LE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification. + @param[out] Configuration The pointer to the pointer to the PCI I/O= and memory resource descriptor. + + @retval EFI_SUCCESS The requested parameters were returned. + @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bri= dge handle. + @retval EFI_DEVICE_ERROR Programming failed due to a hardware err= or. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +EFIAPI +PciGetProposedResources( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + OUT VOID **Configuration + ); + +/** + Provides the hooks from the PCI bus driver to every PCI controller (dev= ice/function) at various + stages of the PCI enumeration process that allow the host bridge driver= to preinitialize individual + PCI controllers before enumeration. + + This function is called during the PCI enumeration process. No specific= action is expected from this + member function. It allows the host bridge driver to preinitialize indi= vidual PCI controllers before + enumeration. + + @param This Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_AL= LOCATION_PROTOCOL instance. + @param RootBridgeHandle The associated PCI root bridge handle. Type EF= I_HANDLE is defined in + InstallProtocolInterface() in the UEFI 2.0 Spe= cification. + @param PciAddress The address of the PCI device on the PCI bus. = This address can be passed to the + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functio= ns to access the PCI + configuration space of the device. See Table 1= 2-1 in the UEFI 2.0 Specification for + the definition of EFI_PCI_ROOT_BRIDGE_IO_PROTO= COL_PCI_ADDRESS. + @param Phase The phase of the PCI device enumeration. + + @retval EFI_SUCCESS The requested parameters were returned. + @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root b= ridge handle. + @retval EFI_INVALID_PARAMETER Phase is not a valid phase that is def= ined in + EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION= _PHASE. + @retval EFI_DEVICE_ERROR Programming failed due to a hardware e= rror. The PCI enumerator should + not enumerate this device, including i= ts child devices if it is a PCI-to-PCI + bridge. + +**/ +EFI_STATUS +EFIAPI +PciPreprocessController ( + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_HANDLE RootBridgeHandle, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress, + IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase + ); + + +// +// Define resource status constant +// +#define EFI_RESOURCE_NONEXISTENT 0xFFFFFFFFFFFFFFFFULL +#define EFI_RESOURCE_LESS 0xFFFFFFFFFFFFFFFEULL + +// +// Driver Instance Data Prototypes +// + +typedef struct { + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation; + UINTN NumberOfBytes; + UINTN NumberOfPages; + EFI_PHYSICAL_ADDRESS HostAddress; + EFI_PHYSICAL_ADDRESS MappedHostAddress; +} MAP_INFO; + +typedef enum { + ResNone =3D 0, + ResSubmitted, + ResRequested, + ResAllocated, + ResStatusMax +} RES_STATUS; + +typedef struct { + PCI_RESOURCE_TYPE Type; + UINT64 Base; + UINT64 Length; + UINT64 Alignment; + RES_STATUS Status; +} PCI_RES_NODE; + +#define PCI_ROOT_BRIDGE_SIGNATURE SIGNATURE_32('P', 'C', 'I', '3') + +// +// Driver Instance Data Macros +// +#define DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(a) \ + CR(a, PCI_ROOT_BRIDGE_INSTANCE, Io, PCI_ROOT_BRIDGE_SIGNATURE) + + +#define DRIVER_INSTANCE_FROM_LIST_ENTRY(a) \ + CR(a, PCI_ROOT_BRIDGE_INSTANCE, Link, PCI_ROOT_BRIDGE_SIGNATURE) + +/** + Initialize and create Pci Root Bridges for Board + + @param PrvateData Driver instance of this Root Bridge IO protocol + @param Protocol Point to protocol instance + @param Info Point to Info field of this driver instance + @param HostBridgeHandle Handle of host bridge + @param Attri Attribute of host bridge + @param HostNo HostNo for this Host Bridge + @param Busno Bus Number for the Host Bridge + + @retval EFI_SUCCESS Success to initialize the Pci Root Bridge. + +**/ + +EFI_STATUS +PciRbInitialize ( + IN PCI_ROOT_BRIDGE_INSTANCE *PrivateData, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Protocol, + IN LsPcieInfo *Info, + IN EFI_HANDLE HostBridgeHandle, + IN UINT64 Attri, + IN INTN HostNo, + IN INTN Busno, + IN UINT64 *PciBaseAddr +); + +/** + Function to return PCI addess space mask +**/ +UINT64 +GetPciAddressSpaceMask ( + IN VOID + ); + +#endif diff --git a/Platform/NXP/Include/PciRootBridge.h b/Platform/NXP/Include/Pc= iRootBridge.h new file mode 100644 index 0000000..cd22e48 --- /dev/null +++ b/Platform/NXP/Include/PciRootBridge.h @@ -0,0 +1,674 @@ +/** PciRootBridge.h + The Header file of the Pci Root Bridge driver + + Copyright 2017 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 + 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 IMPL= IED. + +**/ + +#ifndef _PCI_LS_H_ +#define _PCI_LS_H_ + +#include + +#define MAX_PCI_REGIONS 7 + +typedef UINT64 PciAddrT; +typedef UINT64 PciSizeT; +typedef UINT64 PhysAddrT; +typedef UINT64 PhysSizeT; +typedef INTN PciDevT; + +// +// Protocol Member Function Prototypes +// + +/** + Polls an address in memory mapped I/O space until an exit condition is = met, or + a timeout occurs. + + This function provides a standard way to poll a PCI memory location. A = PCI memory read + operation is performed at the PCI memory address specified by Address f= or the width specified + by Width. The result of this PCI memory read operation is stored in Res= ult. This PCI memory + read operation is repeated until either a timeout of Delay 100 ns units= has expired, or (Result & + Mask) is equal to Value. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Width Signifies the width of the memory operations. + @param[in] Address The base address of the memory operations. The c= aller is + responsible for aligning Address if required. + @param[in] Mask Mask used for the polling criteria. Bytes above = Width in Mask + are ignored. The bits in the bytes below Width w= hich are zero in + Mask are ignored when polling the memory address. + @param[in] Value The comparison value used for the polling exit c= riteria. + @param[in] Delay The number of 100 ns units to poll. Note that ti= mer available may + be of poorer granularity. + @param[out] Result Pointer to the last value read from the memory l= ocation. + + @retval EFI_SUCCESS The last data returned from the access m= atched the poll exit criteria. + @retval EFI_INVALID_PARAMETER Width is invalid. + @retval EFI_INVALID_PARAMETER Result is NULL. + @retval EFI_TIMEOUT Delay expired before a match occurred. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoPollMem ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result + ); + +/** + Reads from the I/O space of a PCI Root Bridge. Returns when either the = polling exit criteria is + satisfied or after a defined duration. + + This function provides a standard way to poll a PCI I/O location. A PCI= I/O read operation is + performed at the PCI I/O address specified by Address for the width spe= cified by Width. + The result of this PCI I/O read operation is stored in Result. This PCI= I/O read operation is + repeated until either a timeout of Delay 100 ns units has expired, or (= Result & Mask) is equal + to Value. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Width Signifies the width of the I/O operations. + @param[in] Address The base address of the I/O operations. The caller= is responsible + for aligning Address if required. + @param[in] Mask Mask used for the polling criteria. Bytes above Wi= dth in Mask + are ignored. The bits in the bytes below Width whi= ch are zero in + Mask are ignored when polling the I/O address. + @param[in] Value The comparison value used for the polling exit cri= teria. + @param[in] Delay The number of 100 ns units to poll. Note that time= r available may + be of poorer granularity. + @param[out] Result Pointer to the last value read from the memory loc= ation. + + @retval EFI_SUCCESS The last data returned from the access m= atched the poll exit criteria. + @retval EFI_INVALID_PARAMETER Width is invalid. + @retval EFI_INVALID_PARAMETER Result is NULL. + @retval EFI_TIMEOUT Delay expired before a match occurred. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoPollIo ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result + ); + +/** + Enables a PCI driver to access PCI controller registers in the PCI root= bridge memory space. + + The Mem.Read(), and Mem.Write() functions enable a driver to access PCI= controller + registers in the PCI root bridge memory space. + The memory operations are carried out exactly as requested. The caller = is responsible for satisfying + any alignment and memory width restrictions that a PCI Root Bridge on a= platform might require. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Width Signifies the width of the memory operation. + @param[in] Address The base address of the memory operation. The ca= ller is + responsible for aligning the Address if required. + @param[in] Count The number of memory operations to perform. Byte= s moved is + Width size * Count, starting at Address. + @param[out] Buffer For read operations, the destination buffer to s= tore the results. For + write operations, the source buffer to write dat= a from. + + @retval EFI_SUCCESS The data was read from or written to the= PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridg= e. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoMemRead ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + OUT VOID *Buffer + ); + +/** + Enables a PCI driver to access PCI controller registers in the PCI root= bridge memory space. + + The Mem.Read(), and Mem.Write() functions enable a driver to access PCI= controller + registers in the PCI root bridge memory space. + The memory operations are carried out exactly as requested. The caller = is responsible for satisfying + any alignment and memory width restrictions that a PCI Root Bridge on a= platform might require. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Width Signifies the width of the memory operation. + @param[in] Address The base address of the memory operation. The ca= ller is + responsible for aligning the Address if required. + @param[in] Count The number of memory operations to perform. Byte= s moved is + Width size * Count, starting at Address. + @param[in] Buffer For read operations, the destination buffer to s= tore the results. For + write operations, the source buffer to write dat= a from. + + @retval EFI_SUCCESS The data was read from or written to the= PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridg= e. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. +**/ +EFI_STATUS +EFIAPI +RootBridgeIoMemWrite ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer + ); + +/** + Enables a PCI driver to access PCI controller registers in the PCI root= bridge I/O space. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOC= OL. + @param[in] Width Signifies the width of the memory operations. + @param[in] UserAddress The base address of the I/O operation. The cal= ler is responsible for + aligning the Address if required. + @param[in] Count The number of I/O operations to perform. Bytes= moved is Width + size * Count, starting at Address. + @param[out] UserBuffer For read operations, the destination buffer to= store the results. For + write operations, the source buffer to write d= ata from. + + @retval EFI_SUCCESS The data was read from or written to t= he PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bri= dge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due= to a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoIoRead ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 UserAddress, + IN UINTN Count, + OUT VOID *UserBuffer + ); + +/** + Enables a PCI driver to access PCI controller registers in the PCI root= bridge I/O space. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOC= OL. + @param[in] Width Signifies the width of the memory operations. + @param[in] UserAddress The base address of the I/O operation. The cal= ler is responsible for + aligning the Address if required. + @param[in] Count The number of I/O operations to perform. Bytes= moved is Width + size * Count, starting at Address. + @param[in] UserBuffer For read operations, the destination buffer to= store the results. For + write operations, the source buffer to write d= ata from. + + @retval EFI_SUCCESS The data was read from or written to t= he PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bri= dge. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due= to a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoIoWrite ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 UserAddress, + IN UINTN Count, + IN VOID *UserBuffer + ); + +/** + Enables a PCI driver to copy one region of PCI root bridge memory space= to another region of PCI + root bridge memory space. + + The CopyMem() function enables a PCI driver to copy one region of PCI r= oot bridge memory + space to another region of PCI root bridge memory space. This is especi= ally useful for video scroll + operation on a memory mapped video buffer. + The memory operations are carried out exactly as requested. The caller = is responsible for satisfying + any alignment and memory width restrictions that a PCI root bridge on a= platform might require. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL= instance. + @param[in] Width Signifies the width of the memory operations. + @param[in] DestAddress The destination address of the memory operation.= The caller is + responsible for aligning the DestAddress if requ= ired. + @param[in] SrcAddress The source address of the memory operation. The = caller is + responsible for aligning the SrcAddress if requi= red. + @param[in] Count The number of memory operations to perform. Byte= s moved is + Width size * Count, starting at DestAddress and = SrcAddress. + + @retval EFI_SUCCESS The data was copied from one memory re= gion to another memory region. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bri= dge. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due= to a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoCopyMem ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 DestAddress, + IN UINT64 SrcAddress, + IN UINTN Count + ); + +/** + Enables a PCI driver to access PCI controller registers in a PCI root b= ridge's configuration space. + + The Pci.Read() and Pci.Write() functions enable a driver to access PCI = configuration + registers for a PCI controller. + The PCI Configuration operations are carried out exactly as requested. = The caller is responsible for + any alignment and PCI configuration width issues that a PCI Root Bridge= on a platform might + require. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Width Signifies the width of the memory operations. + @param[in] Address The address within the PCI configuration space f= or the PCI controller. + @param[in] Count The number of PCI configuration operations to pe= rform. Bytes + moved is Width size * Count, starting at Address. + @param[out] Buffer For read operations, the destination buffer to s= tore the results. For + write operations, the source buffer to write dat= a from. + + @retval EFI_SUCCESS The data was read from or written to the= PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridg= e. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoPciRead ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + OUT VOID *Buffer + ); + +/** + Enables a PCI driver to access PCI controller registers in a PCI root b= ridge's configuration space. + + The Pci.Read() and Pci.Write() functions enable a driver to access PCI = configuration + registers for a PCI controller. + The PCI Configuration operations are carried out exactly as requested. = The caller is responsible for + any alignment and PCI configuration width issues that a PCI Root Bridge= on a platform might + require. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Width Signifies the width of the memory operations. + @param[in] Address The address within the PCI configuration space f= or the PCI controller. + @param[in] Count The number of PCI configuration operations to pe= rform. Bytes + moved is Width size * Count, starting at Address. + @param[in] Buffer For read operations, the destination buffer to s= tore the results. For + write operations, the source buffer to write dat= a from. + + @retval EFI_SUCCESS The data was read from or written to the= PCI root bridge. + @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridg= e. + @retval EFI_INVALID_PARAMETER Buffer is NULL. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoPciWrite ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer + ); + +/** + Provides the PCI controller-specific addresses required to access syste= m memory from a + DMA bus master. + + The Map() function provides the PCI controller specific addresses neede= d to access system + memory. This function is used to map system memory for PCI bus master D= MA accesses. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_I= O_PROTOCOL. + @param[in] Operation Indicates if the bus master is going t= o read or write to system memory. + @param[in] HostAddress The system memory address to map to th= e PCI controller. + @param[in, out] NumberOfBytes On input the number of bytes to map. O= n output the number of bytes that were mapped. + @param[out] DeviceAddress The resulting map address for the bus = master PCI controller to use + to access the system memory's HostAddr= ess. + @param[out] Mapping The value to pass to Unmap() when the = bus master DMA operation is complete. + + @retval EFI_SUCCESS The range was mapped for the returned Nu= mberOfBytes. + @retval EFI_INVALID_PARAMETER Operation is invalid. + @retval EFI_INVALID_PARAMETER HostAddress is NULL. + @retval EFI_INVALID_PARAMETER NumberOfBytes is NULL. + @retval EFI_INVALID_PARAMETER DeviceAddress is NULL. + @retval EFI_INVALID_PARAMETER Mapping is NULL. + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a co= mmon buffer. + @retval EFI_DEVICE_ERROR The system hardware could not map the re= quested address. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due t= o a lack of resources. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoMap ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ); + +/** + Completes the Map() operation and releases any corresponding resources. + + The Unmap() function completes the Map() operation and releases any cor= responding resources. + If the operation was an EfiPciOperationBusMasterWrite or + EfiPciOperationBusMasterWrite64, the data is committed to the target sy= stem memory. + Any resources used for the mapping are freed. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param[in] Mapping The mapping value returned from Map(). + + @retval EFI_SUCCESS The range was unmapped. + @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned= by Map(). + @retval EFI_DEVICE_ERROR The data was not committed to the target= system memory. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoUnmap ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN VOID *Mapping + ); + +/** + Allocates pages that are suitable for an EfiPciOperationBusMasterCommon= Buffer or + EfiPciOperationBusMasterCommonBuffer64 mapping. + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Type This parameter is not used and must be ignored. + @param MemoryType The type of memory to allocate, EfiBootServicesData = or EfiRuntimeServicesData. + @param Pages The number of pages to allocate. + @param HostAddress A pointer to store the base system memory address of= the allocated range. + @param Attributes The requested bit mask of attributes for the allocat= ed range. Only + the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBIN= E, EFI_PCI_ATTRIBUTE_MEMORY_CACHED, + and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used= with this function. + + @retval EFI_SUCCESS The requested memory pages were allocate= d. + @retval EFI_INVALID_PARAMETER MemoryType is invalid. + @retval EFI_INVALID_PARAMETER HostAddress is NULL. + @retval EFI_UNSUPPORTED Attributes is unsupported. The only lega= l attribute bits are + MEMORY_WRITE_COMBINE, MEMORY_CACHED, and= DUAL_ADDRESS_CYCLE. + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoAllocateBuffer ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT VOID **HostAddress, + IN UINT64 Attributes + ); + +/** + Frees memory that was allocated with AllocateBuffer(). + + The FreeBuffer() function frees memory that was allocated with Allocate= Buffer(). + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Pages The number of pages to free. + @param HostAddress The base system memory address of the allocated rang= e. + + @retval EFI_SUCCESS The requested memory pages were freed. + @retval EFI_INVALID_PARAMETER The memory range specified by HostAddres= s and Pages + was not allocated with AllocateBuffer(). + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoFreeBuffer ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN UINTN Pages, + OUT VOID *HostAddress + ); + +/** + Flushes all PCI posted write transactions from a PCI host bridge to sys= tem memory. + + The Flush() function flushes any PCI posted write transactions from a P= CI host bridge to system + memory. Posted write transactions are generated by PCI bus masters when= they perform write + transactions to target addresses in system memory. + This function does not flush posted write transactions from any PCI bri= dges. A PCI controller + specific action must be taken to guarantee that the posted write transa= ctions have been flushed from + the PCI controller and from all the PCI bridges into the PCI host bridg= e. This is typically done with + a PCI read transaction from the PCI controller prior to calling Flush(). + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + + @retval EFI_SUCCESS The PCI posted write transactions were flush= ed from the PCI host + bridge to system memory. + @retval EFI_DEVICE_ERROR The PCI posted write transactions were not f= lushed from the PCI + host bridge due to a hardware error. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoFlush ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This + ); + +/** + Gets the attributes that a PCI root bridge supports setting with SetAtt= ributes(), and the + attributes that a PCI root bridge is currently using. + + The GetAttributes() function returns the mask of attributes that this P= CI root bridge supports + and the mask of attributes that the PCI root bridge is currently using. + + @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. + @param Supported A pointer to the mask of attributes that this PCI ro= ot bridge + supports setting with SetAttributes(). + @param Attributes A pointer to the mask of attributes that this PCI ro= ot bridge is + currently using. + + @retval EFI_SUCCESS If Supports is not NULL, then the attrib= utes that the PCI root + bridge supports is returned in Supports.= If Attributes is + not NULL, then the attributes that the P= CI root bridge is currently + using is returned in Attributes. + @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL. + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoGetAttributes ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + OUT UINT64 *Supported, + OUT UINT64 *Attributes + ); + +/** + Sets attributes for a resource range on a PCI root bridge. + + The SetAttributes() function sets the attributes specified in Attribute= s for the PCI root + bridge on the resource range specified by ResourceBase and ResourceLeng= th. Since the + granularity of setting these attributes may vary from resource type to = resource type, and from + platform to platform, the actual resource range and the one passed in b= y the caller may differ. As a + result, this function may set the attributes specified by Attributes on= a larger resource range + than the caller requested. The actual range is returned in ResourceBase= and + ResourceLength. The caller is responsible for verifying that the actual= range for which the + attributes were set is acceptable. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_I= O_PROTOCOL. + @param[in] Attributes The mask of attributes to set. If the = attribute bit + MEMORY_WRITE_COMBINE, MEMORY_CACHED, or + MEMORY_DISABLE is set, then the resour= ce range is specified by + ResourceBase and ResourceLength. If + MEMORY_WRITE_COMBINE, MEMORY_CACHED, a= nd + MEMORY_DISABLE are not set, then Resou= rceBase and + ResourceLength are ignored, and may be= NULL. + @param[in, out] ResourceBase A pointer to the base address of the r= esource range to be modified + by the attributes specified by Attribu= tes. + @param[in, out] ResourceLength A pointer to the length of the resourc= e range to be modified by the + attributes specified by Attributes. + + @retval EFI_SUCCESS The current configuration of this PCI root bri= dge was returned in Resources. + @retval EFI_UNSUPPORTED The current configuration of this PCI root bri= dge could not be retrieved. + @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_I= O_PROTOCOL + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoSetAttributes ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN UINT64 Attributes, + IN OUT UINT64 *ResourceBase, + IN OUT UINT64 *ResourceLength + ); + +/** + Retrieves the current resource settings of this PCI root bridge in the = form of a set of ACPI 2.0 + resource descriptors. + + There are only two resource descriptor types from the ACPI Specificatio= n that may be used to + describe the current resources allocated to a PCI root bridge. These ar= e the QWORD Address + Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.= 0 Section 6.4.2.8). The + QWORD Address Space Descriptor can describe memory, I/O, and bus number= ranges for dynamic + or fixed resources. The configuration of a PCI root bridge is described= with one or more QWORD + Address Space Descriptors followed by an End Tag. + + @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOC= OL. + @param[out] Resources A pointer to the ACPI 2.0 resource descriptors= that describe the + current configuration of this PCI root bridge.= The storage for the + ACPI 2.0 resource descriptors is allocated by = this function. The + caller must treat the return buffer as read-on= ly data, and the buffer + must not be freed by the caller. + + @retval EFI_SUCCESS The current configuration of this PCI root bri= dge was returned in Resources. + @retval EFI_UNSUPPORTED The current configuration of this PCI root bri= dge could not be retrieved. + @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_I= O_PROTOCOL + +**/ +EFI_STATUS +EFIAPI +RootBridgeIoConfiguration ( + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + OUT VOID **Resources + ); + +// Structure for PCI region +typedef struct { + PciAddrT BusStart; // Start on the bus + PhysAddrT PhysStart; // Start in physical address space + PciSizeT Size; // Size + UINT64 Flags; // Resource flags + PciAddrT BusLower; +} PciRegion; + +// Structure for PCI space(I/O,Mem,Configuration) +typedef struct { + UINT64 Regs; + INT32 PciNum; + UINT64 Cfg0Phys; + UINT64 Cfg0Size; + UINT64 Cfg1Phys; + UINT64 Cfg1Size; + UINT64 MemBus; + UINT64 MemPhys; + UINT64 MemSize; + UINT64 IoBus; + UINT64 IoPhys; + UINT64 IoSize; +} LsPcieInfo; + +typedef struct { + INTN Idx; + VOID *Dbi; + UINT32 *VaCfg0; + UINT32 *VaCfg1; +} LsPcie; + +typedef struct { + UINTN Vendor, Device; // Vendor and device ID or PCI_ANY_ID +} PciDeviceId; + +typedef struct { + UINTN Vendor, Device; // Vendor and device ID or PCI_ANY_ID + UINTN Class; // Class ID, or PCI_ANY_ID + UINTN Bus; // Bus number, or PCI_ANY_ID + UINTN Dev; // Device number, or PCI_ANY_ID + UINTN Func; // Function number, or PCI_ANY_ID + UINTN Priv[3]; +} PciConfigTable; + +#define ACPI_SPECFLAG_PREFETCHABLE 0x06 +#define EFI_RESOURCE_NONEXISTENT 0xFFFFFFFFFFFFFFFFULL +#define EFI_RESOURCE_LESS 0xFFFFFFFFFFFFFFFEULL + +typedef struct { + ACPI_HID_DEVICE_PATH AcpiDevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH; + +typedef enum { + ResTypeIo =3D 0, + ResTypeMem32, + ResTypePMem32, + ResTypeMem64, + ResTypePMem64, + ResTypeMax +} PCI_RESOURCE_TYPE; + +typedef struct { + UINT64 Base; + UINT64 Length; + UINT64 Alignment; +} PCI_RESOURCE_ALLOC; + +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + EFI_HANDLE Handle; + UINT64 RootBridgeAttrib; + UINT64 Attributes; + UINT64 Supports; + UINTN BusStart; + UINTN BusLength; + UINT64 MemAllocAttributes; + PCI_RESOURCE_ALLOC ResAlloc[ResTypeMax]; + UINT64 PciBaseAddress64; + UINT64 PciMemBase64; + LsPcieInfo *Info; + LsPcie *Pcie; + struct PCI_ROOT_BRIDGE_INSTANCE *Next; + INTN FirstBusno; + INTN LastBusno; + INTN CurrentBusno; + UINTN *CfgAddr; + CHAR8 *CfgData; + INTN IndirectType; + PciRegion Regions[MAX_PCI_REGIONS]; + INTN RegionCnt; + PciConfigTable *ConfigTable; + + PciRegion *PciMem, *PciIo, *PciPrefetch; + + EFI_PCI_ROOT_BRIDGE_DEVICE_PATH DevicePath; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL Io; + +} PCI_ROOT_BRIDGE_INSTANCE; + +#endif --=20 1.9.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Fri May 3 07:57:59 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1513925438690994.15931385454; Thu, 21 Dec 2017 22:50:38 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 14737222CB319; Thu, 21 Dec 2017 22:45:47 -0800 (PST) Received: from NAM02-SN1-obe.outbound.protection.outlook.com (mail-sn1nam02on0070.outbound.protection.outlook.com [104.47.36.70]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 31939222CB318 for ; Thu, 21 Dec 2017 22:45:45 -0800 (PST) Received: from BN6PR03CA0021.namprd03.prod.outlook.com (10.168.230.159) by CO2PR03MB2360.namprd03.prod.outlook.com (10.166.93.20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.345.14; Fri, 22 Dec 2017 06:50:33 +0000 Received: from BN1AFFO11OLC003.protection.gbl (2a01:111:f400:7c10::198) by BN6PR03CA0021.outlook.office365.com (2603:10b6:404:23::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.345.14 via Frontend Transport; Fri, 22 Dec 2017 06:50:32 +0000 Received: from tx30smr01.am.freescale.net (192.88.168.50) by BN1AFFO11OLC003.mail.protection.outlook.com (10.58.53.74) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.20.302.6 via Frontend Transport; Fri, 22 Dec 2017 06:50:18 +0000 Received: from uefi-OptiPlex-790.ap.freescale.net ([10.232.132.56]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id vBM6oHF4022495; Thu, 21 Dec 2017 23:50:28 -0700 X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=104.47.36.70; helo=nam02-sn1-obe.outbound.protection.outlook.com; envelope-from=vabhav.sharma@nxp.com; receiver=edk2-devel@lists.01.org Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=nxp.com; nxp.com; dkim=none (message not signed) header.d=none;nxp.com; dmarc=fail action=none header.from=nxp.com; Received-SPF: Fail (protection.outlook.com: domain of nxp.com does not designate 192.88.168.50 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.168.50; helo=tx30smr01.am.freescale.net; From: Vabhav To: , , , Date: Fri, 22 Dec 2017 00:18:29 +0530 Message-ID: <1513882109-14295-4-git-send-email-vabhav.sharma@nxp.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1513882109-14295-1-git-send-email-vabhav.sharma@nxp.com> References: <1513882109-14295-1-git-send-email-vabhav.sharma@nxp.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131583990184051277; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(7966004)(336005)(396003)(346002)(39860400002)(39380400002)(376002)(2980300002)(1110001)(1109001)(339900001)(189003)(199004)(356003)(5660300001)(8936002)(68736007)(77096006)(59450400001)(305945005)(50226002)(86362001)(106466001)(53936002)(2950100002)(85426001)(36756003)(105606002)(2201001)(97736004)(8656006)(54906003)(110136005)(316002)(16586007)(2906002)(498600001)(4326008)(51416003)(76176011)(104016004)(50466002)(47776003)(81156014)(8676002)(48376002)(81166006)(142933001)(19627235001); DIR:OUT; SFP:1101; SCL:1; SRVR:CO2PR03MB2360; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BN1AFFO11OLC003; 1:0h0WS3KuKWwkeglTZzW+ZpxxhBEwAqX6DRVF05tVqEwHSJLScZSlPQhxHUwH0btk7Z+4QgsopQcZQxggvlmGLVZSx3CNyT91xZ5hujTjEznIk+TGy1KYpie4O9WJDkob MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 1265f373-aa3a-4528-824d-08d549084383 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(4534020)(4628075)(201703131517081)(5600026)(4604075)(2017052603307); SRVR:CO2PR03MB2360; X-Microsoft-Exchange-Diagnostics: 1; CO2PR03MB2360; 3:iLjcSJ+GVnT/4uQaf5lcAC8QRuW4NIXF40LnoRnM7ogoVjQ5kpGAoe+i23c+KyVBY+GaCp1kRlIzg+1oO2BsQfaQnNyOTYVvPp9S9Y4EiCV0AlMZIeLG/eDXLQAx9Q2ny4GV3Ocui2RAOjC2Vg1ADlOPCpneHh34/CKV3PFlkFwtVblgSp/qnuQqAKH3DaHoCYbLFEPmeyD+DhCpE/0RfhmvywsRl5DklcxhAwK7W8++bG8UyZBdKn0NzujQA3DaAg1EJBG22oOvk8zyibC3ZablxADI7nm4EfOw2YIaqh3WFTvhqCs+vbU4uO9AQ4OlEfFsO9gXpHIyHid+6przgx50asdEjr+BQAXYqewmRuc=; 25:/3GEwN18iPJXruwUk5UCAkdpLrvwpF1hrSpdYBFNxjvOoMcxJFb37H4gfcBCxqm7TbQ0A8nJ8TqSSJoY5YRbhPBV7Hw0WNj4fUKMtdXKeP/8agm174wqpMsjjMkIcEGh2uVmtx8hOTcJ7/gAsF9MopHTStxJmEnppIcgnqZoQHh+9/uemud8ELu9LqbXGFs/bW4kFy0Ik9wTB7JRUkQGjuUKDUcK0oOQBelCW4kjLl+jMC3mxMsOr272EvOKw7HtaxKlXO8+1Tm9Opjcrg/MaGrWyEGUMPZAwmrYY1BR1I3/qj3fWUsAYdzkuQ5ogzGQuHr++xAwGL9YgpJooLWrog== X-MS-TrafficTypeDiagnostic: CO2PR03MB2360: X-Microsoft-Exchange-Diagnostics: 1; CO2PR03MB2360; 31:R3/K/PNHwN78qAHKGjs+ginYQBdRideOBtnYonAK5F3ZxMEchQ1vSDB8+FkGj3VjqzZmYINIRp8PBMEeQDQ1BWi7aWD5JVdTZGvuV69kqpsw+ZkfrqYAHkLRZDOPBcDm1IcnmIhE6kXwmZvEYdm/686SfVPnEYgDsRJltpkWXLm9KIMjEZwPCjAyafcwZNUl5ar1iaHNY5KY4P4P/CmIHnIXxkL0qBsXZM8bc14JoRM=; 4:Vw7cFW2T1ikIX6MF9gf2njN9y49H+n7ET6gqDBibJHYYSVBQxDiVks5uTHv8qVPXqJY33CFD+/9p9CS57XwnTUZ1LPkZyR8YiR/AXD1PGUfCgMCMdOAW2t1qf1/FyEPRJX5cj5Mp51yOjTmOJoumz0RWGxvsZfa1xkJXwa/YkumR/PfvZfxmQhUanqLcdyZ3asQH+OfOtcu0pzSqka+KQWE5E2w9vXaXj8IOpaD+bvENGd8L7xVut0ALhMgn7pp1zZYyTnSgTxYGWdIAEeNljikyooK68JJccAC8JZrJpemyhFGvNLCVE/qtHTADjTKW X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6095135)(2401047)(8121501046)(5005006)(3002001)(93006095)(93001095)(10201501046)(3231023)(6055026)(6096035)(20161123559100)(20161123556025)(201703131430075)(201703131433075)(201703131441075)(201703131448075)(201703161259150)(20161123565025)(20161123563025)(20161123561025)(201708071742011); SRVR:CO2PR03MB2360; BCL:0; PCL:0; RULEID:(100000803101)(100110400095)(400006); SRVR:CO2PR03MB2360; X-Forefront-PRVS: 05299D545B X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CO2PR03MB2360; 23:PabqmKqYqAyGIgtchTYqit3b7Wn4YVBs/mCFcKBba?= =?us-ascii?Q?kVda5Tng5MQFerM3VJdlpgrfKpVTN2/0krrKB7j6uT8zEtKUIY5SHo3kBf8o?= =?us-ascii?Q?YpmVA2t64WwbbwB4C8iFOOK3bdaY02sdEOrNwxZ8x91dkdZwAlbclhsZLmGU?= =?us-ascii?Q?txosJ7sXX/87xb8Wv6vrAj5sDyrOH7hrFP58PDiYZyIRHhAQ+QhCFQlIeIaf?= =?us-ascii?Q?eOZ7VWUFnJbNrH4Hf+ZdwuE6ly/ZLV6Y7Kw7EvwP8JPC1YxxN6dAdHJcbeQv?= =?us-ascii?Q?dcsH2BrvIXLN04Bjs5CTlv9JQ3X6BcY284tRR6G/YBzrYOYsnYbCYpaRg7h5?= =?us-ascii?Q?hS4DKPQmnXx2h25HoCEIsDz+95/j4nqNCU07gXyh3+k7Y0CTj2K+GjC3IJdr?= =?us-ascii?Q?a6gGiCdF8x8vPv4AAt2oxwuOJ8Mmlw1PPQ3ojlIujla4jIKY3UCeru9BSrN7?= =?us-ascii?Q?EHtsS/VNfOplMSjPic89CTQEkfRJcfaT72+R5Zrqenut3fDCAAmGEAG+Cc85?= =?us-ascii?Q?sQoI1tCziUZIQtKQSiI7Inmk6OC5oKAFp7u2owqSqqR7KeHooBSOrHbkhm83?= =?us-ascii?Q?bLBVlLIUIW4XJoU7CyxPnTa7c2tCXTdNinLoZYTmOt3EOKAAOV8PKFF/xGMg?= =?us-ascii?Q?pFKNKjtImtx29JDBc5j7xbW9gVpa7DmysXzP1K27NjqakCQjJoGTspfaqm5N?= =?us-ascii?Q?Tg/Wli2inLf9aPnQ2it7nk4iw+jFtsJuNVoK+/RthWVF87eLY69f8HtI/TRV?= =?us-ascii?Q?Fmxi67ckS7J98T+Hs4ansg6/OdnNPpc27uXmgZw7j3VmaYNNYgUILPJXb6Pr?= =?us-ascii?Q?HT5VlR2cDKQuK7DQ1X+2NRRAOFdxXGXL6Rf6OEA6wnfDvYNXD7to0K2btCJd?= =?us-ascii?Q?NEbaDoL8VsprsckHaSksgtMwNqZYUzmba5BeWIzufcU4gJxEtadPlR/pqdMi?= =?us-ascii?Q?ibuVF/cmfknUzyOOcLuoLyEekuLFBc4vLkdZ7fDRfGg3aohb8PGIHijRZrPA?= =?us-ascii?Q?uew+BY3GJFV40gJZvJltDK3pHJ3KQCKvVaQNlfAiDxiiG00ClFXF/GUFRLEG?= =?us-ascii?Q?GPDCkX2z2WE73Mf42i2KK76V+/FNeYsPIHsVTiAPHWvWa+JC59/PzLkxKDWO?= =?us-ascii?Q?aJfAzTKXyU5vQPi6eAYe9fVIPGbiPutNSeVIVt8umwUjtXuQg1CCg=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; CO2PR03MB2360; 6:EHPRPWgug2jdUADIoMRglOEC6gjom4JmosAQZL27dqMo60INEEYSaxla3K5NM8OvRN0Zj1aI3Lw8gueTX8+cCJpu2HSBtQADwMbaFqhzExt+Fcr+88g2mBSIAcj2ZFoaRWtLLg9g1+Fjh3EsC9Af7VXyinmLqnFvthJ8+V1x5oe8UTUFaphqgcEJVY40qMp3BvgfyMZgiXoyVbdkl/wq1zhNofgfAZ+DiNY/OJSCsCKVrhzGcnhwHDjX8L4bNlOWRXgXxNVRAxWJNEWrVOdwP69cTrhm7Hf2L4aBHock4GNjCDef1c1Ln9FyMqYW9ER2vRlMd35JzZgEkq6UN1SimwI8hdkkfM4i7JwWkrM1VIQ=; 5:0W5msubzCSwfupt4j276V+1xfXxqQxJczCxzBaSSeaqJJiRPCnFtBQ9XKKzOjTx7w2T11f9h6lBM15o2Ppb8X4KkH7YiL1mV0jlLL0uMr1JWGbD7/Hc+XpCceqeZ8v6pSybnGh5ZR6DEitqROcHvsRAMF4NVh6swLt8gaDCnq9I=; 24:/wbG7Tl+uibKe/jXlQBihxdm2vCasp/+DTZsfoHMcm7s02Sd4gH53YI8Eaa9gboO+NpRa7xKpbukHur255ZV1vMm0+N76WuMZP/rRSmVqy4=; 7:kFwXjEE8gPE/iIdVrAhhquMWIfR9bY9XUZTP9g9SaH/3caFsToV2LD680/pSuMd+kbrnEyXCxxTHMbBA5BQNnxE9DO+rL5weyO2QmmH98v4x/SKmru2Qk7iMFh3VhIOLQnn4H2slbhuBFnCX96YXJBbohLoRDGqKEgPzu/XFJaEQP/NDUgdGoH5/DW9y+8LtyJrPxThE+V27uzPq90OJJ3rHIO22d8Op9kNTEpaK1mchup1L+nVWoQbaPk3KxsKH SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Dec 2017 06:50:18.2491 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 1265f373-aa3a-4528-824d-08d549084383 X-MS-Exchange-CrossTenant-Id: 5afe0b00-7697-4969-b663-5eab37d5f47e X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e; Ip=[192.88.168.50]; Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO2PR03MB2360 Subject: [edk2] [PATCH edk2-platforms 3/3] Compilation:Modify dsc, fdf files 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: , Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Enabling support for compilation of PciHost Bridge Library, PciHostBridge Dxe Driver and include respective serdes functions Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Vabhav --- Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc | 31 ++++++++++++++++++++++++= ++++ Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf | 6 ++++++ Silicon/NXP/Chassis/Chassis.c | 11 ++++++++++ Silicon/NXP/Chassis/Chassis2/SerDes.h | 11 ++++++++++ Silicon/NXP/LS1043A/LS1043A.dsc | 1 + 5 files changed, 60 insertions(+) diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc b/Platform/NXP/LS= 1043aRdbPkg/LS1043aRdbPkg.dsc index 7ea791e..21f451f 100644 --- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc +++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.dsc @@ -54,6 +54,11 @@ # MmcLib|edk2-platforms/Platform/NXP/Library/MmcLib/MmcLib.inf =20 + # + # Pci Library + # + PciHostBridgeLib|edk2-platforms/Platform/NXP/Library/PciHostBridgeLib/Pc= iHostBridgeLib.inf + [PcdsFixedAtBuild.common] =20 # @@ -70,6 +75,7 @@ gNxpQoriqLsTokenSpaceGuid.PcdWdogBigEndian|TRUE gNxpQoriqLsTokenSpaceGuid.PcdMmcBigEndian|TRUE gNxpQoriqLsTokenSpaceGuid.PcdIfcBigEndian|TRUE + gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian|TRUE =20 # # NV Storage PCDs. @@ -79,6 +85,25 @@ gNxpQoriqLsTokenSpaceGuid.PcdFlashReservedRegionBase64|0x60300000 =20 # + # PCIe Pcds + # + gNxpQoriqLsTokenSpaceGuid.PcdPciExp1SysAddr|0x03400000 + gNxpQoriqLsTokenSpaceGuid.PcdPciExp2SysAddr|0x03500000 + gNxpQoriqLsTokenSpaceGuid.PcdPciExp3SysAddr|0x03600000 + gNxpQoriqLsTokenSpaceGuid.PcdKludgeMapPciMmioAsCached|FALSE + gNxpQoriqLsTokenSpaceGuid.PcdPciMaxPayloadFixup|FALSE + gNxpQoriqLsTokenSpaceGuid.PcdPciBusMin|0 + gNxpQoriqLsTokenSpaceGuid.PcdPciBusMax|255 + gNxpQoriqLsTokenSpaceGuid.PcdPci1Mmio64Base|0x4040000000 + gNxpQoriqLsTokenSpaceGuid.PcdPci2Mmio64Base|0x4840000000 + gNxpQoriqLsTokenSpaceGuid.PcdPci3Mmio64Base|0x5040000000 + gNxpQoriqLsTokenSpaceGuid.PcdPciMmio64Size|0x0040000000 + gNxpQoriqLsTokenSpaceGuid.PcdPciDebug|FALSE + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutBase|0x10000 + gNxpQoriqLsTokenSpaceGuid.PcdPcieLutDbg|0x7FC + gNxpQoriqLsTokenSpaceGuid.PcdPciMemOneTransaction|0x10000000 + + # # I2C controller Pcds # gNxpQoriqLsTokenSpaceGuid.PcdI2cBus|0 @@ -109,4 +134,10 @@ EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf edk2-platforms/Platform/NXP/Drivers/MmcHostDxe/MmcHostDxe.inf =20 + # + # PCI + # + MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf + edk2-platforms/Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDxe.inf + ## diff --git a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf b/Platform/NXP/LS= 1043aRdbPkg/LS1043aRdbPkg.fdf index 023480b..d462ae2 100644 --- a/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf +++ b/Platform/NXP/LS1043aRdbPkg/LS1043aRdbPkg.fdf @@ -127,6 +127,12 @@ READ_LOCK_STATUS =3D TRUE INF edk2-platforms/Platform/NXP/Drivers/NorFlashDxe/NorFlashDxe.inf =20 # + # PCI + # + INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf + INF edk2-platforms/Platform/NXP/Drivers/PciHostBridgeDxe/PciHostBridgeDx= e.inf + + # # Network modules # INF MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf diff --git a/Silicon/NXP/Chassis/Chassis.c b/Silicon/NXP/Chassis/Chassis.c index a6a77c2..2a7ecbc 100644 --- a/Silicon/NXP/Chassis/Chassis.c +++ b/Silicon/NXP/Chassis/Chassis.c @@ -411,3 +411,14 @@ CalculateI2cClockRate ( =20 return SocSysInfo.FreqSystemBus; } + +/** + Return PCI address space mask +**/ +UINT64 +GetPciAddressSpaceMask ( + IN VOID + ) +{ + return MAX_UINT32; +} diff --git a/Silicon/NXP/Chassis/Chassis2/SerDes.h b/Silicon/NXP/Chassis/Ch= assis2/SerDes.h index 9fc60d3..fb2e728 100644 --- a/Silicon/NXP/Chassis/Chassis2/SerDes.h +++ b/Silicon/NXP/Chassis/Chassis2/SerDes.h @@ -66,4 +66,15 @@ SerDesProbeLanes( IN VOID *Arg ); =20 +VOID +GetSerdesProtocolMaps( + OUT UINT64 *SerDes1ProtocolMapPtr +); + +BOOLEAN +IsSerDesLaneProtocolConfigured( + IN UINT64 SerDes1ProtocolMap, + IN SERDES_PROTOCOL Device +); + #endif /* __SERDES_H */ diff --git a/Silicon/NXP/LS1043A/LS1043A.dsc b/Silicon/NXP/LS1043A/LS1043A.= dsc index 024c09a..22cea54 100644 --- a/Silicon/NXP/LS1043A/LS1043A.dsc +++ b/Silicon/NXP/LS1043A/LS1043A.dsc @@ -76,5 +76,6 @@ gNxpQoriqLsTokenSpaceGuid.PcdI2c2BaseAddr|0x021A0000 gNxpQoriqLsTokenSpaceGuid.PcdI2c3BaseAddr|0x021B0000 gNxpQoriqLsTokenSpaceGuid.PcdNumI2cController|4 + gNxpQoriqLsTokenSpaceGuid.PcdNumPciController|3 =20 ## --=20 1.9.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel