]>
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> | |
f427ee49 | 39 | #include <kern/percpu.h> |
5ba3f43e A |
40 | #include <kern/processor.h> |
41 | #include <pexpert/pexpert.h> | |
42 | #include <arm/dbgwrap.h> | |
f427ee49 | 43 | #include <arm/machine_routines.h> |
5ba3f43e A |
44 | #include <arm/proc_reg.h> |
45 | #include <arm/thread.h> | |
46 | #include <arm/pmap.h> | |
47 | ||
48 | #if MONOTONIC | |
49 | #include <machine/monotonic.h> | |
50 | #endif /* MONOTONIC */ | |
51 | ||
0a7de745 | 52 | #define NSEC_PER_HZ (NSEC_PER_SEC / 100) |
5ba3f43e A |
53 | |
54 | typedef struct reset_handler_data { | |
0a7de745 A |
55 | vm_offset_t assist_reset_handler; /* Assist handler phys address */ |
56 | vm_offset_t cpu_data_entries; /* CpuDataEntries phys address */ | |
5ba3f43e | 57 | #if !__arm64__ |
0a7de745 | 58 | vm_offset_t boot_args; /* BootArgs phys address */ |
5ba3f43e A |
59 | #endif |
60 | } reset_handler_data_t; | |
61 | ||
0a7de745 | 62 | extern reset_handler_data_t ResetHandlerData; |
5ba3f43e | 63 | |
cb323159 A |
64 | /* Put the static check for cpumap_t here as it's defined in <kern/processor.h> */ |
65 | static_assert(sizeof(cpumap_t) * CHAR_BIT >= MAX_CPUS, "cpumap_t bitvector is too small for current MAX_CPUS value"); | |
66 | ||
0a7de745 | 67 | #ifdef __arm__ |
cb323159 | 68 | #define CPUWINDOWS_BASE_MASK 0xFFF00000UL |
5ba3f43e | 69 | #else |
f427ee49 | 70 | #define CPUWINDOWS_BASE_MASK 0xFFFFFFFFFFE00000UL |
5ba3f43e | 71 | #endif |
cb323159 | 72 | #define CPUWINDOWS_BASE (VM_MAX_KERNEL_ADDRESS & CPUWINDOWS_BASE_MASK) |
f427ee49 A |
73 | #define CPUWINDOWS_TOP (CPUWINDOWS_BASE + (MAX_CPUS * CPUWINDOWS_MAX * ARM_PGBYTES)) |
74 | ||
c3c9b80d | 75 | static_assert((CPUWINDOWS_BASE >= VM_MIN_KERNEL_ADDRESS) && ((CPUWINDOWS_TOP - 1) <= VM_MAX_KERNEL_ADDRESS), |
f427ee49 | 76 | "CPU copy windows too large for CPUWINDOWS_BASE_MASK value"); |
5ba3f43e A |
77 | |
78 | typedef struct cpu_data_entry { | |
f427ee49 A |
79 | void *cpu_data_paddr; /* Cpu data physical address */ |
80 | struct cpu_data *cpu_data_vaddr; /* Cpu data virtual address */ | |
5ba3f43e | 81 | #if __arm__ |
f427ee49 A |
82 | uint32_t cpu_data_offset_8; |
83 | uint32_t cpu_data_offset_12; | |
5ba3f43e A |
84 | #elif __arm64__ |
85 | #else | |
86 | #error Check cpu_data_entry padding for this architecture | |
87 | #endif | |
88 | } cpu_data_entry_t; | |
89 | ||
90 | ||
91 | typedef struct rtclock_timer { | |
0a7de745 | 92 | mpqueue_head_t queue; |
f427ee49 A |
93 | uint64_t deadline; |
94 | uint32_t is_set:1, | |
0a7de745 A |
95 | has_expired:1, |
96 | :0; | |
5ba3f43e A |
97 | } rtclock_timer_t; |
98 | ||
0a7de745 A |
99 | typedef struct { |
100 | /* | |
101 | * The wake variants of these counters are reset to 0 when the CPU wakes. | |
102 | */ | |
103 | uint64_t irq_ex_cnt; | |
104 | uint64_t irq_ex_cnt_wake; | |
105 | uint64_t ipi_cnt; | |
106 | uint64_t ipi_cnt_wake; | |
107 | uint64_t timer_cnt; | |
cb323159 | 108 | #if MONOTONIC |
0a7de745 | 109 | uint64_t pmi_cnt_wake; |
cb323159 | 110 | #endif /* MONOTONIC */ |
0a7de745 A |
111 | uint64_t undef_ex_cnt; |
112 | uint64_t unaligned_cnt; | |
113 | uint64_t vfp_cnt; | |
114 | uint64_t data_ex_cnt; | |
115 | uint64_t instr_ex_cnt; | |
5ba3f43e A |
116 | } cpu_stat_t; |
117 | ||
0a7de745 | 118 | typedef struct cpu_data { |
f427ee49 A |
119 | unsigned short cpu_number; |
120 | unsigned short cpu_flags; | |
121 | int cpu_type; | |
122 | int cpu_subtype; | |
123 | int cpu_threadtype; | |
124 | ||
125 | vm_offset_t istackptr; | |
126 | vm_offset_t intstack_top; | |
5ba3f43e | 127 | #if __arm64__ |
f427ee49 A |
128 | vm_offset_t excepstackptr; |
129 | vm_offset_t excepstack_top; | |
d9a64523 | 130 | #else |
f427ee49 A |
131 | vm_offset_t fiqstackptr; |
132 | vm_offset_t fiqstack_top; | |
5ba3f43e | 133 | #endif |
f427ee49 A |
134 | thread_t cpu_active_thread; |
135 | vm_offset_t cpu_active_stack; | |
136 | cpu_id_t cpu_id; | |
137 | unsigned volatile int cpu_signal; | |
138 | ast_t cpu_pending_ast; | |
139 | cache_dispatch_t cpu_cache_dispatch; | |
140 | ||
141 | #if __arm64__ | |
142 | uint64_t cpu_base_timebase; | |
143 | uint64_t cpu_timebase; | |
5ba3f43e A |
144 | #else |
145 | union { | |
0a7de745 A |
146 | struct { |
147 | uint32_t low; | |
148 | uint32_t high; | |
149 | } split; | |
150 | struct { | |
151 | uint64_t val; | |
152 | } raw; | |
153 | } cbtb; | |
154 | #define cpu_base_timebase_low cbtb.split.low | |
155 | #define cpu_base_timebase_high cbtb.split.high | |
5ba3f43e A |
156 | |
157 | union { | |
0a7de745 A |
158 | struct { |
159 | uint32_t low; | |
160 | uint32_t high; | |
161 | } split; | |
162 | struct { | |
163 | uint64_t val; | |
164 | } raw; | |
165 | } ctb; | |
166 | #define cpu_timebase_low ctb.split.low | |
167 | #define cpu_timebase_high ctb.split.high | |
5ba3f43e | 168 | #endif |
f427ee49 A |
169 | bool cpu_hibernate; /* This cpu is currently hibernating the system */ |
170 | bool cpu_running; | |
171 | bool cluster_master; | |
2a1bd2d3 A |
172 | #if __ARM_ARCH_8_5__ |
173 | bool sync_on_cswitch; | |
174 | #endif /* __ARM_ARCH_8_5__ */ | |
f427ee49 A |
175 | /* true if processor_start() or processor_exit() is operating on this CPU */ |
176 | bool in_state_transition; | |
5ba3f43e | 177 | |
f427ee49 A |
178 | uint32_t cpu_decrementer; |
179 | get_decrementer_t cpu_get_decrementer_func; | |
180 | set_decrementer_t cpu_set_decrementer_func; | |
181 | fiq_handler_t cpu_get_fiq_handler; | |
5ba3f43e | 182 | |
f427ee49 A |
183 | void *cpu_tbd_hardware_addr; |
184 | void *cpu_tbd_hardware_val; | |
5ba3f43e | 185 | |
f427ee49 | 186 | void *cpu_console_buf; |
5ba3f43e | 187 | |
f427ee49 A |
188 | processor_idle_t cpu_idle_notify; |
189 | uint64_t cpu_idle_latency; | |
190 | uint64_t cpu_idle_pop; | |
5ba3f43e | 191 | |
0a7de745 | 192 | #if __arm__ || __ARM_KERNEL_PROTECT__ |
f427ee49 | 193 | vm_offset_t cpu_exc_vectors; |
5c9f4661 | 194 | #endif /* __ARM_KERNEL_PROTECT__ */ |
f427ee49 A |
195 | vm_offset_t cpu_reset_handler; |
196 | uintptr_t cpu_reset_assist; | |
197 | uint32_t cpu_reset_type; | |
198 | ||
199 | unsigned int interrupt_source; | |
200 | void *cpu_int_state; | |
201 | IOInterruptHandler interrupt_handler; | |
202 | void *interrupt_nub; | |
203 | void *interrupt_target; | |
204 | void *interrupt_refCon; | |
205 | ||
206 | idle_timer_t idle_timer_notify; | |
207 | void *idle_timer_refcon; | |
208 | uint64_t idle_timer_deadline; | |
209 | ||
210 | uint64_t rtcPop; | |
211 | rtclock_timer_t rtclock_timer; | |
212 | struct _rtclock_data_ *rtclock_datap; | |
213 | ||
214 | arm_debug_state_t *cpu_user_debug; /* Current debug state */ | |
215 | vm_offset_t cpu_debug_interface_map; | |
216 | ||
217 | volatile int debugger_active; | |
218 | volatile int PAB_active; /* Tells the console if we are dumping backtraces */ | |
219 | ||
220 | void *cpu_xcall_p0; | |
221 | void *cpu_xcall_p1; | |
222 | void *cpu_imm_xcall_p0; | |
223 | void *cpu_imm_xcall_p1; | |
224 | ||
225 | #if defined(ARMA7) | |
226 | volatile uint32_t cpu_CLW_active; | |
227 | volatile uint64_t cpu_CLWFlush_req; | |
228 | volatile uint64_t cpu_CLWFlush_last; | |
229 | volatile uint64_t cpu_CLWClean_req; | |
230 | volatile uint64_t cpu_CLWClean_last; | |
5ba3f43e A |
231 | #endif |
232 | ||
0a7de745 | 233 | #if __arm64__ |
f427ee49 | 234 | vm_offset_t coresight_base[CORESIGHT_REGIONS]; |
5ba3f43e A |
235 | #endif |
236 | ||
237 | /* CCC ARMv8 registers */ | |
f427ee49 | 238 | uint64_t cpu_regmap_paddr; |
5ba3f43e | 239 | |
f427ee49 A |
240 | uint32_t cpu_phys_id; |
241 | uint32_t cpu_l2_access_penalty; | |
242 | platform_error_handler_t platform_error_handler; | |
5ba3f43e | 243 | |
f427ee49 | 244 | int cpu_mcount_off; |
5ba3f43e | 245 | |
f427ee49 A |
246 | #define ARM_CPU_ON_SLEEP_PATH 0x50535553UL |
247 | volatile unsigned int cpu_sleep_token; | |
248 | unsigned int cpu_sleep_token_last; | |
5ba3f43e | 249 | |
f427ee49 A |
250 | cluster_type_t cpu_cluster_type; |
251 | uint32_t cpu_cluster_id; | |
252 | uint32_t cpu_l2_id; | |
253 | uint32_t cpu_l2_size; | |
254 | uint32_t cpu_l3_id; | |
255 | uint32_t cpu_l3_size; | |
5ba3f43e | 256 | |
f427ee49 A |
257 | enum { |
258 | CPU_NOT_HALTED = 0, | |
259 | CPU_HALTED, | |
260 | CPU_HALTED_WITH_STATE | |
261 | } halt_status; | |
262 | #if defined(HAS_APPLE_PAC) | |
263 | uint64_t rop_key; | |
264 | uint64_t jop_key; | |
265 | #endif /* defined(HAS_APPLE_PAC) */ | |
5ba3f43e | 266 | |
f427ee49 | 267 | /* large structs with large alignment requirements */ |
5ba3f43e | 268 | #if KPC |
0a7de745 | 269 | /* double-buffered performance counter data */ |
f427ee49 | 270 | uint64_t *cpu_kpc_buf[2]; |
5ba3f43e | 271 | /* PMC shadow and reload value buffers */ |
f427ee49 A |
272 | uint64_t *cpu_kpc_shadow; |
273 | uint64_t *cpu_kpc_reload; | |
5ba3f43e A |
274 | #endif |
275 | #if MONOTONIC | |
f427ee49 | 276 | struct mt_cpu cpu_monotonic; |
5ba3f43e | 277 | #endif /* MONOTONIC */ |
f427ee49 | 278 | cpu_stat_t cpu_stat; |
c6bf4f31 | 279 | #if !XNU_MONITOR |
f427ee49 A |
280 | struct pmap_cpu_data cpu_pmap_cpu_data; |
281 | #endif | |
282 | dbgwrap_thread_state_t halt_state; | |
283 | #if DEVELOPMENT || DEBUG | |
284 | uint64_t wfe_count; | |
285 | uint64_t wfe_deadline_checks; | |
286 | uint64_t wfe_terminations; | |
c6bf4f31 | 287 | #endif |
5ba3f43e A |
288 | } cpu_data_t; |
289 | ||
290 | /* | |
291 | * cpu_flags | |
292 | */ | |
f427ee49 A |
293 | #define SleepState 0x0800 |
294 | #define StartedState 0x1000 | |
5ba3f43e | 295 | |
f427ee49 A |
296 | extern cpu_data_entry_t CpuDataEntries[MAX_CPUS]; |
297 | PERCPU_DECL(cpu_data_t, cpu_data); | |
298 | #define BootCpuData __PERCPU_NAME(cpu_data) | |
299 | extern boot_args *BootArgs; | |
5ba3f43e A |
300 | |
301 | #if __arm__ | |
f427ee49 A |
302 | extern unsigned int *ExceptionLowVectorsBase; |
303 | extern unsigned int *ExceptionVectorsTable; | |
5ba3f43e | 304 | #elif __arm64__ |
f427ee49 A |
305 | extern unsigned int LowResetVectorBase; |
306 | extern unsigned int LowResetVectorEnd; | |
5ba3f43e | 307 | #if WITH_CLASSIC_S2R |
f427ee49 | 308 | extern uint8_t SleepToken[8]; |
5ba3f43e | 309 | #endif |
f427ee49 | 310 | extern unsigned int LowExceptionVectorBase; |
5ba3f43e A |
311 | #else |
312 | #error Unknown arch | |
313 | #endif | |
314 | ||
f427ee49 A |
315 | extern cpu_data_t *cpu_datap(int cpu); |
316 | extern cpu_data_t *cpu_data_alloc(boolean_t is_boot); | |
317 | extern void cpu_stack_alloc(cpu_data_t*); | |
318 | extern void cpu_data_init(cpu_data_t *cpu_data_ptr); | |
319 | extern void cpu_data_free(cpu_data_t *cpu_data_ptr); | |
320 | extern kern_return_t cpu_data_register(cpu_data_t *cpu_data_ptr); | |
321 | extern cpu_data_t *processor_to_cpu_datap( processor_t processor); | |
5ba3f43e A |
322 | |
323 | #if __arm64__ | |
0a7de745 A |
324 | typedef struct sysreg_restore { |
325 | uint64_t tcr_el1; | |
5ba3f43e A |
326 | } sysreg_restore_t; |
327 | ||
328 | extern sysreg_restore_t sysreg_restore; | |
329 | #endif /* __arm64__ */ | |
330 | ||
0a7de745 | 331 | #endif /* ARM_CPU_DATA_INTERNAL */ |