From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8A582C00528 for ; Thu, 27 Jul 2023 08:04:16 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id CE3AA86870; Thu, 27 Jul 2023 10:03:59 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="jfIGRm6U"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 61E328687D; Thu, 27 Jul 2023 10:01:37 +0200 (CEST) Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 21BFD8680B for ; Thu, 27 Jul 2023 10:00:41 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=nm@ti.com Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 36R80UQm073148; Thu, 27 Jul 2023 03:00:30 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1690444830; bh=veglNWtj2OsL1I14rcWBDTjLgEmmiAzFzkn/MU2G0YQ=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=jfIGRm6UhJdZVtnnb1az9LEjiZxy5ECGOJFxBTHymLPW0ngxnPfnh16CGz04ux3sd Vk0cKfMdYRX444B3Gy4UyeWVVZ0AFI0M3oKyE7jHGSdXwsWb9j3qJIqp4LYxSW5RW6 T5zbx9c8NTVonh03V7eH2/jmPKB+XNhr+PSMGSZY= Received: from DFLE112.ent.ti.com (dfle112.ent.ti.com [10.64.6.33]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 36R80UJD039404 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 27 Jul 2023 03:00:30 -0500 Received: from DFLE111.ent.ti.com (10.64.6.32) by DFLE112.ent.ti.com (10.64.6.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Thu, 27 Jul 2023 03:00:29 -0500 Received: from lelv0326.itg.ti.com (10.180.67.84) by DFLE111.ent.ti.com (10.64.6.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Thu, 27 Jul 2023 03:00:29 -0500 Received: from localhost (ileaxei01-snat.itg.ti.com [10.180.69.5]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id 36R80Tf0018297; Thu, 27 Jul 2023 03:00:29 -0500 From: Nishanth Menon To: , Tom Rini CC: Wadim Egorov , Francesco Dolcini , Sjoerd Simons , Neha Malcom Francis , Bryan Brattlof , Vignesh Raghavendra , Marcel Ziswiler , Nikhil Jain , Nishanth Menon Subject: [PATCH 05/16] doc: board: ti: k3: Reuse build instructions Date: Thu, 27 Jul 2023 03:00:16 -0500 Message-ID: <20230727080027.2817701-6-nm@ti.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230727080027.2817701-1-nm@ti.com> References: <20230727080027.2817701-1-nm@ti.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Introduce common variables to define a generic build instruction that is then used in specific board specific description. Labels are introduced in the evm.rst files to be then reused in variant board documentation as well. Signed-off-by: Nishanth Menon --- doc/board/ti/am62x_sk.rst | 61 +++++++++++++++++-------- doc/board/ti/am65x_evm.rst | 61 +++++++++++++++++-------- doc/board/ti/j7200_evm.rst | 58 ++++++++++++++++------- doc/board/ti/j721e_evm.rst | 59 ++++++++++++++++-------- doc/board/ti/k3.rst | 94 ++++++++++++++++++++++++++++++++------ 5 files changed, 245 insertions(+), 88 deletions(-) diff --git a/doc/board/ti/am62x_sk.rst b/doc/board/ti/am62x_sk.rst index f511b5935c16..c8a696d3920b 100644 --- a/doc/board/ti/am62x_sk.rst +++ b/doc/board/ti/am62x_sk.rst @@ -56,39 +56,60 @@ Sources: Build procedure: ---------------- -1. Trusted Firmware-A: +0. Setup the environment variables: -.. code-block:: bash +.. include:: k3.rst + :start-after: .. k3_rst_include_start_common_env_vars_desc + :end-before: .. k3_rst_include_end_common_env_vars_desc - $ make CROSS_COMPILE=aarch64-none-linux-gnu- ARCH=aarch64 PLAT=k3 \ - TARGET_BOARD=lite SPD=opteed +.. include:: k3.rst + :start-after: .. k3_rst_include_start_board_env_vars_desc + :end-before: .. k3_rst_include_end_board_env_vars_desc -2. OP-TEE: +Set the variables corresponding to this platform: +.. include:: k3.rst + :start-after: .. k3_rst_include_start_common_env_vars_defn + :end-before: .. k3_rst_include_end_common_env_vars_defn .. code-block:: bash - $ make PLATFORM=k3 CFG_ARM64_core=y CROSS_COMPILE=arm-none-linux-gnueabihf- \ - CROSS_COMPILE64=aarch64-none-linux-gnu- + $ export UBOOT_CFG_CORTEXR=am62x_evm_r5_defconfig + $ export UBOOT_CFG_CORTEXA=am62x_evm_a53_defconfig + $ export TFA_BOARD=lite + $ # we dont use any extra TFA parameters + $ unset TFA_EXTRA_ARGS + $ export OPTEE_PLATFORM=k3-am62x + $ export OPTEE_EXTRA_ARGS="CFG_WITH_SOFTWARE_PRNG=y" -3. U-Boot: +.. am62x_evm_rst_include_start_build_steps -* 3.1 R5: +1. Trusted Firmware-A: -.. code-block:: bash +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_tfa + :end-before: .. k3_rst_include_end_build_steps_tfa - $ make ARCH=arm am62x_evm_r5_defconfig - $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf- \ - BINMAN_INDIRS= -* 3.2 A53: +2. OP-TEE: -.. code-block:: bash +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_optee + :end-before: .. k3_rst_include_end_build_steps_optee + +3. U-Boot: - $ make ARCH=arm am62x_evm_a53_defconfig - $ make ARCH=arm CROSS_COMPILE=aarch64-none-linux-gnu- \ - BL31=/build/k3/lite/release/bl31.bin \ - TEE=/out/arm-plat-k3/core/tee-raw.bin \ - BINMAN_INDIRS= +* 4.1 R5: + +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_spl_r5 + :end-before: .. k3_rst_include_end_build_steps_spl_r5 + +* 4.2 A72: + +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_uboot + :end-before: .. k3_rst_include_end_build_steps_uboot +.. am62x_evm_rst_include_end_build_steps Target Images -------------- diff --git a/doc/board/ti/am65x_evm.rst b/doc/board/ti/am65x_evm.rst index 7876886bc0d3..134ad0ed7fbc 100644 --- a/doc/board/ti/am65x_evm.rst +++ b/doc/board/ti/am65x_evm.rst @@ -55,38 +55,61 @@ Sources: Build procedure: ---------------- -1. Trusted Firmware-A: +0. Setup the environment variables: -.. code-block:: bash +.. include:: k3.rst + :start-after: .. k3_rst_include_start_common_env_vars_desc + :end-before: .. k3_rst_include_end_common_env_vars_desc - $ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=aarch64 PLAT=k3 \ - TARGET_BOARD=generic SPD=opteed +.. include:: k3.rst + :start-after: .. k3_rst_include_start_board_env_vars_desc + :end-before: .. k3_rst_include_end_board_env_vars_desc -2. OP-TEE: +Set the variables corresponding to this platform: +.. include:: k3.rst + :start-after: .. k3_rst_include_start_common_env_vars_defn + :end-before: .. k3_rst_include_end_common_env_vars_defn .. code-block:: bash - $ make PLATFORM=k3-am65x CFG_ARM64_core=y + $ export UBOOT_CFG_CORTEXR=am65x_evm_r5_defconfig + $ export UBOOT_CFG_CORTEXA=am65x_evm_a53_defconfig + $ export TFA_BOARD=generic + $ # we dont use any extra TFA parameters + $ unset TFA_EXTRA_ARGS + $ export OPTEE_PLATFORM=k3-am65x + $ # we dont use any extra OP-TEE parameters + $ unset OPTEE_EXTRA_ARGS -3. U-Boot: +.. am65x_evm_rst_include_start_build_steps -* 4.1 R5: +1. Trusted Firmware-A: -.. code-block:: bash +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_tfa + :end-before: .. k3_rst_include_end_build_steps_tfa - $ make am65x_evm_r5_defconfig - $ make CROSS_COMPILE=arm-linux-gnueabihf- \ - BINMAN_INDIRS= -* 4.2 A53: +2. OP-TEE: -.. code-block:: bash +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_optee + :end-before: .. k3_rst_include_end_build_steps_optee - $ make am65x_evm_a53_defconfig - $ make CROSS_COMPILE=aarch64-linux-gnu- \ - BL31=/build/k3/generic/release/bl31.bin \ - TEE=/out/arm-plat-k3/core/tee-raw.bin \ - BINMAN_INDIRS= +3. U-Boot: + +* 4.1 R5: + +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_spl_r5 + :end-before: .. k3_rst_include_end_build_steps_spl_r5 + +* 4.2 A72: + +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_uboot + :end-before: .. k3_rst_include_end_build_steps_uboot +.. am65x_evm_rst_include_end_build_steps Target Images -------------- diff --git a/doc/board/ti/j7200_evm.rst b/doc/board/ti/j7200_evm.rst index fea01b55e2a1..998748ea53ec 100644 --- a/doc/board/ti/j7200_evm.rst +++ b/doc/board/ti/j7200_evm.rst @@ -44,37 +44,61 @@ Sources: Build procedure: ---------------- -1. Trusted Firmware-A: +0. Setup the environment variables: -.. code-block:: bash +.. include:: k3.rst + :start-after: .. k3_rst_include_start_common_env_vars_desc + :end-before: .. k3_rst_include_end_common_env_vars_desc - $ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=aarch64 PLAT=k3 TARGET_BOARD=generic SPD=opteed +.. include:: k3.rst + :start-after: .. k3_rst_include_start_board_env_vars_desc + :end-before: .. k3_rst_include_end_board_env_vars_desc -2. OP-TEE: +Set the variables corresponding to this platform: +.. include:: k3.rst + :start-after: .. k3_rst_include_start_common_env_vars_defn + :end-before: .. k3_rst_include_end_common_env_vars_defn .. code-block:: bash - $ make PLATFORM=k3-j7200 CFG_ARM64_core=y + $ export UBOOT_CFG_CORTEXR=j7200_evm_r5_defconfig + $ export UBOOT_CFG_CORTEXA=j7200_evm_a72_defconfig + $ export TFA_BOARD=generic + $ # we dont use any extra TFA parameters + $ unset TFA_EXTRA_ARGS + $ export OPTEE_PLATFORM=k3-j7200 + $ # we dont use any extra OP-TEE parameters + $ unset OPTEE_EXTRA_ARGS + +.. j7200_evm_rst_include_start_build_steps + +1. Trusted Firmware-A: + +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_tfa + :end-before: .. k3_rst_include_end_build_steps_tfa + + +2. OP-TEE: + +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_optee + :end-before: .. k3_rst_include_end_build_steps_optee 3. U-Boot: * 4.1 R5: -.. code-block:: bash - - $ make CROSS_COMPILE=arm-linux-gnueabihf- j7200_evm_r5_defconfig O=build/r5 - $ make CROSS_COMPILE=arm-linux-gnueabihf- \ - BINMAN_INDIRS= +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_spl_r5 + :end-before: .. k3_rst_include_end_build_steps_spl_r5 * 4.2 A72: -.. code-block:: bash - - $ make CROSS_COMPILE=aarch64-linux-gnu- j7200_evm_a72_defconfig O=build/a72 - $ make CROSS_COMPILE=aarch64-linux-gnu- \ - BL31=/build/k3/generic/release/bl31.bin \ - TEE=/out/arm-plat-k3/core/tee-raw.bin \ - BINMAN_INDIRS= +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_uboot + :end-before: .. k3_rst_include_end_build_steps_uboot +.. j7200_evm_rst_include_end_build_steps Target Images -------------- diff --git a/doc/board/ti/j721e_evm.rst b/doc/board/ti/j721e_evm.rst index 2659c5ea0dd2..45d80fc6ef44 100644 --- a/doc/board/ti/j721e_evm.rst +++ b/doc/board/ti/j721e_evm.rst @@ -48,38 +48,61 @@ Sources: Build procedure: ---------------- -1. Trusted Firmware-A: +0. Setup the environment variables: -.. code-block:: bash +.. include:: k3.rst + :start-after: .. k3_rst_include_start_common_env_vars_desc + :end-before: .. k3_rst_include_end_common_env_vars_desc - $ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=aarch64 PLAT=k3 \ - TARGET_BOARD=generic SPD=opteed +.. include:: k3.rst + :start-after: .. k3_rst_include_start_board_env_vars_desc + :end-before: .. k3_rst_include_end_board_env_vars_desc -2. OP-TEE: +Set the variables corresponding to this platform: +.. include:: k3.rst + :start-after: .. k3_rst_include_start_common_env_vars_defn + :end-before: .. k3_rst_include_end_common_env_vars_defn .. code-block:: bash - $ make PLATFORM=k3-j721e CFG_ARM64_core=y + $ export UBOOT_CFG_CORTEXR=j721e_evm_r5_defconfig + $ export UBOOT_CFG_CORTEXA=j721e_evm_a72_defconfig + $ export TFA_BOARD=generic + $ # we dont use any extra TFA parameters + $ unset TFA_EXTRA_ARGS + $ export OPTEE_PLATFORM=k3-j721e + $ # we dont use any extra OP-TEE parameters + $ unset OPTEE_EXTRA_ARGS + +.. j721e_evm_rst_include_start_build_steps + +1. Trusted Firmware-A: + +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_tfa + :end-before: .. k3_rst_include_end_build_steps_tfa + + +2. OP-TEE: + +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_optee + :end-before: .. k3_rst_include_end_build_steps_optee 3. U-Boot: * 4.1 R5: -.. code-block:: bash - - $ make j721e_evm_r5_defconfig - $ make CROSS_COMPILE=arm-linux-gnueabihf- \ - BINMAN_INDIRS= +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_spl_r5 + :end-before: .. k3_rst_include_end_build_steps_spl_r5 * 4.2 A72: -.. code-block:: bash - - $ make j721e_evm_a72_defconfig - $ make CROSS_COMPILE=aarch64-linux-gnu- \ - BL31=/build/k3/generic/release/bl31.bin \ - TEE=/out/arm-plat-k3/core/tee-raw.bin \ - BINMAN_INDIRS= +.. include:: k3.rst + :start-after: .. k3_rst_include_start_build_steps_uboot + :end-before: .. k3_rst_include_end_build_steps_uboot +.. j721e_evm_rst_include_end_build_steps Target Images -------------- diff --git a/doc/board/ti/k3.rst b/doc/board/ti/k3.rst index 2df57c9850ae..6bc6caf2340c 100644 --- a/doc/board/ti/k3.rst +++ b/doc/board/ti/k3.rst @@ -154,10 +154,71 @@ compiled for 64bit main domain CPU cores. All of that to say you will need both a 32bit and 64bit cross compiler (assuming you're using an x86 desktop) +.. k3_rst_include_start_common_env_vars_desc +.. list-table:: Generic environment variables + :widths: 25 25 50 + :header-rows: 1 + + * - S/w Component + - Env Variable + - Description + * - All Software + - CC32 + - Cross compiler for ARMv7 (ARM 32bit), Typically arm-linux-gnueabihf- + * - All Software + - CC64 + - Cross compiler for ARMv8 (ARM 64bit), Typically aarch64-linux-gnu- + * - All Software + - LNX_FW_PATH + - Path to TI Linux firmware repository + * - All Software + - TFA_PATH + - Path to source of Trusted Firmware-A + * - All Software + - OPTEE_PATH + - Path to source of OP-TEE +.. k3_rst_include_end_common_env_vars_desc + +.. k3_rst_include_start_common_env_vars_defn .. code-block:: bash $ export CC32=arm-linux-gnueabihf- $ export CC64=aarch64-linux-gnu- + $ export LNX_FW_PATH=path/to/ti-linux-firmware + $ export TFA_PATH=path/to/trusted-firmware-a + $ export OPTEE_PATH=path/to/optee_os +.. k3_rst_include_end_common_env_vars_defn + +We will also need some common environment variables set up for the various +other build sources. we shall use the following, in the build descriptions below: + +.. k3_rst_include_start_board_env_vars_desc +.. list-table:: Board specific environment variables + :widths: 25 25 50 + :header-rows: 1 + + * - S/w Component + - Env Variable + - Description + * - U-Boot + - UBOOT_CFG_CORTEXR + - Defconfig for Cortex-R (Boot processor). + * - U-Boot + - UBOOT_CFG_CORTEXA + - Defconfig for Cortex-A (MPU processor). + * - Trusted Firmware-A + - TFA_BOARD + - Platform name used for building TF-A for Cortex-A Processor. + * - Trusted Firmware-A + - TFA_EXTRA_ARGS + - Any extra arguments used for building TF-A. + * - OP-TEE + - OPTEE_PLATFORM + - Platform name used for building OP-TEE for Cortex-A Processor. + * - OP-TEE + - OPTEE_EXTRA_ARGS + - Any extra arguments used for building OP-TEE. +.. k3_rst_include_end_board_env_vars_desc Building tiboot3.bin ^^^^^^^^^^^^^^^^^^^^^ @@ -168,13 +229,13 @@ Building tiboot3.bin the final `tiboot3.bin` binary. (or the `sysfw.itb` if your device uses the split binary flow) - +.. k3_rst_include_start_build_steps_spl_r5 .. code-block:: bash $ # inside u-boot source - $ make ARCH=arm {SOC}_evm_r5_defconfig - $ make ARCH=arm CROSS_COMPILE=$CC32 \ - BINMAN_INDIRS= + $ make ARCH=arm $UBOOT_CFG_CORTEXR + $ make ARCH=arm CROSS_COMPILE=$CC32 BINMAN_INDIRS=$LNX_FW_PATH +.. k3_rst_include_end_build_steps_spl_r5 At this point you should have all the needed binaries to boot the wakeup domain of your K3 SoC. @@ -204,39 +265,44 @@ firmware if your device using a split firmware. 2. We will first need TF-A, as it's the first thing to run on the 'big' application cores on the main domain. +.. k3_rst_include_start_build_steps_tfa .. code-block:: bash $ # inside trusted-firmware-a source - $ make CROSS_COMPILE=$CC64 ARCH=aarch64 PLAT=k3 \ - TARGET_BOARD={lite|generic|j784s4} \ - SPD=opteed + $ make CROSS_COMPILE=$CC64 ARCH=aarch64 PLAT=k3 SPD=opteed $TFA_EXTRA_ARGS\ + TARGET_BOARD=$TFA_BOARD +.. k3_rst_include_end_build_steps_tfa Typically all `j7*` devices will use `TARGET_BOARD=generic` or `TARGET_BOARD -=j784s4` (if it is a J784S4 device), while all Sitara (`am6*`) devices +=j784s4` (if it is a J784S4 device), while typical Sitara (`am6*`) devices use the `lite` option. 3. The Open Portable Trusted Execution Environment (OP-TEE) is designed to run as a companion to a non-secure Linux kernel for Cortex-A cores using the TrustZone technology built into the core. +.. k3_rst_include_start_build_steps_optee .. code-block:: bash $ # inside optee_os source - $ make CROSS_COMPILE=$CC32 CROSS_COMPILE64=$CC64 \ - PLATFORM=k3 CFG_ARM64_core=y + $ make CROSS_COMPILE=$CC32 CROSS_COMPILE64=$CC64 CFG_ARM64_core=y $OPTEE_EXTRA_ARGS\ + PLATFORM=$OPTEE_PLATFORM +.. k3_rst_include_end_build_steps_optee 4. Finally, after TF-A has initialized the main domain and OP-TEE has finished, we can jump back into U-Boot again, this time running on a 64bit core in the main domain. +.. k3_rst_include_start_build_steps_uboot .. code-block:: bash $ # inside u-boot source - $ make ARCH=arm {SOC}_evm_a{53,72}_defconfig + $ make ARCH=arm $UBOOT_CFG_CORTEXA $ make ARCH=arm CROSS_COMPILE=$CC64 \ - BINMAN_INDIRS= \ - BL31=/build/k3/generic/release/bl31.bin \ - TEE=/out/arm-plat-k3/core/tee-raw.bin + BINMAN_INDIRS=$LNX_FW_PATH \ + BL31=$TFA_PATH/build/k3/$TFA_BOARD/release/bl31.bin \ + TEE=$OPTEE_PATH/out/arm-plat-k3/core/tee-raw.bin +.. k3_rst_include_end_build_steps_uboot At this point you should have every binary needed initialize both the wakeup and main domain and to boot to the U-Boot prompt -- 2.40.0