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