1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2021-2024, STMicroelectronics
4 */
5
6 #include <assert.h>
7 #include <drivers/stm32_rif.h>
8 #include <drivers/stm32mp_dt_bindings.h>
9 #include <io.h>
10 #include <kernel/panic.h>
11 #include <mm/core_memprot.h>
12
13 #define MAX_CID_BITFIELD U(3)
14
15 /**
16 * get_scid_mask() - Get the static CID mask according to the number of
17 * supported CIDs
18 *
19 * @nb_cid_supp: Number of CIDs supported. Cannot be 0.
20 */
get_scid_mask(unsigned int nb_cid_supp)21 static uint32_t get_scid_mask(unsigned int nb_cid_supp)
22 {
23 uint32_t msb_nb_cid_supp = 0;
24
25 assert(nb_cid_supp);
26
27 msb_nb_cid_supp = sizeof(nb_cid_supp) * 8 -
28 __builtin_clz((nb_cid_supp - 1) | 1);
29
30 /* SCID bitfield highend can't be > SCID_SHIFT + MAX_CID_BITFIELD */
31 assert(msb_nb_cid_supp <= MAX_CID_BITFIELD);
32
33 return GENMASK_32(_CIDCFGR_SCID_SHIFT + msb_nb_cid_supp - 1,
34 _CIDCFGR_SCID_SHIFT);
35 }
36
stm32_rif_check_access(uint32_t cidcfgr,uint32_t semcr,unsigned int nb_cid_supp,unsigned int cid_to_check)37 TEE_Result stm32_rif_check_access(uint32_t cidcfgr,
38 uint32_t semcr,
39 unsigned int nb_cid_supp,
40 unsigned int cid_to_check)
41 {
42 uint32_t scid_mask = get_scid_mask(nb_cid_supp);
43
44 if (!(cidcfgr & _CIDCFGR_CFEN))
45 return TEE_SUCCESS;
46
47 if (stm32_rif_scid_ok(cidcfgr, scid_mask, cid_to_check))
48 return TEE_SUCCESS;
49
50 if (stm32_rif_semaphore_enabled_and_ok(cidcfgr, cid_to_check)) {
51 if (!(semcr & _SEMCR_MUTEX) ||
52 ((semcr & scid_mask) >> _CIDCFGR_SCID_SHIFT) ==
53 cid_to_check) {
54 return TEE_SUCCESS;
55 }
56 }
57
58 return TEE_ERROR_ACCESS_DENIED;
59 }
60
stm32_rif_parse_cfg(uint32_t rif_conf,struct rif_conf_data * conf_data,unsigned int nb_channel)61 void stm32_rif_parse_cfg(uint32_t rif_conf, struct rif_conf_data *conf_data,
62 unsigned int nb_channel)
63 {
64 uint32_t channel_id = 0;
65 unsigned int conf_index = 0;
66
67 /* Shift corresponding to the desired resources */
68 channel_id = RIF_CHANNEL_ID(rif_conf);
69 if (channel_id >= nb_channel)
70 panic("Bad RIF controllers number");
71
72 /* Some peripherals have more than 32 RIF channels */
73 conf_index = channel_id / 32;
74
75 /* Privilege configuration */
76 if (rif_conf & BIT(RIF_PRIV_SHIFT))
77 conf_data->priv_conf[conf_index] |= BIT(channel_id);
78
79 /* Security RIF configuration */
80 if (rif_conf & BIT(RIF_SEC_SHIFT))
81 conf_data->sec_conf[conf_index] |= BIT(channel_id);
82
83 /* RIF configuration lock */
84 if (rif_conf & BIT(RIF_LOCK_SHIFT) && conf_data->lock_conf)
85 conf_data->lock_conf[conf_index] |= BIT(channel_id);
86
87 /* CID configuration */
88 conf_data->cid_confs[channel_id] = (rif_conf & RIF_PERx_CID_MASK) >>
89 RIF_PERx_CID_SHIFT;
90
91 /* Store that this RIF resource is to be configured */
92 conf_data->access_mask[conf_index] |= BIT(channel_id);
93 }
94
stm32_rif_semaphore_is_available(vaddr_t addr)95 bool stm32_rif_semaphore_is_available(vaddr_t addr)
96 {
97 return !(io_read32(addr) & _SEMCR_MUTEX);
98 }
99
stm32_rif_acquire_semaphore(vaddr_t addr,unsigned int nb_cid_supp)100 TEE_Result stm32_rif_acquire_semaphore(vaddr_t addr, unsigned int nb_cid_supp)
101 {
102 uint32_t scid_mask = get_scid_mask(nb_cid_supp);
103
104 /* Take the semaphore */
105 io_setbits32(addr, _SEMCR_MUTEX);
106
107 /* Check that the Cortex-A has the semaphore */
108 if (stm32_rif_semaphore_is_available(addr) ||
109 ((io_read32(addr) & scid_mask) >> _CIDCFGR_SCID_SHIFT) != RIF_CID1)
110 return TEE_ERROR_ACCESS_DENIED;
111
112 return TEE_SUCCESS;
113 }
114
stm32_rif_release_semaphore(vaddr_t addr,unsigned int nb_cid_supp)115 TEE_Result stm32_rif_release_semaphore(vaddr_t addr, unsigned int nb_cid_supp)
116 {
117 uint32_t scid_mask = get_scid_mask(nb_cid_supp);
118
119 if (stm32_rif_semaphore_is_available(addr))
120 return TEE_SUCCESS;
121
122 /* Release the semaphore */
123 io_clrbits32(addr, _SEMCR_MUTEX);
124
125 /* Check that current compartment no more owns the semaphore */
126 if (!stm32_rif_semaphore_is_available(addr) &&
127 ((io_read32(addr) & scid_mask) >> _CIDCFGR_SCID_SHIFT) == RIF_CID1)
128 return TEE_ERROR_ACCESS_DENIED;
129
130 return TEE_SUCCESS;
131 }
132