+
+/*
+ * Per-cpu data.
+ *
+ * Each processor has a per-cpu data area which is dereferenced through the
+ * current_cpu_datap() macro. For speed, the %gs segment is based here, and
+ * using this, inlines provides single-instruction access to frequently used
+ * members - such as get_cpu_number()/cpu_number(), and get_active_thread()/
+ * current_thread().
+ *
+ * Cpu data owned by another processor can be accessed using the
+ * cpu_datap(cpu_number) macro which uses the cpu_data_ptr[] array of per-cpu
+ * pointers.
+ */
+typedef struct cpu_data
+{
+ struct cpu_data *cpu_this; /* pointer to myself */
+ thread_t cpu_active_thread;
+ thread_t cpu_active_kloaded;
+ vm_offset_t cpu_active_stack;
+ vm_offset_t cpu_kernel_stack;
+ vm_offset_t cpu_int_stack_top;
+ int cpu_preemption_level;
+ int cpu_simple_lock_count;
+ int cpu_interrupt_level;
+ int cpu_number; /* Logical CPU */
+ int cpu_phys_number; /* Physical CPU */
+ cpu_id_t cpu_id; /* Platform Expert */
+ int cpu_signals; /* IPI events */
+ int cpu_mcount_off; /* mcount recursion */
+ ast_t cpu_pending_ast;
+ int cpu_type;
+ int cpu_subtype;
+ int cpu_threadtype;
+ int cpu_running;
+ struct cpu_core *cpu_core; /* cpu's parent core */
+ uint64_t cpu_rtc_tick_deadline;
+ uint64_t cpu_rtc_intr_deadline;
+ rtclock_timer_t cpu_rtc_timer;
+ rtc_nanotime_t cpu_rtc_nanotime;
+ void *cpu_console_buf;
+ struct processor *cpu_processor;
+ struct cpu_pmap *cpu_pmap;
+ struct mp_desc_table *cpu_desc_tablep;
+ cpu_desc_index_t cpu_desc_index;
+ boolean_t cpu_iflag;
+#ifdef MACH_KDB
+ /* XXX Untested: */
+ int cpu_db_pass_thru;
+ vm_offset_t cpu_db_stacks;
+ struct i386_saved_state *cpu_kdb_saved_state;
+ spl_t cpu_kdb_saved_ipl;
+ int cpu_kdb_is_slave;
+ int cpu_kdb_active;
+#endif /* MACH_KDB */
+ int cpu_reserved1;
+} cpu_data_t;
+
+extern cpu_data_t *cpu_data_ptr[];
+extern cpu_data_t cpu_data_master;
+
+/* Macro to generate inline bodies to retrieve per-cpu data fields. */
+#define offsetof(TYPE,MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#define CPU_DATA_GET(member,type) \
+ type ret; \
+ __asm__ volatile ("movl %%gs:%P1,%0" \
+ : "=r" (ret) \
+ : "i" (offsetof(cpu_data_t,member))); \
+ return ret;