smccc.h 3.47 KB
Newer Older
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
1
2
3
4
5
6
/*
 * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
 *
 * 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
23

#if SMCCC_MAJOR_VERSION == 1
# define SMCCC_MINOR_VERSION U(1)
24
# include <lib/smccc_v1.h>
25
26
#elif SMCCC_MAJOR_VERSION == 2
# define SMCCC_MINOR_VERSION U(0)
27
# include <lib/smccc_v2.h>
28
29
#else
# error "Unsupported version of SMCCC."
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
30
#endif
31
32
33
34

/* Various flags passed to SMC handlers */
#define SMC_FROM_SECURE		(U(0) << 0)
#define SMC_FROM_NON_SECURE	(U(1) << 0)
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
35
36
37
38
39

#ifndef __ASSEMBLY__

#include <stdint.h>

40
41
#include <lib/cassert.h>

42
43
#define is_caller_non_secure(_f)	(((_f) & SMC_FROM_NON_SECURE) != U(0))
#define is_caller_secure(_f)		(!is_caller_non_secure(_f))
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
44
45

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

/* The macro below is used to identify a Arm Architectural Service SMC call */
49
#define is_arm_arch_svc_call(_fid)	(GET_SMC_OEN(_fid) == OEN_ARM_START)
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
50
51
52
53
54
55
56
57
58
59
60

/* The macro below is used to identify a valid Fast SMC call */
#define is_valid_fast_smc(_fid)		((!(((_fid) >> 16) & U(0xff))) && \
					   (GET_SMC_TYPE(_fid) == SMC_TYPE_FAST))

/*
 * 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
 */
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#define DEFINE_SVC_UUID2(_name, _tl, _tm, _th, _cl, _ch,		\
		_n0, _n1, _n2, _n3, _n4, _n5)				\
	CASSERT((uint32_t)(_tl) != (uint32_t) SMC_UNK, invalid_svc_uuid);\
	static const uuid_t _name = {					\
		{(_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 }			\
	}
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
76

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
 * 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]))

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
104
#endif /*__ASSEMBLY__*/
105
#endif /* SMCCC_H */