From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (NAM10-MW2-obe.outbound.protection.outlook.com [40.107.94.122]) by mx.groups.io with SMTP id smtpd.web12.5468.1622023923015422447 for ; Wed, 26 May 2021 03:12:03 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@os.amperecomputing.com header.s=selector2 header.b=X+JYaW/A; spf=pass (domain: os.amperecomputing.com, ip: 40.107.94.122, mailfrom: nhi@os.amperecomputing.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=eIO7PM8WlBpsRmq5vsvRJF5a//MWCcHGvwEZv2KsX1gO4wl5l2iqXs2ft1W3UxVN8ZFNGmZVYLcKPxyqi0aWyNZwO/AYGH38F8aCwkQVTPuyoMQ7OFi78LwzL2oUBXNvJB6RqQgUeSrRVVL/FhBd4LHsahYbD27b7y7eIY8HxCPsjfr0xEXObrwTTpG74SFPgMklvKlom49rYXbMOsFzJtP0sW4C55nA2OMwxCmjYp4GUSgqCe5IMI/+B1Di24+QF9+LMhNm2MYRdvrIwImdlsrm+jTBNTTdw/L2Uuuz44jYG+CJfiP6X+D/bLDe8iKoOS9KLtJruolr5t20eUq/5g== 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-SenderADCheck; bh=s2WRN6rujQv8myPvWAuHbdfcmR5pair2dTjJPb6inN8=; b=fzKGutiBktSQq4teglECTeCKEg5RIAhoAUGGOcJiEaeL1Ucox5eYcYGNChqU+cinuIl43CSa9MyynILzYZt6RP5iemoNzVJGP9+GCGZFt1GjUII8HGaO7LpUYe3zcl676e0HSILvZbqbfm4/PZvFz2vd6NMlt5AJbyOxGLddZchrIf8H+a6r5hZm9z+KmEojMygJKeHeSnGl4kyvd2EeRHuES0B2Y8eBKizq9UoK39gYBgDNh5zeAJ2pu6g900cDFDsCLYefZS2gSULhX6ytT+TCY+EnXDDf+DjQvOZNpN6w13VM1PTiNrF0y2t9TSoldk59Y7Lnu/MFS3Htl3YfjA== 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=s2WRN6rujQv8myPvWAuHbdfcmR5pair2dTjJPb6inN8=; b=X+JYaW/ApHHJdt0wv+Ly1qJ1uZbv/1KuRGmwmy2gj4RE6dWJbo2u0lE6mYPKtr+GlxqnOxd84uv04so2fyaxNkthLZzb9I/M/9c00lqLRY3ERp4DiuUXSJ+RgieZdZMgbhWjSbTBSrmdRkfvUY/ABbiBAw9zBbgVDHAq/O7Z5m0= Authentication-Results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=os.amperecomputing.com; Received: from DM6PR01MB5849.prod.exchangelabs.com (2603:10b6:5:205::20) by DM5PR01MB2426.prod.exchangelabs.com (2603:10b6:3:3b::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4150.27; Wed, 26 May 2021 10:12:00 +0000 Received: from DM6PR01MB5849.prod.exchangelabs.com ([fe80::60d2:86dd:1f1c:51dd]) by DM6PR01MB5849.prod.exchangelabs.com ([fe80::60d2:86dd:1f1c:51dd%7]) with mapi id 15.20.4173.020; Wed, 26 May 2021 10:12:00 +0000 From: "Nhi Pham" To: devel@edk2.groups.io CC: Vu Nguyen , Thang Nguyen , Chuong Tran , Phong Vo , Leif Lindholm , Michael D Kinney , Ard Biesheuvel , Nate DeSimone Subject: [edk2-platforms][PATCH v2 15/32] JadePkg: Add PcieBoardLib library instance Date: Wed, 26 May 2021 17:07:07 +0700 Message-ID: <20210526100724.5359-17-nhi@os.amperecomputing.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210526100724.5359-1-nhi@os.amperecomputing.com> References: <20210526100724.5359-1-nhi@os.amperecomputing.com> X-Originating-IP: [118.69.219.201] X-ClientProxiedBy: HKAPR04CA0008.apcprd04.prod.outlook.com (2603:1096:203:d0::18) To DM6PR01MB5849.prod.exchangelabs.com (2603:10b6:5:205::20) Return-Path: nhi@os.amperecomputing.com MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from localhost.localdomain (118.69.219.201) by HKAPR04CA0008.apcprd04.prod.outlook.com (2603:1096:203:d0::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4173.20 via Frontend Transport; Wed, 26 May 2021 10:11:57 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 17eb367f-3478-44ba-4b11-08d9202eb358 X-MS-TrafficTypeDiagnostic: DM5PR01MB2426: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:6430; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: CZbRBx4D/JmGW8pWww/SY9jPk/P2TtWv+pPeK2DtO2voRQuQuBSdFk/BZuMuSoiZbhtkAf7b8qdi2tfsb0WpfBYd2AM4kZ38HLpPsFpUPdgqKU8VndRRBnkRFwsARzl2tFo1HdPSyrfLWFGyO06l+IfoFlNQ0thgoJ4VX7P9alALGvEPUiZeWKSBX1bmDeJznbX8QiUOtDiHfDqfTx0fe7oDwuv+vmN9mAL7phfin5g63ag0GY0/hHusbZPlhBnSR/RMhHp6bYxeOBgk/NnPnaOF7AgW16MEcwj+k/+xjwpe2gZoeWVEINqpO+b3ECkNI/wqJs1YlGUaklzZfUbx06UwpZqbr9/DgLDxrhQb8uPoXvmZhUwyEeUdzFnl0LJsoNxATChG7Uunp8eHOOmpsmlnBkFZeVBH/u8gaqhSbmVIQzd0vl7qFI13S5i/OyZAWrzzC2Tdb3f0atv3teE56JosfLs4XuNfa/2d+MZzwIDR6eGnxYFC7/aNXGfxGNfxici1tn4Nzn+hasgwXR2hJ6LTig5/kroMneA5B3AMJ0my0ja/XO/Epor0ybDzr7AlhjnRBBtjLjTq5moYNTm54d7tY56BDKCwIeg1CTeC+qpEDZACmcF+IXujKayR/wqYU1UiTeFXmAls5CEH3EZ54fAui36MlPGHiMt1nnM/ydYaQ+Nf+qQFMK2gLIj5rhy2uDw4peUihZx+74mRFIhEjy960zQy2byBWrd7AgZx+SWs9lMELAOZDzAw2CubqkKG X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DM6PR01MB5849.prod.exchangelabs.com;PTR:;CAT:NONE;SFS:(4636009)(396003)(39850400004)(136003)(346002)(366004)(376002)(186003)(66476007)(6506007)(2616005)(6486002)(66946007)(52116002)(6916009)(16526019)(66574015)(38100700002)(38350700002)(1076003)(83380400001)(30864003)(66556008)(6512007)(956004)(316002)(478600001)(6666004)(4326008)(8676002)(5660300002)(26005)(86362001)(2906002)(8936002)(54906003)(69590400013)(290074003)(579004)(559001)(44824005);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?8SLxiW1VxzAmKSag+Er4D/zC09qO89N837zyFT+/BCV+YSDM0YZTvqNEio8i?= =?us-ascii?Q?okYmnxY4ggyJNZssUvjfoC+vPW0NgVggWyIkRibKAPiLnhFfSpw8PtmGrIX7?= =?us-ascii?Q?0l74ob4QxQPZ4GaD3TJaJACMTiVN+hNhRNJkdOhqsNdTyAeRiMhGuyw2Js3j?= =?us-ascii?Q?smZY7TGTGX8lyoJJ/MT1aIeo8nWxPwWB0o8kry/qlcQ91O87wmsHjL42soJ6?= =?us-ascii?Q?JoPq0/f/hYhlxHYN4RbqY+mfoMROQzHEd0rqNh9JK/jaEHnbIFHx1dwfiKdy?= =?us-ascii?Q?hT9SdIV+XF1V1kCQhftQSt9mm11qhHEhM1S3l1rx62jDXmDqZqBAFlNmxl0w?= =?us-ascii?Q?tmcuG+wyKuXdVx3rrzAIshAXvGmeoH8L58aGcOIoWo2MpwGwT76dGSLR3E39?= =?us-ascii?Q?7/i8Kz2GXfj+pV3hPGxObnsQxYiMoJqA5+mD75a1RsH0vqd2qUNYkuetUk3z?= =?us-ascii?Q?4KRivVSBEiZYVN605DEn7iA3HZVfZThrJ7CDRQeaElevymXz8ojNHSQ5QB+h?= =?us-ascii?Q?3eu/Fu1urUkQDlw4uUifeP45dcy6l9Tffazl9clF43kq+ffUaE96JyavoH1g?= =?us-ascii?Q?DnN45w8jjWQvcFs+xl02nrzjKh0ezkhfmMVGsssH8QdZx7jymtvx7qfFPoEs?= =?us-ascii?Q?wmHekCbKixllzSosI4KVE6w3xRGi3Vszm7bjhC2QtAHvHhVeJRazBQyVSn5N?= =?us-ascii?Q?xRaUSWY6lr5pn/OqC6xf91+XVyUXsJsvvNJR9pbWtRxqXmYJIFjNQMGanSWB?= =?us-ascii?Q?c3vvH5w+oBG7VRfeLC80EaTLUE7RvbQ3eZCsTdBX9/OKDYPko5CdWv6ZzO5m?= =?us-ascii?Q?N8bYVz0voMg/L0T1fe2rRNuTkz+AqKU5jodnva1kiHGGEvSAyWNuUH4DKkhc?= =?us-ascii?Q?CMBfBPiB1RznKnrWDRYahWMprrInhiHqkijuSh9E934G7dhXe17vfzDugbcW?= =?us-ascii?Q?bGkegscDtVmktl2wELpJ1qUXtEGY1KXK8pGhmqaG6uUp2Ho4OWNuJIKh/cDo?= =?us-ascii?Q?xpCZzcIQAd3/fAU63ZMTFN81c0imXc+0GOppgpFVqbWUZ4MPGQEIB74cUfHc?= =?us-ascii?Q?MH9vC/75VUtMJMnEbNud+LYj/3sZvlllkDonp6o17Em0fyZxX5Jcn/h63fcy?= =?us-ascii?Q?eMxghaejlkwDmwsOUepi4qL1bTEMsb4fpjXEOP/NmBJN4kCh2CDkNSUAYgdI?= =?us-ascii?Q?jXYr601zO9UDPC9dCQYzemzasd51GRH+PwCTq/YNJLmNgih7xbb+NPJ+jizh?= =?us-ascii?Q?NeMBA+NCm+Fgwi3bqWKGmg5OlrkkGZOLa/r8AKD/3Mwz+9A0QHYLiD+36y3O?= =?us-ascii?Q?2KehCCqKRDImXsSVukMEtIdO?= X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: 17eb367f-3478-44ba-4b11-08d9202eb358 X-MS-Exchange-CrossTenant-AuthSource: DM6PR01MB5849.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 May 2021 10:12:00.1936 (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: hDfGXCNef5iGdIwowCtEeQ142QwOpgJbL27DkdsxB0VRoeTES6lb6HnBfT1Feqkms5n++NO2zpNtL2qhGPUIAFVv5prbgyKu528tV3I08oo= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR01MB2426 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain From: Vu Nguyen Provides basic features like: * Screen menu to change bifurcation setting of each Root Complex. Note that we can only change the option for Root Complex which doesn't have default value in the BoardSetting. * Parsing the BoardSetting and coordinate with saved setting to enable corresponding PCIe controller of each Root Complex. * Config speed and lane of enabled controller. 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: Vu Nguyen --- Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec | 3 + Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf | 60 ++ Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h | 89 ++ Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h | 138 ++= + Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h | 102 ++ Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr | 212 ++= ++ Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c | 438 ++= ++++++ Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c | 327 ++= ++++ Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c | 1120 ++= ++++++++++++++++++ Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni | 99 ++ 10 files changed, 2588 insertions(+) diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Amp= ere/AmpereAltraPkg/AmpereAltraPkg.dec index 0d79673ce50a..a372a4e0078b 100644 --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec @@ -40,6 +40,9 @@ [LibraryClasses] ## @libraryclass Defines a set of methods to initialize Pcie PcieCoreLib|Silicon/Ampere/AmpereAltraP/Include/Library/PcieCoreLib.h =20 + ## @libraryclass Defines a set of miscellaneous PCIe functions + PcieBoardLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.= h + ## @libraryclass Defines a set of methods to access flash memory. FlashLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h =20 diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf = b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf new file mode 100644 index 000000000000..6be78f8936d7 --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf @@ -0,0 +1,60 @@ +## @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 PcieBoardLib + FILE_GUID =3D 062191A6-E113-4FD6-84C7-E400B4B34759 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D PcieBoardLib + +[Sources] + PcieBoard.c + PcieBoardCommon.c + PcieBoardScreen.c + PcieBoardScreen.h + PcieBoardScreen.uni + NVDataStruc.h + Vfr.vfr + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec + Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec + +[LibraryClasses] + AmpereCpuLib + BaseLib + DevicePathLib + GpioLib + HiiLib + HobLib + MemoryAllocationLib + SystemFirmwareInterfaceLib + UefiBootServicesTableLib + UefiLib + UefiRuntimeServicesTableLib + +[Protocols] + gEfiDevicePathProtocolGuid + gEfiHiiStringProtocolGuid ## CONSUMES + gEfiHiiConfigRoutingProtocolGuid ## CONSUMES + gEfiHiiConfigAccessProtocolGuid ## PRODUCES + gEfiHiiDatabaseProtocolGuid ## CONSUMES + gEfiConfigKeywordHandlerProtocolGuid ## CONSUMES + +[Guids] + gEfiIfrTianoGuid ## CONSUMES + gPlatformManagerFormsetGuid ## CONSUMES + gPlatformHobGuid ## CONSUMES + +[Depex] + TRUE diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h b/P= latform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h new file mode 100644 index 000000000000..f94f12d968fd --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h @@ -0,0 +1,89 @@ +/** @file + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef NVDATASTRUC_H_ +#define NVDATASTRUC_H_ + +#define MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX 16 + +#define PCIE_VARSTORE_NAME L"PcieIfrNVData" +#define PCIE_VARSTORE_ID 0x1234 +#define PCIE_FORM_ID 0x1235 +#define PCIE_RC0_FORM_ID 0x1236 +#define PCIE_RC1_FORM_ID 0x1237 +#define PCIE_RC2_FORM_ID 0x1238 +#define PCIE_RC3_FORM_ID 0x1239 +#define PCIE_RC4_FORM_ID 0x123A +#define PCIE_RC5_FORM_ID 0x123B +#define PCIE_RC6_FORM_ID 0x123C +#define PCIE_RC7_FORM_ID 0x123D +#define PCIE_RC8_FORM_ID 0x123E +#define PCIE_RC9_FORM_ID 0x123F +#define PCIE_RC10_FORM_ID 0x1240 +#define PCIE_RC11_FORM_ID 0x1241 +#define PCIE_RC12_FORM_ID 0x1242 +#define PCIE_RC13_FORM_ID 0x1243 +#define PCIE_RC14_FORM_ID 0x1244 +#define PCIE_RC15_FORM_ID 0x1245 +#define PCIE_FORM_SET_GUID { 0xe84e70d6, 0xe4b2, 0x4c6e, { 0x98, 0= x51, 0xcb, 0x2b, 0xac, 0x77, 0x7d, 0xbb } } + +#define PCIE_GOTO_ID_BASE 0x8040 + +#pragma pack(1) + +// +// NV data structure definition +// +typedef struct { + BOOLEAN RCStatus[MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX]; + UINT8 RCBifurLo[MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX]; + UINT8 RCBifurHi[MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX]; + UINT32 SmmuPmu; +} PCIE_VARSTORE_DATA; + +// +// Labels definition +// +#define LABEL_UPDATE 0x2223 +#define LABEL_END 0x2224 +#define LABEL_RC0_UPDATE 0x2225 +#define LABEL_RC0_END 0x2226 +#define LABEL_RC1_UPDATE 0x2227 +#define LABEL_RC1_END 0x2228 +#define LABEL_RC2_UPDATE 0x2229 +#define LABEL_RC2_END 0x222A +#define LABEL_RC3_UPDATE 0x222B +#define LABEL_RC3_END 0x222C +#define LABEL_RC4_UPDATE 0x222D +#define LABEL_RC4_END 0x222E +#define LABEL_RC5_UPDATE 0x222F +#define LABEL_RC5_END 0x2230 +#define LABEL_RC6_UPDATE 0x2231 +#define LABEL_RC6_END 0x2232 +#define LABEL_RC7_UPDATE 0x2233 +#define LABEL_RC7_END 0x2234 +#define LABEL_RC8_UPDATE 0x2235 +#define LABEL_RC8_END 0x2236 +#define LABEL_RC9_UPDATE 0x2237 +#define LABEL_RC9_END 0x2238 +#define LABEL_RC10_UPDATE 0x2239 +#define LABEL_RC10_END 0x223A +#define LABEL_RC11_UPDATE 0x223B +#define LABEL_RC11_END 0x223C +#define LABEL_RC12_UPDATE 0x223D +#define LABEL_RC12_END 0x223E +#define LABEL_RC13_UPDATE 0x223F +#define LABEL_RC13_END 0x2240 +#define LABEL_RC14_UPDATE 0x2241 +#define LABEL_RC14_END 0x2242 +#define LABEL_RC15_UPDATE 0x2243 +#define LABEL_RC15_END 0x2244 + +#pragma pack() + +#endif diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h= b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h new file mode 100644 index 000000000000..c5c50060870c --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h @@ -0,0 +1,138 @@ +/** @file + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PCIE_SCREEN_H_ +#define PCIE_SCREEN_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "NVDataStruc.h" + +// +// This is the generated IFR binary data for each formset defined in VFR. +// This data array is ready to be used as input of HiiAddPackages() to +// create a packagelist (which contains Form packages, String packages, et= c). +// +extern UINT8 VfrBin[]; + +// +// This is the generated String package data for all .UNI files. +// This data array is ready to be used as input of HiiAddPackages() to +// create a packagelist (which contains Form packages, String packages, et= c). +// +extern UINT8 PcieDxeStrings[]; + +#define MAX_EDITABLE_ELEMENTS 3 +#define PCIE_RC0_STATUS_OFFSET \ + OFFSET_OF (PCIE_VARSTORE_DATA, RCStatus[0]) +#define PCIE_RC0_BIFUR_LO_OFFSET \ + OFFSET_OF (PCIE_VARSTORE_DATA, RCBifurLo[0]) +#define PCIE_RC0_BIFUR_HI_OFFSET \ + OFFSET_OF (PCIE_VARSTORE_DATA, RCBifurHi[0]) +#define PCIE_SMMU_PMU_OFFSET \ + OFFSET_OF (PCIE_VARSTORE_DATA, SmmuPmu) + +#define PCIE_SCREEN_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('P', 'C', 'I', 'E= ') + +typedef struct { + UINTN Signature; + + EFI_HANDLE DriverHandle; + EFI_HII_HANDLE HiiHandle; + PCIE_VARSTORE_DATA VarStoreConfig; + + // + // Consumed protocol + // + EFI_HII_DATABASE_PROTOCOL *HiiDatabase; + EFI_HII_STRING_PROTOCOL *HiiString; + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; + EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler; + + // + // Produced protocol + // + EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess; +} PCIE_SCREEN_PRIVATE_DATA; + +typedef union { + UINT16 VAR_ID; + struct _PCIE_VAR_ID { + UINT16 PciDevIndex : 12; + UINT16 DataType : 3; + UINT16 Always1 : 1; + } IdField; +} PCIE_VAR_ID; + +typedef struct { + UINTN PciDevIdx; + EFI_STRING_ID GotoStringId; + EFI_STRING_ID GotoHelpStringId; + UINT16 GotoKey; + BOOLEAN ShowItem; +} PCIE_SETUP_GOTO_DATA; + +typedef struct { + VOID *StartOpCodeHandle; + VOID *EndOpCodeHandle; + EFI_IFR_GUID_LABEL *StartLabel; + EFI_IFR_GUID_LABEL *EndLabel; + +} PCIE_IFR_INFO; + +#define PCIE_SCREEN_PRIVATE_FROM_THIS(a) \ + CR (a, PCIE_SCREEN_PRIVATE_DATA, ConfigAccess, PCIE_SCREEN_PRIVATE_DATA_= SIGNATURE) + +#pragma pack(1) + +/// +/// HII specific Vendor Device Path definition. +/// +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} HII_VENDOR_DEVICE_PATH; + +#pragma pack() + +UINT8 +PcieRCDevMapLoDefaultSetting ( + IN UINTN RCIndex, + IN PCIE_SCREEN_PRIVATE_DATA *PrivateData + ); + +UINT8 +PcieRCDevMapHiDefaultSetting ( + IN UINTN RCIndex, + IN PCIE_SCREEN_PRIVATE_DATA *PrivateData + ); + +BOOLEAN +PcieRCActiveDefaultSetting ( + IN UINTN RCIndex, + IN PCIE_SCREEN_PRIVATE_DATA *PrivateData + ); + +#endif /* PCIE_SCREEN_H_ */ diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h b= /Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h new file mode 100644 index 000000000000..bff5b62ba13b --- /dev/null +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h @@ -0,0 +1,102 @@ +/** @file + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PCIE_BOARD_LIB_H_ +#define PCIE_BOARD_LIB_H_ + +#include "Pcie.h" + +/** + + Check if a PCIE port enabled in the board configuration. + + @param Index The port index. + + @retval TRUE if the port enabled, otherwise FA= LSE. + +**/ +BOOLEAN +PcieBoardCheckSysSlotEnabled ( + IN UINTN Index + ); + +VOID +PcieBoardGetRCSegmentNumber ( + IN AC01_RC *RC, + OUT UINTN *SegmentNumber + ); + +/** + + Check if SMM PMU enabled in board screen + + @retval TRUE if the SMMU PMU enabled, otherwis= e FALSE. + +**/ +BOOLEAN +PcieBoardCheckSmmuPmuEnabled ( + VOID + ); + +/** + + Build UEFI menu. + + @param ImageHandle Handle. + @param SystemTable Pointer to System Table. + @param RCList List of Root Complex with properties. + + @retval EFI_SUCCESS if successful, otherwise E= FI_ERROR. + +**/ +EFI_STATUS +PcieBoardScreenInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable, + IN AC01_RC *RCList + ); + +BOOLEAN +IsEmptyRC ( + IN AC01_RC *RC + ); + +VOID +PcieBoardSetupDevmap ( + IN AC01_RC *RC + ); + +VOID +PcieBoardGetLaneAllocation ( + IN AC01_RC *RC + ); + +VOID +PcieBoardGetSpeed ( + IN AC01_RC *RC + ); + +VOID +PcieBoardParseRCParams ( + IN AC01_RC *RC + ); + +VOID +PcieBoardAssertPerst ( + AC01_RC *RC, + UINT32 PcieIndex, + UINT8 Bifurcation, + BOOLEAN isPullToHigh + ); + +BOOLEAN +PcieBoardCheckSmmuPmuEnabled ( + VOID + ); + +#endif /* PCIE_BOARD_LIB_H_ */ diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr b/Platfor= m/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr new file mode 100644 index 000000000000..a596d5ac9a92 --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr @@ -0,0 +1,212 @@ +/** @file + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "NVDataStruc.h" + +formset + guid =3D PCIE_FORM_SET_GUID, + title =3D STRING_TOKEN(STR_PCIE_FORM), + help =3D STRING_TOKEN(STR_PCIE_FORM_HELP), + classguid =3D gPlatformManagerFormsetGuid, + + // + // Define a variable Storage + // + varstore PCIE_VARSTORE_DATA, + varid =3D PCIE_VARSTORE_ID, + name =3D PcieIfrNVData, + guid =3D PCIE_FORM_SET_GUID; + + form + formid =3D PCIE_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_FORM); + + label LABEL_UPDATE; + // dynamic content here + label LABEL_END; + endform; + + form + formid =3D PCIE_RC0_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC0_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC0_FORM); + + label LABEL_RC0_UPDATE; + // dynamic content here + label LABEL_RC0_END; + endform; + + form + formid =3D PCIE_RC1_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC1_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC1_FORM); + + label LABEL_RC1_UPDATE; + // dynamic content here + label LABEL_RC1_END; + endform; + + form + formid =3D PCIE_RC2_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC2_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC2_FORM); + + label LABEL_RC2_UPDATE; + // dynamic content here + label LABEL_RC2_END; + endform; + + form + formid =3D PCIE_RC3_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC3_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC3_FORM); + + label LABEL_RC3_UPDATE; + // dynamic content here + label LABEL_RC3_END; + endform; + + form + formid =3D PCIE_RC4_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC4_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC4_FORM); + + label LABEL_RC4_UPDATE; + // dynamic content here + label LABEL_RC4_END; + endform; + + form + formid =3D PCIE_RC5_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC5_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC5_FORM); + + label LABEL_RC5_UPDATE; + // dynamic content here + label LABEL_RC5_END; + endform; + + form + formid =3D PCIE_RC6_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC6_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC6_FORM); + + label LABEL_RC6_UPDATE; + // dynamic content here + label LABEL_RC6_END; + endform; + + form + formid =3D PCIE_RC7_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC7_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC7_FORM); + + label LABEL_RC7_UPDATE; + // dynamic content here + label LABEL_RC7_END; + endform; + + form + formid =3D PCIE_RC8_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC8_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC8_FORM); + + label LABEL_RC8_UPDATE; + // dynamic content here + label LABEL_RC8_END; + endform; + + form + formid =3D PCIE_RC9_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC9_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC9_FORM); + + label LABEL_RC9_UPDATE; + // dynamic content here + label LABEL_RC9_END; + endform; + + form + formid =3D PCIE_RC10_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC10_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC10_FORM); + + label LABEL_RC10_UPDATE; + // dynamic content here + label LABEL_RC10_END; + endform; + + form + formid =3D PCIE_RC11_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC11_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC11_FORM); + + label LABEL_RC11_UPDATE; + // dynamic content here + label LABEL_RC11_END; + endform; + + form + formid =3D PCIE_RC12_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC12_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC12_FORM); + + label LABEL_RC12_UPDATE; + // dynamic content here + label LABEL_RC12_END; + endform; + + form + formid =3D PCIE_RC13_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC13_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC13_FORM); + + label LABEL_RC13_UPDATE; + // dynamic content here + label LABEL_RC13_END; + endform; + + form + formid =3D PCIE_RC14_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC14_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC14_FORM); + + label LABEL_RC14_UPDATE; + // dynamic content here + label LABEL_RC14_END; + endform; + + form + formid =3D PCIE_RC15_FORM_ID, + title =3D STRING_TOKEN(STR_PCIE_RC15_FORM); + + subtitle text =3D STRING_TOKEN(STR_PCIE_RC15_FORM); + + label LABEL_RC15_UPDATE; + // dynamic content here + label LABEL_RC15_END; + endform; + +endformset; diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c b/Pla= tform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c new file mode 100644 index 000000000000..c0c94d349b5b --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c @@ -0,0 +1,438 @@ +/** @file + + Pcie board specific driver to handle asserting PERST signal to Endpoint + card and parsing NVPARAM board settings for bifurcation programming. + + PERST asserting is via group of GPIO pins to CPLD as Platform Specificat= ion. + + NVPARAM board settings is spec-ed within Firmware Interface Requirement. + Bifuration devmap is programmed before at SCP following the rule + + Root Complex Type-A devmap settings (RP =3D=3D Root Port) + ----------------------------------------- + | RP0 | RP1 | RP2 | RP3 | Devmap | + | (x16) | (x4) | (x8) | (x4) | (output) | + ------------------------------------------- + | Y | N | N | N | 0 | + | Y | N | Y | N | 1 | + | Y | N | Y | Y | 2 | + | Y | Y | Y | Y | 3 | + ----------------------------------------- + + Root Complex Type-B LO (aka RCBxA) devmap settings (RP =3D=3D Root Port) + ---------------------------------------- + | RP0 | RP1 | RP2 | RP3 | Devmap | + | (x8) | (x2) | (x4) | (x3) | (output) | + ---------------------------------------- + | Y | N | N | N | 0 | + | Y | N | Y | N | 1 | + | Y | N | Y | Y | 2 | + | Y | Y | Y | Y | 3 | + ---------------------------------------- + + Root Complex Type-B LO (aka RCBxB) devmap settings (RP =3D=3D Root Port) + ---------------------------------------- + | RP4 | RP5 | RP6 | RP7 | Devmap | + | (x8) | (x2) | (x4) | (x3) | (output) | + ---------------------------------------- + | Y | N | N | N | 0 | + | Y | N | Y | N | 1 | + | Y | N | Y | Y | 2 | + | Y | Y | Y | Y | 3 | + ---------------------------------------- + + 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 +#include +#include +#include + +#ifndef BIT +#define BIT(nr) (1 << (nr)) +#endif + +extern CHAR16 VariableName[]; +extern EFI_GUID gPcieFormSetGuid; + +VOID +EFIAPI +PcieBoardLoadPreset ( + IN AC01_RC *RC + ) +{ + UINT32 Nv; + INTN NvParam; + INTN Ret; + INTN i; + + // Load default value + for (i =3D 0; i < MAX_PCIE_B; i++) { + RC->PresetGen3[i] =3D PRESET_INVALID; + RC->PresetGen4[i] =3D PRESET_INVALID; + } + + // Load override value + if (RC->Socket =3D=3D 0) { + if (RC->Type =3D=3D RCA) { + if (RC->ID < 4) { + NvParam =3D NV_SI_RO_BOARD_S0_RCA0_TXRX_G3PRESET + RC->ID * NVPARA= M_SIZE; + } else { + NvParam =3D NV_SI_RO_BOARD_S0_RCA4_TXRX_G3PRESET + (RC->ID - 4) * = NVPARAM_SIZE; + } + } else { + NvParam =3D NV_SI_RO_BOARD_S0_RCB0A_TXRX_G3PRESET + (RC->ID - 4) * (= 2 * NVPARAM_SIZE); + } + } else if (RC->Type =3D=3D RCA) { + if (RC->ID < 4) { + NvParam =3D NV_SI_RO_BOARD_S1_RCA2_TXRX_G3PRESET + (RC->ID - 2) * NV= PARAM_SIZE; + } else { + NvParam =3D NV_SI_RO_BOARD_S1_RCA4_TXRX_G3PRESET + (RC->ID - 4) * NV= PARAM_SIZE; + } + } else { + NvParam =3D NV_SI_RO_BOARD_S1_RCB0A_TXRX_G3PRESET + (RC->ID - 4) * (2 = * NVPARAM_SIZE); + } + + Ret =3D NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv); + if (Ret =3D=3D EFI_SUCCESS) { + for (i =3D 0; i < 4; i++) { + RC->PresetGen3[i] =3D (Nv >> (NVPARAM_SIZE * i)) & 0xFF; + } + } + + if (RC->Type =3D=3D RCB) { + NvParam +=3D NVPARAM_SIZE; + Ret =3D NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv); + if (Ret =3D=3D EFI_SUCCESS) { + for (i =3D 0; i < 4; i++) { + RC->PresetGen3[i] =3D (Nv >> (NVPARAM_SIZE * i)) & 0xFF; + } + } + } + + if (RC->Socket =3D=3D 0) { + if (RC->Type =3D=3D RCA) { + if (RC->ID < 4) { + NvParam =3D NV_SI_RO_BOARD_S0_RCA0_TXRX_G4PRESET + RC->ID * NVPARA= M_SIZE; + } else { + NvParam =3D NV_SI_RO_BOARD_S0_RCA4_TXRX_G4PRESET + (RC->ID - 4) * = NVPARAM_SIZE; + } + } else { + NvParam =3D NV_SI_RO_BOARD_S0_RCB0A_TXRX_G4PRESET + (RC->ID - 4) * (= 2 * NVPARAM_SIZE); + } + } else if (RC->Type =3D=3D RCA) { + if (RC->ID < 4) { + NvParam =3D NV_SI_RO_BOARD_S1_RCA2_TXRX_G4PRESET + (RC->ID - 2) * NV= PARAM_SIZE; + } else { + NvParam =3D NV_SI_RO_BOARD_S1_RCA4_TXRX_G4PRESET + (RC->ID - 4) * NV= PARAM_SIZE; + } + } else { + NvParam =3D NV_SI_RO_BOARD_S1_RCB0A_TXRX_G4PRESET + (RC->ID - 4) * (2 = * NVPARAM_SIZE); + } + + Ret =3D NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv); + if (Ret =3D=3D EFI_SUCCESS) { + for (i =3D 0; i < 4; i++) { + RC->PresetGen4[i] =3D (Nv >> (8 * i)) & 0xFF; + } + } + + if (RC->Type =3D=3D RCB) { + NvParam +=3D NVPARAM_SIZE; + Ret =3D NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv); + if (Ret =3D=3D EFI_SUCCESS) { + for (i =3D 0; i < 4; i++) { + RC->PresetGen4[i + 4] =3D (Nv >> (8 * i)) & 0xFF; + } + } + } +} + +VOID +EFIAPI +PcieBoardParseRCParams ( + IN AC01_RC *RC + ) +{ + UINT32 Efuse; + PLATFORM_INFO_HOB *PlatformHob; + UINT8 PlatRCId; + EFI_STATUS Status; + VOID *Hob; + UINTN BufferSize; + PCIE_VARSTORE_DATA VarStoreConfig =3D { + .RCStatus =3D {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, + TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE}, + .RCBifurLo =3D {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + .RCBifurHi =3D {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + .SmmuPmu =3D 0 + }; + + PCIE_DEBUG ("%a - Socket%d RC%d\n", __FUNCTION__, RC->Socket, RC->ID); + + PlatRCId =3D RC->Socket * RCS_PER_SOCKET + RC->ID; + // Get RC activation status + BufferSize =3D sizeof (PCIE_VARSTORE_DATA); + Status =3D gRT->GetVariable ( + VariableName, + &gPcieFormSetGuid, + NULL, + &BufferSize, + &VarStoreConfig + ); + if (EFI_ERROR (Status)) { + PCIE_DEBUG ("%a - Failed to read PCIE variable data from config store.= \n", __FUNCTION__); + } + + RC->Active =3D VarStoreConfig.RCStatus[PlatRCId]; + RC->DevMapLo =3D VarStoreConfig.RCBifurLo[PlatRCId]; + RC->DevMapHi =3D VarStoreConfig.RCBifurHi[PlatRCId]; + + PCIE_DEBUG ( + "%a - Socket%d RC%d is %s\n", + __FUNCTION__, + RC->Socket, + RC->ID, + (RC->Active) ? "ACTIVE" : "INACTIVE" + ); + + if (!IsSlaveSocketActive () && RC->Socket =3D=3D 1) { + RC->Active =3D FALSE; + } + + if (RC->Active) { + // + // Consolidate with E-fuse + // + Efuse =3D 0; + Hob =3D GetFirstGuidHob (&gPlatformHobGuid); + if (Hob !=3D NULL) { + PlatformHob =3D (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob); + Efuse =3D PlatformHob->RcDisableMask[0] | (PlatformHob->RcDisableMas= k[1] << RCS_PER_SOCKET); + PCIE_DEBUG ( + "RcDisableMask[0]: 0x%x [1]: 0x%x\n", + PlatformHob->RcDisableMask[0], + PlatformHob->RcDisableMask[1] + ); + + // Update errata flags for Ampere Altra + if ((PlatformHob->ScuProductId[0] & 0xff) =3D=3D 0x01) { + if (PlatformHob->AHBCId[0] =3D=3D 0x20100 + || PlatformHob->AHBCId[0] =3D=3D 0x21100 + || (IsSlaveSocketActive () + && (PlatformHob->AHBCId[1] =3D=3D 0x20100 + || PlatformHob->AHBCId[1] =3D=3D 0x21100))) + { + RC->Flags |=3D PCIE_ERRATA_SPEED1; + PCIE_DEBUG ("RC[%d]: Flags 0x%x\n", RC->ID, RC->Flags); + } + } + } + + RC->Active =3D (RC->Active && !(Efuse & BIT (PlatRCId))) ? TRUE : FALS= E; + } + + /* Load Gen3/Gen4 preset */ + PcieBoardLoadPreset (RC); + PcieBoardGetLaneAllocation (RC); + PcieBoardSetupDevmap (RC); + PcieBoardGetSpeed (RC); +} + +VOID +EFIAPI +PcieBoardReleaseAllPerst ( + IN UINT8 SocketId + ) +{ + UINT32 GpioIndex, GpioPin; + + // Write 1 to all GPIO[16..21] to release all PERST + GpioPin =3D GPIO_DWAPB_PINS_PER_SOCKET * SocketId + 16; + for (GpioIndex =3D 0; GpioIndex < 6; GpioIndex++) { + GpioModeConfig (GpioPin + GpioIndex, GPIO_CONFIG_OUT_HI); + } +} + +VOID +EFIAPI +PcieBoardAssertPerst ( + AC01_RC *RC, + UINT32 PcieIndex, + UINT8 Bifurcation, + BOOLEAN isPullToHigh + ) +{ + UINT32 GpioGroupVal, Val, GpioIndex, GpioPin; + + /* + * For Post-silicon, Fansipan board is using GPIO combination (GPIO[16..= 21]) + * to control CPLD. + * It should be follow PCIE RESET TABLE in Fansipan schematic. + * + * Depend on Bifurcation settings, will active corresponding PERST pin o= r not + */ + + if (RC->Type =3D=3D RCA) { + switch (Bifurcation) { + case 0: // RCA_BIFURCATION_ONE_X16: + if (PcieIndex !=3D 0) { // 1,2,3 + } + break; + + case 1: // RCA_BIFURCATION_TWO_X= 8: + if ((PcieIndex =3D=3D 1) || (PcieIndex =3D=3D 3)) { // 1,3 + } + break; + + case 2: // RCA_BIFURCATION_ONE_X8_TWO_X4: + if (PcieIndex =3D=3D 1) { // 1 + } + break; + + case 3: // RCA_BIFURCATION_FOUR_X4: + break; + + default: + PCIE_DEBUG ("Invalid Bifurcation setting\n"); + break; + } + } else { // RCB + switch (Bifurcation) { + case 0: // RCB_BIFURCATION_ONE_X= 8: + if ((PcieIndex !=3D 0) && (PcieIndex !=3D 4)) { // 1,2,3,5,6,7 + } + break; + + case 1: // RCB_BIFURCATION_TWO_X4: + if ((PcieIndex % 2) !=3D 0) { // 1,3,5,7 + } + break; + + case 2: // RCB_BIFURCATION_ONE_X4_TWO_X2: + if ((PcieIndex =3D=3D 1) || (PcieIndex =3D=3D 5)) { + } + break; + + case 3: // RCB_BIFURCATION_FOUR_X2: + break; + + default: + PCIE_DEBUG ("Invalid Bifurcation setting\n"); + break; + } + } + + if (!isPullToHigh) { // Pull PERST to Low + if (RC->Type =3D=3D RCA) { // RCA: RC->ID: 0->3 ; PcieIndex: 0->3 + GpioGroupVal =3D 62 - RC->ID*4 - PcieIndex; + } + else { // RCB: RC->ID: 4->7 ; PcieIndex: 0->7 + GpioGroupVal =3D 46 - (RC->ID - 4)*8 - PcieIndex; + } + + GpioPin =3D GPIO_DWAPB_PINS_PER_SOCKET * RC->Socket + 16; + for (GpioIndex =3D 0; GpioIndex < 6; GpioIndex++) { + // 6: Number of GPIO pins to control via CPLD + Val =3D (GpioGroupVal & 0x3F) & (1 << GpioIndex); + if (Val =3D=3D 0) { + GpioModeConfig (GpioPin + GpioIndex, GPIO_CONFIG_OUT_LOW); + } else { + GpioModeConfig (GpioPin + GpioIndex, GPIO_CONFIG_OUT_HI); + } + } + + // Keep reset as low as 100 ms as specification + MicroSecondDelay (100 * 1000); + } else { // Pull PERST to High + PcieBoardReleaseAllPerst (RC->Socket); + } +} + +/** + * Overrride the segment number for a root complex with + * a board specific number. + **/ +VOID +EFIAPI +PcieBoardGetRCSegmentNumber ( + IN AC01_RC *RC, + OUT UINTN *SegmentNumber + ) +{ + if (RC->Socket =3D=3D 0) { + if (RC->Type =3D=3D RCA) { + switch (RC->ID) { + case 0: + *SegmentNumber =3D 12; + break; + + case 1: + *SegmentNumber =3D 13; + break; + + case 2: + *SegmentNumber =3D 1; + break; + + case 3: + *SegmentNumber =3D 0; + break; + + default: + *SegmentNumber =3D 16; + } + } else { /* Socket0, CCIX: RCA0 and RCA1 */ + *SegmentNumber =3D RC->ID - 2; + } + } else { /* Socket1, CCIX: RCA0 and RCA1 */ + if (RC->ID =3D=3D 0 || RC->ID =3D=3D 1) { + *SegmentNumber =3D 16; + } else { + *SegmentNumber =3D 4 + RC->ID; + } + } +} + +BOOLEAN +EFIAPI +PcieBoardCheckSmmuPmuEnabled ( + VOID + ) +{ + EFI_GUID PcieFormSetGuid =3D PCIE_FORM_SET_GUID; + PCIE_VARSTORE_DATA VarStoreConfig; + UINTN BufferSize; + EFI_STATUS Status; + + // Get Buffer Storage data from EFI variable + BufferSize =3D sizeof (PCIE_VARSTORE_DATA); + Status =3D gRT->GetVariable ( + PCIE_VARSTORE_NAME, + &PcieFormSetGuid, + NULL, + &BufferSize, + &VarStoreConfig + ); + if (EFI_ERROR (Status)) { + return FALSE; + } + + return VarStoreConfig.SmmuPmu; +} diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c= b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c new file mode 100644 index 000000000000..a8accbf53047 --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c @@ -0,0 +1,327 @@ +/** @file + + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + +#include "Pcie.h" + +/* Host bridge registers */ +#define HBRCAPDMR 0x0 +#define HBRCBPDMR 0x4 + +/* HBRCAPDMR */ +#define RCAPCIDEVMAP_SET(dst, src) \ + (((dst) & ~0x7) | (((UINT32)(src)) & 0x7)) + +/* HBRCBPDMR */ +#define RCBPCIDEVMAPLO_SET(dst, src) \ + (((dst) & ~0x7) | (((UINT32)(src)) & 0x7)) +#define RCBPCIDEVMAPHI_SET(dst, src) \ + (((dst) & ~0x70) | (((UINT32)(src) << 4) & 0x70)) + +#define PCIE_GET_MAX_WIDTH(Pcie, Max) \ + !((Pcie).MaxWidth) ? (Max) : MIN((Pcie).MaxWidth, (Max)) + +BOOLEAN +IsEmptyRC ( + IN AC01_RC *RC + ) +{ + INTN Idx; + + for (Idx =3D PCIE_0; Idx < MAX_PCIE; Idx++) { + if (RC->Pcie[Idx].Active) { + return FALSE; + } + } + + return TRUE; +} + +VOID +PcieBoardSetRCBifur ( + IN AC01_RC *RC, + IN UINT8 RPStart, + IN UINT8 DevMap + ) +{ + UINT8 MaxWidth; + + if (RPStart !=3D PCIE_0 && RPStart !=3D PCIE_4) { + return; + } + + if (RC->Type !=3D RCB && RPStart =3D=3D PCIE_4) { + return; + } + + if (RC->Type =3D=3D RCA && RC->Pcie[RPStart].MaxWidth =3D=3D LNKW_X16) { + RC->Pcie[RPStart + 1].MaxWidth =3D LNKW_X4; + RC->Pcie[RPStart + 2].MaxWidth =3D LNKW_X8; + RC->Pcie[RPStart + 3].MaxWidth =3D LNKW_X4; + } + + if (RC->Type =3D=3D RCB && RC->Pcie[RPStart].MaxWidth =3D=3D LNKW_X8) { + RC->Pcie[RPStart + 1].MaxWidth =3D LNKW_X2; + RC->Pcie[RPStart + 2].MaxWidth =3D LNKW_X4; + RC->Pcie[RPStart + 3].MaxWidth =3D LNKW_X2; + } + + switch (DevMap) { + case 1: + MaxWidth =3D (RC->Type =3D=3D RCA) ? LNKW_X8 : LNKW_X4; + RC->Pcie[RPStart].MaxWidth =3D PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], = MaxWidth); + RC->Pcie[RPStart + 1].Active =3D 0; + RC->Pcie[RPStart + 2].MaxWidth =3D PCIE_GET_MAX_WIDTH (RC->Pcie[RPStar= t + 2], MaxWidth); + RC->Pcie[RPStart + 2].Active =3D 1; + RC->Pcie[RPStart + 3].Active =3D 0; + break; + + case 2: + MaxWidth =3D (RC->Type =3D=3D RCA) ? LNKW_X8 : LNKW_X4; + RC->Pcie[RPStart].MaxWidth =3D PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], = MaxWidth); + RC->Pcie[RPStart + 1].Active =3D 0; + MaxWidth =3D (RC->Type =3D=3D RCA) ? LNKW_X4 : LNKW_X2; + RC->Pcie[RPStart + 2].MaxWidth =3D PCIE_GET_MAX_WIDTH (RC->Pcie[RPStar= t + 2], MaxWidth); + RC->Pcie[RPStart + 2].Active =3D 1; + RC->Pcie[RPStart + 3].MaxWidth =3D PCIE_GET_MAX_WIDTH (RC->Pcie[RPStar= t + 3], MaxWidth); + RC->Pcie[RPStart + 3].Active =3D 1; + break; + + case 3: + MaxWidth =3D (RC->Type =3D=3D RCA) ? LNKW_X4 : LNKW_X2; + RC->Pcie[RPStart].MaxWidth =3D PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], = MaxWidth); + RC->Pcie[RPStart + 1].MaxWidth =3D PCIE_GET_MAX_WIDTH (RC->Pcie[RPStar= t + 1], MaxWidth); + RC->Pcie[RPStart + 1].Active =3D 1; + RC->Pcie[RPStart + 2].MaxWidth =3D PCIE_GET_MAX_WIDTH (RC->Pcie[RPStar= t + 2], MaxWidth); + RC->Pcie[RPStart + 2].Active =3D 1; + RC->Pcie[RPStart + 3].MaxWidth =3D PCIE_GET_MAX_WIDTH (RC->Pcie[RPStar= t + 3], MaxWidth); + RC->Pcie[RPStart + 3].Active =3D 1; + break; + + case 0: + default: + MaxWidth =3D (RC->Type =3D=3D RCA) ? LNKW_X16 : LNKW_X8; + RC->Pcie[RPStart].MaxWidth =3D PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], = MaxWidth); + RC->Pcie[RPStart + 1].Active =3D 0; + RC->Pcie[RPStart + 2].Active =3D 0; + RC->Pcie[RPStart + 3].Active =3D 0; + break; + } +} + +VOID +PcieBoardGetLaneAllocation ( + IN AC01_RC *RC + ) +{ + INTN RPIndex, Ret; + UINT32 Nv, Width; + NVPARAM NvParam; + + // Retrieve lane allocation and capabilities for each controller + if (RC->Type =3D=3D RCA) { + NvParam =3D NV_SI_RO_BOARD_S0_RCA0_CFG + RC->Socket * 96 + + RC->ID * 8; + } else { + NvParam =3D NV_SI_RO_BOARD_S0_RCB0_LO_CFG + RC->Socket * 96 + + (RC->ID - MAX_RCA) * 16; + } + + Ret =3D NVParamGet (NvParam, NV_PERM_ALL, &Nv); + Nv =3D (Ret !=3D EFI_SUCCESS) ? 0 : Nv; + + for (RPIndex =3D 0; RPIndex < MAX_PCIE_A; RPIndex++) { + Width =3D (Nv >> (RPIndex * 8)) & 0xF; + switch (Width) { + case 1: + case 2: + case 3: + case 4: + RC->Pcie[RPIndex].MaxWidth =3D 1 << Width; + RC->Pcie[RPIndex].MaxGen =3D SPEED_GEN3; + RC->Pcie[RPIndex].Active =3D TRUE; + break; + + case 0: + default: + RC->Pcie[RPIndex].MaxWidth =3D LNKW_NONE; + RC->Pcie[RPIndex].MaxGen =3D 0; + RC->Pcie[RPIndex].Active =3D FALSE; + break; + } + } + + if (RC->Type =3D=3D RCB) { + // Processing Hi + NvParam +=3D 8; + Ret =3D NVParamGet (NvParam, NV_PERM_ALL, &Nv); + Nv =3D (Ret !=3D EFI_SUCCESS) ? 0 : Nv; + + for (RPIndex =3D MAX_PCIE_A; RPIndex < MAX_PCIE; RPIndex++) { + Width =3D (Nv >> ((RPIndex - MAX_PCIE_A) * 8)) & 0xF; + switch (Width) { + case 1: + case 2: + case 3: + case 4: + RC->Pcie[RPIndex].MaxWidth =3D 1 << Width; + RC->Pcie[RPIndex].MaxGen =3D SPEED_GEN3; + RC->Pcie[RPIndex].Active =3D TRUE; + break; + + case 0: + default: + RC->Pcie[RPIndex].MaxWidth =3D LNKW_NONE; + RC->Pcie[RPIndex].MaxGen =3D 0; + RC->Pcie[RPIndex].Active =3D FALSE; + break; + } + } + } + + // Do not proceed if no Root Port enabled + if (IsEmptyRC (RC)) { + RC->Active =3D FALSE; + } +} + +VOID +PcieBoardSetupDevmap ( + IN AC01_RC *RC + ) +{ + UINT32 Val; + + if (RC->Pcie[PCIE_0].Active + && RC->Pcie[PCIE_1].Active + && RC->Pcie[PCIE_2].Active + && RC->Pcie[PCIE_3].Active) + { + RC->DefaultDevMapLo =3D 3; + } else if (RC->Pcie[PCIE_0].Active + && RC->Pcie[PCIE_2].Active + && RC->Pcie[PCIE_3].Active) + { + RC->DefaultDevMapLo =3D 2; + } else if (RC->Pcie[PCIE_0].Active + && RC->Pcie[PCIE_2].Active) + { + RC->DefaultDevMapLo =3D 1; + } else { + RC->DefaultDevMapLo =3D 0; + } + + if (RC->Pcie[PCIE_4].Active + && RC->Pcie[PCIE_5].Active + && RC->Pcie[PCIE_6].Active + && RC->Pcie[PCIE_7].Active) + { + RC->DefaultDevMapHi =3D 3; + } else if (RC->Pcie[PCIE_4].Active + && RC->Pcie[PCIE_6].Active + && RC->Pcie[PCIE_7].Active) + { + RC->DefaultDevMapHi =3D 2; + } else if (RC->Pcie[PCIE_4].Active + && RC->Pcie[PCIE_6].Active) + { + RC->DefaultDevMapHi =3D 1; + } else { + RC->DefaultDevMapHi =3D 0; + } + + if (RC->DevMapLo =3D=3D 0) { + RC->DevMapLo =3D RC->DefaultDevMapLo; + } + + if (RC->Type =3D=3D RCB && RC->DevMapHi =3D=3D 0) { + RC->DevMapHi =3D RC->DefaultDevMapHi; + } + + PcieBoardSetRCBifur (RC, PCIE_0, RC->DevMapLo); + if (RC->Type =3D=3D RCB) { + PcieBoardSetRCBifur (RC, PCIE_4, RC->DevMapHi); + } + + if (RC->Active) { + if (RC->Type =3D=3D RCA) { + if (!EFI_ERROR (MailboxMsgRegisterRead (RC->Socket, RC->HBAddr + HBR= CAPDMR, &Val))) { + Val =3D RCAPCIDEVMAP_SET (Val, RC->DevMapLo & 0x7); + MailboxMsgRegisterWrite (RC->Socket, RC->HBAddr + HBRCAPDMR, Val); + } + } else { + if (!EFI_ERROR (MailboxMsgRegisterRead (RC->Socket, RC->HBAddr + HBR= CBPDMR, &Val))) { + Val =3D RCBPCIDEVMAPLO_SET (Val, RC->DevMapLo & 0x7); + Val =3D RCBPCIDEVMAPHI_SET (Val, RC->DevMapHi & 0x7); + MailboxMsgRegisterWrite (RC->Socket, RC->HBAddr + HBRCBPDMR, Val); + } + } + } +} + +VOID +PcieBoardGetSpeed ( + IN AC01_RC *RC + ) +{ + UINT8 MaxGenTbl[MAX_PCIE_A] =3D { SPEED_GEN4, SPEED_GEN4, SPEED_GEN4, SP= EED_GEN4 }; // Bifurcation 0: RCA x16 / RCB x8 + UINT8 MaxGenTblX8X4X4[MAX_PCIE_A] =3D { SPEED_GEN4, SPEED_GEN4, SPEED_GE= N1, SPEED_GEN1 }; // Bifurcation 2: x8 x4 x4 (PCIE_ERRATA_SPEED1) + UINT8 MaxGenTblX4X4X4X4[MAX_PCIE_A] =3D { SPEED_GEN1, SPEED_GEN1, SPEED_= GEN1, SPEED_GEN1 }; // Bifurcation 3: x4 x4 x4 x4 (PCIE_ERRATA_SPEED1) + UINT8 MaxGenTblRCB[MAX_PCIE_A] =3D { SPEED_GEN1, SPEED_GEN1, SPEED_GEN1,= SPEED_GEN1 }; // RCB PCIE_ERRATA_SPEED1 + INTN RPIdx; + UINT8 *MaxGen; + + ASSERT (MAX_PCIE_A =3D=3D 4); + ASSERT (MAX_PCIE =3D=3D 8); + + // + // Due to hardware errata, for A0/A1* + // RCB is limited to Gen1 speed. + // RCA x16, x8 port supports up to Gen4, + // RCA x4 port only supports Gen1. + // + MaxGen =3D MaxGenTbl; + if (RC->Type =3D=3D RCB) { + if (RC->Flags & PCIE_ERRATA_SPEED1) { + MaxGen =3D MaxGenTblRCB; + } + } else { + switch (RC->DevMapLo) { + case 2: /* x8 x4 x4 */ + if (RC->Flags & PCIE_ERRATA_SPEED1) { + MaxGen =3D MaxGenTblX8X4X4; + } + break; + + case 3: /* X4 x4 x4 x4 */ + if (RC->Flags & PCIE_ERRATA_SPEED1) { + MaxGen =3D MaxGenTblX4X4X4X4; + } + break; + + case 1: /* x8 x8 */ + default: + break; + } + } + + for (RPIdx =3D 0; RPIdx < MAX_PCIE_A; RPIdx++) { + RC->Pcie[RPIdx].MaxGen =3D RC->Pcie[RPIdx].Active ? MaxGen[RPIdx] : 0; + } + + if (RC->Type =3D=3D RCB) { + for (RPIdx =3D MAX_PCIE_A; RPIdx < MAX_PCIE; RPIdx++) { + RC->Pcie[RPIdx].MaxGen =3D RC->Pcie[RPIdx].Active ? + MaxGen[RPIdx - MAX_PCIE_A] : 0; + } + } +} diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c= b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c new file mode 100644 index 000000000000..309cc8857b8c --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c @@ -0,0 +1,1120 @@ +/** @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 "PcieBoardScreen.h" + +#ifndef BIT +#define BIT(nr) (1 << (nr)) +#endif + +#define MAX_STRING_SIZE 32 + +CHAR16 VariableName[] =3D PCIE_VARSTORE_NAME; +EFI_GUID gPcieFormSetGuid =3D PCIE_FORM_SET_GUID; + +EFI_HANDLE DriverHandle =3D NULL; +PCIE_SCREEN_PRIVATE_DATA *mPrivateData =3D NULL; + +AC01_RC RCList[MAX_AC01_PCIE_ROOT_COMPLEX]; + +HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath =3D { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8)(sizeof (VENDOR_DEVICE_PATH)), + (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8) + } + }, + PCIE_FORM_SET_GUID + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8)(END_DEVICE_PATH_LENGTH), + (UINT8)((END_DEVICE_PATH_LENGTH) >> 8) + } + } +}; + +/** + This function allows a caller to extract the current configuration for o= ne + or more named elements from the target driver. + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTO= COL. + @param Request A null-terminated Unicode string in + format. + @param Progress On return, points to a character in the R= equest + string. Points to the string's null termi= nator if + request was successful. Points to the mos= t recent + '&' before the first failing name/value p= air (or + the beginning of the string if the failur= e is in + the first name/value pair) if the request= was not + successful. + @param Results A null-terminated Unicode string in + format which has all valu= es filled + in for the names in the Request string. S= tring to + be allocated by the called function. + @retval EFI_SUCCESS The Results is filled with the requested = values. + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results. + @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown nam= e. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in= this + driver. +**/ +EFI_STATUS +EFIAPI +ExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + PCIE_SCREEN_PRIVATE_DATA *PrivateData; + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; + EFI_STRING ConfigRequest; + EFI_STRING ConfigRequestHdr; + UINTN Size; + CHAR16 *StrPointer; + BOOLEAN AllocatedRequest; + PCIE_VARSTORE_DATA *VarStoreConfig; + + if (Progress =3D=3D NULL || Results =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Initialize the local variables. + // + ConfigRequestHdr =3D NULL; + ConfigRequest =3D NULL; + Size =3D 0; + *Progress =3D Request; + AllocatedRequest =3D FALSE; + + PrivateData =3D PCIE_SCREEN_PRIVATE_FROM_THIS (This); + HiiConfigRouting =3D PrivateData->HiiConfigRouting; + VarStoreConfig =3D &PrivateData->VarStoreConfig; + ASSERT (VarStoreConfig !=3D NULL); + + // + // Get Buffer Storage data from EFI variable. + // Try to get the current setting from variable. + // + BufferSize =3D sizeof (PCIE_VARSTORE_DATA); + Status =3D gRT->GetVariable ( + VariableName, + &gPcieFormSetGuid, + NULL, + &BufferSize, + VarStoreConfig + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + if (Request =3D=3D NULL) { + // + // Request is set to NULL, construct full request string. + // + + // + // Allocate and fill a buffer large enough to hold the tem= plate + // followed by "&OFFSET=3D0&WIDTH=3DWWWWWWWWWWWWWWWW" followed by a + // Null-terminator + // + ConfigRequestHdr =3D HiiConstructConfigHdr ( + &gPcieFormSetGuid, + VariableName, + PrivateData->DriverHandle + ); + if (ConfigRequestHdr =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + Size =3D (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16); + ConfigRequest =3D AllocateZeroPool (Size); + ASSERT (ConfigRequest !=3D NULL); + AllocatedRequest =3D TRUE; + UnicodeSPrint ( + ConfigRequest, + Size, + L"%s&OFFSET=3D0&WIDTH=3D%016LX", + ConfigRequestHdr, + (UINT64)BufferSize + ); + FreePool (ConfigRequestHdr); + ConfigRequestHdr =3D NULL; + } else { + // + // Check routing data in . + // Note: if only one Storage is used, then this checking could be skip= ped. + // + if (!HiiIsConfigHdrMatch (Request, &gPcieFormSetGuid, NULL)) { + return EFI_NOT_FOUND; + } + + // + // Set Request to the unified request string. + // + ConfigRequest =3D Request; + + // + // Check whether Request includes Request Element. + // + if (StrStr (Request, L"OFFSET") =3D=3D NULL) { + // + // Check Request Element does exist in Request String + // + StrPointer =3D StrStr (Request, L"PATH"); + if (StrPointer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + if (StrStr (StrPointer, L"&") =3D=3D NULL) { + Size =3D (StrLen (Request) + 32 + 1) * sizeof (CHAR16); + ConfigRequest =3D AllocateZeroPool (Size); + ASSERT (ConfigRequest !=3D NULL); + AllocatedRequest =3D TRUE; + UnicodeSPrint ( + ConfigRequest, + Size, + L"%s&OFFSET=3D0&WIDTH=3D%016LX", + Request, + (UINT64)BufferSize + ); + } + } + } + + // + // Check if requesting Name/Value storage + // + if (StrStr (ConfigRequest, L"OFFSET") =3D=3D NULL) { + // + // Don't have any Name/Value storage names + // + Status =3D EFI_SUCCESS; + } else { + // + // Convert buffer data to by helper function BlockToConfi= g() + // + Status =3D HiiConfigRouting->BlockToConfig ( + HiiConfigRouting, + ConfigRequest, + (UINT8 *)VarStoreConfig, + BufferSize, + Results, + Progress + ); + } + + // + // Free the allocated config request string. + // + if (AllocatedRequest) { + FreePool (ConfigRequest); + } + + if (ConfigRequestHdr !=3D NULL) { + FreePool (ConfigRequestHdr); + } + // + // Set Progress string to the original request string. + // + if (Request =3D=3D NULL) { + *Progress =3D NULL; + } else if (StrStr (Request, L"OFFSET") =3D=3D NULL) { + *Progress =3D Request + StrLen (Request); + } + + return Status; +} + +/** + This function processes the results of changes in configuration. + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTO= COL. + @param Configuration A null-terminated Unicode string in + format. + @param Progress A pointer to a string filled in with the = offset of + the most recent '&' before the first fail= ing + name/value pair (or the beginning of the = string if + the failure is in the first name/value pa= ir) or + the terminating NULL if all was successfu= l. + @retval EFI_SUCCESS The Results is processed successfully. + @retval EFI_INVALID_PARAMETER Configuration is NULL. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in= this + driver. +**/ +EFI_STATUS +EFIAPI +RouteConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + PCIE_SCREEN_PRIVATE_DATA *PrivateData; + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; + PCIE_VARSTORE_DATA *VarStoreConfig; + + if (Configuration =3D=3D NULL || Progress =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + PrivateData =3D PCIE_SCREEN_PRIVATE_FROM_THIS (This); + HiiConfigRouting =3D PrivateData->HiiConfigRouting; + *Progress =3D Configuration; + VarStoreConfig =3D &PrivateData->VarStoreConfig; + ASSERT (VarStoreConfig !=3D NULL); + + // + // Check routing data in . + // Note: if only one Storage is used, then this checking could be skippe= d. + // + if (!HiiIsConfigHdrMatch (Configuration, &gPcieFormSetGuid, NULL)) { + return EFI_NOT_FOUND; + } + + // + // Get Buffer Storage data from EFI variable + // + BufferSize =3D sizeof (PCIE_VARSTORE_DATA); + Status =3D gRT->GetVariable ( + VariableName, + &gPcieFormSetGuid, + NULL, + &BufferSize, + VarStoreConfig + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Check if configuring Name/Value storage + // + if (StrStr (Configuration, L"OFFSET") =3D=3D NULL) { + // + // Don't have any Name/Value storage names + // + return EFI_SUCCESS; + } + + // + // Convert to buffer data by helper function ConfigToBlock(= ) + // + BufferSize =3D sizeof (PCIE_VARSTORE_DATA); + Status =3D HiiConfigRouting->ConfigToBlock ( + HiiConfigRouting, + Configuration, + (UINT8 *)VarStoreConfig, + &BufferSize, + Progress + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Store Buffer Storage back to variable + // + Status =3D gRT->SetVariable ( + VariableName, + &gPcieFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (PCIE_VARSTORE_DATA), + VarStoreConfig + ); + + return Status; +} + +/** + This function processes the results of changes in configuration. + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTO= COL. + @param Action Specifies the type of action taken by the= browser. + @param QuestionId A unique value which is sent to the origi= nal + exporting driver so that it can identify = the type + of data to expect. + @param Type The type of value for the question. + @param Value A pointer to the data being sent to the o= riginal + exporting driver. + @param ActionRequest On return, points to the action requested= by the + callback function. + @retval EFI_SUCCESS The callback successfully handled the act= ion. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold t= he + variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be saved. + @retval EFI_UNSUPPORTED The specified Action is not supported by = the + callback. +**/ +EFI_STATUS +EFIAPI +DriverCallback ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest + ) +{ + PCIE_VARSTORE_DATA *VarStoreConfig; + PCIE_SCREEN_PRIVATE_DATA *PrivateData; + EFI_STATUS Status; + + if (((Value =3D=3D NULL) && + (Action !=3D EFI_BROWSER_ACTION_FORM_OPEN) && + (Action !=3D EFI_BROWSER_ACTION_FORM_CLOSE)) || + (ActionRequest =3D=3D NULL)) + { + return EFI_INVALID_PARAMETER; + } + + PrivateData =3D PCIE_SCREEN_PRIVATE_FROM_THIS (This); + VarStoreConfig =3D &PrivateData->VarStoreConfig; + ASSERT (VarStoreConfig !=3D NULL); + + Status =3D EFI_SUCCESS; + + switch (Action) { + case EFI_BROWSER_ACTION_FORM_OPEN: + break; + + case EFI_BROWSER_ACTION_FORM_CLOSE: + break; + + case EFI_BROWSER_ACTION_DEFAULT_STANDARD: + case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING: + if (QuestionId =3D=3D 0x9000) { + /* SMMU PMU */ + Value->u32 =3D 0; /* default disable */ + break; + } + + switch ((QuestionId - 0x8002) % MAX_EDITABLE_ELEMENTS) { + case 0: + Value->u8 =3D PcieRCActiveDefaultSetting ((QuestionId - 0x8002) / MA= X_EDITABLE_ELEMENTS, PrivateData); + break; + + case 1: + Value->u8 =3D PcieRCDevMapLoDefaultSetting ((QuestionId - 0x8002) / = MAX_EDITABLE_ELEMENTS, PrivateData); + break; + + case 2: + Value->u8 =3D PcieRCDevMapHiDefaultSetting ((QuestionId - 0x8002) / = MAX_EDITABLE_ELEMENTS, PrivateData); + break; + } + break; + + case EFI_BROWSER_ACTION_RETRIEVE: + case EFI_BROWSER_ACTION_CHANGING: + case EFI_BROWSER_ACTION_SUBMITTED: + break; + + default: + Status =3D EFI_UNSUPPORTED; + break; + } + + return Status; +} + +EFI_STATUS +PcieScreenUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + ASSERT (mPrivateData !=3D NULL); + + if (DriverHandle !=3D NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + DriverHandle, + &gEfiDevicePathProtocolGuid, + &mHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &mPrivateData->ConfigAccess, + NULL + ); + DriverHandle =3D NULL; + } + + if (mPrivateData->HiiHandle !=3D NULL) { + HiiRemovePackages (mPrivateData->HiiHandle); + } + + FreePool (mPrivateData); + mPrivateData =3D NULL; + + return EFI_SUCCESS; +} + +/** + This function return default settings for Dev Map LO. + @param RC Root Complex ID. + @param PrivateData Private data. + + @retval Default dev settings. +**/ +UINT8 +PcieRCDevMapLoDefaultSetting ( + IN UINTN RCIndex, + IN PCIE_SCREEN_PRIVATE_DATA *PrivateData + ) +{ + AC01_RC *RC =3D &RCList[RCIndex]; + + return RC->DefaultDevMapLo; +} + +/** + This function return default settings for Dev Map HI. + @param RC Root Complex ID. + @param PrivateData Private data. + + @retval Default dev settings. +**/ +UINT8 +PcieRCDevMapHiDefaultSetting ( + IN UINTN RCIndex, + IN PCIE_SCREEN_PRIVATE_DATA *PrivateData + ) +{ + AC01_RC *RC =3D &RCList[RCIndex]; + + return RC->DefaultDevMapHi; +} + +BOOLEAN +PcieRCActiveDefaultSetting ( + IN UINTN RCIndex, + IN PCIE_SCREEN_PRIVATE_DATA *PrivateData + ) +{ + PLATFORM_INFO_HOB *PlatformHob; + VOID *Hob; + UINT32 Efuse; + + // FIXME: Disable Root Complex 6 (USB and VGA) as default + if (RCIndex =3D=3D 6) { + return FALSE; + } + + Hob =3D GetFirstGuidHob (&gPlatformHobGuid); + if (Hob !=3D NULL) { + PlatformHob =3D (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob); + Efuse =3D PlatformHob->RcDisableMask[0] | (PlatformHob->RcDisableMask[= 1] << RCS_PER_SOCKET); + return (!(Efuse & BIT (RCIndex))) ? TRUE : FALSE; + } + + return FALSE; +} + +/** + This function sets up the first elements of the form. + @param RC Root Complex ID. + @param PrivateData Private data. + @retval EFI_SUCCESS The form is set up successfully. +**/ +EFI_STATUS +PcieRCScreenSetup ( + IN UINTN RCIndex, + IN PCIE_SCREEN_PRIVATE_DATA *PrivateData + ) +{ + VOID *StartOpCodeHandle; + EFI_IFR_GUID_LABEL *StartLabel; + VOID *EndOpCodeHandle; + EFI_IFR_GUID_LABEL *EndLabel; + VOID *OptionsOpCodeHandle; + VOID *OptionsHiOpCodeHandle; + CHAR16 Str[MAX_STRING_SIZE]; + UINT16 DisabledStatusVarOffset; + UINT16 BifurLoVarOffset; + UINT16 BifurHiVarOffset; + UINT8 QuestionFlags, QuestionFlagsSubItem; + AC01_RC *RC; + + RC =3D &RCList[RCIndex]; + + // Initialize the container for dynamic opcodes + StartOpCodeHandle =3D HiiAllocateOpCodeHandle (); + ASSERT (StartOpCodeHandle !=3D NULL); + EndOpCodeHandle =3D HiiAllocateOpCodeHandle (); + ASSERT (EndOpCodeHandle !=3D NULL); + + // Create Hii Extend Label OpCode as the start opcode + StartLabel =3D (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( + StartOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + StartLabel->ExtendOpCode =3D EFI_IFR_EXTEND_OP_LABEL; + StartLabel->Number =3D LABEL_RC0_UPDATE + 2 * RCIndex; + + // Create Hii Extend Label OpCode as the end opcode + EndLabel =3D (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( + EndOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + EndLabel->ExtendOpCode =3D EFI_IFR_EXTEND_OP_LABEL; + EndLabel->Number =3D LABEL_RC0_END + 2 * RCIndex; + + // Create textbox to tell socket + HiiCreateTextOpCode ( + StartOpCodeHandle, + STRING_TOKEN (STR_PCIE_SOCKET), + STRING_TOKEN (STR_PCIE_SOCKET_HELP), + HiiSetString ( + PrivateData->HiiHandle, + 0, + (RC->Socket) ? L"1" : L"0", + NULL + ) + ); + + // Create textbox to tell Root Complex type + HiiCreateTextOpCode ( + StartOpCodeHandle, + STRING_TOKEN (STR_PCIE_RC_TYPE), + STRING_TOKEN (STR_PCIE_RC_TYPE_HELP), + HiiSetString ( + PrivateData->HiiHandle, + 0, + (RC->Type =3D=3D RCA) ? L"Root Complex Type-A" : L"Root Complex Type= -B", + NULL + ) + ); + + UnicodeSPrint (Str, sizeof (Str), L"Root Complex #%2d", RCIndex); + + DisabledStatusVarOffset =3D (UINT16)PCIE_RC0_STATUS_OFFSET + + sizeof (BOOLEAN) * RCIndex; + BifurLoVarOffset =3D (UINT16)PCIE_RC0_BIFUR_LO_OFFSET + + sizeof (UINT8) * RCIndex; + BifurHiVarOffset =3D (UINT16)PCIE_RC0_BIFUR_HI_OFFSET + + sizeof (UINT8) * RCIndex; + + QuestionFlags =3D EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_CALLBACK; + if (IsEmptyRC (RC) + || (GetNumberOfActiveSockets () =3D=3D 1 && RC->Socket =3D=3D 1)) + { + // + // Do not allow changing if none of Root Port underneath enabled + // or slave Root Complex on 1P system. + // + QuestionFlags |=3D EFI_IFR_FLAG_READ_ONLY; + } + // Create the RC disabled checkbox + HiiCreateCheckBoxOpCode ( + StartOpCodeHandle, // Container for dynamic cre= ated opcodes + 0x8002 + MAX_EDITABLE_ELEMENTS * RCIndex, // QuestionId (or "key") + PCIE_VARSTORE_ID, // VarStoreId + DisabledStatusVarOffset, // VarOffset in Buffer Stora= ge + HiiSetString ( + PrivateData->HiiHandle, + 0, + Str, + NULL + ), // Prompt + STRING_TOKEN (STR_PCIE_RC_STATUS_HELP), // Help + QuestionFlags, // QuestionFlags + 0, // CheckBoxFlags + NULL // DefaultsOpCodeHandle + ); + + if (RC->Type =3D=3D RCA) { + // Create Option OpCode to display bifurcation for RCA + OptionsOpCodeHandle =3D HiiAllocateOpCodeHandle (); + ASSERT (OptionsOpCodeHandle !=3D NULL); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE0), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 0 // Devmap=3D0 + ); + + + if (RC->DefaultDevMapLo !=3D 0) { + QuestionFlags |=3D EFI_IFR_FLAG_READ_ONLY; + } + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE1), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 1 // Devmap=3D1 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE2), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 2 // Devmap=3D2 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE3), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 3 // Devmap=3D3 + ); + + HiiCreateOneOfOpCode ( + StartOpCodeHandle, // Container for dynamic c= reated opcodes + 0x8003 + MAX_EDITABLE_ELEMENTS * RCIndex, // Question ID (or call it= "key") + PCIE_VARSTORE_ID, // VarStore ID + BifurLoVarOffset, // Offset in Buffer Storag= e + STRING_TOKEN (STR_PCIE_RCA_BIFUR), // Question prompt text + STRING_TOKEN (STR_PCIE_RCA_BIFUR_HELP), // Question help text + QuestionFlags, // Question flag + EFI_IFR_NUMERIC_SIZE_1, // Data type of Question V= alue + OptionsOpCodeHandle, // Option Opcode list + NULL // Default Opcode is NULl + ); + } else { + // Create Option OpCode to display bifurcation for RCB-Lo + OptionsOpCodeHandle =3D HiiAllocateOpCodeHandle (); + ASSERT (OptionsOpCodeHandle !=3D NULL); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE4), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 0 // Devmap=3D0 + ); + + QuestionFlagsSubItem =3D QuestionFlags; + if (RC->DefaultDevMapLo !=3D 0) { + QuestionFlagsSubItem |=3D EFI_IFR_FLAG_READ_ONLY; + } + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE5), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 1 // Devmap=3D1 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE6), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 2 // Devmap=3D2 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE7), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 3 // Devmap=3D3 + ); + + HiiCreateOneOfOpCode ( + StartOpCodeHandle, // Container for dynamic = created opcodes + 0x8003 + MAX_EDITABLE_ELEMENTS * RCIndex, // Question ID (or call i= t "key") + PCIE_VARSTORE_ID, // VarStore ID + BifurLoVarOffset, // Offset in Buffer Stora= ge + STRING_TOKEN (STR_PCIE_RCB_LO_BIFUR), // Question prompt text + STRING_TOKEN (STR_PCIE_RCB_LO_BIFUR_HELP), // Question help text + QuestionFlagsSubItem, // Question flag + EFI_IFR_NUMERIC_SIZE_1, // Data type of Question = Value + OptionsOpCodeHandle, // Option Opcode list + NULL // Default Opcode is NULl + ); + + // Create Option OpCode to display bifurcation for RCB-Hi + OptionsHiOpCodeHandle =3D HiiAllocateOpCodeHandle (); + ASSERT (OptionsHiOpCodeHandle !=3D NULL); + + QuestionFlagsSubItem =3D QuestionFlags; + if (RC->DefaultDevMapHi !=3D 0) { + QuestionFlagsSubItem |=3D EFI_IFR_FLAG_READ_ONLY; + } + + HiiCreateOneOfOptionOpCode ( + OptionsHiOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE4), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 0 // Devmap=3D0 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsHiOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE5), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 1 // Devmap=3D1 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsHiOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE6), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 2 // Devmap=3D2 + ); + + HiiCreateOneOfOptionOpCode ( + OptionsHiOpCodeHandle, + STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE7), + 0, + EFI_IFR_NUMERIC_SIZE_1, + 3 // Devmap=3D3 + ); + + HiiCreateOneOfOpCode ( + StartOpCodeHandle, // Container for dynamic = created opcodes + 0x8004 + MAX_EDITABLE_ELEMENTS * RCIndex, // Question ID (or call i= t "key") + PCIE_VARSTORE_ID, // VarStore ID + BifurHiVarOffset, // Offset in Buffer Stora= ge + STRING_TOKEN (STR_PCIE_RCB_HI_BIFUR), // Question prompt text + STRING_TOKEN (STR_PCIE_RCB_HI_BIFUR_HELP), // Question help text + QuestionFlagsSubItem, // Question flag + EFI_IFR_NUMERIC_SIZE_1, // Data type of Question = Value + OptionsHiOpCodeHandle, // Option Opcode list + NULL // Default Opcode is NULl + ); + } + + HiiUpdateForm ( + PrivateData->HiiHandle, // HII handle + &gPcieFormSetGuid, // Formset GUID + PCIE_RC0_FORM_ID + RCIndex, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + EndOpCodeHandle // Insert data + ); + + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); + + return EFI_SUCCESS; +} + +/** + This function sets up the first elements of the form. + @param PrivateData Private data. + @retval EFI_SUCCESS The form is set up successfully. +**/ +EFI_STATUS +PcieMainScreenSetup ( + IN PCIE_SCREEN_PRIVATE_DATA *PrivateData + ) +{ + VOID *StartOpCodeHandle; + EFI_IFR_GUID_LABEL *StartLabel; + VOID *EndOpCodeHandle; + EFI_IFR_GUID_LABEL *EndLabel; + CHAR16 Str[MAX_STRING_SIZE]; + UINTN RC; + PCIE_SETUP_GOTO_DATA *GotoItem =3D NULL; + EFI_QUESTION_ID GotoId; + + // Initialize the container for dynamic opcodes + StartOpCodeHandle =3D HiiAllocateOpCodeHandle (); + ASSERT (StartOpCodeHandle !=3D NULL); + EndOpCodeHandle =3D HiiAllocateOpCodeHandle (); + ASSERT (EndOpCodeHandle !=3D NULL); + + // Create Hii Extend Label OpCode as the start opcode + StartLabel =3D (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( + StartOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + StartLabel->ExtendOpCode =3D EFI_IFR_EXTEND_OP_LABEL; + StartLabel->Number =3D LABEL_UPDATE; + + // Create Hii Extend Label OpCode as the end opcode + EndLabel =3D (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( + EndOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + EndLabel->ExtendOpCode =3D EFI_IFR_EXTEND_OP_LABEL; + EndLabel->Number =3D LABEL_END; + + HiiCreateCheckBoxOpCode ( + StartOpCodeHandle, // Container for dynamic crea= ted opcodes + 0x9000, // Question ID + PCIE_VARSTORE_ID, // VarStore ID + (UINT16)PCIE_SMMU_PMU_OFFSET, // Offset in Buffer Storage + STRING_TOKEN (STR_PCIE_SMMU_PMU_PROMPT), // Question prompt text + STRING_TOKEN (STR_PCIE_SMMU_PMU_HELP), // Question help text + EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, + 0, + NULL + ); + + // + // Create the a seperated line + // + HiiCreateTextOpCode ( + StartOpCodeHandle, + STRING_TOKEN (STR_PCIE_FORM_SEPERATE_LINE), + STRING_TOKEN (STR_PCIE_FORM_SEPERATE_LINE), + STRING_TOKEN (STR_PCIE_FORM_SEPERATE_LINE) + ); + + // Create Goto form for each RC + for (RC =3D 0; RC < MAX_AC01_PCIE_ROOT_COMPLEX; RC++) { + + GotoItem =3D AllocateZeroPool (sizeof (PCIE_SETUP_GOTO_DATA)); + if (GotoItem =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + GotoItem->PciDevIdx =3D RC; + + GotoId =3D PCIE_GOTO_ID_BASE + (UINT16)RC; + + // Update HII string + UnicodeSPrint (Str, sizeof (Str), L"Root Complex #%2d", RC); + GotoItem->GotoStringId =3D HiiSetString ( + PrivateData->HiiHandle, + 0, + Str, + NULL + ); + GotoItem->GotoHelpStringId =3D STRING_TOKEN (STR_PCIE_GOTO_HELP); + GotoItem->ShowItem =3D TRUE; + + // Add goto control + HiiCreateGotoOpCode ( + StartOpCodeHandle, + PCIE_RC0_FORM_ID + RC, + GotoItem->GotoStringId, + GotoItem->GotoHelpStringId, + EFI_IFR_FLAG_CALLBACK, + GotoId + ); + } + + HiiUpdateForm ( + PrivateData->HiiHandle, // HII handle + &gPcieFormSetGuid, // Formset GUID + PCIE_FORM_ID, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + EndOpCodeHandle // Insert data + ); + + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); + + return EFI_SUCCESS; +} + +EFI_STATUS +PcieBoardScreenInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable, + IN AC01_RC *NewRCList + ) +{ + EFI_STATUS Status; + EFI_HII_HANDLE HiiHandle; + EFI_HII_DATABASE_PROTOCOL *HiiDatabase; + EFI_HII_STRING_PROTOCOL *HiiString; + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; + EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler; + UINTN BufferSize; + BOOLEAN IsUpdated; + PCIE_VARSTORE_DATA *VarStoreConfig; + UINT8 RCIndex; + AC01_RC *RC; + + // + // Initialize driver private data + // + mPrivateData =3D AllocateZeroPool (sizeof (PCIE_SCREEN_PRIVATE_DATA)); + if (mPrivateData =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + mPrivateData->Signature =3D PCIE_SCREEN_PRIVATE_DATA_SIGNATURE; + + mPrivateData->ConfigAccess.ExtractConfig =3D ExtractConfig; + mPrivateData->ConfigAccess.RouteConfig =3D RouteConfig; + mPrivateData->ConfigAccess.Callback =3D DriverCallback; + + // + // Locate Hii Database protocol + // + Status =3D gBS->LocateProtocol ( + &gEfiHiiDatabaseProtocolGuid, + NULL, + (VOID **)&HiiDatabase + ); + if (EFI_ERROR (Status)) { + return Status; + } + mPrivateData->HiiDatabase =3D HiiDatabase; + + // + // Locate HiiString protocol + // + Status =3D gBS->LocateProtocol ( + &gEfiHiiStringProtocolGuid, + NULL, + (VOID **)&HiiString + ); + if (EFI_ERROR (Status)) { + return Status; + } + mPrivateData->HiiString =3D HiiString; + + // + // Locate ConfigRouting protocol + // + Status =3D gBS->LocateProtocol ( + &gEfiHiiConfigRoutingProtocolGuid, + NULL, + (VOID **)&HiiConfigRouting + ); + if (EFI_ERROR (Status)) { + return Status; + } + mPrivateData->HiiConfigRouting =3D HiiConfigRouting; + + // + // Locate keyword handler protocol + // + Status =3D gBS->LocateProtocol ( + &gEfiConfigKeywordHandlerProtocolGuid, + NULL, + (VOID **)&HiiKeywordHandler + ); + if (EFI_ERROR (Status)) { + return Status; + } + mPrivateData->HiiKeywordHandler =3D HiiKeywordHandler; + + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &DriverHandle, + &gEfiDevicePathProtocolGuid, + &mHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &mPrivateData->ConfigAccess, + NULL + ); + ASSERT_EFI_ERROR (Status); + + mPrivateData->DriverHandle =3D DriverHandle; + + // + // Publish our HII data + // + HiiHandle =3D HiiAddPackages ( + &gPcieFormSetGuid, + DriverHandle, + PcieBoardLibStrings, + VfrBin, + NULL + ); + if (HiiHandle =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + mPrivateData->HiiHandle =3D HiiHandle; + + // Make a shadow copy all Root Complexes' properties + CopyMem ((VOID *)RCList, (VOID *)NewRCList, sizeof (RCList)); + + // + // Initialize efi varstore configuration data + // + VarStoreConfig =3D &mPrivateData->VarStoreConfig; + ZeroMem (VarStoreConfig, sizeof (PCIE_VARSTORE_DATA)); + + // Get Buffer Storage data from EFI variable + BufferSize =3D sizeof (PCIE_VARSTORE_DATA); + Status =3D gRT->GetVariable ( + VariableName, + &gPcieFormSetGuid, + NULL, + &BufferSize, + VarStoreConfig + ); + + IsUpdated =3D FALSE; + + if (EFI_ERROR (Status)) { + VarStoreConfig->SmmuPmu =3D 0; /* Disable by default */ + IsUpdated =3D TRUE; + } + // Update board settings to menu + for (RCIndex =3D 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) { + RC =3D &RCList[RCIndex]; + + if (EFI_ERROR (Status)) { + VarStoreConfig->RCBifurLo[RCIndex] =3D RC->DevMapLo; + VarStoreConfig->RCBifurHi[RCIndex] =3D RC->DevMapHi; + VarStoreConfig->RCStatus[RCIndex] =3D RC->Active; + IsUpdated =3D TRUE; + } + // FIXME: Disable Root Complex 6 (USB and VGA) as default + if (EFI_ERROR (Status) && RCIndex =3D=3D 6) { + VarStoreConfig->RCStatus[RCIndex] =3D 0; + } + } + + if (IsUpdated) { + // Update Buffer Storage + Status =3D gRT->SetVariable ( + VariableName, + &gPcieFormSetGuid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (PCIE_VARSTORE_DATA), + VarStoreConfig + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + Status =3D PcieMainScreenSetup (mPrivateData); + ASSERT_EFI_ERROR (Status); + + for (RCIndex =3D 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) { + Status =3D PcieRCScreenSetup (RCIndex, mPrivateData); + ASSERT_EFI_ERROR (Status); + } + + return Status; +} diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.u= ni b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni new file mode 100644 index 000000000000..776eaa476787 --- /dev/null +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni @@ -0,0 +1,99 @@ +// +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved. +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// + +#langdef en-US "English" + +#string STR_PCIE_FORM #language en-US "PCIE Root Complex= Configuration" +#string STR_PCIE_FORM_HELP #language en-US "Configure Root Co= mplex" + +#string STR_PCIE_FORM_SEPERATE_LINE #language en-US "" + +///// + +#string STR_PCIE_GOTO #language en-US "" +#string STR_PCIE_GOTO_HELP #language en-US "Change On Board R= oot Complex Settings." + +#string STR_PCIE_RC_STATUS #language en-US "" +#string STR_PCIE_RC_STATUS_HELP #language en-US "Enable / Disable = Root Complex" + +#string STR_PCIE_RCA_BIFUR #language en-US "Bifurcation x16" +#string STR_PCIE_RCA_BIFUR_HELP #language en-US "Set bifurcation m= ode for x16 Root Complex Type-A" + +#string STR_PCIE_RCB_LO_BIFUR #language en-US "Bifurcation 1st x= 8" +#string STR_PCIE_RCB_LO_BIFUR_HELP #language en-US "Set bifurcation m= ode for 1st x8 Root Complex Type-B" + +#string STR_PCIE_RCB_HI_BIFUR #language en-US "Bifurcation 2nd x= 8" +#string STR_PCIE_RCB_HI_BIFUR_HELP #language en-US "Set bifurcation m= ode for 2nd x8 Root Complex Type-B" + +///// + +#string STR_PCIE_RC0_FORM #language en-US "Root Complex 0 Co= nfiguration" +#string STR_PCIE_RC0_FORM_HELP #language en-US "Root Complex 0 Co= nfiguration" + +#string STR_PCIE_RC1_FORM #language en-US "Root Complex 1 Co= nfiguration" +#string STR_PCIE_RC1_FORM_HELP #language en-US "Root Complex 1 Co= nfiguration" + +#string STR_PCIE_RC2_FORM #language en-US "Root Complex 2 Co= nfiguration" +#string STR_PCIE_RC2_FORM_HELP #language en-US "Root Complex 2 Co= nfiguration" + +#string STR_PCIE_RC3_FORM #language en-US "Root Complex 3 Co= nfiguration" +#string STR_PCIE_RC3_FORM_HELP #language en-US "Root Complex 3 Co= nfiguration" + +#string STR_PCIE_RC4_FORM #language en-US "Root Complex 4 Co= nfiguration" +#string STR_PCIE_RC4_FORM_HELP #language en-US "Root Complex 4 Co= nfiguration" + +#string STR_PCIE_RC5_FORM #language en-US "Root Complex 5 Co= nfiguration" +#string STR_PCIE_RC5_FORM_HELP #language en-US "Root Complex 5 Co= nfiguration" + +#string STR_PCIE_RC6_FORM #language en-US "Root Complex 6 Co= nfiguration" +#string STR_PCIE_RC6_FORM_HELP #language en-US "Root Complex 6 Co= nfiguration" + +#string STR_PCIE_RC7_FORM #language en-US "Root Complex 7 Co= nfiguration" +#string STR_PCIE_RC7_FORM_HELP #language en-US "Root Complex 7 Co= nfiguration" + +#string STR_PCIE_RC8_FORM #language en-US "Root Complex 8 Co= nfiguration" +#string STR_PCIE_RC8_FORM_HELP #language en-US "Root Complex 8 Co= nfiguration" + +#string STR_PCIE_RC9_FORM #language en-US "Root Complex 9 Co= nfiguration" +#string STR_PCIE_RC9_FORM_HELP #language en-US "Root Complex 9 Co= nfiguration" + +#string STR_PCIE_RC10_FORM #language en-US "Root Complex 10 C= onfiguration" +#string STR_PCIE_RC10_FORM_HELP #language en-US "Root Complex 10 C= onfiguration" + +#string STR_PCIE_RC11_FORM #language en-US "Root Complex 11 C= onfiguration" +#string STR_PCIE_RC11_FORM_HELP #language en-US "Root Complex 11 C= onfiguration" + +#string STR_PCIE_RC12_FORM #language en-US "Root Complex 12 C= onfiguration" +#string STR_PCIE_RC12_FORM_HELP #language en-US "Root Complex 12 C= onfiguration" + +#string STR_PCIE_RC13_FORM #language en-US "Root Complex 13 C= onfiguration" +#string STR_PCIE_RC13_FORM_HELP #language en-US "Root Complex 13 C= onfiguration" + +#string STR_PCIE_RC14_FORM #language en-US "Root Complex 14 C= onfiguration" +#string STR_PCIE_RC14_FORM_HELP #language en-US "Root Complex 14 C= onfiguration" + +#string STR_PCIE_RC15_FORM #language en-US "Root Complex 15 C= onfiguration" +#string STR_PCIE_RC15_FORM_HELP #language en-US "Root Complex 15 C= onfiguration" + +#string STR_PCIE_BIFUR_SELECT_VALUE0 #language en-US "x16" +#string STR_PCIE_BIFUR_SELECT_VALUE1 #language en-US "x8+x8" +#string STR_PCIE_BIFUR_SELECT_VALUE2 #language en-US "x8+x4+x4" +#string STR_PCIE_BIFUR_SELECT_VALUE3 #language en-US "x4+x4+x4+x4" +#string STR_PCIE_BIFUR_SELECT_VALUE4 #language en-US "x8" +#string STR_PCIE_BIFUR_SELECT_VALUE5 #language en-US "x4+x4" +#string STR_PCIE_BIFUR_SELECT_VALUE6 #language en-US "x4+x2+x2" +#string STR_PCIE_BIFUR_SELECT_VALUE7 #language en-US "x2+x2+x2+x2" + +#string STR_PCIE_SOCKET #language en-US "Socket" +#string STR_PCIE_SOCKET_HELP #language en-US "Socket 0 - Master= ; Socket 1 - Slave" +#string STR_PCIE_SOCKET_VALUE #language en-US "" + +#string STR_PCIE_RC_TYPE #language en-US "Type" +#string STR_PCIE_RC_TYPE_HELP #language en-US "Type-A: x16 lanes= bifurcated down to x4; Type-B: 2 of x8 lanes, each bifurcated down to x2" +#string STR_PCIE_RC_TYPE_VALUE #language en-US "" + +#string STR_PCIE_SMMU_PMU_PROMPT #language en-US "SMMU Pmu" +#string STR_PCIE_SMMU_PMU_HELP #language en-US "Enable/Disable PM= U feature for SMMU" --=20 2.17.1