xref: /rk3399_ARM-atf/plat/qti/msm8916/aarch64/msm8916_helpers.S (revision dddba19a6a3cb7a1039beaffc3169c4eb3291afd)
1*dddba19aSStephan Gerhold/*
2*dddba19aSStephan Gerhold * Copyright (c) 2021, Stephan Gerhold <stephan@gerhold.net>
3*dddba19aSStephan Gerhold *
4*dddba19aSStephan Gerhold * SPDX-License-Identifier: BSD-3-Clause
5*dddba19aSStephan Gerhold */
6*dddba19aSStephan Gerhold
7*dddba19aSStephan Gerhold#include <arch.h>
8*dddba19aSStephan Gerhold#include <asm_macros.S>
9*dddba19aSStephan Gerhold
10*dddba19aSStephan Gerhold#include <msm8916_mmap.h>
11*dddba19aSStephan Gerhold
12*dddba19aSStephan Gerhold#define APCS_TCM_START_ADDR	0x10
13*dddba19aSStephan Gerhold#define APCS_TCM_REDIRECT_EN_0	BIT_32(0)
14*dddba19aSStephan Gerhold
15*dddba19aSStephan Gerhold	.globl	plat_crash_console_init
16*dddba19aSStephan Gerhold	.globl	plat_crash_console_putc
17*dddba19aSStephan Gerhold	.globl	plat_crash_console_flush
18*dddba19aSStephan Gerhold	.globl	plat_panic_handler
19*dddba19aSStephan Gerhold	.globl	plat_my_core_pos
20*dddba19aSStephan Gerhold	.globl	plat_get_my_entrypoint
21*dddba19aSStephan Gerhold	.globl	plat_reset_handler
22*dddba19aSStephan Gerhold	.globl	platform_mem_init
23*dddba19aSStephan Gerhold	.globl	msm8916_entry_point
24*dddba19aSStephan Gerhold
25*dddba19aSStephan Gerhold	/* -------------------------------------------------
26*dddba19aSStephan Gerhold	 * int plat_crash_console_init(void)
27*dddba19aSStephan Gerhold	 * Initialize the crash console.
28*dddba19aSStephan Gerhold	 * Out: x0 - 1 on success, 0 on error
29*dddba19aSStephan Gerhold	 * Clobber list : x0 - x4
30*dddba19aSStephan Gerhold	 * -------------------------------------------------
31*dddba19aSStephan Gerhold	 */
32*dddba19aSStephan Gerholdfunc plat_crash_console_init
33*dddba19aSStephan Gerhold	mov	x1, #BLSP_UART2_BASE
34*dddba19aSStephan Gerhold
35*dddba19aSStephan Gerhold	/*
36*dddba19aSStephan Gerhold	 * If the non-secure world has been actively using the UART there might
37*dddba19aSStephan Gerhold	 * be still some characters left to be sent in the FIFO. In that case,
38*dddba19aSStephan Gerhold	 * resetting the transmitter too early might cause all output to become
39*dddba19aSStephan Gerhold	 * corrupted. To avoid that, try to flush (wait until FIFO empty) first.
40*dddba19aSStephan Gerhold	 */
41*dddba19aSStephan Gerhold	mov	x4, lr
42*dddba19aSStephan Gerhold	bl	console_uartdm_core_flush
43*dddba19aSStephan Gerhold	mov	lr, x4
44*dddba19aSStephan Gerhold
45*dddba19aSStephan Gerhold	mov	x0, #1
46*dddba19aSStephan Gerhold	b	console_uartdm_core_init
47*dddba19aSStephan Gerholdendfunc plat_crash_console_init
48*dddba19aSStephan Gerhold
49*dddba19aSStephan Gerhold	/* -------------------------------------------------
50*dddba19aSStephan Gerhold	 * int plat_crash_console_putc(int c)
51*dddba19aSStephan Gerhold	 * Print a character on the crash console.
52*dddba19aSStephan Gerhold	 * In : w0 - character to be printed
53*dddba19aSStephan Gerhold	 * Out: w0 - printed character on success
54*dddba19aSStephan Gerhold	 * Clobber list : x1, x2
55*dddba19aSStephan Gerhold	 * -------------------------------------------------
56*dddba19aSStephan Gerhold	 */
57*dddba19aSStephan Gerholdfunc plat_crash_console_putc
58*dddba19aSStephan Gerhold	mov	x1, #BLSP_UART2_BASE
59*dddba19aSStephan Gerhold	b	console_uartdm_core_putc
60*dddba19aSStephan Gerholdendfunc plat_crash_console_putc
61*dddba19aSStephan Gerhold
62*dddba19aSStephan Gerhold	/* -------------------------------------------------
63*dddba19aSStephan Gerhold	 * void plat_crash_console_flush(void)
64*dddba19aSStephan Gerhold	 * Force a write of all buffered data that has not
65*dddba19aSStephan Gerhold	 * been output.
66*dddba19aSStephan Gerhold	 * Clobber list : x1, x2
67*dddba19aSStephan Gerhold	 * -------------------------------------------------
68*dddba19aSStephan Gerhold	 */
69*dddba19aSStephan Gerholdfunc plat_crash_console_flush
70*dddba19aSStephan Gerhold	mov	x1, #BLSP_UART2_BASE
71*dddba19aSStephan Gerhold	b	console_uartdm_core_flush
72*dddba19aSStephan Gerholdendfunc plat_crash_console_flush
73*dddba19aSStephan Gerhold
74*dddba19aSStephan Gerhold	/* -------------------------------------------------
75*dddba19aSStephan Gerhold	 * void plat_panic_handler(void) __dead
76*dddba19aSStephan Gerhold	 * Called when an unrecoverable error occurs.
77*dddba19aSStephan Gerhold	 * -------------------------------------------------
78*dddba19aSStephan Gerhold	 */
79*dddba19aSStephan Gerholdfunc plat_panic_handler
80*dddba19aSStephan Gerhold	/* Try to shutdown/reset */
81*dddba19aSStephan Gerhold	mov_imm	x0, MPM_PS_HOLD
82*dddba19aSStephan Gerhold	str	wzr, [x0]
83*dddba19aSStephan Gerhold1:	b	1b
84*dddba19aSStephan Gerholdendfunc plat_panic_handler
85*dddba19aSStephan Gerhold
86*dddba19aSStephan Gerhold	/* -------------------------------------------------
87*dddba19aSStephan Gerhold	 * unsigned int plat_my_core_pos(void)
88*dddba19aSStephan Gerhold	 * Out: x0 - index of the calling CPU
89*dddba19aSStephan Gerhold	 * -------------------------------------------------
90*dddba19aSStephan Gerhold	 */
91*dddba19aSStephan Gerholdfunc plat_my_core_pos
92*dddba19aSStephan Gerhold	/* There is just a single cluster so this is very simple */
93*dddba19aSStephan Gerhold	mrs	x0, mpidr_el1
94*dddba19aSStephan Gerhold	and	x0, x0, #MPIDR_CPU_MASK
95*dddba19aSStephan Gerhold	ret
96*dddba19aSStephan Gerholdendfunc plat_my_core_pos
97*dddba19aSStephan Gerhold
98*dddba19aSStephan Gerhold	/* -------------------------------------------------
99*dddba19aSStephan Gerhold	 * uintptr_t plat_get_my_entrypoint(void)
100*dddba19aSStephan Gerhold	 * Distinguish cold and warm boot and return warm boot
101*dddba19aSStephan Gerhold	 * entry address if available.
102*dddba19aSStephan Gerhold	 * Out: x0 - warm boot entry point or 0 on cold boot
103*dddba19aSStephan Gerhold	 * -------------------------------------------------
104*dddba19aSStephan Gerhold	 */
105*dddba19aSStephan Gerholdfunc plat_get_my_entrypoint
106*dddba19aSStephan Gerhold	ldr	x0, msm8916_entry_point
107*dddba19aSStephan Gerhold	ret
108*dddba19aSStephan Gerholdendfunc plat_get_my_entrypoint
109*dddba19aSStephan Gerhold
110*dddba19aSStephan Gerhold	/* -------------------------------------------------
111*dddba19aSStephan Gerhold	 * void plat_reset_handler(void)
112*dddba19aSStephan Gerhold	 * Perform additional initialization after reset.
113*dddba19aSStephan Gerhold	 * Clobber list : x0 - x18, x30
114*dddba19aSStephan Gerhold	 * -------------------------------------------------
115*dddba19aSStephan Gerhold	 */
116*dddba19aSStephan Gerholdfunc plat_reset_handler
117*dddba19aSStephan Gerhold	/*
118*dddba19aSStephan Gerhold	 * Check if the CPU is running at the correct address.
119*dddba19aSStephan Gerhold	 * During cold boot the CPU enters here at the wrong address
120*dddba19aSStephan Gerhold	 * using the "boot remapper". (It remaps the BL31_BASE to
121*dddba19aSStephan Gerhold	 * the CPU reset address 0x0).
122*dddba19aSStephan Gerhold	 */
123*dddba19aSStephan Gerhold	mov	x0, #BL31_BASE
124*dddba19aSStephan Gerhold	adr	x1, bl31_entrypoint
125*dddba19aSStephan Gerhold	cmp	x0, x1
126*dddba19aSStephan Gerhold	b.ne	_remapped_cold_boot
127*dddba19aSStephan Gerhold	/* Already running at correct address, just return directly */
128*dddba19aSStephan Gerhold	ret
129*dddba19aSStephan Gerhold
130*dddba19aSStephan Gerhold_remapped_cold_boot:
131*dddba19aSStephan Gerhold	/*
132*dddba19aSStephan Gerhold	 * The previous boot stage seems to use the L2 cache as TCM.
133*dddba19aSStephan Gerhold	 * Disable the TCM redirect before enabling caches to avoid
134*dddba19aSStephan Gerhold	 * strange crashes.
135*dddba19aSStephan Gerhold	 */
136*dddba19aSStephan Gerhold	mov	x2, #APCS_CFG
137*dddba19aSStephan Gerhold	ldr	w3, [x2, #APCS_TCM_START_ADDR]
138*dddba19aSStephan Gerhold	and	w3, w3, #~APCS_TCM_REDIRECT_EN_0
139*dddba19aSStephan Gerhold	str	w3, [x2, #APCS_TCM_START_ADDR]
140*dddba19aSStephan Gerhold
141*dddba19aSStephan Gerhold	/* Enter BL31 again at the real address */
142*dddba19aSStephan Gerhold	br	x0
143*dddba19aSStephan Gerholdendfunc plat_reset_handler
144*dddba19aSStephan Gerhold
145*dddba19aSStephan Gerhold	/* -------------------------------------------------
146*dddba19aSStephan Gerhold	 * void platform_mem_init(void)
147*dddba19aSStephan Gerhold	 * Performs additional memory initialization early
148*dddba19aSStephan Gerhold	 * in the boot process.
149*dddba19aSStephan Gerhold	 * -------------------------------------------------
150*dddba19aSStephan Gerhold	 */
151*dddba19aSStephan Gerholdfunc platform_mem_init
152*dddba19aSStephan Gerhold	/* Nothing to do here, all memory is already initialized */
153*dddba19aSStephan Gerhold	ret
154*dddba19aSStephan Gerholdendfunc platform_mem_init
155*dddba19aSStephan Gerhold
156*dddba19aSStephan Gerhold	.data
157*dddba19aSStephan Gerhold	.align	3
158*dddba19aSStephan Gerhold
159*dddba19aSStephan Gerhold	/* -------------------------------------------------
160*dddba19aSStephan Gerhold	 * Warm boot entry point for CPU. Set by PSCI code.
161*dddba19aSStephan Gerhold	 * -------------------------------------------------
162*dddba19aSStephan Gerhold	 */
163*dddba19aSStephan Gerholdmsm8916_entry_point:
164*dddba19aSStephan Gerhold	.quad	0
165