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