11506f47aSGatien Chevallier /* SPDX-License-Identifier: BSD-2-Clause */
21506f47aSGatien Chevallier /*
31506f47aSGatien Chevallier * Copyright (c) 2022-2024, STMicroelectronics
41506f47aSGatien Chevallier */
51506f47aSGatien Chevallier
61506f47aSGatien Chevallier #ifndef __DRIVERS_STM32_RIF_H
71506f47aSGatien Chevallier #define __DRIVERS_STM32_RIF_H
81506f47aSGatien Chevallier
91506f47aSGatien Chevallier #include <dt-bindings/firewall/stm32mp25-rif.h>
101506f47aSGatien Chevallier #include <tee_api_types.h>
111506f47aSGatien Chevallier #include <types_ext.h>
121506f47aSGatien Chevallier #include <util.h>
131506f47aSGatien Chevallier
141506f47aSGatien Chevallier /*
151506f47aSGatien Chevallier * CIDCFGR register
161506f47aSGatien Chevallier */
171506f47aSGatien Chevallier #define _CIDCFGR_CFEN BIT(0)
18*646ad62bSGatien Chevallier #define _CIDCFGR_SCID_SHIFT U(4)
191506f47aSGatien Chevallier #define _CIDCFGR_SEMEN BIT(1)
20*646ad62bSGatien Chevallier #define _CIDCFGR_SEMWL_SHIFT U(16)
21*646ad62bSGatien Chevallier #define _CIDCFGR_SEMWL(x) BIT(_CIDCFGR_SEMWL_SHIFT + (x))
221506f47aSGatien Chevallier
231506f47aSGatien Chevallier /*
241506f47aSGatien Chevallier * SEMCR register
251506f47aSGatien Chevallier */
261506f47aSGatien Chevallier #define _SEMCR_MUTEX BIT(0)
271506f47aSGatien Chevallier #define _SEMCR_SEMCID_SHIFT U(4)
281506f47aSGatien Chevallier #define _SEMCR_SEMCID_MASK GENMASK_32(6, 4)
291506f47aSGatien Chevallier
301506f47aSGatien Chevallier /*
311506f47aSGatien Chevallier * Miscellaneous
321506f47aSGatien Chevallier */
331506f47aSGatien Chevallier #define MAX_CID_SUPPORTED U(8)
341506f47aSGatien Chevallier
35*646ad62bSGatien Chevallier #define RIF_CHANNEL_ID(x) (RIF_PER_ID_MASK & (x))
361506f47aSGatien Chevallier
371506f47aSGatien Chevallier /**
381506f47aSGatien Chevallier * struct rif_conf_data - Structure containing RIF configuration data
391506f47aSGatien Chevallier *
401506f47aSGatien Chevallier * @access_mask: Array of the masks of the registers which will be configured.
411506f47aSGatien Chevallier * @sec_conf: Secure configuration registers.
421506f47aSGatien Chevallier * @priv_conf: Privilege configuration registers.
431506f47aSGatien Chevallier * @cid_confs: CID filtering configuration register value for a peripheral
441506f47aSGatien Chevallier * resource (e.g: GPIO pins, FMC controllers)
451506f47aSGatien Chevallier * @lock_conf: RIF configuration locking registers
461506f47aSGatien Chevallier *
471506f47aSGatien Chevallier * For a hardware block having 56 channels, there will be 56 cid_confs
481506f47aSGatien Chevallier * registers and 2 sec_conf and priv_conf registers
491506f47aSGatien Chevallier */
501506f47aSGatien Chevallier struct rif_conf_data {
511506f47aSGatien Chevallier uint32_t *access_mask;
521506f47aSGatien Chevallier uint32_t *sec_conf;
531506f47aSGatien Chevallier uint32_t *priv_conf;
541506f47aSGatien Chevallier uint32_t *cid_confs;
551506f47aSGatien Chevallier uint32_t *lock_conf;
561506f47aSGatien Chevallier };
571506f47aSGatien Chevallier
581506f47aSGatien Chevallier #ifdef CFG_STM32_RIF
591506f47aSGatien Chevallier /**
601506f47aSGatien Chevallier * stm32_rif_scid_ok() - Check if a given static CID configuration authorizes
611506f47aSGatien Chevallier * access to a given CID
621506f47aSGatien Chevallier *
631506f47aSGatien Chevallier * @cidcfgr: Value of the CIDCFGR register
641506f47aSGatien Chevallier * @scid_m: Mask of the static CID in the register
651506f47aSGatien Chevallier * @cid_to_check: CID of the target compartment
661506f47aSGatien Chevallier *
671506f47aSGatien Chevallier * Returns true if given CID is authorized, false otherwise.
681506f47aSGatien Chevallier */
stm32_rif_scid_ok(uint32_t cidcfgr,uint32_t scid_m,uint32_t cid_to_check)691506f47aSGatien Chevallier static inline bool stm32_rif_scid_ok(uint32_t cidcfgr, uint32_t scid_m,
701506f47aSGatien Chevallier uint32_t cid_to_check)
711506f47aSGatien Chevallier {
72*646ad62bSGatien Chevallier return (cidcfgr & scid_m) ==
73*646ad62bSGatien Chevallier SHIFT_U32(cid_to_check, _CIDCFGR_SCID_SHIFT) &&
741506f47aSGatien Chevallier !(cidcfgr & _CIDCFGR_SEMEN);
751506f47aSGatien Chevallier }
761506f47aSGatien Chevallier
771506f47aSGatien Chevallier /**
781506f47aSGatien Chevallier * stm32_rif_semaphore_enabled_and_ok() - Check if semaphore mode is enabled and
791506f47aSGatien Chevallier * that a given CID can request the
801506f47aSGatien Chevallier * semaphore ownership
811506f47aSGatien Chevallier *
821506f47aSGatien Chevallier * @cidcfgr: Value of the cidcfgr register
8356b8883fSGatien Chevallier * @cid_to_check: CID to check
841506f47aSGatien Chevallier *
8556b8883fSGatien Chevallier * Returns true if the requested CID can request the semaphore ownership,
861506f47aSGatien Chevallier * false otherwise.
871506f47aSGatien Chevallier */
stm32_rif_semaphore_enabled_and_ok(uint32_t cidcfgr,uint32_t cid_to_check)881506f47aSGatien Chevallier static inline bool stm32_rif_semaphore_enabled_and_ok(uint32_t cidcfgr,
8956b8883fSGatien Chevallier uint32_t cid_to_check)
901506f47aSGatien Chevallier {
911506f47aSGatien Chevallier return (cidcfgr & _CIDCFGR_CFEN) && (cidcfgr & _CIDCFGR_SEMEN) &&
9256b8883fSGatien Chevallier (cidcfgr & _CIDCFGR_SEMWL(cid_to_check));
931506f47aSGatien Chevallier }
941506f47aSGatien Chevallier
951506f47aSGatien Chevallier /**
96cd187630SGatien Chevallier * stm32_rifsc_check_tdcid() - Check if the execution context is TDCID or not
97cd187630SGatien Chevallier *
98cd187630SGatien Chevallier * @tdcid_state: [out] Set to true if TDCID, false otherwise.
99cd187630SGatien Chevallier *
100cd187630SGatien Chevallier * Returns TEE_ERROR_DEFER_DRIVER_INIT if RIFSC driver isn't probed, TEE_SUCCESS
101cd187630SGatien Chevallier * otherwise.
102cd187630SGatien Chevallier */
103cd187630SGatien Chevallier TEE_Result stm32_rifsc_check_tdcid(bool *tdcid_state);
104cd187630SGatien Chevallier
105cd187630SGatien Chevallier /**
1061506f47aSGatien Chevallier * stm32_rif_check_access() - Test peripheral access for a given compartment
1071506f47aSGatien Chevallier *
1081506f47aSGatien Chevallier * @cidcfgr: CIDCFGR configuration register value
1091506f47aSGatien Chevallier * @semcr: SEMCR register value
1101506f47aSGatien Chevallier * @nb_cid_supp: Number of supported CID for the peripheral
1111506f47aSGatien Chevallier * @cid_to_check: CID of the target compartment
1121506f47aSGatien Chevallier *
1131506f47aSGatien Chevallier * Returns TEE_SUCCESS if access is authorized, a TEE_Result error value
1141506f47aSGatien Chevallier * otherwise.
1151506f47aSGatien Chevallier */
1161506f47aSGatien Chevallier TEE_Result stm32_rif_check_access(uint32_t cidcfgr,
1171506f47aSGatien Chevallier uint32_t semcr,
1181506f47aSGatien Chevallier unsigned int nb_cid_supp,
1191506f47aSGatien Chevallier unsigned int cid_to_check);
1201506f47aSGatien Chevallier
1211506f47aSGatien Chevallier /**
1221506f47aSGatien Chevallier * stm32_rif_parse_cfg() - Parse RIF config from Device Tree extracted
1231506f47aSGatien Chevallier * information
1241506f47aSGatien Chevallier *
1251506f47aSGatien Chevallier * @rif_conf: Configuration read in the device tree
1261506f47aSGatien Chevallier * @conf_data: Buffer containing the RIF configuration to apply for a peripheral
1271506f47aSGatien Chevallier * @nb_channel: Number of channels for the peripheral
1281506f47aSGatien Chevallier */
1291506f47aSGatien Chevallier void stm32_rif_parse_cfg(uint32_t rif_conf,
1301506f47aSGatien Chevallier struct rif_conf_data *conf_data,
1311506f47aSGatien Chevallier unsigned int nb_channel);
1321506f47aSGatien Chevallier
1331506f47aSGatien Chevallier /**
1341506f47aSGatien Chevallier * stm32_rif_semaphore_is_available() - Checks if the _SEMCR_MUTEX bit is set
1351506f47aSGatien Chevallier *
1361506f47aSGatien Chevallier * @addr: Address of the register to read from
1371506f47aSGatien Chevallier */
1381506f47aSGatien Chevallier bool stm32_rif_semaphore_is_available(vaddr_t addr);
1391506f47aSGatien Chevallier
1401506f47aSGatien Chevallier /**
1411506f47aSGatien Chevallier * stm32_rif_semaphore_is_available() - Acquires the semaphore by setting the
1421506f47aSGatien Chevallier * _SEMCR_MUTEX bit
1431506f47aSGatien Chevallier *
1441506f47aSGatien Chevallier * @addr: Address of the register to write to
1451506f47aSGatien Chevallier * @nb_cid_supp: Number of CID supported
1461506f47aSGatien Chevallier */
1471506f47aSGatien Chevallier TEE_Result stm32_rif_acquire_semaphore(vaddr_t addr,
1481506f47aSGatien Chevallier unsigned int nb_cid_supp);
1491506f47aSGatien Chevallier
1501506f47aSGatien Chevallier /**
1511506f47aSGatien Chevallier * stm32_rif_semaphore_is_available() - Releases the semaphore by clearing the
1521506f47aSGatien Chevallier * _SEMCR_MUTEX bit
1531506f47aSGatien Chevallier *
1541506f47aSGatien Chevallier * @addr: Address of the register to write to
1551506f47aSGatien Chevallier * @nb_cid_supp: Number of CID supported
1561506f47aSGatien Chevallier */
1571506f47aSGatien Chevallier TEE_Result stm32_rif_release_semaphore(vaddr_t addr,
1581506f47aSGatien Chevallier unsigned int nb_cid_supp);
1591c32a0eaSGatien Chevallier
1601c32a0eaSGatien Chevallier /*
1611c32a0eaSGatien Chevallier * The action to take upon an access violation depends on the platform.
1621c32a0eaSGatien Chevallier * Therefore, it should be defined at platform level.
1631c32a0eaSGatien Chevallier */
1641c32a0eaSGatien Chevallier void stm32_rif_access_violation_action(void);
1651506f47aSGatien Chevallier #else
stm32_rif_scid_ok(uint32_t cidcfgr __unused,uint32_t scid_m __unused,uint32_t cid_to_check __unused)166d4aec8fcSGatien Chevallier static inline bool stm32_rif_scid_ok(uint32_t cidcfgr __unused,
167d4aec8fcSGatien Chevallier uint32_t scid_m __unused,
168d4aec8fcSGatien Chevallier uint32_t cid_to_check __unused)
1691506f47aSGatien Chevallier {
1701506f47aSGatien Chevallier return true;
1711506f47aSGatien Chevallier }
1721506f47aSGatien Chevallier
173d4aec8fcSGatien Chevallier static inline bool
stm32_rif_semaphore_enabled_and_ok(uint32_t cidcfgr __unused,uint32_t cid_to_check __unused)174d4aec8fcSGatien Chevallier stm32_rif_semaphore_enabled_and_ok(uint32_t cidcfgr __unused,
175d4aec8fcSGatien Chevallier uint32_t cid_to_check __unused)
1761506f47aSGatien Chevallier {
1771506f47aSGatien Chevallier return true;
1781506f47aSGatien Chevallier }
1791506f47aSGatien Chevallier
stm32_rifsc_check_tdcid(bool * tdcid_state)180cd187630SGatien Chevallier static inline TEE_Result stm32_rifsc_check_tdcid(bool *tdcid_state)
181cd187630SGatien Chevallier {
182cd187630SGatien Chevallier /* Without CFG_STM32_RIF every CPU can behave as TDCID */
183cd187630SGatien Chevallier *tdcid_state = true;
184cd187630SGatien Chevallier
185cd187630SGatien Chevallier return TEE_SUCCESS;
186cd187630SGatien Chevallier }
187cd187630SGatien Chevallier
1881506f47aSGatien Chevallier 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)1891506f47aSGatien Chevallier stm32_rif_check_access(uint32_t cidcfgr __unused,
1901506f47aSGatien Chevallier uint32_t semcr __unused,
1911506f47aSGatien Chevallier unsigned int nb_cid_supp __unused,
1921506f47aSGatien Chevallier unsigned int cid_to_check __unused)
1931506f47aSGatien Chevallier {
1941506f47aSGatien Chevallier return TEE_SUCCESS;
1951506f47aSGatien Chevallier }
1961506f47aSGatien Chevallier
1971506f47aSGatien Chevallier static inline void
stm32_rif_parse_cfg(uint32_t rif_conf __unused,struct rif_conf_data * conf_data __unused,unsigned int nb_channel __unused)1981506f47aSGatien Chevallier stm32_rif_parse_cfg(uint32_t rif_conf __unused,
1991506f47aSGatien Chevallier struct rif_conf_data *conf_data __unused,
2001506f47aSGatien Chevallier unsigned int nb_channel __unused)
2011506f47aSGatien Chevallier {
2021506f47aSGatien Chevallier }
2031506f47aSGatien Chevallier
stm32_rif_semaphore_is_available(vaddr_t addr __unused)2041506f47aSGatien Chevallier static inline bool stm32_rif_semaphore_is_available(vaddr_t addr __unused)
2051506f47aSGatien Chevallier {
2061506f47aSGatien Chevallier return true;
2071506f47aSGatien Chevallier }
2081506f47aSGatien Chevallier
2091506f47aSGatien Chevallier static inline TEE_Result
stm32_rif_acquire_semaphore(vaddr_t addr __unused,unsigned int nb_cid_supp __unused)2101506f47aSGatien Chevallier stm32_rif_acquire_semaphore(vaddr_t addr __unused,
2111506f47aSGatien Chevallier unsigned int nb_cid_supp __unused)
2121506f47aSGatien Chevallier {
2131506f47aSGatien Chevallier return TEE_SUCCESS;
2141506f47aSGatien Chevallier }
2151506f47aSGatien Chevallier
2161506f47aSGatien Chevallier static inline TEE_Result
stm32_rif_release_semaphore(vaddr_t addr __unused,unsigned int nb_cid_supp __unused)2171506f47aSGatien Chevallier stm32_rif_release_semaphore(vaddr_t addr __unused,
2181506f47aSGatien Chevallier unsigned int nb_cid_supp __unused)
2191506f47aSGatien Chevallier {
2201506f47aSGatien Chevallier return TEE_SUCCESS;
2211506f47aSGatien Chevallier }
2221c32a0eaSGatien Chevallier
stm32_rif_access_violation_action(void)2231c32a0eaSGatien Chevallier static inline void stm32_rif_access_violation_action(void)
2241c32a0eaSGatien Chevallier {
2251c32a0eaSGatien Chevallier }
2261506f47aSGatien Chevallier #endif /* CFG_STM32_RIF */
2271506f47aSGatien Chevallier #endif /* __DRIVERS_STM32_RIF_H */
228