1*b45b5bacSMarek Vasut/* 2*b45b5bacSMarek Vasut * Copyright (c) 2013-2025, ARM Limited and Contributors. All rights reserved. 3*b45b5bacSMarek Vasut * Copyright (c) 2015-2025, Renesas Electronics Corporation. All rights reserved. 4*b45b5bacSMarek Vasut * 5*b45b5bacSMarek Vasut * SPDX-License-Identifier: BSD-3-Clause 6*b45b5bacSMarek Vasut */ 7*b45b5bacSMarek Vasut 8*b45b5bacSMarek Vasut#include <arch.h> 9*b45b5bacSMarek Vasut#include <asm_macros.S> 10*b45b5bacSMarek Vasut#include <common/bl_common.h> 11*b45b5bacSMarek Vasut#include <common/runtime_svc.h> 12*b45b5bacSMarek Vasut#include <cortex_a55.h> 13*b45b5bacSMarek Vasut#include <platform_def.h> 14*b45b5bacSMarek Vasut 15*b45b5bacSMarek Vasut#include "rcar_def.h" 16*b45b5bacSMarek Vasut 17*b45b5bacSMarek Vasut .globl plat_get_my_entrypoint 18*b45b5bacSMarek Vasut .extern plat_set_my_stack 19*b45b5bacSMarek Vasut .globl platform_mem_init 20*b45b5bacSMarek Vasut 21*b45b5bacSMarek Vasut .globl plat_crash_console_init 22*b45b5bacSMarek Vasut .globl plat_crash_console_putc 23*b45b5bacSMarek Vasut .globl plat_crash_console_flush 24*b45b5bacSMarek Vasut .globl plat_invalidate_icache 25*b45b5bacSMarek Vasut .globl plat_secondary_reset 26*b45b5bacSMarek Vasut .globl plat_my_core_pos 27*b45b5bacSMarek Vasut .globl plat_renesas_calc_core_pos 28*b45b5bacSMarek Vasut .globl bl31_plat_enable_mmu 29*b45b5bacSMarek Vasut 30*b45b5bacSMarek Vasut .extern console_rcar_init 31*b45b5bacSMarek Vasut .extern console_rcar_putc 32*b45b5bacSMarek Vasut .extern console_rcar_flush 33*b45b5bacSMarek Vasut .extern rcar_pwrc_code_copy_to_system_ram 34*b45b5bacSMarek Vasut 35*b45b5bacSMarek Vasut /* ----------------------------------------------------- 36*b45b5bacSMarek Vasut * void platform_get_core_pos (mpidr) 37*b45b5bacSMarek Vasut * ----------------------------------------------------- 38*b45b5bacSMarek Vasut */ 39*b45b5bacSMarek Vasutfunc plat_renesas_calc_core_pos 40*b45b5bacSMarek Vasut lsr x0, x0, #8 41*b45b5bacSMarek Vasut and x1, x0, #MPIDR_CPU_MASK 42*b45b5bacSMarek Vasut and x0, x0, #MPIDR_CLUSTER_MASK 43*b45b5bacSMarek Vasut add x0, x1, x0, LSR #7 44*b45b5bacSMarek Vasut ret 45*b45b5bacSMarek Vasutendfunc plat_renesas_calc_core_pos 46*b45b5bacSMarek Vasut 47*b45b5bacSMarek Vasut /* ----------------------------------------------------- 48*b45b5bacSMarek Vasut * void platform_my_core_pos 49*b45b5bacSMarek Vasut * ----------------------------------------------------- 50*b45b5bacSMarek Vasut */ 51*b45b5bacSMarek Vasutfunc plat_my_core_pos 52*b45b5bacSMarek Vasut mrs x0, mpidr_el1 53*b45b5bacSMarek Vasut b plat_renesas_calc_core_pos 54*b45b5bacSMarek Vasutendfunc plat_my_core_pos 55*b45b5bacSMarek Vasut 56*b45b5bacSMarek Vasut /* ----------------------------------------------------- 57*b45b5bacSMarek Vasut * void platform_get_my_entrypoint (unsigned int mpid); 58*b45b5bacSMarek Vasut * 59*b45b5bacSMarek Vasut * Main job of this routine is to distinguish between 60*b45b5bacSMarek Vasut * a cold and warm boot. 61*b45b5bacSMarek Vasut * On a cold boot the secondaries first wait for the 62*b45b5bacSMarek Vasut * platform to be initialized after which they are 63*b45b5bacSMarek Vasut * hotplugged in. The primary proceeds to perform the 64*b45b5bacSMarek Vasut * platform initialization. 65*b45b5bacSMarek Vasut * On a warm boot, each cpu jumps to the address in its 66*b45b5bacSMarek Vasut * mailbox. 67*b45b5bacSMarek Vasut * 68*b45b5bacSMarek Vasut * TODO: Not a good idea to save lr in a temp reg 69*b45b5bacSMarek Vasut * ----------------------------------------------------- 70*b45b5bacSMarek Vasut */ 71*b45b5bacSMarek Vasutfunc plat_get_my_entrypoint 72*b45b5bacSMarek Vasut mrs x0, mpidr_el1 73*b45b5bacSMarek Vasut mov x9, x30 /* lr */ 74*b45b5bacSMarek Vasut 75*b45b5bacSMarek Vasut ldr x1, =BOOT_KIND_BASE 76*b45b5bacSMarek Vasut ldr x21, [x1] 77*b45b5bacSMarek Vasut 78*b45b5bacSMarek Vasut /* Check the reset info */ 79*b45b5bacSMarek Vasut and x1, x21, #0x000c 80*b45b5bacSMarek Vasut cmp x1, #0x0008 81*b45b5bacSMarek Vasut beq el3_panic 82*b45b5bacSMarek Vasut cmp x1, #0x000c 83*b45b5bacSMarek Vasut beq el3_panic 84*b45b5bacSMarek Vasut 85*b45b5bacSMarek Vasut /* Check the boot kind */ 86*b45b5bacSMarek Vasut and x1, x21, #0x0003 87*b45b5bacSMarek Vasut cmp x1, #0x0002 88*b45b5bacSMarek Vasut beq el3_panic 89*b45b5bacSMarek Vasut cmp x1, #0x0003 90*b45b5bacSMarek Vasut beq el3_panic 91*b45b5bacSMarek Vasut 92*b45b5bacSMarek Vasut /* warm boot or cold boot */ 93*b45b5bacSMarek Vasut and x1, x21, #1 94*b45b5bacSMarek Vasut cmp x1, #0 95*b45b5bacSMarek Vasut bne warm_reset 96*b45b5bacSMarek Vasut 97*b45b5bacSMarek Vasut /* Cold boot */ 98*b45b5bacSMarek Vasut mov x0, #0 99*b45b5bacSMarek Vasut b exit 100*b45b5bacSMarek Vasut 101*b45b5bacSMarek Vasutwarm_reset: 102*b45b5bacSMarek Vasut /* -------------------------------------------------------------------- 103*b45b5bacSMarek Vasut * A per-cpu mailbox is maintained in the trusted SDRAM. Its flushed out 104*b45b5bacSMarek Vasut * of the caches after every update using normal memory so its safe to 105*b45b5bacSMarek Vasut * read it here with SO attributes 106*b45b5bacSMarek Vasut * --------------------------------------------------------------------- 107*b45b5bacSMarek Vasut */ 108*b45b5bacSMarek Vasut ldr x10, =MBOX_BASE 109*b45b5bacSMarek Vasut bl plat_renesas_calc_core_pos 110*b45b5bacSMarek Vasut lsl x0, x0, #CACHE_WRITEBACK_SHIFT 111*b45b5bacSMarek Vasut ldr x0, [x10, x0] 112*b45b5bacSMarek Vasut cbz x0, _panic 113*b45b5bacSMarek Vasutexit: 114*b45b5bacSMarek Vasut ret x9 115*b45b5bacSMarek Vasut_panic: 116*b45b5bacSMarek Vasut b el3_panic 117*b45b5bacSMarek Vasut 118*b45b5bacSMarek Vasutendfunc plat_get_my_entrypoint 119*b45b5bacSMarek Vasut 120*b45b5bacSMarek Vasut /* --------------------------------------------- 121*b45b5bacSMarek Vasut * plat_secondary_reset 122*b45b5bacSMarek Vasut * 123*b45b5bacSMarek Vasut * --------------------------------------------- 124*b45b5bacSMarek Vasut */ 125*b45b5bacSMarek Vasutfunc plat_secondary_reset 126*b45b5bacSMarek Vasut mrs x0, sctlr_el3 127*b45b5bacSMarek Vasut bic x0, x0, #SCTLR_EE_BIT 128*b45b5bacSMarek Vasut msr sctlr_el3, x0 129*b45b5bacSMarek Vasut isb 130*b45b5bacSMarek Vasut 131*b45b5bacSMarek Vasut mrs x0, cptr_el3 132*b45b5bacSMarek Vasut bic w0, w0, #TCPAC_BIT 133*b45b5bacSMarek Vasut bic w0, w0, #TTA_BIT 134*b45b5bacSMarek Vasut bic w0, w0, #TFP_BIT 135*b45b5bacSMarek Vasut msr cptr_el3, x0 136*b45b5bacSMarek Vasut 137*b45b5bacSMarek Vasut mov_imm x0, PARAMS_BASE 138*b45b5bacSMarek Vasut mov_imm x2, BL31_BASE 139*b45b5bacSMarek Vasut ldr x3, =BOOT_KIND_BASE 140*b45b5bacSMarek Vasut mov x1, #0x1 141*b45b5bacSMarek Vasut str x1, [x3] 142*b45b5bacSMarek Vasut br x2 /* jump to BL31 */ 143*b45b5bacSMarek Vasut nop 144*b45b5bacSMarek Vasut nop 145*b45b5bacSMarek Vasut nop 146*b45b5bacSMarek Vasutendfunc plat_secondary_reset 147*b45b5bacSMarek Vasut 148*b45b5bacSMarek Vasut /* ----------------------------------------------------- 149*b45b5bacSMarek Vasut * void platform_mem_init (void); 150*b45b5bacSMarek Vasut * 151*b45b5bacSMarek Vasut * Zero out the mailbox registers in the shared memory 152*b45b5bacSMarek Vasut * and set the rcar_boot_kind_flag. 153*b45b5bacSMarek Vasut * The mmu is turned off right now and only the primary can 154*b45b5bacSMarek Vasut * ever execute this code. Secondaries will read the 155*b45b5bacSMarek Vasut * mailboxes using SO accesses. 156*b45b5bacSMarek Vasut * ----------------------------------------------------- 157*b45b5bacSMarek Vasut */ 158*b45b5bacSMarek Vasutfunc platform_mem_init 159*b45b5bacSMarek Vasut ldr x0, =MBOX_BASE 160*b45b5bacSMarek Vasut mov w1, #PLATFORM_CORE_COUNT 161*b45b5bacSMarek Vasutloop: 162*b45b5bacSMarek Vasut str xzr, [x0], #CACHE_WRITEBACK_GRANULE 163*b45b5bacSMarek Vasut subs w1, w1, #1 164*b45b5bacSMarek Vasut b.gt loop 165*b45b5bacSMarek Vasut ret 166*b45b5bacSMarek Vasutendfunc platform_mem_init 167*b45b5bacSMarek Vasut 168*b45b5bacSMarek Vasut /* --------------------------------------------- 169*b45b5bacSMarek Vasut * int plat_crash_console_init(void) 170*b45b5bacSMarek Vasut * Function to initialize log area 171*b45b5bacSMarek Vasut * --------------------------------------------- 172*b45b5bacSMarek Vasut */ 173*b45b5bacSMarek Vasutfunc plat_crash_console_init 174*b45b5bacSMarek Vasut mov x1, sp 175*b45b5bacSMarek Vasut mov_imm x2, RCAR_CRASH_STACK 176*b45b5bacSMarek Vasut mov sp, x2 177*b45b5bacSMarek Vasut str x1, [sp, #-16]! 178*b45b5bacSMarek Vasut str x30, [sp, #-16]! 179*b45b5bacSMarek Vasut bl console_rcar_init 180*b45b5bacSMarek Vasut ldr x30, [sp], #16 181*b45b5bacSMarek Vasut ldr x1, [sp], #16 182*b45b5bacSMarek Vasut mov sp, x1 183*b45b5bacSMarek Vasut ret 184*b45b5bacSMarek Vasutendfunc plat_crash_console_init 185*b45b5bacSMarek Vasut 186*b45b5bacSMarek Vasut /* --------------------------------------------- 187*b45b5bacSMarek Vasut * int plat_crash_console_putc(int c) 188*b45b5bacSMarek Vasut * Function to store a character to log area 189*b45b5bacSMarek Vasut * --------------------------------------------- 190*b45b5bacSMarek Vasut */ 191*b45b5bacSMarek Vasutfunc plat_crash_console_putc 192*b45b5bacSMarek Vasut mov x1, sp 193*b45b5bacSMarek Vasut mov_imm x2, RCAR_CRASH_STACK 194*b45b5bacSMarek Vasut mov sp, x2 195*b45b5bacSMarek Vasut str x1, [sp, #-16]! 196*b45b5bacSMarek Vasut str x30, [sp, #-16]! 197*b45b5bacSMarek Vasut str x3, [sp, #-16]! 198*b45b5bacSMarek Vasut str x4, [sp, #-16]! 199*b45b5bacSMarek Vasut str x5, [sp, #-16]! 200*b45b5bacSMarek Vasut str x6, [sp, #-16]! 201*b45b5bacSMarek Vasut str x7, [sp, #-16]! 202*b45b5bacSMarek Vasut bl console_rcar_putc 203*b45b5bacSMarek Vasut ldr x7, [sp], #16 204*b45b5bacSMarek Vasut ldr x6, [sp], #16 205*b45b5bacSMarek Vasut ldr x5, [sp], #16 206*b45b5bacSMarek Vasut ldr x4, [sp], #16 207*b45b5bacSMarek Vasut ldr x3, [sp], #16 208*b45b5bacSMarek Vasut ldr x30, [sp], #16 209*b45b5bacSMarek Vasut ldr x1, [sp], #16 210*b45b5bacSMarek Vasut mov sp, x1 211*b45b5bacSMarek Vasut ret 212*b45b5bacSMarek Vasutendfunc plat_crash_console_putc 213*b45b5bacSMarek Vasut 214*b45b5bacSMarek Vasut /* --------------------------------------------- 215*b45b5bacSMarek Vasut * void plat_crash_console_flush() 216*b45b5bacSMarek Vasut * --------------------------------------------- 217*b45b5bacSMarek Vasut */ 218*b45b5bacSMarek Vasutfunc plat_crash_console_flush 219*b45b5bacSMarek Vasut b console_rcar_flush 220*b45b5bacSMarek Vasutendfunc plat_crash_console_flush 221*b45b5bacSMarek Vasut 222*b45b5bacSMarek Vasut /* --------------------------------------------- 223*b45b5bacSMarek Vasut * void plat_invalidate_icache(void) 224*b45b5bacSMarek Vasut * Instruction Cache Invalidate All to PoU 225*b45b5bacSMarek Vasut * --------------------------------------------- 226*b45b5bacSMarek Vasut */ 227*b45b5bacSMarek Vasutfunc plat_invalidate_icache 228*b45b5bacSMarek Vasut ic iallu 229*b45b5bacSMarek Vasut ret 230*b45b5bacSMarek Vasutendfunc plat_invalidate_icache 231*b45b5bacSMarek Vasut 232*b45b5bacSMarek Vasut /* ----------------------------------------------------- 233*b45b5bacSMarek Vasut * void bl31_plat_enable_mmu(uint32_t flags); 234*b45b5bacSMarek Vasut * 235*b45b5bacSMarek Vasut * Enable MMU in BL31. 236*b45b5bacSMarek Vasut * And copy the code to run on System RAM. 237*b45b5bacSMarek Vasut * Note: This function call will only be done from Warm boot. 238*b45b5bacSMarek Vasut * ----------------------------------------------------- 239*b45b5bacSMarek Vasut */ 240*b45b5bacSMarek Vasutfunc bl31_plat_enable_mmu 241*b45b5bacSMarek Vasut mov x28, x30 242*b45b5bacSMarek Vasut bl enable_mmu_direct_el3 243*b45b5bacSMarek Vasut bl rcar_pwrc_code_copy_to_system_ram 244*b45b5bacSMarek Vasut mov x30, x28 245*b45b5bacSMarek Vasut ret 246*b45b5bacSMarek Vasutendfunc bl31_plat_enable_mmu 247