Commit 49555a7c authored by Anton Blanchard's avatar Anton Blanchard

[PATCH] cleanup debugger hooks

Theres still more to do here, but at least the ifdef mess is gone. No
more checking for NULL before calling functions, that was playing with
fire. Oh yeah and lots more deletions :)

Clean up the debugger hooks, it was way too easy to screw up.
And we did. And Linus hit it.

- create CONFIG_DEBUGGER so we can enable kernel debugging options but not
  have any trace of debugger gunk.
- remove a bunch of xmon prototypes so no one gets the urge to call them
- Use die() instead of panic in a number of places, it gives us much better
  debug information.
- Get rid of the ifdef madness
parent 2d1eb995
...@@ -356,9 +356,16 @@ config MAGIC_SYSRQ ...@@ -356,9 +356,16 @@ config MAGIC_SYSRQ
keys are documented in <file:Documentation/sysrq.txt>. Don't say Y keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
unless you really know what this hack does. unless you really know what this hack does.
config DEBUGGER
bool "Enable debugger hooks"
depends on DEBUG_KERNEL
help
Include in-kernel hooks for kernel debuggers. Unless you are
intending to debug the kernel, say N here.
config XMON config XMON
bool "Include xmon kernel debugger" bool "Include xmon kernel debugger"
depends on DEBUG_KERNEL depends on DEBUGGER
help help
Include in-kernel hooks for the xmon kernel monitor/debugger. Include in-kernel hooks for the xmon kernel monitor/debugger.
Unless you are intending to debug the kernel, say N here. Unless you are intending to debug the kernel, say N here.
......
...@@ -645,9 +645,9 @@ void openpic_request_IPIs(void) ...@@ -645,9 +645,9 @@ void openpic_request_IPIs(void)
request_irq(openpic_vec_ipi+1, openpic_ipi_action, SA_INTERRUPT, request_irq(openpic_vec_ipi+1, openpic_ipi_action, SA_INTERRUPT,
"IPI1 (reschedule)", 0); "IPI1 (reschedule)", 0);
request_irq(openpic_vec_ipi+2, openpic_ipi_action, SA_INTERRUPT, request_irq(openpic_vec_ipi+2, openpic_ipi_action, SA_INTERRUPT,
"IPI2 (invalidate tlb)", 0); "IPI2 (unused)", 0);
request_irq(openpic_vec_ipi+3, openpic_ipi_action, SA_INTERRUPT, request_irq(openpic_vec_ipi+3, openpic_ipi_action, SA_INTERRUPT,
"IPI3 (xmon break)", 0); "IPI3 (debugger break)", 0);
for ( i = 0; i < OPENPIC_NUM_IPI ; i++ ) for ( i = 0; i < OPENPIC_NUM_IPI ; i++ )
openpic_enable_ipi(openpic_vec_ipi+i); openpic_enable_ipi(openpic_vec_ipi+i);
......
...@@ -206,25 +206,6 @@ EXPORT_SYMBOL(timer_interrupt); ...@@ -206,25 +206,6 @@ EXPORT_SYMBOL(timer_interrupt);
EXPORT_SYMBOL(irq_desc); EXPORT_SYMBOL(irq_desc);
EXPORT_SYMBOL(get_wchan); EXPORT_SYMBOL(get_wchan);
EXPORT_SYMBOL(console_drivers); EXPORT_SYMBOL(console_drivers);
#ifdef CONFIG_XMON
EXPORT_SYMBOL(xmon);
#endif
#ifdef CONFIG_DEBUG_KERNEL
extern void (*debugger)(struct pt_regs *regs);
extern int (*debugger_bpt)(struct pt_regs *regs);
extern int (*debugger_sstep)(struct pt_regs *regs);
extern int (*debugger_iabr_match)(struct pt_regs *regs);
extern int (*debugger_dabr_match)(struct pt_regs *regs);
extern void (*debugger_fault_handler)(struct pt_regs *regs);
EXPORT_SYMBOL(debugger);
EXPORT_SYMBOL(debugger_bpt);
EXPORT_SYMBOL(debugger_sstep);
EXPORT_SYMBOL(debugger_iabr_match);
EXPORT_SYMBOL(debugger_dabr_match);
EXPORT_SYMBOL(debugger_fault_handler);
#endif
EXPORT_SYMBOL(tb_ticks_per_usec); EXPORT_SYMBOL(tb_ticks_per_usec);
EXPORT_SYMBOL(paca); EXPORT_SYMBOL(paca);
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/btext.h> #include <asm/btext.h>
#include <asm/nvram.h> #include <asm/nvram.h>
#include <asm/system.h>
extern unsigned long klimit; extern unsigned long klimit;
/* extern void *stab; */ /* extern void *stab; */
...@@ -79,10 +80,6 @@ unsigned long decr_overclock_proc0_set = 0; ...@@ -79,10 +80,6 @@ unsigned long decr_overclock_proc0_set = 0;
int powersave_nap; int powersave_nap;
#ifdef CONFIG_XMON
extern void xmon_map_scc(void);
#endif
char saved_command_line[256]; char saved_command_line[256];
unsigned char aux_device_present; unsigned char aux_device_present;
...@@ -163,11 +160,7 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -163,11 +160,7 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
#endif #endif
#ifdef CONFIG_XMON_DEFAULT #ifdef CONFIG_XMON_DEFAULT
debugger = xmon; xmon_init();
debugger_bpt = xmon_bpt;
debugger_sstep = xmon_sstep;
debugger_iabr_match = xmon_iabr_match;
debugger_dabr_match = xmon_dabr_match;
#endif #endif
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
...@@ -601,13 +594,15 @@ void __init setup_arch(char **cmdline_p) ...@@ -601,13 +594,15 @@ void __init setup_arch(char **cmdline_p)
calibrate_delay = ppc64_calibrate_delay; calibrate_delay = ppc64_calibrate_delay;
ppc64_boot_msg(0x12, "Setup Arch"); ppc64_boot_msg(0x12, "Setup Arch");
#ifdef CONFIG_XMON #ifdef CONFIG_XMON
xmon_map_scc(); if (strstr(cmd_line, "xmon")) {
if (strstr(cmd_line, "xmon")) /* ensure xmon is enabled */
xmon(0); xmon_init();
debugger(0);
}
#endif /* CONFIG_XMON */ #endif /* CONFIG_XMON */
/* /*
* Set cache line size based on type of cpu as a default. * Set cache line size based on type of cpu as a default.
* Systems with OF can look in the properties on the cpu node(s) * Systems with OF can look in the properties on the cpu node(s)
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/xics.h> #include <asm/xics.h>
#include <asm/cputable.h> #include <asm/cputable.h>
#include <asm/system.h>
int smp_threads_ready; int smp_threads_ready;
unsigned long cache_decay_ticks; unsigned long cache_decay_ticks;
...@@ -394,7 +395,7 @@ void smp_local_timer_interrupt(struct pt_regs * regs) ...@@ -394,7 +395,7 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
void smp_message_recv(int msg, struct pt_regs *regs) void smp_message_recv(int msg, struct pt_regs *regs)
{ {
switch( msg ) { switch(msg) {
case PPC_MSG_CALL_FUNCTION: case PPC_MSG_CALL_FUNCTION:
smp_call_function_interrupt(); smp_call_function_interrupt();
break; break;
...@@ -407,11 +408,11 @@ void smp_message_recv(int msg, struct pt_regs *regs) ...@@ -407,11 +408,11 @@ void smp_message_recv(int msg, struct pt_regs *regs)
/* spare */ /* spare */
break; break;
#endif #endif
#ifdef CONFIG_XMON #ifdef CONFIG_DEBUGGER
case PPC_MSG_XMON_BREAK: case PPC_MSG_DEBUGGER_BREAK:
xmon(regs); debugger(regs);
break; break;
#endif /* CONFIG_XMON */ #endif
default: default:
printk("SMP %d: smp_message_recv(): unknown msg %d\n", printk("SMP %d: smp_message_recv(): unknown msg %d\n",
smp_processor_id(), msg); smp_processor_id(), msg);
...@@ -424,12 +425,12 @@ void smp_send_reschedule(int cpu) ...@@ -424,12 +425,12 @@ void smp_send_reschedule(int cpu)
smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0); smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0);
} }
#ifdef CONFIG_XMON #ifdef CONFIG_DEBUGGER
void smp_send_xmon_break(int cpu) void smp_send_debugger_break(int cpu)
{ {
smp_message_pass(cpu, PPC_MSG_XMON_BREAK, 0, 0); smp_message_pass(cpu, PPC_MSG_DEBUGGER_BREAK, 0, 0);
} }
#endif /* CONFIG_XMON */ #endif
static void stop_this_cpu(void *dummy) static void stop_this_cpu(void *dummy)
{ {
...@@ -507,10 +508,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, ...@@ -507,10 +508,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
printk("smp_call_function on cpu %d: other cpus not " printk("smp_call_function on cpu %d: other cpus not "
"responding (%d)\n", smp_processor_id(), "responding (%d)\n", smp_processor_id(),
atomic_read(&data.started)); atomic_read(&data.started));
#ifdef CONFIG_DEBUG_KERNEL
if (debugger)
debugger(0); debugger(0);
#endif
goto out; goto out;
} }
} }
...@@ -525,10 +523,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, ...@@ -525,10 +523,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
smp_processor_id(), smp_processor_id(),
atomic_read(&data.finished), atomic_read(&data.finished),
atomic_read(&data.started)); atomic_read(&data.started));
#ifdef CONFIG_DEBUG_KERNEL
if (debugger)
debugger(0); debugger(0);
#endif
goto out; goto out;
} }
} }
......
...@@ -45,13 +45,20 @@ extern void bad_page_fault(struct pt_regs *, unsigned long, int); ...@@ -45,13 +45,20 @@ extern void bad_page_fault(struct pt_regs *, unsigned long, int);
extern int fwnmi_active; extern int fwnmi_active;
#endif #endif
#ifdef CONFIG_DEBUG_KERNEL #ifdef CONFIG_DEBUGGER
void (*debugger)(struct pt_regs *regs); int (*__debugger)(struct pt_regs *regs);
int (*debugger_bpt)(struct pt_regs *regs); int (*__debugger_bpt)(struct pt_regs *regs);
int (*debugger_sstep)(struct pt_regs *regs); int (*__debugger_sstep)(struct pt_regs *regs);
int (*debugger_iabr_match)(struct pt_regs *regs); int (*__debugger_iabr_match)(struct pt_regs *regs);
int (*debugger_dabr_match)(struct pt_regs *regs); int (*__debugger_dabr_match)(struct pt_regs *regs);
void (*debugger_fault_handler)(struct pt_regs *regs); int (*__debugger_fault_handler)(struct pt_regs *regs);
EXPORT_SYMBOL(__debugger);
EXPORT_SYMBOL(__debugger_bpt);
EXPORT_SYMBOL(__debugger_sstep);
EXPORT_SYMBOL(__debugger_iabr_match);
EXPORT_SYMBOL(__debugger_dabr_match);
EXPORT_SYMBOL(__debugger_fault_handler);
#endif #endif
/* /*
...@@ -88,11 +95,9 @@ static void ...@@ -88,11 +95,9 @@ static void
_exception(int signr, siginfo_t *info, struct pt_regs *regs) _exception(int signr, siginfo_t *info, struct pt_regs *regs)
{ {
if (!user_mode(regs)) { if (!user_mode(regs)) {
#ifdef CONFIG_DEBUG_KERNEL if (debugger(regs))
if (debugger) return;
debugger(regs); die("Exception in kernel mode\n", regs, signr);
#endif
die("Exception in kernel mode", regs, signr);
} }
force_sig_info(signr, info, current); force_sig_info(signr, info, current);
...@@ -146,12 +151,8 @@ SystemResetException(struct pt_regs *regs) ...@@ -146,12 +151,8 @@ SystemResetException(struct pt_regs *regs)
} }
#endif #endif
#ifdef CONFIG_DEBUG_KERNEL if (!debugger(regs))
if (debugger) die("System Reset", regs, 0);
debugger(regs);
else
#endif
panic("System Reset");
/* Must die if the interrupt is not recoverable */ /* Must die if the interrupt is not recoverable */
if (!(regs->msr & MSR_RI)) if (!(regs->msr & MSR_RI))
...@@ -228,23 +229,12 @@ MachineCheckException(struct pt_regs *regs) ...@@ -228,23 +229,12 @@ MachineCheckException(struct pt_regs *regs)
} }
#endif #endif
#ifdef CONFIG_DEBUG_KERNEL if (debugger_fault_handler(regs))
if (debugger_fault_handler) {
debugger_fault_handler(regs);
return; return;
} if (debugger(regs))
if (debugger) return;
debugger(regs);
#endif die("Machine check in kernel mode", regs, 0);
console_verbose();
spin_lock_irq(&die_lock);
bust_spinlocks(1);
printk("Machine check in kernel mode.\n");
printk("Caused by (from SRR1=%lx): ", regs->msr);
show_regs(regs);
bust_spinlocks(0);
spin_unlock_irq(&die_lock);
panic("Unrecoverable Machine Check");
} }
void void
...@@ -267,10 +257,8 @@ InstructionBreakpointException(struct pt_regs *regs) ...@@ -267,10 +257,8 @@ InstructionBreakpointException(struct pt_regs *regs)
{ {
siginfo_t info; siginfo_t info;
#ifdef CONFIG_DEBUG_KERNEL if (debugger_iabr_match(regs))
if (debugger_iabr_match && debugger_iabr_match(regs))
return; return;
#endif
info.si_signo = SIGTRAP; info.si_signo = SIGTRAP;
info.si_errno = 0; info.si_errno = 0;
info.si_code = TRAP_BRKPT; info.si_code = TRAP_BRKPT;
...@@ -372,12 +360,8 @@ ProgramCheckException(struct pt_regs *regs) ...@@ -372,12 +360,8 @@ ProgramCheckException(struct pt_regs *regs)
{ {
siginfo_t info; siginfo_t info;
#ifdef CONFIG_DEBUG_KERNEL if (debugger_fault_handler(regs))
if (debugger_fault_handler) {
debugger_fault_handler(regs);
return; return;
}
#endif
if (regs->msr & 0x100000) { if (regs->msr & 0x100000) {
/* IEEE FP exception */ /* IEEE FP exception */
...@@ -394,10 +378,9 @@ ProgramCheckException(struct pt_regs *regs) ...@@ -394,10 +378,9 @@ ProgramCheckException(struct pt_regs *regs)
} else if (regs->msr & 0x20000) { } else if (regs->msr & 0x20000) {
/* trap exception */ /* trap exception */
#ifdef CONFIG_DEBUG_KERNEL if (debugger_bpt(regs))
if (debugger_bpt && debugger_bpt(regs))
return; return;
#endif
if (check_bug_trap(regs)) { if (check_bug_trap(regs)) {
regs->nip += 4; regs->nip += 4;
return; return;
...@@ -421,17 +404,13 @@ ProgramCheckException(struct pt_regs *regs) ...@@ -421,17 +404,13 @@ ProgramCheckException(struct pt_regs *regs)
void void
KernelFPUnavailableException(struct pt_regs *regs) KernelFPUnavailableException(struct pt_regs *regs)
{ {
printk("Illegal floating point used in kernel (task=0x%p, " die("Unrecoverable FP Unavailable Exception in Kernel", regs, 0);
"pc=0x%016lx, trap=0x%lx)\n", current, regs->nip, regs->trap);
panic("Unrecoverable FP Unavailable Exception in Kernel");
} }
void void
KernelAltivecUnavailableException(struct pt_regs *regs) KernelAltivecUnavailableException(struct pt_regs *regs)
{ {
printk("Illegal VMX/Altivec used in kernel (task=0x%p, " die("Unrecoverable VMX/Altivec Unavailable Exception in Kernel", regs, 0);
"pc=0x%016lx, trap=0x%lx)\n", current, regs->nip, regs->trap);
panic("Unrecoverable VMX/Altivec Unavailable Exception in Kernel");
} }
void void
...@@ -441,10 +420,9 @@ SingleStepException(struct pt_regs *regs) ...@@ -441,10 +420,9 @@ SingleStepException(struct pt_regs *regs)
regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */ regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */
#ifdef CONFIG_DEBUG_KERNEL if (debugger_sstep(regs))
if (debugger_sstep && debugger_sstep(regs))
return; return;
#endif
info.si_signo = SIGTRAP; info.si_signo = SIGTRAP;
info.si_errno = 0; info.si_errno = 0;
info.si_code = TRAP_TRACE; info.si_code = TRAP_TRACE;
......
...@@ -353,11 +353,11 @@ irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs) ...@@ -353,11 +353,11 @@ irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
smp_message_recv(PPC_MSG_MIGRATE_TASK, regs); smp_message_recv(PPC_MSG_MIGRATE_TASK, regs);
} }
#endif #endif
#ifdef CONFIG_XMON #ifdef CONFIG_DEBUGGER
if (test_and_clear_bit(PPC_MSG_XMON_BREAK, if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK,
&xics_ipi_message[cpu].value)) { &xics_ipi_message[cpu].value)) {
mb(); mb();
smp_message_recv(PPC_MSG_XMON_BREAK, regs); smp_message_recv(PPC_MSG_DEBUGGER_BREAK, regs);
} }
#endif #endif
} }
......
...@@ -37,12 +37,6 @@ ...@@ -37,12 +37,6 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/ppcdebug.h>
#ifdef CONFIG_DEBUG_KERNEL
int debugger_kernel_faults = 1;
#endif
void bad_page_fault(struct pt_regs *, unsigned long, int); void bad_page_fault(struct pt_regs *, unsigned long, int);
/* /*
...@@ -60,13 +54,10 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, ...@@ -60,13 +54,10 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
unsigned long code = SEGV_MAPERR; unsigned long code = SEGV_MAPERR;
unsigned long is_write = error_code & 0x02000000; unsigned long is_write = error_code & 0x02000000;
#ifdef CONFIG_DEBUG_KERNEL if (regs->trap == 0x300 || regs->trap == 0x380) {
if (debugger_fault_handler && (regs->trap == 0x300 || if (debugger_fault_handler(regs))
regs->trap == 0x380)) {
debugger_fault_handler(regs);
return; return;
} }
#endif
/* On a kernel SLB miss we can only check for a valid exception entry */ /* On a kernel SLB miss we can only check for a valid exception entry */
if (!user_mode(regs) && (regs->trap == 0x380)) { if (!user_mode(regs) && (regs->trap == 0x380)) {
...@@ -74,13 +65,10 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, ...@@ -74,13 +65,10 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
return; return;
} }
#ifdef CONFIG_DEBUG_KERNEL
if (error_code & 0x00400000) { if (error_code & 0x00400000) {
/* DABR match */
if (debugger_dabr_match(regs)) if (debugger_dabr_match(regs))
return; return;
} }
#endif
if (in_atomic() || mm == NULL) { if (in_atomic() || mm == NULL) {
bad_page_fault(regs, address, SIGSEGV); bad_page_fault(regs, address, SIGSEGV);
...@@ -149,11 +137,6 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, ...@@ -149,11 +137,6 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
info.si_errno = 0; info.si_errno = 0;
info.si_code = code; info.si_code = code;
info.si_addr = (void *) address; info.si_addr = (void *) address;
#ifdef CONFIG_XMON
ifppcdebug(PPCDBG_SIGNALXMON)
PPCDBG_ENTER_DEBUGGER_REGS(regs);
#endif
force_sig_info(SIGSEGV, &info, current); force_sig_info(SIGSEGV, &info, current);
return; return;
} }
...@@ -207,9 +190,7 @@ bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) ...@@ -207,9 +190,7 @@ bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
} }
/* kernel has accessed a bad area */ /* kernel has accessed a bad area */
#ifdef CONFIG_DEBUG_KERNEL if (debugger(regs))
if (debugger_kernel_faults && debugger) return;
debugger(regs);
#endif
die("Kernel access of bad area", regs, sig); die("Kernel access of bad area", regs, sig);
} }
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
#include <asm/cputable.h> #include <asm/cputable.h>
#include <asm/ppcdebug.h> #include <asm/ppcdebug.h>
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/system.h>
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
#include <asm/iSeries/iSeries_dma.h> #include <asm/iSeries/iSeries_dma.h>
...@@ -691,11 +692,7 @@ void __init do_init_bootmem(void) ...@@ -691,11 +692,7 @@ void __init do_init_bootmem(void)
bootmap_pages = bootmem_bootmap_pages(total_pages); bootmap_pages = bootmem_bootmap_pages(total_pages);
start = (unsigned long)__a2p(lmb_alloc(bootmap_pages<<PAGE_SHIFT, PAGE_SIZE)); start = (unsigned long)__a2p(lmb_alloc(bootmap_pages<<PAGE_SHIFT, PAGE_SIZE));
if (start == 0) { BUG_ON(!start);
udbg_printf("do_init_bootmem: failed to allocate a bitmap.\n");
udbg_printf("\tbootmap_pages = 0x%lx.\n", bootmap_pages);
PPCDBG_ENTER_DEBUGGER();
}
boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages); boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
......
...@@ -11,31 +11,23 @@ ...@@ -11,31 +11,23 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/sysrq.h> #include <linux/sysrq.h>
#include <linux/init.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/udbg.h> #include <asm/udbg.h>
#include <asm/system.h>
extern void xmon_printf(const char *fmt, ...);
#define TB_SPEED 25000000
static inline unsigned int readtb(void)
{
unsigned int ret;
asm volatile("mftb %0" : "=r" (ret) :);
return ret;
}
#ifdef CONFIG_MAGIC_SYSRQ #ifdef CONFIG_MAGIC_SYSRQ
static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs, static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
struct tty_struct *tty) struct tty_struct *tty)
{ {
xmon(pt_regs); /* ensure xmon is enabled */
xmon_init();
debugger(pt_regs);
} }
static struct sysrq_key_op sysrq_xmon_op = static struct sysrq_key_op sysrq_xmon_op =
...@@ -45,16 +37,13 @@ static struct sysrq_key_op sysrq_xmon_op = ...@@ -45,16 +37,13 @@ static struct sysrq_key_op sysrq_xmon_op =
.action_msg = "Entering xmon\n", .action_msg = "Entering xmon\n",
}; };
#endif /* CONFIG_MAGIC_SYSRQ */ static int __init setup_xmon_sysrq(void)
void
xmon_map_scc(void)
{ {
#ifdef CONFIG_MAGIC_SYSRQ
/* This maybe isn't the best place to register sysrq 'x' */
__sysrq_put_key_op('x', &sysrq_xmon_op); __sysrq_put_key_op('x', &sysrq_xmon_op);
#endif /* CONFIG_MAGIC_SYSRQ */ return 0;
} }
__initcall(setup_xmon_sysrq);
#endif /* CONFIG_MAGIC_SYSRQ */
int int
xmon_write(void *handle, void *ptr, int nb) xmon_write(void *handle, void *ptr, int nb)
...@@ -62,8 +51,6 @@ xmon_write(void *handle, void *ptr, int nb) ...@@ -62,8 +51,6 @@ xmon_write(void *handle, void *ptr, int nb)
return udbg_write(ptr, nb); return udbg_write(ptr, nb);
} }
int xmon_wants_key;
int int
xmon_read(void *handle, void *ptr, int nb) xmon_read(void *handle, void *ptr, int nb)
{ {
...@@ -80,11 +67,6 @@ void *xmon_stdin; ...@@ -80,11 +67,6 @@ void *xmon_stdin;
void *xmon_stdout; void *xmon_stdout;
void *xmon_stderr; void *xmon_stderr;
void
xmon_init(void)
{
}
int int
xmon_putc(int c, void *f) xmon_putc(int c, void *f)
{ {
......
...@@ -73,11 +73,10 @@ static struct bpt iabr; ...@@ -73,11 +73,10 @@ static struct bpt iabr;
static unsigned bpinstr = 0x7fe00008; /* trap */ static unsigned bpinstr = 0x7fe00008; /* trap */
/* Prototypes */ /* Prototypes */
extern void (*debugger_fault_handler)(struct pt_regs *);
static int cmds(struct pt_regs *); static int cmds(struct pt_regs *);
static int mread(unsigned long, void *, int); static int mread(unsigned long, void *, int);
static int mwrite(unsigned long, void *, int); static int mwrite(unsigned long, void *, int);
static void handle_fault(struct pt_regs *); static int handle_fault(struct pt_regs *);
static void byterev(unsigned char *, int); static void byterev(unsigned char *, int);
static void memex(void); static void memex(void);
static int bsesc(void); static int bsesc(void);
...@@ -235,7 +234,7 @@ static inline void disable_surveillance(void) ...@@ -235,7 +234,7 @@ static inline void disable_surveillance(void)
#endif #endif
} }
void int
xmon(struct pt_regs *excp) xmon(struct pt_regs *excp)
{ {
struct pt_regs regs; struct pt_regs regs;
...@@ -342,6 +341,8 @@ xmon(struct pt_regs *excp) ...@@ -342,6 +341,8 @@ xmon(struct pt_regs *excp)
cpu_clear(smp_processor_id(), cpus_in_xmon); cpu_clear(smp_processor_id(), cpus_in_xmon);
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
set_msrd(msr); /* restore interrupt enable */ set_msrd(msr); /* restore interrupt enable */
return 0;
} }
int int
...@@ -627,7 +628,7 @@ static void cpu_cmd(void) ...@@ -627,7 +628,7 @@ static void cpu_cmd(void)
printf("stopping all cpus\n"); printf("stopping all cpus\n");
/* interrupt other cpu(s) */ /* interrupt other cpu(s) */
cpu = MSG_ALL_BUT_SELF; cpu = MSG_ALL_BUT_SELF;
smp_send_xmon_break(cpu); smp_send_debugger_break(cpu);
return; return;
} }
termch = cmd; termch = cmd;
...@@ -1052,8 +1053,8 @@ cacheflush(void) ...@@ -1052,8 +1053,8 @@ cacheflush(void)
nflush = 1; nflush = 1;
scanhex(&nflush); scanhex(&nflush);
nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES; nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
if( setjmp(bus_error_jmp) == 0 ) { if (setjmp(bus_error_jmp) == 0) {
debugger_fault_handler = handle_fault; __debugger_fault_handler = handle_fault;
sync(); sync();
if (cmd != 'i') { if (cmd != 'i') {
...@@ -1067,7 +1068,7 @@ cacheflush(void) ...@@ -1067,7 +1068,7 @@ cacheflush(void)
/* wait a little while to see if we get a machine check */ /* wait a little while to see if we get a machine check */
__delay(200); __delay(200);
} }
debugger_fault_handler = 0; __debugger_fault_handler = 0;
} }
unsigned long unsigned long
...@@ -1088,7 +1089,7 @@ read_spr(int n) ...@@ -1088,7 +1089,7 @@ read_spr(int n)
code = (unsigned long (*)(void)) opd; code = (unsigned long (*)(void)) opd;
if (setjmp(bus_error_jmp) == 0) { if (setjmp(bus_error_jmp) == 0) {
debugger_fault_handler = handle_fault; __debugger_fault_handler = handle_fault;
sync(); sync();
ret = code(); ret = code();
...@@ -1100,7 +1101,7 @@ read_spr(int n) ...@@ -1100,7 +1101,7 @@ read_spr(int n)
printf("*** Error reading spr %x\n", n); printf("*** Error reading spr %x\n", n);
} }
debugger_fault_handler = 0; __debugger_fault_handler = 0;
return ret; return ret;
} }
...@@ -1122,7 +1123,7 @@ write_spr(int n, unsigned long val) ...@@ -1122,7 +1123,7 @@ write_spr(int n, unsigned long val)
code = (unsigned long (*)(unsigned long)) opd; code = (unsigned long (*)(unsigned long)) opd;
if (setjmp(bus_error_jmp) == 0) { if (setjmp(bus_error_jmp) == 0) {
debugger_fault_handler = handle_fault; __debugger_fault_handler = handle_fault;
sync(); sync();
code(val); code(val);
...@@ -1134,7 +1135,7 @@ write_spr(int n, unsigned long val) ...@@ -1134,7 +1135,7 @@ write_spr(int n, unsigned long val)
printf("*** Error writing spr %x\n", n); printf("*** Error writing spr %x\n", n);
} }
debugger_fault_handler = 0; __debugger_fault_handler = 0;
} }
static unsigned long regno; static unsigned long regno;
...@@ -1213,7 +1214,7 @@ mread(unsigned long adrs, void *buf, int size) ...@@ -1213,7 +1214,7 @@ mread(unsigned long adrs, void *buf, int size)
n = 0; n = 0;
if (setjmp(bus_error_jmp) == 0) { if (setjmp(bus_error_jmp) == 0) {
debugger_fault_handler = handle_fault; __debugger_fault_handler = handle_fault;
sync(); sync();
p = (char *)adrs; p = (char *)adrs;
q = (char *)buf; q = (char *)buf;
...@@ -1238,7 +1239,7 @@ mread(unsigned long adrs, void *buf, int size) ...@@ -1238,7 +1239,7 @@ mread(unsigned long adrs, void *buf, int size)
__delay(200); __delay(200);
n = size; n = size;
} }
debugger_fault_handler = 0; __debugger_fault_handler = 0;
return n; return n;
} }
...@@ -1250,7 +1251,7 @@ mwrite(unsigned long adrs, void *buf, int size) ...@@ -1250,7 +1251,7 @@ mwrite(unsigned long adrs, void *buf, int size)
n = 0; n = 0;
if (setjmp(bus_error_jmp) == 0) { if (setjmp(bus_error_jmp) == 0) {
debugger_fault_handler = handle_fault; __debugger_fault_handler = handle_fault;
sync(); sync();
p = (char *) adrs; p = (char *) adrs;
q = (char *) buf; q = (char *) buf;
...@@ -1277,14 +1278,14 @@ mwrite(unsigned long adrs, void *buf, int size) ...@@ -1277,14 +1278,14 @@ mwrite(unsigned long adrs, void *buf, int size)
} else { } else {
printf("*** Error writing address %x\n", adrs + n); printf("*** Error writing address %x\n", adrs + n);
} }
debugger_fault_handler = 0; __debugger_fault_handler = 0;
return n; return n;
} }
static int fault_type; static int fault_type;
static char *fault_chars[] = { "--", "**", "##" }; static char *fault_chars[] = { "--", "**", "##" };
static void static int
handle_fault(struct pt_regs *regs) handle_fault(struct pt_regs *regs)
{ {
switch (regs->trap) { switch (regs->trap) {
...@@ -1300,6 +1301,8 @@ handle_fault(struct pt_regs *regs) ...@@ -1300,6 +1301,8 @@ handle_fault(struct pt_regs *regs)
} }
longjmp(bus_error_jmp, 1); longjmp(bus_error_jmp, 1);
return 0;
} }
#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t)) #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
...@@ -1913,7 +1916,7 @@ void __xmon_print_symbol(const char *fmt, unsigned long address) ...@@ -1913,7 +1916,7 @@ void __xmon_print_symbol(const char *fmt, unsigned long address)
char namebuf[128]; char namebuf[128];
if (setjmp(bus_error_jmp) == 0) { if (setjmp(bus_error_jmp) == 0) {
debugger_fault_handler = handle_fault; __debugger_fault_handler = handle_fault;
sync(); sync();
name = kallsyms_lookup(address, &size, &offset, &modname, name = kallsyms_lookup(address, &size, &offset, &modname,
namebuf); namebuf);
...@@ -1924,7 +1927,7 @@ void __xmon_print_symbol(const char *fmt, unsigned long address) ...@@ -1924,7 +1927,7 @@ void __xmon_print_symbol(const char *fmt, unsigned long address)
name = "symbol lookup failed"; name = "symbol lookup failed";
} }
debugger_fault_handler = 0; __debugger_fault_handler = 0;
if (!name) { if (!name) {
char addrstr[sizeof("0x%lx") + (BITS_PER_LONG*3/10)]; char addrstr[sizeof("0x%lx") + (BITS_PER_LONG*3/10)];
...@@ -2037,6 +2040,15 @@ static void dump_stab(void) ...@@ -2037,6 +2040,15 @@ static void dump_stab(void)
} }
} }
void xmon_init(void)
{
__debugger = xmon;
__debugger_bpt = xmon_bpt;
__debugger_sstep = xmon_sstep;
__debugger_iabr_match = xmon_iabr_match;
__debugger_dabr_match = xmon_dabr_match;
}
void dump_segments(void) void dump_segments(void)
{ {
if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) if (cur_cpu_spec->cpu_features & CPU_FTR_SLB)
......
...@@ -95,11 +95,6 @@ extern char *trace_names[64]; ...@@ -95,11 +95,6 @@ extern char *trace_names[64];
#define ppcdebugset(FLAGS) (udbg_ifdebug(FLAGS)) #define ppcdebugset(FLAGS) (udbg_ifdebug(FLAGS))
#define PPCDBG_BINFMT (test_thread_flag(TIF_32BIT) ? PPCDBG_BINFMT32 : PPCDBG_BINFMT64) #define PPCDBG_BINFMT (test_thread_flag(TIF_32BIT) ? PPCDBG_BINFMT32 : PPCDBG_BINFMT64)
#ifdef CONFIG_XMON
#define PPCDBG_ENTER_DEBUGGER() xmon(0)
#define PPCDBG_ENTER_DEBUGGER_REGS(X) xmon(X)
#endif
#else #else
#define PPCDBG(...) do {;} while (0) #define PPCDBG(...) do {;} while (0)
#define PPCDBGCALL(FLAGS,FUNCTION) do {;} while (0) #define PPCDBGCALL(FLAGS,FUNCTION) do {;} while (0)
...@@ -107,12 +102,4 @@ extern char *trace_names[64]; ...@@ -107,12 +102,4 @@ extern char *trace_names[64];
#define ppcdebugset(FLAGS) (0) #define ppcdebugset(FLAGS) (0)
#endif /* CONFIG_PPCDBG */ #endif /* CONFIG_PPCDBG */
#ifndef PPCDBG_ENTER_DEBUGGER
#define PPCDBG_ENTER_DEBUGGER() do {;} while(0)
#endif
#ifndef PPCDBG_ENTER_DEBUGGER_REGS
#define PPCDBG_ENTER_DEBUGGER_REGS(A) do {;} while(0)
#endif
#endif /*__PPCDEBUG_H */ #endif /*__PPCDEBUG_H */
...@@ -29,8 +29,7 @@ ...@@ -29,8 +29,7 @@
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
extern void smp_message_pass(int target, int msg, unsigned long data, int wait); extern void smp_message_pass(int target, int msg, unsigned long data, int wait);
extern void smp_send_tlb_invalidate(int); extern void smp_send_debugger_break(int cpu);
extern void smp_send_xmon_break(int cpu);
struct pt_regs; struct pt_regs;
extern void smp_message_recv(int, struct pt_regs *); extern void smp_message_recv(int, struct pt_regs *);
...@@ -63,17 +62,22 @@ extern cpumask_t cpu_available_map; ...@@ -63,17 +62,22 @@ extern cpumask_t cpu_available_map;
* in /proc/interrupts will be wrong!!! --Troy */ * in /proc/interrupts will be wrong!!! --Troy */
#define PPC_MSG_CALL_FUNCTION 0 #define PPC_MSG_CALL_FUNCTION 0
#define PPC_MSG_RESCHEDULE 1 #define PPC_MSG_RESCHEDULE 1
/* This is unused now */
#if 0
#define PPC_MSG_MIGRATE_TASK 2 #define PPC_MSG_MIGRATE_TASK 2
#define PPC_MSG_XMON_BREAK 3 #endif
#define PPC_MSG_DEBUGGER_BREAK 3
void smp_init_iSeries(void); void smp_init_iSeries(void);
void smp_init_pSeries(void); void smp_init_pSeries(void);
#endif /* !(CONFIG_SMP) */ #endif /* !(CONFIG_SMP) */
#endif /* __ASSEMBLY__ */
#define get_hard_smp_processor_id(CPU) (paca[(CPU)].xHwProcNum) #define get_hard_smp_processor_id(CPU) (paca[(CPU)].xHwProcNum)
#define set_hard_smp_processor_id(CPU, VAL) do { (paca[(CPU)].xHwProcNum = VAL); } while (0) #define set_hard_smp_processor_id(CPU, VAL) \
do { (paca[(CPU)].xHwProcNum = VAL); } while (0)
#endif /* __ASSEMBLY__ */
#endif /* !(_PPC64_SMP_H) */ #endif /* !(_PPC64_SMP_H) */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/compiler.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/hw_irq.h> #include <asm/hw_irq.h>
...@@ -52,31 +53,41 @@ ...@@ -52,31 +53,41 @@
#define smp_read_barrier_depends() do { } while(0) #define smp_read_barrier_depends() do { } while(0)
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
#ifdef CONFIG_DEBUG_KERNEL #ifdef CONFIG_DEBUGGER
extern void (*debugger)(struct pt_regs *regs);
extern int (*debugger_bpt)(struct pt_regs *regs); extern int (*__debugger)(struct pt_regs *regs);
extern int (*debugger_sstep)(struct pt_regs *regs); extern int (*__debugger_bpt)(struct pt_regs *regs);
extern int (*debugger_iabr_match)(struct pt_regs *regs); extern int (*__debugger_sstep)(struct pt_regs *regs);
extern int (*debugger_dabr_match)(struct pt_regs *regs); extern int (*__debugger_iabr_match)(struct pt_regs *regs);
extern void (*debugger_fault_handler)(struct pt_regs *regs); extern int (*__debugger_dabr_match)(struct pt_regs *regs);
extern int (*__debugger_fault_handler)(struct pt_regs *regs);
#define DEBUGGER_BOILERPLATE(__NAME) \
static inline int __NAME(struct pt_regs *regs) \
{ \
if (unlikely(__ ## __NAME)) \
return __ ## __NAME(regs); \
return 0; \
}
DEBUGGER_BOILERPLATE(debugger)
DEBUGGER_BOILERPLATE(debugger_bpt)
DEBUGGER_BOILERPLATE(debugger_sstep)
DEBUGGER_BOILERPLATE(debugger_iabr_match)
DEBUGGER_BOILERPLATE(debugger_dabr_match)
DEBUGGER_BOILERPLATE(debugger_fault_handler)
#ifdef CONFIG_XMON
extern void xmon_init(void);
#endif
#else #else
#define debugger(regs) do { } while (0) #define debugger(regs) 0
#define debugger_bpt(regs) 0 #define debugger_bpt(regs) 0
#define debugger_sstep(regs) 0 #define debugger_sstep(regs) 0
#define debugger_iabr_match(regs) 0 #define debugger_iabr_match(regs) 0
#define debugger_dabr_match(regs) 0 #define debugger_dabr_match(regs) 0
#define debugger_fault_handler ((void (*)(struct pt_regs *))0) #define debugger_fault_handler(regs) 0
#endif
#ifdef CONFIG_XMON
extern void xmon_irq(int, void *, struct pt_regs *);
extern void xmon(struct pt_regs *regs);
extern int xmon_bpt(struct pt_regs *regs);
extern int xmon_sstep(struct pt_regs *regs);
extern int xmon_iabr_match(struct pt_regs *regs);
extern int xmon_dabr_match(struct pt_regs *regs);
extern void (*xmon_fault_handler)(struct pt_regs *regs);
#endif #endif
extern void show_regs(struct pt_regs * regs); extern void show_regs(struct pt_regs * regs);
......
#ifndef __PPC_XMON_H
#define __PPC_XMON_H
#ifdef __KERNEL__
struct pt_regs;
extern void xmon(struct pt_regs *excp);
extern void xmon_printf(const char *fmt, ...);
extern void xmon_map_scc(void);
extern int xmon_bpt(struct pt_regs *regs);
extern int xmon_sstep(struct pt_regs *regs);
extern int xmon_iabr_match(struct pt_regs *regs);
extern int xmon_dabr_match(struct pt_regs *regs);
extern void (*xmon_fault_handler)(struct pt_regs *regs);
#endif
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment