]>
Commit | Line | Data |
---|---|---|
1c79356b | 1 | /* |
f427ee49 | 2 | * Copyright (c) 2000-2019 Apple Inc. All rights reserved. |
1c79356b | 3 | * |
2d21ac55 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
0a7de745 | 5 | * |
2d21ac55 A |
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. | |
0a7de745 | 14 | * |
2d21ac55 A |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
0a7de745 | 17 | * |
2d21ac55 A |
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 | |
8f6c56a5 A |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
2d21ac55 A |
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. | |
0a7de745 | 25 | * |
2d21ac55 | 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
1c79356b A |
27 | */ |
28 | #ifndef _PEXPERT_PEXPERT_H_ | |
29 | #define _PEXPERT_PEXPERT_H_ | |
30 | ||
31 | #include <sys/cdefs.h> | |
32 | ||
39236c6e | 33 | #ifdef KERNEL |
1c79356b A |
34 | #include <IOKit/IOInterrupts.h> |
35 | #include <kern/kern_types.h> | |
39236c6e | 36 | #endif |
1c79356b | 37 | |
f427ee49 A |
38 | #if XNU_KERNEL_PRIVATE |
39 | #include <libkern/kernel_mach_header.h> | |
40 | #endif | |
41 | ||
1c79356b A |
42 | __BEGIN_DECLS |
43 | #include <mach/boolean.h> | |
44 | #include <mach/kern_return.h> | |
45 | #include <mach/machine/vm_types.h> | |
46 | ||
47 | #ifdef PEXPERT_KERNEL_PRIVATE | |
48 | #include <pexpert/protos.h> | |
49 | #endif | |
50 | #include <pexpert/boot.h> | |
51 | ||
0a7de745 | 52 | #if defined(PEXPERT_KERNEL_PRIVATE) || defined(IOKIT_KERNEL_PRIVATE) |
1c79356b A |
53 | typedef void *cpu_id_t; |
54 | #else | |
55 | typedef void *cpu_id_t; | |
56 | #endif | |
57 | ||
5ba3f43e | 58 | #if XNU_KERNEL_PRIVATE |
f427ee49 | 59 | #if defined(__arm__) || defined(__arm64__) |
5ba3f43e A |
60 | extern struct embedded_panic_header *panic_info; |
61 | extern vm_offset_t gPanicBase; | |
62 | extern unsigned int gPanicSize; | |
63 | ||
64 | /* | |
65 | * If invoked with NULL first argument, return the max buffer size that can | |
66 | * be saved in the second argument | |
67 | */ | |
68 | void PE_save_buffer_to_vram( | |
69 | unsigned char *, | |
70 | unsigned int *); | |
71 | ||
f427ee49 | 72 | #else /* defined(__arm__) || defined(__arm64__) */ |
5ba3f43e | 73 | extern struct macos_panic_header *panic_info; |
f427ee49 | 74 | #endif /* defined(__arm__) || defined(__arm64__) */ |
5ba3f43e | 75 | #endif /* XNU_KERNEL_PRIVATE */ |
1c79356b | 76 | |
0a7de745 | 77 | extern void lpss_uart_enable(boolean_t on_off); |
a39ff7e2 | 78 | |
1c79356b | 79 | void PE_enter_debugger( |
593a1d5f | 80 | const char *cause); |
1c79356b A |
81 | |
82 | void PE_init_platform( | |
0a7de745 | 83 | boolean_t vm_initialized, |
1c79356b A |
84 | void *args); |
85 | ||
fe8ab488 A |
86 | /* |
87 | * Copies the requested number of bytes from the "random-seed" property in | |
88 | * the device tree, and zeros the corresponding bytes in the device tree. | |
89 | * Returns the number of bytes actually copied. | |
90 | */ | |
91 | uint32_t PE_get_random_seed( | |
92 | unsigned char * dst_random_seed, | |
93 | uint32_t request_size); | |
94 | ||
3e170ce0 A |
95 | uint32_t PE_i_can_has_debugger( |
96 | uint32_t *); | |
97 | ||
cb323159 A |
98 | int PE_stub_poll_input(unsigned int options, char *c); |
99 | ||
5ba3f43e | 100 | #if defined(__arm__) || defined(__arm64__) |
d9a64523 A |
101 | boolean_t PE_panic_debugging_enabled(void); |
102 | ||
5ba3f43e A |
103 | void PE_mark_hwaccess(uint64_t thread); |
104 | #endif /* defined(__arm__) || defined(__arm64__) */ | |
105 | ||
106 | /* Return the offset of the specified address into the panic region */ | |
107 | uint32_t PE_get_offset_into_panic_region( | |
108 | char *location); | |
109 | ||
110 | /* Zeroes the panic header, sets the panic magic and initializes the header to be used */ | |
111 | void PE_init_panicheader( | |
112 | void); | |
113 | ||
114 | /* Updates the panic header during a nested panic */ | |
115 | void PE_update_panicheader_nestedpanic( | |
116 | void); | |
3e170ce0 | 117 | |
f427ee49 A |
118 | /* Invokes AppleARMIO::handlePlatformError() if present */ |
119 | bool PE_handle_platform_error( | |
120 | vm_offset_t far); | |
121 | ||
3e170ce0 A |
122 | #if KERNEL_PRIVATE |
123 | ||
124 | /* | |
125 | * Kexts should consult this bitmask to change behavior, since the kernel | |
126 | * may be configured as RELEASE but have MACH_ASSERT enabled, or boot args | |
127 | * may have changed the kernel behavior for statistics and kexts should | |
128 | * participate similarly | |
129 | */ | |
130 | ||
0a7de745 A |
131 | #define kPEICanHasAssertions 0x00000001 /* Exceptional conditions should panic() instead of printf() */ |
132 | #define kPEICanHasStatistics 0x00000002 /* Gather expensive statistics (that don't otherwise change behavior */ | |
133 | #define kPEICanHasDiagnosticAPI 0x00000004 /* Vend API to userspace or kexts that introspect kernel state */ | |
3e170ce0 A |
134 | |
135 | extern uint32_t PE_i_can_has_kernel_configuration(void); | |
136 | ||
137 | #endif /* KERNEL_PRIVATE */ | |
2d21ac55 | 138 | |
91447636 A |
139 | extern int32_t gPESerialBaud; |
140 | ||
3e170ce0 A |
141 | extern uint8_t gPlatformECID[8]; |
142 | ||
39037602 A |
143 | extern uint32_t gPlatformMemoryID; |
144 | ||
55e303ae A |
145 | unsigned int PE_init_taproot(vm_offset_t *taddr); |
146 | ||
1c79356b A |
147 | extern void (*PE_kputc)(char c); |
148 | ||
149 | void PE_init_printf( | |
150 | boolean_t vm_initialized); | |
151 | ||
152 | extern void (*PE_putc)(char c); | |
153 | ||
f427ee49 A |
154 | /* |
155 | * Perform pre-lockdown IOKit initialization. | |
156 | * This is guaranteed to execute prior to machine_lockdown(). | |
157 | * The precise operations performed by this function depend upon | |
158 | * the security model employed by the platform, but in general this | |
159 | * function should be expected to at least perform basic C++ runtime | |
160 | * and I/O registry initialization. | |
161 | */ | |
1c79356b A |
162 | void PE_init_iokit( |
163 | void); | |
164 | ||
f427ee49 A |
165 | /* |
166 | * Perform post-lockdown IOKit initialization. | |
167 | * This is guaranteed to execute after machine_lockdown(). | |
168 | * The precise operations performed by this function depend upon | |
169 | * the security model employed by the platform. For example, if | |
170 | * the platform treats machine_lockdown() as a strict security | |
171 | * checkpoint, general-purpose IOKit matching may not begin until | |
172 | * this function is called. | |
173 | */ | |
174 | void PE_lockdown_iokit( | |
175 | void); | |
176 | ||
1c79356b | 177 | struct clock_frequency_info_t { |
0a7de745 A |
178 | unsigned long bus_clock_rate_hz; |
179 | unsigned long cpu_clock_rate_hz; | |
180 | unsigned long dec_clock_rate_hz; | |
181 | unsigned long bus_clock_rate_num; | |
182 | unsigned long bus_clock_rate_den; | |
183 | unsigned long bus_to_cpu_rate_num; | |
184 | unsigned long bus_to_cpu_rate_den; | |
185 | unsigned long bus_to_dec_rate_num; | |
186 | unsigned long bus_to_dec_rate_den; | |
187 | unsigned long timebase_frequency_hz; | |
188 | unsigned long timebase_frequency_num; | |
189 | unsigned long timebase_frequency_den; | |
190 | unsigned long long bus_frequency_hz; | |
191 | unsigned long long bus_frequency_min_hz; | |
192 | unsigned long long bus_frequency_max_hz; | |
193 | unsigned long long cpu_frequency_hz; | |
194 | unsigned long long cpu_frequency_min_hz; | |
195 | unsigned long long cpu_frequency_max_hz; | |
196 | unsigned long long prf_frequency_hz; | |
197 | unsigned long long prf_frequency_min_hz; | |
198 | unsigned long long prf_frequency_max_hz; | |
199 | unsigned long long mem_frequency_hz; | |
200 | unsigned long long mem_frequency_min_hz; | |
201 | unsigned long long mem_frequency_max_hz; | |
202 | unsigned long long fix_frequency_hz; | |
1c79356b A |
203 | }; |
204 | ||
d9a64523 A |
205 | extern int debug_cpu_performance_degradation_factor; |
206 | ||
1c79356b A |
207 | typedef struct clock_frequency_info_t clock_frequency_info_t; |
208 | ||
209 | extern clock_frequency_info_t gPEClockFrequencyInfo; | |
210 | ||
211 | struct timebase_freq_t { | |
0a7de745 A |
212 | unsigned long timebase_num; |
213 | unsigned long timebase_den; | |
1c79356b A |
214 | }; |
215 | ||
216 | typedef void (*timebase_callback_func)(struct timebase_freq_t *timebase_freq); | |
217 | ||
218 | void PE_register_timebase_callback(timebase_callback_func callback); | |
219 | ||
220 | void PE_call_timebase_callback(void); | |
221 | ||
39236c6e | 222 | #ifdef KERNEL |
1c79356b A |
223 | void PE_install_interrupt_handler( |
224 | void *nub, int source, | |
0a7de745 | 225 | void *target, IOInterruptHandler handler, void *refCon); |
39236c6e | 226 | #endif |
1c79356b | 227 | |
91447636 | 228 | #ifndef _FN_KPRINTF |
0a7de745 A |
229 | #define _FN_KPRINTF |
230 | void kprintf(const char *fmt, ...) __printflike(1, 2); | |
2d21ac55 A |
231 | #endif |
232 | ||
b0d623f7 A |
233 | #if KERNEL_PRIVATE |
234 | void _consume_kprintf_args(int, ...); | |
235 | #endif | |
236 | ||
2d21ac55 | 237 | #if CONFIG_NO_KPRINTF_STRINGS |
b0d623f7 A |
238 | #if KERNEL_PRIVATE |
239 | #define kprintf(x, ...) _consume_kprintf_args( 0, ## __VA_ARGS__ ) | |
240 | #else | |
2d21ac55 | 241 | #define kprintf(x, ...) do {} while (0) |
91447636 | 242 | #endif |
b0d623f7 | 243 | #endif |
1c79356b A |
244 | |
245 | void init_display_putc(unsigned char *baseaddr, int rowbytes, int height); | |
246 | void display_putc(char c); | |
247 | ||
1c79356b | 248 | enum { |
0a7de745 A |
249 | kPEReadTOD, |
250 | kPEWriteTOD | |
1c79356b | 251 | }; |
1c79356b A |
252 | |
253 | enum { | |
0a7de745 A |
254 | kPEWaitForInput = 0x00000001, |
255 | kPERawInput = 0x00000002 | |
1c79356b | 256 | }; |
1c79356b A |
257 | |
258 | /* Private Stuff - eventually put in pexpertprivate.h */ | |
259 | enum { | |
0a7de745 A |
260 | kDebugTypeNone = 0, |
261 | kDebugTypeDisplay = 1, | |
262 | kDebugTypeSerial = 2 | |
1c79356b A |
263 | }; |
264 | ||
316670eb A |
265 | /* Scale factor values for PE_Video.v_scale */ |
266 | enum { | |
0a7de745 A |
267 | kPEScaleFactorUnknown = 0, |
268 | kPEScaleFactor1x = 1, | |
269 | kPEScaleFactor2x = 2 | |
316670eb A |
270 | }; |
271 | ||
1c79356b | 272 | struct PE_Video { |
0a7de745 A |
273 | unsigned long v_baseAddr; /* Base address of video memory */ |
274 | unsigned long v_rowBytes; /* Number of bytes per pixel row */ | |
275 | unsigned long v_width; /* Width */ | |
276 | unsigned long v_height; /* Height */ | |
277 | unsigned long v_depth; /* Pixel Depth */ | |
278 | unsigned long v_display; /* Text or Graphics */ | |
279 | char v_pixelFormat[64]; | |
280 | unsigned long v_offset; /* offset into video memory to start at */ | |
281 | unsigned long v_length; /* length of video memory (0 for v_rowBytes * v_height) */ | |
282 | unsigned char v_rotate; /* Rotation: 0:normal, 1:right 90, 2:left 180, 3:left 90 */ | |
283 | unsigned char v_scale; /* Scale Factor for both X & Y */ | |
284 | char reserved1[2]; | |
060df5ea | 285 | #ifdef __LP64__ |
0a7de745 | 286 | long reserved2; |
060df5ea | 287 | #else |
0a7de745 | 288 | long v_baseAddrHigh; |
060df5ea | 289 | #endif |
1c79356b A |
290 | }; |
291 | ||
292 | typedef struct PE_Video PE_Video; | |
293 | ||
2d21ac55 A |
294 | extern void initialize_screen(PE_Video *, unsigned int); |
295 | ||
b7266188 A |
296 | extern void dim_screen(void); |
297 | ||
1c79356b A |
298 | extern int PE_current_console( |
299 | PE_Video *info); | |
300 | ||
301 | extern void PE_create_console( | |
0a7de745 | 302 | void); |
1c79356b A |
303 | |
304 | extern int PE_initialize_console( | |
0a7de745 | 305 | PE_Video *newInfo, |
1c79356b A |
306 | int op); |
307 | ||
0a7de745 A |
308 | #define kPEGraphicsMode 1 |
309 | #define kPETextMode 2 | |
310 | #define kPETextScreen 3 | |
311 | #define kPEAcquireScreen 4 | |
312 | #define kPEReleaseScreen 5 | |
313 | #define kPEEnableScreen 6 | |
314 | #define kPEDisableScreen 7 | |
315 | #define kPEBaseAddressChange 8 | |
316 | #define kPERefreshBootGraphics 9 | |
1c79356b A |
317 | |
318 | extern void PE_display_icon( unsigned int flags, | |
0a7de745 | 319 | const char * name ); |
1c79356b A |
320 | |
321 | typedef struct PE_state { | |
0a7de745 A |
322 | boolean_t initialized; |
323 | PE_Video video; | |
324 | void *deviceTreeHead; | |
325 | void *bootArgs; | |
f427ee49 | 326 | vm_size_t deviceTreeSize; |
1c79356b A |
327 | } PE_state_t; |
328 | ||
329 | extern PE_state_t PE_state; | |
330 | ||
331 | extern char * PE_boot_args( | |
332 | void); | |
333 | ||
91447636 | 334 | extern boolean_t PE_parse_boot_argn( |
0a7de745 A |
335 | const char *arg_string, |
336 | void *arg_ptr, | |
337 | int max_arg); | |
1c79356b | 338 | |
39037602 A |
339 | #if XNU_KERNEL_PRIVATE |
340 | extern boolean_t PE_parse_boot_arg_str( | |
341 | const char *arg_string, | |
342 | char * arg_ptr, | |
343 | int size); | |
344 | #endif /* XNU_KERNEL_PRIVATE */ | |
345 | ||
6d2010ae | 346 | extern boolean_t PE_get_default( |
0a7de745 A |
347 | const char *property_name, |
348 | void *property_ptr, | |
6d2010ae A |
349 | unsigned int max_property); |
350 | ||
0a7de745 A |
351 | #define PE_default_value(_key, _variable, _default) \ |
352 | do { \ | |
353 | if (!PE_get_default((_key), &(_variable), sizeof(_variable))) \ | |
354 | _variable = _default; \ | |
6d2010ae A |
355 | } while(0) |
356 | ||
1c79356b | 357 | enum { |
0a7de745 A |
358 | kPEOptionKey = 0x3a, |
359 | kPECommandKey = 0x37, | |
360 | kPEControlKey = 0x36, | |
361 | kPEShiftKey = 0x38 | |
1c79356b A |
362 | }; |
363 | ||
364 | extern boolean_t PE_get_hotkey( | |
0a7de745 | 365 | unsigned char key); |
1c79356b A |
366 | |
367 | extern kern_return_t PE_cpu_start( | |
368 | cpu_id_t target, | |
369 | vm_offset_t start_paddr, | |
370 | vm_offset_t arg_paddr); | |
371 | ||
372 | extern void PE_cpu_halt( | |
373 | cpu_id_t target); | |
374 | ||
f427ee49 A |
375 | extern bool PE_cpu_down( |
376 | cpu_id_t target); | |
377 | ||
1c79356b A |
378 | extern void PE_cpu_signal( |
379 | cpu_id_t source, | |
380 | cpu_id_t target); | |
381 | ||
3e170ce0 A |
382 | extern void PE_cpu_signal_deferred( |
383 | cpu_id_t source, | |
384 | cpu_id_t target); | |
385 | ||
386 | extern void PE_cpu_signal_cancel( | |
387 | cpu_id_t source, | |
388 | cpu_id_t target); | |
389 | ||
1c79356b A |
390 | extern void PE_cpu_machine_init( |
391 | cpu_id_t target, | |
2d21ac55 | 392 | boolean_t bootb); |
1c79356b A |
393 | |
394 | extern void PE_cpu_machine_quiesce( | |
395 | cpu_id_t target); | |
396 | ||
397 | extern void pe_init_debug(void); | |
398 | ||
b7266188 A |
399 | extern boolean_t PE_imgsrc_mount_supported(void); |
400 | ||
cb323159 A |
401 | extern void PE_panic_hook(const char *str); |
402 | ||
403 | extern void PE_init_cpu(void); | |
404 | ||
f427ee49 A |
405 | extern void PE_handle_ext_interrupt(void); |
406 | ||
5ba3f43e A |
407 | #if defined(__arm__) || defined(__arm64__) |
408 | typedef void (*perfmon_interrupt_handler_func)(cpu_id_t source); | |
409 | extern kern_return_t PE_cpu_perfmon_interrupt_install_handler(perfmon_interrupt_handler_func handler); | |
410 | extern void PE_cpu_perfmon_interrupt_enable(cpu_id_t target, boolean_t enable); | |
411 | ||
5ba3f43e A |
412 | #if DEVELOPMENT || DEBUG |
413 | extern void PE_arm_debug_enable_trace(void); | |
cb323159 A |
414 | extern void (*PE_arm_debug_panic_hook)(const char *str); |
415 | #else | |
416 | extern void(*const PE_arm_debug_panic_hook)(const char *str); | |
5ba3f43e A |
417 | #endif |
418 | #endif | |
b7266188 | 419 | |
f427ee49 A |
420 | |
421 | typedef enum kc_kind { | |
422 | KCKindNone = -1, | |
423 | KCKindUnknown = 0, | |
424 | KCKindPrimary = 1, | |
425 | KCKindPageable = 2, | |
426 | KCKindAuxiliary = 3, | |
427 | KCNumKinds = 4, | |
428 | } kc_kind_t; | |
429 | ||
430 | typedef enum kc_format { | |
431 | KCFormatUnknown = 0, | |
432 | KCFormatStatic = 1, | |
433 | KCFormatDynamic = 2, | |
434 | KCFormatFileset = 3, | |
435 | KCFormatKCGEN = 4, | |
436 | } kc_format_t; | |
437 | ||
438 | #if XNU_KERNEL_PRIVATE | |
439 | /* set the mach-o header for a given KC type */ | |
440 | extern void PE_set_kc_header(kc_kind_t type, kernel_mach_header_t *header, uintptr_t slide); | |
441 | void PE_reset_kc_header(kc_kind_t type); | |
442 | /* set both lowest VA (base) and mach-o header for a given KC type */ | |
443 | extern void PE_set_kc_header_and_base(kc_kind_t type, kernel_mach_header_t *header, void *base, uintptr_t slide); | |
444 | /* The highest non-LINKEDIT virtual address */ | |
445 | extern vm_offset_t kc_highest_nonlinkedit_vmaddr; | |
446 | #endif | |
447 | /* returns a pointer to the mach-o header for a give KC type, returns NULL if nothing's been set */ | |
448 | extern void *PE_get_kc_header(kc_kind_t type); | |
449 | /* returns a pointer to the lowest VA of of the KC of the given type */ | |
450 | extern void *PE_get_kc_baseaddress(kc_kind_t type); | |
451 | /* returns an array of length KCNumKinds of the lowest VAs of each KC type - members could be NULL */ | |
452 | extern const void * const*PE_get_kc_base_pointers(void); | |
453 | /* returns the slide for the kext collection */ | |
454 | extern uintptr_t PE_get_kc_slide(kc_kind_t type); | |
455 | /* quickly accesss the format of the primary kc */ | |
456 | extern bool PE_get_primary_kc_format(kc_format_t *type); | |
457 | /* set vnode ptr for kc fileset */ | |
458 | extern void PE_set_kc_vp(kc_kind_t type, void *vp); | |
459 | /* quickly set vnode ptr for kc fileset */ | |
460 | void * PE_get_kc_vp(kc_kind_t type); | |
461 | /* drop reference to kc fileset vnodes */ | |
462 | void PE_reset_all_kc_vp(void); | |
463 | ||
b7266188 | 464 | #if KERNEL_PRIVATE |
5c9f4661 A |
465 | #if defined(__arm64__) |
466 | extern uint8_t PE_smc_stashed_x86_power_state; | |
467 | extern uint8_t PE_smc_stashed_x86_efi_boot_state; | |
468 | extern uint8_t PE_smc_stashed_x86_system_state; | |
d9a64523 A |
469 | extern uint8_t PE_smc_stashed_x86_shutdown_cause; |
470 | extern uint64_t PE_smc_stashed_x86_prev_power_transitions; | |
5c9f4661 A |
471 | extern uint32_t PE_pcie_stashed_link_state; |
472 | #endif | |
473 | ||
b7266188 | 474 | boolean_t PE_reboot_on_panic(void); |
743345f9 | 475 | void PE_sync_panic_buffers(void); |
5c9f4661 A |
476 | |
477 | typedef struct PE_panic_save_context { | |
478 | void *psc_buffer; | |
479 | uint32_t psc_offset; | |
480 | uint32_t psc_length; | |
481 | } PE_panic_save_context_t; | |
b7266188 | 482 | #endif |
2d21ac55 | 483 | |
1c79356b A |
484 | __END_DECLS |
485 | ||
486 | #endif /* _PEXPERT_PEXPERT_H_ */ |