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)
49typedef void *cpu_id_t;
50#else
51typedef void *cpu_id_t;
52#endif
53
54#if XNU_KERNEL_PRIVATE
55#if CONFIG_EMBEDDED
56extern struct embedded_panic_header *panic_info;
57extern vm_offset_t gPanicBase;
58extern 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 */
64void PE_save_buffer_to_vram(
65 unsigned char *,
66 unsigned int *);
67
68#else /* CONFIG_EMBEDDED */
69extern struct macos_panic_header *panic_info;
70#endif /* CONFIG_EMBEDDED */
71#endif /* XNU_KERNEL_PRIVATE */
72
73extern void lpss_uart_enable (boolean_t on_off);
74
75void PE_enter_debugger(
76 const char *cause);
77
78void 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 */
87uint32_t PE_get_random_seed(
88 unsigned char * dst_random_seed,
89 uint32_t request_size);
90
91uint32_t PE_i_can_has_debugger(
92 uint32_t *);
93
94#if defined(__arm__) || defined(__arm64__)
95boolean_t PE_panic_debugging_enabled(void);
96
97void 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 */
101uint32_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 */
105void PE_init_panicheader(
106 void);
107
108/* Updates the panic header during a nested panic */
109void PE_update_panicheader_nestedpanic(
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
125extern uint32_t PE_i_can_has_kernel_configuration(void);
126
127#endif /* KERNEL_PRIVATE */
128
129void PE_init_kprintf(
130 boolean_t vm_initialized);
131
132extern int32_t gPESerialBaud;
133
134extern uint8_t gPlatformECID[8];
135
136extern uint32_t gPlatformMemoryID;
137
138unsigned int PE_init_taproot(vm_offset_t *taddr);
139
140extern void (*PE_kputc)(char c);
141
142void PE_init_printf(
143 boolean_t vm_initialized);
144
145extern void (*PE_putc)(char c);
146
147void PE_init_iokit(
148 void);
149
150struct 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
178extern int debug_cpu_performance_degradation_factor;
179
180typedef struct clock_frequency_info_t clock_frequency_info_t;
181
182extern clock_frequency_info_t gPEClockFrequencyInfo;
183
184struct timebase_freq_t {
185 unsigned long timebase_num;
186 unsigned long timebase_den;
187};
188
189typedef void (*timebase_callback_func)(struct timebase_freq_t *timebase_freq);
190
191void PE_register_timebase_callback(timebase_callback_func callback);
192
193void PE_call_timebase_callback(void);
194
195#ifdef KERNEL
196void 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
203void kprintf(const char *fmt, ...) __printflike(1,2);
204#endif
205
206#if KERNEL_PRIVATE
207void _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
218void init_display_putc(unsigned char *baseaddr, int rowbytes, int height);
219void display_putc(char c);
220
221enum {
222 kPEReadTOD,
223 kPEWriteTOD
224};
225extern int (*PE_read_write_time_of_day)(
226 unsigned int options,
227 long * secs);
228
229enum {
230 kPEWaitForInput = 0x00000001,
231 kPERawInput = 0x00000002
232};
233extern int (*PE_poll_input)(
234 unsigned int options,
235 char * c);
236
237extern 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 */
243enum {
244 kDebugTypeNone = 0,
245 kDebugTypeDisplay = 1,
246 kDebugTypeSerial = 2
247};
248
249/* Scale factor values for PE_Video.v_scale */
250enum {
251 kPEScaleFactorUnknown = 0,
252 kPEScaleFactor1x = 1,
253 kPEScaleFactor2x = 2
254};
255
256struct 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
276typedef struct PE_Video PE_Video;
277
278extern void initialize_screen(PE_Video *, unsigned int);
279
280extern void dim_screen(void);
281
282extern int PE_current_console(
283 PE_Video *info);
284
285extern void PE_create_console(
286 void);
287
288extern 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
302extern void PE_display_icon( unsigned int flags,
303 const char * name );
304
305typedef struct PE_state {
306 boolean_t initialized;
307 PE_Video video;
308 void *deviceTreeHead;
309 void *bootArgs;
310} PE_state_t;
311
312extern PE_state_t PE_state;
313
314extern char * PE_boot_args(
315 void);
316
317#if !defined(__LP64__) && !defined(__arm__)
318extern boolean_t PE_parse_boot_arg(
319 const char *arg_string,
320 void *arg_ptr) __deprecated;
321#endif
322
323extern 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
329extern 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
335extern 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
346enum {
347 kPEOptionKey = 0x3a,
348 kPECommandKey = 0x37,
349 kPEControlKey = 0x36,
350 kPEShiftKey = 0x38
351};
352
353extern boolean_t PE_get_hotkey(
354 unsigned char key);
355
356extern kern_return_t PE_cpu_start(
357 cpu_id_t target,
358 vm_offset_t start_paddr,
359 vm_offset_t arg_paddr);
360
361extern void PE_cpu_halt(
362 cpu_id_t target);
363
364extern void PE_cpu_signal(
365 cpu_id_t source,
366 cpu_id_t target);
367
368extern void PE_cpu_signal_deferred(
369 cpu_id_t source,
370 cpu_id_t target);
371
372extern void PE_cpu_signal_cancel(
373 cpu_id_t source,
374 cpu_id_t target);
375
376extern void PE_cpu_machine_init(
377 cpu_id_t target,
378 boolean_t bootb);
379
380extern void PE_cpu_machine_quiesce(
381 cpu_id_t target);
382
383extern void pe_init_debug(void);
384
385extern boolean_t PE_imgsrc_mount_supported(void);
386
387#if defined(__arm__) || defined(__arm64__)
388typedef void (*perfmon_interrupt_handler_func)(cpu_id_t source);
389extern kern_return_t PE_cpu_perfmon_interrupt_install_handler(perfmon_interrupt_handler_func handler);
390extern void PE_cpu_perfmon_interrupt_enable(cpu_id_t target, boolean_t enable);
391
392extern void (*PE_arm_debug_panic_hook)(const char *str);
393#if DEVELOPMENT || DEBUG
394extern void PE_arm_debug_enable_trace(void);
395#endif
396#endif
397
398#if KERNEL_PRIVATE
399#if defined(__arm64__)
400extern uint8_t PE_smc_stashed_x86_power_state;
401extern uint8_t PE_smc_stashed_x86_efi_boot_state;
402extern uint8_t PE_smc_stashed_x86_system_state;
403extern uint8_t PE_smc_stashed_x86_shutdown_cause;
404extern uint64_t PE_smc_stashed_x86_prev_power_transitions;
405extern uint32_t PE_pcie_stashed_link_state;
406#endif
407
408boolean_t PE_reboot_on_panic(void);
409void PE_sync_panic_buffers(void);
410
411typedef 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