diff options
Diffstat (limited to 'include/asm-x86_64/smp.h')
-rw-r--r-- | include/asm-x86_64/smp.h | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h new file mode 100644 index 000000000000..fe523e3e2ff4 --- /dev/null +++ b/include/asm-x86_64/smp.h | |||
@@ -0,0 +1,149 @@ | |||
1 | #ifndef __ASM_SMP_H | ||
2 | #define __ASM_SMP_H | ||
3 | |||
4 | /* | ||
5 | * We need the APIC definitions automatically as part of 'smp.h' | ||
6 | */ | ||
7 | #ifndef __ASSEMBLY__ | ||
8 | #include <linux/config.h> | ||
9 | #include <linux/threads.h> | ||
10 | #include <linux/cpumask.h> | ||
11 | #include <linux/bitops.h> | ||
12 | extern int disable_apic; | ||
13 | #endif | ||
14 | |||
15 | #ifdef CONFIG_X86_LOCAL_APIC | ||
16 | #ifndef __ASSEMBLY__ | ||
17 | #include <asm/fixmap.h> | ||
18 | #include <asm/mpspec.h> | ||
19 | #ifdef CONFIG_X86_IO_APIC | ||
20 | #include <asm/io_apic.h> | ||
21 | #endif | ||
22 | #include <asm/apic.h> | ||
23 | #include <asm/thread_info.h> | ||
24 | #endif | ||
25 | #endif | ||
26 | |||
27 | #ifdef CONFIG_SMP | ||
28 | #ifndef ASSEMBLY | ||
29 | |||
30 | #include <asm/pda.h> | ||
31 | |||
32 | struct pt_regs; | ||
33 | |||
34 | /* | ||
35 | * Private routines/data | ||
36 | */ | ||
37 | |||
38 | extern void smp_alloc_memory(void); | ||
39 | extern cpumask_t cpu_online_map; | ||
40 | extern volatile unsigned long smp_invalidate_needed; | ||
41 | extern int pic_mode; | ||
42 | extern int smp_num_siblings; | ||
43 | extern void smp_flush_tlb(void); | ||
44 | extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); | ||
45 | extern void smp_send_reschedule(int cpu); | ||
46 | extern void smp_invalidate_rcv(void); /* Process an NMI */ | ||
47 | extern void (*mtrr_hook) (void); | ||
48 | extern void zap_low_mappings(void); | ||
49 | void smp_stop_cpu(void); | ||
50 | extern cpumask_t cpu_sibling_map[NR_CPUS]; | ||
51 | extern u8 phys_proc_id[NR_CPUS]; | ||
52 | |||
53 | #define SMP_TRAMPOLINE_BASE 0x6000 | ||
54 | |||
55 | /* | ||
56 | * On x86 all CPUs are mapped 1:1 to the APIC space. | ||
57 | * This simplifies scheduling and IPI sending and | ||
58 | * compresses data structures. | ||
59 | */ | ||
60 | |||
61 | extern cpumask_t cpu_callout_map; | ||
62 | extern cpumask_t cpu_callin_map; | ||
63 | #define cpu_possible_map cpu_callout_map | ||
64 | |||
65 | static inline int num_booting_cpus(void) | ||
66 | { | ||
67 | return cpus_weight(cpu_callout_map); | ||
68 | } | ||
69 | |||
70 | #define __smp_processor_id() read_pda(cpunumber) | ||
71 | |||
72 | extern __inline int hard_smp_processor_id(void) | ||
73 | { | ||
74 | /* we don't want to mark this access volatile - bad code generation */ | ||
75 | return GET_APIC_ID(*(unsigned int *)(APIC_BASE+APIC_ID)); | ||
76 | } | ||
77 | |||
78 | #define safe_smp_processor_id() (disable_apic ? 0 : x86_apicid_to_cpu(hard_smp_processor_id())) | ||
79 | |||
80 | #endif /* !ASSEMBLY */ | ||
81 | |||
82 | #define NO_PROC_ID 0xFF /* No processor magic marker */ | ||
83 | |||
84 | #endif | ||
85 | |||
86 | #ifndef ASSEMBLY | ||
87 | /* | ||
88 | * Some lowlevel functions might want to know about | ||
89 | * the real APIC ID <-> CPU # mapping. | ||
90 | */ | ||
91 | extern u8 x86_cpu_to_apicid[NR_CPUS]; /* physical ID */ | ||
92 | extern u8 x86_cpu_to_log_apicid[NR_CPUS]; | ||
93 | extern u8 bios_cpu_apicid[]; | ||
94 | |||
95 | static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) | ||
96 | { | ||
97 | return cpus_addr(cpumask)[0]; | ||
98 | } | ||
99 | |||
100 | static inline int x86_apicid_to_cpu(u8 apicid) | ||
101 | { | ||
102 | int i; | ||
103 | |||
104 | for (i = 0; i < NR_CPUS; ++i) | ||
105 | if (x86_cpu_to_apicid[i] == apicid) | ||
106 | return i; | ||
107 | |||
108 | /* No entries in x86_cpu_to_apicid? Either no MPS|ACPI, | ||
109 | * or called too early. Either way, we must be CPU 0. */ | ||
110 | if (x86_cpu_to_apicid[0] == BAD_APICID) | ||
111 | return 0; | ||
112 | |||
113 | return -1; | ||
114 | } | ||
115 | |||
116 | static inline int cpu_present_to_apicid(int mps_cpu) | ||
117 | { | ||
118 | if (mps_cpu < NR_CPUS) | ||
119 | return (int)bios_cpu_apicid[mps_cpu]; | ||
120 | else | ||
121 | return BAD_APICID; | ||
122 | } | ||
123 | |||
124 | #endif /* !ASSEMBLY */ | ||
125 | |||
126 | #ifndef CONFIG_SMP | ||
127 | #define stack_smp_processor_id() 0 | ||
128 | #define safe_smp_processor_id() 0 | ||
129 | #define cpu_logical_map(x) (x) | ||
130 | #else | ||
131 | #include <asm/thread_info.h> | ||
132 | #define stack_smp_processor_id() \ | ||
133 | ({ \ | ||
134 | struct thread_info *ti; \ | ||
135 | __asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK)); \ | ||
136 | ti->cpu; \ | ||
137 | }) | ||
138 | #endif | ||
139 | |||
140 | #ifndef __ASSEMBLY__ | ||
141 | static __inline int logical_smp_processor_id(void) | ||
142 | { | ||
143 | /* we don't want to mark this access volatile - bad code generation */ | ||
144 | return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR)); | ||
145 | } | ||
146 | #endif | ||
147 | |||
148 | #endif | ||
149 | |||