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