xref: /rk3399_ARM-atf/include/plat/common/plat_hold_pen.S (revision ecab5d9e3f81b7bf093002b8614359adfc8d880d)
1/*
2 * Copyright (c) 2026, BayLibre SAS
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef PLAT_HOLD_PEN_S
8#define PLAT_HOLD_PEN_S
9
10#include <plat/common/plat_hold_pen.h>
11
12/*
13 * plat_hold_pen_wait_and_jump base, idx, tmp
14 *
15 * Compute the hold pen slot address from a base address and core
16 * index, then poll until both magic tags are valid and the entry
17 * field contains a real entrypoint (not HOLD_STATE_WAIT), then
18 * branch to it. This macro does not return.
19 *
20 * Before branching, writes HOLD_STATE_WAIT back to prevent stale
21 * reuse on warm boot. The dcache is not enabled when this macro is
22 * used so no flush is needed.
23 *
24 *   base: register holding the hold pen base address (clobbered)
25 *   idx:  register holding the core index (clobbered)
26 *   tmp:  scratch register
27 */
28
29#ifdef __aarch64__
30	.macro plat_hold_pen_wait_and_jump base, idx, tmp
31	mov	\tmp, #HOLD_SLOT_SIZE
32	madd	\base, \idx, \tmp, \base
33poll_\@:
34	ldr	\idx, [\base, #HOLD_SLOT_MAGIC1]
35	mov_imm	\tmp, HOLD_MAGIC1
36	cmp	\idx, \tmp
37	b.ne	wait_\@
38	ldr	\idx, [\base, #HOLD_SLOT_MAGIC2]
39	mov_imm	\tmp, HOLD_MAGIC2
40	cmp	\idx, \tmp
41	b.ne	wait_\@
42	ldr	\idx, [\base, #HOLD_SLOT_ENTRY]
43	cmp	\idx, #HOLD_STATE_WAIT
44	b.eq	wait_\@
45	/* Prevent reuse of stale entry on warm boot */
46	mov	\tmp, #HOLD_STATE_WAIT
47	str	\tmp, [\base, #HOLD_SLOT_ENTRY]
48	br	\idx
49wait_\@:
50	wfe
51	b	poll_\@
52	.endm
53#else /* __aarch64__ */
54	.macro plat_hold_pen_wait_and_jump base, idx, tmp
55	mov	\tmp, #HOLD_SLOT_SIZE
56	mla	\base, \idx, \tmp, \base
57poll_\@:
58	ldr	\idx, [\base, #HOLD_SLOT_MAGIC1]
59	mov_imm	\tmp, HOLD_MAGIC1
60	cmp	\idx, \tmp
61	bne	wait_\@
62	ldr	\idx, [\base, #HOLD_SLOT_MAGIC2]
63	mov_imm	\tmp, HOLD_MAGIC2
64	cmp	\idx, \tmp
65	bne	wait_\@
66	ldr	\idx, [\base, #HOLD_SLOT_ENTRY]
67	cmp	\idx, #HOLD_STATE_WAIT
68	beq	wait_\@
69	/* Prevent reuse of stale entry on warm boot */
70	mov	\tmp, #HOLD_STATE_WAIT
71	str	\tmp, [\base, #HOLD_SLOT_ENTRY]
72	bx	\idx
73wait_\@:
74	wfe
75	b	poll_\@
76	.endm
77#endif /* __aarch64__ */
78
79#endif /* PLAT_HOLD_PEN_S */
80