std_svc_setup.c 3.15 KB
Newer Older
1
/*
2
 * Copyright (c) 2014-2018, 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>
dp-arm's avatar
dp-arm committed
8
#include <cpu_data.h>
9
#include <debug.h>
dp-arm's avatar
dp-arm committed
10
#include <pmf.h>
11
#include <psci.h>
dp-arm's avatar
dp-arm committed
12
#include <runtime_instr.h>
13
#include <runtime_svc.h>
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
14
#include <sdei.h>
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
15
#include <smccc_helpers.h>
16
#include <spm_svc.h>
17
#include <std_svc.h>
18
19
#include <stdint.h>
#include <uuid.h>
20
21
22
23
24
25

/* Standard Service UUID */
DEFINE_SVC_UUID(arm_svc_uid,
		0x108d905b, 0xf863, 0x47e8, 0xae, 0x2d,
		0xc0, 0xfb, 0x56, 0x41, 0xf6, 0xe2);

26
27
28
29
/* Setup Standard Services */
static int32_t std_svc_setup(void)
{
	uintptr_t svc_arg;
30
	int ret = 0;
31
32
33
34
35

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

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

#if ENABLE_SPM
	if (spm_setup() != 0) {
		ret = 1;
	}
#endif

Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
49
50
51
52
53
#if SDEI_SUPPORT
	/* SDEI initialisation */
	sdei_init();
#endif

54
	return ret;
55
56
}

57
58
59
60
/*
 * Top-level Standard Service SMC handler. This handler will in turn dispatch
 * calls to PSCI SMC handler
 */
61
static uintptr_t std_svc_smc_handler(uint32_t smc_fid,
62
63
64
65
			     u_register_t x1,
			     u_register_t x2,
			     u_register_t x3,
			     u_register_t x4,
66
67
			     void *cookie,
			     void *handle,
68
			     u_register_t flags)
69
70
71
72
73
74
{
	/*
	 * 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
75
76
77
		uint64_t ret;

#if ENABLE_RUNTIME_INSTRUMENTATION
78
79
80
81
82

		/*
		 * 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
83
84
		PMF_WRITE_TIMESTAMP(rt_instr_svc,
		    RT_INSTR_ENTER_PSCI,
85
		    PMF_CACHE_MAINT,
dp-arm's avatar
dp-arm committed
86
87
88
89
90
91
92
93
94
95
96
97
98
		    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);
99
100
	}

101
102
103
104
105
106
107
108
109
110
111
#if ENABLE_SPM
	/*
	 * Dispatch SPM calls to SPM SMC handler and return its return
	 * value
	 */
	if (is_spm_fid(smc_fid)) {
		return spm_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
				       handle, flags);
	}
#endif

Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
112
113
114
115
116
117
118
#if SDEI_SUPPORT
	if (is_sdei_fid(smc_fid)) {
		return sdei_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle,
				flags);
	}
#endif

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
	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:
		WARN("Unimplemented Standard Service Call: 0x%x \n", smc_fid);
		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,
148
		std_svc_setup,
149
150
		std_svc_smc_handler
);