4 #include <linux/cpumask.h>
5 #include <linux/init.h>
8 * We need the APIC definitions automatically as part of 'smp.h'
11 #include <asm/io_apic.h>
12 #include <asm/mpspec.h>
14 #include <asm/thread_info.h>
16 extern cpumask_t cpu_initialized;
17 extern cpumask_t cpu_callin_map;
19 extern int smp_call_function_mask(cpumask_t mask, void (*func)(void *),
20 void *info, int wait);
24 #define raw_smp_processor_id() read_pda(cpunumber)
26 #define stack_smp_processor_id() \
28 struct thread_info *ti; \
29 asm("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK)); \
34 * On x86 all CPUs are mapped 1:1 to the APIC space. This simplifies
35 * scheduling and IPI sending and compresses data structures.
37 static inline int num_booting_cpus(void)
39 return cpus_weight(cpu_callout_map);
42 #else /* CONFIG_SMP */
43 #define stack_smp_processor_id() 0
45 #endif /* !CONFIG_SMP */
47 #define safe_smp_processor_id() smp_processor_id()
49 #ifdef CONFIG_X86_LOCAL_APIC
51 static inline int logical_smp_processor_id(void)
53 /* we don't want to mark this access volatile - bad code generation */
54 return GET_APIC_LOGICAL_ID(*(u32 *)(APIC_BASE + APIC_LDR));
57 # ifdef APIC_DEFINITION
58 extern int hard_smp_processor_id(void);
60 # include <mach_apicdef.h>
61 static inline int hard_smp_processor_id(void)
63 /* we don't want to mark this access volatile - bad code generation */
64 return GET_APIC_ID(*(u32 *)(APIC_BASE + APIC_ID));
66 # endif /* APIC_DEFINITION */
68 #else /* CONFIG_X86_LOCAL_APIC */
71 # define hard_smp_processor_id() 0
74 #endif /* CONFIG_X86_LOCAL_APIC */