From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM11-BN8-obe.outbound.protection.outlook.com (NAM11-BN8-obe.outbound.protection.outlook.com [40.107.236.95]) by mx.groups.io with SMTP id smtpd.web10.1543.1637242453679666757 for ; Thu, 18 Nov 2021 05:34:14 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@os.amperecomputing.com header.s=selector2 header.b=lmtu3TXM; spf=pass (domain: os.amperecomputing.com, ip: 40.107.236.95, mailfrom: nhi@os.amperecomputing.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=c4Zc6CBbsJqtI8nYDcbIZqBvyWY/sgzxIuiC4W1wZqSdVSCRg4k3zqoA85n2+gJchhKT9Rh4z+xyvCAolxDv+bOO6YjmvdDXU+6rY1HKmWaFd3bmuBoZ6F58bs5ypm4HUOggpGDAr4gHy4umMLFEPt49mM6SittYnLIn3shSyloYwS58dWJ22lX9Aax31GiJyg1vboJ0AWFbFzhLtSUFDvHUDaHk5yTtaFGqiI1MIIynWYsN3tu6oJ/d4tzN4jTKIUmO3PtNAWaw6vSz/3rjw6km2WMF8VD9sQ4589adC77IckHYjB66l96JYEQVe0LlEv3heZtf0SH9wcmdDTTbsw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=PlAs+1bkto9Zuj0x1oeyHAirKKEKkMNTqWiliXAETuI=; b=KINIomWLKjdwO1TvO19GbTEVdWjl6JEqFmJv/Lni4F/u0FtqWFdZXCTOJgnhAwPopvHtn0tDbiDLorO2lN8r/uupUd7XZ2iAQL3v5IuLp8OE7SCenzDWu/FhPpo+nMGM2EmLLYrGy6nttZQ8tKuqS58yPD1YfUtepH5kEuK8n//Aw2CQhbXs8gqAeuHCri96PjizI8jKvj0V0dNZXk1k1qAHWGHlVE0p3t8bnqc99x+CCDoQnob5ASvYaBdlLwfNLm7tRaCCuVsxhNOH4nCk/NsKdGyasyRxY49buHQdjxKlt1RJLDXftxpDHUqMDFmx0JM+Y/PUcZmAUPlaGCwO5g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=os.amperecomputing.com; dmarc=pass action=none header.from=os.amperecomputing.com; dkim=pass header.d=os.amperecomputing.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=os.amperecomputing.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=PlAs+1bkto9Zuj0x1oeyHAirKKEKkMNTqWiliXAETuI=; b=lmtu3TXMuIjAQNTEyMBlZBSq5rkGq8+MTzOQdU2jqzMOl/glpFhJwiX4Srpfgi53T9dU9XaBoSY8Kapy9AO/kTeq7N+yDnAdQO0/RqB4IxB1VsE0YhlXwwErfY3dpSvNjiNxmr3p6MU3Z9n6Msb0s2Uf2MS1VXWmlVabwr4t9LA= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=os.amperecomputing.com; Received: from PH0PR01MB7287.prod.exchangelabs.com (2603:10b6:510:10a::21) by PH0PR01MB6521.prod.exchangelabs.com (2603:10b6:510:99::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4713.19; Thu, 18 Nov 2021 13:34:09 +0000 Received: from PH0PR01MB7287.prod.exchangelabs.com ([fe80::254c:9533:7f35:aee]) by PH0PR01MB7287.prod.exchangelabs.com ([fe80::254c:9533:7f35:aee%4]) with mapi id 15.20.4713.019; Thu, 18 Nov 2021 13:34:09 +0000 Message-ID: Date: Thu, 18 Nov 2021 20:33:57 +0700 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Thunderbird/91.3.1 Subject: Re: [edk2-platforms][PATCH v5 11/30] AmpereAltraPkg: Add Ac01PcieLib library instance To: Leif Lindholm CC: devel@edk2.groups.io, patches@amperecomputing.com, vunguyen@os.amperecomputing.com, Thang Nguyen , Chuong Tran , Phong Vo , Michael D Kinney , Ard Biesheuvel , Nate DeSimone References: <20211117164727.10922-1-nhi@os.amperecomputing.com> <20211117164727.10922-12-nhi@os.amperecomputing.com> From: "Nhi Pham" In-Reply-To: X-ClientProxiedBy: HK2PR0401CA0012.apcprd04.prod.outlook.com (2603:1096:202:2::22) To PH0PR01MB7287.prod.exchangelabs.com (2603:10b6:510:10a::21) Return-Path: nhi@os.amperecomputing.com MIME-Version: 1.0 Received: from [192.168.1.4] (113.170.183.52) by HK2PR0401CA0012.apcprd04.prod.outlook.com (2603:1096:202:2::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4713.21 via Frontend Transport; Thu, 18 Nov 2021 13:34:05 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ffba308d-3e68-4842-da58-08d9aa981916 X-MS-TrafficTypeDiagnostic: PH0PR01MB6521: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:8882; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: eCLVpu6fe85E/YEypBkHh0/QvNxN1/8X8dIlnqnOf65vyzUPc5DlzOLN8y3VVeFmNqbH03ww5C08S8Q/0L584oSbCR3RE2B6we1xkKzg2pMaBok+RW7HJOH49Tkf1XaY/yf4j4iRK/N2rrdWrctxD/pGmkS3F5JRHGUwZ5ordCKyWGNvod6618mnZtHrquZAR5T7Mh1JVZWsXmSxIEC2szlmmRNR+glrKNnbYD5BxM6BQfK1uJyKoXPDDZaXEqsUarsARZAc1zNzkH8NBD9J9I1H24lG9XXh3Nn/Hpq6g+6A3sY06+jbasN4p3OHSVqpKhaVL10VE6aTTOjvFecTypzHURYJP8EEW53+7RRc9tyWB1fLUtG1K9vEDCHPRJsqsVG3qi+QJJD5TGOWMhsLTGiS9TJTkR+QV4/8BjxjGPT17qGXxnWdijMOPKOGTZMWEQarhF3ILFl4Z6YTWXMU81jTfYhI4HFWwdSAnE1HLgx0bL7WUZats5nrhh6x8fuHYZqnHbf6Rq04vDs7VZMvo+Gr2YhP1lFI+NQCS4MLfFJCa1+ycvzZClbK/Z2OoC5H/4+eMCjzYUB8qMKRoaL3ELIugYKEcC9Xl/7ziqxpBsV42n/m1Cq8pWdA5/sjan7GjaOT1FNI/XqGfMzzjtNgYyRd1D1/A0y7KzDLVF8ILPmNUBmR+EgCtMTaQWIBgW1+pUt5pOtpT35OW+/PoJAwzDdA93nHeTaqZRCpRBtfc3dL9zTk4w4vQpLuKneVqThC43UOYVhxYd5U0e9S5TPzLlmmKvat9zsEqk5so8RjQuQ= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH0PR01MB7287.prod.exchangelabs.com;PTR:;CAT:NONE;SFS:(4636009)(366004)(6916009)(26005)(31686004)(186003)(6486002)(2616005)(956004)(30864003)(38100700002)(31696002)(316002)(53546011)(54906003)(16576012)(8676002)(19627235002)(5660300002)(86362001)(4326008)(66556008)(8936002)(508600001)(66476007)(2906002)(66946007)(38350700002)(6666004)(83380400001)(52116002)(9186005)(43740500002)(45980500001)(579004)(559001);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?CeapukRicQu6yJ6fIFMmRoTteMDjFUhpX65Gi07COnpyrF9erx4+1r+hgYN6?= =?us-ascii?Q?buh1yWTHRRQ5NiSEhBSt3GuxEZ7FfXsqrC/e06NDCDM95e1+lE5KdO/Q7/eD?= =?us-ascii?Q?ZPax2BBU9PcKJ9V4b4I0lOy5uvK5K4ececjyTXnQibi71PzgEx1lyoFklHB8?= =?us-ascii?Q?X4F/axAuRgvz+INVTGsFt9sC3NJMdak9Im2PbT3bOY7F66+ncTgOiIq2UtKt?= =?us-ascii?Q?yCLlbXTv/BtuhwNPBZ1xyHhiDXe5QIKVRbvMxT1lkYwWqPa9uTOXgA6dTDtv?= =?us-ascii?Q?9j4qRzWml2Jthmcp//Ix9EKyNKCpX78klCmN6jvJCpT63fsJ1ebEFrX9vmSQ?= =?us-ascii?Q?PJLpH6rmlIVF+cm740/qkwUkdr06wgua3nQ/wiTZlqG3ew8gjM9T9BkXSRwF?= =?us-ascii?Q?iBvvlyKKqzWXfdRjmeGZR56jRvRSSbXiC29FqgGyFZJ6Kv57EI+A9nO5Yz5T?= =?us-ascii?Q?0CzqOuf9lEnsNDTXnhyFQ2bJYPvDdhWwwbvDc25L5f/W+d6EKsolQzQws7h0?= =?us-ascii?Q?VpPsSB5TFSfSFPaPmsw3MpIFPXmHvbg1ZfnyW/FH8Y0uXDQKS/5lIYvl91sT?= =?us-ascii?Q?/wJrTwIWTODIO8dGKKOXOYHdCHSIr6x3ydsgskM5JiLKNpBsPS9Bjq5jU3lV?= =?us-ascii?Q?zn4kJFFa06FCeQZXe1mw2AiBcMBuBmgJ6cqXNcgX7PBttmw8VQrXEu1JZu+I?= =?us-ascii?Q?q/0rDJA2GrUQRTNdtRCSSYZc13ob+y9s8n4syreAWHGcDTTTAgxlYtCob4iT?= =?us-ascii?Q?Kx+qy0zXb7iWabSBFZYMSvgWwwGyJ/1ibVvih5GY5kx+SsUDdYfoU+l+Fcym?= =?us-ascii?Q?17rBHjl5aw2kYo5UCJZjb/XPEN4KFNFEfEyzY8z6t+Xwx0Hc5QItzLbTlUBi?= =?us-ascii?Q?XHK9sLobVLwCTJWaHY1xnFB6TSW1zWHp7q1gCKnLvvuGiuTG8wwOOjY0Km3i?= =?us-ascii?Q?3DhXB9GGGw/TSV7uCr+tq65Eg5RbuY76TV350IPq1hsTJ7HR7Zh2ZJhrI98a?= =?us-ascii?Q?G7U0ixTCxd4hULFGIcZ3EuKH0AKnIZjfwL/BBqOaJ8/ZWKCSzyIsIT4WU/uV?= =?us-ascii?Q?J6mWR3XxMu5rnonaGwMixdhy/zcpk8wuwbvXRLsi18oW12y/ZbYHrjFG0SjQ?= =?us-ascii?Q?3hEa5HKA9DboTPJezkaLkA4mVDqZyBZDWBPReU2kB7SE/eTgcrAVqa847XY6?= =?us-ascii?Q?q9Zg+6Y2QNTPGI3p49CAMMyec7rKknUWJ32F4pMnbXAKh+zTVVNOGn9TOIcU?= =?us-ascii?Q?5Vu+NxhhdOV4Fk80Mg1T0kjKrLEF4LXThzjrXxHIbJz474Mg1PA9y3gp60Dq?= =?us-ascii?Q?7+8tdo8seSFZCViIeZgSaejzNWpcB0fW/Q09ILE+bHoNBRCCzzMwUIPfUyT8?= =?us-ascii?Q?Ojd0RciIH4ObD+I/9pZNUUGLRL8y9Gpdmj/dbIFIdzz8w7QG/JsNLvmdTnp8?= =?us-ascii?Q?cLhMRnZb8DoF0LwQXkhK6cJ7wdRsU9wy9fB1V3rQhl+EPqszXgTBkepKKs8E?= =?us-ascii?Q?kaqjxPnNBTeblhnmWlM4P9xLoeH/pAspQeXZOJkZuF2BqcosBDWzBlIDOLTo?= =?us-ascii?Q?0BY1TWzPXcGfsj95Lxdr3qAHu+/AoFkZzq/ddajQDjkQ910nP9ASoKf9cqwc?= =?us-ascii?Q?lLtETk5b0xgrqTsoYWTt9vUALAaKLd6VYz2gKAan7Pne7LdFgBYCqfn6Vy1Z?= =?us-ascii?Q?Ek+Y0YA9rnnXaK6MLgbbHaWOYW0=3D?= X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: ffba308d-3e68-4842-da58-08d9aa981916 X-MS-Exchange-CrossTenant-AuthSource: PH0PR01MB7287.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Nov 2021 13:34:08.8079 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3bc2b170-fd94-476d-b0ce-4229bdc904a7 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ngZioDDhiHk6qslegHAt6d3EDEBxqLOBICXepr2vtXrMD7zzaz8+QTkU6NofswjKy9oEbT3aWZG/yhS1L0AyVgUbO7mZwjw0s9SsmScdLiA= X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR01MB6521 Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable On 18/11/2021 19:33, Leif Lindholm wrote: > Hi Nhi, > > On Wed, Nov 17, 2021 at 23:47:08 +0700, Nhi Pham wrote: >> From: Vu Nguyen >> >> Provides essential functions to initialize the PCIe Root Complex on >> Ampere Altra processor. > The NOOPT build fails for me with > /work/git/edk2-platforms/Silicon/Ampere/AmpereAltraPkg/Library/Ac01PcieLi= b/PcieCore.c: > In function =E2=80=98Ac01PFACommand=E2=80=99: /work/git/edk2-platforms/Si= licon/Ampere/AmpereAltraPkg/Library/Ac01PcieLib/PcieCore.c:1024:26: > error: variable =E2=80=98CfgBase=E2=80=99 set but not used [-Werror=3Dunu= sed-but-set-variable] > 1024 | PHYSICAL_ADDRESS CfgBase; > | ^~~~~~~ > > I will have a look at 1-10/30 - in the mean time, could you fix this > along with anything else in later patches preventing a successful > NOOPT build? And then send out only updated versions of affected > patches (as v6), not the whole set. Thanks, Leif. I will fix and send shortly. > > In case your toolchain does not expose this bug, I'm using: > gcc version 10.2.1 20210110 (Debian 10.2.1-6) I see the compilation error now with gcc. Thank you. I used CLANG for=20 checking NOOPT. Best regards, Nhi > > Best Regards, > > Leif > >> Cc: Thang Nguyen >> Cc: Chuong Tran >> Cc: Phong Vo >> Cc: Leif Lindholm >> Cc: Michael D Kinney >> Cc: Ard Biesheuvel >> Cc: Nate DeSimone >> >> Signed-off-by: Nhi Pham >> --- >> Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec = | 6 + >> Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc = | 2 + >> Platform/Ampere/JadePkg/Jade.dsc = | 5 + >> Silicon/Ampere/AmpereAltraPkg/Library/Ac01PcieLib/Ac01PcieLib.inf = | 42 + >> Silicon/Ampere/AmpereAltraPkg/Library/BoardPcieLibNull/BoardPcieLibNul= l.inf | 25 + >> Silicon/Ampere/AmpereAltraPkg/Include/Library/Ac01PcieLib.h = | 49 + >> Silicon/Ampere/AmpereAltraPkg/Include/Library/BoardPcieLib.h = | 45 + >> Silicon/Ampere/AmpereAltraPkg/Library/Ac01PcieLib/PcieCore.h = | 372 +++++ >> Silicon/Ampere/AmpereAltraPkg/Library/Ac01PcieLib/PcieCore.c = | 1419 ++++++++++++++++++++ >> Silicon/Ampere/AmpereAltraPkg/Library/BoardPcieLibNull/BoardPcieLibNul= l.c | 47 + >> 10 files changed, 2012 insertions(+) >> >> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/= Ampere/AmpereAltraPkg/AmpereAltraPkg.dec >> index e19925c68a0e..7bd4d3ac9462 100644 >> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec >> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec >> @@ -43,6 +43,12 @@ [LibraryClasses] >> ## @libraryclass Defines a set of methods to access flash memory. >> FlashLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h >> =20 >> + ## @libraryclass Defines a set of platform dependent functions >> + BoardPcieLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/BoardPcieL= ib.h >> + >> + ## @libraryclass Defines a set of methods to initialize Pcie >> + Ac01PcieLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/Ac01PcieLib= .h >> + >> [Guids] >> ## NVParam MM GUID >> gNVParamMmGuid =3D { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x9= 3, 0x36, 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } } >> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Sili= con/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc >> index fa9b120b2c2b..5b767ecb024f 100644 >> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc >> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc >> @@ -81,6 +81,8 @@ [LibraryClasses.common] >> NVParamLib|Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamL= ib.inf >> MailboxInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/MailboxInt= erfaceLib/MailboxInterfaceLib.inf >> SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/Sys= temFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf >> + PciePhyLib|Silicon/Ampere/AmpereAltraBinPkg/Library/PciePhyLib/PciePh= yLib.inf >> + Ac01PcieLib|Silicon/Ampere/AmpereAltraPkg/Library/Ac01PcieLib/Ac01Pci= eLib.inf >> AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/Ampe= reCpuLib.inf >> TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf >> I2cLib|Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf >> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/= Jade.dsc >> index e4b29e36fc8d..23a297d0dbeb 100644 >> --- a/Platform/Ampere/JadePkg/Jade.dsc >> +++ b/Platform/Ampere/JadePkg/Jade.dsc >> @@ -82,6 +82,11 @@ [LibraryClasses] >> # >> AcpiLib|EmbeddedPkg/Library/AcpiLib/AcpiLib.inf >> =20 >> + # >> + # Pcie Board >> + # >> + BoardPcieLib|Silicon/Ampere/AmpereAltraPkg/Library/BoardPcieLibNull/B= oardPcieLibNull.inf >> + >> ######################################################################= ########## >> # >> # Specific Platform Pcds >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/Ac01PcieLib/Ac01PcieL= ib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/Ac01PcieLib/Ac01PcieLib.inf >> new file mode 100644 >> index 000000000000..8c8661265cd5 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/Ac01PcieLib/Ac01PcieLib.inf >> @@ -0,0 +1,42 @@ >> +## @file >> +# >> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.=
>> +# >> +# SPDX-License-Identifier: BSD-2-Clause-Patent >> +# >> +## >> + >> +[Defines] >> + INF_VERSION =3D 0x0001001B >> + BASE_NAME =3D Ac01PcieLib >> + FILE_GUID =3D 8ABFA0FC-313E-11E8-B467-0ED5F89F71= 8B >> + MODULE_TYPE =3D BASE >> + VERSION_STRING =3D 1.0 >> + LIBRARY_CLASS =3D Ac01PcieLib >> + >> +[Sources] >> + PcieCore.c >> + PcieCore.h >> + >> +[Packages] >> + ArmPkg/ArmPkg.dec >> + MdePkg/MdePkg.dec >> + Silicon/Ampere/AmpereAltraBinPkg/AmpereAltraBinPkg.dec >> + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec >> + >> +[LibraryClasses] >> + ArmGenericTimerCounterLib >> + BaseLib >> + BoardPcieLib >> + DebugLib >> + HobLib >> + IoLib >> + PciePhyLib >> + SystemFirmwareInterfaceLib >> + TimerLib >> + >> +[Guids] >> + gPlatformInfoHobGuid >> + >> +[Depex] >> + TRUE >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/BoardPcieLibNull/Boar= dPcieLibNull.inf b/Silicon/Ampere/AmpereAltraPkg/Library/BoardPcieLibNull/B= oardPcieLibNull.inf >> new file mode 100644 >> index 000000000000..435092b864ec >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/BoardPcieLibNull/BoardPcieLi= bNull.inf >> @@ -0,0 +1,25 @@ >> +## @file >> +# >> +# Copyright (c) 2021, Ampere Computing LLC. All rights reserved.
>> +# >> +# SPDX-License-Identifier: BSD-2-Clause-Patent >> +# >> +## >> + >> +[Defines] >> + INF_VERSION =3D 0x0001001B >> + BASE_NAME =3D BoardPcieLibNull >> + FILE_GUID =3D 7820C925-F525-4101-8E64-87838356B7= A6 >> + MODULE_TYPE =3D BASE >> + VERSION_STRING =3D 1.0 >> + LIBRARY_CLASS =3D BoardPcieLib >> + >> +[Sources.common] >> + BoardPcieLibNull.c >> + >> +[Packages] >> + MdePkg/MdePkg.dec >> + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec >> + >> +[LibraryClasses] >> + BaseLib >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/Ac01PcieLib.h= b/Silicon/Ampere/AmpereAltraPkg/Include/Library/Ac01PcieLib.h >> new file mode 100644 >> index 000000000000..692bc2669915 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/Ac01PcieLib.h >> @@ -0,0 +1,49 @@ >> +/** @file >> + >> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.=
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#ifndef AC01_PCIE_LIB_H_ >> +#define AC01_PCIE_LIB_H_ >> + >> +/** >> + Setup and initialize the AC01 PCIe Root Complex and underneath PCIe c= ontrollers >> + >> + @param RootComplex Pointer to Root Complex structure >> + @param ReInit Re-init status >> + @param ReInitPcieIndex PCIe controller index >> + >> + @retval RETURN_SUCCESS The Root Complex has been initialized su= ccessfully. >> + @retval RETURN_DEVICE_ERROR PHY, Memory or PIPE is not ready. >> +**/ >> +RETURN_STATUS >> +Ac01PcieCoreSetupRC ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN BOOLEAN ReInit, >> + IN UINT8 ReInitPcieIndex >> + ); >> + >> +/** >> + Verify the link status and retry to initialize the Root Complex if th= ere's any issue. >> + >> + @param RootComplexList Pointer to the Root Complex list >> +**/ >> +VOID >> +Ac01PcieCorePostSetupRC ( >> + IN AC01_ROOT_COMPLEX *RootComplexList >> + ); >> + >> +/** >> + Callback function when the Host Bridge enumeration end. >> + >> + @param RootComplex Pointer to the Root Complex structure >> +**/ >> +VOID >> +Ac01PcieCoreEndEnumeration ( >> + IN AC01_ROOT_COMPLEX *RootComplex >> + ); >> + >> +#endif /* AC01_PCIE_LIB_H_ */ >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/BoardPcieLib.= h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/BoardPcieLib.h >> new file mode 100644 >> index 000000000000..34e7dee702ec >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/BoardPcieLib.h >> @@ -0,0 +1,45 @@ >> +/** @file >> + >> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.=
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#ifndef BOARD_PCIE_LIB_H_ >> +#define BOARD_PCIE_LIB_H_ >> + >> +#include >> + >> +/** >> + Assert PERST of the PCIe controller >> + >> + @param[in] RootComplex Root Complex instance. >> + @param[in] PcieIndex PCIe controller index of input Root= Complex. >> + @param[in] IsPullToHigh Target status for the PERST. >> + >> + @retval RETURN_SUCCESS The operation is successful. >> + @retval Others An error occurred. >> +**/ >> +RETURN_STATUS >> +EFIAPI >> +BoardPcieAssertPerst ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN UINT8 PcieIndex, >> + IN BOOLEAN IsPullToHigh >> + ); >> + >> +/** >> + Override the segment number for a root complex with a board specific = number. >> + >> + @param[in] RootComplex Root Complex instance with properti= es. >> + >> + @retval Segment number corresponding to the input root complex. >> + Default segment number is 0x0F. >> +**/ >> +UINT16 >> +BoardPcieGetSegmentNumber ( >> + IN AC01_ROOT_COMPLEX *RootComplex >> + ); >> + >> +#endif /* BOARD_PCIE_LIB_H_ */ >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/Ac01PcieLib/PcieCore.= h b/Silicon/Ampere/AmpereAltraPkg/Library/Ac01PcieLib/PcieCore.h >> new file mode 100644 >> index 000000000000..1db8a68b3df4 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/Ac01PcieLib/PcieCore.h >> @@ -0,0 +1,372 @@ >> +/** @file >> + >> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.=
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#ifndef AC01_PCIE_CORE_H_ >> +#define AC01_PCIE_CORE_H_ >> + >> +#define BUS_SHIFT 20 >> +#define DEV_SHIFT 15 >> + >> +#define GET_LOW_8_BITS(x) ((x) & 0xFF) >> +#define GET_HIGH_8_BITS(x) (((x) >> 8) & 0xFF) >> +#define GET_LOW_16_BITS(x) ((x) & 0xFFFF) >> +#define GET_HIGH_16_BITS(x) (((x) >> 16) & 0xFFFF) >> +#define GET_CAPABILITY_PTR(x) (GET_LOW_16_BITS (x) >> 8) >> +#define GET_EXT_CAPABILITY_PTR(x) (GET_HIGH_16_BITS (x) >> 4) >> + >> +#define WORD_ALIGN_MASK 0x3 >> + >> +#define MAX_REINIT 3 // Number of soft reset= retry >> + >> +#define SLOT_POWER_LIMIT_75W 75 // Watt >> + >> +#define LINK_CHECK_SUCCESS 0 >> +#define LINK_CHECK_FAILED -1 >> +#define LINK_CHECK_WRONG_PARAMETER 1 >> + >> +#define AMPERE_PCIE_VENDOR_ID 0x1DEF >> +#define AC01_HOST_BRIDGE_DEVICE_ID_RCA 0xE100 >> +#define AC01_HOST_BRIDGE_DEVICE_ID_RCB 0xE110 >> +#define AC01_PCIE_BRIDGE_DEVICE_ID_RCA 0xE101 >> +#define AC01_PCIE_BRIDGE_DEVICE_ID_RCB 0xE111 >> + >> +#define MEMRDY_TIMEOUT 10 // 10 us >> +#define PIPE_CLOCK_TIMEOUT 20000 // 20,000 us >> +#define LTSSM_TRANSITION_TIMEOUT 100000 // 100 ms in total >> +#define EP_LINKUP_TIMEOUT (10 * 1000) // 10ms >> +#define LINK_WAIT_INTERVAL_US 50 >> + >> +#define PFA_MODE_ENABLE 0 >> +#define PFA_MODE_CLEAR 1 >> +#define PFA_MODE_READ 2 >> + >> +// >> +// Host Bridge registers >> +// >> +#define AC01_HOST_BRIDGE_RCA_DEV_MAP_REG 0x0 >> +#define AC01_HOST_BRIDGE_RCB_DEV_MAP_REG 0x4 >> +#define AC01_HOST_BRIDGE_VENDOR_DEVICE_ID_REG 0x10 >> + >> +// AC01_HOST_BRIDGE_RCA_DEV_MAP_REG >> +#define RCA_DEV_MAP_SET(dst, src) (((dst) & ~0x7) | (((UI= NT32) (src)) & 0x7)) >> +#define RCA_DEV_MAP_GET(val) ((val) & 0x7) >> + >> +// AC01_HOST_BRIDGE_RCB_DEV_MAP_REG >> +#define RCB_DEV_MAP_LOW_SET(dst, src) (((dst) & ~0x7) | (((UI= NT32) (src)) & 0x7)) >> +#define RCB_DEV_MAP_LOW_GET(val) ((val) & 0x7) >> + >> +#define RCB_DEV_MAP_HIGH_SET(dst, src) (((dst) & ~0x70) | (((U= INT32) (src) << 4) & 0x70)) >> +#define RCB_DEV_MAP_HIGH_GET(val) (((val) & 0x7) >> 4) >> + >> +// AC01_HOST_BRIDGE_VENDOR_DEVICE_ID_REG >> +#define VENDOR_ID_SET(dst, src) (((dst) & ~0xFFFF) | ((= (UINT32) (src)) & 0xFFFF)) >> +#define VENDOR_ID_GET(val) ((val) & 0xFFFF) >> + >> +#define DEVICE_ID_SET(dst, src) (((dst) & ~0xFFFF0000) = | (((UINT32) (src) << 16) & 0xFFFF0000)) >> +#define DEVICE_ID_GET(val) (((val) & 0xFFFF0000) >= > 16) >> + >> +// >> +// PCIe core registers >> +// >> +#define AC01_PCIE_CORE_LINK_CTRL_REG 0x0 >> +#define AC01_PCIE_CORE_LINK_STAT_REG 0x4 >> +#define AC01_PCIE_CORE_IRQ_SEL_REG 0xC >> +#define AC01_PCIE_CORE_HOT_PLUG_STAT_REG 0x28 >> +#define AC01_PCIE_CORE_IRQ_ENABLE_REG 0x30 >> +#define AC01_PCIE_CORE_IRQ_EVENT_STAT_REG 0x38 >> +#define AC01_PCIE_CORE_BLOCK_EVENT_STAT_REG 0x3C >> +#define AC01_PCIE_CORE_RESET_REG 0xC000 >> +#define AC01_PCIE_CORE_CLOCK_REG 0xC004 >> +#define AC01_PCIE_CORE_MEM_READY_REG 0xC104 >> +#define AC01_PCIE_CORE_RAM_SHUTDOWN_REG 0xC10C >> + >> +// AC01_PCIE_CORE_LINK_CTRL_REG >> +#define LTSSMENB_SET(dst, src) (((dst) & ~0x1) | (((UINT32= ) (src)) & 0x1)) >> +#define HOLD_LINK_TRAINING 0 >> +#define START_LINK_TRAINING 1 >> +#define DEVICETYPE_SET(dst, src) (((dst) & ~0xF0) | (((UINT3= 2) (src) << 4) & 0xF0)) >> +#define DEVICETYPE_GET(val) (((val) & 0xF0) >> 4) >> + >> +// AC01_PCIE_CORE_LINK_STAT_REG >> +#define PHY_STATUS_MASK (1 << 2) >> +#define SMLH_LTSSM_STATE_MASK 0x3F00 >> +#define SMLH_LTSSM_STATE_GET(val) ((val & SMLH_LTSSM_STATE_MA= SK) >> 8) >> +#define LTSSM_STATE_L0 0x11 >> +#define RDLH_SMLH_LINKUP_STATUS_GET(val) (val & 0x3) >> +#define PHY_STATUS_MASK_BIT 0x04 >> +#define SMLH_LINK_UP_MASK_BIT 0x02 >> +#define RDLH_LINK_UP_MASK_BIT 0x01 >> + >> +// AC01_PCIE_CORE_IRQ_SEL_REG >> +#define AER_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & = 0x1)) >> +#define PME_SET(dst, src) (((dst) & ~0x2) | (((UINT32) (src) << = 1) & 0x2)) >> +#define LINKAUTOBW_SET(dst, src) (((dst) & ~0x4) | (((UINT32) (src) << = 2) & 0x4)) >> +#define BWMGMT_SET(dst, src) (((dst) & ~0x8) | (((UINT32) (src) << = 3) & 0x8)) >> +#define EQRQST_SET(dst, src) (((dst) & ~0x10) | (((UINT32) (src) <<= 4) & 0x10)) >> +#define INTPIN_SET(dst, src) (((dst) & ~0xFF00) | (((UINT32) (src) = << 8) & 0xFF00)) >> +#define IRQ_INT_A 0x01 >> + >> +// AC01_PCIE_CORE_HOT_PLUG_STAT_REG >> +#define PWR_IND_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & = 0x1)) >> +#define ATTEN_IND_SET(dst, src) (((dst) & ~0x2) | (((UINT32) (src) << = 1) & 0x2)) >> +#define PWR_CTRL_SET(dst, src) (((dst) & ~0x4) | (((UINT32) (src) << = 2) & 0x4)) >> +#define EML_CTRL_SET(dst, src) (((dst) & ~0x8) | (((UINT32) (src) << = 3) & 0x8)) >> + >> +// AC01_PCIE_CORE_BLOCK_EVENT_STAT_REG >> +#define LINKUP_MASK 0x1 >> + >> +// AC01_PCIE_CORE_RESET_REG >> +#define DWC_PCIE_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & = 0x1)) >> +#define RESET_MASK 0x1 >> +#define ASSERT_RESET 0x1 >> + >> +// AC01_PCIE_CORE_CLOCK_REG >> +#define AXIPIPE_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & = 0x1)) >> + >> +// AC01_PCIE_CORE_MEM_READY_REG >> +#define MEMORY_READY 0x1 >> + >> +// AC01_PCIE_CORE_RAM_SHUTDOWN_REG >> +#define SD_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & = 0x1)) >> + >> +// >> +// AC01 PCIe Type 1 configuration registers >> +// >> +#define TYPE1_DEV_ID_VEND_ID_REG 0 >> +#define TYPE1_CLASS_CODE_REV_ID_REG 0x8 >> +#define TYPE1_CAP_PTR_REG 0x34 >> +#define SEC_LAT_TIMER_SUB_BUS_SEC_BUS_PRI_BUS_REG 0x18 >> +#define BRIDGE_CTRL_INT_PIN_INT_LINE_REG 0x3C >> +#define PCIE_CAPABILITY_BASE 0x70 >> +#define EXT_CAPABILITY_START_BASE 0x100 >> +#define AER_CAPABILITY_BASE 0x100 >> + >> +// TYPE1_DEV_ID_VEND_ID_REG >> +#define VENDOR_ID_SET(dst, src) (((dst) & ~0xFFFF) | ((= (UINT32) (src)) & 0xFFFF)) >> +#define DEVICE_ID_SET(dst, src) (((dst) & ~0xFFFF0000) = | (((UINT32) (src) << 16) & 0xFFFF0000)) >> + >> +// TYPE1_CLASS_CODE_REV_ID_REG >> +#define BASE_CLASS_CODE_SET(dst, src) (((dst) & ~0xFF000000) = | (((UINT32) (src) << 24) & 0xFF000000)) >> +#define DEFAULT_BASE_CLASS_CODE 6 >> +#define SUB_CLASS_CODE_SET(dst, src) (((dst) & ~0xFF0000) |= (((UINT32) (src) << 16) & 0xFF0000)) >> +#define DEFAULT_SUB_CLASS_CODE 4 >> +#define PROGRAM_INTERFACE_SET(dst, src) (((dst) & ~0xFF00) | ((= (UINT32) (src) << 8) & 0xFF00)) >> +#define REVISION_ID_SET(dst, src) (((dst) & ~0xFF) | (((U= INT32) (src)) & 0xFF)) >> +#define DEFAULT_REVISION_ID 4 >> + >> +// SEC_LAT_TIMER_SUB_BUS_SEC_BUS_PRI_BUS_REG >> +#define SUB_BUS_SET(dst, src) (((dst) & ~0xFF0000) | = (((UINT32) (src) << 16) & 0xFF0000)) >> +#define DEFAULT_SUB_BUS 0xFF >> +#define SEC_BUS_SET(dst, src) (((dst) & ~0xFF00) | ((= (UINT32) (src) << 8) & 0xFF00)) >> +#define PRIM_BUS_SET(dst, src) (((dst) & ~0xFF) | (((U= INT32) (src)) & 0xFF)) >> +#define DEFAULT_PRIM_BUS 0x00 >> + >> +// BRIDGE_CTRL_INT_PIN_INT_LINE_REG >> +#define INT_PIN_SET(dst, src) (((dst) & ~0xFF00) | ((= (UINT32) (src) << 8) & 0xFF00)) >> + >> +// >> +// PCI Express Capability >> +// >> +#define PCIE_CAPABILITY_ID 0x10 >> +#define LINK_CAPABILITIES_REG 0xC >> +#define LINK_CONTROL_LINK_STATUS_REG 0x10 >> +#define SLOT_CAPABILITIES_REG 0x14 >> +#define DEVICE_CONTROL2_DEVICE_STATUS2_REG 0x28 >> +#define LINK_CAPABILITIES2_REG 0x2C >> +#define LINK_CONTROL2_LINK_STATUS2_REG 0x30 >> + >> +// LINK_CAPABILITIES_REG >> +#define CAP_ACTIVE_STATE_LINK_PM_SUPPORT_SET(dst, src) (((dst) & ~0xC00= ) | (((UINT32)(src) << 10) & 0xC00)) >> +#define NO_ASPM_SUPPORTED 0x0 >> +#define L0S_SUPPORTED 0x1 >> +#define L1_SUPPORTED 0x2 >> +#define L0S_L1_SUPPORTED 0x3 >> +#define CAP_MAX_LINK_WIDTH_GET(val) ((val & 0x3F0) >> 4) >> +#define CAP_MAX_LINK_WIDTH_SET(dst, src) (((dst) & ~0x3F0) | (((= UINT32) (src) << 4) & 0x3F0)) >> +#define CAP_MAX_LINK_WIDTH_X1 0x1 >> +#define CAP_MAX_LINK_WIDTH_X2 0x2 >> +#define CAP_MAX_LINK_WIDTH_X4 0x4 >> +#define CAP_MAX_LINK_WIDTH_X8 0x8 >> +#define CAP_MAX_LINK_WIDTH_X16 0x10 >> +#define CAP_MAX_LINK_SPEED_GET(val) ((val & 0xF)) >> +#define CAP_MAX_LINK_SPEED_SET(dst, src) (((dst) & ~0xF) | (((UI= NT32) (src)) & 0xF)) >> +#define MAX_LINK_SPEED_25 0x1 >> +#define MAX_LINK_SPEED_50 0x2 >> +#define MAX_LINK_SPEED_80 0x3 >> +#define MAX_LINK_SPEED_160 0x4 >> +#define MAX_LINK_SPEED_320 0x5 >> + >> +// LINK_CONTROL_LINK_STATUS_REG >> +#define CAP_DLL_ACTIVE_GET(val) ((val & 0x20000000) >> = 29) >> +#define CAP_SLOT_CLK_CONFIG_SET(dst, src) (((dst) & ~0x10000000) = | (((UINT32) (src) << 28) & 0x10000000)) >> +#define CAP_NEGO_LINK_WIDTH_GET(val) ((val & 0x3F00000) >> 2= 0) >> +#define CAP_LINK_SPEED_GET(val) ((val & 0xF0000) >> 16) >> +#define CAP_LINK_SPEED_SET(dst, src) (((dst) & ~0xF0000) | (= ((UINT32) (src) << 16) & 0xF0000)) >> +#define CAP_LINK_SPEED_TO_VECTOR(val) (1 << ((val) - 1)) >> +#define CAP_EN_CLK_POWER_MAN_GET(val) ((val & 0x100) >> 8) >> +#define CAP_EN_CLK_POWER_MAN_SET(dst, src) (((dst) & ~0x100) | (((= UINT32) (src) << 8) & 0x100)) >> +#define CAP_COMMON_CLK_SET(dst, src) (((dst) & ~0x40) | (((U= INT32) (src) << 6) & 0x40)) >> +#define CAP_RETRAIN_LINK_SET(dst, src) (((dst) & ~0x20) | (((U= INT32) (src) << 5) & 0x20)) >> +#define CAP_LINK_TRAINING_GET(val) ((val & 0x8000000) >> 2= 7) >> +#define CAP_LINK_DISABLE_SET(dst, src) (((dst) & ~0x10) | (((U= INT32)(src) << 4) & 0x10)) >> + >> +// SLOT_CAPABILITIES_REG >> +#define SLOT_HPC_SET(dst, src) (((dst) & ~0x40) | (((U= INT32) (src) << 6) & 0x40)) >> +#define SLOT_CAP_SLOT_POWER_LIMIT_VALUE_SET(dst, src) \ >> + (((dst) & ~0x7F80) | ((= (UINT32)(src) << 7) & 0x7F80)) >> + >> +// DEVICE_CONTROL2_DEVICE_STATUS2_REG >> +#define CAP_CPL_TIMEOUT_VALUE_SET(dst, src) (((dst) & ~0xF) | (((UI= NT32) (src)) & 0xF)) >> + >> +// LINK_CONTROL2_LINK_STATUS2_REG >> +#define CAP_TARGET_LINK_SPEED_SET(dst, src) (((dst) & ~0xF) | (((UI= NT32) (src)) & 0xF)) >> + >> +// >> +// Advanced Error Reporting Capability >> +// >> +#define AER_CAPABILITY_ID 0x0001 >> +#define UNCORR_ERR_STATUS_OFF 0x04 >> +#define UNCORR_ERR_MASK_OFF 0x08 >> + >> +// UNCORR_ERR_MASK_OFF >> +#define CMPLT_TIMEOUT_ERR_MASK_SET(dst, src) (((dst) & ~0x4000) | ((= (UINT32) (src) << 14) & 0x4000)) >> +#define SDES_ERR_MASK_SET(dst, src) (((dst) & ~0x20) | (((U= INT32)(src) << 5) & 0x20)) >> + >> +// >> +// Vendor specific RAS D.E.S Capability >> +// >> +#define RAS_DES_CAPABILITY_ID 0x000B >> +#define EVENT_COUNTER_CONTROL_REG 0x08 >> +#define EVENT_COUNTER_DATA_REG 0x0C >> + >> +// EVENT_COUNTER_CONTROL_REG >> +#define ECCR_GROUP_EVENT_SEL_SET(dst, src) (((dst) & ~0xFFF0000) |= (((UINT32)(src) << 16) & 0xFFF0000)) >> +#define ECCR_GROUP_SEL_SET(dst, src) (((dst) & ~0xF000000) |= (((UINT32)(src) << 24) & 0xF000000)) >> +#define ECCR_EVENT_SEL_SET(dst, src) (((dst) & ~0xFF0000) | = (((UINT32)(src) << 16) & 0xFF0000)) >> +#define ECCR_LANE_SEL_SET(dst, src) (((dst) & ~0xF00) | (((= UINT32)(src) << 8) & 0xF00)) >> +#define ECCR_EVENT_COUNTER_ENABLE_SET(dst, src) (((dst) & ~0x1C) | (((U= INT32)(src) << 2) & 0x1C)) >> +#define EVENT_COUNTER_ENABLE_NO_CHANGE 0x00 >> +#define EVENT_COUNTER_ENABLE_ALL_ON 0x07 >> +#define ECCR_EVENT_COUNTER_CLEAR_SET(dst, src) (((dst) & ~0x3) | (((UI= NT32)(src)) & 0x3)) >> +#define EVENT_COUNTER_CLEAR_NO_CHANGE 0x00 >> +#define EVENT_COUNTER_CLEAR_ALL_CLEAR 0x03 >> + >> +// >> +// Secondary PCI Express Capability >> +// >> +#define SPCIE_CAPABILITY_ID 0x0019 >> +#define SPCIE_CAP_OFF_0C_REG 0x0C >> + >> +// SPCIE_CAP_OFF_0C_REG >> +#define DSP_TX_PRESET0_SET(dst,src) (((dst) & ~0xF) | (((UI= NT32) (src)) & 0xF)) >> +#define DSP_TX_PRESET1_SET(dst,src) (((dst) & ~0xF0000) | (= ((UINT32) (src) << 16) & 0xF0000)) >> +#define DEFAULT_GEN3_PRESET 0x05 >> + >> +// >> +// Physical Layer 16.0 GT/s Extended Capability >> +// >> +#define PL16G_CAPABILITY_ID 0x0026 >> +#define PL16G_STATUS_REG 0x0C >> +#define PL16G_CAP_OFF_20H_REG 0x20 >> + >> +// PL16G_STATUS_REG >> +#define PL16G_STATUS_EQ_CPL_GET(val) (val & 0x1) >> +#define PL16G_STATUS_EQ_CPL_P1_GET(val) ((val & 0x2) >> 1) >> +#define PL16G_STATUS_EQ_CPL_P2_GET(val) ((val & 0x4) >> 2) >> +#define PL16G_STATUS_EQ_CPL_P3_GET(val) ((val & 0x8) >> 3) >> + >> +// PL16G_CAP_OFF_20H_REG >> +#define DSP_16G_TX_PRESET0_SET(dst,src) (((dst) & ~0xF) | (((UI= NT32) (src)) & 0xF)) >> +#define DSP_16G_TX_PRESET1_SET(dst,src) (((dst) & ~0xF00) | (((= UINT32) (src) << 8) & 0xF00)) >> +#define DSP_16G_TX_PRESET2_SET(dst,src) (((dst) & ~0xF0000) | (= ((UINT32) (src) << 16) & 0xF0000)) >> +#define DSP_16G_TX_PRESET3_SET(dst,src) (((dst) & ~0xF000000) |= (((UINT32) (src) << 24) & 0xF000000)) >> +#define DSP_16G_RXTX_PRESET0_SET(dst,src) (((dst) & ~0xFF) | (((U= INT32) (src)) & 0xFF)) >> +#define DSP_16G_RXTX_PRESET1_SET(dst,src) (((dst) & ~0xFF00) | ((= (UINT32) (src) << 8) & 0xFF00)) >> +#define DSP_16G_RXTX_PRESET2_SET(dst,src) (((dst) & ~0xFF0000) | = (((UINT32) (src) << 16) & 0xFF0000)) >> +#define DSP_16G_RXTX_PRESET3_SET(dst,src) (((dst) & ~0xFF000000) = | (((UINT32) (src) << 24) & 0xFF000000)) >> +#define DEFAULT_GEN4_PRESET 0x57 >> + >> +// >> +// Port Logic >> +// >> +#define PORT_LINK_CTRL_OFF 0x710 >> +#define FILTER_MASK_2_OFF 0x720 >> +#define GEN2_CTRL_OFF 0x80C >> +#define GEN3_RELATED_OFF 0x890 >> +#define GEN3_EQ_CONTROL_OFF 0x8A8 >> +#define MISC_CONTROL_1_OFF 0x8BC >> +#define AMBA_ERROR_RESPONSE_DEFAULT_OFF 0x8D0 >> +#define AMBA_LINK_TIMEOUT_OFF 0x8D4 >> +#define AMBA_ORDERING_CTRL_OFF 0x8D8 >> +#define DTIM_CTRL0_OFF 0xAB0 >> +#define AUX_CLK_FREQ_OFF 0xB40 >> +#define CCIX_CTRL_OFF 0xC20 >> + >> +// PORT_LINK_CTRL_OFF >> +#define LINK_CAPABLE_SET(dst, src) (((dst) & ~0x3F0000) | = (((UINT32) (src) << 16) & 0x3F0000)) >> +#define LINK_CAPABLE_X1 0x1 >> +#define LINK_CAPABLE_X2 0x3 >> +#define LINK_CAPABLE_X4 0x7 >> +#define LINK_CAPABLE_X8 0xF >> +#define LINK_CAPABLE_X16 0x1F >> +#define LINK_CAPABLE_X32 0x3F >> +#define FAST_LINK_MODE_SET(dst, src) (((dst) & ~0x80) | (((U= INT32) (src) << 7) & 0x80)) >> + >> +// FILTER_MASK_2_OFF >> +#define CX_FLT_MASK_VENMSG0_DROP_SET(dst, src) (((dst) & ~0x1) | (((UI= NT32) (src)) & 0x1)) >> +#define CX_FLT_MASK_VENMSG1_DROP_SET(dst, src) (((dst) & ~0x2) | (((UI= NT32) (src) << 1) & 0x2)) >> +#define CX_FLT_MASK_DABORT_4UCPL_SET(dst, src) (((dst) & ~0x4) | (((UI= NT32) (src) << 2) & 0x4)) >> + >> +// GEN2_CTRL_OFF >> +#define NUM_OF_LANES_SET(dst, src) (((dst) & ~0x1F00) | ((= (UINT32) (src) << 8) & 0x1F00)) >> +#define NUM_OF_LANES_X2 0x2 >> +#define NUM_OF_LANES_X4 0x4 >> +#define NUM_OF_LANES_X8 0x8 >> +#define NUM_OF_LANES_X16 0x10 >> + >> +// GEN3_RELATED_OFF >> +#define RATE_SHADOW_SEL_SET(dst, src) (((dst) & ~0x3000000) |= (((UINT32) (src) << 24) & 0x3000000)) >> +#define GEN3_DATA_RATE 0x00 >> +#define GEN4_DATA_RATE 0x01 >> +#define EQ_PHASE_2_3_SET(dst, src) (((dst) & ~0x200) | (((= UINT32) (src) << 9) & 0x200)) >> +#define ENABLE_EQ_PHASE_2_3 0x00 >> +#define DISABLE_EQ_PHASE_2_3 0x01 >> +#define RXEQ_REGRDLESS_SET(dst, src) (((dst) & ~0x2000) | ((= (UINT32) (src) << 13) & 0x2000)) >> +#define ASSERT_RXEQ 0x01 >> + >> +// GEN3_EQ_CONTROL_OFF >> +#define GEN3_EQ_FB_MODE(dst, src) (((dst) & ~0xF) | ((UIN= T32) (src) & 0xF)) >> +#define FOM_METHOD 0x01 >> +#define GEN3_EQ_PRESET_VEC(dst, src) (((dst) & 0xFF0000FF) |= (((UINT32) (src) << 8) & 0xFFFF00)) >> +#define EQ_DEFAULT_PRESET_VECTOR 0x370 >> +#define GEN3_EQ_INIT_EVAL(dst,src) (((dst) & ~0x1000000) |= (((UINT32) (src) << 24) & 0x1000000)) >> +#define INCLUDE_INIT_FOM 0x01 >> + >> +// MISC_CONTROL_1_OFF >> +#define DBI_RO_WR_EN_SET(dst, src) (((dst) & ~0x1) | (((UI= NT32) (src)) & 0x1)) >> +#define ENABLE_WR 0x01 >> +#define DISABLE_WR 0x00 >> + >> +// AMBA_ERROR_RESPONSE_DEFAULT_OFF >> +#define AMBA_ERROR_RESPONSE_CRS_SET(dst, src) (((dst) & ~0x18) | = (((UINT32) (src) << 3) & 0x18)) >> +#define AMBA_ERROR_RESPONSE_GLOBAL_SET(dst, src) (((dst) & ~0x1) | (= ((UINT32) (src)) & 0x1)) >> + >> +// AMBA_LINK_TIMEOUT_OFF >> +#define LINK_TIMEOUT_PERIOD_DEFAULT_SET(dst, src) (((dst) & ~0xFF) | = (((UINT32) (src)) & 0xFF)) >> + >> +// AMBA_ORDERING_CTRL_OFF >> +#define AX_MSTR_ZEROLREAD_FW_SET(dst, src) (((dst) & ~0x80) | = (((UINT32) (src) << 7) & 0x80)) >> + >> +// DTIM_CTRL0_OFF >> +#define DTIM_CTRL0_ROOT_PORT_ID_SET(dst, src) (((dst) & ~0xFFFF) = | (((UINT32) (src)) & 0xFFFF)) >> + >> +// AUX_CLK_FREQ_OFF >> +#define AUX_CLK_FREQ_SET(dst, src) (((dst) & ~0x1FF) |= (((UINT32) (src)) & 0x1FF)) >> +#define AUX_CLK_500MHZ 500 >> + >> +#endif /* AC01_PCIE_CORE_H_ */ >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/Ac01PcieLib/PcieCore.= c b/Silicon/Ampere/AmpereAltraPkg/Library/Ac01PcieLib/PcieCore.c >> new file mode 100644 >> index 000000000000..846e8593f57d >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/Ac01PcieLib/PcieCore.c >> @@ -0,0 +1,1419 @@ >> +/** @file >> + >> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.=
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#include >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include "PcieCore.h" >> + >> +/** >> + Return the next extended capability base address >> + >> + @param RootComplex Pointer to AC01_ROOT_COMPLEX structure >> + @param PcieIndex PCIe controller index >> + @param IsRootComplex TRUE: Checking RootComplex configuration spac= e >> + FALSE: Checking EP configuration space >> + @param ExtCapabilityId >> +**/ >> +PHYSICAL_ADDRESS >> +GetCapabilityBase ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN UINT8 PcieIndex, >> + IN BOOLEAN IsRootComplex, >> + IN UINT16 ExtCapabilityId >> + ) >> +{ >> + BOOLEAN IsExtCapability =3D FALSE; >> + PHYSICAL_ADDRESS CfgBase; >> + UINT32 CapabilityId; >> + UINT32 NextCapabilityPtr; >> + UINT32 Val; >> + >> + if (IsRootComplex) { >> + CfgBase =3D RootComplex->MmcfgBase + (RootComplex->Pcie[PcieIndex].= DevNum << DEV_SHIFT); >> + } else { >> + CfgBase =3D RootComplex->MmcfgBase + (RootComplex->Pcie[PcieIndex].= DevNum << BUS_SHIFT); >> + } >> + >> + Val =3D MmioRead32 (CfgBase + TYPE1_CAP_PTR_REG); >> + NextCapabilityPtr =3D GET_LOW_8_BITS (Val); >> + >> + // Loop untill desired capability is found else return 0 >> + while (1) { >> + if ((NextCapabilityPtr & WORD_ALIGN_MASK) !=3D 0) { >> + // Not alignment, just return >> + return 0; >> + } >> + >> + Val =3D MmioRead32 (CfgBase + NextCapabilityPtr); >> + if (NextCapabilityPtr < EXT_CAPABILITY_START_BASE) { >> + CapabilityId =3D GET_LOW_8_BITS (Val); >> + } else { >> + CapabilityId =3D GET_LOW_16_BITS (Val); >> + } >> + >> + if (CapabilityId =3D=3D ExtCapabilityId) { >> + return (CfgBase + NextCapabilityPtr); >> + } >> + >> + if (NextCapabilityPtr < EXT_CAPABILITY_START_BASE) { >> + NextCapabilityPtr =3D GET_CAPABILITY_PTR (Val); >> + } else { >> + NextCapabilityPtr =3D GET_EXT_CAPABILITY_PTR (Val); >> + } >> + >> + if ((NextCapabilityPtr =3D=3D 0) && !IsExtCapability) { >> + IsExtCapability =3D TRUE; >> + NextCapabilityPtr =3D EXT_CAPABILITY_START_BASE; >> + } >> + >> + if ((NextCapabilityPtr =3D=3D 0) && IsExtCapability) { >> + return 0; >> + } >> + } >> +} >> + >> +/** >> + Configure equalization settings for Gen3 and Gen4 >> + >> + @param RootComplex Pointer to AC01_ROOT_COMPLEX structure >> + @param PcieIndex PCIe controller index >> +**/ >> +STATIC >> +VOID >> +ConfigureEqualization ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN UINT8 PcieIndex >> + ) >> +{ >> + PHYSICAL_ADDRESS CfgBase; >> + PHYSICAL_ADDRESS Gen3RelatedAddr; >> + PHYSICAL_ADDRESS Gen3EqControlAddr; >> + UINT32 Val; >> + >> + CfgBase =3D RootComplex->MmcfgBase + (RootComplex->Pcie[PcieIndex].De= vNum << DEV_SHIFT); >> + >> + // >> + // Gen3 and Gen4 EQ process use the same setting registers which are >> + // GEN3_RELATED_OFF and GEN3_EQ_CONTROL_OFF. Both are shadow register= s >> + // and controlled by GEN3_RELATED_OFF[25:24]. >> + // >> + Gen3RelatedAddr =3D CfgBase + GEN3_RELATED_OFF; >> + Gen3EqControlAddr =3D CfgBase + GEN3_EQ_CONTROL_OFF; >> + >> + // >> + // Equalization setting for Gen3 >> + // >> + Val =3D MmioRead32 (Gen3RelatedAddr); >> + Val =3D RATE_SHADOW_SEL_SET (Val, GEN3_DATA_RATE); >> + MmioWrite32 (Gen3RelatedAddr, Val); >> + >> + Val =3D EQ_PHASE_2_3_SET (Val, ENABLE_EQ_PHASE_2_3); >> + Val =3D RXEQ_REGRDLESS_SET (Val, ASSERT_RXEQ); >> + MmioWrite32 (Gen3RelatedAddr, Val); >> + >> + Val =3D MmioRead32 (Gen3EqControlAddr); >> + Val =3D GEN3_EQ_FB_MODE (Val, FOM_METHOD); >> + Val =3D GEN3_EQ_PRESET_VEC (Val, EQ_DEFAULT_PRESET_VECTOR); >> + Val =3D GEN3_EQ_INIT_EVAL (Val, INCLUDE_INIT_FOM); >> + MmioWrite32 (Gen3EqControlAddr, Val); >> + >> + // >> + // Equalization setting for Gen4 >> + // >> + Val =3D MmioRead32 (Gen3RelatedAddr); >> + Val =3D RATE_SHADOW_SEL_SET (Val, GEN4_DATA_RATE); >> + MmioWrite32 (Gen3RelatedAddr, Val); >> + >> + Val =3D EQ_PHASE_2_3_SET (Val, ENABLE_EQ_PHASE_2_3); >> + Val =3D RXEQ_REGRDLESS_SET (Val, ASSERT_RXEQ); >> + MmioWrite32 (Gen3RelatedAddr, Val); >> + >> + Val =3D MmioRead32 (Gen3EqControlAddr); >> + Val =3D GEN3_EQ_FB_MODE (Val, FOM_METHOD); >> + Val =3D GEN3_EQ_PRESET_VEC (Val, EQ_DEFAULT_PRESET_VECTOR); >> + Val =3D GEN3_EQ_INIT_EVAL (Val, INCLUDE_INIT_FOM); >> + MmioWrite32 (Gen3EqControlAddr, Val); >> +} >> + >> +/** >> + Configure presets for Gen3 equalization >> + >> + @param RootComplex Pointer to AC01_ROOT_COMPLEX structure >> + @param PcieIndex PCIe controller index >> +**/ >> +STATIC >> +VOID >> +ConfigurePresetGen3 ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN UINT8 PcieIndex >> + ) >> +{ >> + PHYSICAL_ADDRESS LaneEqControlAddr; >> + PHYSICAL_ADDRESS SpcieCapabilityBase; >> + UINT32 Idx; >> + UINT32 LinkWidth; >> + UINT32 Val; >> + >> + // Get the Secondary PCI Express Extended capability base address >> + SpcieCapabilityBase =3D GetCapabilityBase (RootComplex, PcieIndex, TR= UE, SPCIE_CAPABILITY_ID); >> + if (SpcieCapabilityBase =3D=3D 0) { >> + DEBUG (( >> + DEBUG_ERROR, >> + "PCIE%d.%d: Cannot get SPCIE capability address\n", >> + RootComplex->ID, >> + PcieIndex >> + )); >> + return; >> + } >> + >> + LinkWidth =3D RootComplex->Pcie[PcieIndex].MaxWidth; >> + >> + // Each register holds the Preset for 2 lanes >> + for (Idx =3D 0; Idx < (LinkWidth / 2); Idx++) { >> + LaneEqControlAddr =3D SpcieCapabilityBase + SPCIE_CAP_OFF_0C_REG + = Idx * sizeof (UINT32); >> + Val =3D MmioRead32 (LaneEqControlAddr); >> + Val =3D DSP_TX_PRESET0_SET (Val, DEFAULT_GEN3_PRESET); >> + Val =3D DSP_TX_PRESET1_SET (Val, DEFAULT_GEN3_PRESET); >> + MmioWrite32 (LaneEqControlAddr, Val); >> + } >> +} >> + >> +/** >> + Configure presets for Gen4 equalization >> + >> + @param RootComplex Pointer to AC01_ROOT_COMPLEX structure >> + @param PcieIndex PCIe controller index >> +**/ >> +STATIC >> +VOID >> +ConfigurePresetGen4 ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN UINT8 PcieIndex >> + ) >> +{ >> + PHYSICAL_ADDRESS LaneEqControlAddr; >> + PHYSICAL_ADDRESS Pl16gCapabilityBase; >> + UINT32 Idx; >> + UINT32 LinkWidth; >> + UINT32 Val; >> + UINT8 Preset; >> + >> + // Get the Physical Layer 16.0 GT/s Extended capability base address >> + Pl16gCapabilityBase =3D GetCapabilityBase (RootComplex, PcieIndex, TR= UE, PL16G_CAPABILITY_ID); >> + if (Pl16gCapabilityBase =3D=3D 0) { >> + DEBUG (( >> + DEBUG_ERROR, >> + "PCIE%d.%d: Cannot get PL16G capability address\n", >> + RootComplex->ID, >> + PcieIndex >> + )); >> + return; >> + } >> + >> + if (RootComplex->PresetGen4[PcieIndex] =3D=3D PRESET_INVALID) { >> + Preset =3D DEFAULT_GEN4_PRESET; >> + } else { >> + Preset =3D RootComplex->PresetGen4[PcieIndex]; >> + } >> + >> + LinkWidth =3D RootComplex->Pcie[PcieIndex].MaxWidth; >> + >> + if (LinkWidth =3D=3D CAP_MAX_LINK_WIDTH_X2) { >> + LaneEqControlAddr =3D Pl16gCapabilityBase + PL16G_CAP_OFF_20H_REG; >> + Val =3D MmioRead32 (LaneEqControlAddr); >> + Val =3D DSP_16G_RXTX_PRESET0_SET (Val, Preset); >> + Val =3D DSP_16G_RXTX_PRESET1_SET (Val, Preset); >> + MmioWrite32 (LaneEqControlAddr, Val); >> + } else { >> + // Each register holds the Preset for 4 lanes >> + for (Idx =3D 0; Idx < (LinkWidth / 4); Idx++) { >> + LaneEqControlAddr =3D Pl16gCapabilityBase + PL16G_CAP_OFF_20H_REG= + Idx * sizeof (UINT32); >> + Val =3D MmioRead32 (LaneEqControlAddr); >> + Val =3D DSP_16G_RXTX_PRESET0_SET (Val, Preset); >> + Val =3D DSP_16G_RXTX_PRESET1_SET (Val, Preset); >> + Val =3D DSP_16G_RXTX_PRESET2_SET (Val, Preset); >> + Val =3D DSP_16G_RXTX_PRESET3_SET (Val, Preset); >> + MmioWrite32 (LaneEqControlAddr, Val); >> + } >> + } >> +} >> + >> +VOID >> +ProgramHostBridgeInfo ( >> + AC01_ROOT_COMPLEX *RootComplex >> + ) >> +{ >> + EFI_STATUS Status; >> + PHYSICAL_ADDRESS TargetAddress; >> + UINT32 Val; >> + >> + // Program Root Complex Bifurcation >> + if (RootComplex->Active) { >> + if (RootComplex->Type =3D=3D RootComplexTypeA) { >> + TargetAddress =3D RootComplex->HostBridgeBase + AC01_HOST_BRIDGE_= RCA_DEV_MAP_REG; >> + Status =3D MailboxMsgRegisterRead (RootComplex->Socket, TargetAdd= ress, &Val); >> + if (!RETURN_ERROR (Status)) { >> + Val =3D RCA_DEV_MAP_SET (Val, RootComplex->DevMapLow); >> + MailboxMsgRegisterWrite (RootComplex->Socket, TargetAddress, Va= l); >> + } >> + } else { >> + TargetAddress =3D RootComplex->HostBridgeBase + AC01_HOST_BRIDGE_= RCB_DEV_MAP_REG; >> + Status =3D MailboxMsgRegisterRead (RootComplex->Socket, TargetAdd= ress, &Val); >> + if (!RETURN_ERROR (Status)) { >> + Val =3D RCB_DEV_MAP_LOW_SET (Val, RootComplex->DevMapLow); >> + Val =3D RCB_DEV_MAP_HIGH_SET (Val, RootComplex->DevMapHigh); >> + MailboxMsgRegisterWrite (RootComplex->Socket, TargetAddress, Va= l); >> + } >> + } >> + } >> + >> + // Program Vendor ID and Device ID >> + TargetAddress =3D RootComplex->HostBridgeBase + AC01_HOST_BRIDGE_VEND= OR_DEVICE_ID_REG; >> + Status =3D MailboxMsgRegisterRead (RootComplex->Socket, TargetAddress= , &Val); >> + if (!RETURN_ERROR (Status)) { >> + Val =3D VENDOR_ID_SET (Val, AMPERE_PCIE_VENDOR_ID); >> + if (RootComplexTypeA =3D=3D RootComplex->Type) { >> + Val =3D DEVICE_ID_SET (Val, AC01_HOST_BRIDGE_DEVICE_ID_RCA); >> + } else { >> + Val =3D DEVICE_ID_SET (Val, AC01_HOST_BRIDGE_DEVICE_ID_RCB); >> + } >> + MailboxMsgRegisterWrite (RootComplex->Socket, TargetAddress, Val); >> + } >> +} >> + >> +VOID >> +ProgramRootPortInfo ( >> + AC01_ROOT_COMPLEX *RootComplex, >> + UINT32 PcieIndex >> + ) >> +{ >> + PHYSICAL_ADDRESS CfgBase; >> + PHYSICAL_ADDRESS TargetAddress; >> + UINT32 Val; >> + >> + CfgBase =3D RootComplex->MmcfgBase + (RootComplex->Pcie[PcieIndex].De= vNum << DEV_SHIFT); >> + >> + // Program Class Code >> + TargetAddress =3D CfgBase + TYPE1_CLASS_CODE_REV_ID_REG; >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D REVISION_ID_SET (Val, DEFAULT_REVISION_ID); >> + Val =3D SUB_CLASS_CODE_SET (Val, DEFAULT_SUB_CLASS_CODE); >> + Val =3D BASE_CLASS_CODE_SET (Val, DEFAULT_BASE_CLASS_CODE); >> + MmioWrite32 (TargetAddress, Val); >> + >> + // Program Vendor ID and Device ID >> + TargetAddress =3D CfgBase + TYPE1_DEV_ID_VEND_ID_REG; >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D VENDOR_ID_SET (Val, AMPERE_PCIE_VENDOR_ID); >> + if (RootComplexTypeA =3D=3D RootComplex->Type) { >> + Val =3D DEVICE_ID_SET (Val, AC01_PCIE_BRIDGE_DEVICE_ID_RCA + PcieIn= dex); >> + } else { >> + Val =3D DEVICE_ID_SET (Val, AC01_PCIE_BRIDGE_DEVICE_ID_RCB + PcieIn= dex); >> + } >> + MmioWrite32 (TargetAddress, Val); >> +} >> + >> +VOID >> +ProgramLinkCapabilities ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN UINT8 PcieIndex >> + ) >> +{ >> + PHYSICAL_ADDRESS CfgBase; >> + PHYSICAL_ADDRESS TargetAddress; >> + UINT32 Val; >> + UINT8 MaxWidth; >> + UINT8 MaxGen; >> + >> + CfgBase =3D RootComplex->MmcfgBase + (RootComplex->Pcie[PcieIndex].De= vNum << DEV_SHIFT); >> + >> + MaxWidth =3D RootComplex->Pcie[PcieIndex].MaxWidth; >> + MaxGen =3D RootComplex->Pcie[PcieIndex].MaxGen; >> + >> + TargetAddress =3D CfgBase + PORT_LINK_CTRL_OFF; >> + Val =3D MmioRead32 (TargetAddress); >> + switch (MaxWidth) { >> + case LINK_WIDTH_X2: >> + Val =3D LINK_CAPABLE_SET (Val, LINK_CAPABLE_X2); >> + break; >> + >> + case LINK_WIDTH_X4: >> + Val =3D LINK_CAPABLE_SET (Val, LINK_CAPABLE_X4); >> + break; >> + >> + case LINK_WIDTH_X8: >> + Val =3D LINK_CAPABLE_SET (Val, LINK_CAPABLE_X8); >> + break; >> + >> + case LINK_WIDTH_X16: >> + default: >> + Val =3D LINK_CAPABLE_SET (Val, LINK_CAPABLE_X16); >> + break; >> + } >> + MmioWrite32 (TargetAddress, Val); >> + >> + TargetAddress =3D CfgBase + GEN2_CTRL_OFF; >> + Val =3D MmioRead32 (TargetAddress); >> + switch (MaxWidth) { >> + case LINK_WIDTH_X2: >> + Val =3D NUM_OF_LANES_SET (Val, NUM_OF_LANES_X2); >> + break; >> + >> + case LINK_WIDTH_X4: >> + Val =3D NUM_OF_LANES_SET (Val, NUM_OF_LANES_X4); >> + break; >> + >> + case LINK_WIDTH_X8: >> + Val =3D NUM_OF_LANES_SET (Val, NUM_OF_LANES_X8); >> + break; >> + >> + case LINK_WIDTH_X16: >> + default: >> + Val =3D NUM_OF_LANES_SET (Val, NUM_OF_LANES_X16); >> + break; >> + } >> + MmioWrite32 (TargetAddress, Val); >> + >> + TargetAddress =3D CfgBase + PCIE_CAPABILITY_BASE + LINK_CAPABILITIES_= REG; >> + Val =3D MmioRead32 (TargetAddress); >> + switch (MaxWidth) { >> + case LINK_WIDTH_X2: >> + Val =3D CAP_MAX_LINK_WIDTH_SET (Val, CAP_MAX_LINK_WIDTH_X2); >> + break; >> + >> + case LINK_WIDTH_X4: >> + Val =3D CAP_MAX_LINK_WIDTH_SET (Val, CAP_MAX_LINK_WIDTH_X4); >> + break; >> + >> + case LINK_WIDTH_X8: >> + Val =3D CAP_MAX_LINK_WIDTH_SET (Val, CAP_MAX_LINK_WIDTH_X8); >> + break; >> + >> + case LINK_WIDTH_X16: >> + default: >> + Val =3D CAP_MAX_LINK_WIDTH_SET (Val, CAP_MAX_LINK_WIDTH_X16); >> + break; >> + } >> + >> + switch (MaxGen) { >> + case LINK_SPEED_GEN1: >> + Val =3D CAP_MAX_LINK_SPEED_SET (Val, MAX_LINK_SPEED_25); >> + break; >> + >> + case LINK_SPEED_GEN2: >> + Val =3D CAP_MAX_LINK_SPEED_SET (Val, MAX_LINK_SPEED_50); >> + break; >> + >> + case LINK_SPEED_GEN3: >> + Val =3D CAP_MAX_LINK_SPEED_SET (Val, MAX_LINK_SPEED_80); >> + break; >> + >> + default: >> + Val =3D CAP_MAX_LINK_SPEED_SET (Val, MAX_LINK_SPEED_160); >> + break; >> + } >> + // Enable ASPM Capability >> + Val =3D CAP_ACTIVE_STATE_LINK_PM_SUPPORT_SET (Val, L0S_L1_SUPPORTED); >> + MmioWrite32 (TargetAddress, Val); >> + >> + TargetAddress =3D CfgBase + PCIE_CAPABILITY_BASE + LINK_CONTROL2_LINK= _STATUS2_REG; >> + Val =3D MmioRead32 (TargetAddress); >> + switch (MaxGen) { >> + case LINK_SPEED_GEN1: >> + Val =3D CAP_TARGET_LINK_SPEED_SET (Val, MAX_LINK_SPEED_25); >> + break; >> + >> + case LINK_SPEED_GEN2: >> + Val =3D CAP_TARGET_LINK_SPEED_SET (Val, MAX_LINK_SPEED_50); >> + break; >> + >> + case LINK_SPEED_GEN3: >> + Val =3D CAP_TARGET_LINK_SPEED_SET (Val, MAX_LINK_SPEED_80); >> + break; >> + >> + default: >> + Val =3D CAP_TARGET_LINK_SPEED_SET (Val, MAX_LINK_SPEED_160); >> + break; >> + } >> + MmioWrite32 (TargetAddress, Val); >> +} >> + >> +VOID >> +DisableCompletionTimeOut ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN UINT8 PcieIndex, >> + IN BOOLEAN IsMask >> + ) >> +{ >> + PHYSICAL_ADDRESS CfgBase; >> + PHYSICAL_ADDRESS TargetAddress; >> + UINT32 Val; >> + >> + CfgBase =3D RootComplex->MmcfgBase + (RootComplex->Pcie[PcieIndex].De= vNum << DEV_SHIFT); >> + >> + TargetAddress =3D CfgBase + AER_CAPABILITY_BASE + UNCORR_ERR_MASK_OFF= ; >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D CMPLT_TIMEOUT_ERR_MASK_SET (Val, IsMask ? 1 : 0); >> + MmioWrite32 (TargetAddress, Val); >> +} >> + >> +BOOLEAN >> +EnableItsMemory ( >> + AC01_ROOT_COMPLEX *RootComplex, >> + UINT32 PcieIndex >> + ) >> +{ >> + PHYSICAL_ADDRESS CsrBase; >> + PHYSICAL_ADDRESS TargetAddress; >> + UINT32 TimeOut; >> + UINT32 Val; >> + >> + CsrBase =3D RootComplex->Pcie[PcieIndex].CsrBase; >> + >> + // Clear memory shutdown >> + TargetAddress =3D CsrBase + AC01_PCIE_CORE_RAM_SHUTDOWN_REG; >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D SD_SET (Val, 0); >> + MmioWrite32 (TargetAddress, Val); >> + >> + // Poll till ITS Memory is ready >> + TimeOut =3D MEMRDY_TIMEOUT; >> + do { >> + Val =3D MmioRead32 (CsrBase + AC01_PCIE_CORE_MEM_READY_REG); >> + if (Val & MEMORY_READY) { >> + return TRUE; >> + } >> + >> + TimeOut--; >> + MicroSecondDelay (1); >> + } while (TimeOut > 0); >> + >> + return FALSE; >> +} >> + >> +BOOLEAN >> +EnableAxiPipeClock ( >> + AC01_ROOT_COMPLEX *RootComplex, >> + UINT32 PcieIndex >> + ) >> +{ >> + PHYSICAL_ADDRESS CsrBase; >> + PHYSICAL_ADDRESS TargetAddress; >> + UINT32 TimeOut; >> + UINT32 Val; >> + >> + CsrBase =3D RootComplex->Pcie[PcieIndex].CsrBase; >> + >> + // Enable subsystem clock and release reset >> + TargetAddress =3D CsrBase + AC01_PCIE_CORE_CLOCK_REG; >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D AXIPIPE_SET (Val, 1); >> + MmioWrite32 (TargetAddress, Val); >> + >> + TargetAddress =3D CsrBase + AC01_PCIE_CORE_RESET_REG; >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D DWC_PCIE_SET (Val, 0); >> + MmioWrite32 (TargetAddress, Val); >> + >> + // >> + // Controller does not provide any indicator for reset released. >> + // Must wait at least 1us as per EAS. >> + // >> + MicroSecondDelay (1); >> + >> + // Poll till PIPE clock is stable >> + TimeOut =3D PIPE_CLOCK_TIMEOUT; >> + do { >> + Val =3D MmioRead32 (CsrBase + AC01_PCIE_CORE_LINK_STAT_REG); >> + if (!(Val & PHY_STATUS_MASK)) { >> + return TRUE; >> + } >> + >> + TimeOut--; >> + MicroSecondDelay (1); >> + } while (TimeOut > 0); >> + >> + return FALSE; >> +} >> + >> +VOID >> +SetLinkTimeout ( >> + AC01_ROOT_COMPLEX *RootComplex, >> + UINT32 PcieIndex, >> + UINTN Timeout >> + ) >> +{ >> + PHYSICAL_ADDRESS TargetAddress; >> + UINT32 Val; >> + >> + TargetAddress =3D RootComplex->MmcfgBase + (RootComplex->Pcie[PcieInd= ex].DevNum << DEV_SHIFT) >> + + AMBA_LINK_TIMEOUT_OFF; >> + >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D LINK_TIMEOUT_PERIOD_DEFAULT_SET (Val, Timeout); >> + MmioWrite32 (TargetAddress, Val); >> +} >> + >> +VOID >> +StartLinkTraining ( >> + AC01_ROOT_COMPLEX *RootComplex, >> + UINT32 PcieIndex, >> + BOOLEAN StartLink >> + ) >> +{ >> + PHYSICAL_ADDRESS TargetAddress; >> + UINT32 Val; >> + >> + TargetAddress =3D RootComplex->Pcie[PcieIndex].CsrBase + AC01_PCIE_CO= RE_LINK_CTRL_REG; >> + >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D LTSSMENB_SET (Val, StartLink ? START_LINK_TRAINING : HOLD_LIN= K_TRAINING); >> + MmioWrite32 (TargetAddress, Val); >> +} >> + >> +VOID >> +EnableDbiAccess ( >> + AC01_ROOT_COMPLEX *RootComplex, >> + UINT32 PcieIndex, >> + BOOLEAN EnableDbi >> + ) >> +{ >> + PHYSICAL_ADDRESS TargetAddress; >> + UINT32 Val; >> + >> + TargetAddress =3D RootComplex->MmcfgBase + (RootComplex->Pcie[PcieInd= ex].DevNum << DEV_SHIFT) >> + + MISC_CONTROL_1_OFF; >> + >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D DBI_RO_WR_EN_SET (Val, EnableDbi ? ENABLE_WR : DISABLE_WR); >> + MmioWrite32 (TargetAddress, Val); >> +} >> + >> +/** >> + Setup and initialize the AC01 PCIe Root Complex and underneath PCIe c= ontrollers >> + >> + @param RootComplex Pointer to Root Complex structure >> + @param ReInit Re-init status >> + @param ReInitPcieIndex PCIe controller index >> + >> + @retval RETURN_SUCCESS The Root Complex has been initialized su= ccessfully. >> + @retval RETURN_DEVICE_ERROR PHY, Memory or PIPE is not ready. >> +**/ >> +RETURN_STATUS >> +Ac01PcieCoreSetupRC ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN BOOLEAN ReInit, >> + IN UINT8 ReInitPcieIndex >> + ) >> +{ >> + PHYSICAL_ADDRESS CfgBase; >> + PHYSICAL_ADDRESS CsrBase; >> + PHYSICAL_ADDRESS TargetAddress; >> + RETURN_STATUS Status; >> + UINT32 Val; >> + UINT8 PcieIndex; >> + >> + DEBUG ((DEBUG_INFO, "Initializing Socket%d RootComplex%d\n", RootComp= lex->Socket, RootComplex->ID)); >> + >> + ProgramHostBridgeInfo (RootComplex); >> + >> + if (!ReInit) { >> + Status =3D PciePhyInit (RootComplex->SerdesBase); >> + if (RETURN_ERROR (Status)) { >> + DEBUG ((DEBUG_ERROR, "%a: Failed to initialize the PCIe PHY\n", _= _FUNCTION__)); >> + return RETURN_DEVICE_ERROR; >> + } >> + } >> + >> + // Setup each controller >> + for (PcieIndex =3D 0; PcieIndex < RootComplex->MaxPcieController; Pci= eIndex++) { >> + >> + if (ReInit) { >> + PcieIndex =3D ReInitPcieIndex; >> + } >> + >> + if (!RootComplex->Pcie[PcieIndex].Active) { >> + continue; >> + } >> + >> + DEBUG ((DEBUG_INFO, "Initializing Controller %d\n", PcieIndex)); >> + >> + CsrBase =3D RootComplex->Pcie[PcieIndex].CsrBase; >> + CfgBase =3D RootComplex->MmcfgBase + (RootComplex->Pcie[PcieIndex].= DevNum << DEV_SHIFT); >> + >> + // Put Controller into reset if not in reset already >> + TargetAddress =3D CsrBase + AC01_PCIE_CORE_RESET_REG; >> + Val =3D MmioRead32 (TargetAddress); >> + if (!(Val & RESET_MASK)) { >> + Val =3D DWC_PCIE_SET (Val, ASSERT_RESET); >> + MmioWrite32 (TargetAddress, Val); >> + >> + // Delay 50ms to ensure controller finish its reset >> + MicroSecondDelay (50000); >> + } >> + >> + if (!EnableItsMemory (RootComplex, PcieIndex)) { >> + DEBUG ((DEBUG_ERROR, "- Pcie[%d] - ITS Memory is not ready\n", Pc= ieIndex)); >> + return RETURN_DEVICE_ERROR; >> + } >> + >> + // Hold link training >> + StartLinkTraining (RootComplex, PcieIndex, FALSE); >> + >> + if (!EnableAxiPipeClock (RootComplex, PcieIndex)) { >> + DEBUG ((DEBUG_ERROR, "- Pcie[%d] - PIPE clock is not stable\n", P= cieIndex)); >> + return RETURN_DEVICE_ERROR; >> + } >> + >> + // Start PERST pulse >> + BoardPcieAssertPerst (RootComplex, PcieIndex, TRUE); >> + >> + // Allow programming to config space >> + EnableDbiAccess (RootComplex, PcieIndex, TRUE); >> + >> + // Program the power limit >> + TargetAddress =3D CfgBase + PCIE_CAPABILITY_BASE + SLOT_CAPABILITIE= S_REG; >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D SLOT_CAP_SLOT_POWER_LIMIT_VALUE_SET (Val, SLOT_POWER_LIMIT_= 75W); >> + MmioWrite32 (TargetAddress, Val); >> + >> + // Program DTI for ATS support >> + TargetAddress =3D CfgBase + DTIM_CTRL0_OFF; >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D DTIM_CTRL0_ROOT_PORT_ID_SET (Val, 0); >> + MmioWrite32 (TargetAddress, Val); >> + >> + // >> + // Program number of lanes used >> + // - Reprogram LINK_CAPABLE of PORT_LINK_CTRL_OFF >> + // - Reprogram NUM_OF_LANES of GEN2_CTRL_OFF >> + // - Reprogram CAP_MAX_LINK_WIDTH of LINK_CAPABILITIES_REG >> + // >> + ProgramLinkCapabilities (RootComplex, PcieIndex); >> + >> + // Set Zero byte request handling >> + TargetAddress =3D CfgBase + FILTER_MASK_2_OFF; >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D CX_FLT_MASK_VENMSG0_DROP_SET (Val, 0); >> + Val =3D CX_FLT_MASK_VENMSG1_DROP_SET (Val, 0); >> + Val =3D CX_FLT_MASK_DABORT_4UCPL_SET (Val, 0); >> + MmioWrite32 (TargetAddress, Val); >> + >> + TargetAddress =3D CfgBase + AMBA_ORDERING_CTRL_OFF; >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D AX_MSTR_ZEROLREAD_FW_SET (Val, 0); >> + MmioWrite32 (TargetAddress, Val); >> + >> + // >> + // Set Completion with CRS handling for CFG Request >> + // Set Completion with CA/UR handling non-CFG Request >> + // >> + TargetAddress =3D CfgBase + AMBA_ERROR_RESPONSE_DEFAULT_OFF; >> + Val =3D MmioRead32 (TargetAddress); >> + // 0x2: OKAY with FFFF_0001 and FFFF_FFFF >> + Val =3D AMBA_ERROR_RESPONSE_CRS_SET (Val, 0x2); >> + MmioWrite32 (TargetAddress, Val); >> + >> + // Set Legacy PCIE interrupt map to INTA >> + TargetAddress =3D CfgBase + BRIDGE_CTRL_INT_PIN_INT_LINE_REG; >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D INT_PIN_SET (Val, IRQ_INT_A); >> + MmioWrite32 (TargetAddress, Val); >> + >> + TargetAddress =3D CsrBase + AC01_PCIE_CORE_IRQ_SEL_REG; >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D INTPIN_SET (Val, IRQ_INT_A); >> + MmioWrite32 (TargetAddress, Val); >> + >> + if (RootComplex->Pcie[PcieIndex].MaxGen >=3D LINK_SPEED_GEN2) { >> + ConfigureEqualization (RootComplex, PcieIndex); >> + if (RootComplex->Pcie[PcieIndex].MaxGen >=3D LINK_SPEED_GEN3) { >> + ConfigurePresetGen3 (RootComplex, PcieIndex); >> + if (RootComplex->Pcie[PcieIndex].MaxGen >=3D LINK_SPEED_GEN4) { >> + ConfigurePresetGen4 (RootComplex, PcieIndex); >> + } >> + } >> + } >> + >> + // Link timeout after 1ms >> + SetLinkTimeout (RootComplex, PcieIndex, 1); >> + >> + DisableCompletionTimeOut (RootComplex, PcieIndex, TRUE); >> + >> + ProgramRootPortInfo (RootComplex, PcieIndex); >> + >> + // Enable common clock for downstream >> + TargetAddress =3D CfgBase + PCIE_CAPABILITY_BASE + LINK_CONTROL_LIN= K_STATUS_REG; >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D CAP_SLOT_CLK_CONFIG_SET (Val, 1); >> + Val =3D CAP_COMMON_CLK_SET (Val, 1); >> + MmioWrite32 (TargetAddress, Val); >> + >> + // Match aux_clk to system >> + TargetAddress =3D CfgBase + AUX_CLK_FREQ_OFF; >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D AUX_CLK_FREQ_SET (Val, AUX_CLK_500MHZ); >> + MmioWrite32 (TargetAddress, Val); >> + >> + // Assert PERST low to reset endpoint >> + BoardPcieAssertPerst (RootComplex, PcieIndex, FALSE); >> + >> + // Start link training >> + StartLinkTraining (RootComplex, PcieIndex, TRUE); >> + >> + // Complete the PERST pulse >> + BoardPcieAssertPerst (RootComplex, PcieIndex, TRUE); >> + >> + // Lock programming of config space >> + EnableDbiAccess (RootComplex, PcieIndex, FALSE); >> + >> + if (ReInit) { >> + return RETURN_SUCCESS; >> + } >> + } >> + >> + return RETURN_SUCCESS; >> +} >> + >> +BOOLEAN >> +PcieLinkUpCheck ( >> + IN AC01_PCIE_CONTROLLER *Pcie >> + ) >> +{ >> + PHYSICAL_ADDRESS CsrBase; >> + UINT32 BlockEvent; >> + UINT32 LinkStat; >> + >> + CsrBase =3D Pcie->CsrBase; >> + >> + // Check if card present >> + // smlh_ltssm_state[13:8] =3D 0 >> + // phy_status[2] =3D 0 >> + // smlh_link_up[1] =3D 0 >> + // rdlh_link_up[0] =3D 0 >> + LinkStat =3D MmioRead32 (CsrBase + AC01_PCIE_CORE_LINK_STAT_REG); >> + LinkStat =3D LinkStat & (SMLH_LTSSM_STATE_MASK | PHY_STATUS_MASK_BIT = | >> + SMLH_LINK_UP_MASK_BIT | RDLH_LINK_UP_MASK_BIT)= ; >> + if (LinkStat =3D=3D 0) { >> + return FALSE; >> + } >> + >> + BlockEvent =3D MmioRead32 (CsrBase + AC01_PCIE_CORE_BLOCK_EVENT_STAT_= REG); >> + LinkStat =3D MmioRead32 (CsrBase + AC01_PCIE_CORE_LINK_STAT_REG); >> + >> + if (((BlockEvent & LINKUP_MASK) !=3D 0) >> + && (SMLH_LTSSM_STATE_GET(LinkStat) =3D=3D LTSSM_STATE_L0)) { >> + return TRUE; >> + } >> + >> + return FALSE; >> +} >> + >> +/** >> + Callback function when the Host Bridge enumeration end. >> + >> + @param RootComplex Pointer to the Root Complex structure >> +**/ >> +VOID >> +Ac01PcieCoreEndEnumeration ( >> + IN AC01_ROOT_COMPLEX *RootComplex >> + ) >> +{ >> + >> + PHYSICAL_ADDRESS TargetAddress; >> + UINT32 PcieIndex; >> + UINT32 Val; >> + >> + if (RootComplex =3D=3D NULL || !RootComplex->Active) { >> + return; >> + } >> + >> + // Clear uncorrectable error during enumuration phase. Mainly complet= ion timeout. >> + for (PcieIndex =3D 0; PcieIndex < RootComplex->MaxPcieController; Pci= eIndex++) { >> + if (!RootComplex->Pcie[PcieIndex].Active) { >> + continue; >> + } >> + >> + if (!PcieLinkUpCheck(&RootComplex->Pcie[PcieIndex])) { >> + // If link down/disabled after enumeration, disable completed tim= e out >> + DisableCompletionTimeOut (RootComplex, PcieIndex, TRUE); >> + } >> + >> + // Clear all errors >> + TargetAddress =3D RootComplex->MmcfgBase + ((PcieIndex + 1) << DEV_= SHIFT) \ >> + + AER_CAPABILITY_BASE + UNCORR_ERR_STATUS_OFF; >> + Val =3D MmioRead32 (TargetAddress); >> + if (Val !=3D 0) { >> + // Clear error by writting >> + MmioWrite32 (TargetAddress, Val); >> + } >> + } >> +} >> + >> +/** >> + Comparing current link status with the max capabilities of the link >> + >> + @param RootComplex Pointer to AC01_ROOT_COMPLEX structure >> + @param PcieIndex PCIe controller index >> + @param EpMaxWidth EP max link width >> + @param EpMaxGen EP max link speed >> + >> + @retval -1: Link status do not match with link max capab= ilities >> + 1: Link capabilites are invalid >> + 0: Link status are correct >> +**/ >> +INT32 >> +Ac01PcieCoreLinkCheck ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN UINT8 PcieIndex, >> + IN UINT8 EpMaxWidth, >> + IN UINT8 EpMaxGen >> + ) >> +{ >> + PHYSICAL_ADDRESS CsrBase, CfgBase; >> + UINT32 Val, LinkStat; >> + UINT32 MaxWidth, MaxGen; >> + >> + CsrBase =3D RootComplex->Pcie[PcieIndex].CsrBase; >> + CfgBase =3D RootComplex->MmcfgBase + (RootComplex->Pcie[PcieIndex].De= vNum << DEV_SHIFT); >> + >> + Val =3D MmioRead32 (CfgBase + PCIE_CAPABILITY_BASE + LINK_CAPABILITIE= S_REG); >> + if ((CAP_MAX_LINK_WIDTH_GET (Val) =3D=3D 0) || >> + (CAP_MAX_LINK_SPEED_GET (Val) =3D=3D 0)) { >> + DEBUG ((DEBUG_INFO, "\tPCIE%d.%d: Wrong RootComplex capabilities\n"= , RootComplex->ID, PcieIndex)); >> + return LINK_CHECK_WRONG_PARAMETER; >> + } >> + >> + if ((EpMaxWidth =3D=3D 0) || (EpMaxGen =3D=3D 0)) { >> + DEBUG ((DEBUG_INFO, "\tPCIE%d.%d: Wrong EP capabilities\n", RootCom= plex->ID, PcieIndex)); >> + return LINK_CHECK_FAILED; >> + } >> + >> + // Compare RootComplex and EP capabilities >> + if (CAP_MAX_LINK_WIDTH_GET (Val) > EpMaxWidth) { >> + MaxWidth =3D EpMaxWidth; >> + } else { >> + MaxWidth =3D CAP_MAX_LINK_WIDTH_GET (Val); >> + } >> + >> + // Compare RootComplex and EP capabilities >> + if (CAP_MAX_LINK_SPEED_GET (Val) > EpMaxGen) { >> + MaxGen =3D EpMaxGen; >> + } else { >> + MaxGen =3D CAP_MAX_LINK_SPEED_GET (Val); >> + } >> + >> + LinkStat =3D MmioRead32 (CsrBase + AC01_PCIE_CORE_LINK_STAT_REG); >> + Val =3D MmioRead32 (CfgBase + PCIE_CAPABILITY_BASE + LINK_CONTROL_LIN= K_STATUS_REG); >> + DEBUG (( >> + DEBUG_INFO, >> + "PCIE%d.%d: Link MaxWidth %d MaxGen %d, AC01_PCIE_CORE_LINK_STAT_RE= G 0x%x", >> + RootComplex->ID, >> + PcieIndex, >> + MaxWidth, >> + MaxGen, >> + LinkStat >> + )); >> + >> + // Checking all conditions of the link >> + // If one of them is not sastified, return link up fail >> + if ((CAP_NEGO_LINK_WIDTH_GET (Val) !=3D MaxWidth) || >> + (CAP_LINK_SPEED_GET (Val) !=3D MaxGen) || >> + (RDLH_SMLH_LINKUP_STATUS_GET (LinkStat) !=3D (SMLH_LINK_UP_MASK_B= IT | RDLH_LINK_UP_MASK_BIT))) >> + { >> + DEBUG ((DEBUG_INFO, "\tLinkCheck FAILED\n")); >> + return LINK_CHECK_FAILED; >> + } >> + >> + DEBUG ((DEBUG_INFO, "\tLinkCheck SUCCESS\n")); >> + return LINK_CHECK_SUCCESS; >> +} >> + >> +INT32 >> +PFACounterRead ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN UINT8 PcieIndex, >> + IN UINT64 RasDesCapabilityBase >> + ) >> +{ >> + INT32 Ret =3D LINK_CHECK_SUCCESS; >> + UINT32 Val; >> + UINT8 ErrCode, ErrGrpNum; >> + >> + UINT32 ErrCtrlCfg[] =3D { >> + 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, 0x008, 0x00= 9, 0x00A, // Per Lane >> + 0x105, 0x106, 0x107, 0x108, 0x109, 0x10A, >> + 0x200, 0x201, 0x202, 0x203, 0x204, 0x205, 0x206, 0x207, >> + 0x300, 0x301, 0x302, 0x303, 0x304, 0x305, >> + 0x400, 0x401, = // Per Lane >> + 0x500, 0x501, 0x502, 0x503, 0x504, 0x505, 0x506, 0x507, 0x508, 0x50= 9, 0x50A, 0x50B, 0x50C, 0x50D >> + }; >> + >> + for (ErrCode =3D 0; ErrCode < ARRAY_SIZE (ErrCtrlCfg); ErrCode++) { >> + ErrGrpNum =3D GET_HIGH_8_BITS (ErrCtrlCfg[ErrCode]); >> + // Skipping per lane group >> + // Checking common lane group because AER error are included in com= mon group only >> + if ((ErrGrpNum !=3D 0) && (ErrGrpNum !=3D 4)) { >> + Val =3D MmioRead32 (RasDesCapabilityBase + EVENT_COUNTER_CONTROL_= REG); >> + if (RootComplex->Type =3D=3D RootComplexTypeA) { >> + // RootComplexTypeA - 4 PCIe controller per port, 1 controller = in charge of 4 lanes >> + Val =3D ECCR_LANE_SEL_SET (Val, PcieIndex * 4); >> + } else { >> + // RootComplexTypeB - 8 PCIe controller per port, 1 controller = in charge of 2 lanes >> + Val =3D ECCR_LANE_SEL_SET (Val, PcieIndex * 2); >> + } >> + Val =3D ECCR_GROUP_EVENT_SEL_SET (Val, ErrCtrlCfg[ErrCode]); >> + MmioWrite32 (RasDesCapabilityBase + EVENT_COUNTER_CONTROL_REG, Va= l); >> + >> + // After setting Counter Control reg >> + // This delay just to make sure Counter Data reg is update with n= ew value >> + MicroSecondDelay (1); >> + Val =3D MmioRead32 (RasDesCapabilityBase + EVENT_COUNTER_DATA_REG= ); >> + if (Val !=3D 0) { >> + Ret =3D LINK_CHECK_FAILED; >> + DEBUG (( >> + DEBUG_ERROR, >> + "\tSocket%d RootComplex%d RP%d \t%s: %d \tGROUP:%d-EVENT:%d\n= ", >> + RootComplex->Socket, >> + RootComplex->ID, >> + PcieIndex, >> + Val, >> + ErrGrpNum, >> + GET_LOW_8_BITS (ErrCtrlCfg[ErrCode]) >> + )); >> + } >> + } >> + } >> + >> + return Ret; >> +} >> + >> +/** >> + Handle Predictive Failure Analysis command >> + >> + @param RootComplex Pointer to Root Complex structure >> + @param PcieIndex PCIe controller index >> + @param PFAMode The PFA mode >> + >> + @retval The link status >> +**/ >> +INT32 >> +Ac01PFACommand ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN UINT8 PcieIndex, >> + IN UINT8 PFAMode >> + ) >> +{ >> + PHYSICAL_ADDRESS CfgBase; >> + PHYSICAL_ADDRESS RasDesCapabilityBase; >> + PHYSICAL_ADDRESS TargetAddress; >> + INT32 Ret =3D LINK_CHECK_SUCCESS; >> + UINT32 Val; >> + >> + CfgBase =3D RootComplex->MmcfgBase + (RootComplex->Pcie[PcieIndex].De= vNum << DEV_SHIFT); >> + >> + // Allow programming to config space >> + EnableDbiAccess (RootComplex, PcieIndex, TRUE); >> + >> + // Get the RAS D.E.S. capability base address >> + RasDesCapabilityBase =3D GetCapabilityBase (RootComplex, PcieIndex, T= RUE, RAS_DES_CAPABILITY_ID); >> + if (RasDesCapabilityBase =3D=3D 0) { >> + DEBUG ((DEBUG_INFO, "PCIE%d.%d: Cannot get RAS DES capability addre= ss\n", RootComplex->ID, PcieIndex)); >> + return LINK_CHECK_WRONG_PARAMETER; >> + } >> + >> + TargetAddress =3D RasDesCapabilityBase + EVENT_COUNTER_CONTROL_REG; >> + >> + switch (PFAMode) { >> + case PFA_MODE_ENABLE: >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D ECCR_EVENT_COUNTER_ENABLE_SET (Val, EVENT_COUNTER_ENABLE_AL= L_ON); >> + Val =3D ECCR_EVENT_COUNTER_CLEAR_SET (Val, EVENT_COUNTER_CLEAR_NO_C= HANGE); >> + MmioWrite32 (TargetAddress, Val); >> + break; >> + >> + case PFA_MODE_CLEAR: >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D ECCR_EVENT_COUNTER_ENABLE_SET (Val, EVENT_COUNTER_ENABLE_NO= _CHANGE); >> + Val =3D ECCR_EVENT_COUNTER_CLEAR_SET (Val, EVENT_COUNTER_CLEAR_ALL_= CLEAR); >> + MmioWrite32 (TargetAddress, Val); >> + break; >> + >> + case PFA_MODE_READ: >> + Ret =3D PFACounterRead (RootComplex, PcieIndex, RasDesCapabilityBas= e); >> + break; >> + >> + default: >> + DEBUG ((DEBUG_ERROR, "%a: Invalid PFA mode\n")); >> + } >> + >> + // Disable programming to config space >> + EnableDbiAccess (RootComplex, PcieIndex, FALSE); >> + >> + return Ret; >> +} >> + >> +UINT32 >> +EndpointCfgReady ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN UINT8 PcieIndex >> + ) >> +{ >> + PHYSICAL_ADDRESS CfgBase; >> + UINT32 TimeOut; >> + UINT32 Val; >> + >> + CfgBase =3D RootComplex->MmcfgBase + (RootComplex->Pcie[PcieIndex].De= vNum << BUS_SHIFT); >> + >> + // Loop read CfgBase value until got valid value or >> + // reach to timeout EP_LINKUP_TIMEOUT (or more depend on card) >> + TimeOut =3D EP_LINKUP_TIMEOUT; >> + do { >> + Val =3D MmioRead32 (CfgBase); >> + if (Val !=3D 0xFFFF0001 && Val !=3D 0xFFFFFFFF) { >> + return TRUE; >> + } >> + >> + TimeOut -=3D LINK_WAIT_INTERVAL_US; >> + MicroSecondDelay (LINK_WAIT_INTERVAL_US); >> + } while (TimeOut > 0); >> + >> + return FALSE; >> +} >> + >> +/** >> + Get link capabilities link width and speed of endpoint >> + >> + @param RootComplex[in] Pointer to AC01_ROOT_COMPLEX structure >> + @param PcieIndex[in] PCIe controller index >> + @param EpMaxWidth[out] EP max link width >> + @param EpMaxGen[out] EP max link speed >> +**/ >> +VOID >> +Ac01PcieCoreGetEndpointInfo ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN UINT8 PcieIndex, >> + OUT UINT8 *EpMaxWidth, >> + OUT UINT8 *EpMaxGen >> + ) >> +{ >> + PHYSICAL_ADDRESS CfgBase; >> + PHYSICAL_ADDRESS PcieCapBase; >> + PHYSICAL_ADDRESS SecLatTimerAddr; >> + PHYSICAL_ADDRESS TargetAddress; >> + UINT32 RestoreVal; >> + UINT32 Val; >> + >> + CfgBase =3D RootComplex->MmcfgBase + (RootComplex->Pcie[PcieIndex].De= vNum << DEV_SHIFT); >> + SecLatTimerAddr =3D CfgBase + SEC_LAT_TIMER_SUB_BUS_SEC_BUS_PRI_BUS_= REG; >> + >> + *EpMaxWidth =3D 0; >> + *EpMaxGen =3D 0; >> + >> + // Allow programming to config space >> + EnableDbiAccess (RootComplex, PcieIndex, TRUE); >> + >> + Val =3D MmioRead32 (SecLatTimerAddr); >> + RestoreVal =3D Val; >> + Val =3D SUB_BUS_SET (Val, DEFAULT_SUB_BUS); >> + Val =3D SEC_BUS_SET (Val, RootComplex->Pcie[PcieIndex].DevNum); >> + Val =3D PRIM_BUS_SET (Val, DEFAULT_PRIM_BUS); >> + MmioWrite32 (SecLatTimerAddr, Val); >> + >> + if (EndpointCfgReady (RootComplex, PcieIndex)) { >> + PcieCapBase =3D GetCapabilityBase (RootComplex, PcieIndex, FALSE, P= CIE_CAPABILITY_ID); >> + if (PcieCapBase =3D=3D 0) { >> + DEBUG (( >> + DEBUG_ERROR, >> + "PCIE%d.%d Cannot get PCIe capability base address!\n", >> + RootComplex->ID, >> + PcieIndex >> + )); >> + } else { >> + Val =3D MmioRead32 (PcieCapBase + LINK_CAPABILITIES_REG); >> + *EpMaxWidth =3D CAP_MAX_LINK_WIDTH_GET (Val); >> + *EpMaxGen =3D CAP_MAX_LINK_SPEED_GET (Val); >> + DEBUG (( >> + DEBUG_INFO, >> + "PCIE%d.%d EP MaxWidth %d EP MaxGen %d \n", RootComplex->ID, >> + PcieIndex, >> + *EpMaxWidth, >> + *EpMaxGen >> + )); >> + >> + // From EP, enabling common clock for upstream >> + TargetAddress =3D PcieCapBase + LINK_CONTROL_LINK_STATUS_REG; >> + Val =3D MmioRead32 (TargetAddress); >> + Val =3D CAP_SLOT_CLK_CONFIG_SET (Val, 1); >> + Val =3D CAP_COMMON_CLK_SET (Val, 1); >> + MmioWrite32 (TargetAddress, Val); >> + } >> + } >> + >> + // Restore value in order to not affect enumeration process >> + MmioWrite32 (SecLatTimerAddr, RestoreVal); >> + >> + // Disable programming to config space >> + EnableDbiAccess (RootComplex, PcieIndex, FALSE); >> +} >> + >> +VOID >> +PollLinkUp ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN UINT8 PcieIndex >> + ) >> +{ >> + UINT32 TimeOut; >> + >> + // Poll until link up >> + // This checking for linkup status and >> + // give LTSSM state the time to transit from DECTECT state to L0 stat= e >> + // Total delay are 100ms, smaller number of delay cannot always make = sure >> + // the state transition is completed >> + TimeOut =3D LTSSM_TRANSITION_TIMEOUT; >> + do { >> + if (PcieLinkUpCheck (&RootComplex->Pcie[PcieIndex])) { >> + DEBUG (( >> + DEBUG_INFO, >> + "\tPCIE%d.%d LinkStat is correct after soft reset, transition t= ime: %d\n", >> + RootComplex->ID, >> + PcieIndex, >> + TimeOut >> + )); >> + RootComplex->Pcie[PcieIndex].LinkUp =3D TRUE; >> + break; >> + } >> + >> + MicroSecondDelay (100); >> + TimeOut -=3D 100; >> + } while (TimeOut > 0); >> + >> + if (TimeOut <=3D 0) { >> + DEBUG ((DEBUG_ERROR, "\tPCIE%d.%d LinkStat TIMEOUT after re-init\n"= , RootComplex->ID, PcieIndex)); >> + } else { >> + DEBUG ((DEBUG_INFO, "PCIE%d.%d Link re-initialization passed!\n", R= ootComplex->ID, PcieIndex)); >> + } >> +} >> + >> +/** >> + Check active PCIe controllers of RootComplex, retrain or soft reset i= f needed >> + >> + @param RootComplex[in] Pointer to AC01_ROOT_COMPLEX structure >> + @param PcieIndex[in] PCIe controller index >> + >> + @retval -1: Link recovery had failed >> + 1: Link width and speed are not correct >> + 0: Link recovery succeed >> +**/ >> +INT32 >> +Ac01PcieCoreQoSLinkCheckRecovery ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN UINT8 PcieIndex >> + ) >> +{ >> + INT32 LinkStatusCheck, RasdesChecking; >> + INT32 NumberOfReset =3D MAX_REINIT; >> + UINT8 EpMaxWidth, EpMaxGen; >> + >> + // PCIe controller is not active or Link is not up >> + // Nothing to be done >> + if ((!RootComplex->Pcie[PcieIndex].Active) || (!RootComplex->Pcie[Pci= eIndex].LinkUp)) { >> + return LINK_CHECK_WRONG_PARAMETER; >> + } >> + >> + do { >> + if (RootComplex->Pcie[PcieIndex].LinkUp) { >> + // Enable all of RASDES register to detect any training error >> + Ac01PFACommand (RootComplex, PcieIndex, PFA_MODE_ENABLE); >> + >> + // Accessing Endpoint and checking current link capabilities >> + Ac01PcieCoreGetEndpointInfo (RootComplex, PcieIndex, &EpMaxWidth,= &EpMaxGen); >> + LinkStatusCheck =3D Ac01PcieCoreLinkCheck (RootComplex, PcieIndex= , EpMaxWidth, EpMaxGen); >> + >> + // Delay to allow the link to perform internal operation and gene= rate >> + // any error status update. This allows detection of any error ob= served >> + // during initial link training. Possible evaluation time can be >> + // between 100ms to 200ms. >> + MicroSecondDelay (100000); >> + >> + // Check for error >> + RasdesChecking =3D Ac01PFACommand (RootComplex, PcieIndex, PFA_MO= DE_READ); >> + >> + // Clear error counter >> + Ac01PFACommand (RootComplex, PcieIndex, PFA_MODE_CLEAR); >> + >> + // If link check functions return passed, then breaking out >> + // else go to soft reset >> + if (LinkStatusCheck !=3D LINK_CHECK_FAILED && >> + RasdesChecking !=3D LINK_CHECK_FAILED && >> + PcieLinkUpCheck (&RootComplex->Pcie[PcieIndex])) >> + { >> + return LINK_CHECK_SUCCESS; >> + } >> + >> + RootComplex->Pcie[PcieIndex].LinkUp =3D FALSE; >> + } >> + >> + // Trigger controller soft reset >> + DEBUG ((DEBUG_INFO, "PCIE%d.%d Start link re-initialization..\n", R= ootComplex->ID, PcieIndex)); >> + Ac01PcieCoreSetupRC (RootComplex, TRUE, PcieIndex); >> + >> + PollLinkUp (RootComplex, PcieIndex); >> + >> + NumberOfReset--; >> + } while (NumberOfReset > 0); >> + >> + return LINK_CHECK_SUCCESS; >> +} >> + >> +VOID >> +Ac01PcieCoreUpdateLink ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + OUT BOOLEAN *IsNextRoundNeeded, >> + OUT INT8 *FailedPciePtr, >> + OUT INT8 *FailedPcieCount >> + ) >> +{ >> + AC01_PCIE_CONTROLLER *Pcie; >> + PHYSICAL_ADDRESS CfgBase; >> + UINT8 PcieIndex; >> + UINT32 Index; >> + UINT32 Val; >> + >> + *IsNextRoundNeeded =3D FALSE; >> + *FailedPcieCount =3D 0; >> + for (Index =3D 0; Index < MaxPcieControllerOfRootComplexB; Index++) { >> + FailedPciePtr[Index] =3D -1; >> + } >> + >> + if (!RootComplex->Active) { >> + return; >> + } >> + >> + // Loop for all controllers >> + for (PcieIndex =3D 0; PcieIndex < RootComplex->MaxPcieController; Pci= eIndex++) { >> + Pcie =3D &RootComplex->Pcie[PcieIndex]; >> + CfgBase =3D RootComplex->MmcfgBase + (RootComplex->Pcie[PcieIndex].= DevNum << DEV_SHIFT); >> + >> + if (Pcie->Active && !Pcie->LinkUp) { >> + if (PcieLinkUpCheck (Pcie)) { >> + Pcie->LinkUp =3D TRUE; >> + Val =3D MmioRead32 (CfgBase + PCIE_CAPABILITY_BASE + LINK_CONTR= OL_LINK_STATUS_REG); >> + >> + DEBUG (( >> + DEBUG_INFO, >> + "%a Socket%d RootComplex%d RP%d NEGO_LINK_WIDTH: 0x%x LINK_SP= EED: 0x%x\n", >> + __FUNCTION__, >> + RootComplex->Socket, >> + RootComplex->ID, >> + PcieIndex, >> + CAP_NEGO_LINK_WIDTH_GET (Val), >> + CAP_LINK_SPEED_GET (Val) >> + )); >> + >> + // Doing link checking and recovery if needed >> + Ac01PcieCoreQoSLinkCheckRecovery (RootComplex, PcieIndex); >> + >> + // Link timeout after 32ms >> + SetLinkTimeout (RootComplex, PcieIndex, 32); >> + >> + // Un-mask Completion Timeout >> + DisableCompletionTimeOut (RootComplex, PcieIndex, FALSE); >> + >> + } else { >> + *IsNextRoundNeeded =3D FALSE; >> + FailedPciePtr[*FailedPcieCount] =3D PcieIndex; >> + *FailedPcieCount +=3D 1; >> + } >> + } >> + } >> +} >> + >> +/** >> + Verify the link status and retry to initialize the Root Complex if th= ere's any issue. >> + >> + @param RootComplexList Pointer to the Root Complex list >> +**/ >> +VOID >> +Ac01PcieCorePostSetupRC ( >> + IN AC01_ROOT_COMPLEX *RootComplexList >> + ) >> +{ >> + UINT8 RCIndex, Idx; >> + BOOLEAN IsNextRoundNeeded, NextRoundNeeded; >> + UINT64 PrevTick, CurrTick, ElapsedCycle; >> + UINT64 TimerTicks64; >> + UINT8 ReInit; >> + INT8 FailedPciePtr[MaxPcieControllerOfRootComplexB]; >> + INT8 FailedPcieCount; >> + >> + ReInit =3D 0; >> + >> +_link_polling: >> + NextRoundNeeded =3D FALSE; >> + // >> + // It is not guaranteed the timer service is ready prior to PCI Dxe. >> + // Calculate system ticks for link training. >> + // >> + TimerTicks64 =3D ArmGenericTimerGetTimerFreq (); /* 1 Second */ >> + PrevTick =3D ArmGenericTimerGetSystemCount (); >> + ElapsedCycle =3D 0; >> + >> + do { >> + CurrTick =3D ArmGenericTimerGetSystemCount (); >> + if (CurrTick < PrevTick) { >> + ElapsedCycle +=3D MAX_UINT64 - PrevTick; >> + PrevTick =3D 0; >> + } >> + ElapsedCycle +=3D (CurrTick - PrevTick); >> + PrevTick =3D CurrTick; >> + } while (ElapsedCycle < TimerTicks64); >> + >> + for (RCIndex =3D 0; RCIndex < AC01_PCIE_MAX_ROOT_COMPLEX; RCIndex++) = { >> + Ac01PcieCoreUpdateLink (&RootComplexList[RCIndex], &IsNextRoundNeed= ed, FailedPciePtr, &FailedPcieCount); >> + if (IsNextRoundNeeded) { >> + NextRoundNeeded =3D TRUE; >> + } >> + } >> + >> + if (NextRoundNeeded && ReInit < MAX_REINIT) { >> + // >> + // Timer is up. Give another chance to re-program controller >> + // >> + ReInit++; >> + for (RCIndex =3D 0; RCIndex < AC01_PCIE_MAX_ROOT_COMPLEX; RCIndex++= ) { >> + Ac01PcieCoreUpdateLink (&RootComplexList[RCIndex], &IsNextRoundNe= eded, FailedPciePtr, &FailedPcieCount); >> + if (IsNextRoundNeeded) { >> + for (Idx =3D 0; Idx < FailedPcieCount; Idx++) { >> + if (FailedPciePtr[Idx] =3D=3D -1) { >> + continue; >> + } >> + >> + // >> + // Some controller still observes link-down. Re-init controll= er >> + // >> + Ac01PcieCoreSetupRC (&RootComplexList[RCIndex], TRUE, FailedP= ciePtr[Idx]); >> + } >> + } >> + } >> + >> + goto _link_polling; >> + } >> +} >> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/BoardPcieLibNull/Boar= dPcieLibNull.c b/Silicon/Ampere/AmpereAltraPkg/Library/BoardPcieLibNull/Boa= rdPcieLibNull.c >> new file mode 100644 >> index 000000000000..0916adb77539 >> --- /dev/null >> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/BoardPcieLibNull/BoardPcieLi= bNull.c >> @@ -0,0 +1,47 @@ >> +/** @file >> + >> + Copyright (c) 2021, Ampere Computing LLC. All rights reserved.
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> + >> +**/ >> + >> +#include >> + >> +/** >> + Assert PERST of input PCIe controller >> + >> + @param[in] RootComplex RootComplex instance. >> + @param[in] PcieIndex PCIe controller index of input Root= Complex. >> + @param[in] Bifurcation Bifurcation mode of input Root Comp= lex. >> + @param[in] IsPullToHigh Target status for the PERST. >> + >> + @retval RETURN_SUCCESS The operation is successful. >> + @retval Others An error occurred. >> +**/ >> +RETURN_STATUS >> +EFIAPI >> +BoardPcieAssertPerst ( >> + IN AC01_ROOT_COMPLEX *RootComplex, >> + IN UINT8 PcieIndex, >> + IN BOOLEAN IsPullToHigh >> + ) >> +{ >> + return RETURN_SUCCESS; >> +} >> + >> +/** >> + Override the segment number for a root complex with a board specific = number. >> + >> + @param[in] RootComplex Root Complex instance with properti= es. >> + >> + @retval Segment number corresponding to the input root complex. >> + Default segment number is 0x0F. >> +**/ >> +UINT16 >> +BoardPcieGetSegmentNumber ( >> + IN AC01_ROOT_COMPLEX *RootComplex >> + ) >> +{ >> + return 0x0F; >> +} >> --=20 >> 2.17.1 >>