0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/slab.h>
0014 #include <linux/sched/debug.h>
0015 #include <linux/pgtable.h>
0016
0017 #include <asm/timer.h>
0018 #include <asm/traps.h>
0019 #include <asm/irq.h>
0020 #include <asm/io.h>
0021 #include <asm/cacheflush.h>
0022
0023 #include "irq.h"
0024 #include "kernel.h"
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103 struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS];
0104 struct sun4m_irq_global __iomem *sun4m_irq_global;
0105
0106 struct sun4m_handler_data {
0107 bool percpu;
0108 long mask;
0109 };
0110
0111
0112
0113
0114 #define SUN4M_INT_ENABLE 0x80000000
0115 #define SUN4M_INT_E14 0x00000080
0116 #define SUN4M_INT_E10 0x00080000
0117
0118 #define SUN4M_INT_MASKALL 0x80000000
0119 #define SUN4M_INT_MODULE_ERR 0x40000000
0120 #define SUN4M_INT_M2S_WRITE_ERR 0x20000000
0121 #define SUN4M_INT_ECC_ERR 0x10000000
0122 #define SUN4M_INT_VME_ERR 0x08000000
0123 #define SUN4M_INT_FLOPPY 0x00400000
0124 #define SUN4M_INT_MODULE 0x00200000
0125 #define SUN4M_INT_VIDEO 0x00100000
0126 #define SUN4M_INT_REALTIME 0x00080000
0127 #define SUN4M_INT_SCSI 0x00040000
0128 #define SUN4M_INT_AUDIO 0x00020000
0129 #define SUN4M_INT_ETHERNET 0x00010000
0130 #define SUN4M_INT_SERIAL 0x00008000
0131 #define SUN4M_INT_KBDMS 0x00004000
0132 #define SUN4M_INT_SBUSBITS 0x00003F80
0133 #define SUN4M_INT_VMEBITS 0x0000007F
0134
0135 #define SUN4M_INT_ERROR (SUN4M_INT_MODULE_ERR | \
0136 SUN4M_INT_M2S_WRITE_ERR | \
0137 SUN4M_INT_ECC_ERR | \
0138 SUN4M_INT_VME_ERR)
0139
0140 #define SUN4M_INT_SBUS(x) (1 << (x+7))
0141 #define SUN4M_INT_VME(x) (1 << (x))
0142
0143
0144 #define OBP_INT_LEVEL_SOFT 0x10
0145 #define OBP_INT_LEVEL_ONBOARD 0x20
0146 #define OBP_INT_LEVEL_SBUS 0x30
0147 #define OBP_INT_LEVEL_VME 0x40
0148
0149 #define SUN4M_TIMER_IRQ (OBP_INT_LEVEL_ONBOARD | 10)
0150 #define SUN4M_PROFILE_IRQ (OBP_INT_LEVEL_ONBOARD | 14)
0151
0152 static unsigned long sun4m_imask[0x50] = {
0153
0154 0, SUN4M_SOFT_INT(1),
0155 SUN4M_SOFT_INT(2), SUN4M_SOFT_INT(3),
0156 SUN4M_SOFT_INT(4), SUN4M_SOFT_INT(5),
0157 SUN4M_SOFT_INT(6), SUN4M_SOFT_INT(7),
0158 SUN4M_SOFT_INT(8), SUN4M_SOFT_INT(9),
0159 SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11),
0160 SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13),
0161 SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15),
0162
0163 0, SUN4M_SOFT_INT(1),
0164 SUN4M_SOFT_INT(2), SUN4M_SOFT_INT(3),
0165 SUN4M_SOFT_INT(4), SUN4M_SOFT_INT(5),
0166 SUN4M_SOFT_INT(6), SUN4M_SOFT_INT(7),
0167 SUN4M_SOFT_INT(8), SUN4M_SOFT_INT(9),
0168 SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11),
0169 SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13),
0170 SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15),
0171
0172 0, 0, 0, 0,
0173 SUN4M_INT_SCSI, 0, SUN4M_INT_ETHERNET, 0,
0174 SUN4M_INT_VIDEO, SUN4M_INT_MODULE,
0175 SUN4M_INT_REALTIME, SUN4M_INT_FLOPPY,
0176 (SUN4M_INT_SERIAL | SUN4M_INT_KBDMS),
0177 SUN4M_INT_AUDIO, SUN4M_INT_E14, SUN4M_INT_MODULE_ERR,
0178
0179 0, 0, SUN4M_INT_SBUS(0), SUN4M_INT_SBUS(1),
0180 0, SUN4M_INT_SBUS(2), 0, SUN4M_INT_SBUS(3),
0181 0, SUN4M_INT_SBUS(4), 0, SUN4M_INT_SBUS(5),
0182 0, SUN4M_INT_SBUS(6), 0, 0,
0183
0184 0, 0, SUN4M_INT_VME(0), SUN4M_INT_VME(1),
0185 0, SUN4M_INT_VME(2), 0, SUN4M_INT_VME(3),
0186 0, SUN4M_INT_VME(4), 0, SUN4M_INT_VME(5),
0187 0, SUN4M_INT_VME(6), 0, 0
0188 };
0189
0190 static void sun4m_mask_irq(struct irq_data *data)
0191 {
0192 struct sun4m_handler_data *handler_data;
0193 int cpu = smp_processor_id();
0194
0195 handler_data = irq_data_get_irq_handler_data(data);
0196 if (handler_data->mask) {
0197 unsigned long flags;
0198
0199 local_irq_save(flags);
0200 if (handler_data->percpu) {
0201 sbus_writel(handler_data->mask, &sun4m_irq_percpu[cpu]->set);
0202 } else {
0203 sbus_writel(handler_data->mask, &sun4m_irq_global->mask_set);
0204 }
0205 local_irq_restore(flags);
0206 }
0207 }
0208
0209 static void sun4m_unmask_irq(struct irq_data *data)
0210 {
0211 struct sun4m_handler_data *handler_data;
0212 int cpu = smp_processor_id();
0213
0214 handler_data = irq_data_get_irq_handler_data(data);
0215 if (handler_data->mask) {
0216 unsigned long flags;
0217
0218 local_irq_save(flags);
0219 if (handler_data->percpu) {
0220 sbus_writel(handler_data->mask, &sun4m_irq_percpu[cpu]->clear);
0221 } else {
0222 sbus_writel(handler_data->mask, &sun4m_irq_global->mask_clear);
0223 }
0224 local_irq_restore(flags);
0225 }
0226 }
0227
0228 static unsigned int sun4m_startup_irq(struct irq_data *data)
0229 {
0230 irq_link(data->irq);
0231 sun4m_unmask_irq(data);
0232 return 0;
0233 }
0234
0235 static void sun4m_shutdown_irq(struct irq_data *data)
0236 {
0237 sun4m_mask_irq(data);
0238 irq_unlink(data->irq);
0239 }
0240
0241 static struct irq_chip sun4m_irq = {
0242 .name = "sun4m",
0243 .irq_startup = sun4m_startup_irq,
0244 .irq_shutdown = sun4m_shutdown_irq,
0245 .irq_mask = sun4m_mask_irq,
0246 .irq_unmask = sun4m_unmask_irq,
0247 };
0248
0249
0250 static unsigned int sun4m_build_device_irq(struct platform_device *op,
0251 unsigned int real_irq)
0252 {
0253 struct sun4m_handler_data *handler_data;
0254 unsigned int irq;
0255 unsigned int pil;
0256
0257 if (real_irq >= OBP_INT_LEVEL_VME) {
0258 prom_printf("Bogus sun4m IRQ %u\n", real_irq);
0259 prom_halt();
0260 }
0261 pil = (real_irq & 0xf);
0262 irq = irq_alloc(real_irq, pil);
0263
0264 if (irq == 0)
0265 goto out;
0266
0267 handler_data = irq_get_handler_data(irq);
0268 if (unlikely(handler_data))
0269 goto out;
0270
0271 handler_data = kzalloc(sizeof(struct sun4m_handler_data), GFP_ATOMIC);
0272 if (unlikely(!handler_data)) {
0273 prom_printf("IRQ: kzalloc(sun4m_handler_data) failed.\n");
0274 prom_halt();
0275 }
0276
0277 handler_data->mask = sun4m_imask[real_irq];
0278 handler_data->percpu = real_irq < OBP_INT_LEVEL_ONBOARD;
0279 irq_set_chip_and_handler_name(irq, &sun4m_irq,
0280 handle_level_irq, "level");
0281 irq_set_handler_data(irq, handler_data);
0282
0283 out:
0284 return irq;
0285 }
0286
0287 struct sun4m_timer_percpu {
0288 u32 l14_limit;
0289 u32 l14_count;
0290 u32 l14_limit_noclear;
0291 u32 user_timer_start_stop;
0292 };
0293
0294 static struct sun4m_timer_percpu __iomem *timers_percpu[SUN4M_NCPUS];
0295
0296 struct sun4m_timer_global {
0297 u32 l10_limit;
0298 u32 l10_count;
0299 u32 l10_limit_noclear;
0300 u32 reserved;
0301 u32 timer_config;
0302 };
0303
0304 static struct sun4m_timer_global __iomem *timers_global;
0305
0306 static void sun4m_clear_clock_irq(void)
0307 {
0308 sbus_readl(&timers_global->l10_limit);
0309 }
0310
0311 void sun4m_nmi(struct pt_regs *regs)
0312 {
0313 unsigned long afsr, afar, si;
0314
0315 printk(KERN_ERR "Aieee: sun4m NMI received!\n");
0316
0317 __asm__ __volatile__("mov 0x500, %%g1\n\t"
0318 "lda [%%g1] 0x4, %0\n\t"
0319 "mov 0x600, %%g1\n\t"
0320 "lda [%%g1] 0x4, %1\n\t" :
0321 "=r" (afsr), "=r" (afar));
0322 printk(KERN_ERR "afsr=%08lx afar=%08lx\n", afsr, afar);
0323 si = sbus_readl(&sun4m_irq_global->pending);
0324 printk(KERN_ERR "si=%08lx\n", si);
0325 if (si & SUN4M_INT_MODULE_ERR)
0326 printk(KERN_ERR "Module async error\n");
0327 if (si & SUN4M_INT_M2S_WRITE_ERR)
0328 printk(KERN_ERR "MBus/SBus async error\n");
0329 if (si & SUN4M_INT_ECC_ERR)
0330 printk(KERN_ERR "ECC memory error\n");
0331 if (si & SUN4M_INT_VME_ERR)
0332 printk(KERN_ERR "VME async error\n");
0333 printk(KERN_ERR "you lose buddy boy...\n");
0334 show_regs(regs);
0335 prom_halt();
0336 }
0337
0338 void sun4m_unmask_profile_irq(void)
0339 {
0340 unsigned long flags;
0341
0342 local_irq_save(flags);
0343 sbus_writel(sun4m_imask[SUN4M_PROFILE_IRQ], &sun4m_irq_global->mask_clear);
0344 local_irq_restore(flags);
0345 }
0346
0347 void sun4m_clear_profile_irq(int cpu)
0348 {
0349 sbus_readl(&timers_percpu[cpu]->l14_limit);
0350 }
0351
0352 static void sun4m_load_profile_irq(int cpu, unsigned int limit)
0353 {
0354 unsigned int value = limit ? timer_value(limit) : 0;
0355 sbus_writel(value, &timers_percpu[cpu]->l14_limit);
0356 }
0357
0358 static void __init sun4m_init_timers(void)
0359 {
0360 struct device_node *dp = of_find_node_by_name(NULL, "counter");
0361 int i, err, len, num_cpu_timers;
0362 unsigned int irq;
0363 const u32 *addr;
0364
0365 if (!dp) {
0366 printk(KERN_ERR "sun4m_init_timers: No 'counter' node.\n");
0367 return;
0368 }
0369
0370 addr = of_get_property(dp, "address", &len);
0371 of_node_put(dp);
0372 if (!addr) {
0373 printk(KERN_ERR "sun4m_init_timers: No 'address' prop.\n");
0374 return;
0375 }
0376
0377 num_cpu_timers = (len / sizeof(u32)) - 1;
0378 for (i = 0; i < num_cpu_timers; i++) {
0379 timers_percpu[i] = (void __iomem *)
0380 (unsigned long) addr[i];
0381 }
0382 timers_global = (void __iomem *)
0383 (unsigned long) addr[num_cpu_timers];
0384
0385
0386 sbus_writel(0x00000000, &timers_global->timer_config);
0387
0388 #ifdef CONFIG_SMP
0389 sparc_config.cs_period = SBUS_CLOCK_RATE * 2;
0390 sparc_config.features |= FEAT_L14_ONESHOT;
0391 #else
0392 sparc_config.cs_period = SBUS_CLOCK_RATE / HZ;
0393 sparc_config.features |= FEAT_L10_CLOCKEVENT;
0394 #endif
0395 sparc_config.features |= FEAT_L10_CLOCKSOURCE;
0396 sbus_writel(timer_value(sparc_config.cs_period),
0397 &timers_global->l10_limit);
0398
0399 master_l10_counter = &timers_global->l10_count;
0400
0401 irq = sun4m_build_device_irq(NULL, SUN4M_TIMER_IRQ);
0402
0403 err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL);
0404 if (err) {
0405 printk(KERN_ERR "sun4m_init_timers: Register IRQ error %d.\n",
0406 err);
0407 return;
0408 }
0409
0410 for (i = 0; i < num_cpu_timers; i++)
0411 sbus_writel(0, &timers_percpu[i]->l14_limit);
0412 if (num_cpu_timers == 4)
0413 sbus_writel(SUN4M_INT_E14, &sun4m_irq_global->mask_set);
0414
0415 #ifdef CONFIG_SMP
0416 {
0417 unsigned long flags;
0418 struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)];
0419
0420
0421
0422
0423
0424 local_irq_save(flags);
0425 trap_table->inst_one = lvl14_save[0];
0426 trap_table->inst_two = lvl14_save[1];
0427 trap_table->inst_three = lvl14_save[2];
0428 trap_table->inst_four = lvl14_save[3];
0429 local_ops->cache_all();
0430 local_irq_restore(flags);
0431 }
0432 #endif
0433 }
0434
0435 void __init sun4m_init_IRQ(void)
0436 {
0437 struct device_node *dp = of_find_node_by_name(NULL, "interrupt");
0438 int len, i, mid, num_cpu_iregs;
0439 const u32 *addr;
0440
0441 if (!dp) {
0442 printk(KERN_ERR "sun4m_init_IRQ: No 'interrupt' node.\n");
0443 return;
0444 }
0445
0446 addr = of_get_property(dp, "address", &len);
0447 of_node_put(dp);
0448 if (!addr) {
0449 printk(KERN_ERR "sun4m_init_IRQ: No 'address' prop.\n");
0450 return;
0451 }
0452
0453 num_cpu_iregs = (len / sizeof(u32)) - 1;
0454 for (i = 0; i < num_cpu_iregs; i++) {
0455 sun4m_irq_percpu[i] = (void __iomem *)
0456 (unsigned long) addr[i];
0457 }
0458 sun4m_irq_global = (void __iomem *)
0459 (unsigned long) addr[num_cpu_iregs];
0460
0461 local_irq_disable();
0462
0463 sbus_writel(~SUN4M_INT_MASKALL, &sun4m_irq_global->mask_set);
0464 for (i = 0; !cpu_find_by_instance(i, NULL, &mid); i++)
0465 sbus_writel(~0x17fff, &sun4m_irq_percpu[mid]->clear);
0466
0467 if (num_cpu_iregs == 4)
0468 sbus_writel(0, &sun4m_irq_global->interrupt_target);
0469
0470 sparc_config.init_timers = sun4m_init_timers;
0471 sparc_config.build_device_irq = sun4m_build_device_irq;
0472 sparc_config.clock_rate = SBUS_CLOCK_RATE;
0473 sparc_config.clear_clock_irq = sun4m_clear_clock_irq;
0474 sparc_config.load_profile_irq = sun4m_load_profile_irq;
0475
0476
0477
0478 }