From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (NAM10-BN7-obe.outbound.protection.outlook.com [40.107.92.121]) by mx.groups.io with SMTP id smtpd.web11.53794.1683792645235590947 for ; Thu, 11 May 2023 01:10:45 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@os.amperecomputing.com header.s=selector2 header.b=D26qqqjK; spf=pass (domain: os.amperecomputing.com, ip: 40.107.92.121, mailfrom: minhnguyen1@os.amperecomputing.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FBWIjA8mruxN07v9W2ueYNTQezKCojUD9noFzu1zeKeXHeP3UXkCTbotgZpU3Tjl/hxXWlfCd+bgH/p2q6E3hE5huqdR/Rn558thPpc0ydbq9lwWBY/e5kSBuDLbmNdn6lz80kbGf1oEsOFBi5+0FaSQEFuOkTl8jw6wd60LYrdV+t4ci/CYycece5NtRg3p159vBQgpRYKbUp9QSh/E2m4I9DBVdp9TiP8ZAhYhpuhaYpnOAOxJEnBilGeR0K/oO6k+TVnR1c4SdS41irOd1aU/b/rEpxfi09k5Ip5ebg/nEygzw7sjX7bIvynUdQdIbsjBFHSlYXDx8necD7CpsA== 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=oFG0QoFDhZTyKFyzJeunlECJs4vlHckJSNOR/RI0go4=; b=T8Q/FpWlASNy+txioXWchA5v4E2vSv5ld7LEQjWuiyPyj6+v0MWRYW82PaOgHNX6A8ZeZdg+MDacHEnCySVwbkUkW3q18M/OYr5f8YOzBBnFh7EgWIgTSxlLxFF2gL0QdXDZyb27xcfV/KW2xTZBxxpqi9qffqC1lfyVe7gLQuKOIXl/L2E9VB6IJhpQGwEYWoQeJgbEZ0vnsLA4yUH37aC3IqO9nRP8Av1gIj07RIGopJN5Ha1HzguCsnkW/6WjJKp55ABgfZmbKfRRCRmGeiynC8atxqA+d7UoKkpUzdwE33UKb9dipvr0U5zbauH12OuDv8tOtCXJ0ouZrZgG3A== 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=oFG0QoFDhZTyKFyzJeunlECJs4vlHckJSNOR/RI0go4=; b=D26qqqjKffkrMDyt3qIsgk6cwQERfl+cuK3bWZitJ6/HC30GTlm+isP/zkmPiEIPMQAhxn8lsxJ+m/mJg4srrZ3qo2dt6Fx8jTk7+zXALMksfpFfv9W/gs/XWWaIMjJLUOXLTJ7LhivJkLMd5ad/2ClNEUXx77Yqgu60yUJ0J+A= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=os.amperecomputing.com; Received: from PH0PR01MB8048.prod.exchangelabs.com (2603:10b6:510:280::7) by CY4PR0101MB3144.prod.exchangelabs.com (2603:10b6:910:49::35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6340.19; Thu, 11 May 2023 08:10:40 +0000 Received: from PH0PR01MB8048.prod.exchangelabs.com ([fe80::bbdb:b58c:140e:c4e1]) by PH0PR01MB8048.prod.exchangelabs.com ([fe80::bbdb:b58c:140e:c4e1%6]) with mapi id 15.20.6387.019; Thu, 11 May 2023 08:10:40 +0000 From: Minh Nguyen To: devel@edk2.groups.io CC: patches@amperecomputing.com, quic_llindhol@quicinc.com, ardb+tianocore@kernel.org, nhi@os.amperecomputing.com, tinhnguyen@os.amperecomputing.com, Vu Nguyen , Minh Nguyen Subject: [edk2-platforms][PATCH 1/6] AmpereAltraPkg: Add PCIe Hot Plug library Date: Thu, 11 May 2023 15:10:06 +0700 Message-ID: <20230511081011.2692963-2-minhnguyen1@os.amperecomputing.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230511081011.2692963-1-minhnguyen1@os.amperecomputing.com> References: <20230511081011.2692963-1-minhnguyen1@os.amperecomputing.com> X-ClientProxiedBy: SI2P153CA0033.APCP153.PROD.OUTLOOK.COM (2603:1096:4:190::21) To PH0PR01MB8048.prod.exchangelabs.com (2603:10b6:510:280::7) Return-Path: minhnguyen1@os.amperecomputing.com MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH0PR01MB8048:EE_|CY4PR0101MB3144:EE_ X-MS-Office365-Filtering-Correlation-Id: 52b39f19-219a-4c2c-71bf-08db51f735bc X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: e+/z4lS1zKh9SvHzjBfuaMajwdVTpE0Xvcxb3+aV7Dw0fDlvoWP4LYL2aDdhmqCWRC48Uxufqtx9m4gGkYv37I7yyOUwcw34SG6QrUVVB8BZE+ze/YdLKDqcWMTGNutgpX9zyD87vJIEQoJpV1W/CUN1Q3I09SI1MoWwngvbWzY2X4MIah2rGotA9Uroo8BsFGNL/Tt2wPEoyxdHz+gXcmKT+CTanmAkQgEptmEN2GVnQUlXesqTZsP++2aMyJ5+2sxI1mb3LREdKwphbkK7ZuV8stqzlKKbbOWu2DTkKs80PEYKbKX5+xWamK+39tFXhb5f48qhN7MCD+hGXNM3+OJ46C7bbDPrZ07Oc0XPupKGH0q2N29HPiImXXGLIlrf+uBc+L/yFy02Su2lE6dWoAkCSd9FH6ygXTtJsHP3kjrCmRJIu44MmCAbkTjJy3R86Lc00ELsGj3C8cZFs0VdIwUdJdD0CsecaqX67HdAD1QBDoxbvbtZO5FFWHM21UQnulVcHH8CRHbBNirN+WBgL60Gk/BlexDcoo12ay3dTcdRfHasiTCIuPbd2gB91XYS8eZwe2Bz1Zuy02/kVPwCKXzyBTBzUvkUgwNFpidL5zo17eBaRbyl1hyhA+d+DO+B X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH0PR01MB8048.prod.exchangelabs.com;PTR:;CAT:NONE;SFS:(13230028)(4636009)(136003)(376002)(39860400002)(366004)(346002)(396003)(451199021)(6666004)(478600001)(66556008)(316002)(6486002)(66946007)(54906003)(52116002)(6916009)(66476007)(86362001)(26005)(83380400001)(6512007)(107886003)(6506007)(4326008)(1076003)(8936002)(186003)(2906002)(30864003)(8676002)(41300700001)(5660300002)(38350700002)(38100700002)(2616005);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?3a7hS651/+5H32TeskwcsJ+QWjT0vk+65Fxb1Zm5uIXZoTIMdlHVa3ZnZlyw?= =?us-ascii?Q?nDebf8ctO29YsAWKG7zwKK2+0T9jMaaAXPSmqTyXvJPrm65EQazNG2qqlQIl?= =?us-ascii?Q?1D8it6/MTh37R8vFqXN52EGSs3eF9YimN7Kl6mwdA+/ndyOcCbE84PsRJtCJ?= =?us-ascii?Q?DeW/dh/K+K7WQSKPkFV4AqABaanw5H+B6JRVcRCFbrqqwbRX4RXZMMIVN1Ua?= =?us-ascii?Q?3cQiSg+TGt/wljrkmCbqZrlr8ZVc22laUO4PYd2LrQGpZrJXKRKSZ4fxUL77?= =?us-ascii?Q?K7eXOZbaAS4vpuIWZLF2ra4iSDoi+OwTfMLw6Qo8RYwmk/XQh8/TRoDIHJ+2?= =?us-ascii?Q?lFSvorzGPQhfeuxIhnvzX8MEg1FVGCHxl0sKi3MgKdsjAJEg8Bkgtv/SOMhY?= =?us-ascii?Q?x4VJ9dXj/4Ip04xgLWzefmBBkehD0/bXAVFFhoMUPl0qD7EqNha3kGBTXPaO?= =?us-ascii?Q?nHdVXNrk0Y1K7pqsJmVfGTcJDNWcOI9Osljf7ieY7I23eTTMyOKREGfKvQyE?= =?us-ascii?Q?x1USK4vzbqItyQ7mDowzVT3uxfKEF7TJ7TBJG4zI+NAjuIzuB5dmO9KGDpnw?= =?us-ascii?Q?n0YSMWF0F0Sxe8lzoOjlMOM0G9IYLNbDVltt5240qcHfdr7tJL2k/6FeEhR6?= =?us-ascii?Q?X1kn6oxo1Ury5cPx2WQ1sgF4Ruz7hXjq1AdErhQs0S0tLlSi7VxqLkHQupMH?= =?us-ascii?Q?2ron3Hi6AAHqHdqxejSIkHJcgyZZNFwC+QLuSCEYifErrecy41x5ZxXGgTeO?= =?us-ascii?Q?BdH4HaLoX73/pOo6+ktVSKRGw/2fsI//Hjb0BuIyfDihUgK7CXf87p0MGbOZ?= =?us-ascii?Q?b7LGw25EmBX+fsbt8GvlV7Feq1g+LufJFKdWF2BbazJuHbEu6WOBQCRSxoyP?= =?us-ascii?Q?26EHAeyJr2MqIxNmVifSkn7/5cJqkNCTbLsRAgO+nZKrxAtRzVNq4f3Lex/3?= =?us-ascii?Q?eoI2fHb3FXHG2bfnmllITJvkO1hpgiMrVRCKtmuCuk/yFtyaU9x3bdMYW6c2?= =?us-ascii?Q?erPwNW06U5SmV7d6BQskoq1rn/C1ugwGKFymayf1YNLxSAX49+B8iD44gAEb?= =?us-ascii?Q?UdCngSB9EprNNavRrJ7XvwNV3vCLwxdgGypKXczr98bCF2UUkO9ft5603eRs?= =?us-ascii?Q?RaNw3HKgUNL1d450gjdoYLxsXzeMEmpmu9WRDdvJnboJgFiSrHTyHFIvGar0?= =?us-ascii?Q?k83d7u2JLqeq/g2Ypgt8tbbGBXE/zaxMyUFGsJhQCHv5vMQiIGtgkkjT/0ii?= =?us-ascii?Q?FZc/XNTct57o7EcrTa0yuOQHb0DUHtctnafnVs2W33F+EC0v++HKY01au005?= =?us-ascii?Q?9xHKzTijAs0Txp/jWwHYOCcEHhr3GX2dwSFjNmxVPcMnblGXaPLEl2pYL3IY?= =?us-ascii?Q?7MhKpCEUWTH+Hrr8up/85k02NcGFNUYhtKHv/BO+CGCPIcfn/mAIOi9WmzWy?= =?us-ascii?Q?bsCP//pqUg8LJf7k6vg+OepxS/B0HPxSOOLxwyedZrXkngLVrMZGqa+4LsXp?= =?us-ascii?Q?un/jBEWkh8x4LA3ZuQYvZUYEa3XJWtyMohR3SBP6XT4Ua6C55KIO+JUeNMjm?= =?us-ascii?Q?xd3FluIFrWlibb2pW2C7xyYTXiPOcPieS2IJnCga9H6RQytlf2qQcxSU7POX?= =?us-ascii?Q?r9A5D3xuVFADCf4ddEmntQ19TVfR6OG029iXpVsLgOuw?= X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: 52b39f19-219a-4c2c-71bf-08db51f735bc X-MS-Exchange-CrossTenant-AuthSource: PH0PR01MB8048.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 May 2023 08:10:40.7989 (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: 0yxDdKpths85H3FVNUvQ/5v198985jrUAQ9LN5LdsR5d06sua5bCQ1BDIhRJnmyPdbOpBIW6sjs+P2hAMdX+vq79lCisbVLZFwBVwV8b+nZWTaVYXR2tQaMvd+I5DCMt X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR0101MB3144 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain From: Vu Nguyen This adds PCIe Hot Plug library to support Hot Plug feature and specific procedures for setting different Portmap tables (GPIO pins used for PCIe reset). Signed-off-by: Minh Nguyen --- Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec | = 8 +- Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec | = 13 + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc | = 1 + Platform/Ampere/JadePkg/Jade.dsc | = 66 ++++ Silicon/Ampere/AmpereAltraPkg/Library/PcieHotPlugLib/PcieHotPlugLib.inf | = 37 ++ Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieHotPlugLib.h | = 162 ++++++++ Silicon/Ampere/AmpereSiliconPkg/Include/Library/PcieHotPlugPortMapLib.h | = 81 ++++ Silicon/Ampere/AmpereAltraPkg/Library/PcieHotPlugLib/PcieHotPlugLib.c | = 397 ++++++++++++++++++++ 8 files changed, 764 insertions(+), 1 deletion(-) diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Amp= ere/AmpereAltraPkg/AmpereAltraPkg.dec index d795c9229691..d4881eaed692 100644 --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec @@ -1,6 +1,6 @@ ## @file # -# Copyright (c) 2020-2021, Ampere Computing LLC. All rights reserved.
+# Copyright (c) 2020-2023, Ampere Computing LLC. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -49,6 +49,9 @@ [LibraryClasses] ## @libraryclass Defines a set of methods to initialize Pcie Ac01PcieLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/Ac01PcieLib.h =20 + ## @libraryclass Defines a set of methods to start Hot plug feature + PcieHotPlugLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieHotPlug= Lib.h + [Guids] ## NVParam MM GUID gNVParamMmGuid =3D { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x93, 0= x36, 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } } @@ -70,3 +73,6 @@ [Guids] =20 ## Include/Guid/AcpiConfigHii.h gAcpiConfigFormSetGuid =3D { 0x0ceb6764, 0xd415, 0x4b01, { 0xa8, 0x43, 0= xd1, 0x01, 0xbc, 0xb0, 0xd8, 0x29 } } + + ## PCIe Hot Plug GUID + gPcieHotPlugGuid =3D { 0x5598273c, 0x11ea, 0xa496, { 0x42, 0x02, 0x37, 0= xbb, 0x02, 0x00, 0x13, 0xac } } diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon= /Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec index 625a9b2b1e89..9259956c7caa 100644 --- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec +++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec @@ -80,3 +80,16 @@ [PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx] # # SMBIOS Type 0 - BIOS Information gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate|"MM/DD/YYYY"|VOID*= |0xB0000002 # Must follow this MM/DD/YYYY SMBIOS date format + + # Pcie HotPlug reset map + gAmpereTokenSpaceGuid.PcdPcieHotPlugGpioResetMap|0x0|UINT8|0xB000000A + + # + # Pcie HotPlug Port Map table + # + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable|{0x00}|PCIE_HOT_PLUG_PO= RT_MAP_TABLE|0xB000000B { + + Library/PcieHotPlugPortMapLib.h + + Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec + } diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon= /Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc index 9275e0053af6..8cb2a3fe6422 100644 --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc @@ -81,6 +81,7 @@ [LibraryClasses.common] NVParamLib|Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.i= nf MailboxInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfa= ceLib/MailboxInterfaceLib.inf SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/SystemF= irmwareInterfaceLib/SystemFirmwareInterfaceLib.inf + PcieHotPlugLib|Silicon/Ampere/AmpereAltraPkg/Library/PcieHotPlugLib/Pcie= HotPlugLib.inf PciePhyLib|Silicon/Ampere/AmpereAltraBinPkg/Library/PciePhyLib/PciePhyLi= b.inf Ac01PcieLib|Silicon/Ampere/AmpereAltraPkg/Library/Ac01PcieLib/Ac01PcieLi= b.inf AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCp= uLib.inf diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jad= e.dsc index f14d286cdfb8..a6b5fa3ca2d3 100644 --- a/Platform/Ampere/JadePkg/Jade.dsc +++ b/Platform/Ampere/JadePkg/Jade.dsc @@ -100,7 +100,73 @@ [PcdsFeatureFlag.common] # gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE =20 + # + # Flag to indicate option of using default or specific platform Port Map= table + # + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.UseDefaultConfig|TRUE + [PcdsFixedAtBuild] + gAmpereTokenSpaceGuid.PcdPcieHotPlugGpioResetMap|0x3F + + # + # Setting Portmap table + # + # * Elements of array: + # - 0: Index of Portmap entry in Portmap table structure (Vport). + # - 1: Socket number (Socket). + # - 2: Root complex port for each Portmap entry (RcaPort). + # - 3: Root complex sub-port for each Portmap entry (RcaSubPort). + # - 4: Select output port of IO expander (PinPort). + # - 5: I2C address of IO expander that CPLD backplane simulates (I2= cAddress). + # - 6: Address of I2C switch between CPU and CPLD backplane (MuxAdd= ress). + # - 7: Channel of I2C switch (MuxChannel). + # - 8: It is set from PcieHotPlugSetGPIOMapCmd () function to selec= t GPIO[16:21] (PcdPcieHotPlugGpioResetMap) or I2C for PCIe reset purpose. + # - 9: Segment of root complex (Segment). + # - 10: SSD slot index on the front panel of backplane (DriveIndex). + # + # * Caution: + # - The last array ({ 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF }) requi= re if no fully structured used. + # - Size of Portmap table: PortMap[MAX_PORT_MAP_ENTRY][sizeof(PCIE_H= OT_PLUG_PORTMAP_ENTRY)] <=3D> PortMap[96][11]. + # * Example: Bellow configuration is the configuration for Portmap tab= le of Mt. Jade 2U platform. + # + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[0]|{ 0, 0, 2, 0= , 0, 0x00, 0x00, 0x0, 0, 1, 0xFF } # S0 RCA2.0 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[1]|{ 1, 0, 3, 0= , 1, 0x00, 0x00, 0x0, 0, 0, 0xFF } # S0 RCA3.0 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[2]|{ 2, 0, 4, 0= , 2, 0x27, 0x70, 0x1, 0, 2, 6 } # S0 RCB0.0 - SSD6 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[3]|{ 3, 0, 4, 2= , 3, 0x27, 0x70, 0x1, 0, 2, 7 } # S0 RCB0.2 - SSD7 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[4]|{ 4, 0, 4, 4= , 0, 0x25, 0x70, 0x1, 0, 2, 2 } # S0 RCB0.4 - SSD2 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[5]|{ 5, 0, 4, 6= , 1, 0x25, 0x70, 0x1, 0, 2, 3 } # S0 RCB0.6 - SSD3 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[6]|{ 6, 0, 5, 0= , 0, 0x24, 0x70, 0x1, 0, 3, 0 } # S0 RCB1.0 - SSD0 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[7]|{ 7, 0, 5, 2= , 1, 0x24, 0x70, 0x1, 0, 3, 1 } # S0 RCB1.2 - SSD1 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[8]|{ 8, 0, 5, 4= , 2, 0x26, 0x70, 0x1, 0, 3, 4 } # S0 RCB1.4 - SSD4 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[9]|{ 9, 0, 5, 6= , 3, 0x26, 0x70, 0x1, 0, 3, 5 } # S0 RCB1.6 - SSD5 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[10]|{ 10, 0, 6,= 0, 2, 0x00, 0x00, 0x0, 0, 4, 0xFF } # S0 RCB2.0 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[11]|{ 11, 0, 6,= 2, 3, 0x00, 0x00, 0x0, 0, 4, 0xFF } # S0 RCB2.2 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[12]|{ 12, 0, 6,= 4, 0, 0x00, 0x00, 0x0, 0, 4, 0xFF } # S0 RCB2.4 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[13]|{ 13, 0, 7,= 0, 1, 0x00, 0x00, 0x0, 0, 5, 0xFF } # S0 RCB3.0 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[14]|{ 14, 0, 7,= 4, 2, 0x00, 0x00, 0x0, 0, 5, 0xFF } # S0 RCB3.4 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[15]|{ 15, 0, 7,= 6, 3, 0x00, 0x00, 0x0, 0, 5, 0xFF } # S0 RCB3.6 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[16]|{ 16, 1, 2,= 0, 0, 0x26, 0x70, 0x2, 0, 6, 20 } # S1 RCA2.0 - SSD20 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[17]|{ 17, 1, 2,= 1, 1, 0x26, 0x70, 0x2, 0, 6, 21 } # S1 RCA2.1 - SSD21 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[18]|{ 18, 1, 2,= 2, 2, 0x27, 0x70, 0x2, 0, 6, 22 } # S1 RCA2.2 - SSD22 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[19]|{ 19, 1, 2,= 3, 3, 0x27, 0x70, 0x2, 0, 6, 23 } # S1 RCA2.3 - SSD23 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[20]|{ 20, 1, 3,= 0, 0, 0x00, 0x00, 0x0, 0, 7, 0xFF } # S1 RCA3.0 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[21]|{ 21, 1, 3,= 2, 1, 0x00, 0x00, 0x0, 0, 7, 0xFF } # S1 RCA3.2 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[22]|{ 22, 1, 4,= 0, 0, 0x00, 0x00, 0x0, 0, 8, 0xFF } # S1 RCB0.0 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[23]|{ 23, 1, 4,= 4, 2, 0x25, 0x70, 0x2, 0, 8, 18 } # S1 RCB0.4 - SSD18 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[24]|{ 24, 1, 4,= 6, 3, 0x25, 0x70, 0x2, 0, 8, 19 } # S1 RCB0.6 - SSD19 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[25]|{ 25, 1, 5,= 0, 0, 0x24, 0x70, 0x2, 0, 9, 16 } # S1 RCB1.0 - SSD16 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[26]|{ 26, 1, 5,= 2, 1, 0x24, 0x70, 0x2, 0, 9, 17 } # S1 RCB1.2 - SSD17 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[27]|{ 27, 1, 5,= 4, 2, 0x00, 0x00, 0x0, 0, 9, 0xFF } # S1 RCB1.4 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[28]|{ 28, 1, 6,= 0, 3, 0x25, 0x70, 0x4, 0, 10, 11 } # S1 RCB2.0 - SSD11 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[29]|{ 29, 1, 6,= 2, 2, 0x25, 0x70, 0x4, 0, 10, 10 } # S1 RCB2.2 - SSD10 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[30]|{ 30, 1, 6,= 4, 1, 0x27, 0x70, 0x4, 0, 10, 15 } # S1 RCB2.4 - SSD15 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[31]|{ 31, 1, 6,= 6, 0, 0x27, 0x70, 0x4, 0, 10, 14 } # S1 RCB2.6 - SSD14 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[32]|{ 32, 1, 7,= 0, 3, 0x26, 0x70, 0x4, 0, 11, 13 } # S1 RCB3.0 - SSD13 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[33]|{ 33, 1, 7,= 2, 2, 0x26, 0x70, 0x4, 0, 11, 12 } # S1 RCB3.2 - SSD12 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[34]|{ 34, 1, 7,= 4, 1, 0x24, 0x70, 0x4, 0, 11, 9 } # S1 RCB3.4 - SSD9 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[35]|{ 35, 1, 7,= 6, 0, 0x24, 0x70, 0x4, 0, 11, 8 } # S1 RCB3.6 - SSD8 + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable.PortMap[36]|{ 0xFF, 0, = 0, 0, 0, 0, 0, 0, 0, 0, 0xFF } # Require if no fully structure used + !ifdef $(FIRMWARE_VER) gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"$(FIRMWARE_VER= )" !endif diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieHotPlugLib/PcieHotPl= ugLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/PcieHotPlugLib/PcieHotPlu= gLib.inf new file mode 100644 index 000000000000..faeb74ecc0bf --- /dev/null +++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieHotPlugLib/PcieHotPlugLib.i= nf @@ -0,0 +1,37 @@ +## @file +# +# Copyright (c) 2023, Ampere Computing LLC. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x0001001B + BASE_NAME =3D PcieHotPlugLib + FILE_GUID =3D 6C0C1D32-CB51-4236-AC33-A7A6D4B638E2 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D PcieHotPlugLib + +[Sources] + PcieHotPlugLib.c + +[Packages] + ArmPkg/ArmPkg.dec + MdePkg/MdePkg.dec + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec + Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec + +[LibraryClasses] + ArmSmcLib + BaseMemoryLib + DebugLib + PcdLib + +[Pcd] + gAmpereTokenSpaceGuid.PcdPcieHotPlugGpioResetMap + gAmpereTokenSpaceGuid.PcdPcieHotPlugPortMapTable + +[Guids] + gPcieHotPlugGuid diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieHotPlugLib.h= b/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieHotPlugLib.h new file mode 100644 index 000000000000..e2f17d366a58 --- /dev/null +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieHotPlugLib.h @@ -0,0 +1,162 @@ +/** @file + + Copyright (c) 2023, Ampere Computing LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ + +#ifndef PCIE_HOT_PLUG_H_ +#define PCIE_HOT_PLUG_H_ + +#define PCIE_HOT_PLUG_SPCI_CMD_ALERT_IRQ 1 // Alert IRQ +#define PCIE_HOT_PLUG_SPCI_CMD_START 2 // Stat monitor event +#define PCIE_HOT_PLUG_SPCI_CMD_CHG 3 // Indicate PCIE port ch= ange state explicitly +#define PCIE_HOT_PLUG_SPCI_CMD_LED 4 // Control LED state +#define PCIE_HOT_PLUG_SPCI_CMD_PORT_MAP_CLR 5 // Clear all port map +#define PCIE_HOT_PLUG_SPCI_CMD_PORT_MAP_SET 6 // Set port map +#define PCIE_HOT_PLUG_SPCI_CMD_PORT_MAP_LOCK 7 // Lock port map +#define PCIE_HOT_PLUG_SPCI_CMD_GPIO_MAP 8 // Set GPIO reset map + +#define LED_FAULT 1 // LED_CMD: LED type - Fault +#define LED_ATT 2 // LED_CMD: LED type - Attention + +#define LED_SET_ON 1 +#define LED_SET_OFF 2 +#define LED_SET_BLINK 3 + +// DEN0077A Arm Secure Partition Client Interface Specification 1.0 Beta_0= _0 + +// Client ID used for SPCI calls +#define SPCI_CLIENT_ID 0x0000ACAC + +// SPCI error codes. +#define SPCI_SUCCESS 0 +#define SPCI_NOT_SUPPORTED -1 +#define SPCI_INVALID_PARAMETER -2 +#define SPCI_NO_MEMORY -3 +#define SPCI_BUSY -4 +#define SPCI_QUEUED -5 +#define SPCI_DENIED -6 +#define SPCI_NOT_PRESENT -7 + +// Bit definitions inside the function id as per the SMC calling conventio= n +#define FUNCID_CC_SHIFT 30 +#define FUNCID_OEN_SHIFT 24 + +#define SMC_64 1 +#define SMC_32 0 + +// Definitions to build the complete SMC ID +#define SPCI_FID_MISC_FLAG (0 << 27) +#define SPCI_FID_MISC_SHIFT 20 +#define SPCI_FID_TUN_FLAG (1 << 27) +#define SPCI_FID_TUN_SHIFT 24 + +#define OEN_SPCI_START 0x30 +#define OEN_SPCI_END 0x3F + +#define SPCI_SMC(spci_fid) ((OEN_SPCI_START << FUNCID_OEN_SHIFT) | \ + (1U << 31) | (spci_fid)) +#define SPCI_MISC_32(misc_fid) ((SMC_32 << FUNCID_CC_SHIFT) | \ + SPCI_FID_MISC_FLAG | \ + SPCI_SMC ((misc_fid) << SPCI_FID_MISC_SHI= FT)) +#define SPCI_MISC_64(misc_fid) ((SMC_64 << FUNCID_CC_SHIFT) | \ + SPCI_FID_MISC_FLAG | \ + SPCI_SMC ((misc_fid) << SPCI_FID_MISC_SHI= FT)) +#define SPCI_TUN_64(tun_fid) ((SMC_64 << FUNCID_CC_SHIFT) | \ + SPCI_FID_TUN_FLAG | \ + SPCI_SMC ((tun_fid) << SPCI_FID_TUN_SHIFT= )) + +// SPCI miscellaneous functions +#define SPCI_FID_SERVICE_HANDLE_OPEN 0x2 +#define SPCI_FID_SERVICE_HANDLE_CLOSE 0x3 +#define SPCI_FID_SERVICE_REQUEST_BLOCKING 0x7 +#define SPCI_FID_SERVICE_REQUEST_START 0x8 + +// SPCI tunneling functions +#define SPCI_FID_SERVICE_TUN_REQUEST_BLOCKING 0x2 + +// Complete SMC IDs and associated values +#define SPCI_SERVICE_HANDLE_OPEN \ + SPCI_MISC_32 (SPCI_FID_SERVICE_HANDLE_OPEN) +#define SPCI_SERVICE_HANDLE_CLOSE \ + SPCI_MISC_32 (SPCI_FID_SERVICE_HANDLE_CLOSE) +#define SPCI_SERVICE_REQUEST_BLOCKING_AARCH64 \ + SPCI_MISC_64 (SPCI_FID_SERVICE_REQUEST_BLOCKIN= G) +#define SPCI_SERVICE_REQUEST_START_AARCH64 \ + SPCI_MISC_64 (SPCI_FID_SERVICE_REQUEST_START) +#define SPCI_SERVICE_TUN_REQUEST_BLOCKING_AARCH64 \ + SPCI_TUN_64 (SPCI_FID_SERVICE_TUN_REQUEST_BLOC= KING) + +#pragma pack(1) + +typedef struct { + UINT64 Token; + UINT32 HandleId; + UINT64 SpciCommand; + UINT64 SpciParam1; + UINT64 SpciParam2; + UINT64 SpciParam3; + UINT64 SpciParam4; + UINT64 SpciParam5; +} AMPERE_SPCI_ARGS; + +#pragma pack() + +/** + Set GPIO pins used for PCIe reset. This command + limits the number of GPIO[16:21] for reset purpose. +**/ +VOID +PcieHotPlugSetGpioMap ( + VOID + ); + +/** + Lock current Portmap table. +**/ +VOID +PcieHotPlugSetLockPortMap ( + VOID + ); + +/** + Start Hot plug service. +**/ +VOID +PcieHotPlugSetStart ( + VOID + ); + +/** + Clear current configuration of Portmap table. +**/ +VOID +PcieHotPlugSetClear ( + VOID + ); + +/** + Set configuration for Portmap table. +**/ +VOID +PcieHotPlugSetPortMap ( + VOID + ); + +/** + This function will start Hotplug service after following steps: + - Open handle to make a SPCI call. + - Set GPIO pins for PCIe reset. + - Set configuration for Portmap table. + - Lock current Portmap table. + - Start Hot plug service. + - Close handle. +**/ +VOID +PcieHotPlugStart ( + VOID + ); + +#endif diff --git a/Silicon/Ampere/AmpereSiliconPkg/Include/Library/PcieHotPlugPor= tMapLib.h b/Silicon/Ampere/AmpereSiliconPkg/Include/Library/PcieHotPlugPort= MapLib.h new file mode 100644 index 000000000000..4889f0891c47 --- /dev/null +++ b/Silicon/Ampere/AmpereSiliconPkg/Include/Library/PcieHotPlugPortMapLib= .h @@ -0,0 +1,81 @@ +/** @file + + Copyright (c) 2023, Ampere Computing LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PCIE_HOT_PLUG_PORT_MAP_H_ +#define PCIE_HOT_PLUG_PORT_MAP_H_ + +// "PCIe Bifurcation Mapping" spec just reserve 24x48 bytes (48 ports) +#define MAX_NUMBER_PROCESSORS 2 +#define NUMBER_OF_PCIE_PORTS 48 +#define MAX_PORT_MAP_ENTRY (NUMBER_OF_PCIE_PORTS * MAX_NUMBER_PROCESSO= RS) + +// +// - Macro to create value for PCIe Hot Plug configuration from PcieHotPlu= gPortMapEntry structure. +// - Value structure: +// Bit [0:7]: Vport +// Bit [8:11]: Socket +// Bit [12:15]: RcaPort +// Bit [16:19]: RcaSubPort +// Bit [20:23]: PinPort +// Bit [24:31]: I2cAddress +// Bit [32:39]: MuxAddress +// Bit [40:43]: MuxChannel +// Bit [44:51]: GpioResetNumber +// Bit [52:55]: Segment +// Bit [56: 63]: DriveIndexGpioResetNumber +// +#define PCIE_HOT_PLUG_DECODE_VPORT(Value) ((((UINTN)(Value).V= port) & 0xFF) << 0) +#define PCIE_HOT_PLUG_DECODE_SOCKET(Value) ((((UINTN)(Value).S= ocket) & 0x0F) << 8) +#define PCIE_HOT_PLUG_DECODE_RCA_PORT(Value) ((((UINTN)(Value).R= caPort) & 0x0F) << 12) +#define PCIE_HOT_PLUG_DECODE_RCA_SUB_PORT(Value) ((((UINTN)(Value).R= caSubPort) & 0x0F) << 16) +#define PCIE_HOT_PLUG_DECODE_PIN_PORT(Value) ((((UINTN)(Value).P= inPort) & 0x0F) << 20) +#define PCIE_HOT_PLUG_DECODE_I2C_ADDRESS(Value) ((((UINTN)(Value).I= 2cAddress) & 0xFF) << 24) +#define PCIE_HOT_PLUG_DECODE_MUX_ADDRESS(Value) ((((UINTN)(Value).M= uxAddress) & 0xFF) << 32) +#define PCIE_HOT_PLUG_DECODE_MUX_CHANNEL(Value) ((((UINTN)(Value).M= uxChannel) & 0x0F) << 40) +#define PCIE_HOT_PLUG_DECODE_GPIO_RESET_NUMBER(Value) ((((UINTN)(Value).G= pioResetNumber) & 0xFF) << 44) +#define PCIE_HOT_PLUG_DECODE_SEGMENT(Value) ((((UINTN)(Value).S= egment) & 0x0F) << 52) +#define PCIE_HOT_PLUG_DECODE_DRIVE_INDEX(Value) ((((UINTN)(Value).D= riveIndex) & 0xFF) << 56) + +#define PCIE_HOT_PLUG_GET_CONFIG_VALUE(Value) ( \ + PCIE_HOT_PLUG_DECODE_VPORT(Value) | \ + PCIE_HOT_PLUG_DECODE_SOCKET(Value) | \ + PCIE_HOT_PLUG_DECODE_RCA_PORT(Value) | \ + PCIE_HOT_PLUG_DECODE_RCA_SUB_PORT(Value) | \ + PCIE_HOT_PLUG_DECODE_PIN_PORT(Value) | \ + PCIE_HOT_PLUG_DECODE_I2C_ADDRESS(Value) | \ + PCIE_HOT_PLUG_DECODE_MUX_ADDRESS(Value) | \ + PCIE_HOT_PLUG_DECODE_MUX_CHANNEL(Value) | \ + PCIE_HOT_PLUG_DECODE_GPIO_RESET_NUMBER(Value) | \ + PCIE_HOT_PLUG_DECODE_SEGMENT(Value) | \ + PCIE_HOT_PLUG_DECODE_DRIVE_INDEX(Value) \ +) + +#pragma pack(1) + +typedef struct { + UINT8 Vport; + UINT8 Socket; + UINT8 RcaPort; + UINT8 RcaSubPort; + UINT8 PinPort; + UINT8 I2cAddress; + UINT8 MuxAddress; + UINT8 MuxChannel; + UINT8 GpioResetNumber; + UINT8 Segment; + UINT8 DriveIndex; +} PCIE_HOT_PLUG_PORT_MAP_ENTRY; + +typedef struct { + BOOLEAN UseDefaultConfig; + UINT8 PortMap[MAX_PORT_MAP_ENTRY][sizeof (PCIE_HOT_PLUG_PORT_MAP_EN= TRY)]; +} PCIE_HOT_PLUG_PORT_MAP_TABLE; + +#pragma pack() + +#endif diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieHotPlugLib/PcieHotPl= ugLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/PcieHotPlugLib/PcieHotPlugL= ib.c new file mode 100644 index 000000000000..10de5d17d2b9 --- /dev/null +++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieHotPlugLib/PcieHotPlugLib.c @@ -0,0 +1,397 @@ +/** @file + + Copyright (c) 2023, Ampere Computing LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ + +#include + +#include +#include +#include +#include +#include +#include + +#define END_PORT_MAP_ENTRY 0xFF + +// SPM takes up to 4 arguments as value for SPCI call (Args.SpciParam1->Ar= gs.SpciParam4). +#define MAX_MSG_CMD_ARGS 4 + +UINT32 HandleId; + +STATIC +EFI_STATUS +SpciStatusMap ( + UINTN SpciStatus + ) +{ + switch (SpciStatus) { + case SPCI_SUCCESS: + return EFI_SUCCESS; + + case SPCI_NOT_SUPPORTED: + return EFI_UNSUPPORTED; + + case SPCI_INVALID_PARAMETER: + return EFI_INVALID_PARAMETER; + + case SPCI_NO_MEMORY: + return EFI_OUT_OF_RESOURCES; + + case SPCI_BUSY: + case SPCI_QUEUED: + return EFI_NOT_READY; + + case SPCI_DENIED: + return EFI_ACCESS_DENIED; + + case SPCI_NOT_PRESENT: + return EFI_NOT_FOUND; + + default: + return EFI_DEVICE_ERROR; + } +} + +EFI_STATUS +EFIAPI +SpciServiceHandleOpen ( + UINT16 ClientId, + UINT32 *HandleId, + EFI_GUID Guid + ) +{ + ARM_SMC_ARGS SmcArgs; + EFI_STATUS Status; + UINT32 X1; + UINT64 Uuid1, Uuid2, Uuid3, Uuid4; + + if (HandleId =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a HandleId is NULL \n", __func__)); + return EFI_INVALID_PARAMETER; + } + + Uuid1 =3D Guid.Data1; + Uuid2 =3D Guid.Data3 << 16 | Guid.Data2; + Uuid3 =3D Guid.Data4[3] << 24 | Guid.Data4[2] << 16 | Guid.Data4[1] << 8= | Guid.Data4[0]; + Uuid4 =3D Guid.Data4[7] << 24 | Guid.Data4[6] << 16 | Guid.Data4[5] << 8= | Guid.Data4[4]; + + SmcArgs.Arg0 =3D SPCI_SERVICE_HANDLE_OPEN; + SmcArgs.Arg1 =3D Uuid1; + SmcArgs.Arg2 =3D Uuid2; + SmcArgs.Arg3 =3D Uuid3; + SmcArgs.Arg4 =3D Uuid4; + SmcArgs.Arg5 =3D 0; + SmcArgs.Arg6 =3D 0; + SmcArgs.Arg7 =3D ClientId; + ArmCallSmc (&SmcArgs); + + Status =3D SpciStatusMap (SmcArgs.Arg0); + if (EFI_ERROR (Status)) { + return Status; + } + + X1 =3D SmcArgs.Arg1; + + if ((X1 & 0x0000FFFF) !=3D 0) { + DEBUG (( + DEBUG_ERROR, + "%a: SpciServiceHandleOpen returned X1 =3D 0x%08x\n", + __func__, + X1 + )); + return EFI_DEVICE_ERROR; + } + + // Combine of returned handle and clientid + *HandleId =3D (UINT32)X1 | ClientId; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +SpciServiceHandleClose ( + UINT32 HandleId + ) +{ + ARM_SMC_ARGS SmcArgs; + EFI_STATUS Status; + + SmcArgs.Arg0 =3D SPCI_SERVICE_HANDLE_CLOSE; + SmcArgs.Arg1 =3D HandleId; + ArmCallSmc (&SmcArgs); + + Status =3D SpciStatusMap (SmcArgs.Arg0); + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +SpciServiceRequestStart ( + AMPERE_SPCI_ARGS *Args + ) +{ + ARM_SMC_ARGS SmcArgs; + EFI_STATUS Status; + + if (Args =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: Invalid parameter\n", __func__)); + return EFI_INVALID_PARAMETER; + } + + SmcArgs.Arg0 =3D SPCI_SERVICE_REQUEST_START_AARCH64; + SmcArgs.Arg1 =3D Args->SpciCommand; + SmcArgs.Arg2 =3D Args->SpciParam1; + SmcArgs.Arg3 =3D Args->SpciParam2; + SmcArgs.Arg4 =3D Args->SpciParam3; + SmcArgs.Arg5 =3D Args->SpciParam4; + SmcArgs.Arg6 =3D Args->SpciParam5; + SmcArgs.Arg7 =3D (UINT64)Args->HandleId; + ArmCallSmc (&SmcArgs); + + Status =3D SpciStatusMap (SmcArgs.Arg0); + if (EFI_ERROR (Status)) { + return Status; + } + + // Return Token + Args->Token =3D SmcArgs.Arg1; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +SpciServiceRequestBlocking ( + AMPERE_SPCI_ARGS *Args + ) +{ + ARM_SMC_ARGS SmcArgs; + EFI_STATUS Status; + + if (Args =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: Invalid parameter\n", __func__)); + return EFI_INVALID_PARAMETER; + } + + SmcArgs.Arg0 =3D SPCI_SERVICE_REQUEST_BLOCKING_AARCH64; + SmcArgs.Arg1 =3D Args->SpciCommand; + SmcArgs.Arg2 =3D Args->SpciParam1; + SmcArgs.Arg3 =3D Args->SpciParam2; + SmcArgs.Arg4 =3D Args->SpciParam3; + SmcArgs.Arg5 =3D Args->SpciParam4; + SmcArgs.Arg6 =3D Args->SpciParam5; + SmcArgs.Arg7 =3D (UINT64)Args->HandleId; + ArmCallSmc (&SmcArgs); + + Status =3D SpciStatusMap (SmcArgs.Arg0); + if (EFI_ERROR (Status)) { + return Status; + } + + Args->SpciCommand =3D SmcArgs.Arg1; + Args->SpciParam1 =3D SmcArgs.Arg2; + Args->SpciParam2 =3D SmcArgs.Arg3; + + return EFI_SUCCESS; +} + +/** + Set GPIO pins used for PCIe reset. This command + limits the number of GPIO[16:21] for reset purpose. +**/ +VOID +PcieHotPlugSetGpioMap ( + VOID + ) +{ + AMPERE_SPCI_ARGS Args; + EFI_STATUS Status; + + Args.HandleId =3D HandleId; + Args.SpciCommand =3D PCIE_HOT_PLUG_SPCI_CMD_GPIO_MAP; + Args.SpciParam1 =3D (UINTN)PcdGet8 (PcdPcieHotPlugGpioResetMap); + + Status =3D SpciServiceRequestBlocking (&Args); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SPM HotPlug GPIO reset map failed. Returned: %r\= n", Status)); + } +} + +/** + Lock current Portmap table. +**/ +VOID +PcieHotPlugSetLockPortMap ( + VOID + ) +{ + AMPERE_SPCI_ARGS Args; + EFI_STATUS Status; + + Args.HandleId =3D HandleId; + Args.SpciCommand =3D PCIE_HOT_PLUG_SPCI_CMD_PORT_MAP_LOCK; + + Status =3D SpciServiceRequestBlocking (&Args); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SPM HotPlug port map lock failed. Returned: %r\n= ", Status)); + } +} + +/** + Start Hot plug service. +**/ +VOID +PcieHotPlugSetStart ( + VOID + ) +{ + AMPERE_SPCI_ARGS Args; + EFI_STATUS Status; + + Args.HandleId =3D HandleId; + Args.SpciCommand =3D PCIE_HOT_PLUG_SPCI_CMD_START; + + Status =3D SpciServiceRequestBlocking (&Args); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SPM HotPlug start failed. Returned: %r\n", Statu= s)); + } +} + +/** + Clear current configuration of Portmap table. +**/ +VOID +PcieHotPlugSetClear ( + VOID + ) +{ + AMPERE_SPCI_ARGS Args; + EFI_STATUS Status; + + Args.HandleId =3D HandleId; + Args.SpciCommand =3D PCIE_HOT_PLUG_SPCI_CMD_PORT_MAP_CLR; + + Status =3D SpciServiceRequestBlocking (&Args); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SPM HotPlug clear port map failed. Returned: %r\= n", Status)); + } +} + +/** + Set configuration for Portmap table. +**/ +VOID +PcieHotPlugSetPortMap ( + VOID + ) +{ + AMPERE_SPCI_ARGS Args; + EFI_STATUS Status; + + PCIE_HOT_PLUG_PORT_MAP_TABLE *PortMapTable; + PCIE_HOT_PLUG_PORT_MAP_ENTRY PortMapEntry; + UINT8 Index; + UINT8 PortMapEntryIndex; + BOOLEAN IsEndPortMapEntry; + UINTN ConfigValue; + UINTN *ConfigLegacy; + + // Retrieves PCD of Portmap table. + PortMapTable =3D (PCIE_HOT_PLUG_PORT_MAP_TABLE *)PcdGetPtr (PcdPcieHotPl= ugPortMapTable); + + // + // Check whether specific platform configuration is used? + // Otherwise, keep default configuration (Mt. Jade 2U). + // + if (!PortMapTable->UseDefaultConfig) { + IsEndPortMapEntry =3D FALSE; + PortMapEntryIndex =3D 0; + + // Clear old Port Map table first. + PcieHotPlugSetClear (); + + while (!IsEndPortMapEntry) { + ZeroMem (&Args, sizeof (Args)); + Args.HandleId =3D HandleId; + Args.SpciCommand =3D PCIE_HOT_PLUG_SPCI_CMD_PORT_MAP_SET; + + // Pointer will get configuration value for Args.SpciParam1->Args.Sp= ciParam5 + ConfigLegacy =3D &Args.SpciParam1; + + for (Index =3D 0; Index < MAX_MSG_CMD_ARGS; Index++) { + PortMapEntry =3D *((PCIE_HOT_PLUG_PORT_MAP_ENTRY *)PortMapTable->= PortMap[PortMapEntryIndex]); + ConfigValue =3D PCIE_HOT_PLUG_GET_CONFIG_VALUE (PortMapEntry); + *ConfigLegacy =3D ConfigValue; + + if (PortMapTable->PortMap[PortMapEntryIndex][0] =3D=3D END_PORT_MA= P_ENTRY) { + IsEndPortMapEntry =3D TRUE; + break; + } + + PortMapEntryIndex++; + ConfigLegacy++; + } + + Status =3D SpciServiceRequestBlocking (&Args); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SPM HotPlug set port map failed. Returned: %= r\n", Status)); + } + } + } +} + +/** + This function will start Hotplug service after following steps: + - Open handle to make a SPCI call. + - Set GPIO pins for PCIe reset. + - Set configuration for Portmap table. + - Lock current Portmap table. + - Start Hot plug service. + - Close handle. +**/ +VOID +PcieHotPlugStart ( + VOID + ) +{ + EFI_STATUS Status; + + // Open handle + Status =3D SpciServiceHandleOpen (SPCI_CLIENT_ID, &HandleId, gPcieHotPlu= gGuid); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "SPM failed to return invalid handle. Returned: %r\n", + Status + )); + + return; + } + + // Set GPIO pins for PCIe reset + PcieHotPlugSetGpioMap (); + + // Set Portmap table + PcieHotPlugSetPortMap (); + + // Lock current Portmap table + PcieHotPlugSetLockPortMap (); + + // Start Hot plug service + PcieHotPlugSetStart (); + + // Close handle + Status =3D SpciServiceHandleClose (HandleId); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SPM HotPlug close handle failed. Returned: %r\n"= , Status)); + } +} --=20 2.39.0