pexpert.h
1 /* 2 * Copyright (c) 2000-2019 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 #if XNU_KERNEL_PRIVATE 39 #include <libkern/kernel_mach_header.h> 40 #endif 41 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 52 #if defined(PEXPERT_KERNEL_PRIVATE) || defined(IOKIT_KERNEL_PRIVATE) 53 typedef void *cpu_id_t; 54 #else 55 typedef void *cpu_id_t; 56 #endif 57 58 #if XNU_KERNEL_PRIVATE 59 #if defined(__arm__) || defined(__arm64__) 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 72 #else /* defined(__arm__) || defined(__arm64__) */ 73 extern struct macos_panic_header *panic_info; 74 #endif /* defined(__arm__) || defined(__arm64__) */ 75 #endif /* XNU_KERNEL_PRIVATE */ 76 77 extern void lpss_uart_enable(boolean_t on_off); 78 79 void PE_enter_debugger( 80 const char *cause); 81 82 void PE_init_platform( 83 boolean_t vm_initialized, 84 void *args); 85 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 95 uint32_t PE_i_can_has_debugger( 96 uint32_t *); 97 98 int PE_stub_poll_input(unsigned int options, char *c); 99 100 #if defined(__arm__) || defined(__arm64__) 101 boolean_t PE_panic_debugging_enabled(void); 102 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); 117 118 /* Invokes AppleARMIO::handlePlatformError() if present */ 119 bool PE_handle_platform_error( 120 vm_offset_t far); 121 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 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 */ 134 135 extern uint32_t PE_i_can_has_kernel_configuration(void); 136 137 #endif /* KERNEL_PRIVATE */ 138 139 extern int32_t gPESerialBaud; 140 141 extern uint8_t gPlatformECID[8]; 142 143 extern uint32_t gPlatformMemoryID; 144 145 unsigned int PE_init_taproot(vm_offset_t *taddr); 146 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 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 */ 162 void PE_init_iokit( 163 void); 164 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 177 struct clock_frequency_info_t { 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; 203 }; 204 205 extern int debug_cpu_performance_degradation_factor; 206 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 { 212 unsigned long timebase_num; 213 unsigned long timebase_den; 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 222 #ifdef KERNEL 223 void PE_install_interrupt_handler( 224 void *nub, int source, 225 void *target, IOInterruptHandler handler, void *refCon); 226 #endif 227 228 #ifndef _FN_KPRINTF 229 #define _FN_KPRINTF 230 void kprintf(const char *fmt, ...) __printflike(1, 2); 231 #endif 232 233 #if KERNEL_PRIVATE 234 void _consume_kprintf_args(int, ...); 235 #endif 236 237 #if CONFIG_NO_KPRINTF_STRINGS 238 #if KERNEL_PRIVATE 239 #define kprintf(x, ...) _consume_kprintf_args( 0, ## __VA_ARGS__ ) 240 #else 241 #define kprintf(x, ...) do {} while (0) 242 #endif 243 #endif 244 245 void init_display_putc(unsigned char *baseaddr, int rowbytes, int height); 246 void display_putc(char c); 247 248 enum { 249 kPEReadTOD, 250 kPEWriteTOD 251 }; 252 253 enum { 254 kPEWaitForInput = 0x00000001, 255 kPERawInput = 0x00000002 256 }; 257 258 /* Private Stuff - eventually put in pexpertprivate.h */ 259 enum { 260 kDebugTypeNone = 0, 261 kDebugTypeDisplay = 1, 262 kDebugTypeSerial = 2 263 }; 264 265 /* Scale factor values for PE_Video.v_scale */ 266 enum { 267 kPEScaleFactorUnknown = 0, 268 kPEScaleFactor1x = 1, 269 kPEScaleFactor2x = 2 270 }; 271 272 struct PE_Video { 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]; 285 #ifdef __LP64__ 286 long reserved2; 287 #else 288 long v_baseAddrHigh; 289 #endif 290 }; 291 292 typedef struct PE_Video PE_Video; 293 294 extern void initialize_screen(PE_Video *, unsigned int); 295 296 extern void dim_screen(void); 297 298 extern int PE_current_console( 299 PE_Video *info); 300 301 extern void PE_create_console( 302 void); 303 304 extern int PE_initialize_console( 305 PE_Video *newInfo, 306 int op); 307 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 317 318 extern void PE_display_icon( unsigned int flags, 319 const char * name ); 320 321 typedef struct PE_state { 322 boolean_t initialized; 323 PE_Video video; 324 void *deviceTreeHead; 325 void *bootArgs; 326 vm_size_t deviceTreeSize; 327 } PE_state_t; 328 329 extern PE_state_t PE_state; 330 331 extern char * PE_boot_args( 332 void); 333 334 extern boolean_t PE_parse_boot_argn( 335 const char *arg_string, 336 void *arg_ptr, 337 int max_arg); 338 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 346 extern boolean_t PE_get_default( 347 const char *property_name, 348 void *property_ptr, 349 unsigned int max_property); 350 351 #define PE_default_value(_key, _variable, _default) \ 352 do { \ 353 if (!PE_get_default((_key), &(_variable), sizeof(_variable))) \ 354 _variable = _default; \ 355 } while(0) 356 357 enum { 358 kPEOptionKey = 0x3a, 359 kPECommandKey = 0x37, 360 kPEControlKey = 0x36, 361 kPEShiftKey = 0x38 362 }; 363 364 extern boolean_t PE_get_hotkey( 365 unsigned char key); 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 375 extern bool PE_cpu_down( 376 cpu_id_t target); 377 378 extern void PE_cpu_signal( 379 cpu_id_t source, 380 cpu_id_t target); 381 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 390 extern void PE_cpu_machine_init( 391 cpu_id_t target, 392 boolean_t bootb); 393 394 extern void PE_cpu_machine_quiesce( 395 cpu_id_t target); 396 397 extern void pe_init_debug(void); 398 399 extern boolean_t PE_imgsrc_mount_supported(void); 400 401 extern void PE_panic_hook(const char *str); 402 403 extern void PE_init_cpu(void); 404 405 extern void PE_handle_ext_interrupt(void); 406 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 412 #if DEVELOPMENT || DEBUG 413 extern void PE_arm_debug_enable_trace(void); 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); 417 #endif 418 #endif 419 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 464 #if KERNEL_PRIVATE 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; 469 extern uint8_t PE_smc_stashed_x86_shutdown_cause; 470 extern uint64_t PE_smc_stashed_x86_prev_power_transitions; 471 extern uint32_t PE_pcie_stashed_link_state; 472 #endif 473 474 boolean_t PE_reboot_on_panic(void); 475 void PE_sync_panic_buffers(void); 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; 482 #endif 483 484 __END_DECLS 485 486 #endif /* _PEXPERT_PEXPERT_H_ */