1 /* 2 * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <errno.h> 9 10 #include <arch_features.h> 11 #include <common/fdt_fixup.h> 12 #include <common/fdt_wrappers.h> 13 #include <drivers/arm/gicv3.h> 14 #include <drivers/delay_timer.h> 15 #include <drivers/generic_delay_timer.h> 16 #include <lib/extensions/spe.h> 17 #include <lib/mmio.h> 18 #include <libfdt.h> 19 20 #include "fpga_private.h" 21 #include <plat/common/platform.h> 22 #include <platform_def.h> 23 24 static entry_point_info_t bl33_image_ep_info; 25 static unsigned int system_freq; 26 volatile uint32_t secondary_core_spinlock; 27 28 uintptr_t plat_get_ns_image_entrypoint(void) 29 { 30 #ifdef PRELOADED_BL33_BASE 31 return PRELOADED_BL33_BASE; 32 #else 33 return 0ULL; 34 #endif 35 } 36 37 uint32_t fpga_get_spsr_for_bl33_entry(void) 38 { 39 return SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); 40 } 41 42 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, 43 u_register_t arg2, u_register_t arg3) 44 { 45 /* Add this core to the VALID mpids list */ 46 fpga_valid_mpids[plat_my_core_pos()] = VALID_MPID; 47 48 /* 49 * Notify the secondary CPUs that the C runtime is ready 50 * so they can announce themselves. 51 */ 52 secondary_core_spinlock = C_RUNTIME_READY_KEY; 53 dsbish(); 54 sev(); 55 56 fpga_console_init(); 57 58 bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); 59 bl33_image_ep_info.spsr = fpga_get_spsr_for_bl33_entry(); 60 SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); 61 62 /* Set x0-x3 for the primary CPU as expected by the kernel */ 63 bl33_image_ep_info.args.arg0 = (u_register_t)FPGA_PRELOADED_DTB_BASE; 64 bl33_image_ep_info.args.arg1 = 0U; 65 bl33_image_ep_info.args.arg2 = 0U; 66 bl33_image_ep_info.args.arg3 = 0U; 67 } 68 69 void bl31_plat_arch_setup(void) 70 { 71 } 72 73 void bl31_platform_setup(void) 74 { 75 /* Write frequency to CNTCRL and initialize timer */ 76 generic_delay_timer_init(); 77 78 /* 79 * Before doing anything else, wait for some time to ensure that 80 * the secondary CPUs have populated the fpga_valid_mpids array. 81 * As the number of secondary cores is unknown and can even be 0, 82 * it is not possible to rely on any signal from them, so use a 83 * delay instead. 84 */ 85 mdelay(5); 86 87 /* 88 * On the event of a cold reset issued by, for instance, a reset pin 89 * assertion, we cannot guarantee memory to be initialized to zero. 90 * In such scenario, if the secondary cores reached 91 * plat_secondary_cold_boot_setup before the primary one initialized 92 * .BSS, we could end up having a race condition if the spinlock 93 * was not cleared before. 94 * 95 * Similarly, if there were a reset before the spinlock had been 96 * cleared, the secondary cores would find the lock opened before 97 * .BSS is cleared, causing another race condition. 98 * 99 * So clean the spinlock as soon as we think it is safe to reduce the 100 * chances of any race condition on a reset. 101 */ 102 secondary_core_spinlock = 0UL; 103 104 /* Initialize the GIC driver, cpu and distributor interfaces */ 105 plat_fpga_gic_init(); 106 } 107 108 entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) 109 { 110 entry_point_info_t *next_image_info; 111 next_image_info = &bl33_image_ep_info; 112 113 /* Only expecting BL33: the kernel will run in EL2NS */ 114 assert(type == NON_SECURE); 115 116 /* None of the images can have 0x0 as the entrypoint */ 117 if (next_image_info->pc) { 118 return next_image_info; 119 } else { 120 return NULL; 121 } 122 } 123 124 /* 125 * Even though we sell the FPGA UART as an SBSA variant, it is actually 126 * a full fledged PL011. So the baudrate divider registers exist. 127 */ 128 #ifndef UARTIBRD 129 #define UARTIBRD 0x024 130 #define UARTFBRD 0x028 131 #endif 132 133 /* Round an integer to the closest multiple of a value. */ 134 static unsigned int round_multiple(unsigned int x, unsigned int multiple) 135 { 136 if (multiple < 2) { 137 return x; 138 } 139 140 return ((x + (multiple / 2 - 1)) / multiple) * multiple; 141 } 142 143 #define PL011_FRAC_SHIFT 6 144 #define FPGA_DEFAULT_BAUDRATE 38400 145 #define PL011_OVERSAMPLING 16 146 static unsigned int pl011_freq_from_divider(unsigned int divider) 147 { 148 unsigned int freq; 149 150 freq = divider * FPGA_DEFAULT_BAUDRATE * PL011_OVERSAMPLING; 151 152 return freq >> PL011_FRAC_SHIFT; 153 } 154 155 /* 156 * The FPGAs run most peripherals from one main clock, among them the CPUs, 157 * the arch timer, and the UART baud base clock. 158 * The SCP knows this frequency and programs the UART clock divider for a 159 * 38400 bps baudrate. Recalculate the base input clock from there. 160 */ 161 static unsigned int fpga_get_system_frequency(void) 162 { 163 const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE; 164 int node, err; 165 166 /* 167 * If the arch timer DT node has an explicit clock-frequency property 168 * set, use that, to allow people overriding auto-detection. 169 */ 170 node = fdt_node_offset_by_compatible(fdt, 0, "arm,armv8-timer"); 171 if (node >= 0) { 172 uint32_t freq; 173 174 err = fdt_read_uint32(fdt, node, "clock-frequency", &freq); 175 if (err >= 0) { 176 return freq; 177 } 178 } 179 180 node = fdt_node_offset_by_compatible(fdt, 0, "arm,pl011"); 181 if (node >= 0) { 182 uintptr_t pl011_base; 183 unsigned int divider; 184 185 err = fdt_get_reg_props_by_index(fdt, node, 0, 186 &pl011_base, NULL); 187 if (err >= 0) { 188 divider = mmio_read_32(pl011_base + UARTIBRD); 189 divider <<= PL011_FRAC_SHIFT; 190 divider += mmio_read_32(pl011_base + UARTFBRD); 191 192 /* 193 * The result won't be exact, due to rounding errors, 194 * but the input frequency was a multiple of 250 KHz. 195 */ 196 return round_multiple(pl011_freq_from_divider(divider), 197 250000); 198 } else { 199 WARN("Cannot read PL011 MMIO base\n"); 200 } 201 } else { 202 WARN("No PL011 DT node\n"); 203 } 204 205 /* No PL011 DT node or calculation failed. */ 206 return FPGA_DEFAULT_TIMER_FREQUENCY; 207 } 208 209 unsigned int plat_get_syscnt_freq2(void) 210 { 211 if (system_freq == 0U) { 212 system_freq = fpga_get_system_frequency(); 213 } 214 215 return system_freq; 216 } 217 218 static void fpga_dtb_update_clock(void *fdt, unsigned int freq) 219 { 220 uint32_t freq_dtb = fdt32_to_cpu(freq); 221 uint32_t phandle; 222 int node, err; 223 224 node = fdt_node_offset_by_compatible(fdt, 0, "arm,pl011"); 225 if (node < 0) { 226 WARN("%s(): No PL011 DT node found\n", __func__); 227 228 return; 229 } 230 231 err = fdt_read_uint32(fdt, node, "clocks", &phandle); 232 if (err != 0) { 233 WARN("Cannot find clocks property\n"); 234 235 return; 236 } 237 238 node = fdt_node_offset_by_phandle(fdt, phandle); 239 if (node < 0) { 240 WARN("Cannot get phandle\n"); 241 242 return; 243 } 244 245 err = fdt_setprop_inplace(fdt, node, 246 "clock-frequency", 247 &freq_dtb, 248 sizeof(freq_dtb)); 249 if (err < 0) { 250 WARN("Could not update DT baud clock frequency\n"); 251 252 return; 253 } 254 } 255 256 #define CMDLINE_SIGNATURE "CMD:" 257 258 static int fpga_dtb_set_commandline(void *fdt, const char *cmdline) 259 { 260 int chosen; 261 const char *eol; 262 char nul = 0; 263 int slen, err; 264 265 chosen = fdt_add_subnode(fdt, 0, "chosen"); 266 if (chosen == -FDT_ERR_EXISTS) { 267 chosen = fdt_path_offset(fdt, "/chosen"); 268 } 269 270 if (chosen < 0) { 271 return chosen; 272 } 273 274 /* 275 * There is most likely an EOL at the end of the 276 * command line, make sure we terminate the line there. 277 * We can't replace the EOL with a NUL byte in the 278 * source, as this is in read-only memory. So we first 279 * create the property without any termination, then 280 * append a single NUL byte. 281 */ 282 eol = strchr(cmdline, '\n'); 283 if (eol == NULL) { 284 eol = strchr(cmdline, 0); 285 } 286 /* Skip the signature and omit the EOL/NUL byte. */ 287 slen = eol - (cmdline + strlen(CMDLINE_SIGNATURE)); 288 /* 289 * Let's limit the size of the property, just in case 290 * we find the signature by accident. The Linux kernel 291 * limits to 4096 characters at most (in fact 2048 for 292 * arm64), so that sounds like a reasonable number. 293 */ 294 if (slen > 4095) { 295 slen = 4095; 296 } 297 298 err = fdt_setprop(fdt, chosen, "bootargs", 299 cmdline + strlen(CMDLINE_SIGNATURE), slen); 300 if (err != 0) { 301 return err; 302 } 303 304 return fdt_appendprop(fdt, chosen, "bootargs", &nul, 1); 305 } 306 307 static void fpga_prepare_dtb(void) 308 { 309 void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE; 310 const char *cmdline = (void *)(uintptr_t)FPGA_PRELOADED_CMD_LINE; 311 int err; 312 313 err = fdt_open_into(fdt, fdt, FPGA_MAX_DTB_SIZE); 314 if (err < 0) { 315 ERROR("cannot open devicetree at %p: %d\n", fdt, err); 316 panic(); 317 } 318 319 /* Reserve memory used by Trusted Firmware. */ 320 if (fdt_add_reserved_memory(fdt, "tf-a@80000000", BL31_BASE, 321 BL31_LIMIT - BL31_BASE)) { 322 WARN("Failed to add reserved memory node to DT\n"); 323 } 324 325 /* Check for the command line signature. */ 326 if (!strncmp(cmdline, CMDLINE_SIGNATURE, strlen(CMDLINE_SIGNATURE))) { 327 err = fpga_dtb_set_commandline(fdt, cmdline); 328 if (err == 0) { 329 INFO("using command line at 0x%x\n", 330 FPGA_PRELOADED_CMD_LINE); 331 } else { 332 ERROR("failed to put command line into DTB: %d\n", err); 333 } 334 } 335 336 if (err < 0) { 337 ERROR("Error %d extending Device Tree\n", err); 338 panic(); 339 } 340 341 err = fdt_add_cpus_node(fdt, FPGA_MAX_PE_PER_CPU, 342 FPGA_MAX_CPUS_PER_CLUSTER, 343 FPGA_MAX_CLUSTER_COUNT); 344 345 if (err == -EEXIST) { 346 WARN("Not overwriting already existing /cpus node in DTB\n"); 347 } else { 348 if (err < 0) { 349 ERROR("Error %d creating the /cpus DT node\n", err); 350 panic(); 351 } else { 352 unsigned int nr_cores = fpga_get_nr_gic_cores(); 353 354 INFO("Adjusting GICR DT region to cover %u cores\n", 355 nr_cores); 356 err = fdt_adjust_gic_redist(fdt, nr_cores, 357 fpga_get_redist_base(), 358 fpga_get_redist_size()); 359 if (err < 0) { 360 ERROR("Error %d fixing up GIC DT node\n", err); 361 } 362 } 363 } 364 365 fpga_dtb_update_clock(fdt, system_freq); 366 367 /* Check whether we support the SPE PMU. Remove the DT node if not. */ 368 if (!is_feat_spe_supported()) { 369 int node = fdt_node_offset_by_compatible(fdt, 0, 370 "arm,statistical-profiling-extension-v1"); 371 372 if (node >= 0) { 373 fdt_del_node(fdt, node); 374 } 375 } 376 377 /* Check whether we have an ITS. Remove the DT node if not. */ 378 if (!fpga_has_its()) { 379 int node = fdt_node_offset_by_compatible(fdt, 0, 380 "arm,gic-v3-its"); 381 382 if (node >= 0) { 383 fdt_del_node(fdt, node); 384 } 385 } 386 387 err = fdt_pack(fdt); 388 if (err < 0) { 389 ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, err); 390 } 391 392 clean_dcache_range((uintptr_t)fdt, fdt_blob_size(fdt)); 393 } 394 395 void bl31_plat_runtime_setup(void) 396 { 397 fpga_prepare_dtb(); 398 } 399 400 void bl31_plat_enable_mmu(uint32_t flags) 401 { 402 /* TODO: determine if MMU needs to be enabled */ 403 } 404