std_svc_setup.c 3.81 KB
Newer Older
1
/*
2
 * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
3
 *
dp-arm's avatar
dp-arm committed
4
 * SPDX-License-Identifier: BSD-3-Clause
5
6
 */

7
#include <assert.h>
8
#include <stdint.h>
9
10
11
12
13
14
15
16

#include <common/debug.h>
#include <common/runtime_svc.h>
#include <lib/el3_runtime/cpu_data.h>
#include <lib/pmf/pmf.h>
#include <lib/psci/psci.h>
#include <lib/runtime_instr.h>
#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 <services/trng_svc.h>
21
22
#include <smccc_helpers.h>
#include <tools_share/uuid.h>
23
24

/* Standard Service UUID */
25
26
27
28
29
30
31
static uuid_t arm_svc_uid = {
	{0x5b, 0x90, 0x8d, 0x10},
	{0x63, 0xf8},
	{0xe8, 0x47},
	0xae, 0x2d,
	{0xc0, 0xfb, 0x56, 0x41, 0xf6, 0xe2}
};
32

33
34
35
36
/* Setup Standard Services */
static int32_t std_svc_setup(void)
{
	uintptr_t svc_arg;
37
	int ret = 0;
38
39
40
41
42

	svc_arg = get_arm_std_svc_args(PSCI_FID_MASK);
	assert(svc_arg);

	/*
43
	 * PSCI is one of the specifications implemented as a Standard Service.
44
45
	 * The `psci_setup()` also does EL3 architectural setup.
	 */
46
47
48
49
	if (psci_setup((const psci_lib_args_t *)svc_arg) != PSCI_E_SUCCESS) {
		ret = 1;
	}

50
#if SPM_MM
51
	if (spm_mm_setup() != 0) {
52
53
54
55
		ret = 1;
	}
#endif

56
57
58
59
60
61
#if defined(SPD_spmd)
	if (spmd_setup() != 0) {
		ret = 1;
	}
#endif

Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
62
63
64
65
66
#if SDEI_SUPPORT
	/* SDEI initialisation */
	sdei_init();
#endif

67
68
	trng_setup();

69
	return ret;
70
71
}

72
73
74
75
/*
 * Top-level Standard Service SMC handler. This handler will in turn dispatch
 * calls to PSCI SMC handler
 */
76
static uintptr_t std_svc_smc_handler(uint32_t smc_fid,
77
78
79
80
			     u_register_t x1,
			     u_register_t x2,
			     u_register_t x3,
			     u_register_t x4,
81
82
			     void *cookie,
			     void *handle,
83
			     u_register_t flags)
84
85
86
87
88
89
{
	/*
	 * Dispatch PSCI calls to PSCI SMC handler and return its return
	 * value
	 */
	if (is_psci_fid(smc_fid)) {
dp-arm's avatar
dp-arm committed
90
91
92
		uint64_t ret;

#if ENABLE_RUNTIME_INSTRUMENTATION
93
94
95
96
97

		/*
		 * Flush cache line so that even if CPU power down happens
		 * the timestamp update is reflected in memory.
		 */
dp-arm's avatar
dp-arm committed
98
99
		PMF_WRITE_TIMESTAMP(rt_instr_svc,
		    RT_INSTR_ENTER_PSCI,
100
		    PMF_CACHE_MAINT,
dp-arm's avatar
dp-arm committed
101
102
103
104
105
106
107
108
109
110
111
112
113
		    get_cpu_data(cpu_data_pmf_ts[CPU_DATA_PMF_TS0_IDX]));
#endif

		ret = psci_smc_handler(smc_fid, x1, x2, x3, x4,
		    cookie, handle, flags);

#if ENABLE_RUNTIME_INSTRUMENTATION
		PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
		    RT_INSTR_EXIT_PSCI,
		    PMF_NO_CACHE_MAINT);
#endif

		SMC_RET1(handle, ret);
114
115
	}

116
#if SPM_MM
117
118
119
120
	/*
	 * Dispatch SPM calls to SPM SMC handler and return its return
	 * value
	 */
121
122
123
	if (is_spm_mm_fid(smc_fid)) {
		return spm_mm_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
					  handle, flags);
124
125
126
	}
#endif

127
128
#if defined(SPD_spmd)
	/*
J-Alves's avatar
J-Alves committed
129
	 * Dispatch FFA calls to the FFA SMC handler implemented by the SPM
130
131
	 * dispatcher and return its return value
	 */
J-Alves's avatar
J-Alves committed
132
	if (is_ffa_fid(smc_fid)) {
133
134
135
136
137
		return spmd_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
					handle, flags);
	}
#endif

Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
138
139
140
141
142
143
144
#if SDEI_SUPPORT
	if (is_sdei_fid(smc_fid)) {
		return sdei_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
				flags);
	}
#endif

145
#if TRNG_SUPPORT
146
147
148
149
	if (is_trng_fid(smc_fid)) {
		return trng_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
				flags);
	}
150
#endif
151

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
	switch (smc_fid) {
	case ARM_STD_SVC_CALL_COUNT:
		/*
		 * Return the number of Standard Service Calls. PSCI is the only
		 * standard service implemented; so return number of PSCI calls
		 */
		SMC_RET1(handle, PSCI_NUM_CALLS);

	case ARM_STD_SVC_UID:
		/* Return UID to the caller */
		SMC_UUID_RET(handle, arm_svc_uid);

	case ARM_STD_SVC_VERSION:
		/* Return the version of current implementation */
		SMC_RET2(handle, STD_SVC_VERSION_MAJOR, STD_SVC_VERSION_MINOR);

	default:
169
		VERBOSE("Unimplemented Standard Service Call: 0x%x \n", smc_fid);
170
171
172
173
174
175
176
177
178
179
180
		SMC_RET1(handle, SMC_UNK);
	}
}

/* Register Standard Service Calls as runtime service */
DECLARE_RT_SVC(
		std_svc,

		OEN_STD_START,
		OEN_STD_END,
		SMC_TYPE_FAST,
181
		std_svc_setup,
182
183
		std_svc_smc_handler
);