1 /* 2 * Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 9 #include <common/fdt_wrappers.h> 10 #include <common/runtime_svc.h> 11 #include <libfdt.h> 12 #include <smccc_helpers.h> 13 14 /* default platform version is 0.0 */ 15 static int platform_version_major; 16 static int platform_version_minor; 17 18 #define SMC_FASTCALL 0x80000000 19 #define SMC64_FUNCTION (SMC_FASTCALL | 0x40000000) 20 #define SIP_FUNCTION (SMC64_FUNCTION | 0x02000000) 21 #define SIP_FUNCTION_ID(n) (SIP_FUNCTION | (n)) 22 23 /* 24 * We do not use SMCCC_ARCH_SOC_ID here because qemu_sbsa is virtual platform 25 * which uses SoC present in QEMU. And they can change on their own while we 26 * need version of whole 'virtual hardware platform'. 27 */ 28 #define SIP_SVC_VERSION SIP_FUNCTION_ID(1) 29 #define SIP_SVC_GET_GIC SIP_FUNCTION_ID(100) 30 #define SIP_SVC_GET_GIC_ITS SIP_FUNCTION_ID(101) 31 #define SIP_SVC_GET_CPU_COUNT SIP_FUNCTION_ID(200) 32 #define SIP_SVC_GET_CPU_NODE SIP_FUNCTION_ID(201) 33 34 static uint64_t gic_its_addr; 35 36 typedef struct { 37 uint32_t nodeid; 38 uint32_t mpidr; 39 } cpu_data; 40 41 static struct { 42 uint32_t num_cpus; 43 cpu_data cpu[PLATFORM_CORE_COUNT]; 44 } dynamic_platform_info; 45 46 void sbsa_set_gic_bases(const uintptr_t gicd_base, const uintptr_t gicr_base); 47 uintptr_t sbsa_get_gicd(void); 48 uintptr_t sbsa_get_gicr(void); 49 50 void read_cpuinfo_from_dt(void *dtb) 51 { 52 int node; 53 int prev; 54 int cpu = 0; 55 uint32_t nodeid = 0; 56 uintptr_t mpidr; 57 58 /* 59 * QEMU gives us this DeviceTree node: 60 * numa-node-id entries are only when NUMA config is used 61 * 62 * cpus { 63 * #size-cells = <0x00>; 64 * #address-cells = <0x02>; 65 * 66 * cpu@0 { 67 * numa-node-id = <0x00>; 68 * reg = <0x00 0x00>; 69 * }; 70 * 71 * cpu@1 { 72 * numa-node-id = <0x03>; 73 * reg = <0x00 0x01>; 74 * }; 75 * }; 76 */ 77 node = fdt_path_offset(dtb, "/cpus"); 78 if (node < 0) { 79 ERROR("No information about cpus in DeviceTree.\n"); 80 panic(); 81 } 82 83 /* 84 * QEMU numbers cpus from 0 and there can be /cpus/cpu-map present so we 85 * cannot use fdt_first_subnode() here 86 */ 87 node = fdt_path_offset(dtb, "/cpus/cpu@0"); 88 89 while (node > 0) { 90 if (fdt_getprop(dtb, node, "reg", NULL)) { 91 fdt_get_reg_props_by_index(dtb, node, 0, &mpidr, NULL); 92 } 93 94 if (fdt_getprop(dtb, node, "numa-node-id", NULL)) { 95 fdt_read_uint32(dtb, node, "numa-node-id", &nodeid); 96 } 97 98 dynamic_platform_info.cpu[cpu].nodeid = nodeid; 99 dynamic_platform_info.cpu[cpu].mpidr = mpidr; 100 101 INFO("CPU %d: node-id: %d, mpidr: %ld\n", cpu, nodeid, mpidr); 102 103 cpu++; 104 105 prev = node; 106 node = fdt_next_subnode(dtb, prev); 107 } 108 109 dynamic_platform_info.num_cpus = cpu; 110 INFO("Found %d cpus\n", dynamic_platform_info.num_cpus); 111 } 112 113 void read_platform_config_from_dt(void *dtb) 114 { 115 int node; 116 const fdt64_t *data; 117 int err; 118 uintptr_t gicd_base; 119 uintptr_t gicr_base; 120 121 /* 122 * QEMU gives us this DeviceTree node: 123 * 124 * intc { 125 * reg = < 0x00 0x40060000 0x00 0x10000 126 * 0x00 0x40080000 0x00 0x4000000>; 127 * its { 128 * reg = <0x00 0x44081000 0x00 0x20000>; 129 * }; 130 * }; 131 */ 132 node = fdt_path_offset(dtb, "/intc"); 133 if (node < 0) { 134 return; 135 } 136 137 data = fdt_getprop(dtb, node, "reg", NULL); 138 if (data == NULL) { 139 return; 140 } 141 142 err = fdt_get_reg_props_by_index(dtb, node, 0, &gicd_base, NULL); 143 if (err < 0) { 144 ERROR("Failed to read GICD reg property of GIC node\n"); 145 return; 146 } 147 INFO("GICD base = 0x%lx\n", gicd_base); 148 149 err = fdt_get_reg_props_by_index(dtb, node, 1, &gicr_base, NULL); 150 if (err < 0) { 151 ERROR("Failed to read GICR reg property of GIC node\n"); 152 return; 153 } 154 INFO("GICR base = 0x%lx\n", gicr_base); 155 156 sbsa_set_gic_bases(gicd_base, gicr_base); 157 158 node = fdt_path_offset(dtb, "/intc/its"); 159 if (node < 0) { 160 return; 161 } 162 163 err = fdt_get_reg_props_by_index(dtb, node, 0, &gic_its_addr, NULL); 164 if (err < 0) { 165 ERROR("Failed to read GICI reg property of GIC node\n"); 166 return; 167 } 168 INFO("GICI base = 0x%lx\n", gic_its_addr); 169 } 170 171 void read_platform_version(void *dtb) 172 { 173 int node; 174 175 node = fdt_path_offset(dtb, "/"); 176 if (node >= 0) { 177 platform_version_major = fdt32_ld(fdt_getprop(dtb, node, 178 "machine-version-major", NULL)); 179 platform_version_minor = fdt32_ld(fdt_getprop(dtb, node, 180 "machine-version-minor", NULL)); 181 } 182 } 183 184 void sip_svc_init(void) 185 { 186 /* Read DeviceTree data before MMU is enabled */ 187 188 void *dtb = (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE; 189 int err; 190 191 err = fdt_open_into(dtb, dtb, PLAT_QEMU_DT_MAX_SIZE); 192 if (err < 0) { 193 ERROR("Invalid Device Tree at %p: error %d\n", dtb, err); 194 return; 195 } 196 197 err = fdt_check_header(dtb); 198 if (err < 0) { 199 ERROR("Invalid DTB file passed\n"); 200 return; 201 } 202 203 read_platform_version(dtb); 204 INFO("Platform version: %d.%d\n", platform_version_major, platform_version_minor); 205 206 read_platform_config_from_dt(dtb); 207 read_cpuinfo_from_dt(dtb); 208 } 209 210 /* 211 * This function is responsible for handling all SiP calls from the NS world 212 */ 213 uintptr_t sbsa_sip_smc_handler(uint32_t smc_fid, 214 u_register_t x1, 215 u_register_t x2, 216 u_register_t x3, 217 u_register_t x4, 218 void *cookie, 219 void *handle, 220 u_register_t flags) 221 { 222 uint32_t ns; 223 uint64_t index; 224 225 /* Determine which security state this SMC originated from */ 226 ns = is_caller_non_secure(flags); 227 if (!ns) { 228 ERROR("%s: wrong world SMC (0x%x)\n", __func__, smc_fid); 229 SMC_RET1(handle, SMC_UNK); 230 } 231 232 switch (smc_fid) { 233 case SIP_SVC_VERSION: 234 INFO("Platform version requested\n"); 235 SMC_RET3(handle, NULL, platform_version_major, platform_version_minor); 236 237 case SIP_SVC_GET_GIC: 238 SMC_RET3(handle, NULL, sbsa_get_gicd(), sbsa_get_gicr()); 239 240 case SIP_SVC_GET_GIC_ITS: 241 SMC_RET2(handle, NULL, gic_its_addr); 242 243 case SIP_SVC_GET_CPU_COUNT: 244 SMC_RET2(handle, NULL, dynamic_platform_info.num_cpus); 245 246 case SIP_SVC_GET_CPU_NODE: 247 index = x1; 248 if (index < PLATFORM_CORE_COUNT) { 249 SMC_RET3(handle, NULL, 250 dynamic_platform_info.cpu[index].nodeid, 251 dynamic_platform_info.cpu[index].mpidr); 252 } else { 253 SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM); 254 } 255 256 default: 257 ERROR("%s: unhandled SMC (0x%x) (function id: %d)\n", __func__, smc_fid, 258 smc_fid - SIP_FUNCTION); 259 SMC_RET1(handle, SMC_UNK); 260 } 261 } 262 263 int sbsa_sip_smc_setup(void) 264 { 265 return 0; 266 } 267 268 /* Define a runtime service descriptor for fast SMC calls */ 269 DECLARE_RT_SVC( 270 sbsa_sip_svc, 271 OEN_SIP_START, 272 OEN_SIP_END, 273 SMC_TYPE_FAST, 274 sbsa_sip_smc_setup, 275 sbsa_sip_smc_handler 276 ); 277