1/*
2 * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
9#include <assert_macros.S>
10#include <platform_def.h>
11
12	.globl	plat_my_core_pos
13	.globl	plat_get_my_entrypoint
14	.globl	platform_mem_init
15	.globl	plat_qemu_calc_core_pos
16	.globl	plat_crash_console_init
17	.globl	plat_crash_console_putc
18	.globl	plat_crash_console_flush
19	.globl  plat_secondary_cold_boot_setup
20	.globl  plat_get_my_entrypoint
21	.globl  plat_is_my_cpu_primary
22
23func plat_my_core_pos
24	mrs	x0, mpidr_el1
25	b	plat_qemu_calc_core_pos
26endfunc plat_my_core_pos
27
28/*
29 *  unsigned int plat_qemu_calc_core_pos(u_register_t mpidr);
30 *  With this function: CorePos = (ClusterId * 4) + CoreId
31 */
32func plat_qemu_calc_core_pos
33	and	x1, x0, #MPIDR_CPU_MASK
34	and	x0, x0, #MPIDR_CLUSTER_MASK
35	add	x0, x1, x0, LSR #(MPIDR_AFFINITY_BITS -\
36				  PLATFORM_CPU_PER_CLUSTER_SHIFT)
37	ret
38endfunc plat_qemu_calc_core_pos
39
40	/* -----------------------------------------------------
41	 * unsigned int plat_is_my_cpu_primary (void);
42	 *
43	 * Find out whether the current cpu is the primary
44	 * cpu.
45	 * -----------------------------------------------------
46	 */
47func plat_is_my_cpu_primary
48	mrs	x0, mpidr_el1
49	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
50	cmp	x0, #QEMU_PRIMARY_CPU
51	cset	w0, eq
52	ret
53endfunc plat_is_my_cpu_primary
54
55	/* -----------------------------------------------------
56	 * void plat_secondary_cold_boot_setup (void);
57	 *
58	 * This function performs any platform specific actions
59	 * needed for a secondary cpu after a cold reset e.g
60	 * mark the cpu's presence, mechanism to place it in a
61	 * holding pen etc.
62	 * -----------------------------------------------------
63	 */
64func plat_secondary_cold_boot_setup
65	/* Calculate address of our hold entry */
66	bl	plat_my_core_pos
67	lsl	x0, x0, #PLAT_QEMU_HOLD_ENTRY_SHIFT
68	mov_imm	x2, PLAT_QEMU_HOLD_BASE
69
70	/* Wait until we have a go */
71poll_mailbox:
72	ldr	x1, [x2, x0]
73	cbz	x1, 1f
74
75	/* Clear the mailbox again ready for next time. */
76	mov x1, #PLAT_QEMU_HOLD_STATE_WAIT
77	str x1, [x2, x0]
78
79	/* Jump to the provided entrypoint. */
80	mov_imm	x0, PLAT_QEMU_TRUSTED_MAILBOX_BASE
81	ldr	x1, [x0]
82	br	x1
831:
84	wfe
85	b	poll_mailbox
86endfunc plat_secondary_cold_boot_setup
87
88func plat_get_my_entrypoint
89	/* TODO support warm boot */
90	mov	x0, #0
91	ret
92endfunc plat_get_my_entrypoint
93
94func platform_mem_init
95	ret
96endfunc platform_mem_init
97
98	/* ---------------------------------------------
99	 * int plat_crash_console_init(void)
100	 * Function to initialize the crash console
101	 * without a C Runtime to print crash report.
102	 * Clobber list : x0, x1, x2
103	 * ---------------------------------------------
104	 */
105func plat_crash_console_init
106	mov_imm x0, PLAT_QEMU_CRASH_UART_BASE
107	mov_imm x1, PLAT_QEMU_CRASH_UART_CLK_IN_HZ
108	mov_imm x2, PLAT_QEMU_CONSOLE_BAUDRATE
109	b	console_pl011_core_init
110endfunc plat_crash_console_init
111
112	/* ---------------------------------------------
113	 * int plat_crash_console_putc(int c)
114	 * Function to print a character on the crash
115	 * console without a C Runtime.
116	 * Clobber list : x1, x2
117	 * ---------------------------------------------
118	 */
119func plat_crash_console_putc
120	mov_imm	x1, PLAT_QEMU_CRASH_UART_BASE
121	b	console_pl011_core_putc
122endfunc plat_crash_console_putc
123
124	/* ---------------------------------------------
125	 * void plat_crash_console_flush(int c)
126	 * Function to force a write of all buffered
127	 * data that hasn't been output.
128	 * Out : void.
129	 * Clobber list : x0, x1
130	 * ---------------------------------------------
131	 */
132func plat_crash_console_flush
133	mov_imm	x0, PLAT_QEMU_CRASH_UART_BASE
134	b	console_pl011_core_flush
135endfunc plat_crash_console_flush
136
137