xref: /optee_os/core/include/drivers/stm32_rif.h (revision fc9ea0db8ddf8150754aac716691616c7e3f404a)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2022-2024, STMicroelectronics
4  */
5 
6 #ifndef __DRIVERS_STM32_RIF_H
7 #define __DRIVERS_STM32_RIF_H
8 
9 #include <dt-bindings/firewall/stm32mp25-rif.h>
10 #include <tee_api_types.h>
11 #include <types_ext.h>
12 #include <util.h>
13 
14 /*
15  * CIDCFGR register
16  */
17 #define _CIDCFGR_CFEN			BIT(0)
18 #define _CIDCFGR_SEMEN			BIT(1)
19 #define _CIDCFGR_SEMWL(x)		BIT(SEMWL_SHIFT + (x))
20 
21 /*
22  * SEMCR register
23  */
24 #define _SEMCR_MUTEX			BIT(0)
25 #define _SEMCR_SEMCID_SHIFT		U(4)
26 #define _SEMCR_SEMCID_MASK		GENMASK_32(6, 4)
27 
28 /*
29  * Miscellaneous
30  */
31 #define MAX_CID_SUPPORTED		U(8)
32 
33 #define SCID_SHIFT			U(4)
34 #define SEMWL_SHIFT			U(16)
35 #define RIF_ID_SHIFT			U(24)
36 
37 #define RIF_ID_MASK			GENMASK_32(31, 24)
38 #define RIF_CHANNEL_ID(x)		((RIF_ID_MASK & (x)) >> RIF_ID_SHIFT)
39 
40 #define RIFPROT_SEC			BIT(8)
41 #define RIFPROT_PRIV			BIT(9)
42 #define RIFPROT_LOCK			BIT(10)
43 
44 /**
45  * struct rif_conf_data - Structure containing RIF configuration data
46  *
47  * @access_mask: Array of the masks of the registers which will be configured.
48  * @sec_conf: Secure configuration registers.
49  * @priv_conf: Privilege configuration registers.
50  * @cid_confs: CID filtering configuration register value for a peripheral
51  *             resource (e.g: GPIO pins, FMC controllers)
52  * @lock_conf: RIF configuration locking registers
53  *
54  * For a hardware block having 56 channels, there will be 56 cid_confs
55  * registers and 2 sec_conf and priv_conf registers
56  */
57 struct rif_conf_data {
58 	uint32_t *access_mask;
59 	uint32_t *sec_conf;
60 	uint32_t *priv_conf;
61 	uint32_t *cid_confs;
62 	uint32_t *lock_conf;
63 };
64 
65 #ifdef CFG_STM32_RIF
66 /**
67  * stm32_rif_scid_ok() - Check if a given static CID configuration authorizes
68  *			 access to a given CID
69  *
70  * @cidcfgr: Value of the CIDCFGR register
71  * @scid_m: Mask of the static CID in the register
72  * @cid_to_check: CID of the target compartment
73  *
74  * Returns true if given CID is authorized, false otherwise.
75  */
76 static inline bool stm32_rif_scid_ok(uint32_t cidcfgr, uint32_t scid_m,
77 				     uint32_t cid_to_check)
78 {
79 	return (cidcfgr & scid_m) == SHIFT_U32(cid_to_check, SCID_SHIFT) &&
80 	       !(cidcfgr & _CIDCFGR_SEMEN);
81 }
82 
83 /**
84  * stm32_rif_semaphore_enabled_and_ok() - Check if semaphore mode is enabled and
85  *					  that a given CID can request the
86  *					  semaphore ownership
87  *
88  * @cidcfgr: Value of the cidcfgr register
89  * @cid_to_check: CID to check
90  *
91  * Returns true if the requested CID can request the semaphore ownership,
92  * false otherwise.
93  */
94 static inline bool stm32_rif_semaphore_enabled_and_ok(uint32_t cidcfgr,
95 						      uint32_t cid_to_check)
96 {
97 	return (cidcfgr & _CIDCFGR_CFEN) && (cidcfgr & _CIDCFGR_SEMEN) &&
98 	       (cidcfgr & _CIDCFGR_SEMWL(cid_to_check));
99 }
100 
101 /**
102  * stm32_rifsc_check_tdcid() - Check if the execution context is TDCID or not
103  *
104  * @tdcid_state: [out] Set to true if TDCID, false otherwise.
105  *
106  * Returns TEE_ERROR_DEFER_DRIVER_INIT if RIFSC driver isn't probed, TEE_SUCCESS
107  * otherwise.
108  */
109 TEE_Result stm32_rifsc_check_tdcid(bool *tdcid_state);
110 
111 /**
112  * stm32_rif_check_access() - Test peripheral access for a given compartment
113  *
114  * @cidcfgr: CIDCFGR configuration register value
115  * @semcr: SEMCR register value
116  * @nb_cid_supp: Number of supported CID for the peripheral
117  * @cid_to_check: CID of the target compartment
118  *
119  * Returns TEE_SUCCESS if access is authorized, a TEE_Result error value
120  * otherwise.
121  */
122 TEE_Result stm32_rif_check_access(uint32_t cidcfgr,
123 				  uint32_t semcr,
124 				  unsigned int nb_cid_supp,
125 				  unsigned int cid_to_check);
126 
127 /**
128  * stm32_rif_parse_cfg() - Parse RIF config from Device Tree extracted
129  *			   information
130  *
131  * @rif_conf: Configuration read in the device tree
132  * @conf_data: Buffer containing the RIF configuration to apply for a peripheral
133  * @nb_cid_supp: Number of supported CID for the peripheral
134  * @nb_channel: Number of channels for the peripheral
135  */
136 void stm32_rif_parse_cfg(uint32_t rif_conf,
137 			 struct rif_conf_data *conf_data,
138 			 unsigned int nb_cid_supp,
139 			 unsigned int nb_channel);
140 
141 /**
142  * stm32_rif_semaphore_is_available() - Checks if the _SEMCR_MUTEX bit is set
143  *
144  * @addr: Address of the register to read from
145  */
146 bool stm32_rif_semaphore_is_available(vaddr_t addr);
147 
148 /**
149  * stm32_rif_semaphore_is_available() - Acquires the semaphore by setting the
150  *					_SEMCR_MUTEX bit
151  *
152  * @addr: Address of the register to write to
153  * @nb_cid_supp: Number of CID supported
154  */
155 TEE_Result stm32_rif_acquire_semaphore(vaddr_t addr,
156 				       unsigned int nb_cid_supp);
157 
158 /**
159  * stm32_rif_semaphore_is_available() - Releases the semaphore by clearing the
160  *					_SEMCR_MUTEX bit
161  *
162  * @addr: Address of the register to write to
163  * @nb_cid_supp: Number of CID supported
164  */
165 TEE_Result stm32_rif_release_semaphore(vaddr_t addr,
166 				       unsigned int nb_cid_supp);
167 
168 /*
169  * The action to take upon an access violation depends on the platform.
170  * Therefore, it should be defined at platform level.
171  */
172 void stm32_rif_access_violation_action(void);
173 #else
174 static inline bool stm32_rif_scid_ok(uint32_t cidcfgr __unused,
175 				     uint32_t scid_m __unused,
176 				     uint32_t cid_to_check __unused)
177 {
178 	return true;
179 }
180 
181 static inline bool
182 stm32_rif_semaphore_enabled_and_ok(uint32_t cidcfgr __unused,
183 				   uint32_t cid_to_check __unused)
184 {
185 	return true;
186 }
187 
188 static inline TEE_Result stm32_rifsc_check_tdcid(bool *tdcid_state)
189 {
190 	/* Without CFG_STM32_RIF every CPU can behave as TDCID */
191 	*tdcid_state = true;
192 
193 	return TEE_SUCCESS;
194 }
195 
196 static inline TEE_Result
197 stm32_rif_check_access(uint32_t cidcfgr __unused,
198 		       uint32_t semcr __unused,
199 		       unsigned int nb_cid_supp __unused,
200 		       unsigned int cid_to_check __unused)
201 {
202 	return TEE_SUCCESS;
203 }
204 
205 static inline void
206 stm32_rif_parse_cfg(uint32_t rif_conf __unused,
207 		    struct rif_conf_data *conf_data __unused,
208 		    unsigned int nb_cid_supp __unused,
209 		    unsigned int nb_channel __unused)
210 {
211 }
212 
213 static inline bool stm32_rif_semaphore_is_available(vaddr_t addr __unused)
214 {
215 	return true;
216 }
217 
218 static inline TEE_Result
219 stm32_rif_acquire_semaphore(vaddr_t addr __unused,
220 			    unsigned int nb_cid_supp __unused)
221 {
222 	return TEE_SUCCESS;
223 }
224 
225 static inline TEE_Result
226 stm32_rif_release_semaphore(vaddr_t addr __unused,
227 			    unsigned int nb_cid_supp __unused)
228 {
229 	return TEE_SUCCESS;
230 }
231 
232 static inline void stm32_rif_access_violation_action(void)
233 {
234 }
235 #endif /* CFG_STM32_RIF */
236 #endif /* __DRIVERS_STM32_RIF_H */
237