diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 2ae32447f..bffca722f 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -179,6 +179,10 @@ Arm® Ethos™-N NPU driver :|G|: `stefanasimion`_ :|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 diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index 8d6a2bf23..ae3ffb554 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -574,6 +574,68 @@ 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 and configuration 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_RW_NSAID** + + 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** + + 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: + + - 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 68eb3ecd6..e7e7ee703 100644 --- a/docs/plat/arm/arm-build-options.rst +++ b/docs/plat/arm/arm-build-options.rst @@ -101,6 +101,14 @@ 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`` 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. @@ -165,4 +173,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/drivers/arm/ethosn/ethosn_big_fw.c b/drivers/arm/ethosn/ethosn_big_fw.c new file mode 100644 index 000000000..628f5d976 --- /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 11 + +#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 915a0d87a..85a12c55c 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 */ @@ -15,6 +15,12 @@ #include #include +#include + +#if ARM_ETHOSN_NPU_TZMP1 +#include "ethosn_big_fw.h" +#endif + /* * Number of Arm(R) Ethos(TM)-N NPU (NPU) devices available */ @@ -28,27 +34,89 @@ #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) +#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) +#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) -#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) +#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_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) +#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) + #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) + +#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 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; + +#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, const struct ethosn_device_t **dev_match, const struct ethosn_core_t **core_match) @@ -74,6 +142,83 @@ static bool ethosn_get_device_and_core(uintptr_t core_addr, return false; } +#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) +{ + size_t i; + 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_RO_DATA_NSAID; + streams[INTERMEDIATE_STREAM_INDEX] = + 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) { + 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]); + } +} + +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) +{ + 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) @@ -103,6 +248,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), @@ -125,13 +308,22 @@ static int ethosn_is_sec(uintptr_t core_addr) return 1; } -static bool ethosn_reset(uintptr_t core_addr, int hard_reset) +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_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); @@ -149,18 +341,184 @@ static bool ethosn_reset(uintptr_t core_addr, int 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, + u_register_t asset_alloc_idx, + u_register_t is_protected, + u_register_t aux_features) +{ + 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 (!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); + +#if ARM_ETHOSN_NPU_TZMP1 + ethosn_configure_stream_nsaid(core, is_protected); +#endif + } + + 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; +} + +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, + u_register_t aux_features, + 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, + aux_features); + 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, + u_register_t aux_features, + 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, + 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); + } +} + +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 core_addr, - u_register_t asset_alloc_idx, + 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 */ @@ -171,59 +529,69 @@ 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; + x1 &= 0xFFFFFFFF; + x2 &= 0xFFFFFFFF; x3 &= 0xFFFFFFFF; 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_BOOT_FW)) { WARN("ETHOSN: Unknown SMC call: 0x%x\n", smc_fid); SMC_RET1(handle, SMC_UNK); } - /* Commands that do not require a valid core address */ 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); } - 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)); - } - - 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); - } - - /* Commands that require a valid device, 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 (!device->has_reserved_memory) { - ethosn_configure_smmu_streams(device, core, - asset_alloc_idx); - } - - 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, + SMC_GET_GP(handle, CTX_GPREG_X5), + handle); +} + +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); + 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; + + 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/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>; }; }; }; diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h index dbaf16cd7..993dd122b 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 */ @@ -14,7 +14,16 @@ #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) +#define ETHOSN_FNUM_GET_FW_PROP U(0x55) +#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) +#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) @@ -38,22 +47,33 @@ #define is_ethosn_fid(_fid) (((_fid) & ETHOSN_FID_MASK) == ETHOSN_FID_VALUE) /* Service version */ -#define ETHOSN_VERSION_MAJOR U(2) +#define ETHOSN_VERSION_MAJOR U(3) #define ETHOSN_VERSION_MINOR U(0) /* 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 +#define ETHOSN_INVALID_CONFIGURATION -7 +#define ETHOSN_INVALID_STATE -8 + +/* + * 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) + +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, - u_register_t x3, + u_register_t reset_type, u_register_t x4, void *cookie, void *handle, 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_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/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/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/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 */ 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); 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..986299ee3 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,41 @@ 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"; +#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/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/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 409d7a60f..47258cb23 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 */ @@ -62,6 +65,18 @@ JUNO_DTB_DRAM_MAP_SIZE, \ 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, \ + 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) @@ -102,11 +117,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 @@ -116,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 @@ -310,4 +325,18 @@ /* Number of SCMI channels on the platform */ #define PLAT_ARM_SCMI_CHANNEL_COUNT U(1) +/* 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_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 + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c index 451c7df37..02614da4a 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} }; @@ -76,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/board/juno/juno_ethosn_tzmp1_def.h b/plat/arm/board/juno/juno_ethosn_tzmp1_def.h new file mode 100644 index 000000000..c3e816adc --- /dev/null +++ b/plat/arm/board/juno/juno_ethosn_tzmp1_def.h @@ -0,0 +1,60 @@ +/* + * 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_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) +#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_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, 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 }, \ + { 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, JUNO_DATA_TZC_NS_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 654a7f165..72e7e7837 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 */ @@ -13,6 +13,7 @@ #include #include +#include "juno_ethosn_tzmp1_def.h" #include "juno_tzmp1_def.h" #ifdef JUNO_TZMP1 @@ -78,6 +79,15 @@ static void init_v550(void) #endif /* JUNO_TZMP1 */ +#ifdef JUNO_ETHOSN_TZMP1 + +static const arm_tzc_regions_info_t juno_ethosn_tzmp1_tzc_regions[] = { + JUNO_ETHOSN_TZMP_REGIONS_DEF, + {}, +}; + +#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 +150,17 @@ 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 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 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/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 diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index 2c84eb34d..a4e640771 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 @@ -102,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 de2c4f830..fca6f4f95 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -119,6 +119,43 @@ 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 + + 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. $(eval $(call add_define,MBEDTLS_SHA256_SMALLER)) @@ -322,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) @@ -381,8 +421,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/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; } diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index 6c323312c..743cc90d9 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 */ @@ -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,18 +285,56 @@ 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 */ }; #ifdef IMAGE_BL2 -#if TRUSTED_BOARD_BOOT -#define FCONF_ARM_IO_UUID_NUMBER U(24) +#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_NUMBER U(10) +#define FCONF_ARM_IO_UUID_NUM_NPU U(0) #endif +#if TRUSTED_BOARD_BOOT +#define FCONF_ARM_IO_UUID_NUM_TBB U(12) +#else +#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) */ + +#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_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); @@ -303,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"}, @@ -320,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 */ }; 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; } 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))