#define SEC_AUXCTLR_STASHING_VAL U(0xA5000000)
#define SEC_DEL_REG U(0x0004)
+#if ARM_ETHOSN_NPU_TZMP1
+#define SEC_DEL_VAL U(0x808)
+#else
#define SEC_DEL_VAL U(0x80C)
+#endif
#define SEC_DEL_EXCC_MASK U(0x20)
#define SEC_SECCTLR_REG U(0x0010)
#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_NPU_ID_REG U(0xF000)
#define SEC_NPU_ID_ARCH_VER_SHIFT U(0X10)
+#define FIRMWARE_STREAM_INDEX U(0x0)
+#define PLE_STREAM_INDEX U(0x4)
#define INPUT_STREAM_INDEX U(0x6)
#define INTERMEDIATE_STREAM_INDEX U(0x7)
#define OUTPUT_STREAM_INDEX U(0x8)
#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,
size_t i;
uint32_t streams[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
+ streams[FIRMWARE_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_FW_NSAID;
+ streams[PLE_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_FW_NSAID;
+
if (is_protected) {
streams[INPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_DATA_NSAID;
streams[INTERMEDIATE_STREAM_INDEX] =
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)
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,
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;
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);
x4 &= 0xFFFFFFFF;
}
- if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_GET_FW_PROP)) {
+ if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_BOOT_FW)) {
WARN("ETHOSN: Unknown SMC call: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
}
}
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;
#define ETHOSN_FNUM_SOFT_RESET U(0x53)
#define ETHOSN_FNUM_IS_SLEEPING U(0x54)
#define ETHOSN_FNUM_GET_FW_PROP U(0x55)
-/* 0x56-0x5F reserved for future use */
+#define ETHOSN_FNUM_BOOT_FW U(0x56)
+/* 0x57-0x5F reserved for future use */
/* Properties for ETHOSN_FNUM_TZMP_GET_FW_PROP */
#define ETHOSN_FW_PROP_VERSION U(0xF00)
#define is_ethosn_fid(_fid) (((_fid) & ETHOSN_FID_MASK) == ETHOSN_FID_VALUE)
/* Service version */
-#define ETHOSN_VERSION_MAJOR U(2)
-#define ETHOSN_VERSION_MINOR U(6)
+#define ETHOSN_VERSION_MAJOR U(3)
+#define ETHOSN_VERSION_MINOR U(0)
/* Return codes for function calls */
#define ETHOSN_SUCCESS 0
#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