From 035c9119b2f40db991e29ab69ce4842a907cb91c Mon Sep 17 00:00:00 2001 From: Bjorn Engstrom Date: Fri, 26 Aug 2022 09:45:45 +0200 Subject: [PATCH 01/25] build(ethos-n): add TZMP1 build flag For the Arm(R) Ethos(TM)-N NPU Driver to support running inference with protected memory the TZC must be configured with appropriate regions. This is controlled in build time by the now added build flag. The new build flag is only supported with the Arm Juno platform and the TZC is configured with default memory regions as if TZMP1 wasn't enabled to facilitate adding the new memory regions later. Signed-off-by: Bjorn Engstrom Signed-off-by: Rob Hughes Signed-off-by: Mikael Olsson Change-Id: I9dc49ac5d091cfbc8c20d7c3ab394a2836438b0f --- docs/plat/arm/arm-build-options.rst | 5 ++++- plat/arm/board/juno/juno_security.c | 17 ++++++++++++++++- plat/arm/board/juno/platform.mk | 8 ++++++-- plat/arm/common/arm_common.mk | 15 +++++++++++++++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst index 68eb3ecd6..dda2aa0a9 100644 --- a/docs/plat/arm/arm-build-options.rst +++ b/docs/plat/arm/arm-build-options.rst @@ -101,6 +101,9 @@ Arm Platform Build Options the Arm Juno platform has this included in its ``HW_CONFIG`` and the platform only loads the ``HW_CONFIG`` in AArch64 builds. Default is 0. +- ``ARM_ETHOSN_NPU_TZMP1``: boolean option to enable TZMP1 support for the + Arm® Ethos™-N NPU. Requires ``ARM_ETHOSN_NPU_DRIVER`` to be enabled. + - ``ARM_SPMC_MANIFEST_DTS`` : path to an alternate manifest file used as the SPMC Core manifest. Valid when ``SPD=spmd`` is selected. @@ -165,4 +168,4 @@ Arm CSS Platform-Specific Build Options .. |FIP in a GPT image| image:: ../../resources/diagrams/FIP_in_a_GPT_image.png -*Copyright (c) 2019-2021, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2023, Arm Limited. All rights reserved.* diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c index 654a7f165..a0fd36ce7 100644 --- a/plat/arm/board/juno/juno_security.c +++ b/plat/arm/board/juno/juno_security.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -78,6 +78,18 @@ static void init_v550(void) #endif /* JUNO_TZMP1 */ +#ifdef JUNO_ETHOSN_TZMP1 +/* + * Currently use the default regions defined in ARM_TZC_REGIONS_DEF. + * See the definition in /include/plat/arm/common/plat_arm.h + */ +static const arm_tzc_regions_info_t juno_ethosn_tzmp1_tzc_regions[] = { + ARM_TZC_REGIONS_DEF, /* See define in /include/plat/arm/common/plat_arm.h */ + {}, +}; + +#endif /* JUNO_ETHOSN_TZMP1 */ + /******************************************************************************* * Set up the MMU-401 SSD tables. The power-on configuration has all stream IDs * assigned to Non-Secure except some for the DMA-330. Assign those back to the @@ -140,6 +152,9 @@ void plat_arm_security_setup(void) (void *)JUNO_AP_TZC_SHARE_DRAM1_BASE); INFO("TZC protected shared memory end address for TZMP usecase: %p\n", (void *)JUNO_AP_TZC_SHARE_DRAM1_END); +#elif defined(JUNO_ETHOSN_TZMP1) + arm_tzc400_setup(PLAT_ARM_TZC_BASE, juno_ethosn_tzmp1_tzc_regions); + INFO("TZC set up with default settings for NPU TZMP usecase\n"); #else arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL); #endif diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index 2c84eb34d..d99b16c82 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -43,7 +43,11 @@ $(eval $(call add_define,JUNO_AARCH32_EL3_RUNTIME)) JUNO_TZMP1 := 0 $(eval $(call assert_boolean,JUNO_TZMP1)) ifeq (${JUNO_TZMP1}, 1) -$(eval $(call add_define,JUNO_TZMP1)) + ifeq (${ARM_ETHOSN_NPU_TZMP1},1) + $(error JUNO_TZMP1 cannot be used together with ARM_ETHOSN_NPU_TZMP1) + else + $(eval $(call add_define,JUNO_TZMP1)) + endif endif TRNG_SUPPORT := 1 diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index de2c4f830..dc875e526 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -119,6 +119,21 @@ ARM_ETHOSN_NPU_DRIVER := 0 $(eval $(call assert_boolean,ARM_ETHOSN_NPU_DRIVER)) $(eval $(call add_define,ARM_ETHOSN_NPU_DRIVER)) +# Arm(R) Ethos(TM)-N NPU TZMP1 +ARM_ETHOSN_NPU_TZMP1 := 0 +$(eval $(call assert_boolean,ARM_ETHOSN_NPU_TZMP1)) +$(eval $(call add_define,ARM_ETHOSN_NPU_TZMP1)) +ifeq (${ARM_ETHOSN_NPU_TZMP1},1) + ifeq (${ARM_ETHOSN_NPU_DRIVER},0) + $(error ARM_ETHOSN_NPU_TZMP1 is only available if ARM_ETHOSN_NPU_DRIVER=1) + endif + ifeq (${PLAT},juno) + $(eval $(call add_define,JUNO_ETHOSN_TZMP1)) + else + $(error ARM_ETHOSN_NPU_TZMP1 only supported on Juno platform, not ${PLAT}) + endif +endif + # Use an implementation of SHA-256 with a smaller memory footprint but reduced # speed. $(eval $(call add_define,MBEDTLS_SHA256_SMALLER)) From d77c11e896e04be93caa4a56e50646af6806843f Mon Sep 17 00:00:00 2001 From: Bjorn Engstrom Date: Mon, 19 Sep 2022 08:34:03 +0200 Subject: [PATCH 02/25] feat(ethos-n): add protected NPU TZMP1 regions TZMP1 protected memory regions have been added in the Juno platform to store sensitive data for the Arm(R) Ethos(TM)-N NPU This is enabled when building TF-A with ARM_ETHOSN_NPU_TZMP1. The NPU uses two protected memory regions: 1) Firmware region to protect the NPU's firmware from being modified from the non-secure world 2) Data region for sensitive data used by the NPU Respective memory region can only be accessed with their unique NSAID. Signed-off-by: Bjorn Engstrom Signed-off-by: Mikael Olsson Signed-off-by: Rob Hughes Change-Id: I65200047f10364ca18681ce348a6edb2ffb9b095 --- plat/arm/board/juno/juno_ethosn_tzmp1_def.h | 51 +++++++++++++++++++++ plat/arm/board/juno/juno_security.c | 18 +++++--- 2 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 plat/arm/board/juno/juno_ethosn_tzmp1_def.h diff --git a/plat/arm/board/juno/juno_ethosn_tzmp1_def.h b/plat/arm/board/juno/juno_ethosn_tzmp1_def.h new file mode 100644 index 000000000..131adcd7c --- /dev/null +++ b/plat/arm/board/juno/juno_ethosn_tzmp1_def.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef JUNO_ETHOSN_TZMP1_DEF_H +#define JUNO_ETHOSN_TZMP1_DEF_H + +#define JUNO_ETHOSN_TZC400_NSAID_FW_PROT 7 +#define JUNO_ETHOSN_TZC400_NSAID_DATA_PROT 8 + +#define JUNO_ETHOSN_FW_TZC_PROT_DRAM2_SIZE UL(0x000400000) /* 4 MB */ +#define JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE (ARM_DRAM2_BASE) +#define JUNO_ETHOSN_FW_TZC_PROT_DRAM2_END (ARM_DRAM2_BASE + \ + JUNO_ETHOSN_FW_TZC_PROT_DRAM2_SIZE \ + - 1U) + +#define JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_SIZE UL(0x004000000) /* 64 MB */ +#define JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_BASE ( \ + JUNO_ETHOSN_FW_TZC_PROT_DRAM2_END + 1) +#define JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_END ( \ + JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_BASE + \ + JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_SIZE - 1U) + +#define JUNO_ETHOSN_NS_DRAM2_BASE (JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_END + \ + 1) +#define JUNO_ETHOSN_NS_DRAM2_END (ARM_DRAM2_END) +#define JUNO_ETHOSN_NS_DRAM2_SIZE (ARM_DRAM2_SIZE - \ + JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_END) + +#define JUNO_FW_TZC_PROT_ACCESS \ + (TZC_REGION_ACCESS_RDWR(JUNO_ETHOSN_TZC400_NSAID_FW_PROT)) +#define JUNO_DATA_TZC_PROT_ACCESS \ + (TZC_REGION_ACCESS_RDWR(JUNO_ETHOSN_TZC400_NSAID_DATA_PROT)) + +#define JUNO_ETHOSN_TZMP_REGIONS_DEF \ + { ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END + ARM_L1_GPT_SIZE, \ + TZC_REGION_S_RDWR, 0 }, \ + { ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, \ + ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS }, \ + { JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE, \ + JUNO_ETHOSN_FW_TZC_PROT_DRAM2_END, \ + TZC_REGION_S_RDWR, JUNO_FW_TZC_PROT_ACCESS }, \ + { JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_BASE, \ + JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_END, \ + TZC_REGION_S_NONE, JUNO_DATA_TZC_PROT_ACCESS }, \ + { JUNO_ETHOSN_NS_DRAM2_BASE, JUNO_ETHOSN_NS_DRAM2_END, \ + ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS } + +#endif /* JUNO_ETHOSN_TZMP1_DEF_H */ diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c index a0fd36ce7..72e7e7837 100644 --- a/plat/arm/board/juno/juno_security.c +++ b/plat/arm/board/juno/juno_security.c @@ -13,6 +13,7 @@ #include #include +#include "juno_ethosn_tzmp1_def.h" #include "juno_tzmp1_def.h" #ifdef JUNO_TZMP1 @@ -79,12 +80,9 @@ static void init_v550(void) #endif /* JUNO_TZMP1 */ #ifdef JUNO_ETHOSN_TZMP1 -/* - * Currently use the default regions defined in ARM_TZC_REGIONS_DEF. - * See the definition in /include/plat/arm/common/plat_arm.h - */ + static const arm_tzc_regions_info_t juno_ethosn_tzmp1_tzc_regions[] = { - ARM_TZC_REGIONS_DEF, /* See define in /include/plat/arm/common/plat_arm.h */ + JUNO_ETHOSN_TZMP_REGIONS_DEF, {}, }; @@ -154,7 +152,15 @@ void plat_arm_security_setup(void) (void *)JUNO_AP_TZC_SHARE_DRAM1_END); #elif defined(JUNO_ETHOSN_TZMP1) arm_tzc400_setup(PLAT_ARM_TZC_BASE, juno_ethosn_tzmp1_tzc_regions); - INFO("TZC set up with default settings for NPU TZMP usecase\n"); + INFO("TZC protected shared memory range for NPU TZMP usecase: %p - %p\n", + (void *)JUNO_ETHOSN_NS_DRAM2_BASE, + (void *)JUNO_ETHOSN_NS_DRAM2_END); + INFO("TZC protected Data memory range for NPU TZMP usecase: %p - %p\n", + (void *)JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_BASE, + (void *)JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_END); + INFO("TZC protected FW memory range for NPU TZMP usecase: %p - %p\n", + (void *)JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE, + (void *)JUNO_ETHOSN_FW_TZC_PROT_DRAM2_END); #else arm_tzc400_setup(PLAT_ARM_TZC_BASE, NULL); #endif From fa37d30856fef6742bd82e4e0a3252a4d0b9e091 Mon Sep 17 00:00:00 2001 From: Joshua Pimm Date: Wed, 19 Oct 2022 15:46:27 +0100 Subject: [PATCH 03/25] feat(ethos-n): add reset type to reset SMC calls Adds a reset type argument for the soft and hard reset SMC calls to indicate whether to perform a full reset and setup or only halt the Arm(R) Ethos(TM)-N NPU. For use in cases where the NPU will not be used but must be put into a known state, such as suspending the NPU as part of power management. Signed-off-by: Joshua Pimm Signed-off-by: Mikael Olsson Change-Id: I6018af85a28b0e977166ec29d26f04739123140c --- drivers/arm/ethosn/ethosn_smc.c | 28 +++++++++++++++++++--------- include/drivers/arm/ethosn.h | 15 +++++++++++---- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c index 915a0d87a..c95c22ce5 100644 --- a/drivers/arm/ethosn/ethosn_smc.c +++ b/drivers/arm/ethosn/ethosn_smc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, Arm Limited. All rights reserved. + * Copyright (c) 2021-2023, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -152,7 +152,7 @@ static bool ethosn_reset(uintptr_t core_addr, int hard_reset) uintptr_t ethosn_smc_handler(uint32_t smc_fid, u_register_t core_addr, u_register_t asset_alloc_idx, - u_register_t x3, + u_register_t reset_type, u_register_t x4, void *cookie, void *handle, @@ -173,7 +173,7 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, if (GET_SMC_CC(smc_fid) == SMC_32) { core_addr &= 0xFFFFFFFF; asset_alloc_idx &= 0xFFFFFFFF; - x3 &= 0xFFFFFFFF; + reset_type &= 0xFFFFFFFF; x4 &= 0xFFFFFFFF; } @@ -205,7 +205,15 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, SMC_RET1(handle, ETHOSN_UNKNOWN_ALLOCATOR_IDX); } - /* Commands that require a valid device, core and asset allocator */ + if (reset_type > ETHOSN_RESET_TYPE_HALT) { + WARN("ETHOSN: Invalid reset type given to SMC call.\n"); + SMC_RET1(handle, ETHOSN_INVALID_PARAMETER); + } + + /* + * Commands that require a valid device, reset type, + * core and asset allocator + */ switch (fid) { case ETHOSN_FNUM_HARD_RESET: hard_reset = 1; @@ -215,12 +223,14 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, SMC_RET1(handle, ETHOSN_FAILURE); } - if (!device->has_reserved_memory) { - ethosn_configure_smmu_streams(device, core, - asset_alloc_idx); - } + if (reset_type == ETHOSN_RESET_TYPE_FULL) { + if (!device->has_reserved_memory) { + ethosn_configure_smmu_streams(device, core, + asset_alloc_idx); + } - ethosn_delegate_to_ns(core->addr); + ethosn_delegate_to_ns(core->addr); + } SMC_RET1(handle, ETHOSN_SUCCESS); default: WARN("ETHOSN: Unimplemented SMC call: 0x%x\n", fid); diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h index dbaf16cd7..ce7b2f30f 100644 --- a/include/drivers/arm/ethosn.h +++ b/include/drivers/arm/ethosn.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, Arm Limited. All rights reserved. + * Copyright (c) 2021-2023, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -39,21 +39,28 @@ /* Service version */ #define ETHOSN_VERSION_MAJOR U(2) -#define ETHOSN_VERSION_MINOR U(0) +#define ETHOSN_VERSION_MINOR U(1) /* Return codes for function calls */ #define ETHOSN_SUCCESS 0 #define ETHOSN_NOT_SUPPORTED -1 /* -2 Reserved for NOT_REQUIRED */ -/* -3 Reserved for INVALID_PARAMETER */ +#define ETHOSN_INVALID_PARAMETER -3 #define ETHOSN_FAILURE -4 #define ETHOSN_UNKNOWN_CORE_ADDRESS -5 #define ETHOSN_UNKNOWN_ALLOCATOR_IDX -6 +/* + * Argument types for soft and hard resets to indicate whether to reset + * and reconfigure the NPU or only halt it + */ +#define ETHOSN_RESET_TYPE_FULL U(0) +#define ETHOSN_RESET_TYPE_HALT U(1) + uintptr_t ethosn_smc_handler(uint32_t smc_fid, u_register_t core_addr, u_register_t asset_alloc_idx, - u_register_t x3, + u_register_t reset_type, u_register_t x4, void *cookie, void *handle, From 8a921e354575cd16aaa6f2f5a2aeaaaea35ab886 Mon Sep 17 00:00:00 2001 From: Joshua Pimm Date: Wed, 9 Nov 2022 11:26:11 +0000 Subject: [PATCH 04/25] feat(ethos-n): add multiple asset allocators Adds additional asset allocators to the device tree include file as the non-secure world kernel module for the Arm(R) Ethos(TM)-N NPU now fully supports having and using multiple asset allocators. Signed-off-by: Joshua Pimm Signed-off-by: Mikael Olsson Change-Id: I82d53667ef64968ee814f611d0a90abd3b3cf3de --- fdts/juno-ethosn.dtsi | 237 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 231 insertions(+), 6 deletions(-) diff --git a/fdts/juno-ethosn.dtsi b/fdts/juno-ethosn.dtsi index 460952482..6f8e8ae0a 100644 --- a/fdts/juno-ethosn.dtsi +++ b/fdts/juno-ethosn.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, Arm Limited. All rights reserved. + * Copyright (c) 2021-2023, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -48,28 +48,253 @@ }; }; - asset_allocator { + asset_allocator0 { compatible = "ethosn-asset_allocator"; status = "okay"; command_stream { compatible = "ethosn-memory"; - iommus = <&smmu_ethosn0 2>; + iommus = <&smmu_ethosn0 4>; }; weight_data { compatible = "ethosn-memory"; - iommus = <&smmu_ethosn0 3>; + iommus = <&smmu_ethosn0 5>; }; buffer_data { compatible = "ethosn-memory"; - iommus = <&smmu_ethosn0 4>; + iommus = <&smmu_ethosn0 6>; }; intermediate_data { compatible = "ethosn-memory"; - iommus = <&smmu_ethosn0 5>; + iommus = <&smmu_ethosn0 7>; + }; + }; + + asset_allocator1 { + compatible = "ethosn-asset_allocator"; + status = "okay"; + + command_stream { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 8>; + }; + + weight_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 9>; + }; + + buffer_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 10>; + }; + + intermediate_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 11>; + }; + }; + + asset_allocator2 { + compatible = "ethosn-asset_allocator"; + status = "okay"; + + command_stream { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 12>; + }; + + weight_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 13>; + }; + + buffer_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 14>; + }; + + intermediate_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 15>; + }; + }; + + asset_allocator3 { + compatible = "ethosn-asset_allocator"; + status = "okay"; + + command_stream { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 16>; + }; + + weight_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 17>; + }; + + buffer_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 18>; + }; + + intermediate_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 19>; + }; + }; + + asset_allocator4 { + compatible = "ethosn-asset_allocator"; + status = "okay"; + + command_stream { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 20>; + }; + + weight_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 21>; + }; + + buffer_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 22>; + }; + + intermediate_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 23>; + }; + }; + + asset_allocator5 { + compatible = "ethosn-asset_allocator"; + status = "okay"; + + command_stream { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 24>; + }; + + weight_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 25>; + }; + + buffer_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 26>; + }; + + intermediate_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 27>; + }; + }; + + asset_allocator6 { + compatible = "ethosn-asset_allocator"; + status = "okay"; + + command_stream { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 28>; + }; + + weight_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 29>; + }; + + buffer_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 30>; + }; + + intermediate_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 31>; + }; + }; + + asset_allocator7 { + compatible = "ethosn-asset_allocator"; + status = "okay"; + + command_stream { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 32>; + }; + + weight_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 33>; + }; + + buffer_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 34>; + }; + + intermediate_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 35>; + }; + }; + + asset_allocator8 { + compatible = "ethosn-asset_allocator"; + status = "okay"; + + command_stream { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 36>; + }; + + weight_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 37>; + }; + + buffer_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 38>; + }; + + intermediate_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 39>; + }; + }; + + asset_allocator9 { + compatible = "ethosn-asset_allocator"; + status = "okay"; + + command_stream { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 40>; + }; + + weight_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 41>; + }; + + buffer_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 42>; + }; + + intermediate_data { + compatible = "ethosn-memory"; + iommus = <&smmu_ethosn0 43>; }; }; }; From 2a2e3e87706b56fd1b8e787d3a552cfc12725934 Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Fri, 4 Nov 2022 15:01:02 +0100 Subject: [PATCH 05/25] feat(ethos-n): add NPU sleeping SMC call The non-secure world delegation of the register needed to determine if the Arm(R) Ethos(TM)-N NPU is active or sleeping will be removed in the future. In preparation for the change, a new SMC call has been added to allow the non-secure world to ask the SiP service for the state instead. A minor API version bump has been done with this change to indicate support for the new functionality. Signed-off-by: Mikael Olsson Change-Id: I1338341be385cf1891f4809efb7083fae6d928bc --- drivers/arm/ethosn/ethosn_smc.c | 15 +++++++++++++-- include/drivers/arm/ethosn.h | 5 +++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c index c95c22ce5..86459585e 100644 --- a/drivers/arm/ethosn/ethosn_smc.c +++ b/drivers/arm/ethosn/ethosn_smc.c @@ -43,6 +43,7 @@ #define SEC_DEL_ADDR_EXT_VAL U(0x15) #define SEC_SYSCTRL0_REG U(0x0018) +#define SEC_SYSCTRL0_SLEEPING U(1U << 4) #define SEC_SYSCTRL0_SOFT_RESET U(3U << 29) #define SEC_SYSCTRL0_HARD_RESET U(1U << 31) @@ -125,6 +126,15 @@ static int ethosn_is_sec(uintptr_t core_addr) return 1; } +static int ethosn_core_is_sleeping(uintptr_t core_addr) +{ + const uintptr_t sysctrl0_reg = + ETHOSN_CORE_SEC_REG(core_addr, SEC_SYSCTRL0_REG); + const uint32_t sleeping_mask = SEC_SYSCTRL0_SLEEPING; + + return ((mmio_read_32(sysctrl0_reg) & sleeping_mask) == sleeping_mask); +} + static bool ethosn_reset(uintptr_t core_addr, int hard_reset) { unsigned int timeout; @@ -177,8 +187,7 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, x4 &= 0xFFFFFFFF; } - if (!is_ethosn_fid(smc_fid) || - (fid < ETHOSN_FNUM_VERSION || fid > ETHOSN_FNUM_SOFT_RESET)) { + if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_IS_SLEEPING)) { WARN("ETHOSN: Unknown SMC call: 0x%x\n", smc_fid); SMC_RET1(handle, SMC_UNK); } @@ -197,6 +206,8 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, switch (fid) { case ETHOSN_FNUM_IS_SEC: SMC_RET1(handle, ethosn_is_sec(core->addr)); + case ETHOSN_FNUM_IS_SLEEPING: + SMC_RET1(handle, ethosn_core_is_sleeping(core->addr)); } if (!device->has_reserved_memory && diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h index ce7b2f30f..95244c71f 100644 --- a/include/drivers/arm/ethosn.h +++ b/include/drivers/arm/ethosn.h @@ -14,7 +14,8 @@ #define ETHOSN_FNUM_IS_SEC U(0x51) #define ETHOSN_FNUM_HARD_RESET U(0x52) #define ETHOSN_FNUM_SOFT_RESET U(0x53) -/* 0x54-0x5F reserved for future use */ +#define ETHOSN_FNUM_IS_SLEEPING U(0x54) +/* 0x55-0x5F reserved for future use */ /* SMC64 function IDs */ #define ETHOSN_FID_64(func_num) U(0xC2000000 | func_num) @@ -39,7 +40,7 @@ /* Service version */ #define ETHOSN_VERSION_MAJOR U(2) -#define ETHOSN_VERSION_MINOR U(1) +#define ETHOSN_VERSION_MINOR U(2) /* Return codes for function calls */ #define ETHOSN_SUCCESS 0 From 0165ddd7c06fe2d0556865fce89ced8694e3812e Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Thu, 8 Dec 2022 17:07:06 +0100 Subject: [PATCH 06/25] build(fiptool): add object dependency generation The object target in the fiptool Makefile only depends on the corresponding source file so it won't rebuild the object, if a header file used by the source file is changed. To make it rebuild the object file for both source and header file changes, a dependency file will now be generated for each object and included in the Makefile. Signed-off-by: Mikael Olsson Change-Id: I0468c6e9c54126242150667268d471f28e011b0d --- tools/fiptool/Makefile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile index d7e0fe5be..ac262cdff 100644 --- a/tools/fiptool/Makefile +++ b/tools/fiptool/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2014-2022, Arm Limited and Contributors. All rights reserved. +# Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -61,6 +61,8 @@ ifneq (,$(wildcard ${PLAT_FIPTOOL_HELPER_MK})) include ${PLAT_FIPTOOL_HELPER_MK} endif +DEPS := $(patsubst %.o,%.d,$(OBJECTS)) + .PHONY: all clean distclean --openssl all: ${PROJECT} @@ -74,7 +76,9 @@ ${PROJECT}: --openssl ${OBJECTS} Makefile %.o: %.c Makefile @echo " HOSTCC $<" - ${Q}${HOSTCC} -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@ + ${Q}${HOSTCC} -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} -MD -MP $< -o $@ + +-include $(DEPS) --openssl: ifeq ($(DEBUG),1) @@ -83,4 +87,4 @@ endif clean: - $(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS}) + $(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS} $(DEPS)) From 70a296ee8641802dc60754aec5b18d8347820a5c Mon Sep 17 00:00:00 2001 From: Rajasekaran Kalidoss Date: Wed, 16 Nov 2022 17:16:44 +0100 Subject: [PATCH 07/25] feat(ethos-n): add support to set up NSAID For the TZC to allow the Arm(R) Ethos(TM)-N NPU to access the buffers allocated in a protected memory region, it must include the correct NSAID for that region in its transactions to the memory. This change updates the SiP service to configure the NSAIDs specified by a platform define. When doing a protected access the SiP service now configures the NSAIDs specified by the platform define. For unprotected access the NSAID is set to zero. Signed-off-by: Rajasekaran Kalidoss Signed-off-by: Rob Hughes Signed-off-by: Mikael Olsson Change-Id: I3360ef33705162aba5c67670386922420869e331 --- docs/getting_started/porting-guide.rst | 13 +++++++ drivers/arm/ethosn/ethosn_smc.c | 41 ++++++++++++++++++++-- plat/arm/board/juno/include/platform_def.h | 11 +++++- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index 8d6a2bf23..b3092c790 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -574,6 +574,19 @@ optionally be defined: PLAT_PARTITION_BLOCK_SIZE := 4096 $(eval $(call add_define,PLAT_PARTITION_BLOCK_SIZE)) +If the platform port uses the Arm® Ethos™-N NPU driver with TZMP1 support +enabled, the following constants must also be defined. + +- **ARM_ETHOSN_NPU_PROT_FW_NSAID** + + Defines the Non-secure Access IDentity (NSAID) that the NPU shall use to + access the protected memory that contains the NPU's firmware. + +- **ARM_ETHOSN_NPU_PROT_DATA_NSAID** + + Defines the Non-secure Access IDentity (NSAID) that the NPU shall use to + access the protected memory that contains inference data. + The following constant is optional. It should be defined to override the default behaviour of the ``assert()`` function (for example, to save memory). diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c index 86459585e..7604b8b56 100644 --- a/drivers/arm/ethosn/ethosn_smc.c +++ b/drivers/arm/ethosn/ethosn_smc.c @@ -15,6 +15,8 @@ #include #include +#include + /* * Number of Arm(R) Ethos(TM)-N NPU (NPU) devices available */ @@ -47,9 +49,16 @@ #define SEC_SYSCTRL0_SOFT_RESET U(3U << 29) #define SEC_SYSCTRL0_HARD_RESET U(1U << 31) +#define SEC_NSAID_REG_BASE U(0x3004) +#define SEC_NSAID_OFFSET U(0x1000) + #define SEC_MMUSID_REG_BASE U(0x3008) #define SEC_MMUSID_OFFSET U(0x1000) +#define INPUT_STREAM_INDEX U(0x6) +#define INTERMEDIATE_STREAM_INDEX U(0x7) +#define OUTPUT_STREAM_INDEX U(0x8) + static bool ethosn_get_device_and_core(uintptr_t core_addr, const struct ethosn_device_t **dev_match, const struct ethosn_core_t **core_match) @@ -75,6 +84,29 @@ static bool ethosn_get_device_and_core(uintptr_t core_addr, return false; } +#if ARM_ETHOSN_NPU_TZMP1 +static void ethosn_configure_stream_nsaid(const struct ethosn_core_t *core, + bool is_protected) +{ + size_t i; + uint32_t streams[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + + if (is_protected) { + streams[INPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_DATA_NSAID; + streams[INTERMEDIATE_STREAM_INDEX] = + ARM_ETHOSN_NPU_PROT_DATA_NSAID; + streams[OUTPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_DATA_NSAID; + } + + for (i = 0U; i < ARRAY_SIZE(streams); ++i) { + const uintptr_t reg_addr = SEC_NSAID_REG_BASE + + (SEC_NSAID_OFFSET * i); + mmio_write_32(ETHOSN_CORE_SEC_REG(core->addr, reg_addr), + streams[i]); + } +} +#endif + static void ethosn_configure_smmu_streams(const struct ethosn_device_t *device, const struct ethosn_core_t *core, uint32_t asset_alloc_idx) @@ -163,7 +195,7 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, u_register_t core_addr, u_register_t asset_alloc_idx, u_register_t reset_type, - u_register_t x4, + u_register_t is_protected, void *cookie, void *handle, u_register_t flags) @@ -184,7 +216,7 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, core_addr &= 0xFFFFFFFF; asset_alloc_idx &= 0xFFFFFFFF; reset_type &= 0xFFFFFFFF; - x4 &= 0xFFFFFFFF; + is_protected &= 0xFFFFFFFF; } if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_IS_SLEEPING)) { @@ -238,6 +270,11 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, if (!device->has_reserved_memory) { ethosn_configure_smmu_streams(device, core, asset_alloc_idx); + + #if ARM_ETHOSN_NPU_TZMP1 + ethosn_configure_stream_nsaid(core, + is_protected); + #endif } ethosn_delegate_to_ns(core->addr); diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 409d7a60f..1ccaf5cf7 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,6 +19,9 @@ #include #include "../juno_def.h" +#ifdef JUNO_ETHOSN_TZMP1 +#include "../juno_ethosn_tzmp1_def.h" +#endif /* Required platform porting definitions */ /* Juno supports system power domain */ @@ -310,4 +313,10 @@ /* Number of SCMI channels on the platform */ #define PLAT_ARM_SCMI_CHANNEL_COUNT U(1) +/* Protected memory NSAIDs for the Arm(R) Ethos(TM)-N NPU driver */ +#ifdef JUNO_ETHOSN_TZMP1 +#define ARM_ETHOSN_NPU_PROT_FW_NSAID JUNO_ETHOSN_TZC400_NSAID_FW_PROT +#define ARM_ETHOSN_NPU_PROT_DATA_NSAID JUNO_ETHOSN_TZC400_NSAID_DATA_PROT +#endif + #endif /* PLATFORM_DEF_H */ From c91b08c8a44aafac4f72c64aa8d4777b8c73647e Mon Sep 17 00:00:00 2001 From: Daniele Castro Date: Thu, 24 Nov 2022 12:06:13 +0000 Subject: [PATCH 08/25] feat(ethos-n): add NPU support in fiptool Add platform specific Makefile to add UUIDs and command options for the Arm(R) Ethos(TM)-N NPU firmware binary and certificate data to the FIP so that the TF-A's BL2 can later be used to load the Arm(R) Ethos(TM)-N NPU firmware binary into memory and verify its integrity. Add separate driver specific include header file for the Arm(R) Ethos(TM)-N NPU images containing UUIDs and command options to make it easy to port the FIP support to other platforms. Signed-off-by: Daniele Castro Signed-off-by: Rob Hughes Signed-off-by: Mikael Olsson Change-Id: I8cd64fb20d58f8bd539facb085606213d6cead05 --- include/drivers/arm/ethosn_fip.h | 37 +++++++++++++++++++ plat/arm/board/juno/fip/plat_def_fip_uuid.h | 14 +++++++ .../arm/board/juno/fip/plat_def_uuid_config.c | 25 +++++++++++++ plat/arm/board/juno/plat_fiptool.mk | 16 ++++++++ 4 files changed, 92 insertions(+) create mode 100644 include/drivers/arm/ethosn_fip.h create mode 100644 plat/arm/board/juno/fip/plat_def_fip_uuid.h create mode 100644 plat/arm/board/juno/fip/plat_def_uuid_config.c create mode 100644 plat/arm/board/juno/plat_fiptool.mk diff --git a/include/drivers/arm/ethosn_fip.h b/include/drivers/arm/ethosn_fip.h new file mode 100644 index 000000000..f2c7f932c --- /dev/null +++ b/include/drivers/arm/ethosn_fip.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ETHOSN_FIP_H +#define ETHOSN_FIP_H + +#define UUID_ETHOSN_FW_KEY_CERTIFICATE \ + { { 0x56, 0x66, 0xd0, 0x04 }, { 0xab, 0x98 }, { 0x40, 0xaa }, \ + 0x89, 0x88, { 0xb7, 0x2a, 0x3, 0xa2, 0x56, 0xe2 } } + +#define UUID_ETHOSN_FW_CONTENT_CERTIFICATE \ + { { 0xa5, 0xc4, 0x18, 0xda }, { 0x43, 0x0f }, { 0x48, 0xb1 }, \ + 0x88, 0xcd, { 0x93, 0xf6, 0x78, 0x89, 0xd9, 0xed } } + +#define UUID_ETHOSN_FW \ + { { 0xcf, 0xd4, 0x99, 0xb5 }, { 0xa3, 0xbc }, { 0x4a, 0x7e }, \ + 0x98, 0xcb, { 0x48, 0xa4, 0x1c, 0xb8, 0xda, 0xe1 } } + +#define ETHOSN_FW_KEY_CERTIFICATE_DEF \ + { "Arm(R) Ethos(TM)-N NPU Firmware Key Certificate", \ + UUID_ETHOSN_FW_KEY_CERTIFICATE, \ + "npu-fw-key-cert" } + +#define ETHOSN_FW_CONTENT_CERTIFICATE_DEF \ + { "Arm(R) Ethos(TM)-N NPU Firmware Content Certificate",\ + UUID_ETHOSN_FW_CONTENT_CERTIFICATE, \ + "npu-fw-cert" } + +#define ETHOSN_FW_DEF \ + { "Arm(R) Ethos(TM)-N NPU Firmware", \ + UUID_ETHOSN_FW, \ + "npu-fw" } + +#endif /* ETHOSN_FIP_H */ diff --git a/plat/arm/board/juno/fip/plat_def_fip_uuid.h b/plat/arm/board/juno/fip/plat_def_fip_uuid.h new file mode 100644 index 000000000..0f0d11d41 --- /dev/null +++ b/plat/arm/board/juno/fip/plat_def_fip_uuid.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_DEF_FIP_UUID_H +#define PLAT_DEF_FIP_UUID_H + +#ifdef ARM_ETHOSN_NPU_TZMP1 +#include +#endif + +#endif /* PLAT_DEF_FIP_UUID_H */ diff --git a/plat/arm/board/juno/fip/plat_def_uuid_config.c b/plat/arm/board/juno/fip/plat_def_uuid_config.c new file mode 100644 index 000000000..813392740 --- /dev/null +++ b/plat/arm/board/juno/fip/plat_def_uuid_config.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include "plat_def_fip_uuid.h" + +toc_entry_t plat_def_toc_entries[] = { +#ifdef ARM_ETHOSN_NPU_TZMP1 + ETHOSN_FW_KEY_CERTIFICATE_DEF, + ETHOSN_FW_CONTENT_CERTIFICATE_DEF, + ETHOSN_FW_DEF, +#endif + { + .name = NULL, + .uuid = { { 0 } }, + .cmdline_name = NULL, + } +}; diff --git a/plat/arm/board/juno/plat_fiptool.mk b/plat/arm/board/juno/plat_fiptool.mk new file mode 100644 index 000000000..46b517901 --- /dev/null +++ b/plat/arm/board/juno/plat_fiptool.mk @@ -0,0 +1,16 @@ +# +# Copyright (c) 2023, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +PLAT_DEF_UUID := yes + +ifeq (${PLAT_DEF_UUID}, yes) +HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID +ifeq (${ARM_ETHOSN_NPU_TZMP1},1) +HOSTCCFLAGS += -DARM_ETHOSN_NPU_TZMP1 +endif +INCLUDE_PATHS += -I./ -I${PLAT_DIR}fip -I../../include/ +OBJECTS += ${PLAT_DIR}fip/plat_def_uuid_config.o +endif From f309607229e049a6ff9cbc858efa4dd0c0b921b8 Mon Sep 17 00:00:00 2001 From: Mohamed Elzahhar Date: Wed, 16 Nov 2022 12:05:37 +0000 Subject: [PATCH 09/25] feat(ethos-n): add support for NPU to cert_create Add Juno specific Makefile to the certificate tool build. That Makefile is included by the certificate tool Makefile to add information about the authentication data for the Arm(R) Ethos(TM)-N NPU's firmware binary. Signed-off-by: Mohamed Elzahhar Signed-off-by: Rob Hughes Signed-off-by: Mikael Olsson Change-Id: Ie4b6a1c29d73b3ed5041b57f2cd88033be18a63a --- include/drivers/arm/ethosn_cert.h | 74 +++++++++++++++++++ include/drivers/arm/ethosn_oid.h | 14 ++++ plat/arm/board/juno/cert_create_tbbr.mk | 25 +++++++ .../juno/certificate/include/juno_tbb_cert.h | 20 +++++ .../juno/certificate/include/juno_tbb_ext.h | 18 +++++ .../juno/certificate/include/juno_tbb_key.h | 19 +++++ .../juno/certificate/include/platform_oid.h | 12 +++ .../juno/certificate/src/juno_tbb_cert.c | 18 +++++ .../board/juno/certificate/src/juno_tbb_ext.c | 17 +++++ .../board/juno/certificate/src/juno_tbb_key.c | 15 ++++ 10 files changed, 232 insertions(+) create mode 100644 include/drivers/arm/ethosn_cert.h create mode 100644 include/drivers/arm/ethosn_oid.h create mode 100644 plat/arm/board/juno/cert_create_tbbr.mk create mode 100644 plat/arm/board/juno/certificate/include/juno_tbb_cert.h create mode 100644 plat/arm/board/juno/certificate/include/juno_tbb_ext.h create mode 100644 plat/arm/board/juno/certificate/include/juno_tbb_key.h create mode 100644 plat/arm/board/juno/certificate/include/platform_oid.h create mode 100644 plat/arm/board/juno/certificate/src/juno_tbb_cert.c create mode 100644 plat/arm/board/juno/certificate/src/juno_tbb_ext.c create mode 100644 plat/arm/board/juno/certificate/src/juno_tbb_key.c diff --git a/include/drivers/arm/ethosn_cert.h b/include/drivers/arm/ethosn_cert.h new file mode 100644 index 000000000..7aa887d7f --- /dev/null +++ b/include/drivers/arm/ethosn_cert.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ETHOSN_CERT_H +#define ETHOSN_CERT_H + +#include "ethosn_oid.h" +#include +#include + +/* Arm(R) Ethos(TM)-N NPU Certificates */ +#define ETHOSN_NPU_FW_KEY_CERT_DEF { \ + .id = ETHOSN_NPU_FW_KEY_CERT, \ + .opt = "npu-fw-key-cert", \ + .help_msg = "Arm(R) Ethos(TM)-N NPU Firmware Key Certificate (output file)", \ + .fn = NULL, \ + .cn = "NPU Firmware Key Certificate", \ + .key = NON_TRUSTED_WORLD_KEY, \ + .issuer = ETHOSN_NPU_FW_KEY_CERT, \ + .ext = { \ + NON_TRUSTED_FW_NVCOUNTER_EXT, \ + ETHOSN_NPU_FW_CONTENT_CERT_PK_EXT, \ + }, \ + .num_ext = 2 \ +} + +#define ETHOSN_NPU_FW_CONTENT_CERT_DEF { \ + .id = ETHOSN_NPU_FW_CONTENT_CERT, \ + .opt = "npu-fw-cert", \ + .help_msg = "Arm(R) Ethos(TM)-N NPU Firmware Content Certificate (output file)",\ + .fn = NULL, \ + .cn = "NPU Firmware Content Certificate", \ + .key = ETHOSN_NPU_FW_CONTENT_CERT_KEY, \ + .issuer = ETHOSN_NPU_FW_CONTENT_CERT, \ + .ext = { \ + NON_TRUSTED_FW_NVCOUNTER_EXT, \ + ETHOSN_NPU_FW_HASH_EXT, \ + }, \ + .num_ext = 2 \ +} + +/* NPU Extensions */ +#define ETHOSN_NPU_FW_CONTENT_CERT_PK_EXT_DEF { \ + .oid = ETHOSN_NPU_FW_CONTENT_CERT_PK_OID, \ + .help_msg = "Arm(R) Ethos(TM)-N NPU Firmware content certificate public key", \ + .sn = "NPUFirmwareContentCertPK", \ + .ln = "NPU Firmware content cerificate public key", \ + .asn1_type = V_ASN1_OCTET_STRING, \ + .type = EXT_TYPE_PKEY, \ + .attr.key = ETHOSN_NPU_FW_CONTENT_CERT_KEY \ +} + +#define ETHOSN_NPU_FW_HASH_EXT_DEF { \ + .oid = ETHOSN_NPU_FW_BINARY_OID, \ + .opt = "npu-fw", \ + .help_msg = "Arm(R) Ethos(TM)-N NPU Firmware image file (input file)", \ + .sn = "NPUFirmwareHash", \ + .ln = "NPU Firmware Hash (SHA256)", \ + .asn1_type = V_ASN1_OCTET_STRING, \ + .type = EXT_TYPE_HASH \ +} + +/* NPU Keys */ +#define ETHOSN_NPU_FW_CONTENT_CERT_KEY_DEF { \ + .id = ETHOSN_NPU_FW_CONTENT_CERT_KEY, \ + .opt = "npu-fw-key", \ + .help_msg = "Arm(R) Ethos(TM)-N NPU Firmware Content Certificate key (input/output file)",\ + .desc = "NPU Firmware Content Certificate key" \ +} + +#endif /* ETHOSN_CERT_H */ diff --git a/include/drivers/arm/ethosn_oid.h b/include/drivers/arm/ethosn_oid.h new file mode 100644 index 000000000..a83cd09cb --- /dev/null +++ b/include/drivers/arm/ethosn_oid.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ETHOSN_OID_H +#define ETHOSN_OID_H + +/* Arm(R) Ethos(TM)-N NPU Platform OID */ +#define ETHOSN_NPU_FW_CONTENT_CERT_PK_OID "1.3.6.1.4.1.4128.2300.1" +#define ETHOSN_NPU_FW_BINARY_OID "1.3.6.1.4.1.4128.2300.2" + +#endif /* ETHOSN_OID_H */ diff --git a/plat/arm/board/juno/cert_create_tbbr.mk b/plat/arm/board/juno/cert_create_tbbr.mk new file mode 100644 index 000000000..c092fe042 --- /dev/null +++ b/plat/arm/board/juno/cert_create_tbbr.mk @@ -0,0 +1,25 @@ +# +# Copyright (c) 2023, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +PLAT_DEF_OID := 1 + +ifeq (${PLAT_DEF_OID},1) + ifeq (${ARM_ETHOSN_NPU_DRIVER},1) + $(eval $(call add_define, PLAT_DEF_OID)) + $(eval $(call add_define, PDEF_CERTS)) + $(eval $(call add_define, PDEF_EXTS)) + $(eval $(call add_define, PDEF_KEYS)) + + PLAT_INCLUDE += -I ${PLAT_DIR}/certificate/include \ + -I ../../include/drivers/arm + + PLAT_OBJECTS += ${PLAT_DIR}certificate/src/juno_tbb_cert.o \ + ${PLAT_DIR}certificate/src/juno_tbb_ext.o \ + ${PLAT_DIR}certificate/src/juno_tbb_key.o + + OBJECTS += ${PLAT_OBJECTS} + endif +endif diff --git a/plat/arm/board/juno/certificate/include/juno_tbb_cert.h b/plat/arm/board/juno/certificate/include/juno_tbb_cert.h new file mode 100644 index 000000000..9799405a9 --- /dev/null +++ b/plat/arm/board/juno/certificate/include/juno_tbb_cert.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef JUNO_TBB_CERT_H +#define JUNO_TBB_CERT_H + +#include + +/* + * Juno platform certificates that are used to establish the COT + */ +enum { + ETHOSN_NPU_FW_KEY_CERT = FWU_CERT + 1, + ETHOSN_NPU_FW_CONTENT_CERT, +}; + +#endif /* JUNO_TBB_CERT_H */ diff --git a/plat/arm/board/juno/certificate/include/juno_tbb_ext.h b/plat/arm/board/juno/certificate/include/juno_tbb_ext.h new file mode 100644 index 000000000..ec3822736 --- /dev/null +++ b/plat/arm/board/juno/certificate/include/juno_tbb_ext.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef JUNO_TBB_EXT_H +#define JUNO_TBB_EXT_H + +#include + +/* Juno platform defined TBBR extensions */ +enum { + ETHOSN_NPU_FW_CONTENT_CERT_PK_EXT = FWU_HASH_EXT + 1, + ETHOSN_NPU_FW_HASH_EXT, +}; + +#endif /* JUNO_TBB_EXT_H */ diff --git a/plat/arm/board/juno/certificate/include/juno_tbb_key.h b/plat/arm/board/juno/certificate/include/juno_tbb_key.h new file mode 100644 index 000000000..9576b9d8c --- /dev/null +++ b/plat/arm/board/juno/certificate/include/juno_tbb_key.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef JUNO_TBB_KEY_H +#define JUNO_TBB_KEY_H + +#include + +/* + * Juno platform keys that are used to establish the COT + */ +enum { + ETHOSN_NPU_FW_CONTENT_CERT_KEY = + NON_TRUSTED_FW_CONTENT_CERT_KEY + 1, +}; +#endif /* JUNO_TBB_KEY_H */ diff --git a/plat/arm/board/juno/certificate/include/platform_oid.h b/plat/arm/board/juno/certificate/include/platform_oid.h new file mode 100644 index 000000000..22173c18f --- /dev/null +++ b/plat/arm/board/juno/certificate/include/platform_oid.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef JUNO_PLATFORM_OID_H +#define JUNO_PLATFORM_OID_H + +#include + +#endif /* JUNO_PLATFORM_OID_H */ diff --git a/plat/arm/board/juno/certificate/src/juno_tbb_cert.c b/plat/arm/board/juno/certificate/src/juno_tbb_cert.c new file mode 100644 index 000000000..3cb8304fe --- /dev/null +++ b/plat/arm/board/juno/certificate/src/juno_tbb_cert.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +static cert_t juno_plat_tbb_certificates[] = { + ETHOSN_NPU_FW_KEY_CERT_DEF, + ETHOSN_NPU_FW_CONTENT_CERT_DEF, +}; + +PLAT_REGISTER_COT(juno_plat_tbb_certificates); diff --git a/plat/arm/board/juno/certificate/src/juno_tbb_ext.c b/plat/arm/board/juno/certificate/src/juno_tbb_ext.c new file mode 100644 index 000000000..d8fe9e90f --- /dev/null +++ b/plat/arm/board/juno/certificate/src/juno_tbb_ext.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +static ext_t juno_plat_tbb_extensions[] = { + ETHOSN_NPU_FW_CONTENT_CERT_PK_EXT_DEF, + ETHOSN_NPU_FW_HASH_EXT_DEF, +}; + +PLAT_REGISTER_EXTENSIONS(juno_plat_tbb_extensions); diff --git a/plat/arm/board/juno/certificate/src/juno_tbb_key.c b/plat/arm/board/juno/certificate/src/juno_tbb_key.c new file mode 100644 index 000000000..470755fbb --- /dev/null +++ b/plat/arm/board/juno/certificate/src/juno_tbb_key.c @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +static key_t juno_plat_tbb_keys[] = { + ETHOSN_NPU_FW_CONTENT_CERT_KEY_DEF +}; + +PLAT_REGISTER_KEYS(juno_plat_tbb_keys); From 5a89947ab3ef8541b7adb6058af9ef141073043d Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Wed, 11 Jan 2023 10:36:22 +0100 Subject: [PATCH 10/25] fix(ethos-n): add workaround for erratum 2838783 To workaround Arm(R) Ethos(TM)-N NPU erratum 2838783, the NPU has been configured to allow being woken up by both secure and non-secure events to make sure that an event always wakes up the NPU. The API version has been given a minor version bump with this change to indicate that this fix is included. Signed-off-by: Mikael Olsson Change-Id: I429cdd6bf1e633b4dedf2e94af28937dd892a0ba --- drivers/arm/ethosn/ethosn_smc.c | 3 ++- include/drivers/arm/ethosn.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c index 7604b8b56..cf3491055 100644 --- a/drivers/arm/ethosn/ethosn_smc.c +++ b/drivers/arm/ethosn/ethosn_smc.c @@ -39,7 +39,8 @@ #define SEC_DEL_EXCC_MASK U(0x20) #define SEC_SECCTLR_REG U(0x0010) -#define SEC_SECCTLR_VAL U(0x3) +/* Set bit[10] = 1 to workaround erratum 2838783 */ +#define SEC_SECCTLR_VAL U(0x403) #define SEC_DEL_ADDR_EXT_REG U(0x201C) #define SEC_DEL_ADDR_EXT_VAL U(0x15) diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h index 95244c71f..9f1b499d0 100644 --- a/include/drivers/arm/ethosn.h +++ b/include/drivers/arm/ethosn.h @@ -40,7 +40,7 @@ /* Service version */ #define ETHOSN_VERSION_MAJOR U(2) -#define ETHOSN_VERSION_MINOR U(2) +#define ETHOSN_VERSION_MINOR U(3) /* Return codes for function calls */ #define ETHOSN_SUCCESS 0 From 7f2bf23dec6e6467704d7d71ec44bee030912987 Mon Sep 17 00:00:00 2001 From: Rob Hughes Date: Fri, 20 Jan 2023 10:40:27 +0000 Subject: [PATCH 11/25] fix(fvp): incorrect UUID name in FVP tb_fw_config Signed-off-by: Rob Hughes Signed-off-by: Mikael Olsson Change-Id: I557bca7dd32c3be084bbba11d84dfa2818cb6791 --- plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts index 6fd334d8e..6ba76db60 100644 --- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, ARM Limited. All rights reserved. + * Copyright (c) 2020-2023, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -59,7 +59,7 @@ soc_fw_content_cert_uuid = "e2b20c20-5e63-e411-9ce8-abccf92bb666"; tos_fw_content_cert_uuid = "a49f4411-5e63-e411-8728-3f05722af33d"; nt_fw_content_cert_uuid = "8ec4c1f3-5d63-e411-a7a9-87ee40b23fa7"; - sp_content_cert_uuid = "776dfd44-8697-4c3b-91eb-c13e025a2a6f"; + plat_sp_content_cert_uuid = "776dfd44-8697-4c3b-91eb-c13e025a2a6f"; }; }; #endif /* ARM_IO_IN_DTB */ From e208f3244b311a23b3e7fa1c03b3e98a6228714a Mon Sep 17 00:00:00 2001 From: Rob Hughes Date: Fri, 20 Jan 2023 10:43:41 +0000 Subject: [PATCH 12/25] fix(fconf): fix FCONF_ARM_IO_UUID_NUMBER value The FCONF_ARM_IO_UUID_NUMBER macro is hardcoded to the number of entries in the `load_info` array, but this number did not match the actual length of the array in the case that TRUSTED_BOARD_BOOT is defined, but SPD_spmd is not defined. This patch fixes the hardcoded length by replacing it with a more flexible calculation which sums up the various contributing groups of entries. Signed-off-by: Rob Hughes Signed-off-by: Mikael Olsson Change-Id: I557bca7dd32c3be084bbba11d84dfa2818cb6790 --- plat/arm/common/fconf/arm_fconf_io.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index 6c323312c..dfaaaae07 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022, ARM Limited. All rights reserved. + * Copyright (c) 2019-2023, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -277,11 +277,22 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { #ifdef IMAGE_BL2 +#define FCONF_ARM_IO_UUID_NUM_BASE U(10) + #if TRUSTED_BOARD_BOOT -#define FCONF_ARM_IO_UUID_NUMBER U(24) +#define FCONF_ARM_IO_UUID_NUM_TBB U(12) #else -#define FCONF_ARM_IO_UUID_NUMBER U(10) -#endif +#define FCONF_ARM_IO_UUID_NUM_TBB U(0) +#endif /* TRUSTED_BOARD_BOOT */ + +#if TRUSTED_BOARD_BOOT && defined(SPD_spmd) +#define FCONF_ARM_IO_UUID_NUM_SPD U(2) +#else +#define FCONF_ARM_IO_UUID_NUM_SPD U(0) +#endif /* TRUSTED_BOARD_BOOT && defined(SPD_spmd) */ + +#define FCONF_ARM_IO_UUID_NUMBER FCONF_ARM_IO_UUID_NUM_BASE + \ + FCONF_ARM_IO_UUID_NUM_TBB + FCONF_ARM_IO_UUID_NUM_SPD static io_uuid_spec_t fconf_arm_uuids[FCONF_ARM_IO_UUID_NUMBER]; static OBJECT_POOL_ARRAY(fconf_arm_uuids_pool, fconf_arm_uuids); From 2fad320f5623edcdd23297ab57c4b9b0b0ef872c Mon Sep 17 00:00:00 2001 From: Rob Hughes Date: Fri, 20 Jan 2023 10:47:30 +0000 Subject: [PATCH 13/25] feat(juno): support ARM_IO_IN_DTB option for Juno Add UUIDs for loadable FIP images to Juno's tb_fw_config device tree, so that it can be built with the ARM_IO_IN_DTB option. Increase the max-size of the tb_fw-config image accordingly, as the new entries enlarge that image(new size is 2,116 bytes, rounded up to 2,560 = 0xA00) Signed-off-by: Rob Hughes Signed-off-by: Mikael Olsson Change-Id: I557bca7dd32c3be084bbba11d84dfa2818cb6789 --- plat/arm/board/juno/fdts/juno_fw_config.dts | 4 +-- .../arm/board/juno/fdts/juno_tb_fw_config.dts | 34 ++++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts index 4b88efe8c..2d79ac7ab 100644 --- a/plat/arm/board/juno/fdts/juno_fw_config.dts +++ b/plat/arm/board/juno/fdts/juno_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2021, ARM Limited. All rights reserved. + * Copyright (c) 2019-2023, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,7 +14,7 @@ tb_fw-config { load-address = <0x0 0x4001300>; - max-size = <0x200>; + max-size = <0xA00>; id = ; }; diff --git a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts index 80cfa3ea1..bdff805a3 100644 --- a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts +++ b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, ARM Limited. All rights reserved. + * Copyright (c) 2020-2023, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -23,4 +23,36 @@ mbedtls_heap_addr = <0x0 0x0>; mbedtls_heap_size = <0x0>; }; + +#if ARM_IO_IN_DTB + arm-io_policies { + fip-handles { + compatible = "arm,io-fip-handle"; + scp_bl2_uuid = "9766fd3d-89be-e849-ae5d-78a140608213"; + bl31_uuid = "47d4086d-4cfe-9846-9b95-2950cbbd5a00"; + bl32_uuid = "05d0e189-53dc-1347-8d2b-500a4b7a3e38"; + bl32_extra1_uuid = "0b70c29b-2a5a-7840-9f65-0a5682738288"; + bl32_extra2_uuid = "8ea87bb1-cfa2-3f4d-85fd-e7bba50220d9"; + bl33_uuid = "d6d0eea7-fcea-d54b-9782-9934f234b6e4"; + hw_cfg_uuid = "08b8f1d9-c9cf-9349-a962-6fbc6b7265cc"; + soc_fw_cfg_uuid = "9979814b-0376-fb46-8c8e-8d267f7859e0"; + tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021"; + nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9"; + cca_cert_uuid = "36d83d85-761d-4daf-96f1-cd99d6569b00"; + core_swd_cert_uuid = "52222d31-820f-494d-8bbc-ea6825d3c35a"; + plat_cert_uuid = "d43cd902-5b9f-412e-8ac6-92b6d18be60d"; + t_key_cert_uuid = "827ee890-f860-e411-a1b4-777a21b4f94c"; + scp_fw_key_uuid = "024221a1-f860-e411-8d9b-f33c0e15a014"; + soc_fw_key_uuid = "8ab8becc-f960-e411-9ad0-eb4822d8dcf8"; + tos_fw_key_cert_uuid = "9477d603-fb60-e411-85dd-b7105b8cee04"; + nt_fw_key_cert_uuid = "8ad5832a-fb60-e411-8aaf-df30bbc49859"; + scp_fw_content_cert_uuid = "44be6f04-5e63-e411-b28b-73d8eaae9656"; + soc_fw_content_cert_uuid = "e2b20c20-5e63-e411-9ce8-abccf92bb666"; + tos_fw_content_cert_uuid = "a49f4411-5e63-e411-8728-3f05722af33d"; + nt_fw_content_cert_uuid = "8ec4c1f3-5d63-e411-a7a9-87ee40b23fa7"; + plat_sp_content_cert_uuid = "776dfd44-8697-4c3b-91eb-c13e025a2a6f"; + }; + }; +#endif /* ARM_IO_IN_DTB */ + }; From 33bcaed1211ab27968433b546979687bc1182630 Mon Sep 17 00:00:00 2001 From: Rob Hughes Date: Tue, 17 Jan 2023 16:10:26 +0000 Subject: [PATCH 14/25] feat(ethos-n)!: load NPU firmware at BL2 BL2 on Juno now loads the Arm(R) Ethos(TM)-N NPU firmware into a fixed address, using the existing image loading framework. Includes support for TRUSTED_BOARD_BOOT, if enabled, using the firmware content and key certificates from the FIP. Supports the ARM_IO_IN_DTB option so can specify the firmware location from the dtb rather than it being hardcoded to the FIP Update makefile to automatically embed the appropriate images into the FIP. BREAKING CHANGE: Building the FIP when TZMP1 support is enabled in the NPU driver now requires a parameter to specify the NPU firmware file. Signed-off-by: Rob Hughes Signed-off-by: Mikael Olsson Change-Id: I8cd64fb20d58f8bd539facb085606213d6cead06 --- docs/getting_started/porting-guide.rst | 15 + docs/plat/arm/arm-build-options.rst | 6 +- .../arm/board/juno/fdts/juno_tb_fw_config.dts | 5 + .../board/juno/include/plat_tbbr_img_def.h | 18 + plat/arm/board/juno/include/platform_def.h | 22 +- plat/arm/board/juno/juno_common.c | 3 + plat/arm/board/juno/juno_tbbr_cot_bl2.c | 789 ++++++++++++++++++ plat/arm/board/juno/platform.mk | 12 +- .../common/aarch64/arm_bl2_mem_params_desc.c | 16 +- plat/arm/common/arm_common.mk | 31 +- plat/arm/common/fconf/arm_fconf_io.c | 50 +- 11 files changed, 952 insertions(+), 15 deletions(-) create mode 100644 plat/arm/board/juno/include/plat_tbbr_img_def.h create mode 100644 plat/arm/board/juno/juno_tbbr_cot_bl2.c diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index b3092c790..5b88fcb38 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -587,6 +587,21 @@ enabled, the following constants must also be defined. Defines the Non-secure Access IDentity (NSAID) that the NPU shall use to access the protected memory that contains inference data. +- **ARM_ETHOSN_NPU_FW_IMAGE_BASE** and **ARM_ETHOSN_NPU_FW_IMAGE_LIMIT** + +- Provide FCONF entries to configure the image source for NPU firmware (and certificates). + +- Add MMU mappings such that: + + - BL2 can write the NPU firmware into the region defined by + ``ARM_ETHOSN_NPU_FW_IMAGE_BASE`` and ``ARM_ETHOSN_NPU_FW_IMAGE_LIMIT`` + - BL31 (SiP service) can read the NPU firmware from the same region + +- Add the firmware image ID ``ARM_ETHOSN_NPU_FW_IMAGE_ID`` to the list of images loaded by BL2 + +Please see the reference implementation code for the Juno platform as an example. + + The following constant is optional. It should be defined to override the default behaviour of the ``assert()`` function (for example, to save memory). diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst index dda2aa0a9..83212c6dc 100644 --- a/docs/plat/arm/arm-build-options.rst +++ b/docs/plat/arm/arm-build-options.rst @@ -102,7 +102,11 @@ Arm Platform Build Options only loads the ``HW_CONFIG`` in AArch64 builds. Default is 0. - ``ARM_ETHOSN_NPU_TZMP1``: boolean option to enable TZMP1 support for the - Arm® Ethos™-N NPU. Requires ``ARM_ETHOSN_NPU_DRIVER`` to be enabled. + Arm® Ethos™-N NPU. Requires ``ARM_ETHOSN_NPU_DRIVER`` and + ``TRUSTED_BOARD_BOOT`` to be enabled. + +- ``ARM_ETHOSN_NPU_FW``: location of the NPU firmware binary (ethosn.bin). + This firmware image will be included in the FIP and loaded at runtime. - ``ARM_SPMC_MANIFEST_DTS`` : path to an alternate manifest file used as the SPMC Core manifest. Valid when ``SPD=spmd`` is selected. diff --git a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts index bdff805a3..986299ee3 100644 --- a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts +++ b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts @@ -51,6 +51,11 @@ tos_fw_content_cert_uuid = "a49f4411-5e63-e411-8728-3f05722af33d"; nt_fw_content_cert_uuid = "8ec4c1f3-5d63-e411-a7a9-87ee40b23fa7"; plat_sp_content_cert_uuid = "776dfd44-8697-4c3b-91eb-c13e025a2a6f"; +#if ARM_ETHOSN_NPU_TZMP1 + arm_ethosn_npu_fw_uuid = "cfd499b5-a3bc-4a7e-98cb-48a41cb8dae1"; + arm_ethosn_npu_fw_key_cert_uuid = "5666d004-ab98-40aa-8988-b72a03a256e2"; + arm_ethosn_npu_fw_content_cert_uuid = "a5c418da-430f-48b1-88cd-93f67889d9ed"; +#endif }; }; #endif /* ARM_IO_IN_DTB */ diff --git a/plat/arm/board/juno/include/plat_tbbr_img_def.h b/plat/arm/board/juno/include/plat_tbbr_img_def.h new file mode 100644 index 000000000..3e17ed3d1 --- /dev/null +++ b/plat/arm/board/juno/include/plat_tbbr_img_def.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef JUNO_IMG_DEF_H +#define JUNO_IMG_DEF_H + +#if ARM_ETHOSN_NPU_TZMP1 +/* Arm(R) Ethos(TM)-N NPU images */ +#define ARM_ETHOSN_NPU_FW_KEY_CERT_ID U(MAX_IMG_IDS_WITH_SPMDS + 1) +#define ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID U(MAX_IMG_IDS_WITH_SPMDS + 2) +#define ARM_ETHOSN_NPU_FW_IMAGE_ID U(MAX_IMG_IDS_WITH_SPMDS + 3) +#define MAX_NUMBER_IDS U(MAX_IMG_IDS_WITH_SPMDS + 4) +#endif + +#endif /* JUNO_IMG_DEF_H */ diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 1ccaf5cf7..ef37104e9 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -65,6 +65,13 @@ JUNO_DTB_DRAM_MAP_SIZE, \ MT_MEMORY | MT_RO | MT_NS) +#ifdef JUNO_ETHOSN_TZMP1 +#define JUNO_ETHOSN_PROT_FW_RW MAP_REGION_FLAT( \ + JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE, \ + JUNO_ETHOSN_FW_TZC_PROT_DRAM2_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) +#endif + /* virtual address used by dynamic mem_protect for chunk_base */ #define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000) @@ -105,11 +112,11 @@ #ifdef IMAGE_BL2 #ifdef SPD_opteed -# define PLAT_ARM_MMAP_ENTRIES 11 +# define PLAT_ARM_MMAP_ENTRIES 13 # define MAX_XLAT_TABLES 5 #else -# define PLAT_ARM_MMAP_ENTRIES 10 -# define MAX_XLAT_TABLES 4 +# define PLAT_ARM_MMAP_ENTRIES 11 +# define MAX_XLAT_TABLES 5 #endif #endif @@ -313,10 +320,13 @@ /* Number of SCMI channels on the platform */ #define PLAT_ARM_SCMI_CHANNEL_COUNT U(1) -/* Protected memory NSAIDs for the Arm(R) Ethos(TM)-N NPU driver */ +/* Protected NSAIDs and memory regions for the Arm(R) Ethos(TM)-N NPU driver */ #ifdef JUNO_ETHOSN_TZMP1 -#define ARM_ETHOSN_NPU_PROT_FW_NSAID JUNO_ETHOSN_TZC400_NSAID_FW_PROT -#define ARM_ETHOSN_NPU_PROT_DATA_NSAID JUNO_ETHOSN_TZC400_NSAID_DATA_PROT +#define ARM_ETHOSN_NPU_PROT_FW_NSAID JUNO_ETHOSN_TZC400_NSAID_FW_PROT +#define ARM_ETHOSN_NPU_PROT_DATA_NSAID JUNO_ETHOSN_TZC400_NSAID_DATA_PROT +#define ARM_ETHOSN_NPU_FW_IMAGE_BASE JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE +#define ARM_ETHOSN_NPU_FW_IMAGE_LIMIT \ + (JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE + JUNO_ETHOSN_FW_TZC_PROT_DRAM2_SIZE) #endif #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c index 451c7df37..584b2ed72 100644 --- a/plat/arm/board/juno/juno_common.c +++ b/plat/arm/board/juno/juno_common.c @@ -52,6 +52,9 @@ const mmap_region_t plat_arm_mmap[] = { #endif #if TRUSTED_BOARD_BOOT && !RESET_TO_BL2 ARM_MAP_BL1_RW, +#endif +#ifdef JUNO_ETHOSN_TZMP1 + JUNO_ETHOSN_PROT_FW_RW, #endif {0} }; diff --git a/plat/arm/board/juno/juno_tbbr_cot_bl2.c b/plat/arm/board/juno/juno_tbbr_cot_bl2.c new file mode 100644 index 000000000..d48d2e6bd --- /dev/null +++ b/plat/arm/board/juno/juno_tbbr_cot_bl2.c @@ -0,0 +1,789 @@ +/* + * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include +#include + +#if USE_TBBR_DEFS +#include +#else +#include +#endif + +#include + +static unsigned char soc_fw_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_extra1_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_extra2_hash_buf[HASH_DER_LEN]; +static unsigned char trusted_world_pk_buf[PK_DER_LEN]; +static unsigned char non_trusted_world_pk_buf[PK_DER_LEN]; +static unsigned char content_pk_buf[PK_DER_LEN]; +static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN]; +#if defined(SPD_spmd) +static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN]; +#endif /* SPD_spmd */ +#if ARM_ETHOSN_NPU_TZMP1 +static unsigned char npu_fw_image_hash_buf[HASH_DER_LEN]; +#endif /* ARM_ETHOSN_NPU_TZMP1 */ + + +static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID); +static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, TRUSTED_WORLD_PK_OID); +static auth_param_type_desc_t non_trusted_world_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, NON_TRUSTED_WORLD_PK_OID); +static auth_param_type_desc_t scp_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, SCP_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t soc_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, SOC_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t tos_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, TRUSTED_OS_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t nt_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, NON_TRUSTED_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t scp_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SCP_FW_HASH_OID); +static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID); +static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID); +static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID); +static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID); +static auth_param_type_desc_t tos_fw_extra1_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA1_HASH_OID); +static auth_param_type_desc_t tos_fw_extra2_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA2_HASH_OID); +static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID); +static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID); +#if defined(SPD_spmd) +static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG1_HASH_OID); +static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG2_HASH_OID); +static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG3_HASH_OID); +static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG4_HASH_OID); +static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG5_HASH_OID); +static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG6_HASH_OID); +static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG7_HASH_OID); +static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SP_PKG8_HASH_OID); +#endif /* SPD_spmd */ +#if ARM_ETHOSN_NPU_TZMP1 +static auth_param_type_desc_t npu_fw_cert_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, ETHOSN_NPU_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t npu_fw_image_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, ETHOSN_NPU_FW_BINARY_OID); +#endif /* ARM_ETHOSN_NPU_TZMP1 */ + +/* + * Trusted key certificate + */ +static const auth_img_desc_t trusted_key_cert = { + .img_id = TRUSTED_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &subject_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &trusted_world_pk, + .data = { + .ptr = (void *)trusted_world_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + }, + [1] = { + .type_desc = &non_trusted_world_pk, + .data = { + .ptr = (void *)non_trusted_world_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +/* + * SCP Firmware + */ +static const auth_img_desc_t scp_fw_key_cert = { + .img_id = SCP_FW_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &scp_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t scp_fw_content_cert = { + .img_id = SCP_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &scp_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &scp_fw_content_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &scp_fw_hash, + .data = { + .ptr = (void *)scp_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +static const auth_img_desc_t scp_bl2_image = { + .img_id = SCP_BL2_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &scp_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &scp_fw_hash + } + } + } +}; +/* + * SoC Firmware + */ +static const auth_img_desc_t soc_fw_key_cert = { + .img_id = SOC_FW_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &soc_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t soc_fw_content_cert = { + .img_id = SOC_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &soc_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &soc_fw_content_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &soc_fw_hash, + .data = { + .ptr = (void *)soc_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &soc_fw_config_hash, + .data = { + .ptr = (void *)soc_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +static const auth_img_desc_t bl31_image = { + .img_id = BL31_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &soc_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &soc_fw_hash + } + } + } +}; +/* SOC FW Config */ +static const auth_img_desc_t soc_fw_config = { + .img_id = SOC_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &soc_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &soc_fw_config_hash + } + } + } +}; +/* + * Trusted OS Firmware + */ +static const auth_img_desc_t trusted_os_fw_key_cert = { + .img_id = TRUSTED_OS_FW_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &tos_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t trusted_os_fw_content_cert = { + .img_id = TRUSTED_OS_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_os_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &tos_fw_content_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &tos_fw_hash, + .data = { + .ptr = (void *)tos_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &tos_fw_extra1_hash, + .data = { + .ptr = (void *)tos_fw_extra1_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &tos_fw_extra2_hash, + .data = { + .ptr = (void *)tos_fw_extra2_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [3] = { + .type_desc = &tos_fw_config_hash, + .data = { + .ptr = (void *)tos_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +static const auth_img_desc_t bl32_image = { + .img_id = BL32_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tos_fw_hash + } + } + } +}; +static const auth_img_desc_t bl32_extra1_image = { + .img_id = BL32_EXTRA1_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tos_fw_extra1_hash + } + } + } +}; +static const auth_img_desc_t bl32_extra2_image = { + .img_id = BL32_EXTRA2_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tos_fw_extra2_hash + } + } + } +}; +/* TOS FW Config */ +static const auth_img_desc_t tos_fw_config = { + .img_id = TOS_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tos_fw_config_hash + } + } + } +}; +/* + * Non-Trusted Firmware + */ +static const auth_img_desc_t non_trusted_fw_key_cert = { + .img_id = NON_TRUSTED_FW_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &non_trusted_nv_ctr, + .plat_nv_ctr = &non_trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &nt_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t non_trusted_fw_content_cert = { + .img_id = NON_TRUSTED_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &non_trusted_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &nt_fw_content_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &non_trusted_nv_ctr, + .plat_nv_ctr = &non_trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &nt_world_bl_hash, + .data = { + .ptr = (void *)nt_world_bl_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &nt_fw_config_hash, + .data = { + .ptr = (void *)nt_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +static const auth_img_desc_t bl33_image = { + .img_id = BL33_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &non_trusted_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &nt_world_bl_hash + } + } + } +}; +/* NT FW Config */ +static const auth_img_desc_t nt_fw_config = { + .img_id = NT_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &non_trusted_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &nt_fw_config_hash + } + } + } +}; +/* Secure Partitions */ +#if defined(SPD_spmd) +static const auth_img_desc_t sip_sp_content_cert = { + .img_id = SIP_SP_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &sp_pkg1_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[0], + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &sp_pkg2_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[1], + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &sp_pkg3_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[2], + .len = (unsigned int)HASH_DER_LEN + } + }, + [3] = { + .type_desc = &sp_pkg4_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[3], + .len = (unsigned int)HASH_DER_LEN + } + }, + [4] = { + .type_desc = &sp_pkg5_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[4], + .len = (unsigned int)HASH_DER_LEN + } + }, + [5] = { + .type_desc = &sp_pkg6_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[5], + .len = (unsigned int)HASH_DER_LEN + } + }, + [6] = { + .type_desc = &sp_pkg7_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[6], + .len = (unsigned int)HASH_DER_LEN + } + }, + [7] = { + .type_desc = &sp_pkg8_hash, + .data = { + .ptr = (void *)sp_pkg_hash_buf[7], + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; + +DEFINE_SIP_SP_PKG(1); +DEFINE_SIP_SP_PKG(2); +DEFINE_SIP_SP_PKG(3); +DEFINE_SIP_SP_PKG(4); +DEFINE_SIP_SP_PKG(5); +DEFINE_SIP_SP_PKG(6); +DEFINE_SIP_SP_PKG(7); +DEFINE_SIP_SP_PKG(8); +#endif /* SPD_spmd */ + +#if ARM_ETHOSN_NPU_TZMP1 +static const auth_img_desc_t npu_fw_key_cert = { + .img_id = ARM_ETHOSN_NPU_FW_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &non_trusted_nv_ctr, + .plat_nv_ctr = &non_trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &npu_fw_cert_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; + +static const auth_img_desc_t npu_fw_content_cert = { + .img_id = ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &npu_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &npu_fw_cert_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &non_trusted_nv_ctr, + .plat_nv_ctr = &non_trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &npu_fw_image_hash, + .data = { + .ptr = (void *)npu_fw_image_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + } +}; + +static const auth_img_desc_t npu_fw_image = { + .img_id = ARM_ETHOSN_NPU_FW_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &npu_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &npu_fw_image_hash + } + } + } +}; +#endif /* ARM_ETHOSN_NPU_TZMP1 */ + + +static const auth_img_desc_t * const cot_desc[] = { + [TRUSTED_BOOT_FW_CERT_ID] = &trusted_boot_fw_cert, + [HW_CONFIG_ID] = &hw_config, + [TRUSTED_KEY_CERT_ID] = &trusted_key_cert, + [SCP_FW_KEY_CERT_ID] = &scp_fw_key_cert, + [SCP_FW_CONTENT_CERT_ID] = &scp_fw_content_cert, + [SCP_BL2_IMAGE_ID] = &scp_bl2_image, + [SOC_FW_KEY_CERT_ID] = &soc_fw_key_cert, + [SOC_FW_CONTENT_CERT_ID] = &soc_fw_content_cert, + [BL31_IMAGE_ID] = &bl31_image, + [SOC_FW_CONFIG_ID] = &soc_fw_config, + [TRUSTED_OS_FW_KEY_CERT_ID] = &trusted_os_fw_key_cert, + [TRUSTED_OS_FW_CONTENT_CERT_ID] = &trusted_os_fw_content_cert, + [BL32_IMAGE_ID] = &bl32_image, + [BL32_EXTRA1_IMAGE_ID] = &bl32_extra1_image, + [BL32_EXTRA2_IMAGE_ID] = &bl32_extra2_image, + [TOS_FW_CONFIG_ID] = &tos_fw_config, + [NON_TRUSTED_FW_KEY_CERT_ID] = &non_trusted_fw_key_cert, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert, + [BL33_IMAGE_ID] = &bl33_image, + [NT_FW_CONFIG_ID] = &nt_fw_config, +#if defined(SPD_spmd) + [SIP_SP_CONTENT_CERT_ID] = &sip_sp_content_cert, + [SP_PKG1_ID] = &sp_pkg1, + [SP_PKG2_ID] = &sp_pkg2, + [SP_PKG3_ID] = &sp_pkg3, + [SP_PKG4_ID] = &sp_pkg4, + [SP_PKG5_ID] = &sp_pkg5, + [SP_PKG6_ID] = &sp_pkg6, + [SP_PKG7_ID] = &sp_pkg7, + [SP_PKG8_ID] = &sp_pkg8, +#endif +#if ARM_ETHOSN_NPU_TZMP1 + [ARM_ETHOSN_NPU_FW_KEY_CERT_ID] = &npu_fw_key_cert, + [ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID] = &npu_fw_content_cert, + [ARM_ETHOSN_NPU_FW_IMAGE_ID] = &npu_fw_image, +#endif /* ARM_ETHOSN_NPU_TZMP1 */ +}; + +/* Register the CoT in the authentication module */ +REGISTER_COT(cot_desc); diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index d99b16c82..a4e640771 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -106,8 +106,16 @@ BL1_SOURCES += drivers/arm/css/sds/sds.c endif ifeq (${TRUSTED_BOARD_BOOT}, 1) -BL1_SOURCES += plat/arm/board/juno/juno_trusted_boot.c -BL2_SOURCES += plat/arm/board/juno/juno_trusted_boot.c + # Enable Juno specific TBBR images + $(eval $(call add_define,PLAT_TBBR_IMG_DEF)) + DTC_CPPFLAGS += ${PLAT_INCLUDES} + + BL1_SOURCES += plat/arm/board/juno/juno_trusted_boot.c + BL2_SOURCES += plat/arm/board/juno/juno_trusted_boot.c + + ifeq (${COT_DESC_IN_DTB},0) + BL2_SOURCES += plat/arm/board/juno/juno_tbbr_cot_bl2.c + endif endif endif diff --git a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c index 3d7b3613e..e51219244 100644 --- a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c +++ b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -220,8 +220,20 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING), .next_handoff_image_id = INVALID_IMAGE_ID, - } + }, #endif /* EL3_PAYLOAD_BASE */ + +# if ARM_ETHOSN_NPU_TZMP1 + { + .image_id = ARM_ETHOSN_NPU_FW_IMAGE_ID, + SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, + VERSION_2, image_info_t, 0), + .image_info.image_base = ARM_ETHOSN_NPU_FW_IMAGE_BASE, + .image_info.image_max_size = ARM_ETHOSN_NPU_FW_IMAGE_LIMIT - + ARM_ETHOSN_NPU_FW_IMAGE_BASE, + .next_handoff_image_id = INVALID_IMAGE_ID, + }, +# endif }; REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index dc875e526..e424ec07c 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -132,7 +132,29 @@ ifeq (${ARM_ETHOSN_NPU_TZMP1},1) else $(error ARM_ETHOSN_NPU_TZMP1 only supported on Juno platform, not ${PLAT}) endif -endif + + ifeq (${TRUSTED_BOARD_BOOT},0) + # We rely on TRUSTED_BOARD_BOOT to prevent the firmware code from being + # tampered with, which is required to protect the confidentiality of protected + # inference data. + $(error ARM_ETHOSN_NPU_TZMP1 is only available if TRUSTED_BOARD_BOOT is enabled) + endif + + # We need the FW certificate and key certificate + $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/npu_fw_key.crt,--npu-fw-key-cert)) + $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/npu_fw_content.crt,--npu-fw-cert)) + # Needed for our OIDs to be available in tbbr_cot_bl2.c + $(eval $(call add_define, PLAT_DEF_OID)) + PLAT_INCLUDES += -I${PLAT_DIR}certificate/include + PLAT_INCLUDES += -Iinclude/drivers/arm/ + + # We need the firmware to be built into the FIP + $(eval $(call TOOL_ADD_IMG,ARM_ETHOSN_NPU_FW,--npu-fw)) + + # Needed so that UUIDs from the FIP are available in BL2 + $(eval $(call add_define,PLAT_DEF_FIP_UUID)) + PLAT_INCLUDES += -I${PLAT_DIR}fip +endif # ARM_ETHOSN_NPU_TZMP1 # Use an implementation of SHA-256 with a smaller memory footprint but reduced # speed. @@ -396,8 +418,11 @@ ifneq (${TRUSTED_BOARD_BOOT},0) ifneq (${COT_DESC_IN_DTB},0) BL2_SOURCES += lib/fconf/fconf_cot_getter.c else - BL2_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \ - drivers/auth/tbbr/tbbr_cot_bl2.c + BL2_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c + # Juno has its own TBBR CoT file for BL2 + ifneq (${PLAT},juno) + BL2_SOURCES += drivers/auth/tbbr/tbbr_cot_bl2.c + endif endif else ifeq (${COT},dualroot) AUTH_SOURCES += drivers/auth/dualroot/cot.c diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index dfaaaae07..743cc90d9 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -68,6 +68,9 @@ const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = { [TOS_FW_CONFIG_ID] = {UUID_TOS_FW_CONFIG}, [NT_FW_CONFIG_ID] = {UUID_NT_FW_CONFIG}, [RMM_IMAGE_ID] = {UUID_REALM_MONITOR_MGMT_FIRMWARE}, +#if ARM_ETHOSN_NPU_TZMP1 + [ARM_ETHOSN_NPU_FW_IMAGE_ID] = {UUID_ETHOSN_FW}, +#endif /* ARM_ETHOSN_NPU_TZMP1 */ #endif /* ARM_IO_IN_DTB */ #if TRUSTED_BOARD_BOOT [TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT}, @@ -88,6 +91,10 @@ const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = { [SIP_SP_CONTENT_CERT_ID] = {UUID_SIP_SECURE_PARTITION_CONTENT_CERT}, [PLAT_SP_CONTENT_CERT_ID] = {UUID_PLAT_SECURE_PARTITION_CONTENT_CERT}, #endif +#if ARM_ETHOSN_NPU_TZMP1 + [ARM_ETHOSN_NPU_FW_KEY_CERT_ID] = {UUID_ETHOSN_FW_KEY_CERTIFICATE}, + [ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID] = {UUID_ETHOSN_FW_CONTENT_CERTIFICATE}, +#endif /* ARM_ETHOSN_NPU_TZMP1 */ #endif /* ARM_IO_IN_DTB */ #endif /* TRUSTED_BOARD_BOOT */ }; @@ -191,6 +198,13 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { (uintptr_t)&arm_uuid_spec[NT_FW_CONFIG_ID], open_fip }, +#if ARM_ETHOSN_NPU_TZMP1 + [ARM_ETHOSN_NPU_FW_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[ARM_ETHOSN_NPU_FW_IMAGE_ID], + open_fip + }, +#endif /* ARM_ETHOSN_NPU_TZMP1 */ #endif /* ARM_IO_IN_DTB */ #if TRUSTED_BOARD_BOOT [TRUSTED_BOOT_FW_CERT_ID] = { @@ -271,6 +285,18 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { open_fip }, #endif +#if ARM_ETHOSN_NPU_TZMP1 + [ARM_ETHOSN_NPU_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[ARM_ETHOSN_NPU_FW_KEY_CERT_ID], + open_fip + }, + [ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID], + open_fip + }, +#endif /* ARM_ETHOSN_NPU_TZMP1 */ #endif /* ARM_IO_IN_DTB */ #endif /* TRUSTED_BOARD_BOOT */ }; @@ -279,6 +305,12 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { #define FCONF_ARM_IO_UUID_NUM_BASE U(10) +#if ARM_ETHOSN_NPU_TZMP1 +#define FCONF_ARM_IO_UUID_NUM_NPU U(1) +#else +#define FCONF_ARM_IO_UUID_NUM_NPU U(0) +#endif + #if TRUSTED_BOARD_BOOT #define FCONF_ARM_IO_UUID_NUM_TBB U(12) #else @@ -291,8 +323,17 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { #define FCONF_ARM_IO_UUID_NUM_SPD U(0) #endif /* TRUSTED_BOARD_BOOT && defined(SPD_spmd) */ +#if TRUSTED_BOARD_BOOT && ARM_ETHOSN_NPU_TZMP1 +#define FCONF_ARM_IO_UUID_NUM_NPU_TBB U(2) +#else +#define FCONF_ARM_IO_UUID_NUM_NPU_TBB U(0) +#endif /* TRUSTED_BOARD_BOOT && ARM_ETHOSN_NPU_TZMP1 */ + #define FCONF_ARM_IO_UUID_NUMBER FCONF_ARM_IO_UUID_NUM_BASE + \ - FCONF_ARM_IO_UUID_NUM_TBB + FCONF_ARM_IO_UUID_NUM_SPD + FCONF_ARM_IO_UUID_NUM_NPU + \ + FCONF_ARM_IO_UUID_NUM_TBB + \ + FCONF_ARM_IO_UUID_NUM_SPD + \ + FCONF_ARM_IO_UUID_NUM_NPU_TBB static io_uuid_spec_t fconf_arm_uuids[FCONF_ARM_IO_UUID_NUMBER]; static OBJECT_POOL_ARRAY(fconf_arm_uuids_pool, fconf_arm_uuids); @@ -314,6 +355,9 @@ static const struct policies_load_info load_info[FCONF_ARM_IO_UUID_NUMBER] = { {SOC_FW_CONFIG_ID, "soc_fw_cfg_uuid"}, {TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"}, {NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"}, +#if ARM_ETHOSN_NPU_TZMP1 + {ARM_ETHOSN_NPU_FW_IMAGE_ID, "arm_ethosn_npu_fw_uuid"}, +#endif /* ARM_ETHOSN_NPU_TZMP1 */ #if TRUSTED_BOARD_BOOT {CCA_CONTENT_CERT_ID, "cca_cert_uuid"}, {CORE_SWD_KEY_CERT_ID, "core_swd_cert_uuid"}, @@ -331,6 +375,10 @@ static const struct policies_load_info load_info[FCONF_ARM_IO_UUID_NUMBER] = { {SIP_SP_CONTENT_CERT_ID, "sip_sp_content_cert_uuid"}, {PLAT_SP_CONTENT_CERT_ID, "plat_sp_content_cert_uuid"}, #endif +#if ARM_ETHOSN_NPU_TZMP1 + {ARM_ETHOSN_NPU_FW_KEY_CERT_ID, "arm_ethosn_npu_fw_key_cert_uuid"}, + {ARM_ETHOSN_NPU_FW_CONTENT_CERT_ID, "arm_ethosn_npu_fw_content_cert_uuid"}, +#endif /* ARM_ETHOSN_NPU_TZMP1 */ #endif /* TRUSTED_BOARD_BOOT */ }; From a2cdbb1df088cde410aea1d5989dfc500aaf7939 Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Wed, 18 Jan 2023 18:05:15 +0100 Subject: [PATCH 15/25] feat(ethos-n): add check for NPU in SiP setup The SiP service in the Arm(R) Ethos(TM)-N NPU driver requires that there is at least one NPU available. If there is no NPU available, the driver is either used incorrectly or the HW config is incorrect. To ensure that the SiP service is not incorrectly used, a setup handler has been added to the service that will validate that there is at least one NPU available. Signed-off-by: Mikael Olsson Change-Id: I8139a652f265cfc0db4a37464f39f1fb92868e10 --- drivers/arm/ethosn/ethosn_smc.c | 10 ++++++++++ include/drivers/arm/ethosn.h | 2 ++ plat/arm/common/arm_sip_svc.c | 10 +++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c index cf3491055..6b1ab85dc 100644 --- a/drivers/arm/ethosn/ethosn_smc.c +++ b/drivers/arm/ethosn/ethosn_smc.c @@ -286,3 +286,13 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, SMC_RET1(handle, SMC_UNK); } } + +int ethosn_smc_setup(void) +{ + if (ETHOSN_NUM_DEVICES == 0U) { + ERROR("ETHOSN: No NPU found\n"); + return ETHOSN_FAILURE; + } + + return 0; +} diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h index 9f1b499d0..01868e37e 100644 --- a/include/drivers/arm/ethosn.h +++ b/include/drivers/arm/ethosn.h @@ -58,6 +58,8 @@ #define ETHOSN_RESET_TYPE_FULL U(0) #define ETHOSN_RESET_TYPE_HALT U(1) +int ethosn_smc_setup(void); + uintptr_t ethosn_smc_handler(uint32_t smc_fid, u_register_t core_addr, u_register_t asset_alloc_idx, diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c index 6456c7841..af8a02fb0 100644 --- a/plat/arm/common/arm_sip_svc.c +++ b/plat/arm/common/arm_sip_svc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019,2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -34,6 +34,14 @@ static int arm_sip_setup(void) #endif /* USE_DEBUGFS */ +#if ARM_ETHOSN_NPU_DRIVER + + if (ethosn_smc_setup() != 0) { + return 1; + } + +#endif /* ARM_ETHOSN_NPU_DRIVER */ + return 0; } From 313b776f851ed184abb265df2b6269fe78f48ecd Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Fri, 13 Jan 2023 09:56:41 +0100 Subject: [PATCH 16/25] feat(ethos-n): add NPU firmware validation When the Arm(R) Ethos(TM)-N NPU driver is built with TZMP1 support, it will now validate the NPU firmware binary that BL2 is expected to load into the protected memory location specified by ARM_ETHOSN_NPU_IMAGE_BASE. Juno has been updated with a new BL31 memory mapping to allow the SiP service to read the protected memory that contains the NPU firmware binary. Signed-off-by: Mikael Olsson Change-Id: I633256ab7dd4f8f5a6f864c8c98a66bf9dfc37f3 --- drivers/arm/ethosn/ethosn_big_fw.c | 57 ++++++++++++++++++++++ drivers/arm/ethosn/ethosn_big_fw.h | 36 ++++++++++++++ drivers/arm/ethosn/ethosn_smc.c | 49 +++++++++++++++++++ plat/arm/board/juno/include/platform_def.h | 9 +++- plat/arm/board/juno/juno_common.c | 3 ++ plat/arm/common/arm_common.mk | 3 ++ 6 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 drivers/arm/ethosn/ethosn_big_fw.c create mode 100644 drivers/arm/ethosn/ethosn_big_fw.h diff --git a/drivers/arm/ethosn/ethosn_big_fw.c b/drivers/arm/ethosn/ethosn_big_fw.c new file mode 100644 index 000000000..9bb33eac8 --- /dev/null +++ b/drivers/arm/ethosn/ethosn_big_fw.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include "ethosn_big_fw.h" + +/* Magic (FourCC) number to identify the big firmware binary */ +#define ETHOSN_BIG_FW_MAGIC ('E' | ('N' << 8) | ('F' << 16) | ('W' << 24)) + +/* Supported big firmware version */ +#define ETHOSN_BIG_FW_VERSION_MAJOR 9 + +#define ETHOSN_ARCH_VER_MAJOR_MASK U(0xF000) +#define ETHOSN_ARCH_VER_MAJOR_SHIFT U(0xC) +#define ETHOSN_ARCH_VER_MINOR_MASK U(0xF00) +#define ETHOSN_ARCH_VER_MINOR_SHIFT U(0x8) +#define ETHOSN_ARCH_VER_REV_MASK U(0xFF) + +/* Convert Arm(R) Ethos(TM)-N NPU architecture version to big firmware format */ +#define ETHOSN_BIG_FW_FORMAT_ARCH_VER(arch_ver) \ + (arch_ver & ETHOSN_ARCH_VER_MAJOR_MASK) << ETHOSN_ARCH_VER_MAJOR_SHIFT | \ + (arch_ver & ETHOSN_ARCH_VER_MINOR_MASK) << ETHOSN_ARCH_VER_MINOR_SHIFT | \ + (arch_ver & ETHOSN_ARCH_VER_REV_MASK) + + +bool ethosn_big_fw_verify_header(const struct ethosn_big_fw *big_fw, + uint32_t npu_arch_ver) +{ + const uint32_t arch_ver = ETHOSN_BIG_FW_FORMAT_ARCH_VER(npu_arch_ver); + + if (big_fw->fw_magic != ETHOSN_BIG_FW_MAGIC) { + ERROR("ETHOSN: Unable to find firmware. Invalid magic value: 0x%02x\n", + big_fw->fw_magic); + + return false; + } + + if (big_fw->fw_ver_major != ETHOSN_BIG_FW_VERSION_MAJOR) { + ERROR("ETHOSN: Unsupported firmware version: %u.%u.%u. Expected Version %u.x.x.\n", + big_fw->fw_ver_major, big_fw->fw_ver_minor, + big_fw->fw_ver_patch, ETHOSN_BIG_FW_VERSION_MAJOR); + + return false; + } + + if (big_fw->arch_min > arch_ver || arch_ver > big_fw->arch_max) { + ERROR("ETHOSN: Firmware is not compatbile with architecture version: 0x%02x\n", + npu_arch_ver); + return false; + } + + return true; +} diff --git a/drivers/arm/ethosn/ethosn_big_fw.h b/drivers/arm/ethosn/ethosn_big_fw.h new file mode 100644 index 000000000..a3213229f --- /dev/null +++ b/drivers/arm/ethosn/ethosn_big_fw.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +/* + * Big FW binary structure. + * Must be kept in sync with the Arm(R) Ethos(TM)-N NPU firmware binary layout. + */ +struct ethosn_big_fw { + uint32_t fw_magic; + uint32_t fw_ver_major; + uint32_t fw_ver_minor; + uint32_t fw_ver_patch; + uint32_t arch_min; + uint32_t arch_max; + uint32_t offset; + uint32_t size; + uint32_t code_offset; + uint32_t code_size; + uint32_t ple_offset; + uint32_t ple_size; + uint32_t vector_table_offset; + uint32_t vector_table_size; + uint32_t unpriv_stack_offset; + uint32_t unpriv_stack_size; + uint32_t priv_stack_offset; + uint32_t priv_stack_size; +} __packed; + +bool ethosn_big_fw_verify_header(const struct ethosn_big_fw *big_fw, + uint32_t npu_arch_ver); diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c index 6b1ab85dc..e314577a3 100644 --- a/drivers/arm/ethosn/ethosn_smc.c +++ b/drivers/arm/ethosn/ethosn_smc.c @@ -17,6 +17,10 @@ #include +#if ARM_ETHOSN_NPU_TZMP1 +#include "ethosn_big_fw.h" +#endif + /* * Number of Arm(R) Ethos(TM)-N NPU (NPU) devices available */ @@ -56,10 +60,18 @@ #define SEC_MMUSID_REG_BASE U(0x3008) #define SEC_MMUSID_OFFSET U(0x1000) +#define SEC_NPU_ID_REG U(0xF000) +#define SEC_NPU_ID_ARCH_VER_SHIFT U(0X10) + #define INPUT_STREAM_INDEX U(0x6) #define INTERMEDIATE_STREAM_INDEX U(0x7) #define OUTPUT_STREAM_INDEX U(0x8) +#if ARM_ETHOSN_NPU_TZMP1 +CASSERT(ARM_ETHOSN_NPU_FW_IMAGE_BASE > 0U, assert_ethosn_invalid_fw_image_base); +static const struct ethosn_big_fw *big_fw; +#endif + static bool ethosn_get_device_and_core(uintptr_t core_addr, const struct ethosn_device_t **dev_match, const struct ethosn_core_t **core_match) @@ -86,6 +98,14 @@ static bool ethosn_get_device_and_core(uintptr_t core_addr, } #if ARM_ETHOSN_NPU_TZMP1 +static uint32_t ethosn_core_read_arch_version(uintptr_t core_addr) +{ + uint32_t npu_id = mmio_read_32(ETHOSN_CORE_SEC_REG(core_addr, + SEC_NPU_ID_REG)); + + return (npu_id >> SEC_NPU_ID_ARCH_VER_SHIFT); +} + static void ethosn_configure_stream_nsaid(const struct ethosn_core_t *core, bool is_protected) { @@ -289,10 +309,39 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, int ethosn_smc_setup(void) { +#if ARM_ETHOSN_NPU_TZMP1 + struct ethosn_device_t *dev; + uint32_t arch_ver; +#endif + if (ETHOSN_NUM_DEVICES == 0U) { ERROR("ETHOSN: No NPU found\n"); return ETHOSN_FAILURE; } +#if ARM_ETHOSN_NPU_TZMP1 + + /* Only one NPU core is supported in the TZMP1 setup */ + if ((ETHOSN_NUM_DEVICES != 1U) || + (ETHOSN_GET_DEVICE(0U)->num_cores != 1U)) { + ERROR("ETHOSN: TZMP1 doesn't support multiple NPU cores\n"); + return ETHOSN_FAILURE; + } + + dev = ETHOSN_GET_DEVICE(0U); + arch_ver = ethosn_core_read_arch_version(dev->cores[0U].addr); + big_fw = (struct ethosn_big_fw *)ARM_ETHOSN_NPU_FW_IMAGE_BASE; + + if (!ethosn_big_fw_verify_header(big_fw, arch_ver)) { + return ETHOSN_FAILURE; + } + + NOTICE("ETHOSN: TZMP1 setup succeeded with firmware version %u.%u.%u\n", + big_fw->fw_ver_major, big_fw->fw_ver_minor, + big_fw->fw_ver_patch); +#else + NOTICE("ETHOSN: Setup succeeded\n"); +#endif + return 0; } diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index ef37104e9..5eaec698d 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -66,6 +66,11 @@ MT_MEMORY | MT_RO | MT_NS) #ifdef JUNO_ETHOSN_TZMP1 +#define JUNO_ETHOSN_PROT_FW_RO MAP_REGION_FLAT( \ + JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE, \ + JUNO_ETHOSN_FW_TZC_PROT_DRAM2_SIZE, \ + MT_RO_DATA | MT_SECURE) + #define JUNO_ETHOSN_PROT_FW_RW MAP_REGION_FLAT( \ JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE, \ JUNO_ETHOSN_FW_TZC_PROT_DRAM2_SIZE, \ @@ -126,8 +131,8 @@ #endif #ifdef IMAGE_BL31 -# define PLAT_ARM_MMAP_ENTRIES 7 -# define MAX_XLAT_TABLES 5 +# define PLAT_ARM_MMAP_ENTRIES 8 +# define MAX_XLAT_TABLES 6 #endif #ifdef IMAGE_BL32 diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c index 584b2ed72..02614da4a 100644 --- a/plat/arm/board/juno/juno_common.c +++ b/plat/arm/board/juno/juno_common.c @@ -79,6 +79,9 @@ const mmap_region_t plat_arm_mmap[] = { #endif SOC_CSS_MAP_DEVICE, ARM_DTB_DRAM_NS, +#ifdef JUNO_ETHOSN_TZMP1 + JUNO_ETHOSN_PROT_FW_RO, +#endif {0} }; #endif diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index e424ec07c..fca6f4f95 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -359,6 +359,9 @@ ifeq (${ARM_ETHOSN_NPU_DRIVER},1) ARM_SVC_HANDLER_SRCS += plat/arm/common/fconf/fconf_ethosn_getter.c \ drivers/delay_timer/delay_timer.c \ drivers/arm/ethosn/ethosn_smc.c +ifeq (${ARM_ETHOSN_NPU_TZMP1},1) +ARM_SVC_HANDLER_SRCS += drivers/arm/ethosn/ethosn_big_fw.c +endif endif ifeq (${ARCH}, aarch64) From 18a6b79c50ca88510c013fc5fba5200473152088 Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Fri, 27 Jan 2023 18:26:36 +0100 Subject: [PATCH 17/25] refactor(ethos-n): split up SMC call handling Doing all the SMC call handling in a single function and using specific names for the x1-4 parameters is no longer practical for upcoming additions to the SiP service. Handling of the different SMC functions have therefore been split into separate functions. Signed-off-by: Mikael Olsson Change-Id: If28da8df0f13c449d1fdb2bd9d792d818ec5e1af --- drivers/arm/ethosn/ethosn_smc.c | 176 +++++++++++++++++++------------- 1 file changed, 105 insertions(+), 71 deletions(-) diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c index e314577a3..124de9243 100644 --- a/drivers/arm/ethosn/ethosn_smc.c +++ b/drivers/arm/ethosn/ethosn_smc.c @@ -188,13 +188,13 @@ static int ethosn_core_is_sleeping(uintptr_t core_addr) return ((mmio_read_32(sysctrl0_reg) & sleeping_mask) == sleeping_mask); } -static bool ethosn_reset(uintptr_t core_addr, int hard_reset) +static bool ethosn_core_reset(uintptr_t core_addr, bool hard_reset) { unsigned int timeout; const uintptr_t sysctrl0_reg = ETHOSN_CORE_SEC_REG(core_addr, SEC_SYSCTRL0_REG); - const uint32_t reset_val = (hard_reset != 0) ? SEC_SYSCTRL0_HARD_RESET - : SEC_SYSCTRL0_SOFT_RESET; + const uint32_t reset_val = hard_reset ? SEC_SYSCTRL0_HARD_RESET : + SEC_SYSCTRL0_SOFT_RESET; mmio_write_32(sysctrl0_reg, reset_val); @@ -212,18 +212,107 @@ static bool ethosn_reset(uintptr_t core_addr, int hard_reset) return timeout < ETHOSN_RESET_TIMEOUT_US; } +static int ethosn_core_full_reset(const struct ethosn_device_t *device, + const struct ethosn_core_t *core, + bool hard_reset, + u_register_t asset_alloc_idx, + u_register_t is_protected) +{ + if (!device->has_reserved_memory && + asset_alloc_idx >= device->num_allocators) { + WARN("ETHOSN: Unknown asset allocator index given to SMC call.\n"); + return ETHOSN_UNKNOWN_ALLOCATOR_IDX; + } + + if (!ethosn_core_reset(core->addr, hard_reset)) { + return ETHOSN_FAILURE; + } + + if (!device->has_reserved_memory) { + ethosn_configure_smmu_streams(device, core, asset_alloc_idx); + +#if ARM_ETHOSN_NPU_TZMP1 + ethosn_configure_stream_nsaid(core, is_protected); +#endif + } + + ethosn_delegate_to_ns(core->addr); + + return ETHOSN_SUCCESS; +} + +static uintptr_t ethosn_smc_core_reset_handler(const struct ethosn_device_t *device, + const struct ethosn_core_t *core, + bool hard_reset, + u_register_t asset_alloc_idx, + u_register_t reset_type, + u_register_t is_protected, + void *handle) +{ + int ret; + + switch (reset_type) { + case ETHOSN_RESET_TYPE_FULL: + ret = ethosn_core_full_reset(device, core, hard_reset, + asset_alloc_idx, is_protected); + break; + case ETHOSN_RESET_TYPE_HALT: + ret = ethosn_core_reset(core->addr, hard_reset) ? ETHOSN_SUCCESS : ETHOSN_FAILURE; + break; + default: + WARN("ETHOSN: Invalid reset type given to SMC call.\n"); + ret = ETHOSN_INVALID_PARAMETER; + break; + } + + SMC_RET1(handle, ret); +} + +static uintptr_t ethosn_smc_core_handler(uint32_t fid, + u_register_t core_addr, + u_register_t asset_alloc_idx, + u_register_t reset_type, + u_register_t is_protected, + void *handle) +{ + bool hard_reset = false; + const struct ethosn_device_t *device = NULL; + const struct ethosn_core_t *core = NULL; + + if (!ethosn_get_device_and_core(core_addr, &device, &core)) { + SMC_RET1(handle, ETHOSN_UNKNOWN_CORE_ADDRESS); + } + + switch (fid) { + case ETHOSN_FNUM_IS_SEC: + SMC_RET1(handle, ethosn_is_sec(core->addr)); + case ETHOSN_FNUM_IS_SLEEPING: + SMC_RET1(handle, ethosn_core_is_sleeping(core->addr)); + case ETHOSN_FNUM_HARD_RESET: + hard_reset = true; + /* Fallthrough */ + case ETHOSN_FNUM_SOFT_RESET: + return ethosn_smc_core_reset_handler(device, core, + hard_reset, + asset_alloc_idx, + reset_type, + is_protected, + handle); + default: + WARN("ETHOSN: Unimplemented SMC call: 0x%x\n", fid); + SMC_RET1(handle, SMC_UNK); + } +} + uintptr_t ethosn_smc_handler(uint32_t smc_fid, - u_register_t core_addr, - u_register_t asset_alloc_idx, - u_register_t reset_type, - u_register_t is_protected, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, void *cookie, void *handle, u_register_t flags) { - int hard_reset = 0; - const struct ethosn_device_t *device = NULL; - const struct ethosn_core_t *core = NULL; const uint32_t fid = smc_fid & FUNCID_NUM_MASK; /* Only SiP fast calls are expected */ @@ -234,10 +323,10 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, /* Truncate parameters to 32-bits for SMC32 */ if (GET_SMC_CC(smc_fid) == SMC_32) { - core_addr &= 0xFFFFFFFF; - asset_alloc_idx &= 0xFFFFFFFF; - reset_type &= 0xFFFFFFFF; - is_protected &= 0xFFFFFFFF; + x1 &= 0xFFFFFFFF; + x2 &= 0xFFFFFFFF; + x3 &= 0xFFFFFFFF; + x4 &= 0xFFFFFFFF; } if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_IS_SLEEPING)) { @@ -245,66 +334,11 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, SMC_RET1(handle, SMC_UNK); } - /* Commands that do not require a valid core address */ - switch (fid) { - case ETHOSN_FNUM_VERSION: + if (fid == ETHOSN_FNUM_VERSION) { SMC_RET2(handle, ETHOSN_VERSION_MAJOR, ETHOSN_VERSION_MINOR); } - if (!ethosn_get_device_and_core(core_addr, &device, &core)) { - SMC_RET1(handle, ETHOSN_UNKNOWN_CORE_ADDRESS); - } - - /* Commands that require a valid core address */ - switch (fid) { - case ETHOSN_FNUM_IS_SEC: - SMC_RET1(handle, ethosn_is_sec(core->addr)); - case ETHOSN_FNUM_IS_SLEEPING: - SMC_RET1(handle, ethosn_core_is_sleeping(core->addr)); - } - - if (!device->has_reserved_memory && - asset_alloc_idx >= device->num_allocators) { - WARN("ETHOSN: Unknown asset allocator index given to SMC call.\n"); - SMC_RET1(handle, ETHOSN_UNKNOWN_ALLOCATOR_IDX); - } - - if (reset_type > ETHOSN_RESET_TYPE_HALT) { - WARN("ETHOSN: Invalid reset type given to SMC call.\n"); - SMC_RET1(handle, ETHOSN_INVALID_PARAMETER); - } - - /* - * Commands that require a valid device, reset type, - * core and asset allocator - */ - switch (fid) { - case ETHOSN_FNUM_HARD_RESET: - hard_reset = 1; - /* Fallthrough */ - case ETHOSN_FNUM_SOFT_RESET: - if (!ethosn_reset(core->addr, hard_reset)) { - SMC_RET1(handle, ETHOSN_FAILURE); - } - - if (reset_type == ETHOSN_RESET_TYPE_FULL) { - if (!device->has_reserved_memory) { - ethosn_configure_smmu_streams(device, core, - asset_alloc_idx); - - #if ARM_ETHOSN_NPU_TZMP1 - ethosn_configure_stream_nsaid(core, - is_protected); - #endif - } - - ethosn_delegate_to_ns(core->addr); - } - SMC_RET1(handle, ETHOSN_SUCCESS); - default: - WARN("ETHOSN: Unimplemented SMC call: 0x%x\n", fid); - SMC_RET1(handle, SMC_UNK); - } + return ethosn_smc_core_handler(fid, x1, x2, x3, x4, handle); } int ethosn_smc_setup(void) From e9812ddca6e72c0501ef1e84753f335dcafb74cd Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Fri, 27 Jan 2023 18:53:48 +0100 Subject: [PATCH 18/25] feat(ethos-n): add SMC call to get FW properties When the Arm(R) Ethos(TM)-N NPU firmware is loaded by BL2 into protected memory, the Linux kernel NPU driver cannot access the firmware. To still allow the kernel driver to access some information about the firmware, SMC calls have been added so it can check compatibility and get the necessary information to map the firmware into the SMMU for the NPU. The API version has been given a minor version bump with this change to indicate the added functionality. Signed-off-by: Mikael Olsson Change-Id: Idb076b7bcf54ed7e8eb39be80114dc1d1c45336d --- drivers/arm/ethosn/ethosn_smc.c | 43 +++++++++++++++++++++++++++++++-- include/drivers/arm/ethosn.h | 11 +++++++-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c index 124de9243..b5cb0408f 100644 --- a/drivers/arm/ethosn/ethosn_smc.c +++ b/drivers/arm/ethosn/ethosn_smc.c @@ -34,6 +34,10 @@ #define ETHOSN_CORE_SEC_REG(core_addr, reg_offset) \ (core_addr + reg_offset) +#define ETHOSN_FW_VA_BASE 0x20000000UL +#define ETHOSN_WORKING_DATA_VA_BASE 0x40000000UL +#define ETHOSN_COMMAND_STREAM_VA_BASE 0x60000000UL + /* Reset timeout in us */ #define ETHOSN_RESET_TIMEOUT_US U(10 * 1000 * 1000) #define ETHOSN_RESET_WAIT_US U(1) @@ -304,6 +308,38 @@ static uintptr_t ethosn_smc_core_handler(uint32_t fid, } } +static uintptr_t ethosn_smc_fw_prop_handler(u_register_t fw_property, + void *handle) +{ +#if ARM_ETHOSN_NPU_TZMP1 + switch (fw_property) { + case ETHOSN_FW_PROP_VERSION: + SMC_RET4(handle, ETHOSN_SUCCESS, + big_fw->fw_ver_major, + big_fw->fw_ver_minor, + big_fw->fw_ver_patch); + case ETHOSN_FW_PROP_MEM_INFO: + SMC_RET3(handle, ETHOSN_SUCCESS, + ((void *)big_fw) + big_fw->offset, + big_fw->size); + case ETHOSN_FW_PROP_OFFSETS: + SMC_RET3(handle, ETHOSN_SUCCESS, + big_fw->ple_offset, + big_fw->unpriv_stack_offset); + case ETHOSN_FW_PROP_VA_MAP: + SMC_RET4(handle, ETHOSN_SUCCESS, + ETHOSN_FW_VA_BASE, + ETHOSN_WORKING_DATA_VA_BASE, + ETHOSN_COMMAND_STREAM_VA_BASE); + default: + WARN("ETHOSN: Unknown firmware property\n"); + SMC_RET1(handle, ETHOSN_INVALID_PARAMETER); + } +#else + SMC_RET1(handle, ETHOSN_NOT_SUPPORTED); +#endif +} + uintptr_t ethosn_smc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, @@ -329,13 +365,16 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, x4 &= 0xFFFFFFFF; } - if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_IS_SLEEPING)) { + if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_GET_FW_PROP)) { WARN("ETHOSN: Unknown SMC call: 0x%x\n", smc_fid); SMC_RET1(handle, SMC_UNK); } - if (fid == ETHOSN_FNUM_VERSION) { + switch (fid) { + case ETHOSN_FNUM_VERSION: SMC_RET2(handle, ETHOSN_VERSION_MAJOR, ETHOSN_VERSION_MINOR); + case ETHOSN_FNUM_GET_FW_PROP: + return ethosn_smc_fw_prop_handler(x1, handle); } return ethosn_smc_core_handler(fid, x1, x2, x3, x4, handle); diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h index 01868e37e..cfdad8ec4 100644 --- a/include/drivers/arm/ethosn.h +++ b/include/drivers/arm/ethosn.h @@ -15,7 +15,14 @@ #define ETHOSN_FNUM_HARD_RESET U(0x52) #define ETHOSN_FNUM_SOFT_RESET U(0x53) #define ETHOSN_FNUM_IS_SLEEPING U(0x54) -/* 0x55-0x5F reserved for future use */ +#define ETHOSN_FNUM_GET_FW_PROP U(0x55) +/* 0x56-0x5F reserved for future use */ + +/* Properties for ETHOSN_FNUM_TZMP_GET_FW_PROP */ +#define ETHOSN_FW_PROP_VERSION U(0xF00) +#define ETHOSN_FW_PROP_MEM_INFO U(0xF01) +#define ETHOSN_FW_PROP_OFFSETS U(0xF02) +#define ETHOSN_FW_PROP_VA_MAP U(0xF03) /* SMC64 function IDs */ #define ETHOSN_FID_64(func_num) U(0xC2000000 | func_num) @@ -40,7 +47,7 @@ /* Service version */ #define ETHOSN_VERSION_MAJOR U(2) -#define ETHOSN_VERSION_MINOR U(3) +#define ETHOSN_VERSION_MINOR U(4) /* Return codes for function calls */ #define ETHOSN_SUCCESS 0 From 7820777fa3c8ca454ab40d5d8a8ba0e311bbb6f9 Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Fri, 10 Feb 2023 11:36:19 +0100 Subject: [PATCH 19/25] feat(ethos-n): add event and aux control support The SiP service for the Arm(R) Ethos(TM)-N NPU driver will now handle setting up the NPU's event and aux control registers during the SMC reset call. The aux control register will no longer be accessible by the non-secure world. The API version has been given a minor bump with this change to indicate the added functionality. Signed-off-by: Mikael Olsson Change-Id: I5b099e25978aa4089c384eb17c5060c5b4eaf373 --- drivers/arm/ethosn/ethosn_big_fw.c | 2 +- drivers/arm/ethosn/ethosn_smc.c | 61 ++++++++++++++++++++++++++++-- include/drivers/arm/ethosn.h | 3 +- 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/drivers/arm/ethosn/ethosn_big_fw.c b/drivers/arm/ethosn/ethosn_big_fw.c index 9bb33eac8..3a53e0e60 100644 --- a/drivers/arm/ethosn/ethosn_big_fw.c +++ b/drivers/arm/ethosn/ethosn_big_fw.c @@ -12,7 +12,7 @@ #define ETHOSN_BIG_FW_MAGIC ('E' | ('N' << 8) | ('F' << 16) | ('W' << 24)) /* Supported big firmware version */ -#define ETHOSN_BIG_FW_VERSION_MAJOR 9 +#define ETHOSN_BIG_FW_VERSION_MAJOR 10 #define ETHOSN_ARCH_VER_MAJOR_MASK U(0xF000) #define ETHOSN_ARCH_VER_MAJOR_SHIFT U(0xC) diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c index b5cb0408f..4a71e81b9 100644 --- a/drivers/arm/ethosn/ethosn_smc.c +++ b/drivers/arm/ethosn/ethosn_smc.c @@ -42,8 +42,16 @@ #define ETHOSN_RESET_TIMEOUT_US U(10 * 1000 * 1000) #define ETHOSN_RESET_WAIT_US U(1) +#define ETHOSN_AUX_FEAT_LEVEL_IRQ U(0x1) +#define ETHOSN_AUX_FEAT_STASHING U(0x2) + +#define SEC_AUXCTLR_REG U(0x0024) +#define SEC_AUXCTLR_VAL U(0x80) +#define SEC_AUXCTLR_LEVEL_IRQ_VAL U(0x04) +#define SEC_AUXCTLR_STASHING_VAL U(0xA5000000) + #define SEC_DEL_REG U(0x0004) -#define SEC_DEL_VAL U(0x81C) +#define SEC_DEL_VAL U(0x80C) #define SEC_DEL_EXCC_MASK U(0x20) #define SEC_SECCTLR_REG U(0x0010) @@ -58,6 +66,9 @@ #define SEC_SYSCTRL0_SOFT_RESET U(3U << 29) #define SEC_SYSCTRL0_HARD_RESET U(1U << 31) +#define SEC_SYSCTRL1_REG U(0x001C) +#define SEC_SYSCTRL1_VAL U(0x180110) + #define SEC_NSAID_REG_BASE U(0x3004) #define SEC_NSAID_OFFSET U(0x1000) @@ -132,6 +143,35 @@ static void ethosn_configure_stream_nsaid(const struct ethosn_core_t *core, } #endif +static void ethosn_configure_events(uintptr_t core_addr) +{ + mmio_write_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_SYSCTRL1_REG), SEC_SYSCTRL1_VAL); +} + +static bool ethosn_configure_aux_features(const struct ethosn_device_t *device, + uintptr_t core_addr, + uint32_t features) +{ + uint32_t val = SEC_AUXCTLR_VAL; + + if (features & ETHOSN_AUX_FEAT_LEVEL_IRQ) { + val |= SEC_AUXCTLR_LEVEL_IRQ_VAL; + } + + if (features & ETHOSN_AUX_FEAT_STASHING) { + /* Stashing can't be used with reserved memory */ + if (device->has_reserved_memory) { + return false; + } + + val |= SEC_AUXCTLR_STASHING_VAL; + } + + mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_AUXCTLR_REG), val); + + return true; +} + static void ethosn_configure_smmu_streams(const struct ethosn_device_t *device, const struct ethosn_core_t *core, uint32_t asset_alloc_idx) @@ -220,7 +260,8 @@ static int ethosn_core_full_reset(const struct ethosn_device_t *device, const struct ethosn_core_t *core, bool hard_reset, u_register_t asset_alloc_idx, - u_register_t is_protected) + u_register_t is_protected, + u_register_t aux_features) { if (!device->has_reserved_memory && asset_alloc_idx >= device->num_allocators) { @@ -232,6 +273,12 @@ static int ethosn_core_full_reset(const struct ethosn_device_t *device, return ETHOSN_FAILURE; } + if (!ethosn_configure_aux_features(device, core->addr, aux_features)) { + return ETHOSN_INVALID_CONFIGURATION; + } + + ethosn_configure_events(core->addr); + if (!device->has_reserved_memory) { ethosn_configure_smmu_streams(device, core, asset_alloc_idx); @@ -251,6 +298,7 @@ static uintptr_t ethosn_smc_core_reset_handler(const struct ethosn_device_t *dev u_register_t asset_alloc_idx, u_register_t reset_type, u_register_t is_protected, + u_register_t aux_features, void *handle) { int ret; @@ -258,7 +306,8 @@ static uintptr_t ethosn_smc_core_reset_handler(const struct ethosn_device_t *dev switch (reset_type) { case ETHOSN_RESET_TYPE_FULL: ret = ethosn_core_full_reset(device, core, hard_reset, - asset_alloc_idx, is_protected); + asset_alloc_idx, is_protected, + aux_features); break; case ETHOSN_RESET_TYPE_HALT: ret = ethosn_core_reset(core->addr, hard_reset) ? ETHOSN_SUCCESS : ETHOSN_FAILURE; @@ -277,6 +326,7 @@ static uintptr_t ethosn_smc_core_handler(uint32_t fid, u_register_t asset_alloc_idx, u_register_t reset_type, u_register_t is_protected, + u_register_t aux_features, void *handle) { bool hard_reset = false; @@ -301,6 +351,7 @@ static uintptr_t ethosn_smc_core_handler(uint32_t fid, asset_alloc_idx, reset_type, is_protected, + aux_features, handle); default: WARN("ETHOSN: Unimplemented SMC call: 0x%x\n", fid); @@ -377,7 +428,9 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, return ethosn_smc_fw_prop_handler(x1, handle); } - return ethosn_smc_core_handler(fid, x1, x2, x3, x4, handle); + return ethosn_smc_core_handler(fid, x1, x2, x3, x4, + SMC_GET_GP(handle, CTX_GPREG_X5), + handle); } int ethosn_smc_setup(void) diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h index cfdad8ec4..c8e2df07c 100644 --- a/include/drivers/arm/ethosn.h +++ b/include/drivers/arm/ethosn.h @@ -47,7 +47,7 @@ /* Service version */ #define ETHOSN_VERSION_MAJOR U(2) -#define ETHOSN_VERSION_MINOR U(4) +#define ETHOSN_VERSION_MINOR U(5) /* Return codes for function calls */ #define ETHOSN_SUCCESS 0 @@ -57,6 +57,7 @@ #define ETHOSN_FAILURE -4 #define ETHOSN_UNKNOWN_CORE_ADDRESS -5 #define ETHOSN_UNKNOWN_ALLOCATOR_IDX -6 +#define ETHOSN_INVALID_CONFIGURATION -7 /* * Argument types for soft and hard resets to indicate whether to reset From a19a0241a6f1573e11d4d747dabb756d15ac4801 Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Fri, 10 Feb 2023 11:39:40 +0100 Subject: [PATCH 20/25] feat(ethos-n): add reserved memory address support The FCONF parsing of the HW_CONFIG for the Arm(R) Ethos(TM)-N NPU now supports reading the address of the reserved memory setup for the NPU so the address can be used in the SiP service for the NPU. Change-Id: I0968255a966e84896b00ea935d6aa3d5232c5f7b Signed-off-by: Mikael Olsson --- include/plat/arm/common/fconf_ethosn_getter.h | 3 +- plat/arm/common/fconf/fconf_ethosn_getter.c | 47 ++++++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/include/plat/arm/common/fconf_ethosn_getter.h b/include/plat/arm/common/fconf_ethosn_getter.h index 5b9a7ed9d..cafbc3efa 100644 --- a/include/plat/arm/common/fconf_ethosn_getter.h +++ b/include/plat/arm/common/fconf_ethosn_getter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, Arm Limited. All rights reserved. + * Copyright (c) 2021-2023, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -45,6 +45,7 @@ struct ethosn_core_t { struct ethosn_device_t { bool has_reserved_memory; + uint64_t reserved_memory_addr; uint32_t num_cores; struct ethosn_core_t cores[ETHOSN_DEV_CORE_NUM_MAX]; uint32_t num_allocators; diff --git a/plat/arm/common/fconf/fconf_ethosn_getter.c b/plat/arm/common/fconf/fconf_ethosn_getter.c index 251471e63..7394e4241 100644 --- a/plat/arm/common/fconf/fconf_ethosn_getter.c +++ b/plat/arm/common/fconf/fconf_ethosn_getter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, Arm Limited. All rights reserved. + * Copyright (c) 2021-2023, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,6 +20,38 @@ struct ethosn_sub_allocator_t { uint32_t stream_id; }; +static int fdt_node_read_reserved_memory_addr(const void *fdt, + int dev_node, + uint64_t *reserved_mem_addrs) +{ + uintptr_t addr; + uint32_t phandle; + int err; + int mem_node; + + err = fdt_read_uint32(fdt, dev_node, "memory-region", &phandle); + if (err != 0) { + ERROR("FCONF: Failed to get reserved memory phandle\n"); + return err; + } + + mem_node = fdt_node_offset_by_phandle(fdt, phandle); + if (mem_node < 0) { + ERROR("FCONF: Failed to find reserved memory node from phandle\n"); + return mem_node; + } + + err = fdt_get_reg_props_by_index(fdt, mem_node, 0U, &addr, NULL); + if (err != 0) { + ERROR("FCONF: Failed to read reserved memory address\n"); + return err; + } + + *reserved_mem_addrs = addr; + + return 0; +} + static bool fdt_node_has_reserved_memory(const void *fdt, int dev_node) { return fdt_get_property(fdt, dev_node, "memory-region", NULL) != NULL; @@ -233,8 +265,10 @@ int fconf_populate_ethosn_config(uintptr_t config) struct ethosn_device_t *dev = ðosn_config.devices[dev_count]; uint32_t dev_asset_alloc_count = 0U; uint32_t dev_core_count = 0U; + uint64_t reserved_memory_addr = 0U; bool has_reserved_memory; int sub_node; + int err; if (!fdt_node_is_enabled(hw_conf_dtb, ethosn_node)) { continue; @@ -246,8 +280,16 @@ int fconf_populate_ethosn_config(uintptr_t config) } has_reserved_memory = fdt_node_has_reserved_memory(hw_conf_dtb, ethosn_node); + if (has_reserved_memory) { + err = fdt_node_read_reserved_memory_addr(hw_conf_dtb, + ethosn_node, + &reserved_memory_addr); + if (err != 0) { + return err; + } + } + fdt_for_each_subnode(sub_node, hw_conf_dtb, ethosn_node) { - int err; if (!fdt_node_is_enabled(hw_conf_dtb, sub_node)) { /* Ignore disabled sub node */ @@ -323,6 +365,7 @@ int fconf_populate_ethosn_config(uintptr_t config) dev->num_cores = dev_core_count; dev->num_allocators = dev_asset_alloc_count; dev->has_reserved_memory = has_reserved_memory; + dev->reserved_memory_addr = reserved_memory_addr; ++dev_count; } From e64abe7bdaeed99093ae5b4aab8956a04ff4075a Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Fri, 10 Feb 2023 16:59:03 +0100 Subject: [PATCH 21/25] feat(ethos-n): add stream extends and attr support The SiP service for the Arm(R) Ethos(TM)-N NPU driver will now handle setting up the address extension and attribute control for the NPU's streams. The non-secure world will still be allowed to read the address extension for stream0 but non-secure access to all other streams have been removed. The API version has been given a minor bump with this change to indicate the added functionality. Signed-off-by: Mikael Olsson Change-Id: I2b041ca4a0a2b5cd6344a4ae144f75e137c72592 --- drivers/arm/ethosn/ethosn_big_fw.c | 2 +- drivers/arm/ethosn/ethosn_smc.c | 58 ++++++++++++++++++++++++++++-- include/drivers/arm/ethosn.h | 2 +- 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/drivers/arm/ethosn/ethosn_big_fw.c b/drivers/arm/ethosn/ethosn_big_fw.c index 3a53e0e60..628f5d976 100644 --- a/drivers/arm/ethosn/ethosn_big_fw.c +++ b/drivers/arm/ethosn/ethosn_big_fw.c @@ -12,7 +12,7 @@ #define ETHOSN_BIG_FW_MAGIC ('E' | ('N' << 8) | ('F' << 16) | ('W' << 24)) /* Supported big firmware version */ -#define ETHOSN_BIG_FW_VERSION_MAJOR 10 +#define ETHOSN_BIG_FW_VERSION_MAJOR 11 #define ETHOSN_ARCH_VER_MAJOR_MASK U(0xF000) #define ETHOSN_ARCH_VER_MAJOR_SHIFT U(0xC) diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c index 4a71e81b9..d1b21e045 100644 --- a/drivers/arm/ethosn/ethosn_smc.c +++ b/drivers/arm/ethosn/ethosn_smc.c @@ -58,8 +58,8 @@ /* Set bit[10] = 1 to workaround erratum 2838783 */ #define SEC_SECCTLR_VAL U(0x403) -#define SEC_DEL_ADDR_EXT_REG U(0x201C) -#define SEC_DEL_ADDR_EXT_VAL U(0x15) +#define SEC_DEL_ADDR_EXT_REG U(0x201C) +#define SEC_DEL_ADDR_EXT_VAL U(0x1) #define SEC_SYSCTRL0_REG U(0x0018) #define SEC_SYSCTRL0_SLEEPING U(1U << 4) @@ -75,6 +75,16 @@ #define SEC_MMUSID_REG_BASE U(0x3008) #define SEC_MMUSID_OFFSET U(0x1000) +#define SEC_ADDR_EXT_REG_BASE U(0x3018) +#define SEC_ADDR_EXT_OFFSET U(0x1000) +#define SEC_ADDR_EXT_SHIFT U(0x14) +#define SEC_ADDR_EXT_MASK U(0x1FFFFE00) + +#define SEC_ATTR_CTLR_REG_BASE U(0x3010) +#define SEC_ATTR_CTLR_OFFSET U(0x1000) +#define SEC_ATTR_CTLR_NUM U(9) +#define SEC_ATTR_CTLR_VAL U(0x1) + #define SEC_NPU_ID_REG U(0xF000) #define SEC_NPU_ID_ARCH_VER_SHIFT U(0X10) @@ -82,6 +92,9 @@ #define INTERMEDIATE_STREAM_INDEX U(0x7) #define OUTPUT_STREAM_INDEX U(0x8) +#define TO_EXTEND_ADDR(addr) \ + ((addr >> SEC_ADDR_EXT_SHIFT) & SEC_ADDR_EXT_MASK) + #if ARM_ETHOSN_NPU_TZMP1 CASSERT(ARM_ETHOSN_NPU_FW_IMAGE_BASE > 0U, assert_ethosn_invalid_fw_image_base); static const struct ethosn_big_fw *big_fw; @@ -201,6 +214,44 @@ static void ethosn_configure_smmu_streams(const struct ethosn_device_t *device, } } +static void ethosn_configure_stream_addr_extends(const struct ethosn_device_t *device, + uintptr_t core_addr) +{ + uint32_t addr_extends[3] = { 0 }; + size_t i; + + if (device->has_reserved_memory) { + const uint32_t addr = TO_EXTEND_ADDR(device->reserved_memory_addr); + + addr_extends[0] = addr; + addr_extends[1] = addr; + addr_extends[2] = addr; + } else { + addr_extends[0] = TO_EXTEND_ADDR(ETHOSN_FW_VA_BASE); + addr_extends[1] = TO_EXTEND_ADDR(ETHOSN_WORKING_DATA_VA_BASE); + addr_extends[2] = TO_EXTEND_ADDR(ETHOSN_COMMAND_STREAM_VA_BASE); + } + + for (i = 0U; i < ARRAY_SIZE(addr_extends); ++i) { + const uintptr_t reg_addr = SEC_ADDR_EXT_REG_BASE + + (SEC_ADDR_EXT_OFFSET * i); + mmio_write_32(ETHOSN_CORE_SEC_REG(core_addr, reg_addr), + addr_extends[i]); + } +} + +static void ethosn_configure_stream_attr_ctlr(uintptr_t core_addr) +{ + size_t i; + + for (i = 0U; i < SEC_ATTR_CTLR_NUM; ++i) { + const uintptr_t reg_addr = SEC_ATTR_CTLR_REG_BASE + + (SEC_ATTR_CTLR_OFFSET * i); + mmio_write_32(ETHOSN_CORE_SEC_REG(core_addr, reg_addr), + SEC_ATTR_CTLR_VAL); + } +} + static void ethosn_delegate_to_ns(uintptr_t core_addr) { mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_SECCTLR_REG), @@ -287,6 +338,9 @@ static int ethosn_core_full_reset(const struct ethosn_device_t *device, #endif } + ethosn_configure_stream_addr_extends(device, core->addr); + ethosn_configure_stream_attr_ctlr(core->addr); + ethosn_delegate_to_ns(core->addr); return ETHOSN_SUCCESS; diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h index c8e2df07c..b43e8dd17 100644 --- a/include/drivers/arm/ethosn.h +++ b/include/drivers/arm/ethosn.h @@ -47,7 +47,7 @@ /* Service version */ #define ETHOSN_VERSION_MAJOR U(2) -#define ETHOSN_VERSION_MINOR U(5) +#define ETHOSN_VERSION_MINOR U(6) /* Return codes for function calls */ #define ETHOSN_SUCCESS 0 From 6dcf3e774457cf00b91abda715adfbefce822877 Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Fri, 10 Feb 2023 16:59:23 +0100 Subject: [PATCH 22/25] feat(ethos-n)!: add protected NPU firmware setup When the Arm(R) Ethos(TM)-N NPU driver is built with TZMP1 support, the NPU should use the firmware that has been loaded into the protected memory by BL2. The Linux Kernel NPU driver in the non-secure world is not allowed to configure the NPU to do this in a TZMP1 build so the SiP service will now configure the NPU to boot with the firmware in the protected memory. BREAKING CHANGE: The Linux Kernel NPU driver can no longer directly configure and boot the NPU in a TZMP1 build. The API version has therefore been given a major version bump with this change. Signed-off-by: Mikael Olsson Change-Id: I65d00f54b3ade3665d7941e270da7a3dec02281a --- drivers/arm/ethosn/ethosn_smc.c | 64 ++++++++++++++++++++++++++++++++- include/drivers/arm/ethosn.h | 8 +++-- 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c index d1b21e045..655856696 100644 --- a/drivers/arm/ethosn/ethosn_smc.c +++ b/drivers/arm/ethosn/ethosn_smc.c @@ -51,7 +51,11 @@ #define SEC_AUXCTLR_STASHING_VAL U(0xA5000000) #define SEC_DEL_REG U(0x0004) +#if ARM_ETHOSN_NPU_TZMP1 +#define SEC_DEL_VAL U(0x808) +#else #define SEC_DEL_VAL U(0x80C) +#endif #define SEC_DEL_EXCC_MASK U(0x20) #define SEC_SECCTLR_REG U(0x0010) @@ -62,7 +66,9 @@ #define SEC_DEL_ADDR_EXT_VAL U(0x1) #define SEC_SYSCTRL0_REG U(0x0018) +#define SEC_SYSCTRL0_CPU_WAIT U(1) #define SEC_SYSCTRL0_SLEEPING U(1U << 4) +#define SEC_SYSCTRL0_INITVTOR_MASK U(0x1FFFFF80) #define SEC_SYSCTRL0_SOFT_RESET U(3U << 29) #define SEC_SYSCTRL0_HARD_RESET U(1U << 31) @@ -88,6 +94,8 @@ #define SEC_NPU_ID_REG U(0xF000) #define SEC_NPU_ID_ARCH_VER_SHIFT U(0X10) +#define FIRMWARE_STREAM_INDEX U(0x0) +#define PLE_STREAM_INDEX U(0x4) #define INPUT_STREAM_INDEX U(0x6) #define INTERMEDIATE_STREAM_INDEX U(0x7) #define OUTPUT_STREAM_INDEX U(0x8) @@ -98,6 +106,14 @@ #if ARM_ETHOSN_NPU_TZMP1 CASSERT(ARM_ETHOSN_NPU_FW_IMAGE_BASE > 0U, assert_ethosn_invalid_fw_image_base); static const struct ethosn_big_fw *big_fw; + +#define FW_INITVTOR_ADDR(big_fw) \ + ((ETHOSN_FW_VA_BASE + big_fw->vector_table_offset) & \ + SEC_SYSCTRL0_INITVTOR_MASK) + +#define SYSCTRL0_INITVTOR_ADDR(value) \ + (value & SEC_SYSCTRL0_INITVTOR_MASK) + #endif static bool ethosn_get_device_and_core(uintptr_t core_addr, @@ -140,6 +156,9 @@ static void ethosn_configure_stream_nsaid(const struct ethosn_core_t *core, size_t i; uint32_t streams[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + streams[FIRMWARE_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_FW_NSAID; + streams[PLE_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_FW_NSAID; + if (is_protected) { streams[INPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_DATA_NSAID; streams[INTERMEDIATE_STREAM_INDEX] = @@ -154,6 +173,13 @@ static void ethosn_configure_stream_nsaid(const struct ethosn_core_t *core, streams[i]); } } + +static void ethosn_configure_vector_table(uintptr_t core_addr) +{ + mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_SYSCTRL0_REG), + FW_INITVTOR_ADDR(big_fw)); +} + #endif static void ethosn_configure_events(uintptr_t core_addr) @@ -307,6 +333,31 @@ static bool ethosn_core_reset(uintptr_t core_addr, bool hard_reset) return timeout < ETHOSN_RESET_TIMEOUT_US; } +static int ethosn_core_boot_fw(uintptr_t core_addr) +{ +#if ARM_ETHOSN_NPU_TZMP1 + const uintptr_t sysctrl0_reg = ETHOSN_CORE_SEC_REG(core_addr, SEC_SYSCTRL0_REG); + const uint32_t sysctrl0_val = mmio_read_32(sysctrl0_reg); + const bool waiting = (sysctrl0_val & SEC_SYSCTRL0_CPU_WAIT); + + if (!waiting) { + WARN("ETHOSN: Firmware is already running.\n"); + return ETHOSN_INVALID_STATE; + } + + if (SYSCTRL0_INITVTOR_ADDR(sysctrl0_val) != FW_INITVTOR_ADDR(big_fw)) { + WARN("ETHOSN: Unknown vector table won't boot firmware.\n"); + return ETHOSN_INVALID_CONFIGURATION; + } + + mmio_clrbits_32(sysctrl0_reg, SEC_SYSCTRL0_CPU_WAIT); + + return ETHOSN_SUCCESS; +#else + return ETHOSN_NOT_SUPPORTED; +#endif +} + static int ethosn_core_full_reset(const struct ethosn_device_t *device, const struct ethosn_core_t *core, bool hard_reset, @@ -341,6 +392,10 @@ static int ethosn_core_full_reset(const struct ethosn_device_t *device, ethosn_configure_stream_addr_extends(device, core->addr); ethosn_configure_stream_attr_ctlr(core->addr); +#if ARM_ETHOSN_NPU_TZMP1 + ethosn_configure_vector_table(core->addr); +#endif + ethosn_delegate_to_ns(core->addr); return ETHOSN_SUCCESS; @@ -407,6 +462,8 @@ static uintptr_t ethosn_smc_core_handler(uint32_t fid, is_protected, aux_features, handle); + case ETHOSN_FNUM_BOOT_FW: + SMC_RET1(handle, ethosn_core_boot_fw(core->addr)); default: WARN("ETHOSN: Unimplemented SMC call: 0x%x\n", fid); SMC_RET1(handle, SMC_UNK); @@ -470,7 +527,7 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, x4 &= 0xFFFFFFFF; } - if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_GET_FW_PROP)) { + if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_BOOT_FW)) { WARN("ETHOSN: Unknown SMC call: 0x%x\n", smc_fid); SMC_RET1(handle, SMC_UNK); } @@ -509,6 +566,11 @@ int ethosn_smc_setup(void) } dev = ETHOSN_GET_DEVICE(0U); + if (dev->has_reserved_memory) { + ERROR("ETHOSN: TZMP1 doesn't support using reserved memory\n"); + return ETHOSN_FAILURE; + } + arch_ver = ethosn_core_read_arch_version(dev->cores[0U].addr); big_fw = (struct ethosn_big_fw *)ARM_ETHOSN_NPU_FW_IMAGE_BASE; diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h index b43e8dd17..993dd122b 100644 --- a/include/drivers/arm/ethosn.h +++ b/include/drivers/arm/ethosn.h @@ -16,7 +16,8 @@ #define ETHOSN_FNUM_SOFT_RESET U(0x53) #define ETHOSN_FNUM_IS_SLEEPING U(0x54) #define ETHOSN_FNUM_GET_FW_PROP U(0x55) -/* 0x56-0x5F reserved for future use */ +#define ETHOSN_FNUM_BOOT_FW U(0x56) +/* 0x57-0x5F reserved for future use */ /* Properties for ETHOSN_FNUM_TZMP_GET_FW_PROP */ #define ETHOSN_FW_PROP_VERSION U(0xF00) @@ -46,8 +47,8 @@ #define is_ethosn_fid(_fid) (((_fid) & ETHOSN_FID_MASK) == ETHOSN_FID_VALUE) /* Service version */ -#define ETHOSN_VERSION_MAJOR U(2) -#define ETHOSN_VERSION_MINOR U(6) +#define ETHOSN_VERSION_MAJOR U(3) +#define ETHOSN_VERSION_MINOR U(0) /* Return codes for function calls */ #define ETHOSN_SUCCESS 0 @@ -58,6 +59,7 @@ #define ETHOSN_UNKNOWN_CORE_ADDRESS -5 #define ETHOSN_UNKNOWN_ALLOCATOR_IDX -6 #define ETHOSN_INVALID_CONFIGURATION -7 +#define ETHOSN_INVALID_STATE -8 /* * Argument types for soft and hard resets to indicate whether to reset From 986c4e991ace5cb40bed35145184e66863c47152 Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Tue, 14 Mar 2023 18:29:06 +0100 Subject: [PATCH 23/25] feat(ethos-n): add separate RO and RW NSAIDs To be able to further restrict the memory access for the Arm(R) Ethos(TM)-N NPU, separate read-only and read/write NSAIDs for the non-protected and protected memory have been added to the Juno platform's TZMP1 TZC configuration for the NPU. The platform definition has been updated accordingly and the NPU driver will now only give read/write access to the streams that require it. Signed-off-by: Mikael Olsson Change-Id: I5a173500fc1943a5cd406a3b379e1f1f554eeda6 --- docs/getting_started/porting-guide.rst | 21 +++++++++++++++--- drivers/arm/ethosn/ethosn_smc.c | 24 ++++++++++++++------- plat/arm/board/juno/include/platform_def.h | 11 +++++++--- plat/arm/board/juno/juno_ethosn_tzmp1_def.h | 19 +++++++++++----- 4 files changed, 56 insertions(+), 19 deletions(-) diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index 5b88fcb38..1a4b107b6 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -582,10 +582,25 @@ enabled, the following constants must also be defined. Defines the Non-secure Access IDentity (NSAID) that the NPU shall use to access the protected memory that contains the NPU's firmware. -- **ARM_ETHOSN_NPU_PROT_DATA_NSAID** +- **ARM_ETHOSN_NPU_PROT_DATA_RW_NSAID** - Defines the Non-secure Access IDentity (NSAID) that the NPU shall use to - access the protected memory that contains inference data. + Defines the Non-secure Access IDentity (NSAID) that the NPU shall use for + read/write access to the protected memory that contains inference data. + +- **ARM_ETHOSN_NPU_PROT_DATA_RO_NSAID** + + Defines the Non-secure Access IDentity (NSAID) that the NPU shall use for + read-only access to the protected memory that contains inference data. + +- **ARM_ETHOSN_NPU_NS_RW_DATA_NSAID** + + Defines the Non-secure Access IDentity (NSAID) that the NPU shall use for + read/write access to the non-protected memory. + +- **ARM_ETHOSN_NPU_NS_RO_DATA_NSAID** + + Defines the Non-secure Access IDentity (NSAID) that the NPU shall use for + read-only access to the non-protected memory. - **ARM_ETHOSN_NPU_FW_IMAGE_BASE** and **ARM_ETHOSN_NPU_FW_IMAGE_LIMIT** diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c index 655856696..85a12c55c 100644 --- a/drivers/arm/ethosn/ethosn_smc.c +++ b/drivers/arm/ethosn/ethosn_smc.c @@ -94,11 +94,12 @@ #define SEC_NPU_ID_REG U(0xF000) #define SEC_NPU_ID_ARCH_VER_SHIFT U(0X10) -#define FIRMWARE_STREAM_INDEX U(0x0) +#define FIRMWARE_STREAM_INDEX U(0x0) +#define WORKING_STREAM_INDEX U(0x1) #define PLE_STREAM_INDEX U(0x4) -#define INPUT_STREAM_INDEX U(0x6) -#define INTERMEDIATE_STREAM_INDEX U(0x7) -#define OUTPUT_STREAM_INDEX U(0x8) +#define INPUT_STREAM_INDEX U(0x6) +#define INTERMEDIATE_STREAM_INDEX U(0x7) +#define OUTPUT_STREAM_INDEX U(0x8) #define TO_EXTEND_ADDR(addr) \ ((addr >> SEC_ADDR_EXT_SHIFT) & SEC_ADDR_EXT_MASK) @@ -154,16 +155,23 @@ static void ethosn_configure_stream_nsaid(const struct ethosn_core_t *core, bool is_protected) { size_t i; - uint32_t streams[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + uint32_t streams[9] = {[0 ... 8] = ARM_ETHOSN_NPU_NS_RO_DATA_NSAID}; streams[FIRMWARE_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_FW_NSAID; streams[PLE_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_FW_NSAID; + streams[WORKING_STREAM_INDEX] = ARM_ETHOSN_NPU_NS_RW_DATA_NSAID; + if (is_protected) { - streams[INPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_DATA_NSAID; + streams[INPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_RO_DATA_NSAID; streams[INTERMEDIATE_STREAM_INDEX] = - ARM_ETHOSN_NPU_PROT_DATA_NSAID; - streams[OUTPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_DATA_NSAID; + ARM_ETHOSN_NPU_PROT_RW_DATA_NSAID; + streams[OUTPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_RW_DATA_NSAID; + } else { + streams[INPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_NS_RO_DATA_NSAID; + streams[INTERMEDIATE_STREAM_INDEX] = + ARM_ETHOSN_NPU_NS_RW_DATA_NSAID; + streams[OUTPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_NS_RW_DATA_NSAID; } for (i = 0U; i < ARRAY_SIZE(streams); ++i) { diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 5eaec698d..47258cb23 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -327,9 +327,14 @@ /* Protected NSAIDs and memory regions for the Arm(R) Ethos(TM)-N NPU driver */ #ifdef JUNO_ETHOSN_TZMP1 -#define ARM_ETHOSN_NPU_PROT_FW_NSAID JUNO_ETHOSN_TZC400_NSAID_FW_PROT -#define ARM_ETHOSN_NPU_PROT_DATA_NSAID JUNO_ETHOSN_TZC400_NSAID_DATA_PROT -#define ARM_ETHOSN_NPU_FW_IMAGE_BASE JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE +#define ARM_ETHOSN_NPU_PROT_FW_NSAID JUNO_ETHOSN_TZC400_NSAID_FW_PROT +#define ARM_ETHOSN_NPU_PROT_RW_DATA_NSAID JUNO_ETHOSN_TZC400_NSAID_DATA_RW_PROT +#define ARM_ETHOSN_NPU_PROT_RO_DATA_NSAID JUNO_ETHOSN_TZC400_NSAID_DATA_RO_PROT + +#define ARM_ETHOSN_NPU_NS_RW_DATA_NSAID JUNO_ETHOSN_TZC400_NSAID_DATA_RW_NS +#define ARM_ETHOSN_NPU_NS_RO_DATA_NSAID JUNO_ETHOSN_TZC400_NSAID_DATA_RO_NS + +#define ARM_ETHOSN_NPU_FW_IMAGE_BASE JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE #define ARM_ETHOSN_NPU_FW_IMAGE_LIMIT \ (JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE + JUNO_ETHOSN_FW_TZC_PROT_DRAM2_SIZE) #endif diff --git a/plat/arm/board/juno/juno_ethosn_tzmp1_def.h b/plat/arm/board/juno/juno_ethosn_tzmp1_def.h index 131adcd7c..c3e816adc 100644 --- a/plat/arm/board/juno/juno_ethosn_tzmp1_def.h +++ b/plat/arm/board/juno/juno_ethosn_tzmp1_def.h @@ -7,8 +7,13 @@ #ifndef JUNO_ETHOSN_TZMP1_DEF_H #define JUNO_ETHOSN_TZMP1_DEF_H -#define JUNO_ETHOSN_TZC400_NSAID_FW_PROT 7 -#define JUNO_ETHOSN_TZC400_NSAID_DATA_PROT 8 +#define JUNO_ETHOSN_TZC400_NSAID_FW_PROT 7 +#define JUNO_ETHOSN_TZC400_NSAID_DATA_RW_PROT 8 +#define JUNO_ETHOSN_TZC400_NSAID_DATA_RO_PROT 13 + +/* 0 is the default NSAID and is included in PLAT_ARM_TZC_NS_DEV_ACCESS */ +#define JUNO_ETHOSN_TZC400_NSAID_DATA_RW_NS 0 +#define JUNO_ETHOSN_TZC400_NSAID_DATA_RO_NS 14 #define JUNO_ETHOSN_FW_TZC_PROT_DRAM2_SIZE UL(0x000400000) /* 4 MB */ #define JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE (ARM_DRAM2_BASE) @@ -32,13 +37,17 @@ #define JUNO_FW_TZC_PROT_ACCESS \ (TZC_REGION_ACCESS_RDWR(JUNO_ETHOSN_TZC400_NSAID_FW_PROT)) #define JUNO_DATA_TZC_PROT_ACCESS \ - (TZC_REGION_ACCESS_RDWR(JUNO_ETHOSN_TZC400_NSAID_DATA_PROT)) + (TZC_REGION_ACCESS_RDWR(JUNO_ETHOSN_TZC400_NSAID_DATA_RW_PROT) | \ + TZC_REGION_ACCESS_RD(JUNO_ETHOSN_TZC400_NSAID_DATA_RO_PROT)) +#define JUNO_DATA_TZC_NS_ACCESS \ + (PLAT_ARM_TZC_NS_DEV_ACCESS | \ + TZC_REGION_ACCESS_RD(JUNO_ETHOSN_TZC400_NSAID_DATA_RO_NS)) #define JUNO_ETHOSN_TZMP_REGIONS_DEF \ { ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END + ARM_L1_GPT_SIZE, \ TZC_REGION_S_RDWR, 0 }, \ { ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, \ - ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS }, \ + ARM_TZC_NS_DRAM_S_ACCESS, JUNO_DATA_TZC_NS_ACCESS}, \ { JUNO_ETHOSN_FW_TZC_PROT_DRAM2_BASE, \ JUNO_ETHOSN_FW_TZC_PROT_DRAM2_END, \ TZC_REGION_S_RDWR, JUNO_FW_TZC_PROT_ACCESS }, \ @@ -46,6 +55,6 @@ JUNO_ETHOSN_DATA_TZC_PROT_DRAM2_END, \ TZC_REGION_S_NONE, JUNO_DATA_TZC_PROT_ACCESS }, \ { JUNO_ETHOSN_NS_DRAM2_BASE, JUNO_ETHOSN_NS_DRAM2_END, \ - ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS } + ARM_TZC_NS_DRAM_S_ACCESS, JUNO_DATA_TZC_NS_ACCESS} #endif /* JUNO_ETHOSN_TZMP1_DEF_H */ From 6ce4c6c0bb347c8ddceb26bff33562e7e7469587 Mon Sep 17 00:00:00 2001 From: Rob Hughes Date: Mon, 20 Feb 2023 12:03:52 +0000 Subject: [PATCH 24/25] docs(ethos-n): update porting-guide.rst for NPU Add some missing configuration that must be done for supporting NPU on other platforms. Signed-off-by: Rob Hughes Signed-off-by: Mikael Olsson Change-Id: Ic505ea60f73b970d0d7ded101830eb2ce8c7ab64 --- docs/getting_started/porting-guide.rst | 25 ++++++++++++++++++++++--- docs/plat/arm/arm-build-options.rst | 5 +++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index 1a4b107b6..ae3ffb554 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -574,8 +574,15 @@ optionally be defined: PLAT_PARTITION_BLOCK_SIZE := 4096 $(eval $(call add_define,PLAT_PARTITION_BLOCK_SIZE)) +If the platform port uses the Arm® Ethos™-N NPU driver, the following +configuration must be performed: + +- The NPU SiP service handler must be hooked up. This consists of both the + initial setup (``ethosn_smc_setup``) and the handler itself + (``ethosn_smc_handler``) + If the platform port uses the Arm® Ethos™-N NPU driver with TZMP1 support -enabled, the following constants must also be defined. +enabled, the following constants and configuration must also be defined: - **ARM_ETHOSN_NPU_PROT_FW_NSAID** @@ -604,7 +611,18 @@ enabled, the following constants must also be defined. - **ARM_ETHOSN_NPU_FW_IMAGE_BASE** and **ARM_ETHOSN_NPU_FW_IMAGE_LIMIT** -- Provide FCONF entries to configure the image source for NPU firmware (and certificates). + Defines the physical address range that the NPU's firmware will be loaded + into and executed from. + +- Configure the platforms TrustZone Controller (TZC) with appropriate regions + of protected memory. At minimum this must include a region for the NPU's + firmware code and a region for protected inference data, and these must be + accessible using the NSAIDs defined above. + +- Include the NPU firmware and certificates in the FIP. + +- Provide FCONF entries to configure the image source for the NPU firmware + and certificates. - Add MMU mappings such that: @@ -612,7 +630,8 @@ enabled, the following constants must also be defined. ``ARM_ETHOSN_NPU_FW_IMAGE_BASE`` and ``ARM_ETHOSN_NPU_FW_IMAGE_LIMIT`` - BL31 (SiP service) can read the NPU firmware from the same region -- Add the firmware image ID ``ARM_ETHOSN_NPU_FW_IMAGE_ID`` to the list of images loaded by BL2 +- Add the firmware image ID ``ARM_ETHOSN_NPU_FW_IMAGE_ID`` to the list of images + loaded by BL2. Please see the reference implementation code for the Juno platform as an example. diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst index 83212c6dc..e7e7ee703 100644 --- a/docs/plat/arm/arm-build-options.rst +++ b/docs/plat/arm/arm-build-options.rst @@ -105,8 +105,9 @@ Arm Platform Build Options Arm® Ethos™-N NPU. Requires ``ARM_ETHOSN_NPU_DRIVER`` and ``TRUSTED_BOARD_BOOT`` to be enabled. -- ``ARM_ETHOSN_NPU_FW``: location of the NPU firmware binary (ethosn.bin). - This firmware image will be included in the FIP and loaded at runtime. +- ``ARM_ETHOSN_NPU_FW``: location of the NPU firmware binary + (```ethosn.bin```). This firmware image will be included in the FIP and + loaded at runtime. - ``ARM_SPMC_MANIFEST_DTS`` : path to an alternate manifest file used as the SPMC Core manifest. Valid when ``SPD=spmd`` is selected. From 61ff8f72b2f2da04578aed10843141ae10123ed8 Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Tue, 28 Mar 2023 15:51:49 +0200 Subject: [PATCH 25/25] docs(maintainers): update NPU driver files New files have been added for the Arm(R) Ethos(TM)-N NPU driver with the addition of TZMP1 support so the files in the maintainers list have been updated accordingly. Signed-off-by: Mikael Olsson Change-Id: I3768b2ab78c117c1dd4fc03b38cf35f6811fa378 --- docs/about/maintainers.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index db412f5d9..f36865ada 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -179,6 +179,10 @@ Arm® Ethos™-N NPU driver :|G|: `mikaelolsson-arm`_ :|F|: drivers/arm/ethosn/ :|F|: include/drivers/arm/ethosn.h +:|F|: include/drivers/arm/ethosn_cert.h +:|F|: include/drivers/arm/ethosn_fip.h +:|F|: include/drivers/arm/ethosn_oid.h +:|F|: plat/arm/board/juno/juno_ethosn_tzmp1_def.h :|F|: plat/arm/common/fconf/fconf_ethosn_getter.c :|F|: include/plat/arm/common/fconf_ethosn_getter.h :|F|: fdts/juno-ethosn.dtsi