]> git.saurik.com Git - apple/xnu.git/blob - osfmk/arm/cpu_data_internal.h
ac6569f7c4d7d9ab014698e429eb4d9c3360f31b
[apple/xnu.git] / osfmk / arm / cpu_data_internal.h
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@
30 *
31 */
32
33 #ifndef ARM_CPU_DATA_INTERNAL
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
50 #define NSEC_PER_HZ (NSEC_PER_SEC / 100)
51
52 typedef struct reset_handler_data {
53 vm_offset_t assist_reset_handler; /* Assist handler phys address */
54 vm_offset_t cpu_data_entries; /* CpuDataEntries phys address */
55 #if !__arm64__
56 vm_offset_t boot_args; /* BootArgs phys address */
57 #endif
58 } reset_handler_data_t;
59
60 extern reset_handler_data_t ResetHandlerData;
61
62 #if __ARM_SMP__
63 #ifdef CPU_COUNT
64 #define MAX_CPUS CPU_COUNT
65 #else
66 #define MAX_CPUS 2
67 #endif
68 #else
69 #define MAX_CPUS 1
70 #endif
71
72 #define CPUWINDOWS_MAX 4
73 #ifdef __arm__
74 #define CPUWINDOWS_BASE 0xFFF00000UL
75 #else
76 #define CPUWINDOWS_BASE_MASK 0xFFFFFFFFFFF00000UL
77 #define CPUWINDOWS_BASE (VM_MAX_KERNEL_ADDRESS & CPUWINDOWS_BASE_MASK)
78 #endif
79 #define CPUWINDOWS_TOP (CPUWINDOWS_BASE + (MAX_CPUS * CPUWINDOWS_MAX * PAGE_SIZE))
80
81 typedef struct cpu_data_entry {
82 void *cpu_data_paddr; /* Cpu data physical address */
83 struct cpu_data *cpu_data_vaddr; /* Cpu data virtual address */
84 #if __arm__
85 uint32_t cpu_data_offset_8;
86 uint32_t cpu_data_offset_12;
87 #elif __arm64__
88 #else
89 #error Check cpu_data_entry padding for this architecture
90 #endif
91 } cpu_data_entry_t;
92
93
94 typedef struct rtclock_timer {
95 mpqueue_head_t queue;
96 uint64_t deadline;
97 uint32_t is_set:1,
98 has_expired:1,
99 :0;
100 } rtclock_timer_t;
101
102 typedef struct {
103 /*
104 * The wake variants of these counters are reset to 0 when the CPU wakes.
105 */
106 uint64_t irq_ex_cnt;
107 uint64_t irq_ex_cnt_wake;
108 uint64_t ipi_cnt;
109 uint64_t ipi_cnt_wake;
110 uint64_t timer_cnt;
111 uint64_t timer_cnt_wake;
112 uint64_t pmi_cnt;
113 uint64_t pmi_cnt_wake;
114 uint64_t undef_ex_cnt;
115 uint64_t unaligned_cnt;
116 uint64_t vfp_cnt;
117 uint64_t data_ex_cnt;
118 uint64_t instr_ex_cnt;
119 } cpu_stat_t;
120
121 typedef struct cpu_data {
122 unsigned short cpu_number;
123 unsigned short cpu_flags;
124 vm_offset_t istackptr;
125 vm_offset_t intstack_top;
126 #if __arm64__
127 vm_offset_t excepstackptr;
128 vm_offset_t excepstack_top;
129 boolean_t cluster_master;
130 #else
131 vm_offset_t fiqstackptr;
132 vm_offset_t fiqstack_top;
133 #endif
134 boolean_t interrupts_enabled;
135 thread_t cpu_active_thread;
136 vm_offset_t cpu_active_stack;
137 unsigned int cpu_ident;
138 cpu_id_t cpu_id;
139 unsigned volatile int cpu_signal;
140 #if DEBUG || DEVELOPMENT
141 void *failed_xcall;
142 unsigned int failed_signal;
143 volatile long failed_signal_count;
144 #endif
145 void *cpu_cache_dispatch;
146 ast_t cpu_pending_ast;
147 struct processor *cpu_processor;
148 int cpu_type;
149 int cpu_subtype;
150 int cpu_threadtype;
151 int cpu_running;
152
153 #ifdef __LP64__
154 uint64_t cpu_base_timebase;
155 uint64_t cpu_timebase;
156 #else
157 union {
158 struct {
159 uint32_t low;
160 uint32_t high;
161 } split;
162 struct {
163 uint64_t val;
164 } raw;
165 } cbtb;
166 #define cpu_base_timebase_low cbtb.split.low
167 #define cpu_base_timebase_high cbtb.split.high
168
169 union {
170 struct {
171 uint32_t low;
172 uint32_t high;
173 } split;
174 struct {
175 uint64_t val;
176 } raw;
177 } ctb;
178 #define cpu_timebase_low ctb.split.low
179 #define cpu_timebase_high ctb.split.high
180 #endif
181
182 uint32_t cpu_decrementer;
183 void *cpu_get_decrementer_func;
184 void *cpu_set_decrementer_func;
185 void *cpu_get_fiq_handler;
186
187 void *cpu_tbd_hardware_addr;
188 void *cpu_tbd_hardware_val;
189
190 void *cpu_console_buf;
191
192 void *cpu_idle_notify;
193 uint64_t cpu_idle_latency;
194 uint64_t cpu_idle_pop;
195
196 #if __arm__ || __ARM_KERNEL_PROTECT__
197 vm_offset_t cpu_exc_vectors;
198 #endif /* __ARM_KERNEL_PROTECT__ */
199 vm_offset_t cpu_reset_handler;
200 uint32_t cpu_reset_type;
201 uintptr_t cpu_reset_assist;
202
203 void *cpu_int_state;
204 IOInterruptHandler interrupt_handler;
205 void *interrupt_nub;
206 unsigned int interrupt_source;
207 void *interrupt_target;
208 void *interrupt_refCon;
209
210 void *idle_timer_notify;
211 void *idle_timer_refcon;
212 uint64_t idle_timer_deadline;
213
214 uint64_t quantum_timer_deadline;
215 uint64_t rtcPop;
216 rtclock_timer_t rtclock_timer;
217 struct _rtclock_data_ *rtclock_datap;
218
219 arm_debug_state_t *cpu_user_debug; /* Current debug state */
220 vm_offset_t cpu_debug_interface_map;
221
222 volatile int debugger_active;
223
224 void *cpu_xcall_p0;
225 void *cpu_xcall_p1;
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;
233 #endif
234
235
236 #if __arm64__
237 vm_offset_t coresight_base[CORESIGHT_REGIONS];
238 #endif
239
240 /* CCC ARMv8 registers */
241 uint64_t cpu_regmap_paddr;
242
243 uint32_t cpu_phys_id;
244 uint32_t cpu_l2_access_penalty;
245 void *platform_error_handler;
246
247 int cpu_mcount_off;
248
249 #define ARM_CPU_ON_SLEEP_PATH 0x50535553UL
250 volatile unsigned int cpu_sleep_token;
251 unsigned int cpu_sleep_token_last;
252
253 cpu_stat_t cpu_stat;
254
255 volatile int PAB_active; /* Tells the console if we are dumping backtraces */
256
257 #if KPC
258 /* double-buffered performance counter data */
259 uint64_t *cpu_kpc_buf[2];
260 /* PMC shadow and reload value buffers */
261 uint64_t *cpu_kpc_shadow;
262 uint64_t *cpu_kpc_reload;
263 #endif
264 #if MONOTONIC
265 struct mt_cpu cpu_monotonic;
266 #endif /* MONOTONIC */
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;
276 enum {
277 CPU_NOT_HALTED = 0,
278 CPU_HALTED,
279 CPU_HALTED_WITH_STATE
280 } halt_status;
281 } cpu_data_t;
282
283 /*
284 * cpu_flags
285 */
286 #define SleepState 0x0800
287 #define StartedState 0x1000
288
289 extern cpu_data_entry_t CpuDataEntries[MAX_CPUS];
290 extern cpu_data_t BootCpuData;
291 extern boot_args *BootArgs;
292
293 #if __arm__
294 extern unsigned int *ExceptionLowVectorsBase;
295 extern unsigned int *ExceptionVectorsTable;
296 #elif __arm64__
297 extern unsigned int LowResetVectorBase;
298 extern unsigned int LowResetVectorEnd;
299 #if WITH_CLASSIC_S2R
300 extern uint8_t SleepToken[8];
301 #endif
302 extern unsigned int LowExceptionVectorBase;
303 #else
304 #error Unknown arch
305 #endif
306
307 extern cpu_data_t *cpu_datap(int cpu);
308 extern cpu_data_t *cpu_data_alloc(boolean_t is_boot);
309 extern void cpu_stack_alloc(cpu_data_t*);
310 extern void cpu_data_init(cpu_data_t *cpu_data_ptr);
311 extern void cpu_data_free(cpu_data_t *cpu_data_ptr);
312 extern kern_return_t cpu_data_register(cpu_data_t *cpu_data_ptr);
313 extern cpu_data_t *processor_to_cpu_datap( processor_t processor);
314
315 #if __arm64__
316 typedef struct sysreg_restore {
317 uint64_t tcr_el1;
318 } sysreg_restore_t;
319
320 extern sysreg_restore_t sysreg_restore;
321 #endif /* __arm64__ */
322
323 #endif /* ARM_CPU_DATA_INTERNAL */