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

Reply via email to