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
keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
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
bool "Include xmon kernel debugger"
depends on DEBUG_KERNEL
depends on DEBUGGER
help
Include in-kernel hooks for the xmon kernel monitor/debugger.
Unless you are intending to debug the kernel, say N here.
......
......@@ -11,9 +11,6 @@
#include <linux/string.h>
#include <linux/ctype.h>
#define BITS_PER_LONG 32
#include <asm/div64.h>
int (*prom)(void *);
void *chosen_handle;
......@@ -28,6 +25,9 @@ void chrpboot(int a1, int a2, void *prom); /* in main.c */
void printk(char *fmt, ...);
/* there is no convenient header to get this from... -- paulus */
extern unsigned long strlen(const char *);
int
write(void *handle, void *ptr, int nb)
{
......@@ -352,7 +352,7 @@ static int skip_atoi(const char **s)
#define SPECIAL 32 /* 0x */
#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];
const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
......@@ -388,8 +388,10 @@ static char * number(char * str, long long num, int base, int size, int precisio
i = 0;
if (num == 0)
tmp[i++]='0';
else while (num != 0)
tmp[i++] = digits[do_div(num,base)];
else while (num != 0) {
tmp[i++] = digits[num % base];
num /= base;
}
if (i > precision)
precision = i;
size -= precision;
......@@ -424,7 +426,7 @@ int sprintf(char * buf, const char *fmt, ...);
int vsprintf(char *buf, const char *fmt, va_list args)
{
int len;
unsigned long long num;
unsigned long num;
int i, base;
char * str;
const char *s;
......@@ -575,9 +577,7 @@ int vsprintf(char *buf, const char *fmt, va_list args)
--fmt;
continue;
}
if (qualifier == 'L')
num = va_arg(args, long long);
else if (qualifier == 'l') {
if (qualifier == 'l') {
num = va_arg(args, unsigned long);
if (flags & SIGN)
num = (signed long) num;
......
......@@ -102,9 +102,8 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
/* functions */
#include <linux/string.h>
extern void *memcpy(void *, const void *, unsigned long);
#define zmemcpy memcpy
#define zmemzero(dest, len) memset(dest, 0, len)
/* Diagnostic functions */
#ifdef DEBUG_ZLIB
......
......@@ -645,9 +645,9 @@ void openpic_request_IPIs(void)
request_irq(openpic_vec_ipi+1, openpic_ipi_action, SA_INTERRUPT,
"IPI1 (reschedule)", 0);
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,
"IPI3 (xmon break)", 0);
"IPI3 (debugger break)", 0);
for ( i = 0; i < OPENPIC_NUM_IPI ; i++ )
openpic_enable_ipi(openpic_vec_ipi+i);
......
......@@ -206,25 +206,6 @@ EXPORT_SYMBOL(timer_interrupt);
EXPORT_SYMBOL(irq_desc);
EXPORT_SYMBOL(get_wchan);
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(paca);
......
......@@ -194,8 +194,8 @@ void show_regs(struct pt_regs * regs)
regs->msr&MSR_DR ? 1 : 0);
if (regs->trap == 0x300 || regs->trap == 0x380 || regs->trap == 0x600)
printk("DAR: %016lx, DSISR: %016lx\n", regs->dar, regs->dsisr);
printk("TASK = %p[%d] '%s' ",
current, current->pid, current->comm);
printk("TASK: %p[%d] '%s' THREAD: %p",
current, current->pid, current->comm, current->thread_info);
#ifdef CONFIG_SMP
printk(" CPU: %d", smp_processor_id());
......@@ -217,6 +217,8 @@ void show_regs(struct pt_regs * regs)
*/
printk("NIP [%016lx] ", 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]);
}
......
......@@ -42,6 +42,7 @@
#include <asm/sections.h>
#include <asm/btext.h>
#include <asm/nvram.h>
#include <asm/system.h>
extern unsigned long klimit;
/* extern void *stab; */
......@@ -79,10 +80,6 @@ unsigned long decr_overclock_proc0_set = 0;
int powersave_nap;
#ifdef CONFIG_XMON
extern void xmon_map_scc(void);
#endif
char saved_command_line[256];
unsigned char aux_device_present;
......@@ -163,11 +160,7 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
#endif
#ifdef CONFIG_XMON_DEFAULT
debugger = xmon;
debugger_bpt = xmon_bpt;
debugger_sstep = xmon_sstep;
debugger_iabr_match = xmon_iabr_match;
debugger_dabr_match = xmon_dabr_match;
xmon_init();
#endif
#ifdef CONFIG_PPC_ISERIES
......@@ -601,13 +594,15 @@ void __init setup_arch(char **cmdline_p)
calibrate_delay = ppc64_calibrate_delay;
ppc64_boot_msg(0x12, "Setup Arch");
#ifdef CONFIG_XMON
xmon_map_scc();
if (strstr(cmd_line, "xmon"))
xmon(0);
if (strstr(cmd_line, "xmon")) {
/* ensure xmon is enabled */
xmon_init();
debugger(0);
}
#endif /* CONFIG_XMON */
/*
* 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)
......
......@@ -49,6 +49,7 @@
#include <asm/machdep.h>
#include <asm/xics.h>
#include <asm/cputable.h>
#include <asm/system.h>
int smp_threads_ready;
unsigned long cache_decay_ticks;
......@@ -394,7 +395,7 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
void smp_message_recv(int msg, struct pt_regs *regs)
{
switch( msg ) {
switch(msg) {
case PPC_MSG_CALL_FUNCTION:
smp_call_function_interrupt();
break;
......@@ -407,11 +408,11 @@ void smp_message_recv(int msg, struct pt_regs *regs)
/* spare */
break;
#endif
#ifdef CONFIG_XMON
case PPC_MSG_XMON_BREAK:
xmon(regs);
#ifdef CONFIG_DEBUGGER
case PPC_MSG_DEBUGGER_BREAK:
debugger(regs);
break;
#endif /* CONFIG_XMON */
#endif
default:
printk("SMP %d: smp_message_recv(): unknown msg %d\n",
smp_processor_id(), msg);
......@@ -424,12 +425,12 @@ void smp_send_reschedule(int cpu)
smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0);
}
#ifdef CONFIG_XMON
void smp_send_xmon_break(int cpu)
#ifdef CONFIG_DEBUGGER
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)
{
......@@ -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 "
"responding (%d)\n", smp_processor_id(),
atomic_read(&data.started));
#ifdef CONFIG_DEBUG_KERNEL
if (debugger)
debugger(0);
#endif
goto out;
}
}
......@@ -525,10 +523,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
smp_processor_id(),
atomic_read(&data.finished),
atomic_read(&data.started));
#ifdef CONFIG_DEBUG_KERNEL
if (debugger)
debugger(0);
#endif
goto out;
}
}
......
......@@ -45,13 +45,20 @@ extern void bad_page_fault(struct pt_regs *, unsigned long, int);
extern int fwnmi_active;
#endif
#ifdef CONFIG_DEBUG_KERNEL
void (*debugger)(struct pt_regs *regs);
int (*debugger_bpt)(struct pt_regs *regs);
int (*debugger_sstep)(struct pt_regs *regs);
int (*debugger_iabr_match)(struct pt_regs *regs);
int (*debugger_dabr_match)(struct pt_regs *regs);
void (*debugger_fault_handler)(struct pt_regs *regs);
#ifdef CONFIG_DEBUGGER
int (*__debugger)(struct pt_regs *regs);
int (*__debugger_bpt)(struct pt_regs *regs);
int (*__debugger_sstep)(struct pt_regs *regs);
int (*__debugger_iabr_match)(struct pt_regs *regs);
int (*__debugger_dabr_match)(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
/*
......@@ -88,10 +95,8 @@ static void
_exception(int signr, siginfo_t *info, struct pt_regs *regs)
{
if (!user_mode(regs)) {
#ifdef CONFIG_DEBUG_KERNEL
if (debugger)
debugger(regs);
#endif
if (debugger(regs))
return;
die("Exception in kernel mode\n", regs, signr);
}
......@@ -146,12 +151,8 @@ SystemResetException(struct pt_regs *regs)
}
#endif
#ifdef CONFIG_DEBUG_KERNEL
if (debugger)
debugger(regs);
else
#endif
panic("System Reset");
if (!debugger(regs))
die("System Reset", regs, 0);
/* Must die if the interrupt is not recoverable */
if (!(regs->msr & MSR_RI))
......@@ -228,23 +229,12 @@ MachineCheckException(struct pt_regs *regs)
}
#endif
#ifdef CONFIG_DEBUG_KERNEL
if (debugger_fault_handler) {
debugger_fault_handler(regs);
if (debugger_fault_handler(regs))
return;
}
if (debugger)
debugger(regs);
#endif
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");
if (debugger(regs))
return;
die("Machine check in kernel mode", regs, 0);
}
void
......@@ -267,10 +257,8 @@ InstructionBreakpointException(struct pt_regs *regs)
{
siginfo_t info;
#ifdef CONFIG_DEBUG_KERNEL
if (debugger_iabr_match && debugger_iabr_match(regs))
if (debugger_iabr_match(regs))
return;
#endif
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
......@@ -372,6 +360,9 @@ ProgramCheckException(struct pt_regs *regs)
{
siginfo_t info;
if (debugger_fault_handler(regs))
return;
if (regs->msr & 0x100000) {
/* IEEE FP exception */
......@@ -387,10 +378,9 @@ ProgramCheckException(struct pt_regs *regs)
} else if (regs->msr & 0x20000) {
/* trap exception */
#ifdef CONFIG_DEBUG_KERNEL
if (debugger_bpt && debugger_bpt(regs))
if (debugger_bpt(regs))
return;
#endif
if (check_bug_trap(regs)) {
regs->nip += 4;
return;
......@@ -414,17 +404,13 @@ ProgramCheckException(struct pt_regs *regs)
void
KernelFPUnavailableException(struct pt_regs *regs)
{
printk("Illegal floating point used in kernel (task=0x%p, "
"pc=0x%016lx, trap=0x%lx)\n", current, regs->nip, regs->trap);
panic("Unrecoverable FP Unavailable Exception in Kernel");
die("Unrecoverable FP Unavailable Exception in Kernel", regs, 0);
}
void
KernelAltivecUnavailableException(struct pt_regs *regs)
{
printk("Illegal VMX/Altivec used in kernel (task=0x%p, "
"pc=0x%016lx, trap=0x%lx)\n", current, regs->nip, regs->trap);
panic("Unrecoverable VMX/Altivec Unavailable Exception in Kernel");
die("Unrecoverable VMX/Altivec Unavailable Exception in Kernel", regs, 0);
}
void
......@@ -434,10 +420,9 @@ SingleStepException(struct pt_regs *regs)
regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */
#ifdef CONFIG_DEBUG_KERNEL
if (debugger_sstep && debugger_sstep(regs))
if (debugger_sstep(regs))
return;
#endif
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_TRACE;
......
......@@ -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);
}
#endif
#ifdef CONFIG_XMON
if (test_and_clear_bit(PPC_MSG_XMON_BREAK,
#ifdef CONFIG_DEBUGGER
if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK,
&xics_ipi_message[cpu].value)) {
mb();
smp_message_recv(PPC_MSG_XMON_BREAK, regs);
smp_message_recv(PPC_MSG_DEBUGGER_BREAK, regs);
}
#endif
}
......
......@@ -37,12 +37,6 @@
#include <asm/system.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);
/*
......@@ -60,13 +54,10 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
unsigned long code = SEGV_MAPERR;
unsigned long is_write = error_code & 0x02000000;
#ifdef CONFIG_DEBUG_KERNEL
if (debugger_fault_handler && (regs->trap == 0x300 ||
regs->trap == 0x380)) {
debugger_fault_handler(regs);
if (regs->trap == 0x300 || regs->trap == 0x380) {
if (debugger_fault_handler(regs))
return;
}
#endif
/* On a kernel SLB miss we can only check for a valid exception entry */
if (!user_mode(regs) && (regs->trap == 0x380)) {
......@@ -74,13 +65,10 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
return;
}
#ifdef CONFIG_DEBUG_KERNEL
if (error_code & 0x00400000) {
/* DABR match */
if (debugger_dabr_match(regs))
return;
}
#endif
if (in_atomic() || mm == NULL) {
bad_page_fault(regs, address, SIGSEGV);
......@@ -149,11 +137,6 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
info.si_errno = 0;
info.si_code = code;
info.si_addr = (void *) address;
#ifdef CONFIG_XMON
ifppcdebug(PPCDBG_SIGNALXMON)
PPCDBG_ENTER_DEBUGGER_REGS(regs);
#endif
force_sig_info(SIGSEGV, &info, current);
return;
}
......@@ -207,9 +190,7 @@ bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
}
/* kernel has accessed a bad area */
#ifdef CONFIG_DEBUG_KERNEL
if (debugger_kernel_faults && debugger)
debugger(regs);
#endif
if (debugger(regs))
return;
die("Kernel access of bad area", regs, sig);
}
......@@ -59,6 +59,7 @@
#include <asm/cputable.h>
#include <asm/ppcdebug.h>
#include <asm/sections.h>
#include <asm/system.h>
#ifdef CONFIG_PPC_ISERIES
#include <asm/iSeries/iSeries_dma.h>
......@@ -691,11 +692,7 @@ void __init do_init_bootmem(void)
bootmap_pages = bootmem_bootmap_pages(total_pages);
start = (unsigned long)__a2p(lmb_alloc(bootmap_pages<<PAGE_SHIFT, PAGE_SIZE));
if (start == 0) {
udbg_printf("do_init_bootmem: failed to allocate a bitmap.\n");
udbg_printf("\tbootmap_pages = 0x%lx.\n", bootmap_pages);
PPCDBG_ENTER_DEBUGGER();
}
BUG_ON(!start);
boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
......
......@@ -43,39 +43,12 @@ GSETSPR(274, sprg2)
GSETSPR(275, sprg3)
GSETSPR(282, ear)
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(1009, hid1)
GSETSPR(1010, iabr)
GSETSPR(1013, dabr)
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)
{
asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
......@@ -90,4 +63,3 @@ static inline void cinval(void *p)
{
asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
}
......@@ -11,31 +11,23 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/sysrq.h>
#include <linux/init.h>
#include <asm/machdep.h>
#include <asm/io.h>
#include <asm/page.h>
#include <asm/prom.h>
#include <asm/processor.h>
#include <asm/udbg.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;
}
#include <asm/system.h>
#ifdef CONFIG_MAGIC_SYSRQ
static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
struct tty_struct *tty)
{
xmon(pt_regs);
/* ensure xmon is enabled */
xmon_init();
debugger(pt_regs);
}
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",
};
#endif /* CONFIG_MAGIC_SYSRQ */
void
xmon_map_scc(void)
static int __init setup_xmon_sysrq(void)
{
#ifdef CONFIG_MAGIC_SYSRQ
/* This maybe isn't the best place to register sysrq 'x' */
__sysrq_put_key_op('x', &sysrq_xmon_op);
#endif /* CONFIG_MAGIC_SYSRQ */
return 0;
}
__initcall(setup_xmon_sysrq);
#endif /* CONFIG_MAGIC_SYSRQ */
int
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);
}
int xmon_wants_key;
int
xmon_read(void *handle, void *ptr, int nb)
{
......@@ -80,11 +67,6 @@ void *xmon_stdin;
void *xmon_stdout;
void *xmon_stderr;
void
xmon_init(void)
{
}
int
xmon_putc(int c, void *f)
{
......
......@@ -73,11 +73,10 @@ static struct bpt iabr;
static unsigned bpinstr = 0x7fe00008; /* trap */
/* Prototypes */
extern void (*debugger_fault_handler)(struct pt_regs *);
static int cmds(struct pt_regs *);
static int mread(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 memex(void);
static int bsesc(void);
......@@ -115,10 +114,7 @@ static void cpu_cmd(void);
#endif /* CONFIG_SMP */
static void csum(void);
static void bootcmds(void);
static void mem_translate(void);
static void mem_check(void);
static void mem_find_real(void);
static void mem_find_vsid(void);
void dump_segments(void);
static void debug_trace(void);
......@@ -149,7 +145,15 @@ Commands:\n\
b show breakpoints\n\
bd set data 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\
di dump instructions\n\
df dump float values\n\
......@@ -162,7 +166,6 @@ Commands:\n\
md compare two blocks of memory\n\
ml locate 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\
p show the task list\n\
r print registers\n\
......@@ -171,7 +174,14 @@ Commands:\n\
t print backtrace\n\
T Enable/Disable PPCDBG flags\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];
#define SSTEP 1 /* stepping because of 's' command */
......@@ -224,7 +234,7 @@ static inline void disable_surveillance(void)
#endif
}
void
int
xmon(struct pt_regs *excp)
{
struct pt_regs regs;
......@@ -308,6 +318,7 @@ xmon(struct pt_regs *excp)
#endif /* CONFIG_SMP */
remove_bpts();
disable_surveillance();
printf("press ? for help ");
cmd = cmds(excp);
if (cmd == 's') {
xmon_trace[smp_processor_id()] = SSTEP;
......@@ -330,17 +341,8 @@ xmon(struct pt_regs *excp)
cpu_clear(smp_processor_id(), cpus_in_xmon);
#endif /* CONFIG_SMP */
set_msrd(msr); /* restore interrupt enable */
}
void
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);
return 0;
}
int
......@@ -524,18 +526,6 @@ cmds(struct pt_regs *excp)
case 'z':
memzcan();
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':
show_mem();
break;
......@@ -587,11 +577,16 @@ cmds(struct pt_regs *excp)
cpu_cmd();
break;
#endif /* CONFIG_SMP */
#ifndef CONFIG_PPC_ISERIES
case 'z':
bootcmds();
#endif
case 'T':
debug_trace();
break;
case 'u':
dump_segments();
break;
default:
printf("Unrecognized command: ");
do {
......@@ -633,7 +628,7 @@ static void cpu_cmd(void)
printf("stopping all cpus\n");
/* interrupt other cpu(s) */
cpu = MSG_ALL_BUT_SELF;
smp_send_xmon_break(cpu);
smp_send_debugger_break(cpu);
return;
}
termch = cmd;
......@@ -1057,14 +1052,23 @@ cacheflush(void)
termch = 0;
nflush = 1;
scanhex(&nflush);
nflush = (nflush + 31) / 32;
nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
if (setjmp(bus_error_jmp) == 0) {
__debugger_fault_handler = handle_fault;
sync();
if (cmd != 'i') {
for (; nflush > 0; --nflush, adrs += 0x20)
for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
cflush((void *) adrs);
} else {
for (; nflush > 0; --nflush, adrs += 0x20)
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
......@@ -1073,6 +1077,7 @@ read_spr(int n)
unsigned int instrs[2];
unsigned long (*code)(void);
unsigned long opd[3];
unsigned long ret = -1UL;
instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
instrs[1] = 0x4e800020;
......@@ -1083,7 +1088,22 @@ read_spr(int n)
store_inst(instrs+1);
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
......@@ -1102,7 +1122,20 @@ write_spr(int n, unsigned long val)
store_inst(instrs+1);
code = (unsigned long (*)(unsigned long)) opd;
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;
......@@ -1112,11 +1145,14 @@ extern char dec_exc;
void
super_regs()
{
int i, cmd;
int cmd;
unsigned long val;
struct paca_struct* ptrPaca = NULL;
struct ItLpPaca* ptrLpPaca = NULL;
struct ItLpRegSave* ptrLpRegSave = NULL;
#ifdef CONFIG_PPC_ISERIES
int i;
struct paca_struct *ptrPaca = NULL;
struct ItLpPaca *ptrLpPaca = NULL;
struct ItLpRegSave *ptrLpRegSave = NULL;
#endif
cmd = skipbl();
if (cmd == '\n') {
......@@ -1130,10 +1166,7 @@ super_regs()
printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3());
printf("toc = %.16lx dar = %.16lx\n", toc, get_dar());
printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1());
printf("asr = %.16lx\n", mfasr());
for (i = 0; i < 8; ++i)
printf("sr%.2ld = %.16lx sr%.2ld = %.16lx\n", i, get_sr(i), i+8, get_sr(i+8));
#ifdef CONFIG_PPC_ISERIES
// Dump out relevant Paca data areas.
printf("Paca: \n");
ptrPaca = get_paca();
......@@ -1149,6 +1182,7 @@ super_regs()
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 Msr =%.16lx Saved Nia =%.16lx \n", ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
#endif
return;
}
......@@ -1163,11 +1197,6 @@ super_regs()
case 'r':
printf("spr %lx = %lx\n", regno, read_spr(regno));
break;
case 's':
val = get_sr(regno);
scanhex(&val);
set_sr(regno, val);
break;
case 'm':
val = get_msr();
scanhex(&val);
......@@ -1185,7 +1214,7 @@ mread(unsigned long adrs, void *buf, int size)
n = 0;
if (setjmp(bus_error_jmp) == 0) {
debugger_fault_handler = handle_fault;
__debugger_fault_handler = handle_fault;
sync();
p = (char *)adrs;
q = (char *)buf;
......@@ -1210,7 +1239,7 @@ mread(unsigned long adrs, void *buf, int size)
__delay(200);
n = size;
}
debugger_fault_handler = 0;
__debugger_fault_handler = 0;
return n;
}
......@@ -1222,7 +1251,7 @@ mwrite(unsigned long adrs, void *buf, int size)
n = 0;
if (setjmp(bus_error_jmp) == 0) {
debugger_fault_handler = handle_fault;
__debugger_fault_handler = handle_fault;
sync();
p = (char *) adrs;
q = (char *) buf;
......@@ -1249,14 +1278,14 @@ mwrite(unsigned long adrs, void *buf, int size)
} else {
printf("*** Error writing address %x\n", adrs + n);
}
debugger_fault_handler = 0;
__debugger_fault_handler = 0;
return n;
}
static int fault_type;
static char *fault_chars[] = { "--", "**", "##" };
static void
static int
handle_fault(struct pt_regs *regs)
{
switch (regs->trap) {
......@@ -1272,6 +1301,8 @@ handle_fault(struct pt_regs *regs)
}
longjmp(bus_error_jmp, 1);
return 0;
}
#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)
char namebuf[128];
if (setjmp(bus_error_jmp) == 0) {
debugger_fault_handler = handle_fault;
__debugger_fault_handler = handle_fault;
sync();
name = kallsyms_lookup(address, &size, &offset, &modname,
namebuf);
......@@ -1896,7 +1927,7 @@ void __xmon_print_symbol(const char *fmt, unsigned long address)
name = "symbol lookup failed";
}
debugger_fault_handler = 0;
__debugger_fault_handler = 0;
if (!name) {
char addrstr[sizeof("0x%lx") + (BITS_PER_LONG*3/10)];
......@@ -1924,240 +1955,8 @@ void __xmon_print_symbol(const char *fmt, unsigned long address)
}
}
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()
static void debug_trace(void)
{
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;
cmd = skipbl();
......@@ -2204,3 +2003,56 @@ static void debug_trace(void) {
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];
#define ppcdebugset(FLAGS) (udbg_ifdebug(FLAGS))
#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
#define PPCDBG(...) do {;} while (0)
#define PPCDBGCALL(FLAGS,FUNCTION) do {;} while (0)
......@@ -107,12 +102,4 @@ extern char *trace_names[64];
#define ppcdebugset(FLAGS) (0)
#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 */
......@@ -29,8 +29,7 @@
#ifdef CONFIG_SMP
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_xmon_break(int cpu);
extern void smp_send_debugger_break(int cpu);
struct pt_regs;
extern void smp_message_recv(int, struct pt_regs *);
......@@ -63,17 +62,22 @@ extern cpumask_t cpu_available_map;
* in /proc/interrupts will be wrong!!! --Troy */
#define PPC_MSG_CALL_FUNCTION 0
#define PPC_MSG_RESCHEDULE 1
/* This is unused now */
#if 0
#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_pSeries(void);
#endif /* !(CONFIG_SMP) */
#endif /* __ASSEMBLY__ */
#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 /* __KERNEL__ */
......@@ -9,6 +9,7 @@
*/
#include <linux/config.h>
#include <linux/compiler.h>
#include <asm/page.h>
#include <asm/processor.h>
#include <asm/hw_irq.h>
......@@ -52,31 +53,41 @@
#define smp_read_barrier_depends() do { } while(0)
#endif /* CONFIG_SMP */
#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);
#ifdef CONFIG_DEBUGGER
extern int (*__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 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
#define debugger(regs) do { } while (0)
#define debugger(regs) 0
#define debugger_bpt(regs) 0
#define debugger_sstep(regs) 0
#define debugger_iabr_match(regs) 0
#define debugger_dabr_match(regs) 0
#define debugger_fault_handler ((void (*)(struct pt_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);
#define debugger_fault_handler(regs) 0
#endif
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