[Kgdb-bugreport] [PATCH] Update arch/ppc KGDB
Status: Beta
Brought to you by:
jwessel
From: Sergei S. <ssh...@ru...> - 2007-05-15 19:02:02
|
Update arch/ppc KGDB implementation: - merge the begginning of trap-to-signal table containing the more or less standard traps for all CPU families; - make the instruction access trap generate SIGSEGV just like its data access counterpart; - add some traps specific to Freescale E200/E500, Book E, 40x, 6xx/74xx, and 8xx CPU families; - remove PPC64 data/instruction segment trap codes as they never reach the high level code anyway; - remove table entries for the reserved trap since they should be translated to SIGHUP anyway; - make the code dealing with the SPE registers also compile for Freescale E200 CPUs and fix it to correctly skip over if SPE support is not enabled; - fix sleeping_thread_to_gdb_regs() to use the specified (and not the current) process' context to retrieve the SPE accumulator and SPEFSCR; - skip over the $r3-$r13 and FP registers do it without duplicate zeroing; - fix coding style (moved/renamed some variables, removed useless parens, etc.); - fix typos in the comments... Signed-off-by: Sergey Shtylyov <ssh...@ru...> --- This patch brings arch/ppc KGDB into sync with arch/powerpc KGDB, it's against the top of KGDB patchset in the linux_2_6_21_uprev branch. arch/ppc/kernel/kgdb.c | 141 +++++++++++++++++++++++++++---------------------- 1 files changed, 80 insertions(+), 61 deletions(-) Index: linux-2.6/arch/ppc/kernel/kgdb.c =================================================================== --- linux-2.6.orig/arch/ppc/kernel/kgdb.c +++ linux-2.6/arch/ppc/kernel/kgdb.c @@ -7,7 +7,7 @@ * * 1998 (c) Michael AK Tesch (te...@cs...) * Copyright (C) 2003 Timesys Corporation. - * 2004 (c) MontaVista Software, Inc. + * Copyright (C) 2004, 2006 MontaVista Software, Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program as licensed "as is" without any warranty of any @@ -35,39 +35,50 @@ static struct hard_trap_info unsigned int tt; /* Trap type code for powerpc */ unsigned char signo; /* Signal that we map this trap into */ } hard_trap_info[] = { -#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) - { 0x0100, 0x02 /* SIGINT */ }, /* critical input interrupt */ + { 0x0100, 0x02 /* SIGINT */ }, /* system reset */ { 0x0200, 0x0b /* SIGSEGV */ }, /* machine check */ - { 0x0300, 0x0b /* SIGSEGV */ }, /* data storage */ - { 0x0400, 0x0a /* SIGBUS */ }, /* instruction storage */ - { 0x0500, 0x02 /* SIGINT */ }, /* interrupt */ + { 0x0300, 0x0b /* SIGSEGV */ }, /* data access */ + { 0x0400, 0x0b /* SIGSEGV */ }, /* instruction access */ + { 0x0500, 0x02 /* SIGINT */ }, /* external interrupt */ { 0x0600, 0x0a /* SIGBUS */ }, /* alignment */ - { 0x0700, 0x04 /* SIGILL */ }, /* program */ - { 0x0800, 0x04 /* SIGILL */ }, /* reserved */ - { 0x0900, 0x04 /* SIGILL */ }, /* reserved */ - { 0x0a00, 0x04 /* SIGILL */ }, /* reserved */ - { 0x0b00, 0x04 /* SIGILL */ }, /* reserved */ - { 0x0c00, 0x14 /* SIGCHLD */ }, /* syscall */ - { 0x0d00, 0x04 /* SIGILL */ }, /* reserved */ - { 0x0e00, 0x04 /* SIGILL */ }, /* reserved */ - { 0x0f00, 0x04 /* SIGILL */ }, /* reserved */ - { 0x2002, 0x05 /* SIGTRAP */}, /* debug */ -#else - { 0x0200, 0x0b /* SIGSEGV */ }, /* machine check */ - { 0x0300, 0x0b /* SIGSEGV */ }, /* address error (store) */ - { 0x0400, 0x0a /* SIGBUS */ }, /* instruction bus error */ - { 0x0500, 0x02 /* SIGINT */ }, /* interrupt */ - { 0x0600, 0x0a /* SIGBUS */ }, /* alingment */ - { 0x0700, 0x05 /* SIGTRAP */ }, /* breakpoint trap */ - { 0x0800, 0x08 /* SIGFPE */}, /* fpu unavail */ + { 0x0700, 0x05 /* SIGTRAP */ }, /* program check */ + { 0x0800, 0x08 /* SIGFPE */ }, /* fp unavailable */ { 0x0900, 0x0e /* SIGALRM */ }, /* decrementer */ - { 0x0a00, 0x04 /* SIGILL */ }, /* reserved */ - { 0x0b00, 0x04 /* SIGILL */ }, /* reserved */ - { 0x0c00, 0x14 /* SIGCHLD */ }, /* syscall */ - { 0x0d00, 0x05 /* SIGTRAP */ }, /* single-step/watch */ - { 0x0e00, 0x08 /* SIGFPE */ }, /* fp assist */ + { 0x0c00, 0x14 /* SIGCHLD */ }, /* system call */ +#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) + { 0x2002, 0x05 /* SIGTRAP */ }, /* debug */ +#if defined(CONFIG_FSL_BOOKE) + { 0x2010, 0x08 /* SIGFPE */ }, /* spe unavailable */ + { 0x2020, 0x08 /* SIGFPE */ }, /* spe unavailable */ + { 0x2030, 0x08 /* SIGFPE */ }, /* spe fp data */ + { 0x2040, 0x08 /* SIGFPE */ }, /* spe fp data */ + { 0x2050, 0x08 /* SIGFPE */ }, /* spe fp round */ + { 0x2060, 0x0e /* SIGILL */ }, /* performace monitor */ + { 0x2900, 0x08 /* SIGFPE */ }, /* apu unavailable */ + { 0x3100, 0x0e /* SIGALRM */ }, /* fixed interval timer */ + { 0x3200, 0x02 /* SIGINT */ }, /* watchdog */ +#else + { 0x1000, 0x0e /* SIGALRM */ }, /* programmable interval timer */ + { 0x1010, 0x0e /* SIGALRM */ }, /* fixed interval timer */ + { 0x1020, 0x02 /* SIGINT */ }, /* watchdog */ + { 0x2010, 0x08 /* SIGFPE */ }, /* fp unavailable */ + { 0x2020, 0x08 /* SIGFPE */ }, /* ap unavailable */ +#endif +#else + { 0x0d00, 0x05 /* SIGTRAP */ }, /* single-step */ +#if defined(CONFIG_8xx) + { 0x1000, 0x04 /* SIGILL */ }, /* software emulation */ +#else + { 0x0f00, 0x04 /* SIGILL */ }, /* performance monitor */ + { 0x0f20, 0x08 /* SIGFPE */ }, /* altivec unavailable */ + { 0x1300, 0x05 /* SIGTRAP */ }, /* instruction address break */ + { 0x1400, 0x02 /* SIGINT */ }, /* SMI */ + { 0x1600, 0x08 /* SIGFPE */ }, /* altivec assist */ + { 0x1700, 0x04 /* SIGILL */ }, /* TAU */ + { 0x2000, 0x05 /* SIGTRAP */ }, /* run mode */ +#endif #endif - { 0x0000, 0x000 } /* Must be last */ + { 0x0000, 0x00 } /* Must be last */ }; extern atomic_t cpu_doing_single_step; @@ -152,20 +163,23 @@ int kgdb_dabr_match(struct pt_regs *regs void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) { - int reg; unsigned long *ptr = gdb_regs; + int reg; memset(gdb_regs, 0, MAXREG * 4); for (reg = 0; reg < 32; reg++) *(ptr++) = regs->gpr[reg]; -#ifndef CONFIG_E500 - for (reg = 0; reg < 64; reg++) - *(ptr++) = 0; -#else +#ifdef CONFIG_FSL_BOOKE +#ifdef CONFIG_SPE for (reg = 0; reg < 32; reg++) *(ptr++) = current->thread.evr[reg]; +#else + ptr += 32; +#endif +#else + ptr += 64; #endif *(ptr++) = regs->nip; @@ -177,8 +191,8 @@ void regs_to_gdb_regs(unsigned long *gdb #ifdef CONFIG_SPE /* u64 acc */ - *(ptr++) = (current->thread.acc >> 32); - *(ptr++) = (current->thread.acc & 0xffffffff); + *(ptr++) = current->thread.acc >> 32; + *(ptr++) = current->thread.acc & 0xffffffff; *(ptr++) = current->thread.spefscr; #endif } @@ -187,8 +201,8 @@ void sleeping_thread_to_gdb_regs(unsigne { struct pt_regs *regs = (struct pt_regs *)(p->thread.ksp + STACK_FRAME_OVERHEAD); - int reg; unsigned long *ptr = gdb_regs; + int reg; memset(gdb_regs, 0, MAXREG * 4); @@ -197,19 +211,21 @@ void sleeping_thread_to_gdb_regs(unsigne *(ptr++) = regs->gpr[reg]; /* Regs GPR3-13 are not saved */ - for (reg = 3; reg < 14; reg++) - *(ptr++) = 0; + ptr += 11; /* Regs GPR14-31 */ for (reg = 14; reg < 32; reg++) *(ptr++) = regs->gpr[reg]; -#ifndef CONFIG_E500 - for (reg = 0; reg < 64; reg++) - *(ptr++) = 0; -#else +#ifdef CONFIG_FSL_BOOKE +#ifdef CONFIG_SPE for (reg = 0; reg < 32; reg++) - *(ptr++) = current->thread.evr[reg]; + *(ptr++) = p->thread.evr[reg]; +#else + ptr += 32; +#endif +#else + ptr += 64; #endif *(ptr++) = regs->nip; @@ -221,32 +237,35 @@ void sleeping_thread_to_gdb_regs(unsigne #ifdef CONFIG_SPE /* u64 acc */ - *(ptr++) = (current->thread.acc >> 32); - *(ptr++) = (current->thread.acc & 0xffffffff); - *(ptr++) = current->thread.spefscr; + *(ptr++) = p->thread.acc >> 32; + *(ptr++) = p->thread.acc & 0xffffffff; + *(ptr++) = p->thread.spefscr; #endif } void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *regs) { - int reg; unsigned long *ptr = gdb_regs; + int reg; #ifdef CONFIG_SPE union { u32 v32[2]; u64 v64; - } u; + } acc; #endif for (reg = 0; reg < 32; reg++) regs->gpr[reg] = *(ptr++); -#ifndef CONFIG_E500 - for (reg = 0; reg < 64; reg++) - ptr++; -#else +#ifdef CONFIG_FSL_BOOKE +#ifdef CONFIG_SPE for (reg = 0; reg < 32; reg++) current->thread.evr[reg] = *(ptr++); +#else + ptr += 32; +#endif +#else + ptr += 64; #endif regs->nip = *(ptr++); @@ -258,15 +277,15 @@ void gdb_regs_to_regs(unsigned long *gdb #ifdef CONFIG_SPE /* u64 acc */ - u.v32[0] = *(ptr++); - u.v32[1] = *(ptr++); - current->thread.acc = u.v64; + acc.v32[0] = *(ptr++); + acc.v32[1] = *(ptr++); + current->thread.acc = acc.v64; current->thread.spefscr = *(ptr++); #endif } /* - * This function does PoerPC specific procesing for interfacing to gdb. + * This function does PowerPC specific processing for interfacing to gdb. */ int kgdb_arch_handle_exception(int vector, int signo, int err_code, char *remcom_in_buffer, char *remcom_out_buffer, @@ -290,9 +309,9 @@ int kgdb_arch_handle_exception(int vecto atomic_set(&cpu_doing_single_step, -1); /* set the trace bit if we're stepping */ if (remcom_in_buffer[0] == 's') { -#if defined (CONFIG_40x) || defined(CONFIG_BOOKE) - mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | - DBCR0_IC | DBCR0_IDM); +#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) + mtspr(SPRN_DBCR0, + mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM); linux_regs->msr |= MSR_DE; #else linux_regs->msr |= MSR_SE; |