]>
Commit | Line | Data |
---|---|---|
5ba3f43e A |
1 | /* |
2 | * Copyright (c) 2007 Apple Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. The rights granted to you under the License | |
10 | * may not be used to create, or enable the creation or redistribution of, | |
11 | * unlawful or unlicensed copies of an Apple operating system, or to | |
12 | * circumvent, violate, or enable the circumvention or violation of, any | |
13 | * terms of an Apple operating system software license agreement. | |
14 | * | |
15 | * Please obtain a copy of the License at | |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
17 | * | |
18 | * The Original Code and all software distributed under the License are | |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
23 | * Please see the License for the specific language governing rights and | |
24 | * limitations under the License. | |
25 | * | |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ | |
27 | */ | |
28 | /* | |
29 | * @OSF_COPYRIGHT@ | |
0a7de745 | 30 | * |
5ba3f43e A |
31 | */ |
32 | ||
0a7de745 | 33 | #ifndef ARM_CPU_DATA_INTERNAL |
5ba3f43e A |
34 | #define ARM_CPU_DATA_INTERNAL |
35 | ||
36 | #include <mach_assert.h> | |
37 | #include <kern/assert.h> | |
38 | #include <kern/kern_types.h> | |
39 | #include <kern/processor.h> | |
40 | #include <pexpert/pexpert.h> | |
41 | #include <arm/dbgwrap.h> | |
42 | #include <arm/proc_reg.h> | |
43 | #include <arm/thread.h> | |
44 | #include <arm/pmap.h> | |
45 | ||
46 | #if MONOTONIC | |
47 | #include <machine/monotonic.h> | |
48 | #endif /* MONOTONIC */ | |
49 | ||
0a7de745 | 50 | #define NSEC_PER_HZ (NSEC_PER_SEC / 100) |
5ba3f43e A |
51 | |
52 | typedef struct reset_handler_data { | |
0a7de745 A |
53 | vm_offset_t assist_reset_handler; /* Assist handler phys address */ |
54 | vm_offset_t cpu_data_entries; /* CpuDataEntries phys address */ | |
5ba3f43e | 55 | #if !__arm64__ |
0a7de745 | 56 | vm_offset_t boot_args; /* BootArgs phys address */ |
5ba3f43e A |
57 | #endif |
58 | } reset_handler_data_t; | |
59 | ||
0a7de745 | 60 | extern reset_handler_data_t ResetHandlerData; |
5ba3f43e A |
61 | |
62 | #if __ARM_SMP__ | |
63 | #ifdef CPU_COUNT | |
0a7de745 | 64 | #define MAX_CPUS CPU_COUNT |
5ba3f43e | 65 | #else |
0a7de745 | 66 | #define MAX_CPUS 2 |
5ba3f43e A |
67 | #endif |
68 | #else | |
0a7de745 | 69 | #define MAX_CPUS 1 |
5ba3f43e A |
70 | #endif |
71 | ||
cb323159 A |
72 | /* Put the static check for cpumap_t here as it's defined in <kern/processor.h> */ |
73 | static_assert(sizeof(cpumap_t) * CHAR_BIT >= MAX_CPUS, "cpumap_t bitvector is too small for current MAX_CPUS value"); | |
74 | ||
0a7de745 | 75 | #ifdef __arm__ |
cb323159 | 76 | #define CPUWINDOWS_BASE_MASK 0xFFF00000UL |
5ba3f43e | 77 | #else |
0a7de745 | 78 | #define CPUWINDOWS_BASE_MASK 0xFFFFFFFFFFF00000UL |
5ba3f43e | 79 | #endif |
cb323159 | 80 | #define CPUWINDOWS_BASE (VM_MAX_KERNEL_ADDRESS & CPUWINDOWS_BASE_MASK) |
0a7de745 | 81 | #define CPUWINDOWS_TOP (CPUWINDOWS_BASE + (MAX_CPUS * CPUWINDOWS_MAX * PAGE_SIZE)) |
5ba3f43e A |
82 | |
83 | typedef struct cpu_data_entry { | |
0a7de745 A |
84 | void *cpu_data_paddr; /* Cpu data physical address */ |
85 | struct cpu_data *cpu_data_vaddr; /* Cpu data virtual address */ | |
5ba3f43e | 86 | #if __arm__ |
0a7de745 A |
87 | uint32_t cpu_data_offset_8; |
88 | uint32_t cpu_data_offset_12; | |
5ba3f43e A |
89 | #elif __arm64__ |
90 | #else | |
91 | #error Check cpu_data_entry padding for this architecture | |
92 | #endif | |
93 | } cpu_data_entry_t; | |
94 | ||
95 | ||
96 | typedef struct rtclock_timer { | |
0a7de745 A |
97 | mpqueue_head_t queue; |
98 | uint64_t deadline; | |
99 | uint32_t is_set:1, | |
100 | has_expired:1, | |
101 | :0; | |
5ba3f43e A |
102 | } rtclock_timer_t; |
103 | ||
0a7de745 A |
104 | typedef struct { |
105 | /* | |
106 | * The wake variants of these counters are reset to 0 when the CPU wakes. | |
107 | */ | |
108 | uint64_t irq_ex_cnt; | |
109 | uint64_t irq_ex_cnt_wake; | |
110 | uint64_t ipi_cnt; | |
111 | uint64_t ipi_cnt_wake; | |
112 | uint64_t timer_cnt; | |
113 | uint64_t timer_cnt_wake; | |
cb323159 | 114 | #if MONOTONIC |
0a7de745 | 115 | uint64_t pmi_cnt_wake; |
cb323159 | 116 | #endif /* MONOTONIC */ |
0a7de745 A |
117 | uint64_t undef_ex_cnt; |
118 | uint64_t unaligned_cnt; | |
119 | uint64_t vfp_cnt; | |
120 | uint64_t data_ex_cnt; | |
121 | uint64_t instr_ex_cnt; | |
5ba3f43e A |
122 | } cpu_stat_t; |
123 | ||
0a7de745 A |
124 | typedef struct cpu_data { |
125 | unsigned short cpu_number; | |
126 | unsigned short cpu_flags; | |
127 | vm_offset_t istackptr; | |
128 | vm_offset_t intstack_top; | |
5ba3f43e | 129 | #if __arm64__ |
0a7de745 A |
130 | vm_offset_t excepstackptr; |
131 | vm_offset_t excepstack_top; | |
132 | boolean_t cluster_master; | |
d9a64523 | 133 | #else |
0a7de745 A |
134 | vm_offset_t fiqstackptr; |
135 | vm_offset_t fiqstack_top; | |
5ba3f43e | 136 | #endif |
0a7de745 A |
137 | boolean_t interrupts_enabled; |
138 | thread_t cpu_active_thread; | |
139 | vm_offset_t cpu_active_stack; | |
140 | unsigned int cpu_ident; | |
141 | cpu_id_t cpu_id; | |
142 | unsigned volatile int cpu_signal; | |
0a7de745 A |
143 | void *cpu_cache_dispatch; |
144 | ast_t cpu_pending_ast; | |
145 | struct processor *cpu_processor; | |
146 | int cpu_type; | |
147 | int cpu_subtype; | |
148 | int cpu_threadtype; | |
149 | int cpu_running; | |
5ba3f43e A |
150 | |
151 | #ifdef __LP64__ | |
0a7de745 A |
152 | uint64_t cpu_base_timebase; |
153 | uint64_t cpu_timebase; | |
5ba3f43e A |
154 | #else |
155 | union { | |
0a7de745 A |
156 | struct { |
157 | uint32_t low; | |
158 | uint32_t high; | |
159 | } split; | |
160 | struct { | |
161 | uint64_t val; | |
162 | } raw; | |
163 | } cbtb; | |
164 | #define cpu_base_timebase_low cbtb.split.low | |
165 | #define cpu_base_timebase_high cbtb.split.high | |
5ba3f43e A |
166 | |
167 | union { | |
0a7de745 A |
168 | struct { |
169 | uint32_t low; | |
170 | uint32_t high; | |
171 | } split; | |
172 | struct { | |
173 | uint64_t val; | |
174 | } raw; | |
175 | } ctb; | |
176 | #define cpu_timebase_low ctb.split.low | |
177 | #define cpu_timebase_high ctb.split.high | |
5ba3f43e A |
178 | #endif |
179 | ||
0a7de745 A |
180 | uint32_t cpu_decrementer; |
181 | void *cpu_get_decrementer_func; | |
182 | void *cpu_set_decrementer_func; | |
183 | void *cpu_get_fiq_handler; | |
5ba3f43e | 184 | |
0a7de745 A |
185 | void *cpu_tbd_hardware_addr; |
186 | void *cpu_tbd_hardware_val; | |
5ba3f43e | 187 | |
0a7de745 | 188 | void *cpu_console_buf; |
5ba3f43e | 189 | |
0a7de745 A |
190 | void *cpu_idle_notify; |
191 | uint64_t cpu_idle_latency; | |
192 | uint64_t cpu_idle_pop; | |
5ba3f43e | 193 | |
0a7de745 A |
194 | #if __arm__ || __ARM_KERNEL_PROTECT__ |
195 | vm_offset_t cpu_exc_vectors; | |
5c9f4661 | 196 | #endif /* __ARM_KERNEL_PROTECT__ */ |
0a7de745 A |
197 | vm_offset_t cpu_reset_handler; |
198 | uint32_t cpu_reset_type; | |
199 | uintptr_t cpu_reset_assist; | |
200 | ||
201 | void *cpu_int_state; | |
202 | IOInterruptHandler interrupt_handler; | |
203 | void *interrupt_nub; | |
204 | unsigned int interrupt_source; | |
205 | void *interrupt_target; | |
206 | void *interrupt_refCon; | |
207 | ||
208 | void *idle_timer_notify; | |
209 | void *idle_timer_refcon; | |
210 | uint64_t idle_timer_deadline; | |
211 | ||
212 | uint64_t quantum_timer_deadline; | |
213 | uint64_t rtcPop; | |
214 | rtclock_timer_t rtclock_timer; | |
215 | struct _rtclock_data_ *rtclock_datap; | |
216 | ||
217 | arm_debug_state_t *cpu_user_debug; /* Current debug state */ | |
218 | vm_offset_t cpu_debug_interface_map; | |
219 | ||
220 | volatile int debugger_active; | |
221 | ||
222 | void *cpu_xcall_p0; | |
223 | void *cpu_xcall_p1; | |
cb323159 A |
224 | void *cpu_imm_xcall_p0; |
225 | void *cpu_imm_xcall_p1; | |
0a7de745 A |
226 | |
227 | #if __ARM_SMP__ && defined(ARMA7) | |
228 | volatile uint32_t cpu_CLW_active; | |
229 | volatile uint64_t cpu_CLWFlush_req; | |
230 | volatile uint64_t cpu_CLWFlush_last; | |
231 | volatile uint64_t cpu_CLWClean_req; | |
232 | volatile uint64_t cpu_CLWClean_last; | |
5ba3f43e A |
233 | #endif |
234 | ||
235 | ||
0a7de745 A |
236 | #if __arm64__ |
237 | vm_offset_t coresight_base[CORESIGHT_REGIONS]; | |
5ba3f43e A |
238 | #endif |
239 | ||
240 | /* CCC ARMv8 registers */ | |
0a7de745 | 241 | uint64_t cpu_regmap_paddr; |
5ba3f43e | 242 | |
0a7de745 A |
243 | uint32_t cpu_phys_id; |
244 | uint32_t cpu_l2_access_penalty; | |
245 | void *platform_error_handler; | |
5ba3f43e | 246 | |
0a7de745 | 247 | int cpu_mcount_off; |
5ba3f43e | 248 | |
0a7de745 A |
249 | #define ARM_CPU_ON_SLEEP_PATH 0x50535553UL |
250 | volatile unsigned int cpu_sleep_token; | |
251 | unsigned int cpu_sleep_token_last; | |
5ba3f43e | 252 | |
0a7de745 | 253 | cpu_stat_t cpu_stat; |
5ba3f43e | 254 | |
0a7de745 | 255 | volatile int PAB_active; /* Tells the console if we are dumping backtraces */ |
5ba3f43e A |
256 | |
257 | #if KPC | |
0a7de745 A |
258 | /* double-buffered performance counter data */ |
259 | uint64_t *cpu_kpc_buf[2]; | |
5ba3f43e | 260 | /* PMC shadow and reload value buffers */ |
0a7de745 A |
261 | uint64_t *cpu_kpc_shadow; |
262 | uint64_t *cpu_kpc_reload; | |
5ba3f43e A |
263 | #endif |
264 | #if MONOTONIC | |
0a7de745 | 265 | struct mt_cpu cpu_monotonic; |
5ba3f43e | 266 | #endif /* MONOTONIC */ |
0a7de745 A |
267 | cluster_type_t cpu_cluster_type; |
268 | uint32_t cpu_cluster_id; | |
269 | uint32_t cpu_l2_id; | |
270 | uint32_t cpu_l2_size; | |
271 | uint32_t cpu_l3_id; | |
272 | uint32_t cpu_l3_size; | |
273 | ||
274 | struct pmap_cpu_data cpu_pmap_cpu_data; | |
275 | dbgwrap_thread_state_t halt_state; | |
5ba3f43e A |
276 | enum { |
277 | CPU_NOT_HALTED = 0, | |
278 | CPU_HALTED, | |
279 | CPU_HALTED_WITH_STATE | |
0a7de745 | 280 | } halt_status; |
cb323159 A |
281 | #if defined(HAS_APPLE_PAC) |
282 | uint64_t rop_key; | |
283 | #endif /* defined(HAS_APPLE_PAC) */ | |
5ba3f43e A |
284 | } cpu_data_t; |
285 | ||
286 | /* | |
287 | * cpu_flags | |
288 | */ | |
0a7de745 A |
289 | #define SleepState 0x0800 |
290 | #define StartedState 0x1000 | |
5ba3f43e | 291 | |
0a7de745 A |
292 | extern cpu_data_entry_t CpuDataEntries[MAX_CPUS]; |
293 | extern cpu_data_t BootCpuData; | |
294 | extern boot_args *BootArgs; | |
5ba3f43e A |
295 | |
296 | #if __arm__ | |
0a7de745 A |
297 | extern unsigned int *ExceptionLowVectorsBase; |
298 | extern unsigned int *ExceptionVectorsTable; | |
5ba3f43e | 299 | #elif __arm64__ |
0a7de745 A |
300 | extern unsigned int LowResetVectorBase; |
301 | extern unsigned int LowResetVectorEnd; | |
5ba3f43e | 302 | #if WITH_CLASSIC_S2R |
0a7de745 | 303 | extern uint8_t SleepToken[8]; |
5ba3f43e | 304 | #endif |
0a7de745 | 305 | extern unsigned int LowExceptionVectorBase; |
5ba3f43e A |
306 | #else |
307 | #error Unknown arch | |
308 | #endif | |
309 | ||
0a7de745 A |
310 | extern cpu_data_t *cpu_datap(int cpu); |
311 | extern cpu_data_t *cpu_data_alloc(boolean_t is_boot); | |
312 | extern void cpu_stack_alloc(cpu_data_t*); | |
313 | extern void cpu_data_init(cpu_data_t *cpu_data_ptr); | |
314 | extern void cpu_data_free(cpu_data_t *cpu_data_ptr); | |
315 | extern kern_return_t cpu_data_register(cpu_data_t *cpu_data_ptr); | |
316 | extern cpu_data_t *processor_to_cpu_datap( processor_t processor); | |
5ba3f43e A |
317 | |
318 | #if __arm64__ | |
0a7de745 A |
319 | typedef struct sysreg_restore { |
320 | uint64_t tcr_el1; | |
5ba3f43e A |
321 | } sysreg_restore_t; |
322 | ||
323 | extern sysreg_restore_t sysreg_restore; | |
324 | #endif /* __arm64__ */ | |
325 | ||
0a7de745 | 326 | #endif /* ARM_CPU_DATA_INTERNAL */ |