1 /*
2  * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef SPM_MM_SVC_H
8 #define SPM_MM_SVC_H
9 
10 #include <lib/utils_def.h>
11 
12 /*
13  * The MM_VERSION_XXX definitions are used when responding to the
14  * MM_VERSION_AARCH32 service request. The version returned is different between
15  * this request and the SPM_MM_VERSION_AARCH32 request - both have been retained
16  * for compatibility.
17  */
18 #define MM_VERSION_MAJOR	U(1)
19 #define MM_VERSION_MAJOR_SHIFT	16
20 #define MM_VERSION_MAJOR_MASK	U(0x7FFF)
21 #define MM_VERSION_MINOR	U(0)
22 #define MM_VERSION_MINOR_SHIFT	0
23 #define MM_VERSION_MINOR_MASK	U(0xFFFF)
24 #define MM_VERSION_FORM(major, minor) ((major << MM_VERSION_MAJOR_SHIFT) | \
25 				       (minor))
26 #define MM_VERSION_COMPILED	MM_VERSION_FORM(MM_VERSION_MAJOR, \
27 						MM_VERSION_MINOR)
28 
29 #define SPM_MM_VERSION_MAJOR		  U(0)
30 #define SPM_MM_VERSION_MAJOR_SHIFT	  16
31 #define SPM_MM_VERSION_MAJOR_MASK	  U(0x7FFF)
32 #define SPM_MM_VERSION_MINOR		  U(1)
33 #define SPM_MM_VERSION_MINOR_SHIFT	  0
34 #define SPM_MM_VERSION_MINOR_MASK	  U(0xFFFF)
35 #define SPM_MM_VERSION_FORM(major, minor) ((major << \
36 					    SPM_MM_VERSION_MAJOR_SHIFT) | \
37 					   (minor))
38 #define SPM_MM_VERSION_COMPILED	SPM_MM_VERSION_FORM(SPM_MM_VERSION_MAJOR, \
39 						    SPM_MM_VERSION_MINOR)
40 
41 /* These macros are used to identify SPM-MM calls using the SMC function ID */
42 #define SPM_MM_FID_MASK			U(0xffff)
43 #define SPM_MM_FID_MIN_VALUE		U(0x40)
44 #define SPM_MM_FID_MAX_VALUE		U(0x7f)
45 #define is_spm_mm_fid(_fid)						 \
46 		((((_fid) & SPM_MM_FID_MASK) >= SPM_MM_FID_MIN_VALUE) && \
47 		 (((_fid) & SPM_MM_FID_MASK) <= SPM_MM_FID_MAX_VALUE))
48 
49 /*
50  * SMC IDs defined in [1] for accessing MM services from the Non-secure world.
51  * These FIDs occupy the range 0x40 - 0x5f.
52  * [1] DEN0060A_ARM_MM_Interface_Specification.pdf
53  */
54 #define MM_VERSION_AARCH32		U(0x84000040)
55 #define MM_COMMUNICATE_AARCH64		U(0xC4000041)
56 #define MM_COMMUNICATE_AARCH32		U(0x84000041)
57 
58 /*
59  * SMC IDs defined for accessing services implemented by the Secure Partition
60  * Manager from the Secure Partition(s). These services enable a partition to
61  * handle delegated events and request privileged operations from the manager.
62  * They occupy the range 0x60-0x7f.
63  */
64 #define SPM_MM_VERSION_AARCH32			U(0x84000060)
65 #define MM_SP_EVENT_COMPLETE_AARCH64		U(0xC4000061)
66 #define MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64	U(0xC4000064)
67 #define MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64	U(0xC4000065)
68 
69 #ifndef __ASSEMBLER__
70 
71 #include <stdint.h>
72 #include <lib/spinlock.h>
73 #include <lib/xlat_tables/xlat_tables_v2.h>
74 #include <lib/utils_def.h>
75 
76 /*
77  * SMC IDs defined in [1] for accessing MM services from the Non-secure world.
78  * These FIDs occupy the range 0x40 - 0x5f.
79  * [1] DEN0060A_ARM_MM_Interface_Specification.pdf
80  */
81 #define MM_INTERFACE_ID_AARCH64               U(0xC4000041)
82 #define MM_INTERFACE_ID_AARCH32               U(0x84000041)
83 
84 /*
85  * Macros used by SP_MEMORY_ATTRIBUTES_SET_AARCH64.
86  */
87 
88 #define SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS    U(0)
89 #define SP_MEMORY_ATTRIBUTES_ACCESS_RW          U(1)
90 /* Value U(2) is reserved. */
91 #define SP_MEMORY_ATTRIBUTES_ACCESS_RO          U(3)
92 #define SP_MEMORY_ATTRIBUTES_ACCESS_MASK        U(3)
93 #define SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT       U(0)
94 
95 #define SP_MEMORY_ATTRIBUTES_EXEC               (U(0) << 2)
96 #define SP_MEMORY_ATTRIBUTES_NON_EXEC           (U(1) << 2)
97 
98 
99 /* SPM error codes. */
100 #define SPM_SUCCESS		  0
101 #define SPM_NOT_SUPPORTED	 -1
102 #define SPM_INVALID_PARAMETER	 -2
103 #define SPM_DENIED		 -3
104 #define SPM_NO_MEMORY		 -5
105 
106 typedef enum sp_state {
107 	SP_STATE_RESET = 0,
108 	SP_STATE_IDLE,
109 	SP_STATE_BUSY
110 } sp_state_t;
111 
112 typedef struct sp_context {
113 	uint64_t c_rt_ctx;
114 	cpu_context_t cpu_ctx;
115 	xlat_ctx_t *xlat_ctx_handle;
116 	uint64_t   sp_stack_base;
117 	uint64_t   sp_pcpu_stack_size;
118 
119 	sp_state_t state;
120 	spinlock_t state_lock;
121 } sp_context_t;
122 
123 /* Setup Function for different SP types. */
124 void spm_sp_common_setup(sp_context_t *sp_ctx);
125 void spm_el0_sp_setup(sp_context_t *sp_ctx);
126 void spm_el1_sp_setup(sp_context_t *sp_ctx);
127 
128 int32_t spm_memory_attributes_get_smc_handler(sp_context_t *sp_ctx,
129 					      uintptr_t base_va);
130 int spm_memory_attributes_set_smc_handler(sp_context_t *sp_ctx,
131 					  u_register_t page_address,
132 					  u_register_t pages_count,
133 					  u_register_t smc_attributes);
134 
135 void sp_state_set(sp_context_t *sp_ptr, sp_state_t state);
136 void sp_state_wait_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to);
137 int sp_state_try_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to);
138 uint64_t spm_sp_synchronous_entry(sp_context_t *ctx);
139 __dead2 void spm_sp_synchronous_exit(sp_context_t *ctx, uint64_t rc);
140 
141 int32_t spm_mm_setup(void);
142 
143 uint64_t spm_mm_smc_handler(uint32_t smc_fid,
144 			    uint64_t x1,
145 			    uint64_t x2,
146 			    uint64_t x3,
147 			    uint64_t x4,
148 			    void *cookie,
149 			    void *handle,
150 			    uint64_t flags);
151 
152 /* Helper to enter a secure partition */
153 uint64_t spm_mm_sp_call(uint32_t smc_fid,
154 			uint64_t x1,
155 			uint64_t x2,
156 			uint64_t x3);
157 
158 #endif /* __ASSEMBLER__ */
159 
160 #endif /* SPM_MM_SVC_H */
161