diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-02-17 11:38:06 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 04:13:24 -0500 |
commit | ebd8c56c5ae154e2c6cfb7453a76a4e7265b2377 (patch) | |
tree | 155df85100a1316ac103dcaed140d20ddc72c855 | |
parent | 101d5c18a928ef82b6c7bf99a9eaa536b5ccf593 (diff) |
[SPARC64]: Fix uniprocessor IRQ targetting on SUN4V.
We need to use the real hardware processor ID when
targetting interrupts, not the "define to 0" thing
the uniprocessor build gives us.
Also, fill in the Node-ID and Agent-ID fields properly
on sun4u/Safari.
Signed-off-by: David S. Miller <davem@davemloft.net>
-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*/ |