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