aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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*/