From 70a296ee8641802dc60754aec5b18d8347820a5c Mon Sep 17 00:00:00 2001 From: Rajasekaran Kalidoss Date: Wed, 16 Nov 2022 17:16:44 +0100 Subject: [PATCH] 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 */ -- 2.39.5