X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/6d2010ae8f7a6078e10b361c6962983bab233e0f..a39ff7e25e19b3a8c3020042a3872ca9ec9659f1:/osfmk/i386/mp.h diff --git a/osfmk/i386/mp.h b/osfmk/i386/mp.h index 6974ef256..6f46c5d4a 100644 --- a/osfmk/i386/mp.h +++ b/osfmk/i386/mp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2008 Apple Inc. All rights reserved. + * Copyright (c) 2000-2012 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -66,7 +66,7 @@ #include #include -#define MAX_CPUS 32 /* (8*sizeof(long)) */ +#define MAX_CPUS 64 /* 8 * sizeof(cpumask_t) */ #ifndef ASSEMBLER #include @@ -75,7 +75,7 @@ #include #include #include -#include +#include __BEGIN_DECLS @@ -103,20 +103,20 @@ extern int kdb_debug; extern int kdb_active[]; extern volatile boolean_t mp_kdp_trap; +extern volatile boolean_t mp_kdp_is_NMI; extern volatile boolean_t force_immediate_debugger_NMI; extern volatile boolean_t pmap_tlb_flush_timeout; extern volatile usimple_lock_t spinlock_timed_out; extern volatile uint32_t spinlock_owner_cpu; +extern uint32_t spinlock_timeout_NMI(uintptr_t thread_addr); extern uint64_t LastDebuggerEntryAllowance; -extern void mp_kdp_enter(void); +extern void mp_kdp_enter(boolean_t proceed_on_failure); extern void mp_kdp_exit(void); extern boolean_t mp_recent_debugger_activity(void); -#if MACH_KDB -extern void mp_kdb_exit(void); -#endif +extern void kernel_spin(uint64_t spin_ns); /* * All cpu rendezvous: @@ -149,16 +149,19 @@ typedef enum {KDP_XCPU_NONE = 0xffff, KDP_CURRENT_LCPU = 0xfffe} kdp_cpu_t; #endif typedef uint32_t cpu_t; -typedef uint32_t cpumask_t; +typedef volatile uint64_t cpumask_t; static inline cpumask_t cpu_to_cpumask(cpu_t cpu) { - return (cpu < 32) ? (1 << cpu) : 0; + return (cpu < MAX_CPUS) ? (1ULL << cpu) : 0; } -#define CPUMASK_ALL 0xffffffff +#define CPUMASK_ALL 0xffffffffffffffffULL #define CPUMASK_SELF cpu_to_cpumask(cpu_number()) #define CPUMASK_OTHERS (CPUMASK_ALL & ~CPUMASK_SELF) +/* Initialation routing called at processor registration */ +extern void mp_cpus_call_cpu_init(int cpu); + /* * Invoke a function (possibly NULL) on a set of cpus specified by a mask. * The mask may include the local cpu. @@ -182,9 +185,19 @@ extern cpu_t mp_cpus_call1( void (*action_func)(void *, void*), void *arg0, void *arg1, - cpumask_t *cpus_calledp, - cpumask_t *cpus_notcalledp); - + cpumask_t *cpus_calledp); + +typedef enum { + NONE = 0, + SPINLOCK_TIMEOUT, + TLB_FLUSH_TIMEOUT, + CROSSCALL_TIMEOUT, + INTERRUPT_WATCHDOG +} NMI_reason_t; +extern void NMIPI_panic(cpumask_t cpus, NMI_reason_t reason); + +/* Interrupt a set of cpus, forcing an exit out of non-root mode */ +extern void mp_cpus_kick(cpumask_t cpus); /* * Power-management-specific SPI to: * - register a callout function, and @@ -266,113 +279,6 @@ i_bit_impl(long word, long bit) { #define i_bit(bit, word) i_bit_impl((long)(*(word)), bit) #endif -#if MACH_RT - -#if defined(__i386__) - -#define _DISABLE_PREEMPTION \ - incl %gs:CPU_PREEMPTION_LEVEL - -#define _ENABLE_PREEMPTION \ - decl %gs:CPU_PREEMPTION_LEVEL ; \ - jne 9f ; \ - pushl %eax ; \ - pushl %ecx ; \ - pushl %edx ; \ - call EXT(kernel_preempt_check) ; \ - popl %edx ; \ - popl %ecx ; \ - popl %eax ; \ -9: - -#define _ENABLE_PREEMPTION_NO_CHECK \ - decl %gs:CPU_PREEMPTION_LEVEL - -#elif defined(__x86_64__) - -#define _DISABLE_PREEMPTION \ - incl %gs:CPU_PREEMPTION_LEVEL - -#define _ENABLE_PREEMPTION \ - decl %gs:CPU_PREEMPTION_LEVEL ; \ - jne 9f ; \ - call EXT(kernel_preempt_check) ; \ -9: - -#define _ENABLE_PREEMPTION_NO_CHECK \ - decl %gs:CPU_PREEMPTION_LEVEL - -#else -#error Unsupported architecture -#endif - -/* x86_64 just calls through to the other macro directly */ -#if MACH_ASSERT && defined(__i386__) -#define DISABLE_PREEMPTION \ - pushl %eax; \ - pushl %ecx; \ - pushl %edx; \ - call EXT(_disable_preemption); \ - popl %edx; \ - popl %ecx; \ - popl %eax -#define ENABLE_PREEMPTION \ - pushl %eax; \ - pushl %ecx; \ - pushl %edx; \ - call EXT(_enable_preemption); \ - popl %edx; \ - popl %ecx; \ - popl %eax -#define ENABLE_PREEMPTION_NO_CHECK \ - pushl %eax; \ - pushl %ecx; \ - pushl %edx; \ - call EXT(_enable_preemption_no_check); \ - popl %edx; \ - popl %ecx; \ - popl %eax -#define MP_DISABLE_PREEMPTION \ - pushl %eax; \ - pushl %ecx; \ - pushl %edx; \ - call EXT(_mp_disable_preemption); \ - popl %edx; \ - popl %ecx; \ - popl %eax -#define MP_ENABLE_PREEMPTION \ - pushl %eax; \ - pushl %ecx; \ - pushl %edx; \ - call EXT(_mp_enable_preemption); \ - popl %edx; \ - popl %ecx; \ - popl %eax -#define MP_ENABLE_PREEMPTION_NO_CHECK \ - pushl %eax; \ - pushl %ecx; \ - pushl %edx; \ - call EXT(_mp_enable_preemption_no_check); \ - popl %edx; \ - popl %ecx; \ - popl %eax -#else /* MACH_ASSERT */ -#define DISABLE_PREEMPTION _DISABLE_PREEMPTION -#define ENABLE_PREEMPTION _ENABLE_PREEMPTION -#define ENABLE_PREEMPTION_NO_CHECK _ENABLE_PREEMPTION_NO_CHECK -#define MP_DISABLE_PREEMPTION _DISABLE_PREEMPTION -#define MP_ENABLE_PREEMPTION _ENABLE_PREEMPTION -#define MP_ENABLE_PREEMPTION_NO_CHECK _ENABLE_PREEMPTION_NO_CHECK -#endif /* MACH_ASSERT */ - -#else /* MACH_RT */ -#define DISABLE_PREEMPTION -#define ENABLE_PREEMPTION -#define ENABLE_PREEMPTION_NO_CHECK -#define MP_DISABLE_PREEMPTION -#define MP_ENABLE_PREEMPTION -#define MP_ENABLE_PREEMPTION_NO_CHECK -#endif /* MACH_RT */ #endif /* _I386_MP_H_ */