diff options
author | Robin Getz <robin.getz@analog.com> | 2007-10-09 17:31:46 +0800 |
---|---|---|
committer | Bryan Wu <bryan.wu@analog.com> | 2007-10-09 17:31:46 +0800 |
commit | 337d390b3a9c1ce92a12bdb77b9ae6ded6273b12 (patch) | |
tree | 2c870e325162c3d1a66390fb6d6db3e92de9e2eb | |
parent | ce3afa1c043ab3d4125671441a57353d80f5f6f7 (diff) |
Blackfin arch: Print out debug info, as early as possible
Print out debug info, as early as possible - even before the
kernel initializes the interrupt vectors. Now we can print out debug
messages almost anytime during the boot process.
Signed-off-by: Robin Getz <robin.getz@analog.com>
Signed-off-by: Bryan Wu <bryan.wu@analog.com>
-rw-r--r-- | arch/blackfin/kernel/early_printk.c | 61 | ||||
-rw-r--r-- | arch/blackfin/mach-bf533/head.S | 6 | ||||
-rw-r--r-- | arch/blackfin/mach-bf537/head.S | 6 | ||||
-rw-r--r-- | arch/blackfin/mach-bf548/head.S | 6 | ||||
-rw-r--r-- | arch/blackfin/mach-bf561/head.S | 6 | ||||
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 43 | ||||
-rw-r--r-- | include/asm-blackfin/irq_handler.h | 1 |
7 files changed, 123 insertions, 6 deletions
diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c index 9bf61706694..6ec518a8111 100644 --- a/arch/blackfin/kernel/early_printk.c +++ b/arch/blackfin/kernel/early_printk.c @@ -38,13 +38,13 @@ extern struct console *bfin_earlyserial_init(unsigned int port, static struct console *early_console; -/* Default console - * Port n == ttyBFn - * cflags == UART output modes - */ +/* Default console */ #define DEFAULT_PORT 0 #define DEFAULT_CFLAG CS8|B57600 +/* Default console for early crashes */ +#define DEFAULT_EARLY_PORT "serial,uart0,57600" + #ifdef CONFIG_SERIAL_CORE /* What should get here is "0,57600" */ static struct console * __init earlyserial_init(char *buf) @@ -158,4 +158,57 @@ int __init setup_early_printk(char *buf) return 0; } +/* + * Set up a temporary Event Vector Table, so if something bad happens before + * the kernel is fully started, it doesn't vector off into somewhere we don't + * know + */ + +asmlinkage void __init init_early_exception_vectors(void) +{ + SSYNC(); + + /* cannot program in software: + * evt0 - emulation (jtag) + * evt1 - reset + */ + bfin_write_EVT2(early_trap); + bfin_write_EVT3(early_trap); + bfin_write_EVT5(early_trap); + bfin_write_EVT6(early_trap); + bfin_write_EVT7(early_trap); + bfin_write_EVT8(early_trap); + bfin_write_EVT9(early_trap); + bfin_write_EVT10(early_trap); + bfin_write_EVT11(early_trap); + bfin_write_EVT12(early_trap); + bfin_write_EVT13(early_trap); + bfin_write_EVT14(early_trap); + bfin_write_EVT15(early_trap); + CSYNC(); + + /* Set all the return from interupt, exception, NMI to a known place + * so if we do a RETI, RETX or RETN by mistake - we go somewhere known + * Note - don't change RETS - we are in a subroutine, or + * RETE - since it might screw up if emulator is attached + */ + asm("\tRETI = %0; RETX = %0; RETN = %0;\n" + : : "p"(early_trap)); + +} + +asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr) +{ + /* This can happen before the uart is initialized, so initialize + * the UART now + */ + if (likely(early_console == NULL)) + setup_early_printk(DEFAULT_EARLY_PORT); + + dump_bfin_regs(fp, retaddr); + dump_bfin_trace_buffer(); + + panic("Died early"); +} + early_param("earlyprintk", setup_early_printk); diff --git a/arch/blackfin/mach-bf533/head.S b/arch/blackfin/mach-bf533/head.S index fa6dc0d8593..1ded945a6fa 100644 --- a/arch/blackfin/mach-bf533/head.S +++ b/arch/blackfin/mach-bf533/head.S @@ -181,6 +181,12 @@ ENTRY(__start) fp = sp; usp = sp; +#ifdef CONFIG_EARLY_PRINTK + SP += -12; + call _init_early_exception_vectors; + SP += 12; +#endif + /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ call _bf53x_relocate_l1_mem; #if CONFIG_BFIN_KERNEL_CLOCK diff --git a/arch/blackfin/mach-bf537/head.S b/arch/blackfin/mach-bf537/head.S index 2c4ae466d4e..3014fe8dd15 100644 --- a/arch/blackfin/mach-bf537/head.S +++ b/arch/blackfin/mach-bf537/head.S @@ -224,6 +224,12 @@ ENTRY(__start) fp = sp; usp = sp; +#ifdef CONFIG_EARLY_PRINTK + SP += -12; + call _init_early_exception_vectors; + SP += 12; +#endif + /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ call _bf53x_relocate_l1_mem; #if CONFIG_BFIN_KERNEL_CLOCK diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S index 532ed0930b5..3071c243d42 100644 --- a/arch/blackfin/mach-bf548/head.S +++ b/arch/blackfin/mach-bf548/head.S @@ -125,6 +125,12 @@ ENTRY(__stext) FP = SP; USP = SP; +#ifdef CONFIG_EARLY_PRINTK + SP += -12; + call _init_early_exception_vectors; + SP += 12; +#endif + /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ call _bf53x_relocate_l1_mem; #if CONFIG_BFIN_KERNEL_CLOCK diff --git a/arch/blackfin/mach-bf561/head.S b/arch/blackfin/mach-bf561/head.S index fd39891ae0f..96a3d456fb6 100644 --- a/arch/blackfin/mach-bf561/head.S +++ b/arch/blackfin/mach-bf561/head.S @@ -169,6 +169,12 @@ ENTRY(__start) fp = sp; usp = sp; +#ifdef CONFIG_EARLY_PRINTK + SP += -12; + call _init_early_exception_vectors; + SP += 12; +#endif + /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ call _bf53x_relocate_l1_mem; #if CONFIG_BFIN_KERNEL_CLOCK diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index e2239361cac..a56b231d94c 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -835,12 +835,13 @@ ENTRY(_ex_trace_buff_full) P2 = [sp++]; P3 = [sp++]; jump _return_from_exception; +ENDPROC(_ex_trace_buff_full) #if CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN == 4 .data #else .section .l1.data.B -#endif +#endif /* CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN */ ENTRY(_trace_buff_offset) .long 0; ALIGN @@ -848,7 +849,45 @@ ENTRY(_software_trace_buff) .rept ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN)*256); .long 0 .endr -#endif +#endif /* CONFIG_DEBUG_BFIN_HWTRACE_EXPAND */ + +#if CONFIG_EARLY_PRINTK +.section .init.text +ENTRY(_early_trap) + SAVE_ALL_SYS + trace_buffer_stop(p0,r0); + + /* Turn caches off, to ensure we don't get double exceptions */ + + P4.L = LO(IMEM_CONTROL); + P4.H = HI(IMEM_CONTROL); + + R5 = [P4]; /* Control Register*/ + BITCLR(R5,ENICPLB_P); + CLI R1; + SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ + .align 8; + [P4] = R5; + SSYNC; + + P4.L = LO(DMEM_CONTROL); + P4.H = HI(DMEM_CONTROL); + R5 = [P4]; + BITCLR(R5,ENDCPLB_P); + SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ + .align 8; + [P4] = R5; + SSYNC; + STI R1; + + r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ + r1 = RETX; + + SP += -12; + call _early_trap_c; + SP += 12; +ENDPROC(_early_trap) +#endif /* CONFIG_EARLY_PRINTK */ /* * Put these in the kernel data section - that should always be covered by diff --git a/include/asm-blackfin/irq_handler.h b/include/asm-blackfin/irq_handler.h index 19534c133c9..139b5208f9d 100644 --- a/include/asm-blackfin/irq_handler.h +++ b/include/asm-blackfin/irq_handler.h @@ -22,6 +22,7 @@ asmlinkage void evt_system_call(void); asmlinkage void init_exception_buff(void); asmlinkage void trap_c(struct pt_regs *fp); asmlinkage void ex_replaceable(void); +asmlinkage void early_trap(void); extern void *ex_table[]; extern void return_from_exception(void); |