1 | /* |
2 | * Copyright (c) 2000-2009 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 | #ifndef _I386_MACHINE_ROUTINES_H_ |
33 | #define _I386_MACHINE_ROUTINES_H_ |
34 | |
35 | #include <mach/mach_types.h> |
36 | #include <mach/boolean.h> |
37 | #include <kern/kern_types.h> |
38 | #include <pexpert/pexpert.h> |
39 | |
40 | #include <sys/cdefs.h> |
41 | #include <sys/appleapiopts.h> |
42 | |
43 | #include <stdarg.h> |
44 | |
45 | __BEGIN_DECLS |
46 | |
47 | #ifdef XNU_KERNEL_PRIVATE |
48 | |
49 | /* are we a 64 bit platform ? */ |
50 | |
51 | boolean_t ml_is64bit(void); |
52 | |
53 | /* is this a 64bit thread? */ |
54 | |
55 | boolean_t ml_thread_is64bit(thread_t); |
56 | |
57 | /* is this a 64bit thread? */ |
58 | |
59 | boolean_t ml_state_is64bit(void *); |
60 | |
61 | /* set state of fpu save area for signal handling */ |
62 | |
63 | void ml_fp_setvalid(boolean_t); |
64 | |
65 | void ml_cpu_set_ldt(int); |
66 | |
67 | /* Interrupt handling */ |
68 | |
69 | /* Initialize Interrupts */ |
70 | void ml_init_interrupt(void); |
71 | |
72 | /* Generate a fake interrupt */ |
73 | void ml_cause_interrupt(void); |
74 | |
75 | /* Initialize Interrupts */ |
76 | void ml_install_interrupt_handler( |
77 | void *nub, |
78 | int source, |
79 | void *target, |
80 | IOInterruptHandler handler, |
81 | void *refCon); |
82 | |
83 | void ml_entropy_collect(void); |
84 | |
85 | uint64_t ml_get_timebase(void); |
86 | void ml_init_lock_timeout(void); |
87 | void ml_init_delay_spin_threshold(int); |
88 | |
89 | boolean_t ml_delay_should_spin(uint64_t interval); |
90 | |
91 | vm_offset_t |
92 | ml_static_ptovirt( |
93 | vm_offset_t); |
94 | |
95 | void ml_static_mfree( |
96 | vm_offset_t, |
97 | vm_size_t); |
98 | |
99 | /* boot memory allocation */ |
100 | vm_offset_t ml_static_malloc( |
101 | vm_size_t size); |
102 | |
103 | vm_offset_t ml_static_slide( |
104 | vm_offset_t vaddr); |
105 | |
106 | vm_offset_t ml_static_unslide( |
107 | vm_offset_t vaddr); |
108 | |
109 | /* virtual to physical on wired pages */ |
110 | vm_offset_t ml_vtophys( |
111 | vm_offset_t vaddr); |
112 | |
113 | vm_size_t ml_nofault_copy( |
114 | vm_offset_t virtsrc, vm_offset_t virtdst, vm_size_t size); |
115 | |
116 | boolean_t ml_validate_nofault( |
117 | vm_offset_t virtsrc, vm_size_t size); |
118 | |
119 | /* Machine topology info */ |
120 | uint64_t ml_cpu_cache_size(unsigned int level); |
121 | uint64_t ml_cpu_cache_sharing(unsigned int level); |
122 | |
123 | /* Initialize the maximum number of CPUs */ |
124 | void ml_init_max_cpus( |
125 | unsigned long max_cpus); |
126 | |
127 | extern void ml_cpu_up(void); |
128 | extern void ml_cpu_down(void); |
129 | |
130 | void bzero_phys_nc( |
131 | addr64_t phys_address, |
132 | uint32_t length); |
133 | extern uint32_t interrupt_timer_coalescing_enabled; |
134 | extern uint32_t idle_entry_timer_processing_hdeadline_threshold; |
135 | |
136 | #if TCOAL_INSTRUMENT |
137 | #define TCOAL_DEBUG KERNEL_DEBUG_CONSTANT |
138 | #else |
139 | #define TCOAL_DEBUG(x, a, b, c, d, e) do { } while(0) |
140 | #endif /* TCOAL_INSTRUMENT */ |
141 | |
142 | #if defined(PEXPERT_KERNEL_PRIVATE) || defined(MACH_KERNEL_PRIVATE) |
143 | /* IO memory map services */ |
144 | |
145 | /* Map memory map IO space */ |
146 | vm_offset_t ml_io_map( |
147 | vm_offset_t phys_addr, |
148 | vm_size_t size); |
149 | |
150 | |
151 | void ml_get_bouncepool_info( |
152 | vm_offset_t *phys_addr, |
153 | vm_size_t *size); |
154 | /* Indicates if spinlock, IPI and other timeouts should be suspended */ |
155 | boolean_t machine_timeout_suspended(void); |
156 | void plctrace_disable(void); |
157 | #endif /* PEXPERT_KERNEL_PRIVATE || MACH_KERNEL_PRIVATE */ |
158 | |
159 | /* Warm up a CPU to receive an interrupt */ |
160 | kern_return_t ml_interrupt_prewarm(uint64_t deadline); |
161 | |
162 | /* Check if the machine layer wants to intercept a panic call */ |
163 | boolean_t ml_wants_panic_trap_to_debugger(void); |
164 | |
165 | /* Machine layer routine for intercepting panics */ |
166 | void ml_panic_trap_to_debugger(const char *panic_format_str, |
167 | va_list *panic_args, |
168 | unsigned int reason, |
169 | void *ctx, |
170 | uint64_t panic_options_mask, |
171 | unsigned long panic_caller); |
172 | #endif /* XNU_KERNEL_PRIVATE */ |
173 | |
174 | #ifdef KERNEL_PRIVATE |
175 | |
176 | /* Type for the Time Base Enable function */ |
177 | typedef void (*time_base_enable_t)(cpu_id_t cpu_id, boolean_t enable); |
178 | |
179 | /* Type for the IPI Hander */ |
180 | typedef void (*ipi_handler_t)(void); |
181 | |
182 | /* Struct for ml_processor_register */ |
183 | struct ml_processor_info { |
184 | cpu_id_t cpu_id; |
185 | boolean_t boot_cpu; |
186 | vm_offset_t start_paddr; |
187 | boolean_t supports_nap; |
188 | unsigned long l2cr_value; |
189 | time_base_enable_t time_base_enable; |
190 | }; |
191 | |
192 | typedef struct ml_processor_info ml_processor_info_t; |
193 | |
194 | |
195 | /* Register a processor */ |
196 | kern_return_t |
197 | ml_processor_register( |
198 | cpu_id_t cpu_id, |
199 | uint32_t lapic_id, |
200 | processor_t *processor_out, |
201 | boolean_t boot_cpu, |
202 | boolean_t start ); |
203 | |
204 | /* PCI config cycle probing */ |
205 | boolean_t ml_probe_read( |
206 | vm_offset_t paddr, |
207 | unsigned int *val); |
208 | boolean_t ml_probe_read_64( |
209 | addr64_t paddr, |
210 | unsigned int *val); |
211 | |
212 | /* Read physical address byte */ |
213 | unsigned int ml_phys_read_byte( |
214 | vm_offset_t paddr); |
215 | unsigned int ml_phys_read_byte_64( |
216 | addr64_t paddr); |
217 | |
218 | /* Read physical address half word */ |
219 | unsigned int ml_phys_read_half( |
220 | vm_offset_t paddr); |
221 | unsigned int ml_phys_read_half_64( |
222 | addr64_t paddr); |
223 | |
224 | /* Read physical address word*/ |
225 | unsigned int ml_phys_read( |
226 | vm_offset_t paddr); |
227 | unsigned int ml_phys_read_64( |
228 | addr64_t paddr); |
229 | unsigned int ml_phys_read_word( |
230 | vm_offset_t paddr); |
231 | unsigned int ml_phys_read_word_64( |
232 | addr64_t paddr); |
233 | |
234 | /* Read physical address double word */ |
235 | unsigned long long ml_phys_read_double( |
236 | vm_offset_t paddr); |
237 | unsigned long long ml_phys_read_double_64( |
238 | addr64_t paddr); |
239 | |
240 | unsigned long long ml_io_read(uintptr_t iovaddr, int iovsz); |
241 | unsigned int ml_io_read8(uintptr_t iovaddr); |
242 | unsigned int ml_io_read16(uintptr_t iovaddr); |
243 | unsigned int ml_io_read32(uintptr_t iovaddr); |
244 | unsigned long long ml_io_read64(uintptr_t iovaddr); |
245 | |
246 | /* Write physical address byte */ |
247 | void ml_phys_write_byte( |
248 | vm_offset_t paddr, unsigned int data); |
249 | void ml_phys_write_byte_64( |
250 | addr64_t paddr, unsigned int data); |
251 | |
252 | /* Write physical address half word */ |
253 | void ml_phys_write_half( |
254 | vm_offset_t paddr, unsigned int data); |
255 | void ml_phys_write_half_64( |
256 | addr64_t paddr, unsigned int data); |
257 | |
258 | /* Write physical address word */ |
259 | void ml_phys_write( |
260 | vm_offset_t paddr, unsigned int data); |
261 | void ml_phys_write_64( |
262 | addr64_t paddr, unsigned int data); |
263 | void ml_phys_write_word( |
264 | vm_offset_t paddr, unsigned int data); |
265 | void ml_phys_write_word_64( |
266 | addr64_t paddr, unsigned int data); |
267 | |
268 | /* Write physical address double word */ |
269 | void ml_phys_write_double( |
270 | vm_offset_t paddr, unsigned long long data); |
271 | void ml_phys_write_double_64( |
272 | addr64_t paddr, unsigned long long data); |
273 | |
274 | /* Struct for ml_cpu_get_info */ |
275 | struct ml_cpu_info { |
276 | uint32_t vector_unit; |
277 | uint32_t cache_line_size; |
278 | uint32_t l1_icache_size; |
279 | uint32_t l1_dcache_size; |
280 | uint32_t l2_settings; |
281 | uint32_t l2_cache_size; |
282 | uint32_t l3_settings; |
283 | uint32_t l3_cache_size; |
284 | }; |
285 | |
286 | typedef struct ml_cpu_info ml_cpu_info_t; |
287 | |
288 | /* Get processor info */ |
289 | void ml_cpu_get_info(ml_cpu_info_t *ml_cpu_info); |
290 | |
291 | void ml_thread_policy( |
292 | thread_t thread, |
293 | unsigned policy_id, |
294 | unsigned policy_info); |
295 | |
296 | #define MACHINE_GROUP 0x00000001 |
297 | #define MACHINE_NETWORK_GROUP 0x10000000 |
298 | #define MACHINE_NETWORK_WORKLOOP 0x00000001 |
299 | #define MACHINE_NETWORK_NETISR 0x00000002 |
300 | |
301 | /* Return the maximum number of CPUs set by ml_init_max_cpus() */ |
302 | int ml_get_max_cpus( |
303 | void); |
304 | |
305 | /* |
306 | * The following are in pmCPU.c not machine_routines.c. |
307 | */ |
308 | extern void ml_set_maxsnoop(uint32_t maxdelay); |
309 | extern unsigned ml_get_maxsnoop(void); |
310 | extern void ml_set_maxbusdelay(uint32_t mdelay); |
311 | extern uint32_t ml_get_maxbusdelay(void); |
312 | extern void ml_set_maxintdelay(uint64_t mdelay); |
313 | extern uint64_t ml_get_maxintdelay(void); |
314 | extern boolean_t ml_get_interrupt_prewake_applicable(void); |
315 | |
316 | |
317 | extern uint64_t tmrCvt(uint64_t time, uint64_t conversion); |
318 | |
319 | extern uint64_t ml_cpu_int_event_time(void); |
320 | |
321 | #endif /* KERNEL_PRIVATE */ |
322 | |
323 | /* Get Interrupts Enabled */ |
324 | boolean_t ml_get_interrupts_enabled(void); |
325 | |
326 | /* Set Interrupts Enabled */ |
327 | boolean_t ml_set_interrupts_enabled(boolean_t enable); |
328 | |
329 | /* Check if running at interrupt context */ |
330 | boolean_t ml_at_interrupt_context(void); |
331 | |
332 | #ifdef XNU_KERNEL_PRIVATE |
333 | extern boolean_t ml_is_quiescing(void); |
334 | extern void ml_set_is_quiescing(boolean_t); |
335 | extern uint64_t ml_get_booter_memory_size(void); |
336 | #endif |
337 | |
338 | /* Zero bytes starting at a physical address */ |
339 | void bzero_phys( |
340 | addr64_t phys_address, |
341 | uint32_t length); |
342 | |
343 | /* Bytes available on current stack */ |
344 | vm_offset_t ml_stack_remaining(void); |
345 | |
346 | __END_DECLS |
347 | #if defined(MACH_KERNEL_PRIVATE) |
348 | __private_extern__ uint64_t |
349 | ml_phys_read_data(uint64_t paddr, int psz); |
350 | __private_extern__ void |
351 | pmap_verify_noncacheable(uintptr_t vaddr); |
352 | #endif /* MACH_KERNEL_PRIVATE */ |
353 | #ifdef XNU_KERNEL_PRIVATE |
354 | |
355 | boolean_t ml_fpu_avx_enabled(void); |
356 | #if !defined(RC_HIDE_XNU_J137) |
357 | boolean_t ml_fpu_avx512_enabled(void); |
358 | #endif |
359 | |
360 | void interrupt_latency_tracker_setup(void); |
361 | void interrupt_reset_latency_stats(void); |
362 | void interrupt_populate_latency_stats(char *, unsigned); |
363 | void ml_get_power_state(boolean_t *, boolean_t *); |
364 | |
365 | void timer_queue_expire_local(void*); |
366 | void timer_queue_expire_rescan(void*); |
367 | void ml_timer_evaluate(void); |
368 | boolean_t ml_timer_forced_evaluation(void); |
369 | |
370 | uint64_t ml_energy_stat(thread_t); |
371 | void ml_gpu_stat_update(uint64_t); |
372 | uint64_t ml_gpu_stat(thread_t); |
373 | boolean_t ml_recent_wake(void); |
374 | |
375 | extern uint64_t reportphyreaddelayabs; |
376 | extern uint32_t reportphyreadosbt; |
377 | extern uint32_t phyreadpanic; |
378 | |
379 | #endif /* XNU_KERNEL_PRIVATE */ |
380 | #endif /* _I386_MACHINE_ROUTINES_H_ */ |
381 | |