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