#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/extable.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <asm/fpu.h>
#include <asm/fpu_emulator.h>
#include <asm/idle.h>
+#include <asm/mips-cm.h>
#include <asm/mips-r2-to-r6-emul.h>
#include <asm/mipsregs.h>
#include <asm/mipsmtregs.h>
print_ip_sym(pc);
pc = unwind_stack(task, &sp, pc, &ra);
} while (pc);
- printk("\n");
+ pr_cont("\n");
}
/*
printk("Stack :");
i = 0;
while ((unsigned long) sp & (PAGE_SIZE - 1)) {
- if (i && ((i % (64 / field)) == 0))
- printk("\n ");
+ if (i && ((i % (64 / field)) == 0)) {
+ pr_cont("\n");
+ printk(" ");
+ }
if (i > 39) {
- printk(" ...");
+ pr_cont(" ...");
break;
}
if (__get_user(stackdata, sp++)) {
- printk(" (Bad stack address)");
+ pr_cont(" (Bad stack address)");
break;
}
- printk(" %0*lx", field, stackdata);
+ pr_cont(" %0*lx", field, stackdata);
i++;
}
- printk("\n");
+ pr_cont("\n");
show_backtrace(task, regs);
}
if (board_be_handler)
action = board_be_handler(regs, fixup != NULL);
+ else
+ mips_cm_error_report();
switch (action) {
case MIPS_BE_DISCARD:
{
if (cpu_has_veic || cpu_has_vint) {
unsigned long sr = set_c0_status(ST0_BEV);
+ /* If available, use WG to set top bits of EBASE */
+ if (cpu_has_ebase_wg) {
+#ifdef CONFIG_64BIT
+ write_c0_ebase_64(ebase | MIPS_EBASE_WG);
+#else
+ write_c0_ebase(ebase | MIPS_EBASE_WG);
+#endif
+ }
write_c0_ebase(ebase);
write_c0_status(sr);
/* Setting vector spacing enables EI/VI mode */
* We shouldn't trust a secondary core has a sane EBASE register
* so use the one calculated by the boot CPU.
*/
- if (!is_boot_cpu)
+ if (!is_boot_cpu) {
+ /* If available, use WG to set top bits of EBASE */
+ if (cpu_has_ebase_wg) {
+#ifdef CONFIG_64BIT
+ write_c0_ebase_64(ebase | MIPS_EBASE_WG);
+#else
+ write_c0_ebase(ebase | MIPS_EBASE_WG);
+#endif
+ }
write_c0_ebase(ebase);
+ }
cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
if (cpu_has_veic || cpu_has_vint) {
unsigned long size = 0x200 + VECTORSPACING*64;
+ phys_addr_t ebase_pa;
+
ebase = (unsigned long)
__alloc_bootmem(size, 1 << fls(size), 0);
+
+ /*
+ * Try to ensure ebase resides in KSeg0 if possible.
+ *
+ * It shouldn't generally be in XKPhys on MIPS64 to avoid
+ * hitting a poorly defined exception base for Cache Errors.
+ * The allocation is likely to be in the low 512MB of physical,
+ * in which case we should be able to convert to KSeg0.
+ *
+ * EVA is special though as it allows segments to be rearranged
+ * and to become uncached during cache error handling.
+ */
+ ebase_pa = __pa(ebase);
+ if (!IS_ENABLED(CONFIG_EVA) && !WARN_ON(ebase_pa >= 0x20000000))
+ ebase = CKSEG0ADDR(ebase_pa);
} else {
ebase = CAC_BASE;
- if (cpu_has_mips_r2_r6)
- ebase += (read_c0_ebase() & 0x3ffff000);
+ if (cpu_has_mips_r2_r6) {
+ if (cpu_has_ebase_wg) {
+#ifdef CONFIG_64BIT
+ ebase = (read_c0_ebase_64() & ~0xfff);
+#else
+ ebase = (read_c0_ebase() & ~0xfff);
+#endif
+ } else {
+ ebase += (read_c0_ebase() & 0x3ffff000);
+ }
+ }
}
if (cpu_has_mmips) {