1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
4 * Andrew Davis <afd@ti.com>
5 */
6
7 #include <arm32.h>
8 #include <io.h>
9 #include <kernel/cache_helpers.h>
10 #include <kernel/thread.h>
11 #include <kernel/tz_ssvce_def.h>
12 #include <kernel/tz_ssvce_pl310.h>
13 #include <platform_config.h>
14 #include <sm/optee_smc.h>
15 #include <sm/pm.h>
16 #include <sm/sm.h>
17 #include <mm/core_memprot.h>
18 #include <trace.h>
19
20 #include "api_monitor_index_a9.h"
21
22 uint32_t suspend_regs[16];
23
ti_sip_handler(struct thread_smc_args * smc_args)24 static enum sm_handler_ret ti_sip_handler(struct thread_smc_args *smc_args)
25 {
26 uint16_t sip_func = OPTEE_SMC_FUNC_NUM(smc_args->a0);
27
28 switch (sip_func) {
29 case SECURE_SVC_PM_LATE_SUSPEND:
30 sm_pm_cpu_do_suspend(suspend_regs);
31 cache_op_inner(DCACHE_AREA_CLEAN, suspend_regs,
32 sizeof(suspend_regs));
33 cache_op_outer(DCACHE_AREA_CLEAN, virt_to_phys(suspend_regs),
34 sizeof(suspend_regs));
35 smc_args->a0 = OPTEE_SMC_RETURN_OK;
36 break;
37 case API_MONITOR_L2CACHE_SETDEBUG_INDEX:
38 io_write32(pl310_base() + PL310_DEBUG_CTRL, smc_args->a1);
39 smc_args->a0 = OPTEE_SMC_RETURN_OK;
40 break;
41 case API_MONITOR_L2CACHE_CLEANINVBYPA_INDEX:
42 arm_cl2_cleaninvbypa(pl310_base(), smc_args->a1,
43 smc_args->a1 + smc_args->a2);
44 smc_args->a0 = OPTEE_SMC_RETURN_OK;
45 break;
46 case API_MONITOR_L2CACHE_SETCONTROL_INDEX:
47 io_write32(pl310_base() + PL310_CTRL, smc_args->a1);
48 smc_args->a0 = OPTEE_SMC_RETURN_OK;
49 break;
50 case API_MONITOR_L2CACHE_SETAUXILIARYCONTROL_INDEX:
51 io_write32(pl310_base() + PL310_AUX_CTRL, smc_args->a1);
52 smc_args->a0 = OPTEE_SMC_RETURN_OK;
53 break;
54 case API_MONITOR_L2CACHE_SETLATENCY_INDEX:
55 io_write32(pl310_base() + PL310_TAG_RAM_CTRL, smc_args->a1);
56 io_write32(pl310_base() + PL310_DATA_RAM_CTRL, smc_args->a2);
57 smc_args->a0 = OPTEE_SMC_RETURN_OK;
58 break;
59 case API_MONITOR_L2CACHE_SETPREFETCHCONTROL_INDEX:
60 io_write32(pl310_base() + PL310_PREFETCH_CTRL, smc_args->a1);
61 smc_args->a0 = OPTEE_SMC_RETURN_OK;
62 break;
63 default:
64 EMSG("Invalid SIP function code: 0x%04"PRIx16, sip_func);
65 smc_args->a0 = OPTEE_SMC_RETURN_EBADCMD;
66 break;
67 }
68
69 return SM_HANDLER_SMC_HANDLED;
70 }
71
sm_platform_handler(struct sm_ctx * ctx)72 enum sm_handler_ret sm_platform_handler(struct sm_ctx *ctx)
73 {
74 uint32_t *nsec_r0 = (uint32_t *)(&ctx->nsec.r0);
75 uint16_t smc_owner = OPTEE_SMC_OWNER_NUM(*nsec_r0);
76
77 switch (smc_owner) {
78 case OPTEE_SMC_OWNER_SIP:
79 return ti_sip_handler((struct thread_smc_args *)nsec_r0);
80 default:
81 return SM_HANDLER_PENDING_SMC;
82 }
83 }
84