xref: /rk3399_ARM-atf/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_per_cpu.S (revision 7303319b3823e9e33748d963e9173f3678aba4da)
1/*
2 * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef RDV3_PER_CPU_S
8#define RDV3_PER_CPU_S
9
10#include <asm_macros.S>
11#include <lib/per_cpu/per_cpu_defs.h>
12
13.globl plat_per_cpu_dcache_clean
14.globl plat_per_cpu_node_base
15.globl plat_per_cpu_base
16
17/* ----------------------------------------------------------------------------
18 * Returns per cpu section node base
19 * Clobbers : x0, x2
20 * ----------------------------------------------------------------------------
21*/
22func plat_per_cpu_node_base
23	/* Load the base address of array */
24	adr_l	x2, per_cpu_nodes_base
25
26	/* Calculate the address of base[x0] */
27	add	x0, x2, x0, lsl #3
28	ldr	x0, [x0]
29	ret
30endfunc plat_per_cpu_node_base
31
32/* ----------------------------------------------------------------------------
33 * Calculate per cpu base for particular cpu.
34 * Clobbers : x0 - x2
35 * return per cpu base address in x0
36 * ----------------------------------------------------------------------------
37 */
38func plat_per_cpu_base
39	/* CPU index */
40	mov	x1, x0
41
42	/* Bounds check: cpu < (NRD_CHIP_COUNT * PER_CPU_NODE_CORE_COUNT) */
43	mov	x0, #NRD_CHIP_COUNT
44	mov	x2, #PER_CPU_NODE_CORE_COUNT
45	mul	x0, x0, x2
46	cmp	x1, x0
47	bhs	exit
48
49	/* r = cpu % PER_CPU_NODE_CORE_COUNT -> x2 */
50	udiv	x0, x1, x2
51	msub	x2, x0, x2, x1
52
53	/* x0 = per_cpu_nodes_base[node] */
54	adrp	x1, per_cpu_nodes_base
55	add	x1, x1, :lo12:per_cpu_nodes_base
56	add	x1, x1, x0, lsl #3
57	/* Loading x0 with particular per cpu section base address */
58	ldr	x0, [x1]
59
60	/* x0 += r * __PER_CPU_UNIT_SECTION_SIZE__ */
61	ldr	x1, =__PER_CPU_UNIT_SECTION_SIZE__
62	madd	x0, x2, x1, x0
63	ret
64
65exit:
66	b	plat_panic_handler
67
68endfunc plat_per_cpu_base
69
70/* ----------------------------------------------------------------------------
71 * No-op placeholder for rdv3.
72 *
73 * rdv3 uses HW_MANAGED_COHERENCY, so multi-CPU accesses to shared
74 * regions are kept coherent in hardware; no explicit dcache clean is needed.
75 * ----------------------------------------------------------------------------
76 */
77func plat_per_cpu_dcache_clean
78	ret
79endfunc plat_per_cpu_dcache_clean
80
81#endif /* RDV3_PER_CPU_S*/
82