1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/slab.h>
14#include <linux/sched/debug.h>
15#include <linux/pgtable.h>
16
17#include <asm/timer.h>
18#include <asm/traps.h>
19#include <asm/irq.h>
20#include <asm/io.h>
21#include <asm/cacheflush.h>
22
23#include "irq.h"
24#include "kernel.h"
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS];
104struct sun4m_irq_global __iomem *sun4m_irq_global;
105
106struct sun4m_handler_data {
107 bool percpu;
108 long mask;
109};
110
111
112
113
114#define SUN4M_INT_ENABLE 0x80000000
115#define SUN4M_INT_E14 0x00000080
116#define SUN4M_INT_E10 0x00080000
117
118#define SUN4M_INT_MASKALL 0x80000000
119#define SUN4M_INT_MODULE_ERR 0x40000000
120#define SUN4M_INT_M2S_WRITE_ERR 0x20000000
121#define SUN4M_INT_ECC_ERR 0x10000000
122#define SUN4M_INT_VME_ERR 0x08000000
123#define SUN4M_INT_FLOPPY 0x00400000
124#define SUN4M_INT_MODULE 0x00200000
125#define SUN4M_INT_VIDEO 0x00100000
126#define SUN4M_INT_REALTIME 0x00080000
127#define SUN4M_INT_SCSI 0x00040000
128#define SUN4M_INT_AUDIO 0x00020000
129#define SUN4M_INT_ETHERNET 0x00010000
130#define SUN4M_INT_SERIAL 0x00008000
131#define SUN4M_INT_KBDMS 0x00004000
132#define SUN4M_INT_SBUSBITS 0x00003F80
133#define SUN4M_INT_VMEBITS 0x0000007F
134
135#define SUN4M_INT_ERROR (SUN4M_INT_MODULE_ERR | \
136 SUN4M_INT_M2S_WRITE_ERR | \
137 SUN4M_INT_ECC_ERR | \
138 SUN4M_INT_VME_ERR)
139
140#define SUN4M_INT_SBUS(x) (1 << (x+7))
141#define SUN4M_INT_VME(x) (1 << (x))
142
143
144#define OBP_INT_LEVEL_SOFT 0x10
145#define OBP_INT_LEVEL_ONBOARD 0x20
146#define OBP_INT_LEVEL_SBUS 0x30
147#define OBP_INT_LEVEL_VME 0x40
148
149#define SUN4M_TIMER_IRQ (OBP_INT_LEVEL_ONBOARD | 10)
150#define SUN4M_PROFILE_IRQ (OBP_INT_LEVEL_ONBOARD | 14)
151
152static unsigned long sun4m_imask[0x50] = {
153
154 0, SUN4M_SOFT_INT(1),
155 SUN4M_SOFT_INT(2), SUN4M_SOFT_INT(3),
156 SUN4M_SOFT_INT(4), SUN4M_SOFT_INT(5),
157 SUN4M_SOFT_INT(6), SUN4M_SOFT_INT(7),
158 SUN4M_SOFT_INT(8), SUN4M_SOFT_INT(9),
159 SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11),
160 SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13),
161 SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15),
162
163 0, SUN4M_SOFT_INT(1),
164 SUN4M_SOFT_INT(2), SUN4M_SOFT_INT(3),
165 SUN4M_SOFT_INT(4), SUN4M_SOFT_INT(5),
166 SUN4M_SOFT_INT(6), SUN4M_SOFT_INT(7),
167 SUN4M_SOFT_INT(8), SUN4M_SOFT_INT(9),
168 SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11),
169 SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13),
170 SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15),
171
172 0, 0, 0, 0,
173 SUN4M_INT_SCSI, 0, SUN4M_INT_ETHERNET, 0,
174 SUN4M_INT_VIDEO, SUN4M_INT_MODULE,
175 SUN4M_INT_REALTIME, SUN4M_INT_FLOPPY,
176 (SUN4M_INT_SERIAL | SUN4M_INT_KBDMS),
177 SUN4M_INT_AUDIO, SUN4M_INT_E14, SUN4M_INT_MODULE_ERR,
178
179 0, 0, SUN4M_INT_SBUS(0), SUN4M_INT_SBUS(1),
180 0, SUN4M_INT_SBUS(2), 0, SUN4M_INT_SBUS(3),
181 0, SUN4M_INT_SBUS(4), 0, SUN4M_INT_SBUS(5),
182 0, SUN4M_INT_SBUS(6), 0, 0,
183
184 0, 0, SUN4M_INT_VME(0), SUN4M_INT_VME(1),
185 0, SUN4M_INT_VME(2), 0, SUN4M_INT_VME(3),
186 0, SUN4M_INT_VME(4), 0, SUN4M_INT_VME(5),
187 0, SUN4M_INT_VME(6), 0, 0
188};
189
190static void sun4m_mask_irq(struct irq_data *data)
191{
192 struct sun4m_handler_data *handler_data;
193 int cpu = smp_processor_id();
194
195 handler_data = irq_data_get_irq_handler_data(data);
196 if (handler_data->mask) {
197 unsigned long flags;
198
199 local_irq_save(flags);
200 if (handler_data->percpu) {
201 sbus_writel(handler_data->mask, &sun4m_irq_percpu[cpu]->set);
202 } else {
203 sbus_writel(handler_data->mask, &sun4m_irq_global->mask_set);
204 }
205 local_irq_restore(flags);
206 }
207}
208
209static void sun4m_unmask_irq(struct irq_data *data)
210{
211 struct sun4m_handler_data *handler_data;
212 int cpu = smp_processor_id();
213
214 handler_data = irq_data_get_irq_handler_data(data);
215 if (handler_data->mask) {
216 unsigned long flags;
217
218 local_irq_save(flags);
219 if (handler_data->percpu) {
220 sbus_writel(handler_data->mask, &sun4m_irq_percpu[cpu]->clear);
221 } else {
222 sbus_writel(handler_data->mask, &sun4m_irq_global->mask_clear);
223 }
224 local_irq_restore(flags);
225 }
226}
227
228static unsigned int sun4m_startup_irq(struct irq_data *data)
229{
230 irq_link(data->irq);
231 sun4m_unmask_irq(data);
232 return 0;
233}
234
235static void sun4m_shutdown_irq(struct irq_data *data)
236{
237 sun4m_mask_irq(data);
238 irq_unlink(data->irq);
239}
240
241static struct irq_chip sun4m_irq = {
242 .name = "sun4m",
243 .irq_startup = sun4m_startup_irq,
244 .irq_shutdown = sun4m_shutdown_irq,
245 .irq_mask = sun4m_mask_irq,
246 .irq_unmask = sun4m_unmask_irq,
247};
248
249
250static unsigned int sun4m_build_device_irq(struct platform_device *op,
251 unsigned int real_irq)
252{
253 struct sun4m_handler_data *handler_data;
254 unsigned int irq;
255 unsigned int pil;
256
257 if (real_irq >= OBP_INT_LEVEL_VME) {
258 prom_printf("Bogus sun4m IRQ %u\n", real_irq);
259 prom_halt();
260 }
261 pil = (real_irq & 0xf);
262 irq = irq_alloc(real_irq, pil);
263
264 if (irq == 0)
265 goto out;
266
267 handler_data = irq_get_handler_data(irq);
268 if (unlikely(handler_data))
269 goto out;
270
271 handler_data = kzalloc(sizeof(struct sun4m_handler_data), GFP_ATOMIC);
272 if (unlikely(!handler_data)) {
273 prom_printf("IRQ: kzalloc(sun4m_handler_data) failed.\n");
274 prom_halt();
275 }
276
277 handler_data->mask = sun4m_imask[real_irq];
278 handler_data->percpu = real_irq < OBP_INT_LEVEL_ONBOARD;
279 irq_set_chip_and_handler_name(irq, &sun4m_irq,
280 handle_level_irq, "level");
281 irq_set_handler_data(irq, handler_data);
282
283out:
284 return irq;
285}
286
287struct sun4m_timer_percpu {
288 u32 l14_limit;
289 u32 l14_count;
290 u32 l14_limit_noclear;
291 u32 user_timer_start_stop;
292};
293
294static struct sun4m_timer_percpu __iomem *timers_percpu[SUN4M_NCPUS];
295
296struct sun4m_timer_global {
297 u32 l10_limit;
298 u32 l10_count;
299 u32 l10_limit_noclear;
300 u32 reserved;
301 u32 timer_config;
302};
303
304static struct sun4m_timer_global __iomem *timers_global;
305
306static void sun4m_clear_clock_irq(void)
307{
308 sbus_readl(&timers_global->l10_limit);
309}
310
311void sun4m_nmi(struct pt_regs *regs)
312{
313 unsigned long afsr, afar, si;
314
315 printk(KERN_ERR "Aieee: sun4m NMI received!\n");
316
317 __asm__ __volatile__("mov 0x500, %%g1\n\t"
318 "lda [%%g1] 0x4, %0\n\t"
319 "mov 0x600, %%g1\n\t"
320 "lda [%%g1] 0x4, %1\n\t" :
321 "=r" (afsr), "=r" (afar));
322 printk(KERN_ERR "afsr=%08lx afar=%08lx\n", afsr, afar);
323 si = sbus_readl(&sun4m_irq_global->pending);
324 printk(KERN_ERR "si=%08lx\n", si);
325 if (si & SUN4M_INT_MODULE_ERR)
326 printk(KERN_ERR "Module async error\n");
327 if (si & SUN4M_INT_M2S_WRITE_ERR)
328 printk(KERN_ERR "MBus/SBus async error\n");
329 if (si & SUN4M_INT_ECC_ERR)
330 printk(KERN_ERR "ECC memory error\n");
331 if (si & SUN4M_INT_VME_ERR)
332 printk(KERN_ERR "VME async error\n");
333 printk(KERN_ERR "you lose buddy boy...\n");
334 show_regs(regs);
335 prom_halt();
336}
337
338void sun4m_unmask_profile_irq(void)
339{
340 unsigned long flags;
341
342 local_irq_save(flags);
343 sbus_writel(sun4m_imask[SUN4M_PROFILE_IRQ], &sun4m_irq_global->mask_clear);
344 local_irq_restore(flags);
345}
346
347void sun4m_clear_profile_irq(int cpu)
348{
349 sbus_readl(&timers_percpu[cpu]->l14_limit);
350}
351
352static void sun4m_load_profile_irq(int cpu, unsigned int limit)
353{
354 unsigned int value = limit ? timer_value(limit) : 0;
355 sbus_writel(value, &timers_percpu[cpu]->l14_limit);
356}
357
358static void __init sun4m_init_timers(void)
359{
360 struct device_node *dp = of_find_node_by_name(NULL, "counter");
361 int i, err, len, num_cpu_timers;
362 unsigned int irq;
363 const u32 *addr;
364
365 if (!dp) {
366 printk(KERN_ERR "sun4m_init_timers: No 'counter' node.\n");
367 return;
368 }
369
370 addr = of_get_property(dp, "address", &len);
371 of_node_put(dp);
372 if (!addr) {
373 printk(KERN_ERR "sun4m_init_timers: No 'address' prop.\n");
374 return;
375 }
376
377 num_cpu_timers = (len / sizeof(u32)) - 1;
378 for (i = 0; i < num_cpu_timers; i++) {
379 timers_percpu[i] = (void __iomem *)
380 (unsigned long) addr[i];
381 }
382 timers_global = (void __iomem *)
383 (unsigned long) addr[num_cpu_timers];
384
385
386 sbus_writel(0x00000000, &timers_global->timer_config);
387
388#ifdef CONFIG_SMP
389 sparc_config.cs_period = SBUS_CLOCK_RATE * 2;
390 sparc_config.features |= FEAT_L14_ONESHOT;
391#else
392 sparc_config.cs_period = SBUS_CLOCK_RATE / HZ;
393 sparc_config.features |= FEAT_L10_CLOCKEVENT;
394#endif
395 sparc_config.features |= FEAT_L10_CLOCKSOURCE;
396 sbus_writel(timer_value(sparc_config.cs_period),
397 &timers_global->l10_limit);
398
399 master_l10_counter = &timers_global->l10_count;
400
401 irq = sun4m_build_device_irq(NULL, SUN4M_TIMER_IRQ);
402
403 err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL);
404 if (err) {
405 printk(KERN_ERR "sun4m_init_timers: Register IRQ error %d.\n",
406 err);
407 return;
408 }
409
410 for (i = 0; i < num_cpu_timers; i++)
411 sbus_writel(0, &timers_percpu[i]->l14_limit);
412 if (num_cpu_timers == 4)
413 sbus_writel(SUN4M_INT_E14, &sun4m_irq_global->mask_set);
414
415#ifdef CONFIG_SMP
416 {
417 unsigned long flags;
418 struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)];
419
420
421
422
423
424 local_irq_save(flags);
425 trap_table->inst_one = lvl14_save[0];
426 trap_table->inst_two = lvl14_save[1];
427 trap_table->inst_three = lvl14_save[2];
428 trap_table->inst_four = lvl14_save[3];
429 local_ops->cache_all();
430 local_irq_restore(flags);
431 }
432#endif
433}
434
435void __init sun4m_init_IRQ(void)
436{
437 struct device_node *dp = of_find_node_by_name(NULL, "interrupt");
438 int len, i, mid, num_cpu_iregs;
439 const u32 *addr;
440
441 if (!dp) {
442 printk(KERN_ERR "sun4m_init_IRQ: No 'interrupt' node.\n");
443 return;
444 }
445
446 addr = of_get_property(dp, "address", &len);
447 of_node_put(dp);
448 if (!addr) {
449 printk(KERN_ERR "sun4m_init_IRQ: No 'address' prop.\n");
450 return;
451 }
452
453 num_cpu_iregs = (len / sizeof(u32)) - 1;
454 for (i = 0; i < num_cpu_iregs; i++) {
455 sun4m_irq_percpu[i] = (void __iomem *)
456 (unsigned long) addr[i];
457 }
458 sun4m_irq_global = (void __iomem *)
459 (unsigned long) addr[num_cpu_iregs];
460
461 local_irq_disable();
462
463 sbus_writel(~SUN4M_INT_MASKALL, &sun4m_irq_global->mask_set);
464 for (i = 0; !cpu_find_by_instance(i, NULL, &mid); i++)
465 sbus_writel(~0x17fff, &sun4m_irq_percpu[mid]->clear);
466
467 if (num_cpu_iregs == 4)
468 sbus_writel(0, &sun4m_irq_global->interrupt_target);
469
470 sparc_config.init_timers = sun4m_init_timers;
471 sparc_config.build_device_irq = sun4m_build_device_irq;
472 sparc_config.clock_rate = SBUS_CLOCK_RATE;
473 sparc_config.clear_clock_irq = sun4m_clear_clock_irq;
474 sparc_config.load_profile_irq = sun4m_load_profile_irq;
475
476
477
478}
479