xref: /rk3399_ARM-atf/plat/nuvoton/common/nuvoton_helpers.S (revision edcece15c76423832fc1ffdb255528bf4c719516)
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