aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-17 11:38:06 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:13:24 -0500
commitebd8c56c5ae154e2c6cfb7453a76a4e7265b2377 (patch)
tree155df85100a1316ac103dcaed140d20ddc72c855
parent101d5c18a928ef82b6c7bf99a9eaa536b5ccf593 (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.S4
-rw-r--r--arch/sparc64/kernel/irq.c98
-rw-r--r--arch/sparc64/kernel/setup.c6
-rw-r--r--include/asm-sparc64/cpudata.h6
-rw-r--r--include/asm-sparc64/irq.h3
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
1694hard_smp_processor_id: 1694hard_smp_processor_id:
1695#endif
1696 .globl real_hard_smp_processor_id
1697real_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
141extern unsigned long real_hard_smp_processor_id(void);
142
143static 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. */
142void enable_irq(unsigned int irq) 179void 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
223static void __init per_cpu_patch(void) 223static 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
285static void __init sun4v_patch(void) 283static 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];
80extern void init_cur_cpu_trap(struct thread_info *); 80extern void init_cur_cpu_trap(struct thread_info *);
81extern void setup_tba(void); 81extern void setup_tba(void);
82 82
83#ifdef CONFIG_SMP
84struct cpuid_patch_entry { 83struct 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};
91extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; 90extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end;
92#endif
93 91
94struct sun4v_1insn_patch_entry { 92struct 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). */ \
130661: ldxa [%g0] ASI_UPA_CONFIG, REG; \ 126661: 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*/