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