Commit 8a81d818 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/netfix-2.6

into home.osdl.org:/home/torvalds/v2.5/linux
parents d5acfb1f 49555a7c
...@@ -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.
......
...@@ -11,9 +11,6 @@ ...@@ -11,9 +11,6 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#define BITS_PER_LONG 32
#include <asm/div64.h>
int (*prom)(void *); int (*prom)(void *);
void *chosen_handle; void *chosen_handle;
...@@ -28,6 +25,9 @@ void chrpboot(int a1, int a2, void *prom); /* in main.c */ ...@@ -28,6 +25,9 @@ void chrpboot(int a1, int a2, void *prom); /* in main.c */
void printk(char *fmt, ...); void printk(char *fmt, ...);
/* there is no convenient header to get this from... -- paulus */
extern unsigned long strlen(const char *);
int int
write(void *handle, void *ptr, int nb) write(void *handle, void *ptr, int nb)
{ {
...@@ -352,7 +352,7 @@ static int skip_atoi(const char **s) ...@@ -352,7 +352,7 @@ static int skip_atoi(const char **s)
#define SPECIAL 32 /* 0x */ #define SPECIAL 32 /* 0x */
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
static char * number(char * str, long long num, int base, int size, int precision, int type) static char * number(char * str, long num, int base, int size, int precision, int type)
{ {
char c,sign,tmp[66]; char c,sign,tmp[66];
const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
...@@ -388,8 +388,10 @@ static char * number(char * str, long long num, int base, int size, int precisio ...@@ -388,8 +388,10 @@ static char * number(char * str, long long num, int base, int size, int precisio
i = 0; i = 0;
if (num == 0) if (num == 0)
tmp[i++]='0'; tmp[i++]='0';
else while (num != 0) else while (num != 0) {
tmp[i++] = digits[do_div(num,base)]; tmp[i++] = digits[num % base];
num /= base;
}
if (i > precision) if (i > precision)
precision = i; precision = i;
size -= precision; size -= precision;
...@@ -424,7 +426,7 @@ int sprintf(char * buf, const char *fmt, ...); ...@@ -424,7 +426,7 @@ int sprintf(char * buf, const char *fmt, ...);
int vsprintf(char *buf, const char *fmt, va_list args) int vsprintf(char *buf, const char *fmt, va_list args)
{ {
int len; int len;
unsigned long long num; unsigned long num;
int i, base; int i, base;
char * str; char * str;
const char *s; const char *s;
...@@ -575,9 +577,7 @@ int vsprintf(char *buf, const char *fmt, va_list args) ...@@ -575,9 +577,7 @@ int vsprintf(char *buf, const char *fmt, va_list args)
--fmt; --fmt;
continue; continue;
} }
if (qualifier == 'L') if (qualifier == 'l') {
num = va_arg(args, long long);
else if (qualifier == 'l') {
num = va_arg(args, unsigned long); num = va_arg(args, unsigned long);
if (flags & SIGN) if (flags & SIGN)
num = (signed long) num; num = (signed long) num;
......
...@@ -102,9 +102,8 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */ ...@@ -102,9 +102,8 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
/* functions */ /* functions */
#include <linux/string.h> extern void *memcpy(void *, const void *, unsigned long);
#define zmemcpy memcpy #define zmemcpy memcpy
#define zmemzero(dest, len) memset(dest, 0, len)
/* Diagnostic functions */ /* Diagnostic functions */
#ifdef DEBUG_ZLIB #ifdef DEBUG_ZLIB
......
...@@ -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);
......
...@@ -194,8 +194,8 @@ void show_regs(struct pt_regs * regs) ...@@ -194,8 +194,8 @@ void show_regs(struct pt_regs * regs)
regs->msr&MSR_DR ? 1 : 0); regs->msr&MSR_DR ? 1 : 0);
if (regs->trap == 0x300 || regs->trap == 0x380 || regs->trap == 0x600) if (regs->trap == 0x300 || regs->trap == 0x380 || regs->trap == 0x600)
printk("DAR: %016lx, DSISR: %016lx\n", regs->dar, regs->dsisr); printk("DAR: %016lx, DSISR: %016lx\n", regs->dar, regs->dsisr);
printk("TASK = %p[%d] '%s' ", printk("TASK: %p[%d] '%s' THREAD: %p",
current, current->pid, current->comm); current, current->pid, current->comm, current->thread_info);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
printk(" CPU: %d", smp_processor_id()); printk(" CPU: %d", smp_processor_id());
...@@ -217,6 +217,8 @@ void show_regs(struct pt_regs * regs) ...@@ -217,6 +217,8 @@ void show_regs(struct pt_regs * regs)
*/ */
printk("NIP [%016lx] ", regs->nip); printk("NIP [%016lx] ", regs->nip);
print_symbol("%s\n", regs->nip); print_symbol("%s\n", regs->nip);
printk("LR [%016lx] ", regs->link);
print_symbol("%s\n", regs->link);
show_stack(current, (unsigned long *)regs->gpr[1]); show_stack(current, (unsigned long *)regs->gpr[1]);
} }
......
...@@ -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;
...@@ -159,15 +156,11 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -159,15 +156,11 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7) unsigned long r6, unsigned long r7)
{ {
#ifdef CONFIG_PPC_PSERIES #ifdef CONFIG_PPC_PSERIES
unsigned int ret, i; unsigned int ret, i;
#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 debugger(0);
if (debugger)
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 debugger(0);
if (debugger)
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,10 +95,8 @@ static void ...@@ -88,10 +95,8 @@ 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);
#endif
die("Exception in kernel mode\n", regs, signr); die("Exception in kernel mode\n", regs, signr);
} }
...@@ -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,6 +360,9 @@ ProgramCheckException(struct pt_regs *regs) ...@@ -372,6 +360,9 @@ ProgramCheckException(struct pt_regs *regs)
{ {
siginfo_t info; siginfo_t info;
if (debugger_fault_handler(regs))
return;
if (regs->msr & 0x100000) { if (regs->msr & 0x100000) {
/* IEEE FP exception */ /* IEEE FP exception */
...@@ -387,10 +378,9 @@ ProgramCheckException(struct pt_regs *regs) ...@@ -387,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;
...@@ -414,17 +404,13 @@ ProgramCheckException(struct pt_regs *regs) ...@@ -414,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
...@@ -434,10 +420,9 @@ SingleStepException(struct pt_regs *regs) ...@@ -434,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)) { return;
debugger_fault_handler(regs);
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);
......
...@@ -43,39 +43,12 @@ GSETSPR(274, sprg2) ...@@ -43,39 +43,12 @@ GSETSPR(274, sprg2)
GSETSPR(275, sprg3) GSETSPR(275, sprg3)
GSETSPR(282, ear) GSETSPR(282, ear)
GSETSPR(287, pvr) GSETSPR(287, pvr)
GSETSPR(528, bat0u)
GSETSPR(529, bat0l)
GSETSPR(530, bat1u)
GSETSPR(531, bat1l)
GSETSPR(532, bat2u)
GSETSPR(533, bat2l)
GSETSPR(534, bat3u)
GSETSPR(535, bat3l)
GSETSPR(1008, hid0) GSETSPR(1008, hid0)
GSETSPR(1009, hid1) GSETSPR(1009, hid1)
GSETSPR(1010, iabr) GSETSPR(1010, iabr)
GSETSPR(1013, dabr) GSETSPR(1013, dabr)
GSETSPR(1023, pir) GSETSPR(1023, pir)
static inline int get_sr(int n)
{
int ret;
#if 0
// DRENG does not assemble
asm (" mfsrin %0,%1" : "=r" (ret) : "r" (n << 28));
#endif
return ret;
}
static inline void set_sr(int n, int val)
{
#if 0
// DRENG does not assemble
asm ("mtsrin %0,%1" : : "r" (val), "r" (n << 28));
#endif
}
static inline void store_inst(void *p) static inline void store_inst(void *p)
{ {
asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p)); asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
...@@ -90,4 +63,3 @@ static inline void cinval(void *p) ...@@ -90,4 +63,3 @@ static inline void cinval(void *p)
{ {
asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p)); asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
} }
...@@ -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);
...@@ -115,10 +114,7 @@ static void cpu_cmd(void); ...@@ -115,10 +114,7 @@ static void cpu_cmd(void);
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
static void csum(void); static void csum(void);
static void bootcmds(void); static void bootcmds(void);
static void mem_translate(void); void dump_segments(void);
static void mem_check(void);
static void mem_find_real(void);
static void mem_find_vsid(void);
static void debug_trace(void); static void debug_trace(void);
...@@ -149,7 +145,15 @@ Commands:\n\ ...@@ -149,7 +145,15 @@ Commands:\n\
b show breakpoints\n\ b show breakpoints\n\
bd set data breakpoint\n\ bd set data breakpoint\n\
bi set instruction breakpoint\n\ bi set instruction breakpoint\n\
bc clear breakpoint\n\ bc clear breakpoint\n"
#ifdef CONFIG_SMP
"\
c print cpus stopped in xmon\n\
ci send xmon interrupt to all other cpus\n\
c# try to switch to cpu number h (in hex)\n"
#endif
"\
C checksum\n\
d dump bytes\n\ d dump bytes\n\
di dump instructions\n\ di dump instructions\n\
df dump float values\n\ df dump float values\n\
...@@ -162,7 +166,6 @@ Commands:\n\ ...@@ -162,7 +166,6 @@ Commands:\n\
md compare two blocks of memory\n\ md compare two blocks of memory\n\
ml locate a block of memory\n\ ml locate a block of memory\n\
mz zero a block of memory\n\ mz zero a block of memory\n\
mx translation information for an effective address\n\
mi show information about memory allocation\n\ mi show information about memory allocation\n\
p show the task list\n\ p show the task list\n\
r print registers\n\ r print registers\n\
...@@ -171,7 +174,14 @@ Commands:\n\ ...@@ -171,7 +174,14 @@ Commands:\n\
t print backtrace\n\ t print backtrace\n\
T Enable/Disable PPCDBG flags\n\ T Enable/Disable PPCDBG flags\n\
x exit monitor\n\ x exit monitor\n\
"; u dump segment table or SLB\n\
? help\n"
#ifndef CONFIG_PPC_ISERIES
"\
zr reboot\n\
zh halt\n"
#endif
;
static int xmon_trace[NR_CPUS]; static int xmon_trace[NR_CPUS];
#define SSTEP 1 /* stepping because of 's' command */ #define SSTEP 1 /* stepping because of 's' command */
...@@ -224,7 +234,7 @@ static inline void disable_surveillance(void) ...@@ -224,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;
...@@ -308,6 +318,7 @@ xmon(struct pt_regs *excp) ...@@ -308,6 +318,7 @@ xmon(struct pt_regs *excp)
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
remove_bpts(); remove_bpts();
disable_surveillance(); disable_surveillance();
printf("press ? for help ");
cmd = cmds(excp); cmd = cmds(excp);
if (cmd == 's') { if (cmd == 's') {
xmon_trace[smp_processor_id()] = SSTEP; xmon_trace[smp_processor_id()] = SSTEP;
...@@ -330,17 +341,8 @@ xmon(struct pt_regs *excp) ...@@ -330,17 +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 */
}
void return 0;
xmon_irq(int irq, void *d, struct pt_regs *regs)
{
unsigned long flags;
local_save_flags(flags);
local_irq_disable();
printf("Keyboard interrupt\n");
xmon(regs);
local_irq_restore(flags);
} }
int int
...@@ -524,18 +526,6 @@ cmds(struct pt_regs *excp) ...@@ -524,18 +526,6 @@ cmds(struct pt_regs *excp)
case 'z': case 'z':
memzcan(); memzcan();
break; break;
case 'x':
mem_translate();
break;
case 'c':
mem_check();
break;
case 'f':
mem_find_real();
break;
case 'e':
mem_find_vsid();
break;
case 'i': case 'i':
show_mem(); show_mem();
break; break;
...@@ -587,11 +577,16 @@ cmds(struct pt_regs *excp) ...@@ -587,11 +577,16 @@ cmds(struct pt_regs *excp)
cpu_cmd(); cpu_cmd();
break; break;
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
#ifndef CONFIG_PPC_ISERIES
case 'z': case 'z':
bootcmds(); bootcmds();
#endif
case 'T': case 'T':
debug_trace(); debug_trace();
break; break;
case 'u':
dump_segments();
break;
default: default:
printf("Unrecognized command: "); printf("Unrecognized command: ");
do { do {
...@@ -633,7 +628,7 @@ static void cpu_cmd(void) ...@@ -633,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;
...@@ -1057,14 +1052,23 @@ cacheflush(void) ...@@ -1057,14 +1052,23 @@ cacheflush(void)
termch = 0; termch = 0;
nflush = 1; nflush = 1;
scanhex(&nflush); scanhex(&nflush);
nflush = (nflush + 31) / 32; nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
if (cmd != 'i') { if (setjmp(bus_error_jmp) == 0) {
for (; nflush > 0; --nflush, adrs += 0x20) __debugger_fault_handler = handle_fault;
cflush((void *) adrs); sync();
} else {
for (; nflush > 0; --nflush, adrs += 0x20) if (cmd != 'i') {
cinval((void *) adrs); for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
cflush((void *) adrs);
} else {
for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
cinval((void *) adrs);
}
sync();
/* wait a little while to see if we get a machine check */
__delay(200);
} }
__debugger_fault_handler = 0;
} }
unsigned long unsigned long
...@@ -1073,6 +1077,7 @@ read_spr(int n) ...@@ -1073,6 +1077,7 @@ read_spr(int n)
unsigned int instrs[2]; unsigned int instrs[2];
unsigned long (*code)(void); unsigned long (*code)(void);
unsigned long opd[3]; unsigned long opd[3];
unsigned long ret = -1UL;
instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
instrs[1] = 0x4e800020; instrs[1] = 0x4e800020;
...@@ -1083,7 +1088,22 @@ read_spr(int n) ...@@ -1083,7 +1088,22 @@ read_spr(int n)
store_inst(instrs+1); store_inst(instrs+1);
code = (unsigned long (*)(void)) opd; code = (unsigned long (*)(void)) opd;
return code(); if (setjmp(bus_error_jmp) == 0) {
__debugger_fault_handler = handle_fault;
sync();
ret = code();
sync();
/* wait a little while to see if we get a machine check */
__delay(200);
} else {
printf("*** Error reading spr %x\n", n);
}
__debugger_fault_handler = 0;
return ret;
} }
void void
...@@ -1102,7 +1122,20 @@ write_spr(int n, unsigned long val) ...@@ -1102,7 +1122,20 @@ write_spr(int n, unsigned long val)
store_inst(instrs+1); store_inst(instrs+1);
code = (unsigned long (*)(unsigned long)) opd; code = (unsigned long (*)(unsigned long)) opd;
code(val); if (setjmp(bus_error_jmp) == 0) {
__debugger_fault_handler = handle_fault;
sync();
code(val);
sync();
/* wait a little while to see if we get a machine check */
__delay(200);
} else {
printf("*** Error writing spr %x\n", n);
}
__debugger_fault_handler = 0;
} }
static unsigned long regno; static unsigned long regno;
...@@ -1112,11 +1145,14 @@ extern char dec_exc; ...@@ -1112,11 +1145,14 @@ extern char dec_exc;
void void
super_regs() super_regs()
{ {
int i, cmd; int cmd;
unsigned long val; unsigned long val;
struct paca_struct* ptrPaca = NULL; #ifdef CONFIG_PPC_ISERIES
struct ItLpPaca* ptrLpPaca = NULL; int i;
struct ItLpRegSave* ptrLpRegSave = NULL; struct paca_struct *ptrPaca = NULL;
struct ItLpPaca *ptrLpPaca = NULL;
struct ItLpRegSave *ptrLpRegSave = NULL;
#endif
cmd = skipbl(); cmd = skipbl();
if (cmd == '\n') { if (cmd == '\n') {
...@@ -1130,10 +1166,7 @@ super_regs() ...@@ -1130,10 +1166,7 @@ super_regs()
printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3()); printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3());
printf("toc = %.16lx dar = %.16lx\n", toc, get_dar()); printf("toc = %.16lx dar = %.16lx\n", toc, get_dar());
printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1()); printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1());
printf("asr = %.16lx\n", mfasr()); #ifdef CONFIG_PPC_ISERIES
for (i = 0; i < 8; ++i)
printf("sr%.2ld = %.16lx sr%.2ld = %.16lx\n", i, get_sr(i), i+8, get_sr(i+8));
// Dump out relevant Paca data areas. // Dump out relevant Paca data areas.
printf("Paca: \n"); printf("Paca: \n");
ptrPaca = get_paca(); ptrPaca = get_paca();
...@@ -1149,7 +1182,8 @@ super_regs() ...@@ -1149,7 +1182,8 @@ super_regs()
printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n", ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0); printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n", ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n", ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3); printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n", ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n", ptrLpRegSave->xMSR, ptrLpRegSave->xNIA); printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n", ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
#endif
return; return;
} }
...@@ -1163,11 +1197,6 @@ super_regs() ...@@ -1163,11 +1197,6 @@ super_regs()
case 'r': case 'r':
printf("spr %lx = %lx\n", regno, read_spr(regno)); printf("spr %lx = %lx\n", regno, read_spr(regno));
break; break;
case 's':
val = get_sr(regno);
scanhex(&val);
set_sr(regno, val);
break;
case 'm': case 'm':
val = get_msr(); val = get_msr();
scanhex(&val); scanhex(&val);
...@@ -1185,7 +1214,7 @@ mread(unsigned long adrs, void *buf, int size) ...@@ -1185,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;
...@@ -1210,7 +1239,7 @@ mread(unsigned long adrs, void *buf, int size) ...@@ -1210,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;
} }
...@@ -1222,7 +1251,7 @@ mwrite(unsigned long adrs, void *buf, int size) ...@@ -1222,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;
...@@ -1249,14 +1278,14 @@ mwrite(unsigned long adrs, void *buf, int size) ...@@ -1249,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) {
...@@ -1272,6 +1301,8 @@ handle_fault(struct pt_regs *regs) ...@@ -1272,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))
...@@ -1885,7 +1916,7 @@ void __xmon_print_symbol(const char *fmt, unsigned long address) ...@@ -1885,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);
...@@ -1896,7 +1927,7 @@ void __xmon_print_symbol(const char *fmt, unsigned long address) ...@@ -1896,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)];
...@@ -1924,240 +1955,8 @@ void __xmon_print_symbol(const char *fmt, unsigned long address) ...@@ -1924,240 +1955,8 @@ void __xmon_print_symbol(const char *fmt, unsigned long address)
} }
} }
void static void debug_trace(void)
mem_translate()
{
int c;
unsigned long ea, va, vsid, vpn, page, hpteg_slot_primary, hpteg_slot_secondary, primary_hash, i, *steg, esid, stabl;
HPTE * hpte;
struct mm_struct * mm;
pte_t *ptep = NULL;
void * pgdir;
c = inchar();
if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
termch = c;
scanhex((void *)&ea);
if ((ea >= KRANGE_START) && (ea <= (KRANGE_START + (1UL<<60)))) {
ptep = 0;
vsid = get_kernel_vsid(ea);
va = ( vsid << 28 ) | ( ea & 0x0fffffff );
} else {
// if in vmalloc range, use the vmalloc page directory
if ( ( ea >= VMALLOC_START ) && ( ea <= VMALLOC_END ) ) {
mm = &init_mm;
vsid = get_kernel_vsid( ea );
}
// if in ioremap range, use the ioremap page directory
else if ( ( ea >= IMALLOC_START ) && ( ea <= IMALLOC_END ) ) {
mm = &ioremap_mm;
vsid = get_kernel_vsid( ea );
}
// if in user range, use the current task's page directory
else if ( ( ea >= USER_START ) && ( ea <= USER_END ) ) {
mm = current->mm;
vsid = get_vsid(mm->context, ea );
}
pgdir = mm->pgd;
va = ( vsid << 28 ) | ( ea & 0x0fffffff );
ptep = find_linux_pte( pgdir, ea );
}
vpn = ((vsid << 28) | (((ea) & 0xFFFF000))) >> 12;
page = vpn & 0xffff;
esid = (ea >> 28) & 0xFFFFFFFFF;
// Search the primary group for an available slot
primary_hash = ( vsid & 0x7fffffffff ) ^ page;
hpteg_slot_primary = ( primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
hpteg_slot_secondary = ( ~primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
printf("ea : %.16lx\n", ea);
printf("esid : %.16lx\n", esid);
printf("vsid : %.16lx\n", vsid);
printf("\nSoftware Page Table\n-------------------\n");
printf("ptep : %.16lx\n", ((unsigned long *)ptep));
if(ptep) {
printf("*ptep : %.16lx\n", *((unsigned long *)ptep));
}
hpte = htab_data.htab + hpteg_slot_primary;
printf("\nHardware Page Table\n-------------------\n");
printf("htab base : %.16lx\n", htab_data.htab);
printf("slot primary : %.16lx\n", hpteg_slot_primary);
printf("slot secondary : %.16lx\n", hpteg_slot_secondary);
printf("\nPrimary Group\n");
for (i=0; i<8; ++i) {
if ( hpte->dw0.dw0.v != 0 ) {
printf("%d: (hpte)%.16lx %.16lx\n", i, hpte->dw0.dword0, hpte->dw1.dword1);
printf(" vsid: %.13lx api: %.2lx hash: %.1lx\n",
(hpte->dw0.dw0.avpn)>>5,
(hpte->dw0.dw0.avpn) & 0x1f,
(hpte->dw0.dw0.h));
printf(" rpn: %.13lx \n", (hpte->dw1.dw1.rpn));
printf(" pp: %.1lx \n",
((hpte->dw1.dw1.pp0)<<2)|(hpte->dw1.dw1.pp));
printf(" wimgn: %.2lx reference: %.1lx change: %.1lx\n",
((hpte->dw1.dw1.w)<<4)|
((hpte->dw1.dw1.i)<<3)|
((hpte->dw1.dw1.m)<<2)|
((hpte->dw1.dw1.g)<<1)|
((hpte->dw1.dw1.n)<<0),
hpte->dw1.dw1.r, hpte->dw1.dw1.c);
}
hpte++;
}
printf("\nSecondary Group\n");
// Search the secondary group
hpte = htab_data.htab + hpteg_slot_secondary;
for (i=0; i<8; ++i) {
if(hpte->dw0.dw0.v) {
printf("%d: (hpte)%.16lx %.16lx\n", i, hpte->dw0.dword0, hpte->dw1.dword1);
printf(" vsid: %.13lx api: %.2lx hash: %.1lx\n",
(hpte->dw0.dw0.avpn)>>5,
(hpte->dw0.dw0.avpn) & 0x1f,
(hpte->dw0.dw0.h));
printf(" rpn: %.13lx \n", (hpte->dw1.dw1.rpn));
printf(" pp: %.1lx \n",
((hpte->dw1.dw1.pp0)<<2)|(hpte->dw1.dw1.pp));
printf(" wimgn: %.2lx reference: %.1lx change: %.1lx\n",
((hpte->dw1.dw1.w)<<4)|
((hpte->dw1.dw1.i)<<3)|
((hpte->dw1.dw1.m)<<2)|
((hpte->dw1.dw1.g)<<1)|
((hpte->dw1.dw1.n)<<0),
hpte->dw1.dw1.r, hpte->dw1.dw1.c);
}
hpte++;
}
printf("\nHardware Segment Table\n-----------------------\n");
stabl = (unsigned long)(KERNELBASE+(_ASR&0xFFFFFFFFFFFFFFFE));
steg = (unsigned long *)((stabl) | ((esid & 0x1f) << 7));
printf("stab base : %.16lx\n", stabl);
printf("slot : %.16lx\n", steg);
for (i=0; i<8; ++i) {
printf("%d: (ste) %.16lx %.16lx\n", i,
*((unsigned long *)(steg+i*2)),*((unsigned long *)(steg+i*2+1)) );
}
}
void mem_check()
{ {
unsigned long htab_size_bytes;
unsigned long htab_end;
unsigned long last_rpn;
HPTE *hpte1, *hpte2;
htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
// last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
last_rpn = 0xfffff;
printf("\nHardware Page Table Check\n-------------------\n");
printf("htab base : %.16lx\n", htab_data.htab);
printf("htab size : %.16lx\n", htab_size_bytes);
#if 1
for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
if ( hpte1->dw0.dw0.v != 0 ) {
if ( hpte1->dw1.dw1.rpn <= last_rpn ) {
for(hpte2 = hpte1+1; hpte2 < (HPTE *)htab_end; hpte2++) {
if ( hpte2->dw0.dw0.v != 0 ) {
if(hpte1->dw1.dw1.rpn == hpte2->dw1.dw1.rpn) {
printf(" Duplicate rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
printf(" hpte1: %16.16lx *hpte1: %16.16lx %16.16lx\n",
hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
printf(" hpte2: %16.16lx *hpte2: %16.16lx %16.16lx\n",
hpte2, hpte2->dw0.dword0, hpte2->dw1.dword1);
}
}
}
} else {
printf(" Bogus rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
printf(" hpte: %16.16lx *hpte: %16.16lx %16.16lx\n",
hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
}
}
}
#endif
printf("\nDone -------------------\n");
}
void mem_find_real()
{
unsigned long htab_size_bytes;
unsigned long htab_end;
unsigned long last_rpn;
HPTE *hpte1;
unsigned long pa, rpn;
int c;
c = inchar();
if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
termch = c;
scanhex((void *)&pa);
rpn = pa >> 12;
htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
// last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
last_rpn = 0xfffff;
printf("\nMem Find RPN\n-------------------\n");
printf("htab base : %.16lx\n", htab_data.htab);
printf("htab size : %.16lx\n", htab_size_bytes);
for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
if ( hpte1->dw0.dw0.v != 0 ) {
if ( hpte1->dw1.dw1.rpn == rpn ) {
printf(" Found rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
printf(" hpte: %16.16lx *hpte1: %16.16lx %16.16lx\n",
hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
}
}
}
printf("\nDone -------------------\n");
}
void mem_find_vsid()
{
unsigned long htab_size_bytes;
unsigned long htab_end;
HPTE *hpte1;
unsigned long vsid;
int c;
c = inchar();
if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
termch = c;
scanhex((void *)&vsid);
htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
printf("\nMem Find VSID\n-------------------\n");
printf("htab base : %.16lx\n", htab_data.htab);
printf("htab size : %.16lx\n", htab_size_bytes);
for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
if ( hpte1->dw0.dw0.v != 0 ) {
if ( ((hpte1->dw0.dw0.avpn)>>5) == vsid ) {
printf(" Found vsid: %.16lx \n", ((hpte1->dw0.dw0.avpn) >> 5));
printf(" hpte: %16.16lx *hpte1: %16.16lx %16.16lx\n",
hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
}
}
}
printf("\nDone -------------------\n");
}
static void debug_trace(void) {
unsigned long val, cmd, on; unsigned long val, cmd, on;
cmd = skipbl(); cmd = skipbl();
...@@ -2204,3 +2003,56 @@ static void debug_trace(void) { ...@@ -2204,3 +2003,56 @@ static void debug_trace(void) {
cmd = skipbl(); cmd = skipbl();
} }
} }
static void dump_slb(void)
{
int i;
unsigned long tmp;
printf("SLB contents of cpu %d\n", smp_processor_id());
for (i = 0; i < naca->slb_size; i++) {
asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
printf("%02d %016lx ", i, tmp);
asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
printf("%016lx\n", tmp);
}
}
static void dump_stab(void)
{
int i;
unsigned long *tmp = (unsigned long *)get_paca()->xStab_data.virt;
printf("Segment table contents of cpu %d\n", smp_processor_id());
for (i = 0; i < PAGE_SIZE/16; i++) {
unsigned long a, b;
a = *tmp++;
b = *tmp++;
if (a || b) {
printf("%03d %016lx ", i, a);
printf("%016lx\n", b);
}
}
}
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)
{
if (cur_cpu_spec->cpu_features & CPU_FTR_SLB)
dump_slb();
else
dump_stab();
}
...@@ -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