xref: /arm-trusted-firmware/services/spd/trusty/generic-arm64-smcall.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <stdio.h>
8*91f16700Schasinglulu 
9*91f16700Schasinglulu #include <common/debug.h>
10*91f16700Schasinglulu #include <common/runtime_svc.h>
11*91f16700Schasinglulu #include <platform_def.h>
12*91f16700Schasinglulu 
13*91f16700Schasinglulu #include "generic-arm64-smcall.h"
14*91f16700Schasinglulu 
15*91f16700Schasinglulu #ifndef PLAT_ARM_GICD_BASE
16*91f16700Schasinglulu #ifdef GICD_BASE
17*91f16700Schasinglulu #define PLAT_ARM_GICD_BASE GICD_BASE
18*91f16700Schasinglulu #define PLAT_ARM_GICC_BASE GICC_BASE
19*91f16700Schasinglulu #ifdef GICR_BASE
20*91f16700Schasinglulu #define PLAT_ARM_GICR_BASE GICR_BASE
21*91f16700Schasinglulu #endif
22*91f16700Schasinglulu #else
23*91f16700Schasinglulu #error PLAT_ARM_GICD_BASE or GICD_BASE must be defined
24*91f16700Schasinglulu #endif
25*91f16700Schasinglulu #endif
26*91f16700Schasinglulu 
27*91f16700Schasinglulu #ifndef PLAT_ARM_GICR_BASE
28*91f16700Schasinglulu #define PLAT_ARM_GICR_BASE SMC_UNK
29*91f16700Schasinglulu #endif
30*91f16700Schasinglulu 
31*91f16700Schasinglulu int trusty_disable_serial_debug;
32*91f16700Schasinglulu 
33*91f16700Schasinglulu struct dputc_state {
34*91f16700Schasinglulu 	char linebuf[128];
35*91f16700Schasinglulu 	unsigned l;
36*91f16700Schasinglulu };
37*91f16700Schasinglulu 
38*91f16700Schasinglulu static struct dputc_state dputc_state[2];
39*91f16700Schasinglulu 
40*91f16700Schasinglulu static void trusty_dputc(char ch, int secure)
41*91f16700Schasinglulu {
42*91f16700Schasinglulu 	unsigned i;
43*91f16700Schasinglulu 	struct dputc_state *s = &dputc_state[!secure];
44*91f16700Schasinglulu 
45*91f16700Schasinglulu 	if (trusty_disable_serial_debug)
46*91f16700Schasinglulu 		return;
47*91f16700Schasinglulu 
48*91f16700Schasinglulu 	s->linebuf[s->l++] = ch;
49*91f16700Schasinglulu 	if (s->l == sizeof(s->linebuf) || ch == '\n') {
50*91f16700Schasinglulu 		if (secure)
51*91f16700Schasinglulu 			printf("secure os: ");
52*91f16700Schasinglulu 		else
53*91f16700Schasinglulu 			printf("non-secure os: ");
54*91f16700Schasinglulu 		for (i = 0; i < s->l; i++) {
55*91f16700Schasinglulu 			putchar(s->linebuf[i]);
56*91f16700Schasinglulu 		}
57*91f16700Schasinglulu 		if (ch != '\n') {
58*91f16700Schasinglulu 			printf(" <...>\n");
59*91f16700Schasinglulu 		}
60*91f16700Schasinglulu 		s->l = 0;
61*91f16700Schasinglulu 	}
62*91f16700Schasinglulu }
63*91f16700Schasinglulu 
64*91f16700Schasinglulu static uint64_t trusty_get_reg_base(uint32_t reg)
65*91f16700Schasinglulu {
66*91f16700Schasinglulu 	switch (reg) {
67*91f16700Schasinglulu 	case SMC_GET_GIC_BASE_GICD:
68*91f16700Schasinglulu 		return PLAT_ARM_GICD_BASE;
69*91f16700Schasinglulu 
70*91f16700Schasinglulu 	case SMC_GET_GIC_BASE_GICC:
71*91f16700Schasinglulu 		return PLAT_ARM_GICC_BASE;
72*91f16700Schasinglulu 
73*91f16700Schasinglulu 	case SMC_GET_GIC_BASE_GICR:
74*91f16700Schasinglulu 		return PLAT_ARM_GICR_BASE;
75*91f16700Schasinglulu 
76*91f16700Schasinglulu 	default:
77*91f16700Schasinglulu 		NOTICE("%s(0x%x) unknown reg\n", __func__, reg);
78*91f16700Schasinglulu 		return SMC_UNK;
79*91f16700Schasinglulu 	}
80*91f16700Schasinglulu }
81*91f16700Schasinglulu 
82*91f16700Schasinglulu static uintptr_t trusty_generic_platform_smc(uint32_t smc_fid,
83*91f16700Schasinglulu 			 u_register_t x1,
84*91f16700Schasinglulu 			 u_register_t x2,
85*91f16700Schasinglulu 			 u_register_t x3,
86*91f16700Schasinglulu 			 u_register_t x4,
87*91f16700Schasinglulu 			 void *cookie,
88*91f16700Schasinglulu 			 void *handle,
89*91f16700Schasinglulu 			 u_register_t flags)
90*91f16700Schasinglulu {
91*91f16700Schasinglulu 	switch (smc_fid) {
92*91f16700Schasinglulu 	case SMC_FC_DEBUG_PUTC:
93*91f16700Schasinglulu 		trusty_dputc(x1, is_caller_secure(flags));
94*91f16700Schasinglulu 		SMC_RET1(handle, 0);
95*91f16700Schasinglulu 
96*91f16700Schasinglulu 	case SMC_FC_GET_REG_BASE:
97*91f16700Schasinglulu 	case SMC_FC64_GET_REG_BASE:
98*91f16700Schasinglulu 		SMC_RET1(handle, trusty_get_reg_base(x1));
99*91f16700Schasinglulu 
100*91f16700Schasinglulu 	default:
101*91f16700Schasinglulu 		NOTICE("%s(0x%x, 0x%lx) unknown smc\n", __func__, smc_fid, x1);
102*91f16700Schasinglulu 		SMC_RET1(handle, SMC_UNK);
103*91f16700Schasinglulu 	}
104*91f16700Schasinglulu }
105*91f16700Schasinglulu 
106*91f16700Schasinglulu /* Define a SPD runtime service descriptor for fast SMC calls */
107*91f16700Schasinglulu DECLARE_RT_SVC(
108*91f16700Schasinglulu 	trusty_fast,
109*91f16700Schasinglulu 
110*91f16700Schasinglulu 	SMC_ENTITY_PLATFORM_MONITOR,
111*91f16700Schasinglulu 	SMC_ENTITY_PLATFORM_MONITOR,
112*91f16700Schasinglulu 	SMC_TYPE_FAST,
113*91f16700Schasinglulu 	NULL,
114*91f16700Schasinglulu 	trusty_generic_platform_smc
115*91f16700Schasinglulu );
116*91f16700Schasinglulu 
117