]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* smp.h: Sparc specific SMP stuff. |
2 | * | |
3 | * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) | |
4 | */ | |
5 | ||
6 | #ifndef _SPARC_SMP_H | |
7 | #define _SPARC_SMP_H | |
8 | ||
9 | #include <linux/config.h> | |
10 | #include <linux/threads.h> | |
11 | #include <asm/head.h> | |
12 | #include <asm/btfixup.h> | |
13 | ||
14 | #ifndef __ASSEMBLY__ | |
15 | ||
16 | #include <linux/cpumask.h> | |
17 | ||
18 | #endif /* __ASSEMBLY__ */ | |
19 | ||
20 | #ifdef CONFIG_SMP | |
21 | ||
22 | #ifndef __ASSEMBLY__ | |
23 | ||
24 | #include <asm/ptrace.h> | |
25 | #include <asm/asi.h> | |
26 | #include <asm/atomic.h> | |
27 | ||
28 | /* | |
29 | * Private routines/data | |
30 | */ | |
31 | ||
32 | extern unsigned char boot_cpu_id; | |
33 | extern cpumask_t phys_cpu_present_map; | |
34 | #define cpu_possible_map phys_cpu_present_map | |
35 | ||
36 | typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long, | |
37 | unsigned long, unsigned long); | |
38 | ||
39 | /* | |
40 | * General functions that each host system must provide. | |
41 | */ | |
42 | ||
43 | void sun4m_init_smp(void); | |
44 | void sun4d_init_smp(void); | |
45 | ||
46 | void smp_callin(void); | |
47 | void smp_boot_cpus(void); | |
48 | void smp_store_cpu_info(int); | |
49 | ||
50 | struct seq_file; | |
51 | void smp_bogo(struct seq_file *); | |
52 | void smp_info(struct seq_file *); | |
53 | ||
54 | BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) | |
55 | BTFIXUPDEF_CALL(void, smp_message_pass, int, int, unsigned long, int) | |
56 | BTFIXUPDEF_CALL(int, __hard_smp_processor_id, void) | |
57 | BTFIXUPDEF_BLACKBOX(hard_smp_processor_id) | |
58 | BTFIXUPDEF_BLACKBOX(load_current) | |
59 | ||
60 | #define smp_cross_call(func,arg1,arg2,arg3,arg4,arg5) BTFIXUP_CALL(smp_cross_call)(func,arg1,arg2,arg3,arg4,arg5) | |
61 | #define smp_message_pass(target,msg,data,wait) BTFIXUP_CALL(smp_message_pass)(target,msg,data,wait) | |
62 | ||
63 | extern __inline__ void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); } | |
64 | extern __inline__ void xc1(smpfunc_t func, unsigned long arg1) | |
65 | { smp_cross_call(func, arg1, 0, 0, 0, 0); } | |
66 | extern __inline__ void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2) | |
67 | { smp_cross_call(func, arg1, arg2, 0, 0, 0); } | |
68 | extern __inline__ void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2, | |
69 | unsigned long arg3) | |
70 | { smp_cross_call(func, arg1, arg2, arg3, 0, 0); } | |
71 | extern __inline__ void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2, | |
72 | unsigned long arg3, unsigned long arg4) | |
73 | { smp_cross_call(func, arg1, arg2, arg3, arg4, 0); } | |
74 | extern __inline__ void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg2, | |
75 | unsigned long arg3, unsigned long arg4, unsigned long arg5) | |
76 | { smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); } | |
77 | ||
78 | extern __inline__ int smp_call_function(void (*func)(void *info), void *info, int nonatomic, int wait) | |
79 | { | |
80 | xc1((smpfunc_t)func, (unsigned long)info); | |
81 | return 0; | |
82 | } | |
83 | ||
84 | extern __volatile__ int __cpu_number_map[NR_CPUS]; | |
85 | extern __volatile__ int __cpu_logical_map[NR_CPUS]; | |
86 | ||
87 | extern __inline__ int cpu_logical_map(int cpu) | |
88 | { | |
89 | return __cpu_logical_map[cpu]; | |
90 | } | |
91 | extern __inline__ int cpu_number_map(int cpu) | |
92 | { | |
93 | return __cpu_number_map[cpu]; | |
94 | } | |
95 | ||
96 | extern __inline__ int hard_smp4m_processor_id(void) | |
97 | { | |
98 | int cpuid; | |
99 | ||
100 | __asm__ __volatile__("rd %%tbr, %0\n\t" | |
101 | "srl %0, 12, %0\n\t" | |
102 | "and %0, 3, %0\n\t" : | |
103 | "=&r" (cpuid)); | |
104 | return cpuid; | |
105 | } | |
106 | ||
107 | extern __inline__ int hard_smp4d_processor_id(void) | |
108 | { | |
109 | int cpuid; | |
110 | ||
111 | __asm__ __volatile__("lda [%%g0] %1, %0\n\t" : | |
112 | "=&r" (cpuid) : "i" (ASI_M_VIKING_TMP1)); | |
113 | return cpuid; | |
114 | } | |
115 | ||
116 | #ifndef MODULE | |
117 | extern __inline__ int hard_smp_processor_id(void) | |
118 | { | |
119 | int cpuid; | |
120 | ||
121 | /* Black box - sun4m | |
122 | __asm__ __volatile__("rd %%tbr, %0\n\t" | |
123 | "srl %0, 12, %0\n\t" | |
124 | "and %0, 3, %0\n\t" : | |
125 | "=&r" (cpuid)); | |
126 | - sun4d | |
127 | __asm__ __volatile__("lda [%g0] ASI_M_VIKING_TMP1, %0\n\t" | |
128 | "nop; nop" : | |
129 | "=&r" (cpuid)); | |
130 | See btfixup.h and btfixupprep.c to understand how a blackbox works. | |
131 | */ | |
132 | __asm__ __volatile__("sethi %%hi(___b_hard_smp_processor_id), %0\n\t" | |
133 | "sethi %%hi(boot_cpu_id), %0\n\t" | |
134 | "ldub [%0 + %%lo(boot_cpu_id)], %0\n\t" : | |
135 | "=&r" (cpuid)); | |
136 | return cpuid; | |
137 | } | |
138 | #else | |
139 | extern __inline__ int hard_smp_processor_id(void) | |
140 | { | |
141 | int cpuid; | |
142 | ||
143 | __asm__ __volatile__("mov %%o7, %%g1\n\t" | |
144 | "call ___f___hard_smp_processor_id\n\t" | |
145 | " nop\n\t" | |
146 | "mov %%g2, %0\n\t" : "=r"(cpuid) : : "g1", "g2"); | |
147 | return cpuid; | |
148 | } | |
149 | #endif | |
150 | ||
39c715b7 | 151 | #define raw_smp_processor_id() (current_thread_info()->cpu) |
1da177e4 LT |
152 | |
153 | #define prof_multiplier(__cpu) cpu_data(__cpu).multiplier | |
154 | #define prof_counter(__cpu) cpu_data(__cpu).counter | |
155 | ||
156 | #endif /* !(__ASSEMBLY__) */ | |
157 | ||
158 | /* Sparc specific messages. */ | |
159 | #define MSG_CROSS_CALL 0x0005 /* run func on cpus */ | |
160 | ||
161 | /* Empirical PROM processor mailbox constants. If the per-cpu mailbox | |
162 | * contains something other than one of these then the ipi is from | |
163 | * Linux's active_kernel_processor. This facility exists so that | |
164 | * the boot monitor can capture all the other cpus when one catches | |
165 | * a watchdog reset or the user enters the monitor using L1-A keys. | |
166 | */ | |
167 | #define MBOX_STOPCPU 0xFB | |
168 | #define MBOX_IDLECPU 0xFC | |
169 | #define MBOX_IDLECPU2 0xFD | |
170 | #define MBOX_STOPCPU2 0xFE | |
171 | ||
172 | #endif /* SMP */ | |
173 | ||
174 | #define NO_PROC_ID 0xFF | |
175 | ||
176 | #endif /* !(_SPARC_SMP_H) */ |