xref: /optee_os/core/arch/arm/plat-ti/sm_platform_handler_a15.c (revision d83a652a9bf81fb12a2dcb9816152b233d35920b)
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/thread.h>
10 #include <mm/core_memprot.h>
11 #include <mm/core_mmu.h>
12 #include <sm/optee_smc.h>
13 #include <sm/sm.h>
14 #include <trace.h>
15 
16 #include "api_monitor_index_a15.h"
17 
18 #define WUGEN_MPU_AMBA_IF_MODE 0x80c
19 
20 register_phys_mem_pgdir(MEM_AREA_IO_SEC, WUGEN_MPU_BASE, WUGEN_MPU_SIZE);
21 
wugen_mpu_base(void)22 static vaddr_t wugen_mpu_base(void)
23 {
24 	static void *va;
25 
26 	if (cpu_mmu_enabled()) {
27 		if (!va)
28 			va = phys_to_virt(WUGEN_MPU_BASE, MEM_AREA_IO_SEC,
29 					  WUGEN_MPU_SIZE);
30 		return (vaddr_t)va;
31 	}
32 
33 	return WUGEN_MPU_BASE;
34 }
35 
write_wugen_mpu_amba_if_mode(uint32_t val)36 static void write_wugen_mpu_amba_if_mode(uint32_t val)
37 {
38 	io_write32(wugen_mpu_base() + WUGEN_MPU_AMBA_IF_MODE, val);
39 }
40 
ti_sip_handler(struct thread_smc_args * smc_args)41 static enum sm_handler_ret ti_sip_handler(struct thread_smc_args *smc_args)
42 {
43 	uint16_t sip_func = OPTEE_SMC_FUNC_NUM(smc_args->a0);
44 
45 	switch (sip_func) {
46 	case API_MONITOR_ACTLR_SETREGISTER_INDEX:
47 		write_actlr(smc_args->a1);
48 		isb();
49 		smc_args->a0 = OPTEE_SMC_RETURN_OK;
50 		break;
51 	case API_MONITOR_TIMER_SETCNTFRQ_INDEX:
52 		write_cntfrq(smc_args->a1);
53 		isb();
54 		smc_args->a0 = OPTEE_SMC_RETURN_OK;
55 		break;
56 	case API_MONITOR_WUGEN_MPU_SETAMBAIF_INDEX:
57 		write_wugen_mpu_amba_if_mode(smc_args->a1);
58 		smc_args->a0 = OPTEE_SMC_RETURN_OK;
59 		break;
60 	default:
61 		EMSG("Invalid SIP function code: 0x%04"PRIx16, sip_func);
62 		smc_args->a0 = OPTEE_SMC_RETURN_EBADCMD;
63 		break;
64 	}
65 
66 	return SM_HANDLER_SMC_HANDLED;
67 }
68 
sm_platform_handler(struct sm_ctx * ctx)69 enum sm_handler_ret sm_platform_handler(struct sm_ctx *ctx)
70 {
71 	uint32_t *nsec_r0 = (uint32_t *)(&ctx->nsec.r0);
72 	uint16_t smc_owner = OPTEE_SMC_OWNER_NUM(*nsec_r0);
73 
74 	switch (smc_owner) {
75 	case OPTEE_SMC_OWNER_SIP:
76 		return ti_sip_handler((struct thread_smc_args *)nsec_r0);
77 	default:
78 		return SM_HANDLER_PENDING_SMC;
79 	}
80 }
81