xref: /optee_os/core/drivers/firewall/stm32_rif.c (revision 19a31ec40245ae01a9adcd206eec2a4bb4479fc9)
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  */
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(SCID_SHIFT + msb_nb_cid_supp - 1, SCID_SHIFT);
34 }
35 
36 TEE_Result stm32_rif_check_access(uint32_t cidcfgr,
37 				  uint32_t semcr,
38 				  unsigned int nb_cid_supp,
39 				  unsigned int cid_to_check)
40 {
41 	uint32_t scid_mask = get_scid_mask(nb_cid_supp);
42 
43 	if (!(cidcfgr & _CIDCFGR_CFEN))
44 		return TEE_SUCCESS;
45 
46 	if (stm32_rif_scid_ok(cidcfgr, scid_mask, cid_to_check))
47 		return TEE_SUCCESS;
48 
49 	if (stm32_rif_semaphore_enabled_and_ok(cidcfgr, cid_to_check)) {
50 		if (!(semcr & _SEMCR_MUTEX) ||
51 		    ((semcr & scid_mask) >> SCID_SHIFT) == cid_to_check) {
52 			return TEE_SUCCESS;
53 		}
54 	}
55 
56 	return TEE_ERROR_ACCESS_DENIED;
57 }
58 
59 void stm32_rif_parse_cfg(uint32_t rif_conf,
60 			 struct rif_conf_data *conf_data,
61 			 unsigned int nb_cid_supp,
62 			 unsigned int nb_channel)
63 {
64 	uint32_t scid_mask = get_scid_mask(nb_cid_supp);
65 	uint32_t cidcfdg_conf_mask = 0;
66 	uint32_t channel_id = 0;
67 	uint32_t semwl_mask = 0;
68 	unsigned int conf_index = 0;
69 
70 	semwl_mask = GENMASK_32(SEMWL_SHIFT + nb_cid_supp - 1, SEMWL_SHIFT);
71 
72 	cidcfdg_conf_mask = scid_mask | semwl_mask | _CIDCFGR_CFEN |
73 			    _CIDCFGR_SEMEN;
74 
75 	/* Shift corresponding to the desired resources */
76 	channel_id = RIF_CHANNEL_ID(rif_conf);
77 	if (channel_id >= nb_channel)
78 		panic("Bad RIF controllers number");
79 
80 	/* Some peripherals have more than 32 RIF channels */
81 	conf_index = channel_id / 32;
82 
83 	/* Privilege configuration */
84 	if (rif_conf & RIFPROT_PRIV)
85 		conf_data->priv_conf[conf_index] |= BIT(channel_id);
86 
87 	/* Security RIF configuration */
88 	if (rif_conf & RIFPROT_SEC)
89 		conf_data->sec_conf[conf_index] |= BIT(channel_id);
90 
91 	/* RIF configuration lock */
92 	if (rif_conf & RIFPROT_LOCK && conf_data->lock_conf)
93 		conf_data->lock_conf[conf_index] |= BIT(channel_id);
94 
95 	/* CID configuration */
96 	conf_data->cid_confs[channel_id] = rif_conf & cidcfdg_conf_mask;
97 
98 	/* Store that this RIF resource is to be configured */
99 	conf_data->access_mask[conf_index] |= BIT(channel_id);
100 }
101 
102 bool stm32_rif_semaphore_is_available(vaddr_t addr)
103 {
104 	return !(io_read32(addr) & _SEMCR_MUTEX);
105 }
106 
107 TEE_Result stm32_rif_acquire_semaphore(vaddr_t addr, unsigned int nb_cid_supp)
108 {
109 	uint32_t scid_mask = get_scid_mask(nb_cid_supp);
110 
111 	/* Take the semaphore */
112 	io_setbits32(addr, _SEMCR_MUTEX);
113 
114 	/* Check that the Cortex-A has the semaphore */
115 	if (stm32_rif_semaphore_is_available(addr) ||
116 	    ((io_read32(addr) & scid_mask) >> SCID_SHIFT) != RIF_CID1)
117 		return TEE_ERROR_ACCESS_DENIED;
118 
119 	return TEE_SUCCESS;
120 }
121 
122 TEE_Result stm32_rif_release_semaphore(vaddr_t addr, unsigned int nb_cid_supp)
123 {
124 	uint32_t scid_mask = get_scid_mask(nb_cid_supp);
125 
126 	if (stm32_rif_semaphore_is_available(addr))
127 		return TEE_SUCCESS;
128 
129 	/* Release the semaphore */
130 	io_clrbits32(addr, _SEMCR_MUTEX);
131 
132 	/* Check that current compartment no more owns the semaphore */
133 	if (!stm32_rif_semaphore_is_available(addr) &&
134 	    ((io_read32(addr) & scid_mask) >> SCID_SHIFT) == RIF_CID1)
135 		return TEE_ERROR_ACCESS_DENIED;
136 
137 	return TEE_SUCCESS;
138 }
139