1*edcece15Srutigl@gmail.com/* 2*edcece15Srutigl@gmail.com * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved. 3*edcece15Srutigl@gmail.com * 4*edcece15Srutigl@gmail.com * Copyright (C) 2022-2023 Nuvoton Ltd. 5*edcece15Srutigl@gmail.com * 6*edcece15Srutigl@gmail.com * SPDX-License-Identifier: BSD-3-Clause 7*edcece15Srutigl@gmail.com */ 8*edcece15Srutigl@gmail.com 9*edcece15Srutigl@gmail.com#ifndef NUVOTON_HELPERS_S 10*edcece15Srutigl@gmail.com#define NUVOTON_HELPERS_S 11*edcece15Srutigl@gmail.com 12*edcece15Srutigl@gmail.com#include <asm_macros.S> 13*edcece15Srutigl@gmail.com#include <cortex_a35.h> 14*edcece15Srutigl@gmail.com#include <platform_def.h> 15*edcece15Srutigl@gmail.com 16*edcece15Srutigl@gmail.com .globl plat_is_my_cpu_primary 17*edcece15Srutigl@gmail.com .globl plat_my_core_pos 18*edcece15Srutigl@gmail.com .globl plat_calc_core_pos 19*edcece15Srutigl@gmail.com .globl plat_reset_handler 20*edcece15Srutigl@gmail.com .globl plat_get_my_entrypoint 21*edcece15Srutigl@gmail.com .globl plat_secondary_cold_boot_setup 22*edcece15Srutigl@gmail.com .globl plat_crash_console_init 23*edcece15Srutigl@gmail.com .globl plat_crash_console_putc 24*edcece15Srutigl@gmail.com .globl plat_crash_console_flush 25*edcece15Srutigl@gmail.com .globl platform_mem_init 26*edcece15Srutigl@gmail.com .globl npcm845x_mailbox_init 27*edcece15Srutigl@gmail.com 28*edcece15Srutigl@gmail.com /* -------------------------------------------------------------------- 29*edcece15Srutigl@gmail.com * Helper macro that reads the part number of the current CPU and jumps 30*edcece15Srutigl@gmail.com * to the given label if it matches the CPU MIDR provided. 31*edcece15Srutigl@gmail.com * 32*edcece15Srutigl@gmail.com * Clobbers x0. 33*edcece15Srutigl@gmail.com * -------------------------------------------------------------------- 34*edcece15Srutigl@gmail.com */ 35*edcece15Srutigl@gmail.com .macro jump_if_cpu_midr _cpu_midr, _label 36*edcece15Srutigl@gmail.com 37*edcece15Srutigl@gmail.com mrs x0, midr_el1 38*edcece15Srutigl@gmail.com ubfx x0, x0, MIDR_PN_SHIFT, #12 39*edcece15Srutigl@gmail.com cmp w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK) 40*edcece15Srutigl@gmail.com b.eq \_label 41*edcece15Srutigl@gmail.com 42*edcece15Srutigl@gmail.com .endm 43*edcece15Srutigl@gmail.com 44*edcece15Srutigl@gmail.com /* ---------------------------------------------- 45*edcece15Srutigl@gmail.com * The mailbox_base is used to distinguish warm/cold 46*edcece15Srutigl@gmail.com * reset. The mailbox_base is in the data section, not 47*edcece15Srutigl@gmail.com * in .bss, this allows function to start using this 48*edcece15Srutigl@gmail.com * variable before the runtime memory is initialized. 49*edcece15Srutigl@gmail.com * ---------------------------------------------- 50*edcece15Srutigl@gmail.com */ 51*edcece15Srutigl@gmail.com .section .data.mailbox_base 52*edcece15Srutigl@gmail.com .align 3 53*edcece15Srutigl@gmail.com mailbox_base: .quad 0x0 54*edcece15Srutigl@gmail.com 55*edcece15Srutigl@gmail.com /* --------------------------------------------- 56*edcece15Srutigl@gmail.com * void plat_reset_handler(void); 57*edcece15Srutigl@gmail.com * 58*edcece15Srutigl@gmail.com * To add: Determine the SoC type and call the appropriate 59*edcece15Srutigl@gmail.com * reset handler. 60*edcece15Srutigl@gmail.com *----------------------------------------------- */ 61*edcece15Srutigl@gmail.com 62*edcece15Srutigl@gmail.comfunc plat_reset_handler 63*edcece15Srutigl@gmail.com ret 64*edcece15Srutigl@gmail.comendfunc plat_reset_handler 65*edcece15Srutigl@gmail.com 66*edcece15Srutigl@gmail.com /* ---------------------------------------------- 67*edcece15Srutigl@gmail.com * unsigned int plat_is_my_cpu_primary(void); 68*edcece15Srutigl@gmail.com * This function checks if this is the primary CPU 69*edcece15Srutigl@gmail.com * ---------------------------------------------- 70*edcece15Srutigl@gmail.com */ 71*edcece15Srutigl@gmail.comfunc plat_is_my_cpu_primary 72*edcece15Srutigl@gmail.com mrs x0, mpidr_el1 73*edcece15Srutigl@gmail.com and x0, x0, #(MPIDR_CPU_MASK) 74*edcece15Srutigl@gmail.com cmp x0, #PLAT_PRIMARY_CPU 75*edcece15Srutigl@gmail.com cset x0, eq 76*edcece15Srutigl@gmail.com ret 77*edcece15Srutigl@gmail.comendfunc plat_is_my_cpu_primary 78*edcece15Srutigl@gmail.com 79*edcece15Srutigl@gmail.com /* ---------------------------------------------- 80*edcece15Srutigl@gmail.com * unsigned int plat_my_core_pos(void) 81*edcece15Srutigl@gmail.com * This Function uses the plat_calc_core_pos() 82*edcece15Srutigl@gmail.com * to get the index of the calling CPU. 83*edcece15Srutigl@gmail.com * ---------------------------------------------- 84*edcece15Srutigl@gmail.com */ 85*edcece15Srutigl@gmail.comfunc plat_my_core_pos 86*edcece15Srutigl@gmail.com mrs x0, mpidr_el1 87*edcece15Srutigl@gmail.com and x1, x0, #MPIDR_CPU_MASK 88*edcece15Srutigl@gmail.com and x0, x0, #MPIDR_CLUSTER_MASK 89*edcece15Srutigl@gmail.com add x0, x1, x0, LSR #6 90*edcece15Srutigl@gmail.com ret 91*edcece15Srutigl@gmail.comendfunc plat_my_core_pos 92*edcece15Srutigl@gmail.com 93*edcece15Srutigl@gmail.com /* 94*edcece15Srutigl@gmail.com * unsigned int plat_calc_core_pos(uint64_t mpidr) 95*edcece15Srutigl@gmail.com * helper function to calculate the core position. 96*edcece15Srutigl@gmail.com * With this function. 97*edcece15Srutigl@gmail.com */ 98*edcece15Srutigl@gmail.comfunc plat_calc_core_pos 99*edcece15Srutigl@gmail.com and x1, x0, #MPIDR_CPU_MASK 100*edcece15Srutigl@gmail.com and x0, x0, #MPIDR_CLUSTER_MASK 101*edcece15Srutigl@gmail.com add x0, x1, x0, LSR #6 102*edcece15Srutigl@gmail.com ret 103*edcece15Srutigl@gmail.comendfunc plat_calc_core_pos 104*edcece15Srutigl@gmail.com 105*edcece15Srutigl@gmail.com /* --------------------------------------------- 106*edcece15Srutigl@gmail.com * function to get the entrypoint. 107*edcece15Srutigl@gmail.com * --------------------------------------------- 108*edcece15Srutigl@gmail.com */ 109*edcece15Srutigl@gmail.com /* --------------------------------------------------------------------- 110*edcece15Srutigl@gmail.com * uintptr_t plat_get_my_entrypoint (void); 111*edcece15Srutigl@gmail.com * 112*edcece15Srutigl@gmail.com * Main job of this routine is to distinguish between a cold and a warm 113*edcece15Srutigl@gmail.com * boot. 114*edcece15Srutigl@gmail.com * 115*edcece15Srutigl@gmail.com * This functions returns: 116*edcece15Srutigl@gmail.com * - 0 for a cold boot. 117*edcece15Srutigl@gmail.com * - Any other value for a warm boot. 118*edcece15Srutigl@gmail.com * --------------------------------------------------------------------- 119*edcece15Srutigl@gmail.com */ 120*edcece15Srutigl@gmail.comfunc plat_get_my_entrypoint 121*edcece15Srutigl@gmail.com mov x1, x30 122*edcece15Srutigl@gmail.com bl plat_is_my_cpu_primary 123*edcece15Srutigl@gmail.com /* 124*edcece15Srutigl@gmail.com * Secondaries always cold boot. 125*edcece15Srutigl@gmail.com */ 126*edcece15Srutigl@gmail.com cbz w0, 1f 127*edcece15Srutigl@gmail.com /* 128*edcece15Srutigl@gmail.com * Primaries warm boot if they are requested 129*edcece15Srutigl@gmail.com * to power off. 130*edcece15Srutigl@gmail.com */ 131*edcece15Srutigl@gmail.com mov_imm x0, PLAT_NPCM_TM_HOLD_BASE 132*edcece15Srutigl@gmail.com ldr x0, [x0] 133*edcece15Srutigl@gmail.com cmp x0, PLAT_NPCM_TM_HOLD_STATE_BSP_OFF 134*edcece15Srutigl@gmail.com adr x0, plat_wait_for_warm_boot 135*edcece15Srutigl@gmail.com csel x0, x0, xzr, eq 136*edcece15Srutigl@gmail.com ret x1 137*edcece15Srutigl@gmail.com1: mov x0, #0 138*edcece15Srutigl@gmail.com ret x1 139*edcece15Srutigl@gmail.comendfunc plat_get_my_entrypoint 140*edcece15Srutigl@gmail.com 141*edcece15Srutigl@gmail.comfunc npcm845x_mailbox_init 142*edcece15Srutigl@gmail.com adrp x1, mailbox_base 143*edcece15Srutigl@gmail.com str x0, [x1, :lo12:mailbox_base] 144*edcece15Srutigl@gmail.com ret 145*edcece15Srutigl@gmail.comendfunc npcm845x_mailbox_init 146*edcece15Srutigl@gmail.com 147*edcece15Srutigl@gmail.comfunc plat_wait_for_warm_boot 148*edcece15Srutigl@gmail.com /* 149*edcece15Srutigl@gmail.com * Calculate address of our hold entry. 150*edcece15Srutigl@gmail.com * As the function will never return, there is no need to save LR. 151*edcece15Srutigl@gmail.com */ 152*edcece15Srutigl@gmail.com bl plat_my_core_pos 153*edcece15Srutigl@gmail.com lsl x0, x0, #3 154*edcece15Srutigl@gmail.com mov x8, x0 155*edcece15Srutigl@gmail.com mov_imm x2, PLAT_NPCM_TM_HOLD_BASE 156*edcece15Srutigl@gmail.com add x0, x0, x2 157*edcece15Srutigl@gmail.com mov_imm x2, PLAT_NPCM_TRUSTED_NOTIFICATION_BASE 158*edcece15Srutigl@gmail.com add x8, x8, x2 159*edcece15Srutigl@gmail.com /* 160*edcece15Srutigl@gmail.com * This code runs way before requesting the warmboot of this core, 161*edcece15Srutigl@gmail.com * so it is possible to clear the mailbox before getting a request 162*edcece15Srutigl@gmail.com * to boot. 163*edcece15Srutigl@gmail.com */ 164*edcece15Srutigl@gmail.com mov x1, PLAT_NPCM_TM_HOLD_STATE_WAIT 165*edcece15Srutigl@gmail.com str x1,[x0] 166*edcece15Srutigl@gmail.com 167*edcece15Srutigl@gmail.com /* Notify that core is in pending state - do not use x0!, uses x7 and x8! */ 168*edcece15Srutigl@gmail.com mov x7, PLAT_NPCM_TM_NOTIFICATION_START 169*edcece15Srutigl@gmail.com str x7,[x8] 170*edcece15Srutigl@gmail.com /* 171*edcece15Srutigl@gmail.com * This code runs way before requesting the warmboot of this core, 172*edcece15Srutigl@gmail.com * so it is possible to clear the mailbox before getting a request 173*edcece15Srutigl@gmail.com * to boot. 174*edcece15Srutigl@gmail.com */ 175*edcece15Srutigl@gmail.com mov x1, PLAT_NPCM_TM_HOLD_STATE_WAIT 176*edcece15Srutigl@gmail.com str x1,[x0] 177*edcece15Srutigl@gmail.com /* Wait until we have a go */ 178*edcece15Srutigl@gmail.compoll_mailbox: 179*edcece15Srutigl@gmail.com wfe 180*edcece15Srutigl@gmail.com ldr x1, [x0] 181*edcece15Srutigl@gmail.com cmp x1, PLAT_NPCM_TM_HOLD_STATE_GO 182*edcece15Srutigl@gmail.com bne poll_mailbox 183*edcece15Srutigl@gmail.com 184*edcece15Srutigl@gmail.com mov x7, PLAT_NPCM_TM_NOTIFICATION_BR 185*edcece15Srutigl@gmail.com str x7,[x8] 186*edcece15Srutigl@gmail.com /* Jump to the provided entrypoint */ 187*edcece15Srutigl@gmail.com mov_imm x0, PLAT_NPCM_TM_ENTRYPOINT 188*edcece15Srutigl@gmail.com ldr x1, [x0] 189*edcece15Srutigl@gmail.com br x1 190*edcece15Srutigl@gmail.comendfunc plat_wait_for_warm_boot 191*edcece15Srutigl@gmail.com 192*edcece15Srutigl@gmail.comfunc plat_secondary_cold_boot_setup 193*edcece15Srutigl@gmail.com b plat_wait_for_warm_boot 194*edcece15Srutigl@gmail.comendfunc plat_secondary_cold_boot_setup 195*edcece15Srutigl@gmail.com 196*edcece15Srutigl@gmail.comfunc plat_crash_console_init 197*edcece15Srutigl@gmail.com mov x0, #1 198*edcece15Srutigl@gmail.com ret 199*edcece15Srutigl@gmail.comendfunc plat_crash_console_init 200*edcece15Srutigl@gmail.com 201*edcece15Srutigl@gmail.comfunc plat_crash_console_putc 202*edcece15Srutigl@gmail.com ret 203*edcece15Srutigl@gmail.comendfunc plat_crash_console_putc 204*edcece15Srutigl@gmail.com 205*edcece15Srutigl@gmail.comfunc plat_crash_console_flush 206*edcece15Srutigl@gmail.com mov x0, #0 207*edcece15Srutigl@gmail.com ret 208*edcece15Srutigl@gmail.comendfunc plat_crash_console_flush 209*edcece15Srutigl@gmail.com 210*edcece15Srutigl@gmail.comfunc platform_mem_init 211*edcece15Srutigl@gmail.com ret 212*edcece15Srutigl@gmail.comendfunc platform_mem_init 213*edcece15Srutigl@gmail.com 214*edcece15Srutigl@gmail.com#endif /* NUVOTON_HELPERS_S */ 215