1/* 2 * Copyright (c) 2015-2020, Broadcom 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <arch.h> 8#include <asm_macros.S> 9#include <assert_macros.S> 10#include <cpu_macros.S> 11#include <cortex_a72.h> 12#include <drivers/ti/uart/uart_16550.h> 13 14#include <platform_def.h> 15 16 .globl plat_reset_handler 17 .globl platform_get_entrypoint 18 .globl plat_secondary_cold_boot_setup 19 .globl platform_mem_init 20 .globl platform_check_mpidr 21 .globl plat_crash_console_init 22 .globl plat_crash_console_putc 23 .globl plat_crash_console_flush 24 .globl plat_disable_acp 25 .globl plat_is_my_cpu_primary 26 .globl plat_my_core_pos 27 .globl platform_is_primary_cpu 28 .globl plat_brcm_calc_core_pos 29 .globl plat_get_my_entrypoint 30 31 32 /* ------------------------------------------------------------ 33 * void plat_l2_init(void); 34 * 35 * BL1 and BL2 run with one core, one cluster 36 * This is safe to disable cluster coherency 37 * to make use of the data cache MMU WB attribute 38 * for the SRAM. 39 * 40 * Set L2 Auxiliary Control Register 41 * -------------------------------------------------------------------- 42 */ 43func plat_l2_init 44 mrs x0, CORTEX_A72_L2ACTLR_EL1 45#if (IMAGE_BL1 || IMAGE_BL2) || defined(USE_SINGLE_CLUSTER) 46 orr x0, x0, #CORTEX_A72_L2ACTLR_DISABLE_ACE_SH_OR_CHI 47#else 48 bic x0, x0, #CORTEX_A72_L2ACTLR_DISABLE_ACE_SH_OR_CHI 49#endif 50 msr CORTEX_A72_L2ACTLR_EL1, x0 51 52 /* Set L2 Control Register */ 53 mrs x0, CORTEX_A72_L2CTLR_EL1 54 mov x1, #((CORTEX_A72_L2_DATA_RAM_LATENCY_MASK << \ 55 CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) | \ 56 (CORTEX_A72_L2_TAG_RAM_LATENCY_MASK << \ 57 CORTEX_A72_L2CTLR_TAG_RAM_LATENCY_SHIFT) | \ 58 (U(0x1) << CORTEX_A72_L2CTLR_TAG_RAM_SETUP_SHIFT) | \ 59 (U(0x1) << CORTEX_A72_L2CTLR_DATA_RAM_SETUP_SHIFT)) 60 bic x0, x0, x1 61 mov x1, #((CORTEX_A72_L2_DATA_RAM_LATENCY_3_CYCLES << \ 62 CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) | \ 63 (U(0x1) << CORTEX_A72_L2CTLR_TAG_RAM_SETUP_SHIFT) | \ 64 (U(0x1) << CORTEX_A72_L2CTLR_DATA_RAM_SETUP_SHIFT)) 65 orr x0, x0, x1 66 msr CORTEX_A72_L2CTLR_EL1, x0 67 68 isb 69 ret 70endfunc plat_l2_init 71 72 /* -------------------------------------------------------------------- 73 * void plat_reset_handler(void); 74 * 75 * Before adding code in this function, refer to the guidelines in 76 * docs/firmware-design.md. 77 * 78 * -------------------------------------------------------------------- 79 */ 80func plat_reset_handler 81 mov x9, x30 82 bl plat_l2_init 83 mov x30, x9 84 ret 85endfunc plat_reset_handler 86 87 /* ----------------------------------------------------- 88 * void platform_get_entrypoint (unsigned int mpid); 89 * 90 * Main job of this routine is to distinguish between 91 * a cold and warm boot. 92 * On a cold boot the secondaries first wait for the 93 * platform to be initialized after which they are 94 * hotplugged in. The primary proceeds to perform the 95 * platform initialization. 96 * ----------------------------------------------------- 97 */ 98func platform_get_entrypoint 99 /*TBD-STINGRAY*/ 100 mov x0, #0 101 ret 102endfunc platform_get_entrypoint 103 104 /* ----------------------------------------------------- 105 * void plat_secondary_cold_boot_setup (void); 106 * 107 * This function performs any platform specific actions 108 * needed for a secondary cpu after a cold reset e.g 109 * mark the cpu's presence, mechanism to place it in a 110 * holding pen etc. 111 * ----------------------------------------------------- 112 */ 113func plat_secondary_cold_boot_setup 114 bl plat_my_core_pos 115 mov_imm x1, SECONDARY_CPU_SPIN_BASE_ADDR 116 add x0, x1, x0, LSL #3 117 mov x1, #0 118 str x1, [x0] 119 120 /* Wait until the entrypoint gets populated */ 121poll_mailbox: 122 ldr x1, [x0] 123 cbz x1, 1f 124 br x1 1251: 126 wfe 127 b poll_mailbox 128endfunc plat_secondary_cold_boot_setup 129 130 131 /* ----------------------------------------------------- 132 * void platform_mem_init(void); 133 * 134 * We don't need to carry out any memory initialization 135 * on CSS platforms. The Secure RAM is accessible straight away. 136 * ----------------------------------------------------- 137 */ 138func platform_mem_init 139 /*TBD-STINGRAY*/ 140 ret 141endfunc platform_mem_init 142 143 /* ----------------------------------------------------- 144 * Placeholder function which should be redefined by 145 * each platform. 146 * ----------------------------------------------------- 147 */ 148func platform_check_mpidr 149 /*TBD-STINGRAY*/ 150 mov x0, xzr 151 ret 152endfunc platform_check_mpidr 153 154 /* --------------------------------------------- 155 * int plat_crash_console_init(void) 156 * Function to initialize the crash console 157 * without a C Runtime to print crash report. 158 * Clobber list : x0, x1, x2 159 * --------------------------------------------- 160 */ 161 162func plat_crash_console_init 163 mov_imm x0, BRCM_CRASH_CONSOLE_BASE 164 mov_imm x1, BRCM_CRASH_CONSOLE_REFCLK 165 mov_imm x2, BRCM_CRASH_CONSOLE_BAUDRATE 166 b console_16550_core_init 167 ret 168endfunc plat_crash_console_init 169 170 /* --------------------------------------------- 171 * int plat_crash_console_putc(void) 172 * Function to print a character on the crash 173 * console without a C Runtime. 174 * Clobber list : x1, x2, x3 175 * --------------------------------------------- 176 */ 177 178func plat_crash_console_putc 179 mov_imm x1, BRCM_CRASH_CONSOLE_BASE 180 b console_16550_core_putc 181 ret 182endfunc plat_crash_console_putc 183 184 /* --------------------------------------------- 185 * void plat_crash_console_flush(void) 186 * Function to flush crash console 187 * Clobber list : x0, x1 188 * --------------------------------------------- 189 */ 190func plat_crash_console_flush 191 mov_imm x0, BRCM_CRASH_CONSOLE_BASE 192 b console_16550_core_flush 193 ret 194endfunc plat_crash_console_flush 195 196 /* ----------------------------------------------------- 197 * Placeholder function which should be redefined by 198 * each platform. This function is allowed to use 199 * registers x0 - x17. 200 * ----------------------------------------------------- 201 */ 202 203func plat_disable_acp 204 /*TBD-STINGRAY*/ 205 ret 206endfunc plat_disable_acp 207 208 /* ----------------------------------------------------- 209 * unsigned int plat_is_my_cpu_primary (void); 210 * 211 * Find out whether the current cpu is the primary 212 * cpu (applicable only after a cold boot) 213 * ----------------------------------------------------- 214 */ 215func plat_is_my_cpu_primary 216 mrs x0, mpidr_el1 217 b platform_is_primary_cpu 218endfunc plat_is_my_cpu_primary 219 220 /* ----------------------------------------------------- 221 * unsigned int plat_my_core_pos(void) 222 * This function uses the plat_brcm_calc_core_pos() 223 * definition to get the index of the calling CPU. 224 * ----------------------------------------------------- 225 */ 226func plat_my_core_pos 227 mrs x0, mpidr_el1 228 b plat_brcm_calc_core_pos 229endfunc plat_my_core_pos 230 231 /* ----------------------------------------------------- 232 * unsigned int platform_is_primary_cpu (void); 233 * 234 * Find out whether the current cpu is the primary 235 * cpu (applicable only after a cold boot) 236 * ----------------------------------------------------- 237 */ 238func platform_is_primary_cpu 239 mov x9, x30 240 bl plat_my_core_pos 241 cmp x0, #PRIMARY_CPU 242 cset x0, eq 243 ret x9 244endfunc platform_is_primary_cpu 245 246 /* ----------------------------------------------------- 247 * unsigned int plat_brcm_calc_core_pos(uint64_t mpidr) 248 * Helper function to calculate the core position. 249 * With this function: CorePos = (ClusterId * 4) + 250 * CoreId 251 * ----------------------------------------------------- 252 */ 253func plat_brcm_calc_core_pos 254 and x1, x0, #MPIDR_CPU_MASK 255 and x0, x0, #MPIDR_CLUSTER_MASK 256 add x0, x1, x0, LSR #7 257 ret 258endfunc plat_brcm_calc_core_pos 259 260func plat_get_my_entrypoint 261 mrs x0, mpidr_el1 262 b platform_get_entrypoint 263endfunc plat_get_my_entrypoint 264