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