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