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 | #ifndef _PEXPERT_PEXPERT_H_ |
29 | #define _PEXPERT_PEXPERT_H_ |
30 | |
31 | #include <sys/cdefs.h> |
32 | |
33 | #ifdef KERNEL |
34 | #include <IOKit/IOInterrupts.h> |
35 | #include <kern/kern_types.h> |
36 | #endif |
37 | |
38 | __BEGIN_DECLS |
39 | #include <mach/boolean.h> |
40 | #include <mach/kern_return.h> |
41 | #include <mach/machine/vm_types.h> |
42 | |
43 | #ifdef PEXPERT_KERNEL_PRIVATE |
44 | #include <pexpert/protos.h> |
45 | #endif |
46 | #include <pexpert/boot.h> |
47 | |
48 | #if defined(PEXPERT_KERNEL_PRIVATE) || defined(IOKIT_KERNEL_PRIVATE) |
49 | typedef void *cpu_id_t; |
50 | #else |
51 | typedef void *cpu_id_t; |
52 | #endif |
53 | |
54 | #if XNU_KERNEL_PRIVATE |
55 | #if CONFIG_EMBEDDED |
56 | extern struct embedded_panic_header *panic_info; |
57 | extern vm_offset_t gPanicBase; |
58 | extern unsigned int gPanicSize; |
59 | |
60 | /* |
61 | * If invoked with NULL first argument, return the max buffer size that can |
62 | * be saved in the second argument |
63 | */ |
64 | void PE_save_buffer_to_vram( |
65 | unsigned char *, |
66 | unsigned int *); |
67 | |
68 | #else /* CONFIG_EMBEDDED */ |
69 | extern struct macos_panic_header *panic_info; |
70 | #endif /* CONFIG_EMBEDDED */ |
71 | #endif /* XNU_KERNEL_PRIVATE */ |
72 | |
73 | extern void lpss_uart_enable (boolean_t on_off); |
74 | |
75 | void PE_enter_debugger( |
76 | const char *cause); |
77 | |
78 | void PE_init_platform( |
79 | boolean_t vm_initialized, |
80 | void *args); |
81 | |
82 | /* |
83 | * Copies the requested number of bytes from the "random-seed" property in |
84 | * the device tree, and zeros the corresponding bytes in the device tree. |
85 | * Returns the number of bytes actually copied. |
86 | */ |
87 | uint32_t PE_get_random_seed( |
88 | unsigned char * dst_random_seed, |
89 | uint32_t request_size); |
90 | |
91 | uint32_t PE_i_can_has_debugger( |
92 | uint32_t *); |
93 | |
94 | #if defined(__arm__) || defined(__arm64__) |
95 | boolean_t PE_panic_debugging_enabled(void); |
96 | |
97 | void PE_mark_hwaccess(uint64_t thread); |
98 | #endif /* defined(__arm__) || defined(__arm64__) */ |
99 | |
100 | /* Return the offset of the specified address into the panic region */ |
101 | uint32_t PE_get_offset_into_panic_region( |
102 | char *location); |
103 | |
104 | /* Zeroes the panic header, sets the panic magic and initializes the header to be used */ |
105 | void ( |
106 | void); |
107 | |
108 | /* Updates the panic header during a nested panic */ |
109 | void ( |
110 | void); |
111 | |
112 | #if KERNEL_PRIVATE |
113 | |
114 | /* |
115 | * Kexts should consult this bitmask to change behavior, since the kernel |
116 | * may be configured as RELEASE but have MACH_ASSERT enabled, or boot args |
117 | * may have changed the kernel behavior for statistics and kexts should |
118 | * participate similarly |
119 | */ |
120 | |
121 | #define kPEICanHasAssertions 0x00000001 /* Exceptional conditions should panic() instead of printf() */ |
122 | #define kPEICanHasStatistics 0x00000002 /* Gather expensive statistics (that don't otherwise change behavior */ |
123 | #define kPEICanHasDiagnosticAPI 0x00000004 /* Vend API to userspace or kexts that introspect kernel state */ |
124 | |
125 | extern uint32_t PE_i_can_has_kernel_configuration(void); |
126 | |
127 | #endif /* KERNEL_PRIVATE */ |
128 | |
129 | void PE_init_kprintf( |
130 | boolean_t vm_initialized); |
131 | |
132 | extern int32_t gPESerialBaud; |
133 | |
134 | extern uint8_t gPlatformECID[8]; |
135 | |
136 | extern uint32_t gPlatformMemoryID; |
137 | |
138 | unsigned int PE_init_taproot(vm_offset_t *taddr); |
139 | |
140 | extern void (*PE_kputc)(char c); |
141 | |
142 | void PE_init_printf( |
143 | boolean_t vm_initialized); |
144 | |
145 | extern void (*PE_putc)(char c); |
146 | |
147 | void PE_init_iokit( |
148 | void); |
149 | |
150 | struct clock_frequency_info_t { |
151 | unsigned long bus_clock_rate_hz; |
152 | unsigned long cpu_clock_rate_hz; |
153 | unsigned long dec_clock_rate_hz; |
154 | unsigned long bus_clock_rate_num; |
155 | unsigned long bus_clock_rate_den; |
156 | unsigned long bus_to_cpu_rate_num; |
157 | unsigned long bus_to_cpu_rate_den; |
158 | unsigned long bus_to_dec_rate_num; |
159 | unsigned long bus_to_dec_rate_den; |
160 | unsigned long timebase_frequency_hz; |
161 | unsigned long timebase_frequency_num; |
162 | unsigned long timebase_frequency_den; |
163 | unsigned long long bus_frequency_hz; |
164 | unsigned long long bus_frequency_min_hz; |
165 | unsigned long long bus_frequency_max_hz; |
166 | unsigned long long cpu_frequency_hz; |
167 | unsigned long long cpu_frequency_min_hz; |
168 | unsigned long long cpu_frequency_max_hz; |
169 | unsigned long long prf_frequency_hz; |
170 | unsigned long long prf_frequency_min_hz; |
171 | unsigned long long prf_frequency_max_hz; |
172 | unsigned long long mem_frequency_hz; |
173 | unsigned long long mem_frequency_min_hz; |
174 | unsigned long long mem_frequency_max_hz; |
175 | unsigned long long fix_frequency_hz; |
176 | }; |
177 | |
178 | extern int debug_cpu_performance_degradation_factor; |
179 | |
180 | typedef struct clock_frequency_info_t clock_frequency_info_t; |
181 | |
182 | extern clock_frequency_info_t gPEClockFrequencyInfo; |
183 | |
184 | struct timebase_freq_t { |
185 | unsigned long timebase_num; |
186 | unsigned long timebase_den; |
187 | }; |
188 | |
189 | typedef void (*timebase_callback_func)(struct timebase_freq_t *timebase_freq); |
190 | |
191 | void PE_register_timebase_callback(timebase_callback_func callback); |
192 | |
193 | void PE_call_timebase_callback(void); |
194 | |
195 | #ifdef KERNEL |
196 | void PE_install_interrupt_handler( |
197 | void *nub, int source, |
198 | void *target, IOInterruptHandler handler, void *refCon); |
199 | #endif |
200 | |
201 | #ifndef _FN_KPRINTF |
202 | #define _FN_KPRINTF |
203 | void kprintf(const char *fmt, ...) __printflike(1,2); |
204 | #endif |
205 | |
206 | #if KERNEL_PRIVATE |
207 | void _consume_kprintf_args(int, ...); |
208 | #endif |
209 | |
210 | #if CONFIG_NO_KPRINTF_STRINGS |
211 | #if KERNEL_PRIVATE |
212 | #define kprintf(x, ...) _consume_kprintf_args( 0, ## __VA_ARGS__ ) |
213 | #else |
214 | #define kprintf(x, ...) do {} while (0) |
215 | #endif |
216 | #endif |
217 | |
218 | void init_display_putc(unsigned char *baseaddr, int rowbytes, int height); |
219 | void display_putc(char c); |
220 | |
221 | enum { |
222 | kPEReadTOD, |
223 | kPEWriteTOD |
224 | }; |
225 | extern int (*PE_read_write_time_of_day)( |
226 | unsigned int options, |
227 | long * secs); |
228 | |
229 | enum { |
230 | kPEWaitForInput = 0x00000001, |
231 | kPERawInput = 0x00000002 |
232 | }; |
233 | extern int (*PE_poll_input)( |
234 | unsigned int options, |
235 | char * c); |
236 | |
237 | extern int (*PE_write_IIC)( |
238 | unsigned char addr, |
239 | unsigned char reg, |
240 | unsigned char data); |
241 | |
242 | /* Private Stuff - eventually put in pexpertprivate.h */ |
243 | enum { |
244 | kDebugTypeNone = 0, |
245 | kDebugTypeDisplay = 1, |
246 | kDebugTypeSerial = 2 |
247 | }; |
248 | |
249 | /* Scale factor values for PE_Video.v_scale */ |
250 | enum { |
251 | kPEScaleFactorUnknown = 0, |
252 | kPEScaleFactor1x = 1, |
253 | kPEScaleFactor2x = 2 |
254 | }; |
255 | |
256 | struct PE_Video { |
257 | unsigned long v_baseAddr; /* Base address of video memory */ |
258 | unsigned long v_rowBytes; /* Number of bytes per pixel row */ |
259 | unsigned long v_width; /* Width */ |
260 | unsigned long v_height; /* Height */ |
261 | unsigned long v_depth; /* Pixel Depth */ |
262 | unsigned long v_display; /* Text or Graphics */ |
263 | char v_pixelFormat[64]; |
264 | unsigned long v_offset; /* offset into video memory to start at */ |
265 | unsigned long v_length; /* length of video memory (0 for v_rowBytes * v_height) */ |
266 | unsigned char v_rotate; /* Rotation: 0:normal, 1:right 90, 2:left 180, 3:left 90 */ |
267 | unsigned char v_scale; /* Scale Factor for both X & Y */ |
268 | char reserved1[2]; |
269 | #ifdef __LP64__ |
270 | long reserved2; |
271 | #else |
272 | long v_baseAddrHigh; |
273 | #endif |
274 | }; |
275 | |
276 | typedef struct PE_Video PE_Video; |
277 | |
278 | extern void initialize_screen(PE_Video *, unsigned int); |
279 | |
280 | extern void dim_screen(void); |
281 | |
282 | extern int PE_current_console( |
283 | PE_Video *info); |
284 | |
285 | extern void PE_create_console( |
286 | void); |
287 | |
288 | extern int PE_initialize_console( |
289 | PE_Video *newInfo, |
290 | int op); |
291 | |
292 | #define kPEGraphicsMode 1 |
293 | #define kPETextMode 2 |
294 | #define kPETextScreen 3 |
295 | #define kPEAcquireScreen 4 |
296 | #define kPEReleaseScreen 5 |
297 | #define kPEEnableScreen 6 |
298 | #define kPEDisableScreen 7 |
299 | #define kPEBaseAddressChange 8 |
300 | #define kPERefreshBootGraphics 9 |
301 | |
302 | extern void PE_display_icon( unsigned int flags, |
303 | const char * name ); |
304 | |
305 | typedef struct PE_state { |
306 | boolean_t initialized; |
307 | PE_Video video; |
308 | void *deviceTreeHead; |
309 | void *bootArgs; |
310 | } PE_state_t; |
311 | |
312 | extern PE_state_t PE_state; |
313 | |
314 | extern char * PE_boot_args( |
315 | void); |
316 | |
317 | #if !defined(__LP64__) && !defined(__arm__) |
318 | extern boolean_t PE_parse_boot_arg( |
319 | const char *arg_string, |
320 | void *arg_ptr) __deprecated; |
321 | #endif |
322 | |
323 | extern boolean_t PE_parse_boot_argn( |
324 | const char *arg_string, |
325 | void *arg_ptr, |
326 | int max_arg); |
327 | |
328 | #if XNU_KERNEL_PRIVATE |
329 | extern boolean_t PE_parse_boot_arg_str( |
330 | const char *arg_string, |
331 | char * arg_ptr, |
332 | int size); |
333 | #endif /* XNU_KERNEL_PRIVATE */ |
334 | |
335 | extern boolean_t PE_get_default( |
336 | const char *property_name, |
337 | void *property_ptr, |
338 | unsigned int max_property); |
339 | |
340 | #define PE_default_value(_key, _variable, _default) \ |
341 | do { \ |
342 | if (!PE_get_default((_key), &(_variable), sizeof(_variable))) \ |
343 | _variable = _default; \ |
344 | } while(0) |
345 | |
346 | enum { |
347 | kPEOptionKey = 0x3a, |
348 | kPECommandKey = 0x37, |
349 | kPEControlKey = 0x36, |
350 | kPEShiftKey = 0x38 |
351 | }; |
352 | |
353 | extern boolean_t PE_get_hotkey( |
354 | unsigned char key); |
355 | |
356 | extern kern_return_t PE_cpu_start( |
357 | cpu_id_t target, |
358 | vm_offset_t start_paddr, |
359 | vm_offset_t arg_paddr); |
360 | |
361 | extern void PE_cpu_halt( |
362 | cpu_id_t target); |
363 | |
364 | extern void PE_cpu_signal( |
365 | cpu_id_t source, |
366 | cpu_id_t target); |
367 | |
368 | extern void PE_cpu_signal_deferred( |
369 | cpu_id_t source, |
370 | cpu_id_t target); |
371 | |
372 | extern void PE_cpu_signal_cancel( |
373 | cpu_id_t source, |
374 | cpu_id_t target); |
375 | |
376 | extern void PE_cpu_machine_init( |
377 | cpu_id_t target, |
378 | boolean_t bootb); |
379 | |
380 | extern void PE_cpu_machine_quiesce( |
381 | cpu_id_t target); |
382 | |
383 | extern void pe_init_debug(void); |
384 | |
385 | extern boolean_t PE_imgsrc_mount_supported(void); |
386 | |
387 | #if defined(__arm__) || defined(__arm64__) |
388 | typedef void (*perfmon_interrupt_handler_func)(cpu_id_t source); |
389 | extern kern_return_t PE_cpu_perfmon_interrupt_install_handler(perfmon_interrupt_handler_func handler); |
390 | extern void PE_cpu_perfmon_interrupt_enable(cpu_id_t target, boolean_t enable); |
391 | |
392 | extern void (*PE_arm_debug_panic_hook)(const char *str); |
393 | #if DEVELOPMENT || DEBUG |
394 | extern void PE_arm_debug_enable_trace(void); |
395 | #endif |
396 | #endif |
397 | |
398 | #if KERNEL_PRIVATE |
399 | #if defined(__arm64__) |
400 | extern uint8_t PE_smc_stashed_x86_power_state; |
401 | extern uint8_t PE_smc_stashed_x86_efi_boot_state; |
402 | extern uint8_t PE_smc_stashed_x86_system_state; |
403 | extern uint8_t PE_smc_stashed_x86_shutdown_cause; |
404 | extern uint64_t PE_smc_stashed_x86_prev_power_transitions; |
405 | extern uint32_t PE_pcie_stashed_link_state; |
406 | #endif |
407 | |
408 | boolean_t PE_reboot_on_panic(void); |
409 | void PE_sync_panic_buffers(void); |
410 | |
411 | typedef struct PE_panic_save_context { |
412 | void *psc_buffer; |
413 | uint32_t psc_offset; |
414 | uint32_t psc_length; |
415 | } PE_panic_save_context_t; |
416 | #endif |
417 | |
418 | __END_DECLS |
419 | |
420 | #endif /* _PEXPERT_PEXPERT_H_ */ |
421 | |