From e64abe7bdaeed99093ae5b4aab8956a04ff4075a Mon Sep 17 00:00:00 2001 From: Mikael Olsson <mikael.olsson@arm.com> Date: Fri, 10 Feb 2023 16:59:03 +0100 Subject: [PATCH] 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 <mikael.olsson@arm.com> 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 -- 2.39.5