From nobody Tue Feb 10 12:40:48 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+83837+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+83837+1787277+3901457@groups.io; arc=fail (BodyHash is different from the expected one); dmarc=pass(p=none dis=none) header.from=groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1637167855902773.555700140729; Wed, 17 Nov 2021 08:50:55 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id RlcfYY1788612xmfqoZjclY6; Wed, 17 Nov 2021 08:50:55 -0800 X-Received: from NAM10-BN7-obe.outbound.protection.outlook.com (NAM10-BN7-obe.outbound.protection.outlook.com [40.107.92.115]) by mx.groups.io with SMTP id smtpd.web11.9792.1637167854688814086 for ; Wed, 17 Nov 2021 08:50:55 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=m50NB52i3WyzHWveCN+z+w3W7JRcbAN1mtZeMfvzQD53TPLRuHDJ/E7hj3ekBAqQ15JdNXvfXyPfH8dZadQ5BFsK9VzzS6tsUkEX5LDEavpOrMASQcpIBDUfBR7wbf7vdvwxfGd7KWCvMgldaVVkkTGsKltEH50aXGEQsgsDstnbzU/z4KScYIpCyHGBguNnWzBngql8veZpv0kJrLRXWHsG8gpM78pRZJtRqHUCG4uHZrU8iTh2A/c+wgkLb9yqcwzdRLg5nj/xnUVkCqIFqI/Wv08AfihviILq4dWJQpGgCpt4MHaV5Z1c/al+ntGLVUSclZ+wsxnNKUqB2wEN2A== 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=6JecveFthjg0jYJ+kOAIoPkmwZ9VgUGUR/WIneSLfkg=; b=lDAJcs02t5IcarUoXqk396dF+jO7BOwyxTNPkzklvwklnbJbeLvvbIWrigmrdhqIlvZyXERTH9HmDRjare5EGI3jVT1i/LANeJbbs1WeN9nDKD7Mwkp8Vg+uqYGKcCvlcp4TwKezmwO0c+C4O531OD/b+pG/wsvYBwT6ODwxs/L+IYrjLU4Ii3zjlxxM9xicvoF1rQL6vvcCheWFvLnRyoc72QM2+HHRdT5kt/icotNkGhv47Ad9uom+o/xbB1+7KBXs9vmt16HOKRKx97UFolwxLJUOn4eG5deaiSkjeWFtYTI5JIGugt7zlCDbro1mPpGK0zfyelk95sjeS55+mA== 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 X-Received: from PH0PR01MB7287.prod.exchangelabs.com (2603:10b6:510:10a::21) by PH0PR01MB7521.prod.exchangelabs.com (2603:10b6:510:f4::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4713.19; Wed, 17 Nov 2021 16:50:53 +0000 X-Received: from PH0PR01MB7287.prod.exchangelabs.com ([fe80::254c:9533:7f35:aee]) by PH0PR01MB7287.prod.exchangelabs.com ([fe80::254c:9533:7f35:aee%4]) with mapi id 15.20.4713.019; Wed, 17 Nov 2021 16:50:53 +0000 From: "Nhi Pham via groups.io" To: devel@edk2.groups.io CC: patches@amperecomputing.com, nhi@os.amperecomputing.com, vunguyen@os.amperecomputing.com, Thang Nguyen , Chuong Tran , Phong Vo , Leif Lindholm , Michael D Kinney , Ard Biesheuvel , Nate DeSimone Subject: [edk2-devel] [edk2-platforms][PATCH v5 24/30] Ampere: Utilize the PCIe User setting Date: Wed, 17 Nov 2021 23:47:21 +0700 Message-ID: <20211117164727.10922-25-nhi@os.amperecomputing.com> In-Reply-To: <20211117164727.10922-1-nhi@os.amperecomputing.com> References: <20211117164727.10922-1-nhi@os.amperecomputing.com> X-ClientProxiedBy: HKAPR04CA0001.apcprd04.prod.outlook.com (2603:1096:203:d0::11) To PH0PR01MB7287.prod.exchangelabs.com (2603:10b6:510:10a::21) MIME-Version: 1.0 X-Received: from sw004.amperecomputing.com (118.69.219.201) by HKAPR04CA0001.apcprd04.prod.outlook.com (2603:1096:203:d0::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4713.21 via Frontend Transport; Wed, 17 Nov 2021 16:50:50 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 4ad7842d-bd5c-469c-6d94-08d9a9ea6ac3 X-MS-TrafficTypeDiagnostic: PH0PR01MB7521: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:2000; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: tmh6KZ71Tf3g+6qXPSun17Or86kIzt5BtqJ2rPnGgUePvyzIGfcEDb4lGuUGnc3o1QmUyNOxF+buN4aKYTLBcqW6UNXD2PNmdxz1zsNxP1afpm6FCAlcKW8uT1S9WmJOpSW1bOkG90FHzntdZij+S8jAs0FYlnesARTW9t/8iXKzH4Md822jVXEuIbKps4JwYpy0zYrbhR6K7//DrSZNN/swmTH/l+cdZd4boGbAwNoQSVOaQ52fA9UrzL9UrnB7nxaHbpO6otQKZ6HsKvFWHLNfS0KoCmsU89Pu2OBa1TfjaYSAPwtl6dYdjmyc7hBGVmCsNM2N+Zd/Xif6ksix+9U8/V6wCl7RcNr2JmPoBz/MPOaKbe0jkUThl2YVTFaYeZhqQ9w4CGFls1ZNx4XEHGMaob1OOd+mH74IAp6vpamsOvbHBUXhBrG3g1pFiFx21b20ZYVYxQRPvK1EzBTpGA7NQuSr2b/nP6EmjNTsviejokMMgQg6tWTqz3cnUwtcs7tC9TTj6pzuzDXxv1R5p3/ufBQRSaPeUKei4w2CQ2KlNPH26dfA1EtVI4C5bpdu27rVBImQ7kGq3ul1YrieRNsEpVNH4CwlQc6l/huYQ7vemest3YtLeOx5EFURm8o2DIEjXI07U3poS6zuumfJXvXAJkVj/Dggx3OPnhe2Qu1Ap01uL0o5h8ah5yJE/2AHUaxVIGMc6nYbCzXrTD/r/g== X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?5+WHdOuce+sk6H1403mP6MuIgVr09zOdESIguZwbkv7QRVnzOxGPkch6Zzxi?= =?us-ascii?Q?h7hb1fcXjqwqXxe7/1F31fp2OTQCE42cBsdYNbZc9qso7dfB6WYEqXMTQ7dy?= =?us-ascii?Q?nZ6SUPPpsphZm+/2RKIug57NpY8pf10f56/aDUoqYPdNLD0hVYxtdR49L1RC?= =?us-ascii?Q?Xbi8aSHsAl6o7bWmnh5U7cQik/K8AydorIOg9ogSw9uDOYtcIvsCkR53/Fsc?= =?us-ascii?Q?BRd306Zf+ubKELD0D4kWe/oE0kA013QE/gGyj9mnLy/eNADPWPzsQuF2EFOn?= =?us-ascii?Q?zHWapfDDVU61wCSOX7R3oBeBuuGxVzjlkSUnlvcp2wcQwPrGgDhurcZwEgaU?= =?us-ascii?Q?xCKSKkqxAFBMg6huVO4qHjnhZjnSNx7Uq612ovXeixk0tMzWzOUxlNmHjFll?= =?us-ascii?Q?CTPFWRp1qGloHXCKu7W51tFbMZNtB30GO3PmrPEPbDGFH5tPLI0uVODB48sG?= =?us-ascii?Q?dzC85aUwIulX24hE1sQ19oAaUoOVjDr2aTY0M47jJC9zib2yoP3oH2zNkdqg?= =?us-ascii?Q?IBUUGf94GhTPaaDYgCsOfdSAdvmvqBHG6u442BURQ7AgKFXjGCETyTsh9s8J?= =?us-ascii?Q?33hKDhb3ISpIrrRBNlmt6i4k58aAbvnWYaVTsEvAz15gXIRgVLKBWyVT6bat?= =?us-ascii?Q?4JUvTrN2Bj+RcMm8ABVaLahqMlBr2d4X/85+sqhdPJ17+hGaN5UgzCmB/ZeW?= =?us-ascii?Q?s7QQ7tk2gDvWxes/Q7LzYvyXUChuztCDzvskD4RX7zBzcXGhWQZ6pHL6qMGG?= =?us-ascii?Q?cnAsOSuQZ36Zpjn3Y+wcp+IgOobGITY/7SjZmIO3GuMC/tcnQAY1mhWHAlRo?= =?us-ascii?Q?BPfINU0m59Zpc9wO0rZdqnzgxLyqZP7w7GNW5/qpS2N4NZnASW4BCfgteN1b?= =?us-ascii?Q?6UKLXrlxct/e0x/vLKRG7C3XgBGCL2mYcXCW1iX5aPvhd82VDkv3L/Bcnmel?= =?us-ascii?Q?SAF1gM1cy1zbL7dNPG7qC1CeddoFfUhYAPxabnt8VfYDS6IglpmLtovjREcY?= =?us-ascii?Q?xYzRgQAfsgwHDDcKalihO1sSGoMgAVuiQDXKKRk3oaUlkTe03ODj59tl2Cg/?= =?us-ascii?Q?RzgtBpbsb6WuYlhoHMlkfQ91Twmp/qUakeORxC8TyFuXDY8sJFG57nbOTg01?= =?us-ascii?Q?++WlgwmWtltFLZTL4gHdhSe3iTYizV4lEtrbdL65UX6JS6t+braC3R4NLVZu?= =?us-ascii?Q?ao8PSPNF8QA7uVro0+0o8v/FMyHFwHsq13kytNiLA/xG2itP7wpaWB3l76jN?= =?us-ascii?Q?w4yW2xNGSVnL0LL73B1hXv9TxPLygNfZpuZBixdFTTM0Sqr5Vm+cG4CU3EQy?= =?us-ascii?Q?DlzhgkLAvvksMZj9o0YgyUthEg1pUkE3S4xmFpO2PY7EKzbEK+U9D4A7pQre?= =?us-ascii?Q?1/k2ZkFDARDcwWSmMjFenVAjXAeHrftkRgHYH0qgmwfUYJ+l2cTq99e9C2qC?= =?us-ascii?Q?p/AfLekniruWOpiNFLPFwk7ZfiM7wytyFoajKno2py5ec5dIO1Ot11LvTMTp?= =?us-ascii?Q?dkwp+fPV3Ue7KB96i/jkyeU4ij/nrk+xd5Id452gF2i8xXGB2recoDX2yP+N?= =?us-ascii?Q?zbQnAPV97ulaVNV8iDzJZ8Zv2BFSo4CKyqd7psumCcYMCkRNQ/MjryhKmVL9?= =?us-ascii?Q?plZ/bCoRcq/Qkjicg/vYbNCdiFDvjkMizO9PFcNRgyhz7zk4Pv+pTclXtHeH?= =?us-ascii?Q?flzQh+BLhfjeieK0ZJ7XCRtA+n8=3D?= X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4ad7842d-bd5c-469c-6d94-08d9a9ea6ac3 X-MS-Exchange-CrossTenant-AuthSource: PH0PR01MB7287.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Nov 2021 16:50:53.0619 (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: T/AvV3BEw237ZRuhsaJpFRyWQ8bV848GMCPe4fR7VOhJt1qEbKv36921CrXrAV7uU71qxhn2K7TSWJcCeY/eMRl6PynEb7TKuVURMEisIRI= X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR01MB7521 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,nhi@os.amperecomputing.com X-Gm-Message-State: iOLymvaPWEIRFsEtMGMkht48x1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1637167855; bh=mrs9pP6qYZcPyIHQol9wnZWs8TX88CCBcVDbnAJ4SO4=; h=CC:Content-Type:Date:From:Reply-To:Subject:To; b=Z1ncAk4bW9F/jXg52hI11pcrHAeiSZok/naOyfpOhUvL2Rl/r0r6LFkD96RwdSTeTK6 1jLOeICZzLMFrazR0tzh2Rb7BApEshVk2yJsYL5rw7dNPl2xoiUl07psfFAx9LvksUQwA 8eteAeSvZNlDl7ma5PpMViP4B818SmJHeQs= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1637167857354100002 Content-Type: text/plain; charset="utf-8" From: Vu Nguyen This change allows to configure the PCIe bifurcation mode and update the ACPI IORT tables based on the PCIe User setting. Cc: Thang Nguyen Cc: Chuong Tran Cc: Phong Vo Cc: Leif Lindholm Cc: Michael D Kinney Cc: Ard Biesheuvel Cc: Nate DeSimone Signed-off-by: Nhi Pham Reviewed-by: Leif Lindholm --- Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf | 2 + Silicon/Ampere/AmpereAltraPkg/Drivers/PcieInitPei/PcieInitPei.inf | 5 += ++ Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiIort.c | 32 += +++++++++++---- Silicon/Ampere/AmpereAltraPkg/Drivers/PcieInitPei/PcieInitPei.c | 40 += +++++++++++++++++-- 4 files changed, 69 insertions(+), 10 deletions(-) diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDx= e.inf b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf index 415f795d2a54..804e761a1524 100644 --- a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf @@ -52,6 +52,7 @@ [LibraryClasses] UefiBootServicesTableLib UefiDriverEntryPoint UefiLib + UefiRuntimeServicesTableLib =20 [Pcd] gArmPlatformTokenSpaceGuid.PcdCoreCount @@ -70,6 +71,7 @@ [Guids] gEfiEventReadyToBootGuid gPlatformInfoHobGuid gRootComplexInfoHobGuid + gRootComplexConfigFormSetGuid =20 [Protocols] gEfiAcpiTableProtocolGuid ## ALWAYS_CONSUMED diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieInitPei/PcieInitPei.= inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieInitPei/PcieInitPei.inf index 17ac1672dac8..32d60bec1440 100644 --- a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieInitPei/PcieInitPei.inf +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieInitPei/PcieInitPei.inf @@ -31,9 +31,14 @@ [LibraryClasses] DebugLib HobLib PeimEntryPoint + PeiServicesLib + +[Ppis] + gEfiPeiReadOnlyVariable2PpiGuid =20 [Guids] gRootComplexInfoHobGuid + gRootComplexConfigFormSetGuid gPlatformInfoHobGuid =20 [Depex] diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiIort.c b/P= latform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiIort.c index b8f8cfa356af..97be85c51f25 100644 --- a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiIort.c +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiIort.c @@ -7,6 +7,7 @@ **/ =20 #include +#include #include #include #include @@ -17,6 +18,7 @@ #include #include #include +#include #include #include =20 @@ -282,8 +284,10 @@ AcpiInstallIort ( EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; EFI_STATUS Status; INT32 EnabledRCs[AC01_PCIE_MAX_ROOT_COMPLEX]; + ROOT_COMPLEX_CONFIG_VARSTORE_DATA VarStoreConfig; UINT32 RcCount, SmmuPmuAgentCount, TotalCount; UINT8 Idx; + UINTN BufferSize; UINTN TableKey; VOID *Hob; VOID *IortBuffer; @@ -313,14 +317,28 @@ AcpiInstallIort ( } =20 SmmuPmuAgentCount =3D 0; - for (Idx =3D 0; Idx < RcCount; Idx++) { - if (mRootComplexList[EnabledRCs[Idx]].Type =3D=3D RootComplexTypeA) { - SmmuPmuAgentCount +=3D AC01_RCA_MAX_TBU_PMU; - } else { - SmmuPmuAgentCount +=3D AC01_RCB_MAX_TBU_PMU; + + // + // Check SMMU setting + // + BufferSize =3D sizeof (VarStoreConfig); + Status =3D gRT->GetVariable ( + ROOT_COMPLEX_CONFIG_VARSTORE_NAME, + &gRootComplexConfigFormSetGuid, + NULL, + &BufferSize, + &VarStoreConfig + ); + if (!EFI_ERROR (Status) && VarStoreConfig.SmmuPmu) { + for (Idx =3D 0; Idx < RcCount; Idx++) { + if (mRootComplexList[EnabledRCs[Idx]].Type =3D=3D RootComplexTypeA) { + SmmuPmuAgentCount +=3D AC01_RCA_MAX_TBU_PMU; + } else { + SmmuPmuAgentCount +=3D AC01_RCB_MAX_TBU_PMU; + } + // Plus 1 TCU + SmmuPmuAgentCount +=3D 1; } - // Plus 1 TCU - SmmuPmuAgentCount +=3D 1; } =20 TotalCount =3D sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE) + diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieInitPei/PcieInitPei.= c b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieInitPei/PcieInitPei.c index cdd907d378e8..17f6112ea207 100644 --- a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieInitPei/PcieInitPei.c +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieInitPei/PcieInitPei.c @@ -8,6 +8,7 @@ =20 #include =20 +#include #include #include #include @@ -15,7 +16,9 @@ #include #include #include +#include #include +#include =20 #include "RootComplexNVParam.h" =20 @@ -43,8 +46,39 @@ BuildRootComplexData ( ) { AC01_ROOT_COMPLEX *RootComplex; + BOOLEAN ConfigFound; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi; + EFI_STATUS Status; + ROOT_COMPLEX_CONFIG_VARSTORE_DATA RootComplexConfig; UINT8 RCIndex; UINT8 PcieIndex; + UINTN DataSize; + + ConfigFound =3D FALSE; + + // + // Get the Root Complex config from NVRAM + // + Status =3D PeiServicesLocatePpi ( + &gEfiPeiReadOnlyVariable2PpiGuid, + 0, + NULL, + (VOID **)&VariablePpi + ); + if (!EFI_ERROR (Status)) { + DataSize =3D sizeof (RootComplexConfig); + Status =3D VariablePpi->GetVariable ( + VariablePpi, + ROOT_COMPLEX_CONFIG_VARSTORE_NAME, + &gRootComplexConfigFormSetGuid, + NULL, + &DataSize, + &RootComplexConfig + ); + if (!EFI_ERROR (Status)) { + ConfigFound =3D TRUE; + } + } =20 ZeroMem (&mRootComplexList, sizeof (AC01_ROOT_COMPLEX) * AC01_PCIE_MAX_R= OOT_COMPLEX); =20 @@ -58,9 +92,9 @@ BuildRootComplexData ( =20 for (RCIndex =3D 0; RCIndex < AC01_PCIE_MAX_ROOT_COMPLEX; RCIndex++) { RootComplex =3D &mRootComplexList[RCIndex]; - RootComplex->Active =3D TRUE; - RootComplex->DevMapLow =3D 0; - RootComplex->DevMapHigh =3D 0; + RootComplex->Active =3D ConfigFound ? RootComplexConfig.RCStatus[RCInd= ex] : TRUE; + RootComplex->DevMapLow =3D ConfigFound ? RootComplexConfig.RCBifurcati= onLow[RCIndex] : 0; + RootComplex->DevMapHigh =3D ConfigFound ? RootComplexConfig.RCBifurcat= ionLow[RCIndex] : 0; RootComplex->Socket =3D RCIndex / AC01_PCIE_MAX_RCS_PER_SOCKET; RootComplex->ID =3D RCIndex % AC01_PCIE_MAX_RCS_PER_SOCKET; RootComplex->CsrBase =3D mCsrBase[RCIndex]; --=20 2.17.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#83837): https://edk2.groups.io/g/devel/message/83837 Mute This Topic: https://groups.io/mt/87123908/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-