sgi_helper.S 2.94 KB
Newer Older
1
2
3
4
5
6
7
8
9
/*
 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch.h>
#include <asm_macros.S>
#include <platform_def.h>
10
#include <cortex_a75.h>
11
12
13

	.globl	plat_is_my_cpu_primary
	.globl	plat_arm_calc_core_pos
14
	.globl	plat_reset_handler
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

	/* -----------------------------------------------------
	 * unsigned int plat_is_my_cpu_primary (void);
	 *
	 * Find out whether the current cpu is the primary
	 * cpu (applicable only after a cold boot)
	 * -----------------------------------------------------
	 */
func plat_is_my_cpu_primary
	mov	x9, x30
	bl	plat_my_core_pos
	ldr	x1, =SGI_BOOT_CFG_ADDR
	ldr	x1, [x1]
	ubfx	x1, x1, #PLAT_CSS_PRIMARY_CPU_SHIFT, \
			#PLAT_CSS_PRIMARY_CPU_BIT_WIDTH
	cmp	x0, x1
	cset	w0, eq
	ret	x9
endfunc plat_is_my_cpu_primary

	/* -----------------------------------------------------
36
37
38
39
40
41
42
43
44
45
46
47
48
49
	 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
	 *
	 * Helper function to calculate the core position.
	 * (ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) +
	 * (CPUId * CSS_SGI_MAX_PE_PER_CPU) +
	 * ThreadId
	 *
	 * which can be simplified as:
	 *
	 * ((ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER + CPUId) *
	 * CSS_SGI_MAX_PE_PER_CPU) + ThreadId
	 * ------------------------------------------------------
	 */

50
func plat_arm_calc_core_pos
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
	mov	x3, x0

	/*
	 * The MT bit in MPIDR is always set for SGI platforms
	 * and the affinity level 0 corresponds to thread affinity level.
	 */

	/* Extract individual affinity fields from MPIDR */
	ubfx    x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
	ubfx    x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
	ubfx    x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS

	/* Compute linear position */
	mov     x4, #CSS_SGI_MAX_CPUS_PER_CLUSTER
	madd    x1, x2, x4, x1
	mov     x5, #CSS_SGI_MAX_PE_PER_CPU
	madd    x0, x1, x5, x0
68
69
	ret
endfunc plat_arm_calc_core_pos
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

	/* ------------------------------------------------------
	 * Helper macro that reads the part number of the current
	 * CPU and jumps to the given label if it matches the CPU
	 * MIDR provided.
	 *
	 * Clobbers x0.
	 * -----------------------------------------------------
	 */
	.macro  jump_if_cpu_midr _cpu_midr, _label
	mrs	x0, midr_el1
	ubfx	x0, x0, MIDR_PN_SHIFT, #12
	cmp	w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
	b.eq	\_label
	.endm

	/* -----------------------------------------------------
	 * void plat_reset_handler(void);
	 *
	 * Determine the CPU MIDR and disable power down bit for
	 * that CPU.
	 * -----------------------------------------------------
	 */
func plat_reset_handler
	jump_if_cpu_midr CORTEX_A75_MIDR, A75
	ret

	/* -----------------------------------------------------
	 * Disable CPU power down bit in power control register
	 * -----------------------------------------------------
	 */
A75:
	mrs	x0, CORTEX_A75_CPUPWRCTLR_EL1
	bic	x0, x0, #CORTEX_A75_CORE_PWRDN_EN_MASK
	msr	CORTEX_A75_CPUPWRCTLR_EL1, x0
	isb
	ret
endfunc plat_reset_handler