xref: /arm-trusted-firmware/include/lib/cpus/cpu_ops.h (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #ifndef CPU_OPS_H
8*91f16700Schasinglulu #define CPU_OPS_H
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <arch.h>
11*91f16700Schasinglulu 
12*91f16700Schasinglulu #define CPU_IMPL_PN_MASK	(MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | \
13*91f16700Schasinglulu 				(MIDR_PN_MASK << MIDR_PN_SHIFT)
14*91f16700Schasinglulu 
15*91f16700Schasinglulu /* Hardcode to keep compatible with assembly. sizeof(uintptr_t) */
16*91f16700Schasinglulu #if __aarch64__
17*91f16700Schasinglulu #define CPU_WORD_SIZE			8
18*91f16700Schasinglulu #else
19*91f16700Schasinglulu #define CPU_WORD_SIZE			4
20*91f16700Schasinglulu #endif /* __aarch64__ */
21*91f16700Schasinglulu 
22*91f16700Schasinglulu /* The number of CPU operations allowed */
23*91f16700Schasinglulu #define CPU_MAX_PWR_DWN_OPS		2
24*91f16700Schasinglulu /* Special constant to specify that CPU has no reset function */
25*91f16700Schasinglulu #define CPU_NO_RESET_FUNC		0
26*91f16700Schasinglulu 
27*91f16700Schasinglulu #if __aarch64__
28*91f16700Schasinglulu #define CPU_NO_EXTRA1_FUNC		0
29*91f16700Schasinglulu #define CPU_NO_EXTRA2_FUNC		0
30*91f16700Schasinglulu #define CPU_NO_EXTRA3_FUNC		0
31*91f16700Schasinglulu #endif /* __aarch64__ */
32*91f16700Schasinglulu 
33*91f16700Schasinglulu 
34*91f16700Schasinglulu /*
35*91f16700Schasinglulu  * Define the sizes of the fields in the cpu_ops structure. Word size is set per
36*91f16700Schasinglulu  * Aarch so keep these definitions the same and each can include whatever it
37*91f16700Schasinglulu  * needs.
38*91f16700Schasinglulu  */
39*91f16700Schasinglulu #define CPU_MIDR_SIZE		CPU_WORD_SIZE
40*91f16700Schasinglulu #ifdef IMAGE_AT_EL3
41*91f16700Schasinglulu #define CPU_RESET_FUNC_SIZE	CPU_WORD_SIZE
42*91f16700Schasinglulu #else
43*91f16700Schasinglulu #define CPU_RESET_FUNC_SIZE	0
44*91f16700Schasinglulu #endif /* IMAGE_AT_EL3 */
45*91f16700Schasinglulu #define CPU_EXTRA1_FUNC_SIZE	CPU_WORD_SIZE
46*91f16700Schasinglulu #define CPU_EXTRA2_FUNC_SIZE	CPU_WORD_SIZE
47*91f16700Schasinglulu #define CPU_EXTRA3_FUNC_SIZE	CPU_WORD_SIZE
48*91f16700Schasinglulu #define CPU_E_HANDLER_FUNC_SIZE CPU_WORD_SIZE
49*91f16700Schasinglulu /* The power down core and cluster is needed only in BL31 and BL32 */
50*91f16700Schasinglulu #if defined(IMAGE_BL31) || defined(IMAGE_BL32)
51*91f16700Schasinglulu #define CPU_PWR_DWN_OPS_SIZE	CPU_WORD_SIZE * CPU_MAX_PWR_DWN_OPS
52*91f16700Schasinglulu #else
53*91f16700Schasinglulu #define CPU_PWR_DWN_OPS_SIZE	0
54*91f16700Schasinglulu #endif /* defined(IMAGE_BL31) || defined(IMAGE_BL32) */
55*91f16700Schasinglulu 
56*91f16700Schasinglulu #define CPU_ERRATA_LIST_START_SIZE	CPU_WORD_SIZE
57*91f16700Schasinglulu #define CPU_ERRATA_LIST_END_SIZE	CPU_WORD_SIZE
58*91f16700Schasinglulu /* Fields required to print errata status  */
59*91f16700Schasinglulu #if REPORT_ERRATA
60*91f16700Schasinglulu #define CPU_ERRATA_FUNC_SIZE	CPU_WORD_SIZE
61*91f16700Schasinglulu #define CPU_CPU_STR_SIZE	CPU_WORD_SIZE
62*91f16700Schasinglulu /* BL1 doesn't require mutual exclusion and printed flag. */
63*91f16700Schasinglulu #if defined(IMAGE_BL31) || defined(IMAGE_BL32)
64*91f16700Schasinglulu #define CPU_ERRATA_LOCK_SIZE	CPU_WORD_SIZE
65*91f16700Schasinglulu #define CPU_ERRATA_PRINTED_SIZE	CPU_WORD_SIZE
66*91f16700Schasinglulu #else
67*91f16700Schasinglulu #define CPU_ERRATA_LOCK_SIZE	0
68*91f16700Schasinglulu #define CPU_ERRATA_PRINTED_SIZE	0
69*91f16700Schasinglulu #endif /* defined(IMAGE_BL31) || defined(IMAGE_BL32) */
70*91f16700Schasinglulu #else
71*91f16700Schasinglulu #define CPU_ERRATA_FUNC_SIZE	0
72*91f16700Schasinglulu #define CPU_CPU_STR_SIZE	0
73*91f16700Schasinglulu #define CPU_ERRATA_LOCK_SIZE	0
74*91f16700Schasinglulu #define CPU_ERRATA_PRINTED_SIZE	0
75*91f16700Schasinglulu #endif /* REPORT_ERRATA */
76*91f16700Schasinglulu 
77*91f16700Schasinglulu #if defined(IMAGE_BL31) && CRASH_REPORTING
78*91f16700Schasinglulu #define CPU_REG_DUMP_SIZE	CPU_WORD_SIZE
79*91f16700Schasinglulu #else
80*91f16700Schasinglulu #define CPU_REG_DUMP_SIZE	0
81*91f16700Schasinglulu #endif /* defined(IMAGE_BL31) && CRASH_REPORTING */
82*91f16700Schasinglulu 
83*91f16700Schasinglulu 
84*91f16700Schasinglulu /*
85*91f16700Schasinglulu  * Define the offsets to the fields in cpu_ops structure. Every offset is
86*91f16700Schasinglulu  * defined based on the offset and size of the previous field.
87*91f16700Schasinglulu  */
88*91f16700Schasinglulu #define CPU_MIDR		0
89*91f16700Schasinglulu #define CPU_RESET_FUNC		CPU_MIDR + CPU_MIDR_SIZE
90*91f16700Schasinglulu #if __aarch64__
91*91f16700Schasinglulu #define CPU_EXTRA1_FUNC		CPU_RESET_FUNC + CPU_RESET_FUNC_SIZE
92*91f16700Schasinglulu #define CPU_EXTRA2_FUNC		CPU_EXTRA1_FUNC + CPU_EXTRA1_FUNC_SIZE
93*91f16700Schasinglulu #define CPU_EXTRA3_FUNC		CPU_EXTRA2_FUNC + CPU_EXTRA2_FUNC_SIZE
94*91f16700Schasinglulu #define CPU_E_HANDLER_FUNC	CPU_EXTRA3_FUNC + CPU_EXTRA3_FUNC_SIZE
95*91f16700Schasinglulu #define CPU_PWR_DWN_OPS		CPU_E_HANDLER_FUNC + CPU_E_HANDLER_FUNC_SIZE
96*91f16700Schasinglulu #else
97*91f16700Schasinglulu #define CPU_PWR_DWN_OPS		CPU_RESET_FUNC + CPU_RESET_FUNC_SIZE
98*91f16700Schasinglulu #endif /* __aarch64__ */
99*91f16700Schasinglulu #define CPU_ERRATA_LIST_START	CPU_PWR_DWN_OPS + CPU_PWR_DWN_OPS_SIZE
100*91f16700Schasinglulu #define CPU_ERRATA_LIST_END	CPU_ERRATA_LIST_START + CPU_ERRATA_LIST_START_SIZE
101*91f16700Schasinglulu #define CPU_ERRATA_FUNC		CPU_ERRATA_LIST_END + CPU_ERRATA_LIST_END_SIZE
102*91f16700Schasinglulu #define CPU_CPU_STR		CPU_ERRATA_FUNC + CPU_ERRATA_FUNC_SIZE
103*91f16700Schasinglulu #define CPU_ERRATA_LOCK		CPU_CPU_STR + CPU_CPU_STR_SIZE
104*91f16700Schasinglulu #define CPU_ERRATA_PRINTED	CPU_ERRATA_LOCK + CPU_ERRATA_LOCK_SIZE
105*91f16700Schasinglulu #if __aarch64__
106*91f16700Schasinglulu #define CPU_REG_DUMP		CPU_ERRATA_PRINTED + CPU_ERRATA_PRINTED_SIZE
107*91f16700Schasinglulu #define CPU_OPS_SIZE		CPU_REG_DUMP + CPU_REG_DUMP_SIZE
108*91f16700Schasinglulu #else
109*91f16700Schasinglulu #define CPU_OPS_SIZE		CPU_ERRATA_PRINTED + CPU_ERRATA_PRINTED_SIZE
110*91f16700Schasinglulu #endif /* __aarch64__ */
111*91f16700Schasinglulu 
112*91f16700Schasinglulu #ifndef __ASSEMBLER__
113*91f16700Schasinglulu #include <lib/cassert.h>
114*91f16700Schasinglulu #include <lib/spinlock.h>
115*91f16700Schasinglulu 
116*91f16700Schasinglulu struct cpu_ops {
117*91f16700Schasinglulu 	unsigned long midr;
118*91f16700Schasinglulu #ifdef IMAGE_AT_EL3
119*91f16700Schasinglulu 	void (*reset_func)(void);
120*91f16700Schasinglulu #endif /* IMAGE_AT_EL3 */
121*91f16700Schasinglulu #if __aarch64__
122*91f16700Schasinglulu 	void (*extra1_func)(void);
123*91f16700Schasinglulu 	void (*extra2_func)(void);
124*91f16700Schasinglulu 	void (*extra3_func)(void);
125*91f16700Schasinglulu 	void (*e_handler_func)(long es);
126*91f16700Schasinglulu #endif /* __aarch64__ */
127*91f16700Schasinglulu #if (defined(IMAGE_BL31) || defined(IMAGE_BL32)) && CPU_MAX_PWR_DWN_OPS
128*91f16700Schasinglulu 	void (*pwr_dwn_ops[CPU_MAX_PWR_DWN_OPS])(void);
129*91f16700Schasinglulu #endif /* (defined(IMAGE_BL31) || defined(IMAGE_BL32)) && CPU_MAX_PWR_DWN_OPS */
130*91f16700Schasinglulu 	void *errata_list_start;
131*91f16700Schasinglulu 	void *errata_list_end;
132*91f16700Schasinglulu #if REPORT_ERRATA
133*91f16700Schasinglulu 	void (*errata_func)(void);
134*91f16700Schasinglulu 	char *cpu_str;
135*91f16700Schasinglulu #if defined(IMAGE_BL31) || defined(IMAGE_BL32)
136*91f16700Schasinglulu 	spinlock_t *errata_lock;
137*91f16700Schasinglulu 	unsigned int *errata_reported;
138*91f16700Schasinglulu #endif /* defined(IMAGE_BL31) || defined(IMAGE_BL32) */
139*91f16700Schasinglulu #endif /* REPORT_ERRATA */
140*91f16700Schasinglulu #if defined(IMAGE_BL31) && CRASH_REPORTING
141*91f16700Schasinglulu 	void (*reg_dump)(void);
142*91f16700Schasinglulu #endif /* defined(IMAGE_BL31) && CRASH_REPORTING */
143*91f16700Schasinglulu } __packed;
144*91f16700Schasinglulu 
145*91f16700Schasinglulu CASSERT(sizeof(struct cpu_ops) == CPU_OPS_SIZE,
146*91f16700Schasinglulu 	assert_cpu_ops_asm_c_different_sizes);
147*91f16700Schasinglulu 
148*91f16700Schasinglulu long cpu_get_rev_var(void);
149*91f16700Schasinglulu void *get_cpu_ops_ptr(void);
150*91f16700Schasinglulu 
151*91f16700Schasinglulu #endif /* __ASSEMBLER__ */
152*91f16700Schasinglulu #endif /* CPU_OPS_H */
153