smccc.h 6.08 KB
Newer Older
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
1
/*
2
 * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
3
4
5
6
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

7
8
#ifndef SMCCC_H
#define SMCCC_H
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
9

10
#include <lib/utils_def.h>
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
11

12
13
14
15
16
#define SMCCC_VERSION_MAJOR_SHIFT	U(16)
#define SMCCC_VERSION_MAJOR_MASK	U(0x7FFF)
#define SMCCC_VERSION_MINOR_SHIFT	U(0)
#define SMCCC_VERSION_MINOR_MASK	U(0xFFFF)
#define MAKE_SMCCC_VERSION(_major, _minor) \
17
18
19
20
	((((uint32_t)(_major) & SMCCC_VERSION_MAJOR_MASK) << \
						SMCCC_VERSION_MAJOR_SHIFT) \
	| (((uint32_t)(_minor) & SMCCC_VERSION_MINOR_MASK) << \
						SMCCC_VERSION_MINOR_SHIFT))
21

22
#define SMCCC_MAJOR_VERSION U(1)
23
#define SMCCC_MINOR_VERSION U(2)
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

/*******************************************************************************
 * Bit definitions inside the function id as per the SMC calling convention
 ******************************************************************************/
#define FUNCID_TYPE_SHIFT		U(31)
#define FUNCID_TYPE_MASK		U(0x1)
#define FUNCID_TYPE_WIDTH		U(1)

#define FUNCID_CC_SHIFT			U(30)
#define FUNCID_CC_MASK			U(0x1)
#define FUNCID_CC_WIDTH			U(1)

#define FUNCID_OEN_SHIFT		U(24)
#define FUNCID_OEN_MASK			U(0x3f)
#define FUNCID_OEN_WIDTH		U(6)

#define FUNCID_NUM_SHIFT		U(0)
#define FUNCID_NUM_MASK			U(0xffff)
#define FUNCID_NUM_WIDTH		U(16)

44
45
#define GET_SMC_NUM(id)			(((id) >> FUNCID_NUM_SHIFT) & \
					 FUNCID_NUM_MASK)
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#define GET_SMC_TYPE(id)		(((id) >> FUNCID_TYPE_SHIFT) & \
					 FUNCID_TYPE_MASK)
#define GET_SMC_CC(id)			(((id) >> FUNCID_CC_SHIFT) & \
					 FUNCID_CC_MASK)
#define GET_SMC_OEN(id)			(((id) >> FUNCID_OEN_SHIFT) & \
					 FUNCID_OEN_MASK)

/*******************************************************************************
 * Owning entity number definitions inside the function id as per the SMC
 * calling convention
 ******************************************************************************/
#define OEN_ARM_START			U(0)
#define OEN_ARM_END			U(0)
#define OEN_CPU_START			U(1)
#define OEN_CPU_END			U(1)
#define OEN_SIP_START			U(2)
#define OEN_SIP_END			U(2)
#define OEN_OEM_START			U(3)
#define OEN_OEM_END			U(3)
#define OEN_STD_START			U(4)	/* Standard Service Calls */
#define OEN_STD_END			U(4)
#define OEN_STD_HYP_START		U(5)	/* Standard Hypervisor Service calls */
#define OEN_STD_HYP_END			U(5)
#define OEN_VEN_HYP_START		U(6)	/* Vendor Hypervisor Service calls */
#define OEN_VEN_HYP_END			U(6)
#define OEN_TAP_START			U(48)	/* Trusted Applications */
#define OEN_TAP_END			U(49)
#define OEN_TOS_START			U(50)	/* Trusted OS */
#define OEN_TOS_END			U(63)
#define OEN_LIMIT			U(64)

/* Flags and error codes */
#define SMC_64				U(1)
#define SMC_32				U(0)

81
82
#define SMC_TYPE_FAST			UL(1)
#define SMC_TYPE_YIELD			UL(0)
83
84
85
86

#define SMC_OK				ULL(0)
#define SMC_UNK				-1
#define SMC_PREEMPTED			-2	/* Not defined by the SMCCC */
87

88
89
90
91
92
93
/* Return codes for Arm Architecture Service SMC calls */
#define SMC_ARCH_CALL_SUCCESS		0
#define SMC_ARCH_CALL_NOT_SUPPORTED	-1
#define SMC_ARCH_CALL_NOT_REQUIRED	-2
#define SMC_ARCH_CALL_INVAL_PARAM	-3

94
95
96
/* Various flags passed to SMC handlers */
#define SMC_FROM_SECURE		(U(0) << 0)
#define SMC_FROM_NON_SECURE	(U(1) << 0)
johpow01's avatar
johpow01 committed
97
98
#define SMC_FROM_REALM		(U(3) << 0)
#define SMC_FROM_MASK		U(3)
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
99

100
#ifndef __ASSEMBLER__
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
101
102
103

#include <stdint.h>

104
105
#include <lib/cassert.h>

johpow01's avatar
johpow01 committed
106
107
108
109
110
111
#if ENABLE_RME
#define is_caller_non_secure(_f)	(((_f) & SMC_FROM_MASK) == SMC_FROM_NON_SECURE)
#define is_caller_secure(_f)		(((_f) & SMC_FROM_MASK) == SMC_FROM_SECURE)
#define is_caller_realm(_f)		(((_f) & SMC_FROM_MASK) == SMC_FROM_REALM)
#define caller_sec_state(_f)		((_f) & SMC_FROM_MASK)
#else /* ENABLE_RME */
112
113
#define is_caller_non_secure(_f)	(((_f) & SMC_FROM_NON_SECURE) != U(0))
#define is_caller_secure(_f)		(!is_caller_non_secure(_f))
johpow01's avatar
johpow01 committed
114
#endif /* ENABLE_RME */
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
115
116

/* The macro below is used to identify a Standard Service SMC call */
117
#define is_std_svc_call(_fid)		(GET_SMC_OEN(_fid) == OEN_STD_START)
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
118
119

/* The macro below is used to identify a Arm Architectural Service SMC call */
120
#define is_arm_arch_svc_call(_fid)	(GET_SMC_OEN(_fid) == OEN_ARM_START)
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
121
122
123

/* The macro below is used to identify a valid Fast SMC call */
#define is_valid_fast_smc(_fid)		((!(((_fid) >> 16) & U(0xff))) && \
124
125
					   (GET_SMC_TYPE(_fid)		\
					    == (uint32_t)SMC_TYPE_FAST))
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
126
127
128
129
130
131
132

/*
 * Macro to define UUID for services. Apart from defining and initializing a
 * uuid_t structure, this macro verifies that the first word of the defined UUID
 * does not equal SMC_UNK. This is to ensure that the caller won't mistake the
 * returned UUID in x0 for an invalid SMC error return
 */
133
134
#define DEFINE_SVC_UUID2(_name, _tl, _tm, _th, _cl, _ch,		\
		_n0, _n1, _n2, _n3, _n4, _n5)				\
Jimmy Brisson's avatar
Jimmy Brisson committed
135
136
	CASSERT((uint32_t)(_tl) != (uint32_t)SMC_UNK,			\
		invalid_svc_uuid_##_name);				\
137
	static const uuid_t _name = {					\
138
139
140
141
142
143
144
145
146
147
		{((_tl) >> 24) & 0xFF,					\
		 ((_tl) >> 16) & 0xFF,					\
		 ((_tl) >> 8)  & 0xFF,					\
		 ((_tl) & 0xFF)},					\
		{((_tm) >> 8) & 0xFF,					\
		 ((_tm)  & 0xFF)},					\
		{((_th) >> 8) & 0xFF,					\
		 ((_th) & 0xFF)},					\
		(_cl), (_ch),						\
		{ (_n0), (_n1), (_n2), (_n3), (_n4), (_n5) }		\
148
	}
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
149

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*
 * Return a UUID in the SMC return registers.
 *
 * Acccording to section 5.3 of the SMCCC, UUIDs are returned as a single
 * 128-bit value using the SMC32 calling convention. This value is mapped to
 * argument registers x0-x3 on AArch64 (resp. r0-r3 on AArch32). x0 for example
 * shall hold bytes 0 to 3, with byte 0 in the low-order bits.
 */
static inline uint32_t smc_uuid_word(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3)
{
	return ((uint32_t) b0) | (((uint32_t) b1) << 8) |
		(((uint32_t) b2) << 16) | (((uint32_t) b3) << 24);
}

#define SMC_UUID_RET(_h, _uuid)							\
	SMC_RET4(handle,							\
		smc_uuid_word((_uuid).time_low[0], (_uuid).time_low[1],		\
			      (_uuid).time_low[2], (_uuid).time_low[3]),	\
		smc_uuid_word((_uuid).time_mid[0], (_uuid).time_mid[1],		\
			      (_uuid).time_hi_and_version[0],			\
			      (_uuid).time_hi_and_version[1]),			\
		smc_uuid_word((_uuid).clock_seq_hi_and_reserved,		\
			      (_uuid).clock_seq_low, (_uuid).node[0],		\
			      (_uuid).node[1]),					\
		smc_uuid_word((_uuid).node[2], (_uuid).node[3],			\
			      (_uuid).node[4], (_uuid).node[5]))

177
#endif /*__ASSEMBLER__*/
178
#endif /* SMCCC_H */