Checked-in this in cvs
Files Changed
        - ChangeLog
        - powerpc-lite.patch

On Fri, 2006-09-08 at 15:58 +0400, Vitaly Wool wrote:
> Hello folks,
> 
> the patch inlined enables KGDB for PowerPC32 targets in arch/powerpc.
> Verified on 74xx and 85xx targets.
> 
>  Signed-off-by: Vitaly Wool <[EMAIL PROTECTED]>
>  Signed-off-by: Sergey Shtylyov <[EMAIL PROTECTED]>
> 
>  arch/powerpc/kernel/kgdb.c              |  225 
> ++++++++++++++++++++++++++------
>  arch/powerpc/kernel/legacy_serial.c     |    6 
>  arch/powerpc/platforms/powermac/setup.c |    2 
>  3 files changed, 193 insertions(+), 40 deletions(-)
> 
> Index: linux-2.6-kgdb.stg/arch/powerpc/kernel/legacy_serial.c
> ===================================================================
> --- linux-2.6-kgdb.stg.orig/arch/powerpc/kernel/legacy_serial.c
> +++ linux-2.6-kgdb.stg/arch/powerpc/kernel/legacy_serial.c
> @@ -11,6 +11,9 @@
>  #include <asm/udbg.h>
>  #include <asm/pci-bridge.h>
>  #include <asm/ppc-pci.h>
> +#ifdef CONFIG_KGDB_8250
> +#include <linux/kgdb.h>
> +#endif
>  
>  #undef DEBUG
>  
> @@ -470,6 +473,9 @@ static int __init serial_dev_init(void)
>                       fixup_port_pio(i, np, port);
>               if ((port->iotype == UPIO_MEM) || (port->iotype == UPIO_TSI))
>                       fixup_port_mmio(i, np, port);
> +#ifdef CONFIG_KGDB_8250
> +             kgdb8250_add_platform_port(i, port);
> +#endif
>       }
>  
>       DBG("Registering platform serial ports\n");
> Index: linux-2.6-kgdb.stg/arch/powerpc/kernel/kgdb.c
> ===================================================================
> --- linux-2.6-kgdb.stg.orig/arch/powerpc/kernel/kgdb.c
> +++ linux-2.6-kgdb.stg/arch/powerpc/kernel/kgdb.c
> @@ -1,7 +1,7 @@
>  /*
> - * arch/ppc64/kernel/kgdb.c
> + * arch/powerpc/kernel/kgdb.c
>   *
> - * PowerPC64 backend to the KGDB stub.
> + * PowerPC backend to the KGDB stub.
>   *
>   * Maintainer: Tom Rini <[EMAIL PROTECTED]>
>   *
> @@ -10,9 +10,10 @@
>   * Copyright (C) 1996 Paul Mackerras (setjmp/longjmp)
>   * 1998 (c) Michael AK Tesch ([EMAIL PROTECTED])
>   * Copyright (C) 2003 Timesys Corporation.
> - * 2004 (c) MontaVista Software, Inc.
> - * 2005 (c) MontaVista Software, Inc.
> + * Copyright (C) 2004-2006 MontaVista Software, Inc.
>   * PPC64 Mods (C) 2005 Frank Rowand ([EMAIL PROTECTED])
> + * PPC32 support restored by Vitaly Wool <[EMAIL PROTECTED]> and
> + * Sergei Shtylyov <[EMAIL PROTECTED]>
>   *
>   * 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
> @@ -32,7 +33,7 @@
>  #include <asm/machdep.h>
>  
>  /*
> - * This table contains the mapping between PowerPC64 hardware trap types, and
> + * This table contains the mapping between PowerPC hardware trap types, and
>   * signals, which are primarily what GDB understands.  GDB and the kernel
>   * don't always agree on values, so we use constants taken from gdb-6.2.
>   */
> @@ -44,27 +45,55 @@ static struct hard_trap_info
>       { 0x0100, 0x02 /* SIGINT */  },         /* system reset */
>       { 0x0200, 0x0b /* SIGSEGV */ },         /* machine check */
>       { 0x0300, 0x0b /* SIGSEGV */ },         /* data access */
> -     { 0x0380, 0x0b /* SIGSEGV */ },         /* data SLB access */
> -     { 0x0400, 0x0a /* SIGBUS */  },         /* instruction access */
> -     { 0x0480, 0x0a /* SIGBUS */  },         /* instruction segment */
> -     { 0x0500, 0x02 /* SIGINT */  },         /* interrupt */
> +     { 0x0400, 0x0b /* SIGSEGV */ },         /* instruction access */
> +     { 0x0500, 0x02 /* SIGINT */  },         /* external interrupt */
>       { 0x0600, 0x0a /* SIGBUS */  },         /* alignment */
> -     { 0x0700, 0x04 /* SIGILL */  },         /* program */
> -     { 0x0800, 0x08 /* SIGFPE */  },         /* fpu unavailable */
> -     { 0x0900, 0x0e /* SIGALRM */  },        /* decrementer */
> -     { 0x0a00, 0x04 /* SIGILL */  },         /* reserved */
> -     { 0x0b00, 0x04 /* SIGILL */  },         /* reserved */
> -     { 0x0c00, 0x14 /* SIGCHLD */ },         /* syscall */
> -     { 0x0d00, 0x05 /* SIGTRAP */  },        /* single step */
> -     { 0x0e00, 0x04 /* SIGILL */  },         /* reserved */
> +     { 0x0700, 0x05 /* SIGTRAP */ },         /* program check */
> +     { 0x0800, 0x08 /* SIGFPE */  },         /* fp unavailable */
> +     { 0x0900, 0x0e /* SIGALRM */ },         /* decrementer */
> +     { 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 */
> +     { 0x1300, 0x05 /* SIGTRAP */ },         /* instruction address break */
> +#if defined(CONFIG_PPC64)
> +     { 0x1200, 0x05 /* SIGILL */  },         /* system error */
>       { 0x1500, 0x04 /* SIGILL */  },         /* soft patch */
>       { 0x1600, 0x04 /* SIGILL */  },         /* maintenance */
> -     { 0x1700, 0x04 /* SIGILL */  },         /* altivec assist */
> +     { 0x1700, 0x08 /* SIGFPE */  },         /* altivec assist */
>       { 0x1800, 0x04 /* SIGILL */  },         /* thermal */
> -     { 0x0000, 0x000 }                       /* Must be last */
> +#else
> +     { 0x1400, 0x02 /* SIGINT */  },         /* SMI */
> +     { 0x1600, 0x08 /* SIGFPE */  },         /* altivec assist */
> +     { 0x1700, 0x04 /* SIGILL */  },         /* TAU */
> +     { 0x2000, 0x05 /* SIGTRAP */ },         /* run mode */
> +#endif
> +#endif
> +#endif
> +     { 0x0000, 0x00 }                        /* Must be last */
>  };
>  
>  extern atomic_t cpu_doing_single_step;
> @@ -114,10 +143,31 @@ static int kgdb_breakpoint(struct pt_reg
>  
>  static int kgdb_singlestep(struct pt_regs *regs)
>  {
> +     struct thread_info *thread_info, *exception_thread_info;
> +
>       if (user_mode(regs))
>               return 0;
> +     /*
> +     * On Book E and perhaps other processsors, singlestep is handled on
> +     * the critical exception stack.  This causes current_thread_info()
> +     * to fail, since it it locates the thread_info by masking off
> +     * the low bits of the current stack pointer.  We work around
> +     * this issue by copying the thread_info from the kernel stack
> +     * before calling kgdb_handle_exception, and copying it back
> +     * afterwards.  On most processors the copy is avoided since
> +     * exception_thread_info == thread_info.
> +     */
> +     thread_info = (struct thread_info *)(regs->gpr[1] & ~(THREAD_SIZE-1));
> +     exception_thread_info = current_thread_info();
> +
> +     if (thread_info != exception_thread_info)
> +             memcpy(exception_thread_info, thread_info, sizeof *thread_info);
>  
>       kgdb_handle_exception(0, SIGTRAP, 0, regs);
> +
> +     if (thread_info != exception_thread_info)
> +             memcpy(thread_info, exception_thread_info, sizeof *thread_info);
> +
>       return 1;
>  }
>  
> @@ -148,18 +198,28 @@ int kgdb_dabr_match(struct pt_regs *regs
>       ptr = (unsigned long *)ptr32; \
>       } while(0)
>  
> +
>  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, NUMREGBYTES);
>  
>       for (reg = 0; reg < 32; reg++)
>               PACK64(ptr, regs->gpr[reg]);
>  
> -     /* fp registers not used by kernel, leave zero */
> +#ifdef CONFIG_FSL_BOOKE
> +#ifdef CONFIG_SPE
> +     for (reg = 0; reg < 32; reg++)
> +             PACK64(ptr, current->thread.evr[reg]);
> +#else
>       ptr += 32;
> +#endif
> +#else
> +     /* fp registers not used by kernel, leave zero */
> +     ptr += 32 * 8 / sizeof(long);
> +#endif
>  
>       PACK64(ptr, regs->nip);
>       PACK64(ptr, regs->msr);
> @@ -176,17 +236,32 @@ void regs_to_gdb_regs(unsigned long *gdb
>       If this code is enabled, update the definition of NUMREGBYTES to
>       include the vector registers and vector state registers.
>  
> -     PACK32(ptr, p->thread->fpscr);
> +     PACK32(ptr, current->thread->fpscr);
>  
>       /* vr registers not used by kernel, leave zero */
> -     ptr += 64;
> +     ptr += 32 * 16 / sizeof(long);
>  
> -     PACK32(ptr, p->thread->vscr);
> -     PACK32(ptr, p->thread->vrsave);
> +#ifdef CONFIG_ALTIVEC
> +     PACK32(ptr, current->thread->vscr);
> +     PACK32(ptr, current->thread->vrsave);
> +#else
> +     ptr += 2 * 4 / sizeof(long);
> +#endif
> +#else
> +#ifdef CONFIG_FSL_BOOKE
> +#ifdef CONFIG_SPE
> +     /* u64 acc */
> +     PACK32(ptr, current->thread.acc >> 32);
> +     PACK32(ptr, current->thread.acc & 0xffffffff);
> +     PACK64(ptr, current->thread.spefscr);
> +#else
> +     ptr += 2 + 1;
> +#endif
>  #else
>       /* fpscr not used by kernel, leave zero */
>       PACK32(ptr, 0);
>  #endif
> +#endif
>  
>       BUG_ON((unsigned long)ptr >
>              (unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
> @@ -196,8 +271,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, NUMREGBYTES);
>  
> @@ -206,15 +281,23 @@ void sleeping_thread_to_gdb_regs(unsigne
>               PACK64(ptr, regs->gpr[reg]);
>  
>       /* Regs GPR3-13 are caller saved, not in regs->gpr[] */
> -     for (reg = 3; reg < 14; reg++)
> -             PACK64(ptr, 0);
> +     ptr += 11;
>  
>       /* Regs GPR14-31 */
>       for (reg = 14; reg < 32; reg++)
>               PACK64(ptr, regs->gpr[reg]);
>  
> -     /* fp registers not used by kernel, leave zero */
> +#ifdef CONFIG_FSL_BOOKE
> +#ifdef CONFIG_SPE
> +     for (reg = 0; reg < 32; reg++)
> +             PACK64(ptr, p->thread.evr[reg]);
> +#else
>       ptr += 32;
> +#endif
> +#else
> +     /* fp registers not used by kernel, leave zero */
> +     ptr += 32 * 8 / sizeof(long);
> +#endif
>  
>       PACK64(ptr, regs->nip);
>       PACK64(ptr, regs->msr);
> @@ -234,14 +317,29 @@ void sleeping_thread_to_gdb_regs(unsigne
>       PACK32(ptr, p->thread->fpscr);
>  
>       /* vr registers not used by kernel, leave zero */
> -     ptr += 64;
> +     ptr += 32 * 16 / sizeof(long);
>  
> +#ifdef CONFIG_ALTIVEC
>       PACK32(ptr, p->thread->vscr);
>       PACK32(ptr, p->thread->vrsave);
>  #else
> +     ptr += 2 * 4 / sizeof(long);
> +#endif
> +#else
> +#ifdef CONFIG_FSL_BOOKE
> +#ifdef CONFIG_SPE
> +     /* u64 acc */
> +     PACK32(ptr, p->thread.acc >> 32);
> +     PACK32(ptr, p->thread.acc & 0xffffffff);
> +     PACK64(ptr, p->thread.spefscr);
> +#else
> +     ptr += 2 + 1;
> +#endif
> +#else
>       /* fpscr not used by kernel, leave zero */
>       PACK32(ptr, 0);
>  #endif
> +#endif
>  
>       BUG_ON((unsigned long)ptr >
>              (unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
> @@ -258,14 +356,29 @@ void sleeping_thread_to_gdb_regs(unsigne
>  
>  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;
> +     } acc;
> +#endif
>  
>       for (reg = 0; reg < 32; reg++)
>               UNPACK64(regs->gpr[reg], ptr);
>  
> -     /* fp registers not used by kernel, leave zero */
> +#ifdef CONFIG_FSL_BOOKE
> +#ifdef CONFIG_SPE
> +     for (reg = 0; reg < 32; reg++)
> +             UNPACK64(current->thread.evr[reg], ptr);
> +#else
>       ptr += 32;
> +#endif
> +#else
> +     /* fp registers not used by kernel, leave zero */
> +     ptr += 32 * 8 / sizeof(int);
> +#endif
>  
>       UNPACK64(regs->nip, ptr);
>       UNPACK64(regs->msr, ptr);
> @@ -284,13 +397,29 @@ void gdb_regs_to_regs(unsigned long *gdb
>  
>       /* fpscr, vscr, vrsave not used by kernel, leave unchanged */
>  
> -     UNPACK32(p->thread->fpscr, ptr);
> +     UNPACK32(current->thread->fpscr, ptr);
>  
>       /* vr registers not used by kernel, leave zero */
> -     ptr += 64;
> +     ptr += 32 * 16 / sizeof(long);
>  
> -     UNPACK32(p->thread->vscr, ptr);
> -     UNPACK32(p->thread->vrsave, ptr);
> +#ifdef CONFIG_ALTIVEC
> +     UNPACK32(current->thread->vscr, ptr);
> +     UNPACK32(current->thread->vrsave, ptr);
> +#else
> +     ptr += 2 * 4 / sizeof(long);
> +#endif
> +#else
> +#ifdef CONFIG_FSL_BOOKE
> +#ifdef CONFIG_SPE
> +     /* u64 acc */
> +     UNPACK32(acc.v32[0], ptr);
> +     UNPACK32(acc.v32[1], ptr);
> +     current->thread.acc = acc.v64;
> +     UNPACK64(current->thread.spefscr, ptr);
> +#else
> +     ptr += 2 + 1;
> +#endif
> +#endif
>  #endif
>  
>       BUG_ON((unsigned long)ptr >
> @@ -298,7 +427,7 @@ void gdb_regs_to_regs(unsigned long *gdb
>  }
>  
>  /*
> - * This function does PowerPC64 specific procesing for interfacing to gdb.
> + * This function does PowerPC specific procesing for interfacing to gdb.
>   */
>  int kgdb_arch_handle_exception(int vector, int signo, int err_code,
>                              char *remcom_in_buffer, char *remcom_out_buffer,
> @@ -321,7 +450,13 @@ 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);
> +                     linux_regs->msr |= MSR_DE;
> +#else
>                       linux_regs->msr |= MSR_SE;
> +#endif
>                       debugger_step = 1;
>                       if (kgdb_contthread)
>                               atomic_set(&cpu_doing_single_step,
> @@ -335,6 +470,12 @@ int kgdb_arch_handle_exception(int vecto
>  
>  int kgdb_fault_setjmp(unsigned long *curr_context)
>  {
> +#ifdef CONFIG_PPC32
> +      __asm__ __volatile__("mflr 0; stw 0,0(%0);\n\
> +                            stw 1,4(%0); stw 2,8(%0);\n\
> +                            mfcr 0; stw 0,12(%0);\n\
> +                            stmw 13,16(%0)\n" : : "r" (curr_context));
> +#else
>       __asm__ __volatile__("mflr 0; std 0,0(%0)\n\
>                             std       1,8(%0)\n\
>                             std       2,16(%0)\n\
> @@ -358,11 +499,18 @@ int kgdb_fault_setjmp(unsigned long *cur
>                             std       29,160(%0)\n\
>                             std       30,168(%0)\n\
>                             std       31,176(%0)\n" : : "r" (curr_context));
> +#endif
>       return 0;
>  }
>  
>  void kgdb_fault_longjmp(unsigned long *curr_context)
>  {
> +#ifdef CONFIG_PPC32
> +     __asm__ __volatile__("lmw 13,16(%0);\n\
> +                           lwz 0,12(%0); mtcrf 0x38,0;\n\
> +                           lwz 0,0(%0); lwz 1,4(%0); lwz 2,8(%0);\n\
> +                           mtlr 0; mr 3,1\n" : : "r" (curr_context));
> +#else
>       __asm__ __volatile__("ld        13,32(%0)\n\
>                             ld        14,40(%0)\n\
>                             ld        15,48(%0)\n\
> @@ -389,6 +537,7 @@ void kgdb_fault_longjmp(unsigned long *c
>                             ld        2,16(%0)\n\
>                             mtlr      0\n\
>                             mr        3,1\n" : : "r" (curr_context));
> +#endif
>  }
>  
>  /*
> Index: linux-2.6-kgdb.stg/arch/powerpc/platforms/powermac/setup.c
> ===================================================================
> --- linux-2.6-kgdb.stg.orig/arch/powerpc/platforms/powermac/setup.c
> +++ linux-2.6-kgdb.stg/arch/powerpc/platforms/powermac/setup.c
> @@ -98,8 +98,6 @@ extern struct machdep_calls pmac_md;
>  int sccdbg;
>  #endif
>  
> -extern void zs_kgdb_hook(int tty_num);
> -
>  sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;
>  EXPORT_SYMBOL(sys_ctrler);
>  
> 
> -------------------------------------------------------------------------
> Using Tomcat but need to do more? Need to support web services, security?
> Get stuff done quickly with pre-integrated technology to make your job easier
> Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
> http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
> _______________________________________________
> Kgdb-bugreport mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport
> 
> 
-- 
Milind
"The world is divided into one group: those who start counting at 0,
and those who don't."


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Kgdb-bugreport mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to