KGDB: KGDB arch support for ARM
Subsystems (8)
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_undefinstunsigned 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_sevoid __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_machineplatform_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
Quoted 2 lines · Jason Wessel
Signed-off-by Jason Wessel <[email protected]>
...
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