1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Carsten Langgaard, carstenl@mips.com 7 * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc. 8 * Copyright (C) 2001 Ralf Baechle 9 * Copyright (C) 2013 Imagination Technologies Ltd. 10 * 11 * Routines for generic manipulation of the interrupts found on the MIPS 12 * Malta board. The interrupt controller is located in the South Bridge 13 * a PIIX4 device with two internal 82C95 interrupt controllers. 14 */ 15 #include <linux/init.h> 16 #include <linux/irq.h> 17 #include <linux/sched.h> 18 #include <linux/smp.h> 19 #include <linux/interrupt.h> 20 #include <linux/io.h> 21 #include <linux/kernel_stat.h> 22 #include <linux/kernel.h> 23 #include <linux/random.h> 24 25 #include <asm/traps.h> 26 #include <asm/i8259.h> 27 #include <asm/irq_cpu.h> 28 #include <asm/irq_regs.h> 29 #include <asm/mips-boards/malta.h> 30 #include <asm/mips-boards/maltaint.h> 31 #include <asm/gt64120.h> 32 #include <asm/mips-boards/generic.h> 33 #include <asm/mips-boards/msc01_pci.h> 34 #include <asm/msc01_ic.h> 35 #include <asm/gic.h> 36 #include <asm/gcmpregs.h> 37 #include <asm/setup.h> 38 #include <asm/rtlx.h> 39 40 int gcmp_present = -1; 41 static unsigned long _msc01_biu_base; 42 static unsigned long _gcmp_base; 43 static unsigned int ipi_map[NR_CPUS]; 44 45 static DEFINE_RAW_SPINLOCK(mips_irq_lock); 46 47 static inline int mips_pcibios_iack(void) 48 { 49 int irq; 50 51 /* 52 * Determine highest priority pending interrupt by performing 53 * a PCI Interrupt Acknowledge cycle. 54 */ 55 switch (mips_revision_sconid) { 56 case MIPS_REVISION_SCON_SOCIT: 57 case MIPS_REVISION_SCON_ROCIT: 58 case MIPS_REVISION_SCON_SOCITSC: 59 case MIPS_REVISION_SCON_SOCITSCP: 60 MSC_READ(MSC01_PCI_IACK, irq); 61 irq &= 0xff; 62 break; 63 case MIPS_REVISION_SCON_GT64120: 64 irq = GT_READ(GT_PCI0_IACK_OFS); 65 irq &= 0xff; 66 break; 67 case MIPS_REVISION_SCON_BONITO: 68 /* The following will generate a PCI IACK cycle on the 69 * Bonito controller. It's a little bit kludgy, but it 70 * was the easiest way to implement it in hardware at 71 * the given time. 72 */ 73 BONITO_PCIMAP_CFG = 0x20000; 74 75 /* Flush Bonito register block */ 76 (void) BONITO_PCIMAP_CFG; 77 iob(); /* sync */ 78 79 irq = __raw_readl((u32 *)_pcictrl_bonito_pcicfg); 80 iob(); /* sync */ 81 irq &= 0xff; 82 BONITO_PCIMAP_CFG = 0; 83 break; 84 default: 85 pr_emerg("Unknown system controller.\n"); 86 return -1; 87 } 88 return irq; 89 } 90 91 static inline int get_int(void) 92 { 93 unsigned long flags; 94 int irq; 95 raw_spin_lock_irqsave(&mips_irq_lock, flags); 96 97 irq = mips_pcibios_iack(); 98 99 /* 100 * The only way we can decide if an interrupt is spurious 101 * is by checking the 8259 registers. This needs a spinlock 102 * on an SMP system, so leave it up to the generic code... 103 */ 104 105 raw_spin_unlock_irqrestore(&mips_irq_lock, flags); 106 107 return irq; 108 } 109 110 static void malta_hw0_irqdispatch(void) 111 { 112 int irq; 113 114 irq = get_int(); 115 if (irq < 0) { 116 /* interrupt has already been cleared */ 117 return; 118 } 119 120 do_IRQ(MALTA_INT_BASE + irq); 121 122 #ifdef MIPS_VPE_APSP_API 123 if (aprp_hook) 124 aprp_hook(); 125 #endif 126 } 127 128 static void malta_ipi_irqdispatch(void) 129 { 130 int irq; 131 132 if (gic_compare_int()) 133 do_IRQ(MIPS_GIC_IRQ_BASE); 134 135 irq = gic_get_int(); 136 if (irq < 0) 137 return; /* interrupt has already been cleared */ 138 139 do_IRQ(MIPS_GIC_IRQ_BASE + irq); 140 } 141 142 static void corehi_irqdispatch(void) 143 { 144 unsigned int intedge, intsteer, pcicmd, pcibadaddr; 145 unsigned int pcimstat, intisr, inten, intpol; 146 unsigned int intrcause, datalo, datahi; 147 struct pt_regs *regs = get_irq_regs(); 148 149 pr_emerg("CoreHI interrupt, shouldn't happen, we die here!\n"); 150 pr_emerg("epc : %08lx\nStatus: %08lx\n" 151 "Cause : %08lx\nbadVaddr : %08lx\n", 152 regs->cp0_epc, regs->cp0_status, 153 regs->cp0_cause, regs->cp0_badvaddr); 154 155 /* Read all the registers and then print them as there is a 156 problem with interspersed printk's upsetting the Bonito controller. 157 Do it for the others too. 158 */ 159 160 switch (mips_revision_sconid) { 161 case MIPS_REVISION_SCON_SOCIT: 162 case MIPS_REVISION_SCON_ROCIT: 163 case MIPS_REVISION_SCON_SOCITSC: 164 case MIPS_REVISION_SCON_SOCITSCP: 165 ll_msc_irq(); 166 break; 167 case MIPS_REVISION_SCON_GT64120: 168 intrcause = GT_READ(GT_INTRCAUSE_OFS); 169 datalo = GT_READ(GT_CPUERR_ADDRLO_OFS); 170 datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); 171 pr_emerg("GT_INTRCAUSE = %08x\n", intrcause); 172 pr_emerg("GT_CPUERR_ADDR = %02x%08x\n", 173 datahi, datalo); 174 break; 175 case MIPS_REVISION_SCON_BONITO: 176 pcibadaddr = BONITO_PCIBADADDR; 177 pcimstat = BONITO_PCIMSTAT; 178 intisr = BONITO_INTISR; 179 inten = BONITO_INTEN; 180 intpol = BONITO_INTPOL; 181 intedge = BONITO_INTEDGE; 182 intsteer = BONITO_INTSTEER; 183 pcicmd = BONITO_PCICMD; 184 pr_emerg("BONITO_INTISR = %08x\n", intisr); 185 pr_emerg("BONITO_INTEN = %08x\n", inten); 186 pr_emerg("BONITO_INTPOL = %08x\n", intpol); 187 pr_emerg("BONITO_INTEDGE = %08x\n", intedge); 188 pr_emerg("BONITO_INTSTEER = %08x\n", intsteer); 189 pr_emerg("BONITO_PCICMD = %08x\n", pcicmd); 190 pr_emerg("BONITO_PCIBADADDR = %08x\n", pcibadaddr); 191 pr_emerg("BONITO_PCIMSTAT = %08x\n", pcimstat); 192 break; 193 } 194 195 die("CoreHi interrupt", regs); 196 } 197 198 static inline int clz(unsigned long x) 199 { 200 __asm__( 201 " .set push \n" 202 " .set mips32 \n" 203 " clz %0, %1 \n" 204 " .set pop \n" 205 : "=r" (x) 206 : "r" (x)); 207 208 return x; 209 } 210 211 /* 212 * Version of ffs that only looks at bits 12..15. 213 */ 214 static inline unsigned int irq_ffs(unsigned int pending) 215 { 216 #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) 217 return -clz(pending) + 31 - CAUSEB_IP; 218 #else 219 unsigned int a0 = 7; 220 unsigned int t0; 221 222 t0 = pending & 0xf000; 223 t0 = t0 < 1; 224 t0 = t0 << 2; 225 a0 = a0 - t0; 226 pending = pending << t0; 227 228 t0 = pending & 0xc000; 229 t0 = t0 < 1; 230 t0 = t0 << 1; 231 a0 = a0 - t0; 232 pending = pending << t0; 233 234 t0 = pending & 0x8000; 235 t0 = t0 < 1; 236 /* t0 = t0 << 2; */ 237 a0 = a0 - t0; 238 /* pending = pending << t0; */ 239 240 return a0; 241 #endif 242 } 243 244 /* 245 * IRQs on the Malta board look basically (barring software IRQs which we 246 * don't use at all and all external interrupt sources are combined together 247 * on hardware interrupt 0 (MIPS IRQ 2)) like: 248 * 249 * MIPS IRQ Source 250 * -------- ------ 251 * 0 Software (ignored) 252 * 1 Software (ignored) 253 * 2 Combined hardware interrupt (hw0) 254 * 3 Hardware (ignored) 255 * 4 Hardware (ignored) 256 * 5 Hardware (ignored) 257 * 6 Hardware (ignored) 258 * 7 R4k timer (what we use) 259 * 260 * We handle the IRQ according to _our_ priority which is: 261 * 262 * Highest ---- R4k Timer 263 * Lowest ---- Combined hardware interrupt 264 * 265 * then we just return, if multiple IRQs are pending then we will just take 266 * another exception, big deal. 267 */ 268 269 asmlinkage void plat_irq_dispatch(void) 270 { 271 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 272 int irq; 273 274 if (unlikely(!pending)) { 275 spurious_interrupt(); 276 return; 277 } 278 279 irq = irq_ffs(pending); 280 281 if (irq == MIPSCPU_INT_I8259A) 282 malta_hw0_irqdispatch(); 283 else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()])) 284 malta_ipi_irqdispatch(); 285 else 286 do_IRQ(MIPS_CPU_IRQ_BASE + irq); 287 } 288 289 #ifdef CONFIG_MIPS_MT_SMP 290 291 292 #define GIC_MIPS_CPU_IPI_RESCHED_IRQ 3 293 #define GIC_MIPS_CPU_IPI_CALL_IRQ 4 294 295 #define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */ 296 #define C_RESCHED C_SW0 297 #define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for resched */ 298 #define C_CALL C_SW1 299 static int cpu_ipi_resched_irq, cpu_ipi_call_irq; 300 301 static void ipi_resched_dispatch(void) 302 { 303 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ); 304 } 305 306 static void ipi_call_dispatch(void) 307 { 308 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); 309 } 310 311 static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) 312 { 313 #ifdef MIPS_VPE_APSP_API 314 if (aprp_hook) 315 aprp_hook(); 316 #endif 317 318 scheduler_ipi(); 319 320 return IRQ_HANDLED; 321 } 322 323 static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) 324 { 325 smp_call_function_interrupt(); 326 327 return IRQ_HANDLED; 328 } 329 330 static struct irqaction irq_resched = { 331 .handler = ipi_resched_interrupt, 332 .flags = IRQF_PERCPU, 333 .name = "IPI_resched" 334 }; 335 336 static struct irqaction irq_call = { 337 .handler = ipi_call_interrupt, 338 .flags = IRQF_PERCPU, 339 .name = "IPI_call" 340 }; 341 #endif /* CONFIG_MIPS_MT_SMP */ 342 343 static int gic_resched_int_base; 344 static int gic_call_int_base; 345 #define GIC_RESCHED_INT(cpu) (gic_resched_int_base+(cpu)) 346 #define GIC_CALL_INT(cpu) (gic_call_int_base+(cpu)) 347 348 unsigned int plat_ipi_call_int_xlate(unsigned int cpu) 349 { 350 return GIC_CALL_INT(cpu); 351 } 352 353 unsigned int plat_ipi_resched_int_xlate(unsigned int cpu) 354 { 355 return GIC_RESCHED_INT(cpu); 356 } 357 358 static struct irqaction i8259irq = { 359 .handler = no_action, 360 .name = "XT-PIC cascade", 361 .flags = IRQF_NO_THREAD, 362 }; 363 364 static struct irqaction corehi_irqaction = { 365 .handler = no_action, 366 .name = "CoreHi", 367 .flags = IRQF_NO_THREAD, 368 }; 369 370 static msc_irqmap_t msc_irqmap[] __initdata = { 371 {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0}, 372 {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0}, 373 }; 374 static int msc_nr_irqs __initdata = ARRAY_SIZE(msc_irqmap); 375 376 static msc_irqmap_t msc_eicirqmap[] __initdata = { 377 {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0}, 378 {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0}, 379 {MSC01E_INT_I8259A, MSC01_IRQ_LEVEL, 0}, 380 {MSC01E_INT_SMI, MSC01_IRQ_LEVEL, 0}, 381 {MSC01E_INT_COREHI, MSC01_IRQ_LEVEL, 0}, 382 {MSC01E_INT_CORELO, MSC01_IRQ_LEVEL, 0}, 383 {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0}, 384 {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0}, 385 {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0}, 386 {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0} 387 }; 388 389 static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap); 390 391 /* 392 * This GIC specific tabular array defines the association between External 393 * Interrupts and CPUs/Core Interrupts. The nature of the External 394 * Interrupts is also defined here - polarity/trigger. 395 */ 396 397 #define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK 398 #define X GIC_UNUSED 399 400 static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { 401 { X, X, X, X, 0 }, 402 { X, X, X, X, 0 }, 403 { X, X, X, X, 0 }, 404 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 405 { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 406 { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 407 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 408 { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 409 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 410 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 411 { X, X, X, X, 0 }, 412 { X, X, X, X, 0 }, 413 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 414 { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 415 { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 416 { X, X, X, X, 0 }, 417 /* The remainder of this table is initialised by fill_ipi_map */ 418 }; 419 #undef X 420 421 /* 422 * GCMP needs to be detected before any SMP initialisation 423 */ 424 int __init gcmp_probe(unsigned long addr, unsigned long size) 425 { 426 if ((mips_revision_sconid != MIPS_REVISION_SCON_ROCIT) && 427 (mips_revision_sconid != MIPS_REVISION_SCON_GT64120)) { 428 gcmp_present = 0; 429 pr_debug("GCMP NOT present\n"); 430 return gcmp_present; 431 } 432 433 if (gcmp_present >= 0) 434 return gcmp_present; 435 436 _gcmp_base = (unsigned long) ioremap_nocache(GCMP_BASE_ADDR, 437 GCMP_ADDRSPACE_SZ); 438 _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, 439 MSC01_BIU_ADDRSPACE_SZ); 440 gcmp_present = ((GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == 441 GCMP_BASE_ADDR); 442 443 if (gcmp_present) 444 pr_debug("GCMP present\n"); 445 return gcmp_present; 446 } 447 448 /* Return the number of IOCU's present */ 449 int __init gcmp_niocu(void) 450 { 451 return gcmp_present ? ((GCMPGCB(GC) & GCMP_GCB_GC_NUMIOCU_MSK) >> 452 GCMP_GCB_GC_NUMIOCU_SHF) : 0; 453 } 454 455 /* Set GCMP region attributes */ 456 void __init gcmp_setregion(int region, unsigned long base, 457 unsigned long mask, int type) 458 { 459 GCMPGCBn(CMxBASE, region) = base; 460 GCMPGCBn(CMxMASK, region) = mask | type; 461 } 462 463 #if defined(CONFIG_MIPS_MT_SMP) 464 static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) 465 { 466 int intr = baseintr + cpu; 467 gic_intr_map[intr].cpunum = cpu; 468 gic_intr_map[intr].pin = cpupin; 469 gic_intr_map[intr].polarity = GIC_POL_POS; 470 gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; 471 gic_intr_map[intr].flags = GIC_FLAG_IPI; 472 ipi_map[cpu] |= (1 << (cpupin + 2)); 473 } 474 475 static void __init fill_ipi_map(void) 476 { 477 int cpu; 478 479 for (cpu = 0; cpu < nr_cpu_ids; cpu++) { 480 fill_ipi_map1(gic_resched_int_base, cpu, GIC_CPU_INT1); 481 fill_ipi_map1(gic_call_int_base, cpu, GIC_CPU_INT2); 482 } 483 } 484 #endif 485 486 void __init arch_init_ipiirq(int irq, struct irqaction *action) 487 { 488 setup_irq(irq, action); 489 irq_set_handler(irq, handle_percpu_irq); 490 } 491 492 void __init arch_init_irq(void) 493 { 494 init_i8259_irqs(); 495 496 if (!cpu_has_veic) 497 mips_cpu_irq_init(); 498 499 if (gcmp_present) { 500 GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK; 501 gic_present = 1; 502 } else { 503 if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { 504 _msc01_biu_base = (unsigned long) 505 ioremap_nocache(MSC01_BIU_REG_BASE, 506 MSC01_BIU_ADDRSPACE_SZ); 507 gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & 508 MSC01_SC_CFG_GICPRES_MSK) >> 509 MSC01_SC_CFG_GICPRES_SHF; 510 } 511 } 512 if (gic_present) 513 pr_debug("GIC present\n"); 514 515 switch (mips_revision_sconid) { 516 case MIPS_REVISION_SCON_SOCIT: 517 case MIPS_REVISION_SCON_ROCIT: 518 if (cpu_has_veic) 519 init_msc_irqs(MIPS_MSC01_IC_REG_BASE, 520 MSC01E_INT_BASE, msc_eicirqmap, 521 msc_nr_eicirqs); 522 else 523 init_msc_irqs(MIPS_MSC01_IC_REG_BASE, 524 MSC01C_INT_BASE, msc_irqmap, 525 msc_nr_irqs); 526 break; 527 528 case MIPS_REVISION_SCON_SOCITSC: 529 case MIPS_REVISION_SCON_SOCITSCP: 530 if (cpu_has_veic) 531 init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, 532 MSC01E_INT_BASE, msc_eicirqmap, 533 msc_nr_eicirqs); 534 else 535 init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, 536 MSC01C_INT_BASE, msc_irqmap, 537 msc_nr_irqs); 538 } 539 540 if (cpu_has_veic) { 541 set_vi_handler(MSC01E_INT_I8259A, malta_hw0_irqdispatch); 542 set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); 543 setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq); 544 setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction); 545 } else if (cpu_has_vint) { 546 set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); 547 set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch); 548 #ifdef CONFIG_MIPS_MT_SMTC 549 setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq, 550 (0x100 << MIPSCPU_INT_I8259A)); 551 setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, 552 &corehi_irqaction, (0x100 << MIPSCPU_INT_COREHI)); 553 /* 554 * Temporary hack to ensure that the subsidiary device 555 * interrupts coing in via the i8259A, but associated 556 * with low IRQ numbers, will restore the Status.IM 557 * value associated with the i8259A. 558 */ 559 { 560 int i; 561 562 for (i = 0; i < 16; i++) 563 irq_hwmask[i] = (0x100 << MIPSCPU_INT_I8259A); 564 } 565 #else /* Not SMTC */ 566 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); 567 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, 568 &corehi_irqaction); 569 #endif /* CONFIG_MIPS_MT_SMTC */ 570 } else { 571 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); 572 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, 573 &corehi_irqaction); 574 } 575 576 if (gic_present) { 577 /* FIXME */ 578 int i; 579 #if defined(CONFIG_MIPS_MT_SMP) 580 gic_call_int_base = GIC_NUM_INTRS - 581 (NR_CPUS - nr_cpu_ids) * 2 - nr_cpu_ids; 582 gic_resched_int_base = gic_call_int_base - nr_cpu_ids; 583 fill_ipi_map(); 584 #endif 585 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, 586 ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); 587 if (!gcmp_present) { 588 /* Enable the GIC */ 589 i = REG(_msc01_biu_base, MSC01_SC_CFG); 590 REG(_msc01_biu_base, MSC01_SC_CFG) = 591 (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); 592 pr_debug("GIC Enabled\n"); 593 } 594 #if defined(CONFIG_MIPS_MT_SMP) 595 /* set up ipi interrupts */ 596 if (cpu_has_vint) { 597 set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch); 598 set_vi_handler(MIPSCPU_INT_IPI1, malta_ipi_irqdispatch); 599 } 600 /* Argh.. this really needs sorting out.. */ 601 pr_info("CPU%d: status register was %08x\n", 602 smp_processor_id(), read_c0_status()); 603 write_c0_status(read_c0_status() | STATUSF_IP3 | STATUSF_IP4); 604 pr_info("CPU%d: status register now %08x\n", 605 smp_processor_id(), read_c0_status()); 606 write_c0_status(0x1100dc00); 607 pr_info("CPU%d: status register frc %08x\n", 608 smp_processor_id(), read_c0_status()); 609 for (i = 0; i < nr_cpu_ids; i++) { 610 arch_init_ipiirq(MIPS_GIC_IRQ_BASE + 611 GIC_RESCHED_INT(i), &irq_resched); 612 arch_init_ipiirq(MIPS_GIC_IRQ_BASE + 613 GIC_CALL_INT(i), &irq_call); 614 } 615 #endif 616 } else { 617 #if defined(CONFIG_MIPS_MT_SMP) 618 /* set up ipi interrupts */ 619 if (cpu_has_veic) { 620 set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch); 621 set_vi_handler (MSC01E_INT_SW1, ipi_call_dispatch); 622 cpu_ipi_resched_irq = MSC01E_INT_SW0; 623 cpu_ipi_call_irq = MSC01E_INT_SW1; 624 } else { 625 if (cpu_has_vint) { 626 set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, 627 ipi_resched_dispatch); 628 set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, 629 ipi_call_dispatch); 630 } 631 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + 632 MIPS_CPU_IPI_RESCHED_IRQ; 633 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + 634 MIPS_CPU_IPI_CALL_IRQ; 635 } 636 arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched); 637 arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); 638 #endif 639 } 640 } 641 642 void malta_be_init(void) 643 { 644 /* Could change CM error mask register. */ 645 } 646 647 648 static char *tr[8] = { 649 "mem", "gcr", "gic", "mmio", 650 "0x04", "0x05", "0x06", "0x07" 651 }; 652 653 static char *mcmd[32] = { 654 [0x00] = "0x00", 655 [0x01] = "Legacy Write", 656 [0x02] = "Legacy Read", 657 [0x03] = "0x03", 658 [0x04] = "0x04", 659 [0x05] = "0x05", 660 [0x06] = "0x06", 661 [0x07] = "0x07", 662 [0x08] = "Coherent Read Own", 663 [0x09] = "Coherent Read Share", 664 [0x0a] = "Coherent Read Discard", 665 [0x0b] = "Coherent Ready Share Always", 666 [0x0c] = "Coherent Upgrade", 667 [0x0d] = "Coherent Writeback", 668 [0x0e] = "0x0e", 669 [0x0f] = "0x0f", 670 [0x10] = "Coherent Copyback", 671 [0x11] = "Coherent Copyback Invalidate", 672 [0x12] = "Coherent Invalidate", 673 [0x13] = "Coherent Write Invalidate", 674 [0x14] = "Coherent Completion Sync", 675 [0x15] = "0x15", 676 [0x16] = "0x16", 677 [0x17] = "0x17", 678 [0x18] = "0x18", 679 [0x19] = "0x19", 680 [0x1a] = "0x1a", 681 [0x1b] = "0x1b", 682 [0x1c] = "0x1c", 683 [0x1d] = "0x1d", 684 [0x1e] = "0x1e", 685 [0x1f] = "0x1f" 686 }; 687 688 static char *core[8] = { 689 "Invalid/OK", "Invalid/Data", 690 "Shared/OK", "Shared/Data", 691 "Modified/OK", "Modified/Data", 692 "Exclusive/OK", "Exclusive/Data" 693 }; 694 695 static char *causes[32] = { 696 "None", "GC_WR_ERR", "GC_RD_ERR", "COH_WR_ERR", 697 "COH_RD_ERR", "MMIO_WR_ERR", "MMIO_RD_ERR", "0x07", 698 "0x08", "0x09", "0x0a", "0x0b", 699 "0x0c", "0x0d", "0x0e", "0x0f", 700 "0x10", "0x11", "0x12", "0x13", 701 "0x14", "0x15", "0x16", "INTVN_WR_ERR", 702 "INTVN_RD_ERR", "0x19", "0x1a", "0x1b", 703 "0x1c", "0x1d", "0x1e", "0x1f" 704 }; 705 706 int malta_be_handler(struct pt_regs *regs, int is_fixup) 707 { 708 /* This duplicates the handling in do_be which seems wrong */ 709 int retval = is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL; 710 711 if (gcmp_present) { 712 unsigned long cm_error = GCMPGCB(GCMEC); 713 unsigned long cm_addr = GCMPGCB(GCMEA); 714 unsigned long cm_other = GCMPGCB(GCMEO); 715 unsigned long cause, ocause; 716 char buf[256]; 717 718 cause = (cm_error & GCMP_GCB_GMEC_ERROR_TYPE_MSK); 719 if (cause != 0) { 720 cause >>= GCMP_GCB_GMEC_ERROR_TYPE_SHF; 721 if (cause < 16) { 722 unsigned long cca_bits = (cm_error >> 15) & 7; 723 unsigned long tr_bits = (cm_error >> 12) & 7; 724 unsigned long cmd_bits = (cm_error >> 7) & 0x1f; 725 unsigned long stag_bits = (cm_error >> 3) & 15; 726 unsigned long sport_bits = (cm_error >> 0) & 7; 727 728 snprintf(buf, sizeof(buf), 729 "CCA=%lu TR=%s MCmd=%s STag=%lu " 730 "SPort=%lu\n", 731 cca_bits, tr[tr_bits], mcmd[cmd_bits], 732 stag_bits, sport_bits); 733 } else { 734 /* glob state & sresp together */ 735 unsigned long c3_bits = (cm_error >> 18) & 7; 736 unsigned long c2_bits = (cm_error >> 15) & 7; 737 unsigned long c1_bits = (cm_error >> 12) & 7; 738 unsigned long c0_bits = (cm_error >> 9) & 7; 739 unsigned long sc_bit = (cm_error >> 8) & 1; 740 unsigned long cmd_bits = (cm_error >> 3) & 0x1f; 741 unsigned long sport_bits = (cm_error >> 0) & 7; 742 snprintf(buf, sizeof(buf), 743 "C3=%s C2=%s C1=%s C0=%s SC=%s " 744 "MCmd=%s SPort=%lu\n", 745 core[c3_bits], core[c2_bits], 746 core[c1_bits], core[c0_bits], 747 sc_bit ? "True" : "False", 748 mcmd[cmd_bits], sport_bits); 749 } 750 751 ocause = (cm_other & GCMP_GCB_GMEO_ERROR_2ND_MSK) >> 752 GCMP_GCB_GMEO_ERROR_2ND_SHF; 753 754 pr_err("CM_ERROR=%08lx %s <%s>\n", cm_error, 755 causes[cause], buf); 756 pr_err("CM_ADDR =%08lx\n", cm_addr); 757 pr_err("CM_OTHER=%08lx %s\n", cm_other, causes[ocause]); 758 759 /* reprime cause register */ 760 GCMPGCB(GCMEC) = 0; 761 } 762 } 763 764 return retval; 765 } 766 767 void gic_enable_interrupt(int irq_vec) 768 { 769 GIC_SET_INTR_MASK(irq_vec); 770 } 771 772 void gic_disable_interrupt(int irq_vec) 773 { 774 GIC_CLR_INTR_MASK(irq_vec); 775 } 776 777 void gic_irq_ack(struct irq_data *d) 778 { 779 int irq = (d->irq - gic_irq_base); 780 781 GIC_CLR_INTR_MASK(irq); 782 783 if (gic_irq_flags[irq] & GIC_TRIG_EDGE) 784 GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); 785 } 786 787 void gic_finish_irq(struct irq_data *d) 788 { 789 /* Enable interrupts. */ 790 GIC_SET_INTR_MASK(d->irq - gic_irq_base); 791 } 792 793 void __init gic_platform_init(int irqs, struct irq_chip *irq_controller) 794 { 795 int i; 796 797 for (i = gic_irq_base; i < (gic_irq_base + irqs); i++) 798 irq_set_chip(i, irq_controller); 799 } 800