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_set_memory_configuration(struct firewall_query *fw, 94 paddr_t paddr, size_t size) 95 { 96 assert(fw && fw->ctrl && fw->ctrl->ops); 97 98 if (!fw->ctrl->ops->set_memory_conf) 99 return TEE_ERROR_NOT_SUPPORTED; 100 101 return fw->ctrl->ops->set_memory_conf(fw, paddr, size); 102 } 103 104 TEE_Result firewall_check_access(struct firewall_query *fw) 105 { 106 assert(fw && fw->ctrl && fw->ctrl->ops); 107 108 if (!fw->ctrl->ops->check_access) 109 return TEE_ERROR_NOT_SUPPORTED; 110 111 return fw->ctrl->ops->check_access(fw); 112 } 113 114 TEE_Result firewall_acquire_access(struct firewall_query *fw) 115 { 116 assert(fw && fw->ctrl && fw->ctrl->ops); 117 118 if (!fw->ctrl->ops->acquire_access) 119 return TEE_ERROR_NOT_SUPPORTED; 120 121 return fw->ctrl->ops->acquire_access(fw); 122 } 123 124 TEE_Result firewall_check_memory_access(struct firewall_query *fw, 125 paddr_t paddr, size_t size, bool read, 126 bool write) 127 { 128 assert(fw && fw->ctrl && fw->ctrl->ops); 129 130 if (!fw->ctrl->ops->check_memory_access) 131 return TEE_ERROR_NOT_SUPPORTED; 132 133 return fw->ctrl->ops->check_memory_access(fw, paddr, size, read, write); 134 } 135 136 TEE_Result firewall_acquire_memory_access(struct firewall_query *fw, 137 paddr_t paddr, size_t size, bool read, 138 bool write) 139 { 140 assert(fw && fw->ctrl && fw->ctrl->ops); 141 142 if (!fw->ctrl->ops->acquire_memory_access) 143 return TEE_ERROR_NOT_SUPPORTED; 144 145 return fw->ctrl->ops->acquire_memory_access(fw, paddr, size, read, 146 write); 147 } 148 149 void firewall_release_access(struct firewall_query *fw) 150 { 151 assert(fw && fw->ctrl && fw->ctrl->ops); 152 153 if (fw->ctrl->ops->release_access) 154 fw->ctrl->ops->release_access(fw); 155 } 156 157 void firewall_release_memory_access(struct firewall_query *fw, paddr_t paddr, 158 size_t size, bool read, bool write) 159 { 160 assert(fw && fw->ctrl && fw->ctrl->ops); 161 162 if (fw->ctrl->ops->release_memory_access) 163 fw->ctrl->ops->release_memory_access(fw, paddr, size, read, 164 write); 165 } 166 167 /* Firewall controller API */ 168 169 TEE_Result firewall_dt_controller_register(const void *fdt, int node, 170 struct firewall_controller *ctrl) 171 { 172 assert(ctrl); 173 174 DMSG("Registering %s firewall controller", ctrl->name); 175 176 return dt_driver_register_provider(fdt, node, 177 (get_of_device_func)firewall_get, 178 ctrl, DT_DRIVER_FIREWALL); 179 } 180