From: Mikael Olsson Date: Fri, 27 Jan 2023 17:26:36 +0000 (+0100) Subject: refactor(ethos-n): split up SMC call handling X-Git-Tag: baikal/aarch64/sdk5.10~1^2~111^2~8 X-Git-Url: https://git.baikalelectronics.ru/?a=commitdiff_plain;h=18a6b79c50ca88510c013fc5fba5200473152088;p=arm-tf.git refactor(ethos-n): split up SMC call handling Doing all the SMC call handling in a single function and using specific names for the x1-4 parameters is no longer practical for upcoming additions to the SiP service. Handling of the different SMC functions have therefore been split into separate functions. Signed-off-by: Mikael Olsson Change-Id: If28da8df0f13c449d1fdb2bd9d792d818ec5e1af --- diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c index e314577a3..124de9243 100644 --- a/drivers/arm/ethosn/ethosn_smc.c +++ b/drivers/arm/ethosn/ethosn_smc.c @@ -188,13 +188,13 @@ static int ethosn_core_is_sleeping(uintptr_t core_addr) return ((mmio_read_32(sysctrl0_reg) & sleeping_mask) == sleeping_mask); } -static bool ethosn_reset(uintptr_t core_addr, int hard_reset) +static bool ethosn_core_reset(uintptr_t core_addr, bool hard_reset) { unsigned int timeout; const uintptr_t sysctrl0_reg = ETHOSN_CORE_SEC_REG(core_addr, SEC_SYSCTRL0_REG); - const uint32_t reset_val = (hard_reset != 0) ? SEC_SYSCTRL0_HARD_RESET - : SEC_SYSCTRL0_SOFT_RESET; + const uint32_t reset_val = hard_reset ? SEC_SYSCTRL0_HARD_RESET : + SEC_SYSCTRL0_SOFT_RESET; mmio_write_32(sysctrl0_reg, reset_val); @@ -212,99 +212,133 @@ static bool ethosn_reset(uintptr_t core_addr, int hard_reset) return timeout < ETHOSN_RESET_TIMEOUT_US; } -uintptr_t ethosn_smc_handler(uint32_t smc_fid, - u_register_t core_addr, - u_register_t asset_alloc_idx, - u_register_t reset_type, - u_register_t is_protected, - void *cookie, - void *handle, - u_register_t flags) +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) { - 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 */ - if ((GET_SMC_TYPE(smc_fid) != SMC_TYPE_FAST) || - (GET_SMC_OEN(smc_fid) != OEN_SIP_START)) { - SMC_RET1(handle, SMC_UNK); + 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; } - /* Truncate parameters to 32-bits for SMC32 */ - if (GET_SMC_CC(smc_fid) == SMC_32) { - core_addr &= 0xFFFFFFFF; - asset_alloc_idx &= 0xFFFFFFFF; - reset_type &= 0xFFFFFFFF; - is_protected &= 0xFFFFFFFF; + if (!ethosn_core_reset(core->addr, hard_reset)) { + return ETHOSN_FAILURE; } - if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_IS_SLEEPING)) { - WARN("ETHOSN: Unknown SMC call: 0x%x\n", smc_fid); - SMC_RET1(handle, SMC_UNK); + 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 } - /* Commands that do not require a valid core address */ - switch (fid) { - case ETHOSN_FNUM_VERSION: - SMC_RET2(handle, ETHOSN_VERSION_MAJOR, ETHOSN_VERSION_MINOR); + ethosn_delegate_to_ns(core->addr); + + return ETHOSN_SUCCESS; +} + +static uintptr_t ethosn_smc_core_reset_handler(const struct ethosn_device_t *device, + const struct ethosn_core_t *core, + bool hard_reset, + u_register_t asset_alloc_idx, + u_register_t reset_type, + u_register_t is_protected, + void *handle) +{ + int ret; + + switch (reset_type) { + case ETHOSN_RESET_TYPE_FULL: + ret = ethosn_core_full_reset(device, core, hard_reset, + asset_alloc_idx, is_protected); + break; + case ETHOSN_RESET_TYPE_HALT: + ret = ethosn_core_reset(core->addr, hard_reset) ? ETHOSN_SUCCESS : ETHOSN_FAILURE; + break; + default: + WARN("ETHOSN: Invalid reset type given to SMC call.\n"); + ret = ETHOSN_INVALID_PARAMETER; + break; } + SMC_RET1(handle, ret); +} + +static uintptr_t ethosn_smc_core_handler(uint32_t fid, + u_register_t core_addr, + u_register_t asset_alloc_idx, + u_register_t reset_type, + u_register_t is_protected, + void *handle) +{ + bool hard_reset = false; + const struct ethosn_device_t *device = NULL; + const struct ethosn_core_t *core = NULL; + if (!ethosn_get_device_and_core(core_addr, &device, &core)) { SMC_RET1(handle, ETHOSN_UNKNOWN_CORE_ADDRESS); } - /* Commands that require a valid core address */ switch (fid) { case ETHOSN_FNUM_IS_SEC: SMC_RET1(handle, ethosn_is_sec(core->addr)); case ETHOSN_FNUM_IS_SLEEPING: SMC_RET1(handle, ethosn_core_is_sleeping(core->addr)); - } - - if (!device->has_reserved_memory && - asset_alloc_idx >= device->num_allocators) { - WARN("ETHOSN: Unknown asset allocator index given to SMC call.\n"); - SMC_RET1(handle, ETHOSN_UNKNOWN_ALLOCATOR_IDX); - } - - if (reset_type > ETHOSN_RESET_TYPE_HALT) { - WARN("ETHOSN: Invalid reset type given to SMC call.\n"); - SMC_RET1(handle, ETHOSN_INVALID_PARAMETER); - } - - /* - * Commands that require a valid device, reset type, - * core and asset allocator - */ - switch (fid) { case ETHOSN_FNUM_HARD_RESET: - hard_reset = 1; + hard_reset = true; /* Fallthrough */ case ETHOSN_FNUM_SOFT_RESET: - if (!ethosn_reset(core->addr, hard_reset)) { - SMC_RET1(handle, ETHOSN_FAILURE); - } + return ethosn_smc_core_reset_handler(device, core, + hard_reset, + asset_alloc_idx, + reset_type, + is_protected, + handle); + default: + WARN("ETHOSN: Unimplemented SMC call: 0x%x\n", fid); + SMC_RET1(handle, SMC_UNK); + } +} + +uintptr_t ethosn_smc_handler(uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, + void *cookie, + void *handle, + u_register_t flags) +{ + const uint32_t fid = smc_fid & FUNCID_NUM_MASK; - if (reset_type == ETHOSN_RESET_TYPE_FULL) { - if (!device->has_reserved_memory) { - ethosn_configure_smmu_streams(device, core, - asset_alloc_idx); + /* Only SiP fast calls are expected */ + if ((GET_SMC_TYPE(smc_fid) != SMC_TYPE_FAST) || + (GET_SMC_OEN(smc_fid) != OEN_SIP_START)) { + SMC_RET1(handle, SMC_UNK); + } - #if ARM_ETHOSN_NPU_TZMP1 - ethosn_configure_stream_nsaid(core, - is_protected); - #endif - } + /* Truncate parameters to 32-bits for SMC32 */ + if (GET_SMC_CC(smc_fid) == SMC_32) { + x1 &= 0xFFFFFFFF; + x2 &= 0xFFFFFFFF; + x3 &= 0xFFFFFFFF; + x4 &= 0xFFFFFFFF; + } - ethosn_delegate_to_ns(core->addr); - } - SMC_RET1(handle, ETHOSN_SUCCESS); - default: - WARN("ETHOSN: Unimplemented SMC call: 0x%x\n", fid); + if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_IS_SLEEPING)) { + WARN("ETHOSN: Unknown SMC call: 0x%x\n", smc_fid); SMC_RET1(handle, SMC_UNK); } + + if (fid == ETHOSN_FNUM_VERSION) { + SMC_RET2(handle, ETHOSN_VERSION_MAJOR, ETHOSN_VERSION_MINOR); + } + + return ethosn_smc_core_handler(fid, x1, x2, x3, x4, handle); } int ethosn_smc_setup(void)