xref: /optee_os/core/drivers/firewall/firewall.c (revision fc9ea0db8ddf8150754aac716691616c7e3f404a)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (C) 2024, STMicroelectronics
4  */
5 
6 #include <assert.h>
7 #include <config.h>
8 #include <drivers/firewall.h>
9 #include <kernel/dt_driver.h>
10 #include <kernel/panic.h>
11 #include <libfdt.h>
12 #include <malloc.h>
13 #include <trace.h>
14 
15 /* The firewall framework requires device tree support */
16 static_assert(IS_ENABLED(CFG_DT));
17 
18 static TEE_Result firewall_get(struct dt_pargs *parg, void *data,
19 			       struct firewall_query **out_fw)
20 {
21 	struct firewall_query *fw = NULL;
22 	unsigned int i = 0;
23 
24 	assert(parg->args_count >= 0);
25 
26 	fw = calloc(1, sizeof(*fw));
27 	if (!fw)
28 		return TEE_ERROR_OUT_OF_MEMORY;
29 
30 	fw->ctrl = (struct firewall_controller *)data;
31 	fw->arg_count = parg->args_count;
32 
33 	if (fw->arg_count) {
34 		fw->args = calloc(fw->arg_count, sizeof(*fw->args));
35 		if (!fw->args) {
36 			free(fw);
37 			return TEE_ERROR_OUT_OF_MEMORY;
38 		}
39 	}
40 
41 	for (i = 0; i < (unsigned int)parg->args_count; i++)
42 		fw->args[i] = parg->args[i];
43 
44 	*out_fw = fw;
45 
46 	return TEE_SUCCESS;
47 }
48 
49 /* Firewall device API */
50 
51 void firewall_put(struct firewall_query *fw)
52 {
53 	if (fw) {
54 		free(fw->args);
55 		free(fw);
56 	}
57 }
58 
59 TEE_Result firewall_dt_get_by_index(const void *fdt, int node, uint32_t index,
60 				    struct firewall_query **out_fw)
61 {
62 	return dt_driver_device_from_node_idx_prop("access-controllers", fdt,
63 						   node, index,
64 						   DT_DRIVER_FIREWALL,
65 						   out_fw);
66 }
67 
68 TEE_Result firewall_dt_get_by_name(const void *fdt, int node, const char *name,
69 				   struct firewall_query **out_fw)
70 {
71 	int index = 0;
72 
73 	index = fdt_stringlist_search(fdt, node, "access-controllers-names",
74 				      name);
75 	if (index == -FDT_ERR_NOTFOUND)
76 		return TEE_ERROR_ITEM_NOT_FOUND;
77 	else if (index < 0)
78 		return TEE_ERROR_GENERIC;
79 
80 	return firewall_dt_get_by_index(fdt, node, index, out_fw);
81 }
82 
83 TEE_Result firewall_set_configuration(struct firewall_query *fw)
84 {
85 	assert(fw && fw->ctrl && fw->ctrl->ops);
86 
87 	if (!fw->ctrl->ops->set_conf)
88 		return TEE_ERROR_NOT_SUPPORTED;
89 
90 	return fw->ctrl->ops->set_conf(fw);
91 }
92 
93 TEE_Result firewall_check_access(struct firewall_query *fw)
94 {
95 	assert(fw && fw->ctrl && fw->ctrl->ops);
96 
97 	if (!fw->ctrl->ops->check_access)
98 		return TEE_ERROR_NOT_SUPPORTED;
99 
100 	return fw->ctrl->ops->check_access(fw);
101 }
102 
103 TEE_Result firewall_acquire_access(struct firewall_query *fw)
104 {
105 	assert(fw && fw->ctrl && fw->ctrl->ops);
106 
107 	if (!fw->ctrl->ops->acquire_access)
108 		return TEE_ERROR_NOT_SUPPORTED;
109 
110 	return fw->ctrl->ops->acquire_access(fw);
111 }
112 
113 TEE_Result firewall_check_memory_access(struct firewall_query *fw,
114 					paddr_t paddr, size_t size, bool read,
115 					bool write)
116 {
117 	assert(fw && fw->ctrl && fw->ctrl->ops);
118 
119 	if (!fw->ctrl->ops->check_memory_access)
120 		return TEE_ERROR_NOT_SUPPORTED;
121 
122 	return fw->ctrl->ops->check_memory_access(fw, paddr, size, read, write);
123 }
124 
125 TEE_Result firewall_acquire_memory_access(struct firewall_query *fw,
126 					  paddr_t paddr, size_t size, bool read,
127 					  bool write)
128 {
129 	assert(fw && fw->ctrl && fw->ctrl->ops);
130 
131 	if (!fw->ctrl->ops->acquire_memory_access)
132 		return TEE_ERROR_NOT_SUPPORTED;
133 
134 	return fw->ctrl->ops->acquire_memory_access(fw, paddr, size, read,
135 						    write);
136 }
137 
138 void firewall_release_access(struct firewall_query *fw)
139 {
140 	assert(fw && fw->ctrl && fw->ctrl->ops);
141 
142 	if (fw->ctrl->ops->release_access)
143 		fw->ctrl->ops->release_access(fw);
144 }
145 
146 void firewall_release_memory_access(struct firewall_query *fw, paddr_t paddr,
147 				    size_t size, bool read, bool write)
148 {
149 	assert(fw && fw->ctrl && fw->ctrl->ops);
150 
151 	if (fw->ctrl->ops->release_memory_access)
152 		fw->ctrl->ops->release_memory_access(fw, paddr, size, read,
153 						     write);
154 }
155 
156 /* Firewall controller API */
157 
158 TEE_Result firewall_dt_controller_register(const void *fdt, int node,
159 					   struct firewall_controller *ctrl)
160 {
161 	assert(ctrl);
162 
163 	DMSG("Registering %s firewall controller", ctrl->name);
164 
165 	return dt_driver_register_provider(fdt, node,
166 					   (get_of_device_func)firewall_get,
167 					   ctrl, DT_DRIVER_FIREWALL);
168 }
169