diff options
-rw-r--r-- | arch/sparc64/kernel/entry.S | 4 | ||||
-rw-r--r-- | arch/sparc64/kernel/irq.c | 98 | ||||
-rw-r--r-- | arch/sparc64/kernel/setup.c | 6 | ||||
-rw-r--r-- | include/asm-sparc64/cpudata.h | 6 | ||||
-rw-r--r-- | include/asm-sparc64/irq.h | 3 |
5 files changed, 58 insertions, 59 deletions
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index f5c8a293979f..bd332e41532f 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S | |||
@@ -1692,10 +1692,12 @@ __flushw_user: | |||
1692 | #ifdef CONFIG_SMP | 1692 | #ifdef CONFIG_SMP |
1693 | .globl hard_smp_processor_id | 1693 | .globl hard_smp_processor_id |
1694 | hard_smp_processor_id: | 1694 | hard_smp_processor_id: |
1695 | #endif | ||
1696 | .globl real_hard_smp_processor_id | ||
1697 | real_hard_smp_processor_id: | ||
1695 | __GET_CPUID(%o0) | 1698 | __GET_CPUID(%o0) |
1696 | retl | 1699 | retl |
1697 | nop | 1700 | nop |
1698 | #endif | ||
1699 | 1701 | ||
1700 | /* %o0: devhandle | 1702 | /* %o0: devhandle |
1701 | * %o1: devino | 1703 | * %o1: devino |
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index bb0bb34555da..712b16cdd5fb 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c | |||
@@ -138,11 +138,48 @@ out_unlock: | |||
138 | return 0; | 138 | return 0; |
139 | } | 139 | } |
140 | 140 | ||
141 | extern unsigned long real_hard_smp_processor_id(void); | ||
142 | |||
143 | static unsigned int sun4u_compute_tid(unsigned long imap, unsigned long cpuid) | ||
144 | { | ||
145 | unsigned int tid; | ||
146 | |||
147 | if (this_is_starfire) { | ||
148 | tid = starfire_translate(imap, cpuid); | ||
149 | tid <<= IMAP_TID_SHIFT; | ||
150 | tid &= IMAP_TID_UPA; | ||
151 | } else { | ||
152 | if (tlb_type == cheetah || tlb_type == cheetah_plus) { | ||
153 | unsigned long ver; | ||
154 | |||
155 | __asm__ ("rdpr %%ver, %0" : "=r" (ver)); | ||
156 | if ((ver >> 32UL) == __JALAPENO_ID || | ||
157 | (ver >> 32UL) == __SERRANO_ID) { | ||
158 | tid = cpuid << IMAP_TID_SHIFT; | ||
159 | tid &= IMAP_TID_JBUS; | ||
160 | } else { | ||
161 | unsigned int a = cpuid & 0x1f; | ||
162 | unsigned int n = (cpuid >> 5) & 0x1f; | ||
163 | |||
164 | tid = ((a << IMAP_AID_SHIFT) | | ||
165 | (n << IMAP_NID_SHIFT)); | ||
166 | tid &= (IMAP_AID_SAFARI | | ||
167 | IMAP_NID_SAFARI);; | ||
168 | } | ||
169 | } else { | ||
170 | tid = cpuid << IMAP_TID_SHIFT; | ||
171 | tid &= IMAP_TID_UPA; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | return tid; | ||
176 | } | ||
177 | |||
141 | /* Now these are always passed a true fully specified sun4u INO. */ | 178 | /* Now these are always passed a true fully specified sun4u INO. */ |
142 | void enable_irq(unsigned int irq) | 179 | void enable_irq(unsigned int irq) |
143 | { | 180 | { |
144 | struct ino_bucket *bucket = __bucket(irq); | 181 | struct ino_bucket *bucket = __bucket(irq); |
145 | unsigned long imap; | 182 | unsigned long imap, cpuid; |
146 | 183 | ||
147 | imap = bucket->imap; | 184 | imap = bucket->imap; |
148 | if (imap == 0UL) | 185 | if (imap == 0UL) |
@@ -150,54 +187,25 @@ void enable_irq(unsigned int irq) | |||
150 | 187 | ||
151 | preempt_disable(); | 188 | preempt_disable(); |
152 | 189 | ||
190 | /* This gets the physical processor ID, even on uniprocessor, | ||
191 | * so we can always program the interrupt target correctly. | ||
192 | */ | ||
193 | cpuid = real_hard_smp_processor_id(); | ||
194 | |||
153 | if (tlb_type == hypervisor) { | 195 | if (tlb_type == hypervisor) { |
154 | unsigned int ino = __irq_ino(irq); | 196 | unsigned int ino = __irq_ino(irq); |
155 | int cpu = hard_smp_processor_id(); | ||
156 | int err; | 197 | int err; |
157 | 198 | ||
158 | err = sun4v_intr_settarget(ino, cpu); | 199 | err = sun4v_intr_settarget(ino, cpuid); |
159 | if (err != HV_EOK) | 200 | if (err != HV_EOK) |
160 | printk("sun4v_intr_settarget(%x,%d): err(%d)\n", | 201 | printk("sun4v_intr_settarget(%x,%lu): err(%d)\n", |
161 | ino, cpu, err); | 202 | ino, cpuid, err); |
162 | err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED); | 203 | err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED); |
163 | if (err != HV_EOK) | 204 | if (err != HV_EOK) |
164 | printk("sun4v_intr_setenabled(%x): err(%d)\n", | 205 | printk("sun4v_intr_setenabled(%x): err(%d)\n", |
165 | ino, err); | 206 | ino, err); |
166 | } else { | 207 | } else { |
167 | unsigned long tid; | 208 | unsigned int tid = sun4u_compute_tid(imap, cpuid); |
168 | |||
169 | if (tlb_type == cheetah || tlb_type == cheetah_plus) { | ||
170 | unsigned long ver; | ||
171 | |||
172 | __asm__ ("rdpr %%ver, %0" : "=r" (ver)); | ||
173 | if ((ver >> 32) == __JALAPENO_ID || | ||
174 | (ver >> 32) == __SERRANO_ID) { | ||
175 | /* We set it to our JBUS ID. */ | ||
176 | __asm__ __volatile__("ldxa [%%g0] %1, %0" | ||
177 | : "=r" (tid) | ||
178 | : "i" (ASI_JBUS_CONFIG)); | ||
179 | tid = ((tid & (0x1fUL<<17)) << 9); | ||
180 | tid &= IMAP_TID_JBUS; | ||
181 | } else { | ||
182 | /* We set it to our Safari AID. */ | ||
183 | __asm__ __volatile__("ldxa [%%g0] %1, %0" | ||
184 | : "=r" (tid) | ||
185 | : "i"(ASI_SAFARI_CONFIG)); | ||
186 | tid = ((tid & (0x3ffUL<<17)) << 9); | ||
187 | tid &= IMAP_AID_SAFARI; | ||
188 | } | ||
189 | } else if (this_is_starfire == 0) { | ||
190 | /* We set it to our UPA MID. */ | ||
191 | __asm__ __volatile__("ldxa [%%g0] %1, %0" | ||
192 | : "=r" (tid) | ||
193 | : "i" (ASI_UPA_CONFIG)); | ||
194 | tid = ((tid & UPA_CONFIG_MID) << 9); | ||
195 | tid &= IMAP_TID_UPA; | ||
196 | } else { | ||
197 | tid = (starfire_translate(imap, | ||
198 | smp_processor_id()) << 26); | ||
199 | tid &= IMAP_TID_UPA; | ||
200 | } | ||
201 | 209 | ||
202 | /* NOTE NOTE NOTE, IGN and INO are read-only, IGN is a product | 210 | /* NOTE NOTE NOTE, IGN and INO are read-only, IGN is a product |
203 | * of this SYSIO's preconfigured IGN in the SYSIO Control | 211 | * of this SYSIO's preconfigured IGN in the SYSIO Control |
@@ -817,18 +825,8 @@ static int retarget_one_irq(struct irqaction *p, int goal_cpu) | |||
817 | sun4v_intr_setenabled(ino, HV_INTR_ENABLED); | 825 | sun4v_intr_setenabled(ino, HV_INTR_ENABLED); |
818 | } else { | 826 | } else { |
819 | unsigned long imap = bucket->imap; | 827 | unsigned long imap = bucket->imap; |
820 | unsigned int tid; | 828 | unsigned int tid = sun4u_compute_tid(imap, goal_cpu); |
821 | 829 | ||
822 | if (tlb_type == cheetah || tlb_type == cheetah_plus) { | ||
823 | tid = goal_cpu << 26; | ||
824 | tid &= IMAP_AID_SAFARI; | ||
825 | } else if (this_is_starfire == 0) { | ||
826 | tid = goal_cpu << 26; | ||
827 | tid &= IMAP_TID_UPA; | ||
828 | } else { | ||
829 | tid = (starfire_translate(imap, goal_cpu) << 26); | ||
830 | tid &= IMAP_TID_UPA; | ||
831 | } | ||
832 | upa_writel(tid | IMAP_VALID, imap); | 830 | upa_writel(tid | IMAP_VALID, imap); |
833 | } | 831 | } |
834 | 832 | ||
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 9b0c409d5b6a..77066f1bbe2f 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -222,7 +222,6 @@ static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; | |||
222 | 222 | ||
223 | static void __init per_cpu_patch(void) | 223 | static void __init per_cpu_patch(void) |
224 | { | 224 | { |
225 | #ifdef CONFIG_SMP | ||
226 | struct cpuid_patch_entry *p; | 225 | struct cpuid_patch_entry *p; |
227 | unsigned long ver; | 226 | unsigned long ver; |
228 | int is_jbus; | 227 | int is_jbus; |
@@ -233,8 +232,8 @@ static void __init per_cpu_patch(void) | |||
233 | is_jbus = 0; | 232 | is_jbus = 0; |
234 | if (tlb_type != hypervisor) { | 233 | if (tlb_type != hypervisor) { |
235 | __asm__ ("rdpr %%ver, %0" : "=r" (ver)); | 234 | __asm__ ("rdpr %%ver, %0" : "=r" (ver)); |
236 | is_jbus = ((ver >> 32) == __JALAPENO_ID || | 235 | is_jbus = ((ver >> 32UL) == __JALAPENO_ID || |
237 | (ver >> 32) == __SERRANO_ID); | 236 | (ver >> 32UL) == __SERRANO_ID); |
238 | } | 237 | } |
239 | 238 | ||
240 | p = &__cpuid_patch; | 239 | p = &__cpuid_patch; |
@@ -279,7 +278,6 @@ static void __init per_cpu_patch(void) | |||
279 | 278 | ||
280 | p++; | 279 | p++; |
281 | } | 280 | } |
282 | #endif | ||
283 | } | 281 | } |
284 | 282 | ||
285 | static void __init sun4v_patch(void) | 283 | static void __init sun4v_patch(void) |
diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 771aa94dfd95..84656f1895cd 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h | |||
@@ -80,7 +80,6 @@ extern struct trap_per_cpu trap_block[NR_CPUS]; | |||
80 | extern void init_cur_cpu_trap(struct thread_info *); | 80 | extern void init_cur_cpu_trap(struct thread_info *); |
81 | extern void setup_tba(void); | 81 | extern void setup_tba(void); |
82 | 82 | ||
83 | #ifdef CONFIG_SMP | ||
84 | struct cpuid_patch_entry { | 83 | struct cpuid_patch_entry { |
85 | unsigned int addr; | 84 | unsigned int addr; |
86 | unsigned int cheetah_safari[4]; | 85 | unsigned int cheetah_safari[4]; |
@@ -89,7 +88,6 @@ struct cpuid_patch_entry { | |||
89 | unsigned int sun4v[4]; | 88 | unsigned int sun4v[4]; |
90 | }; | 89 | }; |
91 | extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; | 90 | extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; |
92 | #endif | ||
93 | 91 | ||
94 | struct sun4v_1insn_patch_entry { | 92 | struct sun4v_1insn_patch_entry { |
95 | unsigned int addr; | 93 | unsigned int addr; |
@@ -123,8 +121,6 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, | |||
123 | 121 | ||
124 | #include <asm/scratchpad.h> | 122 | #include <asm/scratchpad.h> |
125 | 123 | ||
126 | #ifdef CONFIG_SMP | ||
127 | |||
128 | #define __GET_CPUID(REG) \ | 124 | #define __GET_CPUID(REG) \ |
129 | /* Spitfire implementation (default). */ \ | 125 | /* Spitfire implementation (default). */ \ |
130 | 661: ldxa [%g0] ASI_UPA_CONFIG, REG; \ | 126 | 661: ldxa [%g0] ASI_UPA_CONFIG, REG; \ |
@@ -156,6 +152,8 @@ extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, | |||
156 | nop; \ | 152 | nop; \ |
157 | .previous; | 153 | .previous; |
158 | 154 | ||
155 | #ifdef CONFIG_SMP | ||
156 | |||
159 | #define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ | 157 | #define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ |
160 | __GET_CPUID(TMP) \ | 158 | __GET_CPUID(TMP) \ |
161 | sethi %hi(trap_block), DEST; \ | 159 | sethi %hi(trap_block), DEST; \ |
diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h index 529a9df1ad43..de33d6e1afb5 100644 --- a/include/asm-sparc64/irq.h +++ b/include/asm-sparc64/irq.h | |||
@@ -72,8 +72,11 @@ struct ino_bucket { | |||
72 | #define IMAP_VALID 0x80000000 /* IRQ Enabled */ | 72 | #define IMAP_VALID 0x80000000 /* IRQ Enabled */ |
73 | #define IMAP_TID_UPA 0x7c000000 /* UPA TargetID */ | 73 | #define IMAP_TID_UPA 0x7c000000 /* UPA TargetID */ |
74 | #define IMAP_TID_JBUS 0x7c000000 /* JBUS TargetID */ | 74 | #define IMAP_TID_JBUS 0x7c000000 /* JBUS TargetID */ |
75 | #define IMAP_TID_SHIFT 26 | ||
75 | #define IMAP_AID_SAFARI 0x7c000000 /* Safari AgentID */ | 76 | #define IMAP_AID_SAFARI 0x7c000000 /* Safari AgentID */ |
77 | #define IMAP_AID_SHIFT 26 | ||
76 | #define IMAP_NID_SAFARI 0x03e00000 /* Safari NodeID */ | 78 | #define IMAP_NID_SAFARI 0x03e00000 /* Safari NodeID */ |
79 | #define IMAP_NID_SHIFT 21 | ||
77 | #define IMAP_IGN 0x000007c0 /* IRQ Group Number */ | 80 | #define IMAP_IGN 0x000007c0 /* IRQ Group Number */ |
78 | #define IMAP_INO 0x0000003f /* IRQ Number */ | 81 | #define IMAP_INO 0x0000003f /* IRQ Number */ |
79 | #define IMAP_INR 0x000007ff /* Full interrupt number*/ | 82 | #define IMAP_INR 0x000007ff /* Full interrupt number*/ |