xref: /optee_os/core/drivers/firewall/stm32_rif.c (revision 5d5d7d0b1c038a6836be9f0b38585f5aa6a4dd01)
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(_CIDCFGR_SCID_SHIFT + msb_nb_cid_supp - 1,
34 			  _CIDCFGR_SCID_SHIFT);
35 }
36 
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 
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 
95 bool stm32_rif_semaphore_is_available(vaddr_t addr)
96 {
97 	return !(io_read32(addr) & _SEMCR_MUTEX);
98 }
99 
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 
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