/* SPDX-License-Identifier: BSD-2-Clause */ /* * Copyright (c) 2022-2024, STMicroelectronics */ #ifndef __DRIVERS_STM32_RIF_H #define __DRIVERS_STM32_RIF_H #include #include #include #include /* * CIDCFGR register */ #define _CIDCFGR_CFEN BIT(0) #define _CIDCFGR_SEMEN BIT(1) #define _CIDCFGR_SEMWL(x) BIT(SEMWL_SHIFT + (x)) /* * SEMCR register */ #define _SEMCR_MUTEX BIT(0) #define _SEMCR_SEMCID_SHIFT U(4) #define _SEMCR_SEMCID_MASK GENMASK_32(6, 4) /* * Miscellaneous */ #define MAX_CID_SUPPORTED U(8) #define SCID_SHIFT U(4) #define SEMWL_SHIFT U(16) #define RIF_ID_SHIFT U(24) #define RIF_ID_MASK GENMASK_32(31, 24) #define RIF_CHANNEL_ID(x) ((RIF_ID_MASK & (x)) >> RIF_ID_SHIFT) #define RIFPROT_SEC BIT(8) #define RIFPROT_PRIV BIT(9) #define RIFPROT_LOCK BIT(10) /** * struct rif_conf_data - Structure containing RIF configuration data * * @access_mask: Array of the masks of the registers which will be configured. * @sec_conf: Secure configuration registers. * @priv_conf: Privilege configuration registers. * @cid_confs: CID filtering configuration register value for a peripheral * resource (e.g: GPIO pins, FMC controllers) * @lock_conf: RIF configuration locking registers * * For a hardware block having 56 channels, there will be 56 cid_confs * registers and 2 sec_conf and priv_conf registers */ struct rif_conf_data { uint32_t *access_mask; uint32_t *sec_conf; uint32_t *priv_conf; uint32_t *cid_confs; uint32_t *lock_conf; }; #ifdef CFG_STM32_RIF /** * stm32_rif_scid_ok() - Check if a given static CID configuration authorizes * access to a given CID * * @cidcfgr: Value of the CIDCFGR register * @scid_m: Mask of the static CID in the register * @cid_to_check: CID of the target compartment * * Returns true if given CID is authorized, false otherwise. */ static inline bool stm32_rif_scid_ok(uint32_t cidcfgr, uint32_t scid_m, uint32_t cid_to_check) { return (cidcfgr & scid_m) == SHIFT_U32(cid_to_check, SCID_SHIFT) && !(cidcfgr & _CIDCFGR_SEMEN); } /** * stm32_rif_semaphore_enabled_and_ok() - Check if semaphore mode is enabled and * that a given CID can request the * semaphore ownership * * @cidcfgr: Value of the cidcfgr register * @cid_to_check: CID to check * * Returns true if the requested CID can request the semaphore ownership, * false otherwise. */ static inline bool stm32_rif_semaphore_enabled_and_ok(uint32_t cidcfgr, uint32_t cid_to_check) { return (cidcfgr & _CIDCFGR_CFEN) && (cidcfgr & _CIDCFGR_SEMEN) && (cidcfgr & _CIDCFGR_SEMWL(cid_to_check)); } /** * stm32_rifsc_check_tdcid() - Check if the execution context is TDCID or not * * @tdcid_state: [out] Set to true if TDCID, false otherwise. * * Returns TEE_ERROR_DEFER_DRIVER_INIT if RIFSC driver isn't probed, TEE_SUCCESS * otherwise. */ TEE_Result stm32_rifsc_check_tdcid(bool *tdcid_state); /** * stm32_rif_check_access() - Test peripheral access for a given compartment * * @cidcfgr: CIDCFGR configuration register value * @semcr: SEMCR register value * @nb_cid_supp: Number of supported CID for the peripheral * @cid_to_check: CID of the target compartment * * Returns TEE_SUCCESS if access is authorized, a TEE_Result error value * otherwise. */ TEE_Result stm32_rif_check_access(uint32_t cidcfgr, uint32_t semcr, unsigned int nb_cid_supp, unsigned int cid_to_check); /** * stm32_rif_parse_cfg() - Parse RIF config from Device Tree extracted * information * * @rif_conf: Configuration read in the device tree * @conf_data: Buffer containing the RIF configuration to apply for a peripheral * @nb_cid_supp: Number of supported CID for the peripheral * @nb_channel: Number of channels for the peripheral */ void stm32_rif_parse_cfg(uint32_t rif_conf, struct rif_conf_data *conf_data, unsigned int nb_cid_supp, unsigned int nb_channel); /** * stm32_rif_semaphore_is_available() - Checks if the _SEMCR_MUTEX bit is set * * @addr: Address of the register to read from */ bool stm32_rif_semaphore_is_available(vaddr_t addr); /** * stm32_rif_semaphore_is_available() - Acquires the semaphore by setting the * _SEMCR_MUTEX bit * * @addr: Address of the register to write to * @nb_cid_supp: Number of CID supported */ TEE_Result stm32_rif_acquire_semaphore(vaddr_t addr, unsigned int nb_cid_supp); /** * stm32_rif_semaphore_is_available() - Releases the semaphore by clearing the * _SEMCR_MUTEX bit * * @addr: Address of the register to write to * @nb_cid_supp: Number of CID supported */ TEE_Result stm32_rif_release_semaphore(vaddr_t addr, unsigned int nb_cid_supp); /* * The action to take upon an access violation depends on the platform. * Therefore, it should be defined at platform level. */ void stm32_rif_access_violation_action(void); #else static inline bool stm32_rif_scid_ok(uint32_t cidcfgr __unused, uint32_t scid_m __unused, uint32_t cid_to_check __unused) { return true; } static inline bool stm32_rif_semaphore_enabled_and_ok(uint32_t cidcfgr __unused, uint32_t cid_to_check __unused) { return true; } static inline TEE_Result stm32_rifsc_check_tdcid(bool *tdcid_state) { /* Without CFG_STM32_RIF every CPU can behave as TDCID */ *tdcid_state = true; return TEE_SUCCESS; } 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) { return TEE_SUCCESS; } static inline void stm32_rif_parse_cfg(uint32_t rif_conf __unused, struct rif_conf_data *conf_data __unused, unsigned int nb_cid_supp __unused, unsigned int nb_channel __unused) { } static inline bool stm32_rif_semaphore_is_available(vaddr_t addr __unused) { return true; } static inline TEE_Result stm32_rif_acquire_semaphore(vaddr_t addr __unused, unsigned int nb_cid_supp __unused) { return TEE_SUCCESS; } static inline TEE_Result stm32_rif_release_semaphore(vaddr_t addr __unused, unsigned int nb_cid_supp __unused) { return TEE_SUCCESS; } static inline void stm32_rif_access_violation_action(void) { } #endif /* CFG_STM32_RIF */ #endif /* __DRIVERS_STM32_RIF_H */