xref: /arm-trusted-firmware/plat/ax/lmt/plat_helper.S (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1/* SPDX-License-Identifier: BSD-3-Clause */
2/*
3 * Copyright (C) 2024, Charleye <wangkart@aliyun.com>
4 * All rights reserved.
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
9#include <assert_macros.S>
10#include <platform_def.h>
11
12	.global	lmt_calc_core_pos
13	.global	plat_my_core_pos
14	.global	platform_mem_init
15	.global	plat_is_my_cpu_primary
16	.global plat_secondary_cold_boot_setup
17	.globl  plat_get_my_entrypoint
18
19/*
20 * unsigned int lmt_calc_core_pos(u_register_t mpidr)
21 * core_pos = (cluster_id * max_cpus_per_cluster) + core_id
22 */
23func lmt_calc_core_pos
24	and	x1, x0, #MPIDR_CPU_MASK
25	and	x0, x0, #MPIDR_CLUSTER_MASK
26	add	x0, x1, x0, lsr #6
27	ret
28endfunc lmt_calc_core_pos
29
30func plat_my_core_pos
31	mrs	x0, mpidr_el1
32	lsr	x0, x0, #8
33	b	lmt_calc_core_pos
34endfunc plat_my_core_pos
35
36func platform_mem_init
37	ret
38endfunc platform_mem_init
39
40/*
41 * Secondary CPUs are placed in a holding pen, waiting for their mailbox
42 * to be populated. Note that all CPUs share the same mailbox ; therefore,
43 * populating it will release all CPUs from their holding pen. If
44 * finer-grained control is needed then this should be handled in the
45 * code that secondary CPUs jump to.
46 */
47func plat_secondary_cold_boot_setup
48	/* Calculate address of our hold entry */
49	bl	plat_my_core_pos
50	lsl	x0, x0, #PLAT_LMT_HOLD_ENTRY_SHIFT
51	mov_imm	x2, PLAT_LMT_HOLD_BASE
52
53	/* Wait until we have a go */
54poll_mailbox:
55	ldr	x1, [x2, x0]
56	cbz	x1, 1f
57
58	/* Clear the mailbox again ready for next time. */
59	mov x1, #PLAT_LMT_HOLD_STATE_WAIT
60	str x1, [x2, x0]
61
62	/* Jump to the provided entrypoint. */
63	mov_imm	x0, PLAT_LMT_TRUSTED_MAILBOX_BASE
64	ldr	x1, [x0]
65	br	x1
661:
67	wfe
68	b	poll_mailbox
69endfunc plat_secondary_cold_boot_setup
70
71func plat_get_my_entrypoint
72	/* TODO support warm boot */
73	mov	x0, #0
74	ret
75endfunc plat_get_my_entrypoint
76
77/*
78 * Find out whether the current cpu is the primary
79 * cpu (applicable only after a cold boot)
80 */
81func plat_is_my_cpu_primary
82	mrs	x0, mpidr_el1
83	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
84	cmp	x0, #PLAT_LMT_PRIMARY_CPU
85	cset	w0, eq
86	ret
87endfunc plat_is_my_cpu_primary
88