bool sm_platform_handler(struct sm_ctx *ctx) { if (ctx->nsec.r12 == 0x200) return true; switch (ctx->nsec.r12) { case 0x0: switch (ctx->nsec.r0) { case SECURE_SVC_PM_LATE_SUSPEND: sm_pm_cpu_do_suspend(suspend_regs); cache_op_inner(DCACHE_AREA_CLEAN, suspend_regs, sizeof(suspend_regs)); cache_op_outer(DCACHE_AREA_CLEAN, virt_to_phys(suspend_regs), sizeof(suspend_regs)); ctx->nsec.r0 = API_HAL_RET_VALUE_OK; break; default: ctx->nsec.r0 = API_HAL_RET_VALUE_SERVICE_UNKNWON; break; } break; case API_MONITOR_L2CACHE_SETDEBUG_INDEX: write32(ctx->nsec.r0, pl310_base() + PL310_DEBUG_CTRL); ctx->nsec.r0 = API_HAL_RET_VALUE_OK; break; case API_MONITOR_L2CACHE_CLEANINVBYPA_INDEX: arm_cl2_cleaninvbypa(pl310_base(), ctx->nsec.r0, (ctx->nsec.r0 + ctx->nsec.r1)); ctx->nsec.r0 = API_HAL_RET_VALUE_OK; break; case API_MONITOR_L2CACHE_SETCONTROL_INDEX: write32(ctx->nsec.r0, pl310_base() + PL310_CTRL); ctx->nsec.r0 = API_HAL_RET_VALUE_OK; break; case API_MONITOR_L2CACHE_SETAUXILIARYCONTROL_INDEX: write32(ctx->nsec.r0, pl310_base() + PL310_AUX_CTRL); ctx->nsec.r0 = API_HAL_RET_VALUE_OK; break; case API_MONITOR_L2CACHE_SETLATENCY_INDEX: write32(ctx->nsec.r0, pl310_base() + PL310_TAG_RAM_CTRL); write32(ctx->nsec.r1, pl310_base() + PL310_DATA_RAM_CTRL); ctx->nsec.r0 = API_HAL_RET_VALUE_OK; break; case API_MONITOR_L2CACHE_SETPREFETCHCONTROL_INDEX: write32(ctx->nsec.r0, pl310_base() + PL310_PREFETCH_CTRL); ctx->nsec.r0 = API_HAL_RET_VALUE_OK; break; default: ctx->nsec.r0 = API_HAL_RET_VALUE_SERVICE_UNKNWON; break; } return false; }
unsigned int cache_maintenance_l2(int op, paddr_t pa, size_t len) { unsigned int ret = TEE_SUCCESS; uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ); tee_l2cc_mutex_lock(); switch (op) { case L2CACHE_INVALIDATE: arm_cl2_invbyway(pl310_base()); break; case L2CACHE_AREA_INVALIDATE: if (len) arm_cl2_invbypa(pl310_base(), pa, pa + len - 1); break; case L2CACHE_CLEAN: arm_cl2_cleanbyway(pl310_base()); break; case L2CACHE_AREA_CLEAN: if (len) arm_cl2_cleanbypa(pl310_base(), pa, pa + len - 1); break; case L2CACHE_CLEAN_INV: arm_cl2_cleaninvbyway(pl310_base()); break; case L2CACHE_AREA_CLEAN_INV: if (len) arm_cl2_cleaninvbypa(pl310_base(), pa, pa + len - 1); break; default: ret = TEE_ERROR_NOT_IMPLEMENTED; } tee_l2cc_mutex_unlock(); thread_set_exceptions(exceptions); return ret; }