Skip to contentSkip to conversation

KGDB: KGDB arch support for ARM

PATCH In review Jason Wessel 2 participants 2 messages Oct 15, 2007 – Jan 17, 2008

Subsystems (8)
lore
Share & tools
lore
#0 lore raw

PATCH 14/21 KGDB: KGDB arch support for ARM

arm-lite.patch

From: Jason Wessel <[email protected]>
CC: [email protected]
Subject: [PATCH] KGDB arch support for ARM

This adds a backend, written by Deepak Saxena <[email protected]> and George Davis <[email protected]> as well as support for the TI OMAP boards, ADI Coyote, PXA2xx, ARM Versatile and PNX4008. Geoff Levand <[email protected]>, Nicolas Pitre, and Manish Lachwani have contributed various fixups here as well. This should only require (on boards that don't have a custom uart) registering the uart with KGDB to add any other boards, or using kgdboe it should Just Work.

---
 arch/arm/kernel/Makefile             |    1 
 arch/arm/kernel/kgdb-jmp.S           |   32 +++++
 arch/arm/kernel/kgdb.c               |  207 +++++++++++++++++++++++++++++++++++
 arch/arm/kernel/setup.c              |    5 
 arch/arm/kernel/traps.c              |   11 +
 arch/arm/mach-ixp2000/core.c         |    4 
 arch/arm/mach-ixp2000/ixdp2x01.c     |    6 +
 arch/arm/mach-ixp4xx/coyote-setup.c  |    4 
 arch/arm/mach-ixp4xx/ixdp425-setup.c |   21 ++-
 arch/arm/mach-omap1/serial.c         |    4 
 arch/arm/mach-pnx4008/core.c         |    4 
 arch/arm/mach-pxa/Makefile           |    1 
 arch/arm/mach-pxa/kgdb-serial.c      |   97 ++++++++++++++++
 arch/arm/mach-versatile/core.c       |    8 +
 arch/arm/mm/extable.c                |    7 +
 drivers/serial/Makefile              |    1 
 drivers/serial/amba-pl011.c          |    3 
 drivers/serial/pl011_kgdb.c          |  117 +++++++++++++++++++
 drivers/serial/pxa.c                 |    5 
 include/asm-arm/kgdb.h               |  103 +++++++++++++++++
 lib/Kconfig.kgdb                     |   55 ++++++++-
 21 files changed, 689 insertions(+), 7 deletions(-)
 create mode 100644 arch/arm/kernel/kgdb-jmp.S
 create mode 100644 arch/arm/kernel/kgdb.c
 create mode 100644 arch/arm/mach-pxa/kgdb-serial.c
 create mode 100644 drivers/serial/pl011_kgdb.c
 create mode 100644 include/asm-arm/kgdb.h
arch/arm/kernel/Makefile +1 -0
@@ -20,6 +20,7 @@ obj-$(CONFIG_PCI)		+= bios32.o isa.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
 obj-$(CONFIG_OABI_COMPAT)	+= sys_oabi-compat.o
+obj-$(CONFIG_KGDB)		+= kgdb.o kgdb-jmp.o
 
 obj-$(CONFIG_CRUNCH)		+= crunch.o crunch-bits.o
 AFLAGS_crunch-bits.o		:= -Wa,-mcpu=ep9312
arch/arm/kernel/kgdb-jmp.S new file +32 -0
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/kernel/kgdb-jmp.S
+ *
+ * Trivial setjmp and longjmp procedures to support bus error recovery
+ * which may occur during kgdb memory read/write operations.
+ *
+ * Author: MontaVista Software, Inc. <[email protected]>
+ *         [email protected]
+ *
+ * 2002-2005 (c) 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 kind, whether express or implied.
+ */
+#include <linux/linkage.h>
+
+ENTRY (kgdb_fault_setjmp)
+	/* Save registers */
+	stmia	r0, {r0-r14}
+	str	lr,[r0, #60]
+	mrs	r1,cpsr
+	str	r1,[r0,#64]
+	ldr	r1,[r0,#4]
+	mov	r0, #0
+	mov	pc,lr
+
+ENTRY (kgdb_fault_longjmp)
+	/* Restore registers */
+	mov	r1,#1
+	str	r1,[r0]
+	ldr     r1,[r0, #64]
+	msr     spsr,r1
+	ldmia	r0,{r0-pc}^
arch/arm/kernel/kgdb.c new file +207 -0

207 lines not on this page · raw message

arch/arm/kernel/setup.c +5 -0
@@ -837,6 +837,11 @@ void __init setup_arch(char **cmdline_p)
 	conswitchp = &dummy_con;
 #endif
 #endif
+
+#if	defined(CONFIG_KGDB)
+	extern void __init early_trap_init(void);
+	early_trap_init();
+#endif
 }
 
 
arch/arm/kernel/traps.c +11 -0
@@ -302,6 +302,7 @@ asmlinkage void __exception do_undefinst
 	unsigned int instr;
 	struct undef_hook *hook;
 	siginfo_t info;
+	mm_segment_t fs;
 	void __user *pc;
 	unsigned long flags;
 
@@ -312,6 +313,8 @@ asmlinkage void __exception do_undefinst
 	 */
 	regs->ARM_pc -= correction;
 
+	fs = get_fs();
+	set_fs(KERNEL_DS);
 	pc = (void __user *)instruction_pointer(regs);
 
 	if (processor_mode(regs) == SVC_MODE) {
@@ -321,6 +324,7 @@ asmlinkage void __exception do_undefinst
 	} else {
 		get_user(instr, (u32 __user *)pc);
 	}
+	set_fs(fs);
 
 	spin_lock_irqsave(&undef_lock, flags);
 	list_for_each_entry(hook, &undef_hook, node) {
@@ -706,6 +710,13 @@ EXPORT_SYMBOL(abort);
 
 void __init trap_init(void)
 {
+#if   defined(CONFIG_KGDB)
+	return;
+}
+
+void __init early_trap_init(void)
+{
+#endif
 	unsigned long vectors = CONFIG_VECTORS_BASE;
 	extern char __stubs_start[], __stubs_end[];
 	extern char __vectors_start[], __vectors_end[];
arch/arm/mach-ixp2000/core.c +4 -0
@@ -25,6 +25,7 @@
 #include <linux/bitops.h>
 #include <linux/serial_8250.h>
 #include <linux/mm.h>
+#include <linux/kgdb.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -184,6 +185,9 @@ static struct platform_device ixp2000_se
 void __init ixp2000_uart_init(void)
 {
 	platform_device_register(&ixp2000_serial_device);
+#ifdef CONFIG_KGDB_8250
+	kgdb8250_add_platform_port(0, &ixp2000_serial_port);
+#endif
 }
 
 
arch/arm/mach-ixp2000/ixdp2x01.c +6 -0
@@ -30,6 +30,7 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/serial_8250.h>
+#include <linux/kgdb.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -413,6 +414,11 @@ static void __init ixdp2x01_init_machine
 	platform_add_devices(ixdp2x01_devices, ARRAY_SIZE(ixdp2x01_devices));
 	ixp2000_uart_init();
 	ixdp2x01_uart_init();
+
+#ifdef CONFIG_KGDB_8250
+	kgdb8250_add_platform_port(0, ixdp2x01_serial_port1);
+	kgdb8250_add_platform_port(1, ixdp2x01_serial_port1);
+#endif
 }
 
 
arch/arm/mach-ixp4xx/coyote-setup.c +4 -0
@@ -96,6 +96,10 @@ static void __init coyote_init(void)
 	}
 
 	platform_add_devices(coyote_devices, ARRAY_SIZE(coyote_devices));
+
+#ifdef CONFIG_KGDB_8250
+	kgdb8250_add_platform_port(0, &coyote_uart_data);
+#endif
 }
 
 #ifdef CONFIG_ARCH_ADI_COYOTE
arch/arm/mach-ixp4xx/ixdp425-setup.c +17 -4
@@ -14,6 +14,7 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
+#include <linux/kgdb.h>
 #include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/mtd/mtd.h>
@@ -152,7 +153,8 @@ static struct plat_serial8250_port ixdp4
 		.mapbase	= IXP4XX_UART1_BASE_PHYS,
 		.membase	= (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
 		.irq		= IRQ_IXP4XX_UART1,
-		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+					UPF_SHARE_IRQ,
 		.iotype		= UPIO_MEM,
 		.regshift	= 2,
 		.uartclk	= IXP4XX_UART_XTAL,
@@ -161,7 +163,8 @@ static struct plat_serial8250_port ixdp4
 		.mapbase	= IXP4XX_UART2_BASE_PHYS,
 		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
 		.irq		= IRQ_IXP4XX_UART2,
-		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+					UPF_SHARE_IRQ,
 		.iotype		= UPIO_MEM,
 		.regshift	= 2,
 		.uartclk	= IXP4XX_UART_XTAL,
@@ -219,12 +222,22 @@ static void __init ixdp425_init(void)
 	platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices));
 }
 
+static void __init ixdp425_map_io(void)
+{
+	ixp4xx_map_io();
+
+#ifdef CONFIG_KGDB_8250
+	kgdb8250_add_platform_port(0, &ixdp425_uart_data[0]);
+	kgdb8250_add_platform_port(1, &ixdp425_uart_data[1]);
+#endif
+}
+
 #ifdef CONFIG_ARCH_IXDP425
 MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
 	/* Maintainer: MontaVista Software, Inc. */
 	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
 	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
-	.map_io		= ixp4xx_map_io,
+	.map_io		= ixdp425_map_io,
 	.init_irq	= ixp4xx_init_irq,
 	.timer		= &ixp4xx_timer,
 	.boot_params	= 0x0100,
@@ -237,7 +250,7 @@ MACHINE_START(IXDP465, "Intel IXDP465 De
 	/* Maintainer: MontaVista Software, Inc. */
 	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
 	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
-	.map_io		= ixp4xx_map_io,
+	.map_io		= ixdp425_map_io,
 	.init_irq	= ixp4xx_init_irq,
 	.timer		= &ixp4xx_timer,
 	.boot_params	= 0x0100,
arch/arm/mach-omap1/serial.c +4 -0
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 #include <linux/serial.h>
 #include <linux/tty.h>
+#include <linux/kgdb.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_reg.h>
 #include <linux/clk.h>
@@ -199,6 +200,9 @@ void __init omap_serial_init(void)
 			break;
 		}
 		omap_serial_reset(&serial_platform_data[i]);
+#ifdef CONFIG_KGDB_8250
+		kgdb8250_add_platform_port(i, &serial_platform_data[i]);
+#endif
 	}
 }
 
arch/arm/mach-pnx4008/core.c +4 -0
@@ -224,6 +224,10 @@ static void __init pnx4008_init(void)
 	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
 	/* Switch on the UART clocks */
 	pnx4008_uart_init();
+#ifdef CONFIG_KGDB_8250
+	kgdb8250_add_platform_port(0, &platform_serial_ports[0]);
+	kgdb8250_add_platform_port(1, &platform_serial_ports[1]);
+#endif
 }
 
 static struct map_desc pnx4008_io_desc[] __initdata = {
arch/arm/mach-pxa/Makefile +1 -0
@@ -32,6 +32,7 @@ obj-$(CONFIG_LEDS) += $(led-y)
 # Misc features
 obj-$(CONFIG_PM) += pm.o sleep.o
 obj-$(CONFIG_PXA_SSP) += ssp.o
+obj-$(CONFIG_KGDB_PXA_SERIAL) += kgdb-serial.o
 
 ifeq ($(CONFIG_PXA27x),y)
 obj-$(CONFIG_PM) += standby.o
arch/arm/mach-pxa/kgdb-serial.c new file +97 -0

97 lines not on this page · raw message

arch/arm/mach-versatile/core.c +8 -0
@@ -184,6 +184,14 @@ static struct map_desc versatile_io_desc
 		.type		= MT_DEVICE
 	},
 #endif
+#ifdef CONFIG_KGDB_AMBA_PL011
+	{
+		.virtual	=  IO_ADDRESS(CONFIG_KGDB_AMBA_BASE),
+		.pfn		= __phys_to_pfn(CONFIG_KGDB_AMBA_BASE),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE
+	},
+#endif
 #ifdef CONFIG_PCI
  	{
 		.virtual	=  IO_ADDRESS(VERSATILE_PCI_CORE_BASE),
arch/arm/mm/extable.c +7 -0
@@ -2,6 +2,7 @@
  *  linux/arch/arm/mm/extable.c
  */
 #include <linux/module.h>
+#include <linux/kgdb.h>
 #include <asm/uaccess.h>
 
 int fixup_exception(struct pt_regs *regs)
@@ -11,6 +12,12 @@ int fixup_exception(struct pt_regs *regs
 	fixup = search_exception_tables(instruction_pointer(regs));
 	if (fixup)
 		regs->ARM_pc = fixup->fixup;
+#ifdef CONFIG_KGDB
+	if (atomic_read(&debugger_active) && kgdb_may_fault)
+		/* Restore our previous state. */
+		kgdb_fault_longjmp(kgdb_fault_jmp_regs);
+		/* Not reached. */
+#endif
 
 	return fixup != NULL;
 }
drivers/serial/Makefile +1 -0
@@ -23,6 +23,7 @@ obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mc
 obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250_au1x00.o
 obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
 obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
+obj-$(CONFIG_KGDB_AMBA_PL011)	+= pl011_kgdb.o
 obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
 obj-$(CONFIG_SERIAL_PXA) += pxa.o
 obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
drivers/serial/amba-pl011.c +2 -1
@@ -332,7 +332,8 @@ static int pl011_startup(struct uart_por
 	/*
 	 * Allocate the IRQ
 	 */
-	retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap);
+	retval = request_irq(uap->port.irq, pl011_int, IRQF_SHARED,
+			 "uart-pl011", uap);
 	if (retval)
 		goto clk_dis;
 
drivers/serial/pl011_kgdb.c new file +117 -0

117 lines not on this page · raw message

drivers/serial/pxa.c +5 -0
@@ -42,6 +42,9 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial_core.h>
+#ifdef CONFIG_KGDB_CONSOLE
+#include <linux/kgdb.h>
+#endif
 
 #include <asm/io.h>
 #include <asm/hardware.h>
@@ -690,6 +693,8 @@ serial_pxa_console_init(void)
 console_initcall(serial_pxa_console_init);
 
 #define PXA_CONSOLE	&serial_pxa_console
+#elif defined(CONFIG_KGDB_CONSOLE)
+#define PXA_CONSOLE	&kgdbcons
 #else
 #define PXA_CONSOLE	NULL
 #endif
include/asm-arm/kgdb.h new file +103 -0

103 lines not on this page · raw message

lib/Kconfig.kgdb +53 -2

85 lines not on this page · raw message

#1 lore raw
Quoted 2 lines · Jason Wessel

...

Quoted 13 lines
drivers/serial/pxa.c +3 -0
@@ -42,6 +42,9 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial_core.h>
+#ifdef CONFIG_KGDB_CONSOLE
+#include <linux/kgdb.h>
+#endif
 
 #include <asm/io.h>
 #include <asm/hardware.h>

drivers/serial/pxa.c serial_pxa_console_init(void) · line 700

Quoted 8 lines
drivers/serial/pxa.c +2 -0
@@ -690,6 +693,8 @@ serial_pxa_console_init(void)
 console_initcall(serial_pxa_console_init);
 
 #define PXA_CONSOLE	&serial_pxa_console
+#elif defined(CONFIG_KGDB_CONSOLE)
+#define PXA_CONSOLE	&kgdbcons
 #else
 #define PXA_CONSOLE	NULL
 #endif

This is the only spot in the whole kgdb series where kgdbcons is used outside its home kernel/kgdb.c. Is this really required in order to use the kgdb console with PXA? And why is it like this only for this platform?

[Note that this forces kgdbcons to become non-static, ie. we will have to fully initialize it, unlike it is done so far...]

Thanks,
Jan

Signature · 2 lines
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux