/*
- * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2012 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
#include <i386/apic.h>
#include <i386/mp_events.h>
-#define MAX_CPUS 32 /* (8*sizeof(long)) */
+#define MAX_CPUS 64 /* 8 * sizeof(cpumask_t) */
#ifndef ASSEMBLER
#include <stdint.h>
#include <mach/kern_return.h>
#include <mach/i386/thread_status.h>
#include <mach/vm_types.h>
-#include <kern/lock.h>
+#include <kern/simple_lock.h>
__BEGIN_DECLS
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:
#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.
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
#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_ */