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