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 9 #include <common/fdt_wrappers.h> 10 #include <drivers/delay_timer.h> 11 #include <drivers/generic_delay_timer.h> 12 #include <libfdt.h> 13 14 #include "fpga_private.h" 15 #include <plat/common/platform.h> 16 #include <platform_def.h> 17 18 static entry_point_info_t bl33_image_ep_info; 19 volatile uint32_t secondary_core_spinlock; 20 21 uintptr_t plat_get_ns_image_entrypoint(void) 22 { 23 #ifdef PRELOADED_BL33_BASE 24 return PRELOADED_BL33_BASE; 25 #else 26 return 0ULL; 27 #endif 28 } 29 30 uint32_t fpga_get_spsr_for_bl33_entry(void) 31 { 32 return SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); 33 } 34 35 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, 36 u_register_t arg2, u_register_t arg3) 37 { 38 /* Add this core to the VALID mpids list */ 39 fpga_valid_mpids[plat_my_core_pos()] = VALID_MPID; 40 41 /* 42 * Notify the secondary CPUs that the C runtime is ready 43 * so they can announce themselves. 44 */ 45 secondary_core_spinlock = C_RUNTIME_READY_KEY; 46 dsbish(); 47 sev(); 48 49 fpga_console_init(); 50 51 bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); 52 bl33_image_ep_info.spsr = fpga_get_spsr_for_bl33_entry(); 53 SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); 54 55 /* Set x0-x3 for the primary CPU as expected by the kernel */ 56 bl33_image_ep_info.args.arg0 = (u_register_t)FPGA_PRELOADED_DTB_BASE; 57 bl33_image_ep_info.args.arg1 = 0U; 58 bl33_image_ep_info.args.arg2 = 0U; 59 bl33_image_ep_info.args.arg3 = 0U; 60 } 61 62 void bl31_plat_arch_setup(void) 63 { 64 } 65 66 void bl31_platform_setup(void) 67 { 68 /* Write frequency to CNTCRL and initialize timer */ 69 generic_delay_timer_init(); 70 71 /* 72 * Before doing anything else, wait for some time to ensure that 73 * the secondary CPUs have populated the fpga_valid_mpids array. 74 * As the number of secondary cores is unknown and can even be 0, 75 * it is not possible to rely on any signal from them, so use a 76 * delay instead. 77 */ 78 mdelay(5); 79 80 /* 81 * On the event of a cold reset issued by, for instance, a reset pin 82 * assertion, we cannot guarantee memory to be initialized to zero. 83 * In such scenario, if the secondary cores reached 84 * plat_secondary_cold_boot_setup before the primary one initialized 85 * .BSS, we could end up having a race condition if the spinlock 86 * was not cleared before. 87 * 88 * Similarly, if there were a reset before the spinlock had been 89 * cleared, the secondary cores would find the lock opened before 90 * .BSS is cleared, causing another race condition. 91 * 92 * So clean the spinlock as soon as we think it is safe to reduce the 93 * chances of any race condition on a reset. 94 */ 95 secondary_core_spinlock = 0UL; 96 97 /* Initialize the GIC driver, cpu and distributor interfaces */ 98 plat_fpga_gic_init(); 99 } 100 101 entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) 102 { 103 entry_point_info_t *next_image_info; 104 next_image_info = &bl33_image_ep_info; 105 106 /* Only expecting BL33: the kernel will run in EL2NS */ 107 assert(type == NON_SECURE); 108 109 /* None of the images can have 0x0 as the entrypoint */ 110 if (next_image_info->pc) { 111 return next_image_info; 112 } else { 113 return NULL; 114 } 115 } 116 117 unsigned int plat_get_syscnt_freq2(void) 118 { 119 const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE; 120 int node; 121 122 node = fdt_node_offset_by_compatible(fdt, 0, "arm,armv8-timer"); 123 if (node < 0) { 124 return FPGA_DEFAULT_TIMER_FREQUENCY; 125 } 126 127 return fdt_read_uint32_default(fdt, node, "clock-frequency", 128 FPGA_DEFAULT_TIMER_FREQUENCY); 129 } 130 131 void bl31_plat_enable_mmu(uint32_t flags) 132 { 133 /* TODO: determine if MMU needs to be enabled */ 134 } 135