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
23
24func plat_my_core_pos
25	ldcopr	r0, MPIDR
26	b	plat_qemu_calc_core_pos
27endfunc plat_my_core_pos
28
29/*
30 *  unsigned int plat_qemu_calc_core_pos(u_register_t mpidr);
31 *  With this function: CorePos = (ClusterId * 4) + CoreId
32 */
33func plat_qemu_calc_core_pos
34	and	r1, r0, #MPIDR_CPU_MASK
35	and	r0, r0, #MPIDR_CLUSTER_MASK
36	add	r0, r1, r0, LSR #6
37	bx	lr
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	ldcopr	r0, MPIDR
49	ldr	r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
50	and	r0, r1
51	cmp	r0, #QEMU_PRIMARY_CPU
52	moveq	r0, #1
53	movne	r0, #0
54	bx	lr
55endfunc plat_is_my_cpu_primary
56
57	/* -----------------------------------------------------
58	 * void plat_secondary_cold_boot_setup (void);
59	 *
60	 * This function performs any platform specific actions
61	 * needed for a secondary cpu after a cold reset e.g
62	 * mark the cpu's presence, mechanism to place it in a
63	 * holding pen etc.
64	 * -----------------------------------------------------
65	 */
66func plat_secondary_cold_boot_setup
67	/* Calculate address of our hold entry */
68	bl	plat_my_core_pos
69	lsl	r0, r0, #PLAT_QEMU_HOLD_ENTRY_SHIFT
70	mov_imm	r2, PLAT_QEMU_HOLD_BASE
71
72	/* Wait until we have a go */
73poll_mailbox:
74	ldr	r1, [r2, r0]
75        cmp     r1, #PLAT_QEMU_HOLD_STATE_WAIT
76        beq     1f
77
78	/* Clear the mailbox again ready for next time. */
79	mov r1, #PLAT_QEMU_HOLD_STATE_WAIT
80	str r1, [r2, r0]
81
82	/* Jump to the provided entrypoint. */
83	mov_imm	r0, PLAT_QEMU_TRUSTED_MAILBOX_BASE
84	ldr	r1, [r0]
85	bx	r1
861:
87	wfe
88	b	poll_mailbox
89endfunc plat_secondary_cold_boot_setup
90
91func plat_get_my_entrypoint
92	/* TODO support warm boot */
93	mov	r0, #0
94	bx	lr
95endfunc plat_get_my_entrypoint
96
97func platform_mem_init
98	bx	lr
99endfunc platform_mem_init
100
101	/* ---------------------------------------------
102	 * int plat_crash_console_init(void)
103	 * Function to initialize the crash console
104	 * without a C Runtime to print crash report.
105	 * Clobber list : x0, x1, x2
106	 * ---------------------------------------------
107	 */
108func plat_crash_console_init
109	mov_imm	r0, PLAT_QEMU_CRASH_UART_BASE
110	mov_imm	r1, PLAT_QEMU_CRASH_UART_CLK_IN_HZ
111	mov_imm	r2, PLAT_QEMU_CONSOLE_BAUDRATE
112	b	console_pl011_core_init
113endfunc plat_crash_console_init
114
115	/* ---------------------------------------------
116	 * int plat_crash_console_putc(int c)
117	 * Function to print a character on the crash
118	 * console without a C Runtime.
119	 * Clobber list : x1, x2
120	 * ---------------------------------------------
121	 */
122func plat_crash_console_putc
123	mov_imm	r1, PLAT_QEMU_CRASH_UART_BASE
124	b	console_pl011_core_putc
125endfunc plat_crash_console_putc
126
127	/* ---------------------------------------------
128	 * void plat_crash_console_flush(int c)
129	 * Function to force a write of all buffered
130	 * data that hasn't been output.
131	 * Out : void.
132	 * Clobber list : x0, x1
133	 * ---------------------------------------------
134	 */
135func plat_crash_console_flush
136	mov_imm	r0, PLAT_QEMU_CRASH_UART_BASE
137	b	console_pl011_core_flush
138endfunc plat_crash_console_flush
139
140