Blackfin arch: add supporting for double fault debug handling
[pandora-kernel.git] / arch / blackfin / kernel / setup.c
index 23e637e..8e639dc 100644 (file)
@@ -52,6 +52,8 @@ EXPORT_SYMBOL(mtd_size);
 #endif
 
 char __initdata command_line[COMMAND_LINE_SIZE];
+void __initdata *init_retx, *init_saved_retx, *init_saved_seqstat,
+       *init_saved_icplb_fault_addr, *init_saved_dcplb_fault_addr;
 
 /* boot memmap, for parsing "memmap=" */
 #define BFIN_MEMMAP_MAX                128 /* number of entries in bfin_memmap */
@@ -131,14 +133,14 @@ void __init bf53x_relocate_l1_mem(void)
        dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length +
                        l1_data_a_length, l1_data_b_length);
 
-#ifdef L2_LENGTH
-       l2_length = _ebss_l2 - _stext_l2;
-       if (l2_length > L2_LENGTH)
-               panic("L2 SRAM Overflow\n");
+       if (L2_LENGTH != 0) {
+               l2_length = _ebss_l2 - _stext_l2;
+               if (l2_length > L2_LENGTH)
+                       panic("L2 SRAM Overflow\n");
 
-       /* Copy _stext_l2 to _edata_l2 to L2 SRAM */
-       dma_memcpy(_stext_l2, _l2_lma_start, l2_length);
-#endif
+               /* Copy _stext_l2 to _edata_l2 to L2 SRAM */
+               dma_memcpy(_stext_l2, _l2_lma_start, l2_length);
+       }
 }
 
 /* add_memory_region to memmap */
@@ -738,6 +740,16 @@ void __init setup_arch(char **cmdline_p)
 
        memory_setup();
 
+       /* Initialize Async memory banks */
+       bfin_write_EBIU_AMBCTL0(AMBCTL0VAL);
+       bfin_write_EBIU_AMBCTL1(AMBCTL1VAL);
+       bfin_write_EBIU_AMGCTL(AMGCTLVAL);
+#ifdef CONFIG_EBIU_MBSCTLVAL
+       bfin_write_EBIU_MBSCTL(CONFIG_EBIU_MBSCTLVAL);
+       bfin_write_EBIU_MODE(CONFIG_EBIU_MODEVAL);
+       bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTLVAL);
+#endif
+
        cclk = get_cclk();
        sclk = get_sclk();
 
@@ -771,12 +783,25 @@ void __init setup_arch(char **cmdline_p)
 
        _bfin_swrst = bfin_read_SWRST();
 
-       /* If we double fault, reset the system - otherwise we hang forever */
-       bfin_write_SWRST(DOUBLE_FAULT);
+#ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT
+       bfin_write_SWRST(_bfin_swrst & ~DOUBLE_FAULT);
+#endif
+#ifdef CONFIG_DEBUG_DOUBLEFAULT_RESET
+       bfin_write_SWRST(_bfin_swrst | DOUBLE_FAULT);
+#endif
 
-       if (_bfin_swrst & RESET_DOUBLE)
-               printk(KERN_INFO "Recovering from Double Fault event\n");
-       else if (_bfin_swrst & RESET_WDOG)
+       if (_bfin_swrst & RESET_DOUBLE) {
+               printk(KERN_EMERG "Recovering from DOUBLE FAULT event\n");
+#ifdef CONFIG_DEBUG_DOUBLEFAULT
+               /* We assume the crashing kernel, and the current symbol table match */
+               printk(KERN_EMERG " While handling exception (EXCAUSE = 0x%x) at %pF\n",
+                       (int)init_saved_seqstat & SEQSTAT_EXCAUSE, init_saved_retx);
+               printk(KERN_NOTICE "   DCPLB_FAULT_ADDR: %pF\n", init_saved_dcplb_fault_addr);
+               printk(KERN_NOTICE "   ICPLB_FAULT_ADDR: %pF\n", init_saved_icplb_fault_addr);
+#endif
+               printk(KERN_NOTICE " The instruction at %pF caused a double exception\n",
+                       init_retx);
+       } else if (_bfin_swrst & RESET_WDOG)
                printk(KERN_INFO "Recovering from Watchdog event\n");
        else if (_bfin_swrst & RESET_SOFTWARE)
                printk(KERN_NOTICE "Reset caused by Software reset\n");
@@ -1049,7 +1074,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                   dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS,
                   BFIN_DLINES);
 #ifdef CONFIG_BFIN_ICACHE_LOCK
-       switch (read_iloc()) {
+       switch ((bfin_read_IMEM_CONTROL() >> 3) & WAYALL_L) {
        case WAY0_L:
                seq_printf(m, "Way0 Locked-Down\n");
                break;