xref: /rk3399_ARM-atf/services/std_svc/std_svc_setup.c (revision 665e71b8ea28162ec7737c1411bca3ea89e5957e)
1 /*
2  * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <stdint.h>
9 
10 #include <common/debug.h>
11 #include <common/runtime_svc.h>
12 #include <lib/el3_runtime/cpu_data.h>
13 #include <lib/pmf/pmf.h>
14 #include <lib/psci/psci.h>
15 #include <lib/runtime_instr.h>
16 #include <services/sdei.h>
17 #include <services/spm_mm_svc.h>
18 #include <services/spmd_svc.h>
19 #include <services/std_svc.h>
20 #include <smccc_helpers.h>
21 #include <tools_share/uuid.h>
22 
23 /* Standard Service UUID */
24 static uuid_t arm_svc_uid = {
25 	{0x5b, 0x90, 0x8d, 0x10},
26 	{0x63, 0xf8},
27 	{0xe8, 0x47},
28 	0xae, 0x2d,
29 	{0xc0, 0xfb, 0x56, 0x41, 0xf6, 0xe2}
30 };
31 
32 /* Setup Standard Services */
33 static int32_t std_svc_setup(void)
34 {
35 	uintptr_t svc_arg;
36 	int ret = 0;
37 
38 	svc_arg = get_arm_std_svc_args(PSCI_FID_MASK);
39 	assert(svc_arg);
40 
41 	/*
42 	 * PSCI is one of the specifications implemented as a Standard Service.
43 	 * The `psci_setup()` also does EL3 architectural setup.
44 	 */
45 	if (psci_setup((const psci_lib_args_t *)svc_arg) != PSCI_E_SUCCESS) {
46 		ret = 1;
47 	}
48 
49 #if SPM_MM
50 	if (spm_mm_setup() != 0) {
51 		ret = 1;
52 	}
53 #endif
54 
55 #if defined(SPD_spmd)
56 	if (spmd_setup() != 0) {
57 		ret = 1;
58 	}
59 #endif
60 
61 #if SDEI_SUPPORT
62 	/* SDEI initialisation */
63 	sdei_init();
64 #endif
65 
66 	return ret;
67 }
68 
69 /*
70  * Top-level Standard Service SMC handler. This handler will in turn dispatch
71  * calls to PSCI SMC handler
72  */
73 static uintptr_t std_svc_smc_handler(uint32_t smc_fid,
74 			     u_register_t x1,
75 			     u_register_t x2,
76 			     u_register_t x3,
77 			     u_register_t x4,
78 			     void *cookie,
79 			     void *handle,
80 			     u_register_t flags)
81 {
82 	/*
83 	 * Dispatch PSCI calls to PSCI SMC handler and return its return
84 	 * value
85 	 */
86 	if (is_psci_fid(smc_fid)) {
87 		uint64_t ret;
88 
89 #if ENABLE_RUNTIME_INSTRUMENTATION
90 
91 		/*
92 		 * Flush cache line so that even if CPU power down happens
93 		 * the timestamp update is reflected in memory.
94 		 */
95 		PMF_WRITE_TIMESTAMP(rt_instr_svc,
96 		    RT_INSTR_ENTER_PSCI,
97 		    PMF_CACHE_MAINT,
98 		    get_cpu_data(cpu_data_pmf_ts[CPU_DATA_PMF_TS0_IDX]));
99 #endif
100 
101 		ret = psci_smc_handler(smc_fid, x1, x2, x3, x4,
102 		    cookie, handle, flags);
103 
104 #if ENABLE_RUNTIME_INSTRUMENTATION
105 		PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
106 		    RT_INSTR_EXIT_PSCI,
107 		    PMF_NO_CACHE_MAINT);
108 #endif
109 
110 		SMC_RET1(handle, ret);
111 	}
112 
113 #if SPM_MM
114 	/*
115 	 * Dispatch SPM calls to SPM SMC handler and return its return
116 	 * value
117 	 */
118 	if (is_spm_mm_fid(smc_fid)) {
119 		return spm_mm_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
120 					  handle, flags);
121 	}
122 #endif
123 
124 #if defined(SPD_spmd)
125 	/*
126 	 * Dispatch SPCI calls to the SPCI SMC handler implemented by the SPM
127 	 * dispatcher and return its return value
128 	 */
129 	if (is_spci_fid(smc_fid)) {
130 		return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
131 					handle, flags);
132 	}
133 #endif
134 
135 #if SDEI_SUPPORT
136 	if (is_sdei_fid(smc_fid)) {
137 		return sdei_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
138 				flags);
139 	}
140 #endif
141 
142 	switch (smc_fid) {
143 	case ARM_STD_SVC_CALL_COUNT:
144 		/*
145 		 * Return the number of Standard Service Calls. PSCI is the only
146 		 * standard service implemented; so return number of PSCI calls
147 		 */
148 		SMC_RET1(handle, PSCI_NUM_CALLS);
149 
150 	case ARM_STD_SVC_UID:
151 		/* Return UID to the caller */
152 		SMC_UUID_RET(handle, arm_svc_uid);
153 
154 	case ARM_STD_SVC_VERSION:
155 		/* Return the version of current implementation */
156 		SMC_RET2(handle, STD_SVC_VERSION_MAJOR, STD_SVC_VERSION_MINOR);
157 
158 	default:
159 		WARN("Unimplemented Standard Service Call: 0x%x \n", smc_fid);
160 		SMC_RET1(handle, SMC_UNK);
161 	}
162 }
163 
164 /* Register Standard Service Calls as runtime service */
165 DECLARE_RT_SVC(
166 		std_svc,
167 
168 		OEN_STD_START,
169 		OEN_STD_END,
170 		SMC_TYPE_FAST,
171 		std_svc_setup,
172 		std_svc_smc_handler
173 );
174