Add a KGDB core
Subsystems (19)
PATCH 1/16 Add a KGDB core
Here is a different version of KGDB than found currently in Andrew Morton's tree that Amit Kale and I (and many others) have been working on for some time now (and submitted a while back). I appologize for not resubmitting this sooner, but solving some of the issues George Anzinger and others dug up turned out to take more time than I would have liked.
Having said that, this version of KGDB is designed so that as much code as possible is done in a core file shared by all architectures, and with I/O (ie 8250 serial, custom uart, ethernet) being common when possible and modular. The rough splitup of this is that 95% of the interaction with KGDB is done in files common to all implementations with a small set of architecture specific things (setjmp/longjmp, actually formatting registers for GDB, single stepping).
Much of how to use this version (it is slightly different from George Anzinger's version) is written up in DocBook and viewable that way. I've tried to do this in as clean a way as possible (notifier when possible for example) so that it's as minimally instrusive as possible. But, in order to allow for KGDB to be used very early on (some folks argue this is critical, some argue it's not) there's a few hooks so we can know if pidhash_init has been run, or to try and have KGDB break in as soon as possible, if it can't right then (such as on x86_64 where stacks aren't ready for us to use just yet).
Comments? Thanks!
---
linux-2.6.13-trini/Documentation/DocBook/Makefile | 2 linux-2.6.13-trini/Documentation/DocBook/kgdb.tmpl | 221 ++ linux-2.6.13-trini/MAINTAINERS | 9 linux-2.6.13-trini/include/linux/kgdb.h | 260 ++ linux-2.6.13-trini/kernel/Makefile | 1 linux-2.6.13-trini/kernel/kgdb.c | 1857 +++++++++++++++++ linux-2.6.13-trini/kernel/pid.c | 11 linux-2.6.13-trini/kernel/sched.c | 4 linux-2.6.13-trini/lib/Kconfig.debug | 52 9 files changed, 2415 insertions(+), 2 deletions(-)
Documentation/DocBook/kgdb.tmpl new file +221 -0
@@ -0,0 +1,221 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> + +<book id="kgdbInternals"> + <bookinfo> + <title>KGDB Internals</title> + + <authorgroup> + <author> + <firstname>Tom</firstname> + <surname>Rini</surname> + <affiliation> + <address> + <email>[email protected]</email> + </address> + </affiliation> + </author> + </authorgroup> + + <authorgroup> + <author> + <firstname>Amit S.</firstname> + <surname>Kale</surname> + <affiliation> + <address> + <email>[email protected]</email> + </address> + </affiliation> + </author> + </authorgroup> + + <copyright> + <year>2004-2005</year> + <holder>MontaVista Software, Inc.</holder> + </copyright> + <copyright> + <year>2004</year> + <holder>Amit S. Kale</holder> + </copyright> + + <legalnotice> + <para> + This file is licensed under the terms of the GNU General Public License + version 2. This program is licensed "as is" without any warranty of any + kind, whether express or implied. + </para> + + </legalnotice> + </bookinfo> + +<toc></toc> + <chapter id="Introduction"> + <title>Introduction</title> + <para> + kgdb is a source level debugger for linux kernel. It is used along + with gdb to debug a linux kernel. Kernel developers can debug a kernel + similar to application programs with the use of kgdb. It makes it + possible to place breakpoints in kernel code, step through the code + and observe variables. + </para> + <para> + Two machines are required for using kgdb. One of these machines is a + development machine and the other is a test machine. The machines are + typically connected through a serial line, a null-modem cable which + connects their serial ports. It is also possible however, to use an + ethernet connection between the machines. The kernel to be debugged + runs on the test machine. gdb runs on the development machine. The + serial line or ethernet connection is used by gdb to communicate to + the kernel being debugged. + </para> + </chapter> + <chapter id="CompilingAKernel"> + <title>Compiling a kernel</title> + <para> + To enable <symbol>CONFIG_KGDB</symbol>, look under the "Kernel debugging" + and then select "KGDB: kernel debugging with remote gdb". + </para> + <para> + The first choice for I/O is <symbol>CONFIG_KGDB_ONLY_MODULES</symbol>. + This means that you will only be able to use KGDB after loading a + kernel module that defines how you want to be able to talk with + KGDB. There are two other choices (more on some architectures) that + can be enabled as modules later, if not picked here. + </para> + <para>The first of these is <symbol>CONFIG_KGDB_8250_NOMODULE</symbol>. + This has sub-options such as <symbol>CONFIG_KGDB_SIMPLE_SERIAL</symbol> + which toggles choosing the serial port by ttyS number or by specifying + a port and IRQ number. + </para> + <para> + The second of these choices on most systems for I/O is + <symbol>CONFIG_KGDB_ETH</symbol>. This requires that the machine to be + debugged has an ethernet card which supports the netpoll API, such as + the cards supported by <symbol>CONFIG_E100</symbol>. There are no + sub-options for this, but a kernel command line option is required. + </para> + </chapter> + <chapter id="BootingTheKernel"> + <title>Booting the kernel</title> + <para> + The Kernel command line option <constant>kgdbwait</constant> makes kgdb + wait for gdb connection during booting of a kernel. If the + <symbol>CONFIG_KGDB_8250</symbol> driver is used (or if applicable, + another serial driver) this breakpoint will happen very early on, before + console output. If you wish to change serial port information and you + have enabled both <symbol>CONFIG_KGDB_8250</symbol> and + <symbol>CONFIG_KGDB_SIMPLE_SERIAL</symbol> then you must pass the option + <constant>kgdb8250=portnumber,speed</constant> or on IA64 + <constant>kgdb8250=portnumber,speed,irq,iomembase</constant> before + <constant>kgdbwait</constant>. The values for portnumber are 0-3 and + correspond to ttyS0 to ttyS3 respectively. The supported speeds are + <constant>9600</constant>, <constant>19200</constant>, + <constant>38400</constant>, <constant>57600</constant>, and + <constant>115200</constant>. + </para> + <para> + To have KGDB stop the kernel and wait, with the compiled values for the + serial driver, pass in: <constant>kgdbwait</constant>. + </para> + <para> + To specify the values of the serial port at boot: + <constant>kgdb8250=0,115200</constant>. + On IA64 this could also be: + <constant>kgdb8250=1,115200,74,0xc0000000ff5e0000</constant> + And to have KGDB also stop the kernel and wait for GDB to connect, pass in + <constant>kgdbwait</constant> after this arguement. + </para> + <para> + To configure the <symbol>CONFIG_KGDB_ETH</symbol> driver, pass in + <constant>kgdboe=[src-port]@<src-ip>/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]</constant> + where: + <itemizedlist> + <listitem><para>src-port (optional): source for UDP packets (defaults to <constant>6443</constant>)</para></listitem> + <listitem><para>src-ip: source IP to use (interface address)</para></listitem> + <listitem><para>dev (optional): network interface (<constant>eth0</constant>)</para></listitem> + <listitem><para>tgt-port (optional): port GDB will use (defaults to <constant>6442</constant>)</para></listitem> + <listitem><para>tgt-ip: IP address GDB will be connecting from</para></listitem> + <listitem><para>tgt-macaddr (optional): ethernet MAC address for logging agent (default is broadcast)</para></listitem> + </itemizedlist> + </para> + </chapter> + <chapter id="ConnectingGDB"> + <title>Connecting gdb</title> + <para> + If you have used any of the methods to have KGDB stop and create + an initial breakpoint described in the previous chapter, kgdb prints + the message "Waiting for connection from remote gdb..." on the console + and waits for connection from gdb. At this point you connect gdb to kgdb. + </para> + <para> + Example (serial): + </para> + <programlisting> + % gdb ./vmlinux + (gdb) set remotebaud 115200 + (gdb) target remote /dev/ttyS0 + </programlisting> + <para> + Example (ethernet): + </para> + <programlisting> + % gdb ./vmlinux + (gdb) target remote udp:192.168.2.2:6443 + </programlisting> + <para> + Once connected, you can debug a kernel the way you would debug an + application program. + </para> + </chapter> + <chapter id="CommonBackEndReq"> + <title>The common backend (required)</title> + <para> + There are a few flags which must be set on every architecture in + their <asm/kgdb.h> file. These are: + <itemizedlist> + <listitem> + <para> + NUMREGBYTES: The size in bytes of all of the registers, so + that we can ensure they will all fit into a packet. + </para> + <para> + BUFMAX: The size in bytes of the buffer GDB will read into. + This must be larger than NUMREGBYTES. + </para> + <para> + CACHE_FLUSH_IS_SAFE: Set to one if it always safe to call + flush_cache_range or flush_icache_range. On some architectures, + these functions may not be safe to call on SMP since we keep other + CPUs in a holding pattern. + </para> + </listitem> + </itemizedlist> + </para> + <para> + There are also the following functions for the common backend, + found in kernel/kgdb.c that must be supplied by the + architecture-specific backend. No weak version of these is provided. + </para> +!Iinclude/linux/kgdb.h + </chapter> + <chapter id="CommonBackEndOpt"> + <title>The common backend (optional)</title> + <para> + These functions are part of the common backend, found in kernel/kgdb.c + and are optionally implemented. Some functions (with _hw_ in the name) + end up being required on arches which use hardware breakpoints. + </para> +!Ikernel/kgdb.c + </chapter> + <chapter id="DriverSpecificFunctions"> + <title>Driver-Specific Functions</title> + <para> + Some of the I/O drivers have additional functions that can be + called, that are specific to the driver. Calls from other places + to these functions must be wrapped in #ifdefs for the driver in + question. + </para> +!Idrivers/serial/kgdb_8250.c + </chapter> +</book>
Documentation/DocBook/Makefile renamed from Documentation/DocBook/Makefile~core-lite +1 -1
@@ -10,7 +10,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mc kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ procfs-guide.xml writing_usb_driver.xml \ sis900.xml kernel-api.xml journal-api.xml lsm.xml usb.xml \ - gadget.xml libata.xml mtdnand.xml librs.xml + gadget.xml libata.xml mtdnand.xml librs.xml kgdb.xml ### # The build process is as follows (targets):
include/linux/kgdb.h new file +260 -0
260 lines not on this page · raw message
kernel/kgdb.c new file +1857 -0
1,857 lines not on this page · raw message
kernel/Makefile renamed from kernel/Makefile~core-lite +1 -0
@@ -26,6 +26,7 @@ obj-$(CONFIG_STOP_MACHINE) += stop_machi obj-$(CONFIG_AUDIT) += audit.o obj-$(CONFIG_AUDITSYSCALL) += auditsc.o obj-$(CONFIG_KPROBES) += kprobes.o +obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_SYSFS) += ksysfs.o obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
kernel/pid.c renamed from kernel/pid.c~core-lite +10 -1
@@ -250,8 +250,13 @@ void switch_exec_pids(task_t *leader, ta/* * The pid hash table is scaled according to the amount of memory in the * machine. From a minimum of 16 slots up to 4096 slots at one gigabyte or -* more. +* more. KGDB needs to know if this function has been called already, +* since we might have entered KGDB very early. */ +#ifdef CONFIG_KGDB +int pidhash_init_done; +#endif +void __init pidhash_init (void ) {int i, j, pidhash_size;
@@ -273,6 +278,10 @@ void __init pidhash_init(void)for (j =0 ; j < pidhash_size; j++)INIT_HLIST_HEAD (&pid_hash[i][j]); } + +#ifdef CONFIG_KGDB + pidhash_init_done =1 ; +#endif }void __init pidmap_init (void )
kernel/sched.c renamed from kernel/sched.c~core-lite +4 -0
@@ -47,6 +47,7 @@#include <linux/syscalls.h> #include <linux/times.h> #include <linux/acct.h> +#include <linux/kgdb.h> #include <asm/tlb.h> #include <asm/unistd.h>
@@ -5217,6 +5218,9 @@ void __might_sleep(char *file, int line)#if defined(in_atomic)static unsigned long prev_jiffy;/* ratelimiting */ +if (atomic_read (&debugger_active)) +return ; +if ((in_atomic () ||irqs_disabled ()) && system_state ==SYSTEM_RUNNING && !oops_in_progress) {if (time_before (jiffies, prev_jiffy +HZ ) && prev_jiffy)
lib/Kconfig.debug renamed from lib/Kconfig.debug~core-lite +52 -0
55 lines not on this page · raw message
MAINTAINERS renamed from MAINTAINERS~core-lite +9 -0
@@ -1349,6 +1349,15 @@ L: [email protected] L: [email protected] S: Maintained +KGDB +P: Tom Rini +P: Amit S. Kale +M: [email protected] +M: [email protected] +W: http://sourceforge.net/projects/kgdb +L: [email protected] +S: Maintained + LANMEDIA WAN CARD DRIVER P: Andrew Stanley-Jones M: [email protected]
_
PATCH 2/16 Add support for i386 platforms to KGDB
This adds the basic support for i386. The only real changes outside of new KGDB files and Makefile/related is that for support early on we must set some traps sooner rather than later, but it is safe to always do this. Also, to break in as early as possible, i386 now calls parse_early_param() to explicitly look at anything marked early_param(). We also add a few more notify_die() calls in areas where KGDB needs to take a peek sometimes. Finally, we add some labels to switch_to macros so that when backtracing we can see where we really are.
---
linux-2.6.13-trini/arch/i386/kernel/Makefile | 1 linux-2.6.13-trini/arch/i386/kernel/kgdb-jmp.S | 74 +++++ linux-2.6.13-trini/arch/i386/kernel/kgdb.c | 301 +++++++++++++++++++++ linux-2.6.13-trini/arch/i386/kernel/setup.c | 3 linux-2.6.13-trini/arch/i386/kernel/traps.c | 15 - linux-2.6.13-trini/arch/i386/mm/fault.c | 4 linux-2.6.13-trini/include/asm-i386/kgdb.h | 50 +++ linux-2.6.13-trini/include/asm-i386/system.h | 10 linux-2.6.13-trini/lib/Kconfig.debug | 2 9 files changed, 452 insertions(+), 8 deletions(-)
arch/i386/kernel/kgdb.c new file +301 -0
@@ -0,0 +1,301 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2, or (at your option) any +* later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +*/ + +/* +* Copyright (C) 2000-2001 VERITAS Software Corporation. +*/ +/* +* Contributor: Lake Stevens Instrument Division$ +* Written by: Glenn Engel $ +* Updated by: Amit Kale<[email protected]> +* Updated by: Tom Rini <[email protected]> +* Modified for 386 by Jim Kingdon, Cygnus Support. +* Origianl kgdb, compatibility with 2.1.xx kernel by +* David Grothe <[email protected]> +* Additional support from Tigran Aivazian <[email protected]> +*/ + +#include <linux/string.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/smp.h> +#include <linux/spinlock.h> +#include <linux/delay.h> +#include <asm/vm86.h> +#include <asm/system.h> +#include <asm/ptrace.h> /* for linux pt_regs struct */ +#include <linux/kgdb.h> +#include <linux/init.h> +#include <asm/apicdef.h> +#include <asm/desc.h> +#include <asm/kdebug.h> + +#include "mach_ipi.h" + +/* Put the error code here just in case the user cares. */ +int gdb_i386errcode; +/* Likewise, the vector number here (since GDB only gets the signal +number through the usual means, and that's not very specific). */ +int gdb_i386vector =-1 ; + +extern atomic_t cpu_doing_single_step; + +void regs_to_gdb_regs (unsigned long *gdb_regs,struct pt_regs *regs) +{ + gdb_regs[_EAX] = regs->eax; + gdb_regs[_EBX] = regs->ebx; + gdb_regs[_ECX] = regs->ecx; + gdb_regs[_EDX] = regs->edx; + gdb_regs[_ESI] = regs->esi; + gdb_regs[_EDI] = regs->edi; + gdb_regs[_EBP] = regs->ebp; + gdb_regs[_DS] = regs->xds; + gdb_regs[_ES] = regs->xes; + gdb_regs[_PS] = regs->eflags; + gdb_regs[_CS] = regs->xcs; + gdb_regs[_PC] = regs->eip; + gdb_regs[_ESP] = (int )(®s->esp); + gdb_regs[_SS] = __KERNEL_DS; + gdb_regs[_FS] =0xFFFF ; + gdb_regs[_GS] =0xFFFF ; +} + +/* +* Extracts ebp, esp and eip values understandable by gdb from the values +* saved by switch_to. +* thread.esp points to ebp. flags and ebp are pushed in switch_to hence esp +* prior to entering switch_to is 8 greater then the value that is saved. +* If switch_to changes, change following code appropriately. +*/ +void sleeping_thread_to_gdb_regs (unsigned long *gdb_regs,struct task_struct *p) +{ + gdb_regs[_EAX] =0 ; + gdb_regs[_EBX] =0 ; + gdb_regs[_ECX] =0 ; + gdb_regs[_EDX] =0 ; + gdb_regs[_ESI] =0 ; + gdb_regs[_EDI] =0 ; + gdb_regs[_EBP] = *(unsigned long *)p->thread.esp; + gdb_regs[_DS] = __KERNEL_DS; + gdb_regs[_ES] = __KERNEL_DS; + gdb_regs[_PS] = *(unsigned long *)(p->thread.esp +4 ); + gdb_regs[_CS] = __KERNEL_CS; + gdb_regs[_PC] = p->thread.eip; + gdb_regs[_ESP] = p->thread.esp; + gdb_regs[_SS] = __KERNEL_DS; + gdb_regs[_FS] =0xFFFF ; + gdb_regs[_GS] =0xFFFF ; +} + +void gdb_regs_to_regs (unsigned long *gdb_regs,struct pt_regs *regs) +{ + regs->eax = gdb_regs[_EAX]; + regs->ebx = gdb_regs[_EBX]; + regs->ecx = gdb_regs[_ECX]; + regs->edx = gdb_regs[_EDX]; + regs->esi = gdb_regs[_ESI]; + regs->edi = gdb_regs[_EDI]; + regs->ebp = gdb_regs[_EBP]; + regs->xds = gdb_regs[_DS]; + regs->xes = gdb_regs[_ES]; + regs->eflags = gdb_regs[_PS]; + regs->xcs = gdb_regs[_CS]; + regs->eip = gdb_regs[_PC]; +} + +static struct hw_breakpoint { +unsigned enabled; +unsigned type; +unsigned len; +unsigned addr; +} breakinfo[4 ] = { + { .enabled =0 }, + { .enabled =0 }, + { .enabled =0 }, + { .enabled =0 }, +}; + +void kgdb_correct_hw_break (void ) +{ +int breakno; +int correctit; +int breakbit; +unsigned dr7; + + asmvolatile ("movl %%db7, %0\n" :"=r" (dr7) + :); +do { +unsigned addr0, addr1, addr2, addr3; + asmvolatile ("movl %%db0, %0\n" +"movl %%db1, %1\n" +"movl %%db2, %2\n" +"movl %%db3, %3\n" :"=r" (addr0),"=r" (addr1), +"=r" (addr2),"=r" (addr3):); + }while (0 ); + correctit =0 ; +for (breakno =0 ; breakno <3 ; breakno++) { + breakbit =2 << (breakno <<1 ); +if (!(dr7 & breakbit) && breakinfo[breakno].enabled) { + correctit =1 ; + dr7 |= breakbit; + dr7 &= ~(0xf0000 << (breakno <<2 )); + dr7 |= (((breakinfo[breakno].len <<2 ) | + breakinfo[breakno].type) <<16 ) << + (breakno <<2 ); +switch (breakno) { +case 0 : + asmvolatile ("movl %0, %%dr0\n" ::"r" + (breakinfo[breakno].addr)); +break ; + +case 1 : + asmvolatile ("movl %0, %%dr1\n" ::"r" + (breakinfo[breakno].addr)); +break ; + +case 2 : + asmvolatile ("movl %0, %%dr2\n" ::"r" + (breakinfo[breakno].addr)); +break ; + +case 3 : + asmvolatile ("movl %0, %%dr3\n" ::"r" + (breakinfo[breakno].addr)); +break ; + } + }else if ((dr7 & breakbit) && !breakinfo[breakno].enabled) { + correctit =1 ; + dr7 &= ~breakbit; + dr7 &= ~(0xf0000 << (breakno <<2 )); + } + } +if (correctit) + asmvolatile ("movl %0, %%db7\n" ::"r" (dr7)); +} + +void kgdb_disable_hw_debug (struct pt_regs *regs) +{ +/* Disable hardware debugging while we are in kgdb */ + asmvolatile ("movl %0,%%db7" :/* no output */ :"r" (0 )); +} + +void kgdb_post_master_code (struct pt_regs *regs,int e_vector,int err_code) +{ +/* Master processor is completely in the debugger */ + gdb_i386vector = e_vector; + gdb_i386errcode = err_code; +} + +void kgdb_roundup_cpus (unsigned long flags) +{ +send_IPI_allbutself (APIC_DM_NMI ); +} + +int kgdb_arch_handle_exception (int e_vector,int signo, +int err_code,char *remcom_in_buffer, +char *remcom_out_buffer, +struct pt_regs *linux_regs) +{ +long addr; +char *ptr; +int newPC, dr6; + +switch (remcom_in_buffer[0 ]) { +case 'c' : +case 's' : +/* try to read optional parameter, pc unchanged if no parm */ + ptr = &remcom_in_buffer[1 ]; +if (kgdb_hex2long (&ptr, &addr)) + linux_regs->eip = addr; + newPC = linux_regs->eip; + +/* clear the trace bit */ + linux_regs->eflags &= ~TF_MASK ; +atomic_set (&cpu_doing_single_step,-1 ); + +/* set the trace bit if we're stepping */ +if (remcom_in_buffer[0 ] =='s' ) { + linux_regs->eflags |=TF_MASK ; + debugger_step =1 ; +if (kgdb_contthread) +atomic_set (&cpu_doing_single_step, +smp_processor_id ()); + } + + asmvolatile ("movl %%db6, %0\n" :"=r" (dr6)); +if (!(dr6 &0x4000 )) { +long breakno; +for (breakno =0 ; breakno <4 ; ++breakno) { +if (dr6 & (1 << breakno) && + breakinfo[breakno].type ==0 ) { +/* Set restore flag */ + linux_regs->eflags |=X86_EFLAGS_RF ; +break ; + } + } + } +kgdb_correct_hw_break (); + asmvolatile ("movl %0, %%db6\n" ::"r" (0 )); + +return (0 ); + }/* switch */ +/* this means that we do not want to exit from the handler */ +return -1 ; +} + +/* Register KGDB with the i386die_chain so that we hook into all of the right +* spots. */ +static int kgdb_notify (struct notifier_block *self,unsigned long cmd, +void *ptr) +{ +struct die_args *args = ptr; +struct pt_regs *regs = args->regs; + +/* Bad memory access? */ +if (cmd ==DIE_PAGE_FAULT &&strcmp (args->str,"no context" ) ==0 && +atomic_read (&debugger_active) && kgdb_may_fault) { +kgdb_fault_longjmp (kgdb_fault_jmp_regs); +return NOTIFY_STOP ; + }else if (cmd ==DIE_PAGE_FAULT && +strcmp (args->str,"page fault" ) ==0 ) +/* A normal page fault, ignore. */ +return NOTIFY_DONE ; +else if (cmd ==DIE_NMI &&atomic_read (&debugger_active)) { +/* CPU roundup */ +kgdb_nmihook (smp_processor_id (), regs); +return NOTIFY_STOP ; + }else if (cmd ==DIE_NMI_IPI ||user_mode (regs) || + (cmd ==DIE_DEBUG &&atomic_read (&debugger_active))) +/* Normal watchdog event or userspace debugging, or spurious +* debug exception, ignore. */ +return NOTIFY_DONE ; + +kgdb_handle_exception (args->trapnr, args->signr, args->err, regs); + +return NOTIFY_STOP ; +} + +static struct notifier_block kgdb_notifier = { + .notifier_call = kgdb_notify, +}; + +int kgdb_arch_init (void ) +{ +notifier_chain_register (&i386die_chain, &kgdb_notifier); +return 0 ; +} + +struct kgdb_arch arch_kgdb_ops = { + .gdb_bpt_instr = {0xcc }, +};
arch/i386/kernel/kgdb-jmp.S new file +74 -0
74 lines not on this page · raw message
arch/i386/kernel/Makefile renamed from arch/i386/kernel/Makefile~i386-lite +1 -0
@@ -34,6 +34,7 @@ obj-$(CONFIG_ACPI_SRAT) += srat.o obj-$(CONFIG_HPET_TIMER) += time_hpet.o obj-$(CONFIG_EFI) += efi.o efi_stub.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +obj-$(CONFIG_KGDB) += kgdb.o kgdb-jmp.o EXTRA_AFLAGS := -traditional
arch/i386/kernel/setup.c renamed from arch/i386/kernel/setup.c~i386-lite +3 -0
@@ -147,6 +147,7 @@ EXPORT_SYMBOL(ist_info);struct e820map e820;extern void early_cpu_init (void ); +extern void early_trap_init (void );extern void dmi_scan_machine (void );extern void generic_apic_probe (char *);extern int root_mountflags;
@@ -1473,6 +1474,7 @@ void __init setup_arch(char **cmdline_p)memcpy (&boot_cpu_data, &new_cpu_data,sizeof (new_cpu_data));pre_setup_arch_hook ();early_cpu_init (); +early_trap_init ();/* * FIXME: This isn't an official loader_type right
@@ -1529,6 +1531,7 @@ void __init setup_arch(char **cmdline_p) data_resource.end =virt_to_phys (_edata)-1 ;parse_cmdline_early (cmdline_p); +parse_early_param (); max_low_pfn =setup_memory ();
arch/i386/kernel/traps.c renamed from arch/i386/kernel/traps.c~i386-lite +10 -5
@@ -337,7 +337,7 @@ void die(const char * str, struct pt_reg#endif if (nl)printk ("\n" ); -notify_die (DIE_OOPS , (char *)str, regs, err,255 ,SIGSEGV ); +notify_die (DIE_OOPS , (char *)str, regs, err,255 ,SIGSEGV );show_registers (regs); }else printk (KERN_ERR "Recursive die() failure, output suppressed\n" );
@@ -568,6 +568,7 @@ static DEFINE_SPINLOCK(nmi_print_lock);void die_nmi (struct pt_regs *regs,const char *msg) { +notify_die (DIE_NMIWATCHDOG ,"nmi watchdog" , regs,0 ,2 ,SIGPWR );spin_lock (&nmi_print_lock);/* * We are in trouble anyway, lets at least try
@@ -757,6 +758,7 @@ fastcall void do_debug(struct pt_regs **/ clear_dr7:set_debugreg (0 ,7 ); +notify_die (DIE_DEBUG ,"debug2" , regs, condition, error_code,SIGTRAP );return ; debug_vm86:
@@ -1058,6 +1060,12 @@ static void __init set_task_gate(unsigne_set_gate (idt_table+n,5 ,0 ,0 ,(gdt_entry<<3 )); } +/* Some traps need to be set early. */ +void __init early_trap_init (void ) { +set_intr_gate (1 ,&debug); +set_system_intr_gate (3 , &int3);/* int3 can be called from all */ +set_intr_gate (14 ,&page_fault); +}void __init trap_init (void ) {
@@ -1074,10 +1082,8 @@ void __init trap_init(void)#endif set_trap_gate (0 ,÷_error); -set_intr_gate (1 ,&debug);set_intr_gate (2 ,&nmi); -set_system_intr_gate (3 , &int3);/* int3-5 can be called from all */ -set_system_gate (4 ,&overflow); +set_system_gate (4 ,&overflow);/* int4/5 can be called from all */ set_system_gate (5 ,&bounds);set_trap_gate (6 ,&invalid_op);set_trap_gate (7 ,&device_not_available);
@@ -1087,7 +1093,6 @@ void __init trap_init(void)set_trap_gate (11 ,&segment_not_present);set_trap_gate (12 ,&stack_segment);set_trap_gate (13 ,&general_protection); -set_intr_gate (14 ,&page_fault);set_trap_gate (15 ,&spurious_interrupt_bug);set_trap_gate (16 ,&coprocessor_error);set_trap_gate (17 ,&alignment_check);
arch/i386/mm/fault.c renamed from arch/i386/mm/fault.c~i386-lite +4 -0
@@ -424,6 +424,10 @@ no_context:if (is_prefetch (regs, address, error_code))return ; +if (notify_die (DIE_PAGE_FAULT ,"no context" , regs, error_code,14 , +SIGSEGV ) ==NOTIFY_STOP ) +return ; +/* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice.
include/asm-i386/kgdb.h new file +50 -0
50 lines not on this page · raw message
include/asm-i386/system.h renamed from include/asm-i386/system.h~i386-lite +8 -2
@@ -12,9 +12,13 @@struct task_struct ;/* one of the stranger aspects of C forward declarations.. */ extern struct task_struct *FASTCALL (__switch_to (struct task_struct *prev,struct task_struct *next)); +/* sleeping_thread_to_gdb_regs depends on this code. Correct it if you change +* any of the following */ #define switch_to (prev,next,last) do { \ unsigned long esi,edi; \ - asm volatile("pushfl\n\t" \ + asm volatile(".globl __switch_to_begin\n" \ + "__switch_to_begin:" \ + "pushfl\n\t" \ "pushl %%ebp\n\t" \ "movl %%esp,%0\n\t"/* save ESP */ \"movl %5,%%esp\n\t" /* restore ESP */ \
@@ -23,7 +27,9 @@ extern struct task_struct * FASTCALL(__s "jmp __switch_to\n" \ "1:\t" \ "popl %%ebp\n\t" \ - "popfl" \ + "popfl\n" \ + ".globl __switch_to_end\n" \ + "__switch_to_end:\n" \ :"=m" (prev->thread.esp),"=m" (prev->thread.eip), \ "=a" (last),"=S" (esi),"=D" (edi) \:" m" (next->thread.esp)," m" (next->thread.eip), \
lib/Kconfig.debug renamed from lib/Kconfig.debug~i386-lite +1 -1
@@ -163,7 +163,7 @@ config FRAME_POINTER config KGDB bool "KGDB: kernel debugging with remote gdb" select WANT_EXTRA_DEBUG_INFORMATION - depends on DEBUG_KERNEL + depends on DEBUG_KERNEL && (X86) help If you say Y here, it will be possible to remotely debug the kernel using gdb. It is strongly suggested that you enable
_
PATCH 3/16 Add support for PowerPC32 platforms to KGDB
This adds basic KGDB support to ppc32 (classic, e500 and 4xx), and support for kgdb8250 to a number of boards. This was done mostly myself with some help from Scott Hall for e500 and Frank Rowand pointed out some parts as he did the ppc64 code, as well as Takeharu KATO <[email protected]> for some of the 4xx code and testing.
arch/ppc/Kconfig.debug +0 -36
@@ -2,42 +2,6 @@ menu "Kernel hacking" source "lib/Kconfig.debug" -config KGDB - bool "Include kgdb kernel debugger" - depends on DEBUG_KERNEL && (BROKEN || PPC_GEN550 || 4xx) - select DEBUG_INFO - help - Include in-kernel hooks for kgdb, the Linux kernel source level - debugger. See <http://kgdb.sourceforge.net/> for more information. - Unless you are intending to debug the kernel, say N here. - -choice - prompt "Serial Port" - depends on KGDB - default KGDB_TTYS1 - -config KGDB_TTYS0 - bool "ttyS0" - -config KGDB_TTYS1 - bool "ttyS1" - -config KGDB_TTYS2 - bool "ttyS2" - -config KGDB_TTYS3 - bool "ttyS3" - -endchoice - -config KGDB_CONSOLE - bool "Enable serial console thru kgdb port" - depends on KGDB && 8xx || CPM2 - help - If you enable this, all serial console messages will be sent - over the gdb stub. - If unsure, say N. - config XMON bool "Include xmon kernel debugger" depends on DEBUG_KERNEL
arch/ppc/kernel/kgdb.c new file +329 -0
329 lines not on this page · raw message
arch/ppc/kernel/Makefile +1 -1
@@ -22,7 +22,7 @@ obj-$(CONFIG_POWER4) += cpu_setup_power obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o obj-$(CONFIG_PCI) += pci.o -obj-$(CONFIG_KGDB) += ppc-stub.o +obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_SMP) += smp.o smp-tbsync.o obj-$(CONFIG_TAU) += temp.o obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
arch/ppc/kernel/ppc-stub.c deleted +0 -867
867 lines not on this page · raw message
arch/ppc/kernel/setup.c +0 -16
@@ -45,10 +45,6 @@#include <asm/ppc_sys.h> #endif -#if definedCONFIG_KGDB -#include <asm/kgdb.h> -#endif -extern void platform_init (unsigned long r3,unsigned long r4,unsigned long r5,unsigned long r6,unsigned long r7);extern void bootx_init (unsigned long r4,unsigned long phys);
@@ -703,18 +699,6 @@ void __init setup_arch(char **cmdline_p)#endif /* CONFIG_XMON */ if ( ppc_md.progress ) ppc_md.progress ("setup_arch: enter" ,0x3eab ); -#if defined(CONFIG_KGDB ) -if (ppc_md.kgdb_map_scc) - ppc_md.kgdb_map_scc (); -set_debug_traps (); -if (strstr (cmd_line,"gdb" )) { -if (ppc_md.progress) - ppc_md.progress ("setup_arch: kgdb breakpoint" ,0x4000 ); -printk ("kgdb breakpoint activated\n" ); -breakpoint (); - } -#endif -/* * Set cache line size based on type of cpu as a default. * Systems with OF can look in the properties on the cpu node(s)
arch/ppc/mm/fault.c +9 -0
@@ -28,6 +28,7 @@#include <linux/interrupt.h> #include <linux/highmem.h> #include <linux/module.h> +#include <linux/kgdb.h> #include <asm/page.h> #include <asm/pgtable.h>
@@ -332,6 +333,14 @@ bad_page_fault(struct pt_regs *regs, unsreturn ; } +#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 +/* kernel has accessed a bad area */ #if defined(CONFIG_XMON ) || defined(CONFIG_KGDB )if (debugger_kernel_faults)
arch/ppc/platforms/4xx/bubinga.c +14 -9
@@ -4,7 +4,7 @@* Author: SAW (IBM), derived from walnut.c. * Maintained by MontaVista Software <[email protected]> * -* 2003 (c) MontaVista Softare Inc. This file is licensed under the +* 2003-2004 (c) MontaVista Softare Inc. This file is licensed under the * terms of the GNU General Public License version 2. This program is * licensed "as is" without any warranty of any kind, whether express * or implied.
@@ -101,17 +101,26 @@ bubinga_early_serial_map(void) port.flags =ASYNC_BOOT_AUTOCONF |ASYNC_SKIP_TEST ; port.line =0 ; -if (early_serial_setup (&port) !=0 ) { +#ifdef CONFIG_SERIAL_8250 +if (early_serial_setup (&port) !=0 )printk ("Early serial init of port 0 failed\n" ); - } +#endif + +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (0 , &port); +#endif port.membase = (void *)ACTING_UART1_IO_BASE ; port.irq =ACTING_UART1_INT ; port.line =1 ; -if (early_serial_setup (&port) !=0 ) { +#ifdef CONFIG_SERIAL_8250 +if (early_serial_setup (&port) !=0 )printk ("Early serial init of port 1 failed\n" ); - } +#endif +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (1 , &port); +#endif }void __init
@@ -256,8 +265,4 @@ platform_init(unsigned long r3, unsigned ppc_md.nvram_read_val = todc_direct_read_val; ppc_md.nvram_write_val = todc_direct_write_val;#endif -#ifdef CONFIG_KGDB - ppc_md.early_serial_map = bubinga_early_serial_map; -#endif } -
arch/ppc/platforms/4xx/ebony.c +17 -10
@@ -36,6 +36,7 @@#include <linux/tty.h> #include <linux/serial.h> #include <linux/serial_core.h> +#include <linux/kgdb.h> #include <asm/system.h> #include <asm/pgtable.h>
@@ -242,14 +243,20 @@ ebony_early_serial_map(void) port.flags =ASYNC_BOOT_AUTOCONF |ASYNC_SKIP_TEST ; port.line =0 ; -if (early_serial_setup (&port) !=0 ) { +#ifdef CONFIG_SERIAL_8250 +if (early_serial_setup (&port) !=0 )printk ("Early serial init of port 0 failed\n" ); - } +#endif -#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB ) +#ifdef CONFIG_SERIAL_TEXT_DEBUG /* Configure debug serial access */ gen550_init (0 , &port); +#endif +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (0 , &port); +#endif +#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB_8250 )/* Purge TLB entry added in head_44x.S for early serial access */ _tlbie (UART0_IO_BASE );#endif
@@ -259,14 +266,18 @@ ebony_early_serial_map(void) port.uartclk = clocks.uart1; port.line =1 ; -if (early_serial_setup (&port) !=0 ) { +#ifdef CONFIG_SERIAL_8250 +if (early_serial_setup (&port) !=1 )printk ("Early serial init of port 1 failed\n" ); - } +#endif -#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB ) +#ifdef CONFIG_SERIAL_TEXT_DEBUG /* Configure debug serial access */ gen550_init (1 , &port);#endif +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (1 , &port); +#endif } static void __init
@@ -352,8 +363,4 @@ void __init platform_init(unsigned long ppc_md.nvram_read_val = todc_direct_read_val; ppc_md.nvram_write_val = todc_direct_write_val; -#ifdef CONFIG_KGDB - ppc_md.early_serial_map = ebony_early_serial_map; -#endif } -
arch/ppc/platforms/4xx/ocotea.c +17 -9
@@ -34,6 +34,7 @@#include <linux/tty.h> #include <linux/serial.h> #include <linux/serial_core.h> +#include <linux/kgdb.h> #include <asm/system.h> #include <asm/pgtable.h>
@@ -260,14 +261,20 @@ ocotea_early_serial_map(void) port.flags =ASYNC_BOOT_AUTOCONF |ASYNC_SKIP_TEST ; port.line =0 ; -if (early_serial_setup (&port) !=0 ) { +#ifdef CONFIG_SERIAL_8250 +if (early_serial_setup (&port) !=0 )printk ("Early serial init of port 0 failed\n" ); - } +#endif -#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB ) +#ifdef CONFIG_SERIAL_TEXT_DEBUG /* Configure debug serial access */ gen550_init (0 , &port); +#endif +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (0 , &port); +#endif +#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB_8250 )/* Purge TLB entry added in head_44x.S for early serial access */ _tlbie (UART0_IO_BASE );#endif
@@ -277,14 +284,18 @@ ocotea_early_serial_map(void) port.uartclk = clocks.uart1; port.line =1 ; -if (early_serial_setup (&port) !=0 ) { +#ifdef CONFIG_SERIAL_8250 +if (early_serial_setup (&port) !=1 )printk ("Early serial init of port 1 failed\n" ); - } +#endif -#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB ) +#ifdef CONFIG_SERIAL_TEXT_DEBUG /* Configure debug serial access */ gen550_init (1 , &port);#endif +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (1 , &port); +#endif } static void __init
@@ -363,8 +374,5 @@ void __init platform_init(unsigned long ppc_md.nvram_read_val = todc_direct_read_val; ppc_md.nvram_write_val = todc_direct_write_val; -#ifdef CONFIG_KGDB - ppc_md.early_serial_map = ocotea_early_serial_map; -#endif ppc_md.init = ocotea_init; }
arch/ppc/platforms/4xx/xilinx_ml300.c +6 -12
@@ -42,9 +42,6 @@* ppc4xx_map_io arch/ppc/syslib/ppc4xx_setup.c * start_kernel init/main.c * setup_arch arch/ppc/kernel/setup.c -* #if defined(CONFIG_KGDB) -* *ppc_md.kgdb_map_scc() == gen550_kgdb_map_scc -* #endif * *ppc_md.setup_arch == ml300_setup_arch this file * ppc4xx_setup_arch arch/ppc/syslib/ppc4xx_setup.c * ppc4xx_find_bridges arch/ppc/syslib/ppc405_pci.c
@@ -83,7 +80,6 @@ ml300_map_io(void)static void __init ml300_early_serial_map (void ) { -#ifdef CONFIG_SERIAL_8250 struct serial_state old_ports[] = {SERIAL_PORT_DFNS };struct uart_port port;int i;
@@ -99,11 +95,14 @@ ml300_early_serial_map(void) port.flags =ASYNC_BOOT_AUTOCONF |ASYNC_SKIP_TEST ; port.line = i; -if (early_serial_setup (&port) !=0 ) { +#ifdef CONFIG_SERIAL_8250 +if (early_serial_setup (&port) !=0 )printk ("Early serial init of port %d failed\n" , i); - } +#endif +#ifdef CONFIG_KGDB_8250 + kgdb8250_add_port(i, &port) +#endif } -#endif /* CONFIG_SERIAL_8250 */ }void __init
@@ -138,9 +137,4 @@ platform_init(unsigned long r3, unsigned#if defined(XPAR_POWER_0_POWERDOWN_BASEADDR ) ppc_md.power_off = xilinx_power_off;#endif - -#ifdef CONFIG_KGDB - ppc_md.early_serial_map = ml300_early_serial_map; -#endif } -
arch/ppc/platforms/85xx/sbc8560.c +20 -16
@@ -54,7 +54,6 @@#include <syslib/ppc85xx_common.h> #include <syslib/ppc85xx_setup.h> -#ifdef CONFIG_SERIAL_8250 static void __init sbc8560_early_serial_map (void ) {
@@ -70,27 +69,34 @@ sbc8560_early_serial_map(void) uart_req.membase =ioremap (uart_req.mapbase, MPC85xx_UART0_SIZE); uart_req.type =PORT_16650 ; -#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB ) -gen550_init (0 , &uart_req); +#ifdef CONFIG_SERIAL_8250 +if (early_serial_setup (&uart_req) !=0 ) +printk ("Early serial init of port 0 failed\n" );#endif - -if (early_serial_setup (&uart_req) !=0 ) -printk ("Early serial init of port 0 failed\n" ); - +#ifdef CONFIG_SERIAL_TEXT_DEBUG +gen550_init (0 , &uart_req); +#endif +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (0 , &uart_req); +#endif +/* Assume early_serial_setup() doesn't modify uart_req */ uart_req.line =1 ; uart_req.mapbase =UARTB_ADDR ; uart_req.membase =ioremap (uart_req.mapbase, MPC85xx_UART1_SIZE); uart_req.irq = MPC85xx_IRQ_EXT10; - -#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB ) -gen550_init (1 , &uart_req); + +#ifdef CONFIG_SERIAL_8250 +if (early_serial_setup (&uart_req) !=0 ) +printk ("Early serial init of port 1 failed\n" );#endif - -if (early_serial_setup (&uart_req) !=0 ) - printk("Early serial init of port 1 failed\n"); -} +#ifdef CONFIG_SERIAL_TEXT_DEBUG +gen550_init (1 , &uart_req);#endif +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (1 , &uart_req); +#endif +}/* ************************************************************************ *
@@ -118,9 +124,7 @@ sbc8560_setup_arch(void)/* setup PCI host bridges */ mpc85xx_setup_hose ();#endif -#ifdef CONFIG_SERIAL_8250 sbc8560_early_serial_map (); -#endif #ifdef CONFIG_SERIAL_TEXT_DEBUG /* Invalidate the entry we stole earlier the serial ports * should be properly mapped */
arch/ppc/platforms/chestnut.c +1 -4
@@ -496,7 +496,7 @@ chestnut_power_off(void)static void __init chestnut_map_io (void ) { -#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB ) +#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB_8250 )io_block_mapping (CHESTNUT_UART_BASE ,CHESTNUT_UART_BASE ,0x100000 , _PAGE_IO);#endif
@@ -571,9 +571,6 @@ platform_init(unsigned long r3, unsigned#if defined(CONFIG_SERIAL_TEXT_DEBUG ) ppc_md.progress = gen550_progress;#endif -#if defined(CONFIG_KGDB ) - ppc_md.kgdb_map_scc = gen550_kgdb_map_scc; -#endif if (ppc_md.progress) ppc_md.progress ("chestnut_init(): exit" ,0 );
arch/ppc/platforms/cpci690.c +4 -6
@@ -429,7 +429,7 @@ cpci690_set_bat(u32 addr, u32 size)mb (); } -#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB ) +#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB_MPSC )static void __init cpci690_map_io (void ) {
@@ -475,15 +475,13 @@ platform_init(unsigned long r3, unsignedcpci690_set_bat (CPCI690_BR_BASE ,32 *MB ); cpci690_br_base =CPCI690_BR_BASE ; -#ifdef CONFIG_SERIAL_TEXT_DEBUG +#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB_MPSC ) ppc_md.setup_io_mappings = cpci690_map_io; +#ifdef CONFIG_SERIAL_TEXT_DEBUG ppc_md.progress = mv64x60_mpsc_progress;mv64x60_progress_init (CONFIG_MV64X60_NEW_BASE );#endif /* CONFIG_SERIAL_TEXT_DEBUG */ -#ifdef CONFIG_KGDB - ppc_md.setup_io_mappings = cpci690_map_io; - ppc_md.early_serial_map = cpci690_early_serial_map; -#endif /* CONFIG_KGDB */ +#endif /* defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB_MPSC) */ #if defined(CONFIG_SERIAL_MPSC ) platform_notify = cpci690_platform_notify;
arch/ppc/platforms/mcpn765.c +0 -5
@@ -519,9 +519,4 @@ platform_init(unsigned long r3, unsigned#ifdef CONFIG_SERIAL_TEXT_DEBUG ppc_md.progress = gen550_progress;#endif -#ifdef CONFIG_KGDB - ppc_md.kgdb_map_scc = gen550_kgdb_map_scc; -#endif - -return ; }
arch/ppc/platforms/pcore.c +0 -3
@@ -346,7 +346,4 @@ platform_init(unsigned long r3, unsigned#ifdef CONFIG_SERIAL_TEXT_DEBUG ppc_md.progress = gen550_progress;#endif -#ifdef CONFIG_KGDB - ppc_md.kgdb_map_scc = gen550_kgdb_map_scc; -#endif }
arch/ppc/platforms/pplus.c +0 -3
@@ -908,9 +908,6 @@ platform_init(unsigned long r3, unsigned#ifdef CONFIG_SERIAL_TEXT_DEBUG ppc_md.progress = gen550_progress;#endif /* CONFIG_SERIAL_TEXT_DEBUG */ -#ifdef CONFIG_KGDB - ppc_md.kgdb_map_scc = gen550_kgdb_map_scc; -#endif #ifdef CONFIG_SMP ppc_md.smp_ops = &pplus_smp_ops;#endif /* CONFIG_SMP */
arch/ppc/platforms/sandpoint.c +0 -3
@@ -751,9 +751,6 @@ platform_init(unsigned long r3, unsigned ppc_md.nvram_read_val = todc_mc146818_read_val; ppc_md.nvram_write_val = todc_mc146818_write_val; -#ifdef CONFIG_KGDB - ppc_md.kgdb_map_scc = gen550_kgdb_map_scc; -#endif #ifdef CONFIG_SERIAL_TEXT_DEBUG ppc_md.progress = gen550_progress;#endif
arch/ppc/platforms/spruce.c +12 -9
@@ -181,26 +181,32 @@ spruce_early_serial_map(void) serial_req.membase = (u_char *)UART0_IO_BASE ; serial_req.regshift =0 ; -#if defined(CONFIG_KGDB ) || defined(CONFIG_SERIAL_TEXT_DEBUG ) -gen550_init (0 , &serial_req); -#endif #ifdef CONFIG_SERIAL_8250 if (early_serial_setup (&serial_req) !=0 )printk ("Early serial init of port 0 failed\n" );#endif +#ifdef CONFIG_SERIAL_TEXT_DEBUG +gen550_init (0 , &serial_req); +#endif +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (0 , &port); +#endif /* Assume early_serial_setup() doesn't modify serial_req */ serial_req.line =1 ; serial_req.irq =UART1_INT ; serial_req.membase = (u_char *)UART1_IO_BASE ; -#if defined(CONFIG_KGDB ) || defined(CONFIG_SERIAL_TEXT_DEBUG ) -gen550_init (1 , &serial_req); -#endif #ifdef CONFIG_SERIAL_8250 if (early_serial_setup (&serial_req) !=0 )printk ("Early serial init of port 1 failed\n" );#endif +#ifdef CONFIG_SERIAL_TEXT_DEBUG +gen550_init (1 , &serial_req); +#endif +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (1 , &serial_req); +#endif }TODC_ALLOC ();
@@ -319,7 +325,4 @@ platform_init(unsigned long r3, unsigned#ifdef CONFIG_SERIAL_TEXT_DEBUG ppc_md.progress = gen550_progress;#endif /* CONFIG_SERIAL_TEXT_DEBUG */ -#ifdef CONFIG_KGDB - ppc_md.kgdb_map_scc = gen550_kgdb_map_scc; -#endif }
arch/ppc/syslib/gen550.h +0 -1
@@ -13,4 +13,3 @@extern void gen550_progress (char *,unsigned short );extern void gen550_init (int ,struct uart_port *); -extern void gen550_kgdb_map_scc (void );
arch/ppc/syslib/gen550_kgdb.c deleted +0 -86
86 lines not on this page · raw message
arch/ppc/syslib/ibm44x_common.c +0 -3
@@ -161,9 +161,6 @@ void __init ibm44x_platform_init(void)#ifdef CONFIG_SERIAL_TEXT_DEBUG ppc_md.progress = gen550_progress;#endif /* CONFIG_SERIAL_TEXT_DEBUG */ -#ifdef CONFIG_KGDB - ppc_md.kgdb_map_scc = gen550_kgdb_map_scc; -#endif /* * The Abatron BDI JTAG debugger does not tolerate others
arch/ppc/syslib/Makefile +0 -1
@@ -87,7 +87,6 @@ obj-$(CONFIG_PCI_8260) += m82xx_pci.o i obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o ifeq ($(CONFIG_PPC_GEN550),y) -obj-$(CONFIG_KGDB) += gen550_kgdb.o gen550_dbg.o obj-$(CONFIG_SERIAL_TEXT_DEBUG) += gen550_dbg.o endif ifeq ($(CONFIG_SERIAL_MPSC_CONSOLE),y)
arch/ppc/syslib/mv64x60.c +54 -2
84 lines not on this page · raw message
arch/ppc/syslib/mv64x60_dbg.c +1 -51
61 lines not on this page · raw message
arch/ppc/syslib/ppc85xx_setup.c +8 -5
@@ -71,7 +71,6 @@ mpc85xx_calibrate_decr(void)mtspr (SPRN_TCR ,TCR_DIE ); } -#ifdef CONFIG_SERIAL_8250 void __init mpc85xx_early_serial_map (void ) {
@@ -87,7 +86,7 @@ mpc85xx_early_serial_map(void) pdata[0 ].mapbase += binfo->bi_immr_base; pdata[0 ].membase =ioremap (pdata[0 ].mapbase, MPC85xx_UART0_SIZE); -#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB ) +#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB_8250 )memset (&serial_req,0 ,sizeof (serial_req)); serial_req.iotype =SERIAL_IO_MEM ; serial_req.mapbase = pdata[0 ].mapbase;
@@ -95,18 +94,24 @@ mpc85xx_early_serial_map(void) serial_req.regshift =0 ;gen550_init (0 , &serial_req); +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (0 , &serial_req); +#endif #endif pdata[1 ].uartclk = binfo->bi_busfreq; pdata[1 ].mapbase += binfo->bi_immr_base; pdata[1 ].membase =ioremap (pdata[1 ].mapbase, MPC85xx_UART0_SIZE); -#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB ) +#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB_8250 )/* Assume gen550_init() doesn't modify serial_req */ serial_req.mapbase = pdata[1 ].mapbase; serial_req.membase = pdata[1 ].membase;gen550_init (1 , &serial_req); +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (1 , &serial_req); +#endif #endif }#endif
@@ -365,5 +370,3 @@ mpc85xx_setup_hose(void) return; }#endif /* CONFIG_PCI */ - -
drivers/serial/kgdb_mpsc.c new file +313 -0
313 lines not on this page · raw message
drivers/serial/Makefile +1 -0
@@ -50,6 +50,7 @@ obj-$(CONFIG_SERIAL_IMX) += imx.o obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o obj-$(CONFIG_SERIAL_ICOM) += icom.o obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_sio.o +obj-$(CONFIG_KGDB_MPSC) += kgdb_mpsc.o obj-$(CONFIG_SERIAL_MPSC) += mpsc.o obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o obj-$(CONFIG_SERIAL_JSM) += jsm/
drivers/serial/mpsc.h +4 -0
@@ -207,6 +207,10 @@ struct mpsc_port_info *mpsc_device_remov#define MPSC_RCRR 0x0004#define MPSC_TCRR 0x0008 +/* MPSC Interrupt registers (offset from MV64x60_SDMA_INTR_OFFSET) */ +#define MPSC_INTR_CAUSE 0x0004 +#define MPSC_INTR_MASK 0x0084 +#define MPSC_INTR_CAUSE_RCC (1<<6)/* ***************************************************************************** *
include/asm-ppc/kgdb.h +18 -30
70 lines not on this page · raw message
include/asm-ppc/machdep.h +0 -2
@@ -59,9 +59,7 @@ struct machdep_calls {unsigned long (*find_end_of_memory)(void );void (*setup_io_mappings)(void ); -void (*early_serial_map)(void );void (*progress)(char *,unsigned short ); -void (*kgdb_map_scc)(void );unsigned char (*nvram_read_val)(int addr);void (*nvram_write_val)(int addr,unsigned char val);
include/asm-ppc/mv64x60_defs.h +2 -1
@@ -57,7 +57,8 @@#define MV64x60_IRQ_I2C 37#define MV64x60_IRQ_BRG 39#define MV64x60_IRQ_MPSC_0 40 -#define MV64x60_IRQ_MPSC_1 42 +#define MV64360_IRQ_MPSC_1 41 +#define GT64260_IRQ_MPSC_1 42#define MV64x60_IRQ_COMM 43#define MV64x60_IRQ_P0_GPP_0_7 56#define MV64x60_IRQ_P0_GPP_8_15 57
include/asm-ppc/mv64x60.h +2 -0
@@ -332,6 +332,8 @@ u32 mv64x60_calc_mem_size(struct mv64x60void mv64x60_progress_init (u32 base);void mv64x60_mpsc_progress (char *s,unsigned short hex); +struct platform_device *mv64x60_early_get_pdev_data (const char *name, +int id,int remove);extern struct mv64x60_32bit_window gt64260_32bit_windows[MV64x60_32BIT_WIN_COUNT];
lib/Kconfig.debug +9 -1
@@ -168,7 +168,7 @@ config WANT_EXTRA_DEBUG_INFORMATION config KGDB bool "KGDB: kernel debugging with remote gdb" select WANT_EXTRA_DEBUG_INFORMATION - depends on DEBUG_KERNEL && (X86) + depends on DEBUG_KERNEL && (X86 || ((!SMP || BROKEN) && (PPC32))) help If you say Y here, it will be possible to remotely debug the kernel using gdb. It is strongly suggested that you enable
@@ -194,6 +194,7 @@ choice prompt "Method for KGDB communication" depends on KGDB default KGDB_ONLY_MODULES + default KGDB_MPSC if SERIAL_MPSC help There are a number of different ways in which you can communicate with KGDB. The most common is via serial, with the 8250 driver
@@ -210,4 +211,11 @@ config KGDB_ONLY_MODULES Use only kernel modules to configure KGDB I/O after the kernel is booted. +config KGDB_MPSC + bool "KGDB on MV64x60 MPSC" + depends on SERIAL_MPSC + help + Uses a Marvell GT64260B or MV64x60 Multi-Purpose Serial + Controller (MPSC) channel. Note that the GT64260A is not + supported. endchoice
_
PATCH 4/16 I/O driver for 8250-compatible UARTs
CC: Russell King <[email protected]>
This is the I/O driver for any 8250-compatible UARTs. This also adds some small hooks into the normal serial core so that we can take away the uart and make sure only KGDB is trying to use it. We also make sure that if KGDB_8250 is enabled, SERIAL_8250_NR_UARTS is set to the default of 4. This is so that if we can always depend on that constant in the 8250 driver for giving our table a size. To make it easier (or in some cases, possible) to free up ports on a shared irq system, we add a line member to plat_serial8250_port.
Since the last time this was submitted, I believe that all of the objections that Russell King noted have been fixed.
---
linux-2.6.13-trini/drivers/serial/8250.c | 21 linux-2.6.13-trini/drivers/serial/8250.h | 1 linux-2.6.13-trini/drivers/serial/Kconfig | 2 linux-2.6.13-trini/drivers/serial/Makefile | 1 linux-2.6.13-trini/drivers/serial/kgdb_8250.c | 594 +++++++++++++++++++++ linux-2.6.13-trini/include/linux/kgdb.h | 3 linux-2.6.13-trini/include/linux/serial_8250.h | 1 linux-2.6.13-trini/lib/Kconfig.debug | 92 +++ 8 files changed, 712 insertions(+), 3 deletions(-)
drivers/serial/8250.c renamed from drivers/serial/8250.c~8250 +21 -0
@@ -2516,6 +2516,27 @@ void serial8250_unregister_port(int line }EXPORT_SYMBOL (serial8250_unregister_port); +/** +* serial8250_unregister_by_port - remove a 16x50 serial port +* at runtime. +* @port: A &struct uart_port that describes the port to remove. +* +* Remove one serial port. This may not be called from interrupt +* context. We hand the port back to the our control. +*/ +void serial8250_unregister_by_port (struct uart_port *port) +{ +struct uart_8250_port *uart; + +down (&serial_sem); + uart =serial8250_find_match_or_unused (port); +up (&serial_sem); + +if (uart) +serial8250_unregister_port (uart->port.line); +} +EXPORT_SYMBOL (serial8250_unregister_by_port); +static int __init serial8250_init (void ) {int ret, i;
drivers/serial/8250.h renamed from drivers/serial/8250.h~8250 +1 -0
@@ -19,6 +19,7 @@int serial8250_register_port (struct uart_port *);void serial8250_unregister_port (int line); +void serial8250_unregister_by_port (struct uart_port *port);void serial8250_suspend_port (int line);void serial8250_resume_port (int line);
drivers/serial/Kconfig renamed from drivers/serial/Kconfig~8250 +1 -1
@@ -87,7 +87,7 @@ config SERIAL_8250_ACPI config SERIAL_8250_NR_UARTS int "Maximum number of 8250/16550 serial ports" - depends on SERIAL_8250 + depends on SERIAL_8250 || KGDB_8250 default "4" help Set this to the number of serial ports you want the driver
drivers/serial/kgdb_8250.c new file +594 -0
594 lines not on this page · raw message
drivers/serial/Makefile renamed from drivers/serial/Makefile~8250 +1 -0
@@ -57,3 +57,4 @@ obj-$(CONFIG_SERIAL_JSM) += jsm/ obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o +obj-$(CONFIG_KGDB_8250) += kgdb_8250.o
include/linux/kgdb.h renamed from include/linux/kgdb.h~8250 +2 -1
@@ -224,7 +224,7 @@ typedef unsigned char threadref[8];*/ struct kgdb_io {int (*read_char) (void ); -void (*write_char) (int ); +void (*write_char) (u8 );void (*flush) (void );int (*init) (void );void (*late_init) (void );
@@ -241,6 +241,7 @@ extern void kgdb_unregister_io_module(stextern void kgdb8250_add_port (int i,struct uart_port *serial_req);extern void kgdb8250_add_platform_port (int i,struct plat_serial8250_port *serial_req); +extern int kgdb8250_get_ttyS (void );extern int kgdb_hex2long (char **ptr,long *long_val);extern char *kgdb_mem2hex (char *mem,char *buf,int count);
include/linux/serial_8250.h renamed from include/linux/serial_8250.h~8250 +1 -0
@@ -24,6 +24,7 @@ struct plat_serial8250_port {unsigned char iotype;/* UPIO_* */ unsigned char hub6;unsigned int flags;/* UPF_* flags */ + unsigned int line; /* logical line number */ };#endif
lib/Kconfig.debug renamed from lib/Kconfig.debug~8250 +91 -1
108 lines not on this page · raw message
_
PATCH 5/16 Add support for MIPS platforms to KGDB
This adds basic support to the MIPS architecture as well as support specifically for the MIPS Malta and SiByte 1250-SWARM (32 and 64bit), all from Manish Lachwani. This looks like it should work on anything with an 8250-compatible uart, and be fairly easy to convert other boards custom uarts as needed.
---
linux-2.6.13-trini/arch/mips/Kconfig.debug | 19 linux-2.6.13-trini/arch/mips/kernel/Makefile | 3 linux-2.6.13-trini/arch/mips/kernel/irq.c | 32 linux-2.6.13-trini/arch/mips/kernel/kgdb-jmp.c | 116 + linux-2.6.13-trini/arch/mips/kernel/kgdb-setjmp.S | 27 linux-2.6.13-trini/arch/mips/kernel/kgdb.c | 296 ++ linux-2.6.13-trini/arch/mips/kernel/kgdb_handler.S | 58 linux-2.6.13-trini/arch/mips/kernel/traps.c | 26 linux-2.6.13-trini/arch/mips/mips-boards/generic/Makefile | 1 linux-2.6.13-trini/arch/mips/mips-boards/generic/init.c | 62 linux-2.6.13-trini/arch/mips/mips-boards/malta/malta_setup.c | 8 linux-2.6.13-trini/arch/mips/mm/extable.c | 7 linux-2.6.13-trini/arch/mips/sibyte/cfe/setup.c | 14 linux-2.6.13-trini/arch/mips/sibyte/sb1250/Makefile | 1 linux-2.6.13-trini/arch/mips/sibyte/sb1250/irq.c | 57 linux-2.6.13-trini/arch/mips/sibyte/sb1250/irq_handler.S | 2 linux-2.6.13-trini/arch/mips/sibyte/sb1250/kgdb_sibyte.c | 164 + linux-2.6.13-trini/arch/mips/sibyte/swarm/Makefile | 2 linux-2.6.13-trini/include/asm-mips/kdebug.h | 47 linux-2.6.13-trini/include/asm-mips/kgdb.h | 22 linux-2.6.13-trini/lib/Kconfig.debug | 7 linux-2.6.13/arch/mips/kernel/gdb-low.S | 370 --- linux-2.6.13/arch/mips/kernel/gdb-stub.c | 1091 ---------- linux-2.6.13/arch/mips/sibyte/swarm/dbg_io.c | 76 24 files changed, 791 insertions(+), 1717 deletions(-)
arch/mips/Kconfig.debug renamed from arch/mips/Kconfig.debug~mips-lite +0 -19
@@ -27,25 +27,6 @@ config DEBUG_STACK_USAGE This option will slow down process creation somewhat. -config KGDB - bool "Remote GDB kernel debugging" - depends on DEBUG_KERNEL - select DEBUG_INFO - help - If you say Y here, it will be possible to remotely debug the MIPS - kernel using gdb. This enlarges your kernel image disk size by - several megabytes and requires a machine with more than 16 MB, - better 32 MB RAM to avoid excessive linking time. This is only - useful for kernel hackers. If unsure, say N. - -config GDB_CONSOLE - bool "Console output to GDB" - depends on KGDB - help - If you are using GDB for remote debugging over a serial port and - would like kernel messages to be formatted into GDB $O packets so - that GDB prints them as program output, say 'Y'. - config SB1XXX_CORELIS bool "Corelis Debugger" depends on SIBYTE_SB1xxx_SOC
arch/mips/kernel/gdb-low.S deleted +0 -370
370 lines not on this page · raw message
arch/mips/kernel/gdb-stub.c deleted +0 -1091
1,091 lines not on this page · raw message
arch/mips/kernel/irq.c renamed from arch/mips/kernel/irq.c~mips-lite +13 -19
@@ -26,6 +26,10 @@#include <asm/atomic.h> #include <asm/system.h> #include <asm/uaccess.h> +#include <asm/kgdb.h> + +/* Keep track of if we've done certain initialization already or not. */ +int kgdb_early_setup;/* * 'what should we do if we get a hw irq event on an illegal vector'.
@@ -103,23 +107,13 @@ skip:return 0 ; } -#ifdef CONFIG_KGDB -extern void breakpoint (void ); -extern void set_debug_traps (void ); - -static int kgdb_flag =1 ; -static int __init nokgdb (char *str) -{ - kgdb_flag =0 ; -return 1 ; -} -__setup ("nokgdb" , nokgdb); -#endif -void __init init_IRQ (void ) {int i; +if (kgdb_early_setup) +return ; +for (i =0 ; i <NR_IRQS ; i++) { irq_desc[i].status =IRQ_DISABLED ; irq_desc[i].action =NULL ;
@@ -129,12 +123,12 @@ void __init init_IRQ(void) }arch_init_irq (); -#ifdef CONFIG_KGDB -if (kgdb_flag) { -printk ("Wait for gdb client connection ...\n" ); -set_debug_traps (); -breakpoint (); - } +/* +* We have been called before kgdb_arch_init(). Hence, +* we dont want the traps to be reinitialized +*/ +if (kgdb_early_setup ==0 ) + kgdb_early_setup =1 ;#endif }
arch/mips/kernel/kgdb.c new file +296 -0
296 lines not on this page · raw message
arch/mips/kernel/kgdb_handler.S new file +58 -0
58 lines not on this page · raw message
arch/mips/kernel/kgdb-jmp.c new file +116 -0
116 lines not on this page · raw message
arch/mips/kernel/kgdb-setjmp.S new file +27 -0
@@ -0,0 +1,27 @@ +/* + * arch/mips/kernel/kgdb-jmp.c + * + * Save and restore system registers so that within a limited frame we + * may have a fault and "jump back" to a known safe location. + * + * Copyright (C) 2005 by MontaVista Software. + * Author: Manish Lachwani ([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 kind, whether express or implied. + */ + +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + +ENTRY (kgdb_fault_setjmp) + move a1, sp + move a2, fp +#ifdef CONFIG_MIPS64 + nop +#endif + j kgdb_fault_setjmp_aux + .end kgdb_fault_setjmp
arch/mips/kernel/Makefile renamed from arch/mips/kernel/Makefile~mips-lite +2 -1
@@ -52,7 +52,8 @@ obj-$(CONFIG_MIPS32_COMPAT) += ioctl32.o obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o ptrace32.o -obj-$(CONFIG_KGDB) += gdb-low.o gdb-stub.o +obj-$(CONFIG_KGDB) += kgdb_handler.o kgdb.o kgdb-jmp.o \ + kgdb-setjmp.o obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_MIPS64) += cpu-bugs64.o
arch/mips/kernel/traps.c renamed from arch/mips/kernel/traps.c~mips-lite +25 -1
@@ -10,6 +10,8 @@* Kevin D. Kissell, [email protected] and Carsten Langgaard, [email protected] * Copyright (C) 2000, 01 MIPS Technologies, Inc. * Copyright (C) 2002, 2003, 2004 Maciej W. Rozycki +* +* KGDB specific changes - Manish Lachwani ([email protected]) */ #include <linux/config.h> #include <linux/init.h>
@@ -20,6 +22,7 @@#include <linux/smp_lock.h> #include <linux/spinlock.h> #include <linux/kallsyms.h> +#include <linux/kgdb.h> #include <asm/bootinfo.h> #include <asm/branch.h>
@@ -37,6 +40,7 @@#include <asm/mmu_context.h> #include <asm/watch.h> #include <asm/types.h> +#include <asm/kdebug.h> extern asmlinkage void handle_tlbm(void); extern asmlinkage void handle_tlbl(void);
@@ -69,6 +73,21 @@ int (*board_be_handler)(struct pt_regs **/ #define MODULE_RANGE (8*1024*1024) +struct notifier_block *mips_die_chain; +static spinlock_t die_notifier_lock =SPIN_LOCK_UNLOCKED ; + +int register_die_notifier (struct notifier_block *nb) +{ +int err =0 ; +unsigned long flags; + +spin_lock_irqsave (&die_notifier_lock, flags); + err =notifier_chain_register (&mips_die_chain, nb); +spin_unlock_irqrestore (&die_notifier_lock, flags); + +return err; +} +/* * This routine abuses get_user()/put_user() to reference pointers * with at least a bit of error checking ...
@@ -271,8 +290,10 @@ NORET_TYPE void __die(const char * str,void __die_if_kernel (const char * str,struct pt_regs * regs,const char * file,const char * func,unsigned long line) { -if (!user_mode (regs)) +if (!user_mode (regs)) { +notify_die (DIE_TRAP , (char *)str, regs,0 );__die (str, regs, file, func, line); + } }extern const struct exception_table_entry __start___dbe_table[];
@@ -958,6 +979,9 @@ void __init trap_init(void)extern char except_vec4;unsigned long i; +if (kgdb_early_setup) +return ;/* Already done */ +per_cpu_trap_init ();/*
arch/mips/mips-boards/generic/init.c renamed from arch/mips/mips-boards/generic/init.c~mips-lite +0 -62
74 lines not on this page · raw message
arch/mips/mips-boards/generic/Makefile renamed from arch/mips/mips-boards/generic/Makefile~mips-lite +0 -1
@@ -21,6 +21,5 @@ obj-y := mipsIRQ.o reset.o display.o init.o memory.o \ printf.o cmdline.o time.o obj-$(CONFIG_PCI) += pci.o -obj-$(CONFIG_KGDB) += gdb_hook.o EXTRA_AFLAGS := $(CFLAGS)
arch/mips/mips-boards/malta/malta_setup.c renamed from arch/mips/mips-boards/malta/malta_setup.c~mips-lite +0 -8
@@ -48,10 +48,6 @@ extern void mips_time_init(void);extern void mips_timer_setup (struct irqaction *irq);extern unsigned long mips_rtc_get_time (void ); -#ifdef CONFIG_KGDB -extern void kgdb_config (void ); -#endif -struct resource standard_io_resources[] = { {"dma1" ,0x00 ,0x1f ,IORESOURCE_BUSY }, {"timer" ,0x40 ,0x5f ,IORESOURCE_BUSY },
@@ -124,10 +120,6 @@ static int __init malta_setup(void)*/ enable_dma (4 ); -#ifdef CONFIG_KGDB -kgdb_config (); -#endif -if ((mips_revision_corid ==MIPS_REVISION_CORID_BONITO64 ) || (mips_revision_corid ==MIPS_REVISION_CORID_CORE_20K ) || (mips_revision_corid ==MIPS_REVISION_CORID_CORE_EMUL_BON )) {
arch/mips/mm/extable.c renamed from arch/mips/mm/extable.c~mips-lite +7 -0
@@ -3,6 +3,7 @@*/ #include <linux/module.h> #include <linux/spinlock.h> +#include <linux/kgdb.h> #include <asm/branch.h> #include <asm/uaccess.h>
@@ -16,6 +17,12 @@ int fixup_exception(struct pt_regs *regsreturn 1 ; } +#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 0 ; }
arch/mips/sibyte/cfe/setup.c renamed from arch/mips/sibyte/cfe/setup.c~mips-lite +0 -14
@@ -58,10 +58,6 @@ int cfe_cons_handle;extern unsigned long initrd_start, initrd_end;#endif -#ifdef CONFIG_KGDB -extern int kgdb_port; -#endif - static void ATTRIB_NORET cfe_linux_exit(void *arg) {int warm = *(int *)arg;
@@ -242,9 +238,6 @@ void __init prom_init(void)int argc = fw_arg0;char **envp = (char **) fw_arg2;int *prom_vec = (int *) fw_arg3; -#ifdef CONFIG_KGDB -char *arg; -#endif _machine_restart = cfe_linux_restart; _machine_halt = cfe_linux_halt;
@@ -308,13 +301,6 @@ void __init prom_init(void) } } -#ifdef CONFIG_KGDB -if ((arg =strstr (arcs_cmdline,"kgdb=duart" )) !=NULL ) - kgdb_port = (arg[10 ] =='0' ) ?0 :1 ; -else - kgdb_port =1 ; -#endif -#ifdef CONFIG_BLK_DEV_INITRD {char *ptr;
arch/mips/sibyte/sb1250/irq.c renamed from arch/mips/sibyte/sb1250/irq.c~mips-lite +6 -51
79 lines not on this page · raw message
arch/mips/sibyte/sb1250/irq_handler.S renamed from arch/mips/sibyte/sb1250/irq_handler.S~mips-lite +1 -1
@@ -102,7 +102,7 @@ 2: #endif -#ifdef CONFIG_KGDB +#ifdef CONFIG_KGDB_SIBYTE /* KGDB (uart 1) interrupt is routed to IP[6] */ andi t1, s0, CAUSEF_IP6 beqz t1, 1f
arch/mips/sibyte/sb1250/kgdb_sibyte.c new file +164 -0
164 lines not on this page · raw message
arch/mips/sibyte/sb1250/Makefile renamed from arch/mips/sibyte/sb1250/Makefile~mips-lite +1 -0
@@ -4,5 +4,6 @@ obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SIBYTE_TBPROF) += bcm1250_tbprof.o obj-$(CONFIG_SIBYTE_STANDALONE) += prom.o obj-$(CONFIG_SIBYTE_BUS_WATCHER) += bus_watcher.o +obj-$(CONFIG_KGDB_SIBYTE) += kgdb_sibyte.o EXTRA_AFLAGS := $(CFLAGS)
arch/mips/sibyte/swarm/dbg_io.c deleted +0 -76
76 lines not on this page · raw message
arch/mips/sibyte/swarm/Makefile renamed from arch/mips/sibyte/swarm/Makefile~mips-lite +0 -2
@@ -1,3 +1 @@ lib-y = setup.o rtc_xicor1241.o rtc_m41t81.o - -lib-$(CONFIG_KGDB) += dbg_io.o
include/asm-mips/kdebug.h new file +47 -0
47 lines not on this page · raw message
include/asm-mips/kgdb.h new file +22 -0
@@ -0,0 +1,22 @@ +#ifdef __KERNEL__ +#ifndef _ASM_KGDB_H_ +#define _ASM_KGDB_H_ + +#define BUFMAX 2048 +#define NUMREGBYTES (90*sizeof(long)) +#define NUMCRITREGBYTES (12*sizeof(long)) +#define BREAK_INSTR_SIZE 4 +#define BREAKPOINT () __asm__ __volatile__( \ + ".globl breakinst\n\t" \ + ".set\tnoreorder\n\t" \ + "nop\n" \ + "breakinst:\tbreak\n\t" \ + "nop\n\t" \ + ".set\treorder") +#define CHECK_EXCEPTION_STACK () 1 +#define CACHE_FLUSH_IS_SAFE 0 + +extern int kgdb_early_setup; + +#endif /* _ASM_KGDB_H_ */ +#endif /* __KERNEL__ */
lib/Kconfig.debug renamed from lib/Kconfig.debug~mips-lite +6 -1
@@ -163,7 +163,7 @@ config FRAME_POINTER config KGDB bool "KGDB: kernel debugging with remote gdb" select WANT_EXTRA_DEBUG_INFORMATION - depends on DEBUG_KERNEL && (X86 || ((!SMP || BROKEN) && (PPC32))) + depends on DEBUG_KERNEL && (X86 || MIPS32 || ((!SMP || BROKEN) && PPC32)) help If you say Y here, it will be possible to remotely debug the kernel using gdb. It is strongly suggested that you enable
@@ -189,6 +189,7 @@ choice prompt "Method for KGDB communication" depends on KGDB default KGDB_8250_NOMODULE + default KGDB_SIBYTE if SIBYTE_SB1xxx_SOC default KGDB_MPSC if SERIAL_MPSC help There are a number of different ways in which you can communicate
@@ -222,6 +223,10 @@ config KGDB_MPSC Controller (MPSC) channel. Note that the GT64260A is not supported. +config KGDB_SIBYTE + bool "KGDB: On the Broadcom SWARM serial port" + depends on MIPS && SIBYTE_SB1xxx_SOC + endchoice config KGDB_8250
_
PATCH 6/16 Add support for IA64 platforms to KGDB
This is support of the IA64 arch for KGDB. This is primarily the work of Robert Picco. There are also some IA64 changes in the serial patch so that IA64 can pass in IRQ and iomembase, and all of this is documented in the DocBook files.
---
linux-2.6.13-trini/arch/ia64/kernel/Makefile | 1 linux-2.6.13-trini/arch/ia64/kernel/entry.S | 4 linux-2.6.13-trini/arch/ia64/kernel/ivt.S | 15 linux-2.6.13-trini/arch/ia64/kernel/kgdb-jmp.S | 238 ++++ linux-2.6.13-trini/arch/ia64/kernel/kgdb.c | 1038 +++++++++++++++++++++ linux-2.6.13-trini/arch/ia64/kernel/mca.c | 10 linux-2.6.13-trini/arch/ia64/kernel/process.c | 6 linux-2.6.13-trini/arch/ia64/kernel/smp.c | 17 linux-2.6.13-trini/arch/ia64/kernel/traps.c | 36 linux-2.6.13-trini/arch/ia64/kernel/unwind.c | 87 + linux-2.6.13-trini/arch/ia64/mm/extable.c | 6 linux-2.6.13-trini/arch/ia64/mm/fault.c | 5 linux-2.6.13-trini/include/asm-ia64/kgdb.h | 37 linux-2.6.13-trini/lib/Kconfig.debug | 2 14 files changed, 1497 insertions(+), 5 deletions(-)
arch/ia64/kernel/entry.S renamed from arch/ia64/kernel/entry.S~ia64-lite +2 -2
@@ -929,9 +929,9 @@ GLOBAL_ENTRY(ia64_leave_kernel) shr.u r18=r19,16 // get byte size of existing "dirty" partition ;; mov r16=ar.bsp // get existing backing store pointer - addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 +(pUStk) addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 ;; - ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 +(pUStk) ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 (pKStk) br.cond.dpnt skip_rbs_switch /*
arch/ia64/kernel/ivt.S renamed from arch/ia64/kernel/ivt.S~ia64-lite +15 -0
@@ -69,6 +69,13 @@ # define DBG_FAULT(i) #endif +#ifdef CONFIG_KGDB +#define KGDB_ENABLE_PSR_DB mov r31=psr;; movl r30=IA64_PSR_DB;; or r31=r31,r30;; \ + mov psr.l=r31;; srlz.i;; +#else +#define KGDB_ENABLE_PSR_DB +#endif + #define MINSTATE_VIRT /* needed by minstate.h */ #include "minstate.h"
@@ -479,6 +486,7 @@ ENTRY(page_fault) movl r14=ia64_leave_kernel ;; SAVE_REST + KGDB_ENABLE_PSR_DB mov rp=r14 ;; adds out2=16,r12 // out2 = pointer to pt_regs
@@ -820,6 +828,7 @@ ENTRY(interrupt) srlz.i // ensure everybody knows psr.ic is back on ;; SAVE_REST + KGDB_ENABLE_PSR_DB ;; alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group mov out0=cr.ivr // pass cr.ivr as first arg
@@ -1066,6 +1075,7 @@ ENTRY(non_syscall) movl r15=ia64_leave_kernel ;; SAVE_REST + KGDB_ENABLE_PSR_DB mov rp=r15 ;; br.call.sptk.many b6=ia64_bad_break // avoid WAW on CFM and ignore return addr
@@ -1099,6 +1109,7 @@ ENTRY(dispatch_unaligned_handler) adds r3=8,r2 // set up second base pointer ;; SAVE_REST + KGDB_ENABLE_PSR_DB movl r14=ia64_leave_kernel ;; mov rp=r14
@@ -1141,6 +1152,10 @@ ENTRY(dispatch_to_fault_handler) adds r3=8,r2 // set up second base pointer for SAVE_REST ;; SAVE_REST + cmp.eq p6,p0=29,out0 +(p6) br.cond.spnt 1f;; // debug_vector + KGDB_ENABLE_PSR_DB +1: movl r14=ia64_leave_kernel ;; mov rp=r14
arch/ia64/kernel/kgdb.c new file +1038 -0
1,038 lines not on this page · raw message
arch/ia64/kernel/kgdb-jmp.S new file +238 -0
238 lines not on this page · raw message
arch/ia64/kernel/Makefile renamed from arch/ia64/kernel/Makefile~ia64-lite +1 -0
@@ -24,6 +24,7 @@ obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_r obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o mca_recovery-y += mca_drv.o mca_drv_asm.o +obj-$(CONFIG_KGDB) += kgdb.o kgdb-jmp.o # The gate DSO image is built using a special linker script. targets += gate.so gate-syms.o
arch/ia64/kernel/mca.c renamed from arch/ia64/kernel/mca.c~ia64-lite +10 -0
@@ -472,9 +472,18 @@ static voidinit_handler_platform (pal_min_state_area_t *ms, struct pt_regs *pt, struct switch_stack *sw) { +#ifndef CONFIG_KGDB struct unw_frame_info info; +#endif /* if a kernel debugger is available call it here else just dump the registers */ +#ifdef CONFIG_KGDB +fetch_min_state (ms, pt, sw); +/* +* switch_stack is at ((char *) pt) - sizeof (struct switch_stack) +*/ +kgdb_handle_exception (-1 ,SIGTRAP ,0 , pt); +#else /* * Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be
@@ -510,6 +519,7 @@ init_handler_platform (pal_min_state_areif (!tasklist_lock.write_lock)read_unlock (&tasklist_lock);#endif +#endif printk ("\nINIT dump complete. Please reboot now.\n" );while (1 );/* hang city if no debugger */
arch/ia64/kernel/process.c renamed from arch/ia64/kernel/process.c~ia64-lite +6 -0
@@ -451,6 +451,9 @@ copy_thread (int nr, unsigned long clone*/ child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr |IA64_PSR_BITS_TO_SET ) & ~(IA64_PSR_BITS_TO_CLEAR |IA64_PSR_PP |IA64_PSR_UP )); +#ifdef CONFIG_KGDB + child_ptregs->cr_ipsr |=IA64_PSR_DB ; +#endif /* * NOTE: The calling convention considers all floating point
@@ -679,6 +682,9 @@ kernel_thread (int (*fn)(void *), void * regs.pt.r11 = (unsigned long ) arg;/* 2nd argument */ /* Preserve PSR bits, except for bits 32-34 and 37-45, which we can't read. */ regs.pt.cr_ipsr =ia64_getreg (_IA64_REG_PSR) |IA64_PSR_BN ; +#ifdef CONFIG_KGDB + regs.pt.cr_ipsr |=IA64_PSR_DB ; +#endif regs.pt.cr_ifs =1UL <<63 ;/* mark as valid, empty frame */ regs.sw.ar_fpsr = regs.pt.ar_fpsr =ia64_getreg (_IA64_REG_AR_FPSR); regs.sw.ar_bspstore = (unsigned long ) current +IA64_RBS_OFFSET ;
arch/ia64/kernel/smp.c renamed from arch/ia64/kernel/smp.c~ia64-lite +17 -0
@@ -47,6 +47,7 @@#include <asm/tlbflush.h> #include <asm/unistd.h> #include <asm/mca.h> +#include <linux/kgdb.h> /* * Structure and data for smp_call_function(). This is designed to minimise static memory
@@ -66,6 +67,9 @@ static volatile struct call_data_struct#define IPI_CALL_FUNC 0#define IPI_CPU_STOP 1 +#ifdef CONFIG_KGDB +#define IPI_KGDB_INTERRUPT 2 +#endif /* This needs to be cacheline aligned because it is written to by *other* CPUs. */ static DEFINE_PER_CPU(u64, ipi_operation) ____cacheline_aligned;
@@ -155,6 +159,11 @@ handle_IPI (int irq, void *dev_id, struccase IPI_CPU_STOP :stop_this_cpu ();break ; +#ifdef CONFIG_KGDB +case IPI_KGDB_INTERRUPT : +kgdb_wait_ipi (regs); +break ; +#endif default :printk (KERN_CRIT "Unknown IPI on CPU %d: %lu\n" , this_cpu, which);
@@ -305,6 +314,14 @@ smp_call_function_single (int cpuid, voi }EXPORT_SYMBOL (smp_call_function_single); +#ifdef CONFIG_KGDB +void +smp_send_nmi_allbutself (void ) +{ +send_IPI_allbutself (IPI_KGDB_INTERRUPT ); +} +#endif +/* * this function sends a 'generic call function' IPI to all other CPUs * in the system.
arch/ia64/kernel/traps.c renamed from arch/ia64/kernel/traps.c~ia64-lite +34 -2
@@ -15,6 +15,7 @@#include <linux/vt_kern.h> /* For unblank_screen() */ #include <linux/module.h> /* for EXPORT_SYMBOL */ #include <linux/hardirq.h> +#include <linux/kgdb.h> #include <asm/fpswa.h> #include <asm/ia32.h>
@@ -108,6 +109,10 @@ die (const char *str, struct pt_regs *re }else printk (KERN_ERR "Recursive die() failure, output suppressed\n" ); +#ifdef CONFIG_KGDB +kgdb_handle_exception (1 ,SIGTRAP , err, regs); +#endif +bust_spinlocks (0 ); die.lock_owner =-1 ;spin_unlock_irq (&die.lock);
@@ -157,7 +162,9 @@ ia64_bad_break (unsigned long break_num, == NOTIFY_STOP) {return ; } +#ifndef CONFIG_KGDB die_if_kernel ("bugcheck!" , regs, break_num); +#endif sig =SIGILL ; code =ILL_ILLOPC ;break ;
@@ -219,8 +226,10 @@ ia64_bad_break (unsigned long break_num,break ;default : +#ifndef CONFIG_KGDB if (break_num <0x40000 || break_num >0x100000 )die_if_kernel ("Bad break" , regs, break_num); +#endif if (break_num <0x80000 ) { sig =SIGILL ; code = __ILL_BREAK;
@@ -228,6 +237,15 @@ ia64_bad_break (unsigned long break_num, sig =SIGTRAP ; code =TRAP_BRKPT ; } } +#ifdef CONFIG_KGDB +/* +* We don't want to trap simulator system calls. +*/ +if (break_num !=0x80001 ) { +kgdb_handle_exception (11 , sig, break_num, regs); +return ; + } +#endif siginfo.si_signo = sig; siginfo.si_errno =0 ; siginfo.si_code = code;
@@ -543,10 +561,21 @@ ia64_fault (unsigned long vector, unsign }sprintf (buf,"Unsupported data reference" );break ; -case 29 :/* Debug */ -case 35 :/* Taken Branch Trap */ case 36 :/* Single Step Trap */ +#ifdef CONFIG_KGDB +if (vector ==36 && !user_mode (®s) && + kgdb_hwbreak_sstep[smp_processor_id ()]) { + kgdb_hwbreak_sstep[smp_processor_id ()] =0 ; + regs.cr_ipsr &= ~IA64_PSR_SS ; +return ; + }else if (!user_mode (®s)) { +kgdb_handle_exception (vector,SIGTRAP , isr, ®s); +return ; + } +#endif +/* Fall */ +case 35 :/* Taken Branch Trap */ if (fsys_mode (current, ®s)) {extern char __kernel_syscall_via_break[];/*
@@ -664,6 +693,9 @@ ia64_fault (unsigned long vector, unsignsprintf (buf,"Fault %lu" , vector);break ; } +#ifdef CONFIG_KGDB +kgdb_handle_exception (vector,SIGTRAP , isr, ®s); +#endif die_if_kernel (buf, ®s, error);force_sig (SIGILL , current); }
arch/ia64/kernel/unwind.c renamed from arch/ia64/kernel/unwind.c~ia64-lite +87 -0
123 lines not on this page · raw message
arch/ia64/mm/extable.c renamed from arch/ia64/mm/extable.c~ia64-lite +6 -0
@@ -7,6 +7,7 @@#include <linux/config.h> #include <linux/sort.h> +#include <linux/kgdb.h> #include <asm/uaccess.h> #include <asm/module.h>
@@ -74,6 +75,11 @@ search_extable (const struct exception_telse last = mid -1 ; } +#ifdef CONFIG_KGDB +if (atomic_read (&debugger_active) && kgdb_may_fault) +kgdb_fault_longjmp (kgdb_fault_jmp_regs); +/* Not reached. */ +#endif return NULL ; }
arch/ia64/mm/fault.c renamed from arch/ia64/mm/fault.c~ia64-lite +5 -0
@@ -9,6 +9,7 @@#include <linux/mm.h> #include <linux/smp_lock.h> #include <linux/interrupt.h> +#include <linux/kgdb.h> #include <asm/pgtable.h> #include <asm/processor.h>
@@ -248,6 +249,10 @@ ia64_do_page_fault (unsigned long addres*/ bust_spinlocks (1 ); +#ifdef CONFIG_KGDB +kgdb_handle_exception (14 ,SIGSEGV , isr, regs); +#endif +if (address <PAGE_SIZE )printk (KERN_ALERT "Unable to handle kernel NULL pointer dereference (address %016lx)\n" , address);else
include/asm-ia64/kgdb.h new file +37 -0
@@ -0,0 +1,37 @@ +#ifdef __KERNEL__ +#ifndef _ASM_KGDB_H_ +#define _ASM_KGDB_H_ + +/* +* Copyright (C) 2001-2004 Amit S. Kale +*/ + +#include <linux/threads.h> + +/************************************************************************/ +/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ +/* at least NUMREGBYTES*2 are needed for register packets */ +/* Longer buffer is needed to list all threads */ +#define BUFMAX 1024 + +/* Number of bytes of registers. We set this to 0 so that certain GDB +* packets will fail, forcing the use of others, which are more friendly +* on ia64. */ +#define NUMREGBYTES 0 + +#define NUMCRITREGBYTES (70*8) +#define JMP_REGS_ALIGNMENT __attribute__ ((aligned (16))) + +#define BREAKNUM 0x00003333300LL +#define KGDBBREAKNUM 0x6665UL +#define BREAKPOINT () asm volatile ("break.m 0x6665") +#define BREAK_INSTR_SIZE 16 +#define CHECK_EXCEPTION_STACK () 1 +#define CACHE_FLUSH_IS_SAFE 1 + +struct pt_regs ; +extern volatile int kgdb_hwbreak_sstep[NR_CPUS ]; +extern void smp_send_nmi_allbutself (void ); +extern void kgdb_wait_ipi (struct pt_regs *); +#endif /* _ASM_KGDB_H_ */ +#endif /* __KERNEL__ */
lib/Kconfig.debug renamed from lib/Kconfig.debug~ia64-lite +1 -1
@@ -163,7 +163,7 @@ config FRAME_POINTER config KGDB bool "KGDB: kernel debugging with remote gdb" select WANT_EXTRA_DEBUG_INFORMATION - depends on DEBUG_KERNEL && (X86 || MIPS32 || ((!SMP || BROKEN) && PPC32)) + depends on DEBUG_KERNEL && (X86 || MIPS32 || IA64 || ((!SMP || BROKEN) && PPC32)) help If you say Y here, it will be possible to remotely debug the kernel using gdb. It is strongly suggested that you enable
_
PATCH 7/16 x86_64: Rename KDB_VECTOR to DEBUGGER_VECTOR
CC: Andi Kleen <[email protected]>, Keith Owens <[email protected]>
The existing hook from KDB in the IPI code is really just a hook for the NMI vector. We rename the vector thusly and then it's up to the debugger to handle things from do_default_nmi().
---
linux-2.6.13-trini/arch/x86_64/kernel/i8259.c | 3 +-- linux-2.6.13-trini/arch/x86_64/kernel/smp.c | 2 +- linux-2.6.13-trini/arch/x86_64/kernel/traps.c | 2 +- linux-2.6.13-trini/include/asm-x86_64/hw_irq.h | 2 +- linux-2.6.13-trini/include/asm-x86_64/ipi.h | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-)
arch/x86_64/kernel/i8259.c renamed from arch/x86_64/kernel/i8259.c~x86_64-rename_kdb_vector +1 -2
@@ -544,10 +544,9 @@ void __init init_IRQ(void)int vector =FIRST_EXTERNAL_VECTOR + i;if (i >=NR_IRQS )break ; -if (vector !=IA32_SYSCALL_VECTOR && vector !=KDB_VECTOR ) { +if (vector !=IA32_SYSCALL_VECTOR && vector !=NMI_VECTOR )set_intr_gate (vector, interrupt[i]); } - }#ifdef CONFIG_SMP /*
arch/x86_64/kernel/smp.c renamed from arch/x86_64/kernel/smp.c~x86_64-rename_kdb_vector +1 -1
@@ -252,7 +252,7 @@ void flush_tlb_all(void)void smp_kdb_stop (void ) { -send_IPI_allbutself (KDB_VECTOR ); +send_IPI_allbutself (NMI_VECTOR ); }/*
arch/x86_64/kernel/traps.c renamed from arch/x86_64/kernel/traps.c~x86_64-rename_kdb_vector +1 -1
@@ -931,7 +931,7 @@ void __init trap_init(void)set_system_gate (IA32_SYSCALL_VECTOR , ia32_syscall);#endif -set_intr_gate (KDB_VECTOR , call_debug); +set_intr_gate (NMI_VECTOR , call_debug);/* * Should be a barrier for any external CPU state.
include/asm-x86_64/hw_irq.h renamed from include/asm-x86_64/hw_irq.h~x86_64-rename_kdb_vector +1 -1
@@ -54,7 +54,7 @@ struct hw_interrupt_type;#define RESCHEDULE_VECTOR 0xfc#define TASK_MIGRATION_VECTOR 0xfb#define CALL_FUNCTION_VECTOR 0xfa -#define KDB_VECTOR 0xf9 +#define NMI_VECTOR 0xf9#define THERMAL_APIC_VECTOR 0xf0
include/asm-x86_64/ipi.h renamed from include/asm-x86_64/ipi.h~x86_64-rename_kdb_vector +1 -1
@@ -32,7 +32,7 @@static inline unsigned int __prepare_ICR (unsigned int shortcut,int vector,unsigned int dest) {unsigned int icr =APIC_DM_FIXED | shortcut | vector | dest; -if (vector ==KDB_VECTOR ) +if (vector ==NMI_VECTOR ) icr = (icr & (~APIC_VECTOR_MASK )) |APIC_DM_NMI ;return icr; }
_
PATCH 8/16 Add support for X86_64 platforms to KGDB
This adds support for the x86_64 architecture. In addition to what was noted in the core-lite patch about stuff outside of new files, we add -g0 to compiling of syscalls.o as otherwise we run into problems when debugging modules, and like i386 annotate switch_to().
---
linux-2.6.13-trini/arch/x86_64/Kconfig.debug | 3 linux-2.6.13-trini/arch/x86_64/kernel/Makefile | 2 linux-2.6.13-trini/arch/x86_64/kernel/kgdb-jmp.S | 65 ++ linux-2.6.13-trini/arch/x86_64/kernel/kgdb.c | 460 +++++++++++++++++++ linux-2.6.13-trini/arch/x86_64/kernel/setup.c | 3 linux-2.6.13-trini/arch/x86_64/kernel/setup64.c | 14 linux-2.6.13-trini/arch/x86_64/kernel/traps.c | 24 linux-2.6.13-trini/arch/x86_64/mm/fault.c | 4 linux-2.6.13-trini/include/asm-x86_64/kgdb.h | 50 ++ linux-2.6.13-trini/include/asm-x86_64/proto.h | 2 linux-2.6.13-trini/include/asm-x86_64/system.h | 6 linux-2.6.13-trini/lib/Kconfig.debug | 2 12 files changed, 617 insertions(+), 18 deletions(-)
arch/x86_64/Kconfig.debug renamed from arch/x86_64/Kconfig.debug~x86_64-lite +0 -3
@@ -51,7 +51,4 @@ config IOMMU_LEAK Add a simple leak tracer to the IOMMU code. This is useful when you are debugging a buggy device driver that leaks IOMMU mappings. -#config X86_REMOTE_DEBUG -# bool "kgdb debugging stub" - endmenu
arch/x86_64/kernel/kgdb.c new file +460 -0
460 lines not on this page · raw message
arch/x86_64/kernel/kgdb-jmp.S new file +65 -0
65 lines not on this page · raw message
arch/x86_64/kernel/Makefile renamed from arch/x86_64/kernel/Makefile~x86_64-lite +2 -0
@@ -4,6 +4,7 @@ extra-y := head.o head64.o init_task.o vmlinux.lds EXTRA_AFLAGS := -traditional +CFLAGS_vsyscall.o := -g0 obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \ x8664_ksyms.o i387.o syscall.o vsyscall.o \
@@ -29,6 +30,7 @@ obj-$(CONFIG_GART_IOMMU) += pci-gart.o a obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o obj-$(CONFIG_SWIOTLB) += swiotlb.o obj-$(CONFIG_KPROBES) += kprobes.o +obj-$(CONFIG_KGDB) += kgdb.o kgdb-jmp.o obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o obj-$(CONFIG_MODULES) += module.o
arch/x86_64/kernel/traps.c renamed from arch/x86_64/kernel/traps.c~x86_64-lite +12 -12
@@ -29,6 +29,7 @@#include <linux/module.h> #include <linux/moduleparam.h> #include <linux/nmi.h> +#include <linux/kgdb.h> #include <asm/system.h> #include <asm/uaccess.h>
@@ -902,12 +903,21 @@ void do_call_debug(struct pt_regs *regs)notify_die (DIE_CALL ,"debug call" , regs,0 ,255 ,SIGINT ); } -void __init trap_init (void ) +void __init early_trap_init (void ) { -set_intr_gate (0 ,÷_error);set_intr_gate_ist (1 ,&debug,DEBUG_STACK );set_intr_gate_ist (2 ,&nmi,NMI_STACK );set_system_gate (3 ,&int3); +set_intr_gate (13 ,&general_protection); +set_intr_gate (14 ,&page_fault); +set_intr_gate (11 ,&segment_not_present); +set_intr_gate (NMI_VECTOR , call_debug); +cpu_init (); +} + +void __init trap_init (void ) +{ +set_intr_gate (0 ,÷_error);set_system_gate (4 ,&overflow);/* int4-5 can be called from all */ set_system_gate (5 ,&bounds);set_intr_gate (6 ,&invalid_op);
@@ -915,10 +925,7 @@ void __init trap_init(void)set_intr_gate_ist (8 ,&double_fault,DOUBLEFAULT_STACK );set_intr_gate (9 ,&coprocessor_segment_overrun);set_intr_gate (10 ,&invalid_TSS); -set_intr_gate (11 ,&segment_not_present);set_intr_gate_ist (12 ,&stack_segment,STACKFAULT_STACK ); -set_intr_gate (13 ,&general_protection); -set_intr_gate (14 ,&page_fault);set_intr_gate (15 ,&spurious_interrupt_bug);set_intr_gate (16 ,&coprocessor_error);set_intr_gate (17 ,&alignment_check);
@@ -930,13 +937,6 @@ void __init trap_init(void)#ifdef CONFIG_IA32_EMULATION set_system_gate (IA32_SYSCALL_VECTOR , ia32_syscall);#endif - -set_intr_gate (NMI_VECTOR , call_debug); - -/* -* Should be a barrier for any external CPU state. -*/ -cpu_init (); }
diff -puN include/asm-x86_64/hw_irq.h~x86_64-lite include/asm-x86_64/hw_irq.h diff -puN include/asm-x86_64/ipi.h~x86_64-lite include/asm-x86_64/ipi.h
include/asm-x86_64/kgdb.h new file +50 -0
50 lines not on this page · raw message
include/asm-x86_64/system.h renamed from include/asm-x86_64/system.h~x86_64-lite +5 -1
@@ -27,7 +27,9 @@ ,"rcx","rbx","rdx","r8","r9","r10","r11","r12","r13","r14","r15"#define switch_to (prev,next,last) \ - asm volatile(SAVE_CONTEXT \ + asm volatile(".globl __switch_to_begin\n\t" \ + "__switch_to_begin:\n\t" \ + SAVE_CONTEXT \ "movq %%rsp,%P[threadrsp](%[prev])\n\t"/* save RSP */ \"movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */ \"call __switch_to\n\t" \
@@ -39,6 +41,8 @@ "movq %%rax,%%rdi\n\t" \ "jc ret_from_fork\n\t" \ RESTORE_CONTEXT \ + ".globl __switch_to_end\n\t" \ + "__switch_to_end:\n\t" \ : "=a" (last) \: [next] " S " (next), [prev] " D " (prev), \ [threadrsp] " i" (offsetof(struct task_struct, thread.rsp)), \
lib/Kconfig.debug renamed from lib/Kconfig.debug~x86_64-lite +1 -1
@@ -163,7 +163,7 @@ config FRAME_POINTER config KGDB bool "KGDB: kernel debugging with remote gdb" select WANT_EXTRA_DEBUG_INFORMATION - depends on DEBUG_KERNEL && (X86 || MIPS32 || IA64 || ((!SMP || BROKEN) && PPC32)) + depends on DEBUG_KERNEL && (X86 || MIPS32 || IA64 || X86_64 || ((!SMP || BROKEN) && PPC32)) help If you say Y here, it will be possible to remotely debug the kernel using gdb. It is strongly suggested that you enable
arch/x86_64/kernel/setup.c renamed from arch/x86_64/kernel/setup.c~x86_64-lite +3 -0
@@ -525,6 +525,9 @@ void __init setup_arch(char **cmdline_p) {unsigned long kernel_end; +early_setup_per_cpu_area (); +early_trap_init (); +ROOT_DEV =old_decode_dev (ORIG_ROOT_DEV ); drive_info =DRIVE_INFO ; screen_info =SCREEN_INFO ;
arch/x86_64/kernel/setup64.c renamed from arch/x86_64/kernel/setup64.c~x86_64-lite +13 -1
@@ -77,6 +77,16 @@ static int __init nonx32_setup(char *str }__setup ("noexec32=" , nonx32_setup); +void __init early_setup_per_cpu_area (void ) +{ + static char cpu0[PERCPU_ENOUGH_ROOM] + __attribute__ ((aligned (SMP_CACHE_BYTES))); +char *ptr = cpu0; + + cpu_pda[0 ].data_offset = ptr - __per_cpu_start; +memcpy (ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); +} +/* * Great future plan: * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data.
@@ -97,7 +107,9 @@ void __init setup_per_cpu_areas(void)for (i =0 ; i <NR_CPUS ; i++) {char *ptr; -if (!NODE_DATA (cpu_to_node (i))) { +if (cpu_pda[i].data_offset) +continue ; +else if (!NODE_DATA (cpu_to_node (i))) {printk ("cpu with no node %d, num_online_nodes %d\n" , i,num_online_nodes ()); ptr =alloc_bootmem (size);
include/asm-x86_64/proto.h renamed from include/asm-x86_64/proto.h~x86_64-lite +2 -0
@@ -10,6 +10,8 @@ struct pt_regs;extern void get_cpu_vendor (struct cpuinfo_x86 *);extern void start_kernel (void ); +extern void early_trap_init (void ); +extern void early_setup_per_cpu_area (void );extern void pda_init (int );extern void early_idt_handler (void );
arch/x86_64/mm/fault.c renamed from arch/x86_64/mm/fault.c~x86_64-lite +4 -0
@@ -516,6 +516,10 @@ no_context:if (is_errata93 (regs, address))return ; +if (notify_die (DIE_PAGE_FAULT ,"no context" , regs, error_code,14 , +SIGSEGV ) ==NOTIFY_STOP ) +return ; +/* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice.
_
PATCH 10/16 Add support for ARM platforms to KGDB
In reply to Tom RiniThis 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, and ARM Versatile. 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.
---
linux-2.6.13-trini/arch/arm/kernel/Makefile | 1 linux-2.6.13-trini/arch/arm/kernel/kgdb-jmp.S | 30 + linux-2.6.13-trini/arch/arm/kernel/kgdb.c | 208 +++++++++++ linux-2.6.13-trini/arch/arm/kernel/setup.c | 5 linux-2.6.13-trini/arch/arm/kernel/traps.c | 11 linux-2.6.13-trini/arch/arm/mach-ixp2000/core.c | 5 linux-2.6.13-trini/arch/arm/mach-ixp2000/ixdp2x01.c | 6 linux-2.6.13-trini/arch/arm/mach-ixp4xx/coyote-setup.c | 5 linux-2.6.13-trini/arch/arm/mach-ixp4xx/ixdp425-setup.c | 12 linux-2.6.13-trini/arch/arm/mach-omap1/board-osk.c | 6 linux-2.6.13-trini/arch/arm/mach-omap1/serial.c | 4 linux-2.6.13-trini/arch/arm/mach-pxa/Makefile | 1 linux-2.6.13-trini/arch/arm/mach-pxa/kgdb-serial.c | 98 +++++ linux-2.6.13-trini/arch/arm/mach-versatile/kgdb_serial.c | 121 ++++++ linux-2.6.13-trini/arch/arm/mm/extable.c | 7 linux-2.6.13-trini/drivers/serial/amba-pl011.c | 2 linux-2.6.13-trini/include/asm-arm/kgdb.h | 90 ++++ linux-2.6.13-trini/include/asm-arm/system.h | 41 ++ linux-2.6.13-trini/lib/Kconfig.debug | 35 + 19 files changed, 681 insertions(+), 7 deletions(-)
arch/arm/kernel/kgdb.c new file +208 -0
@@ -0,0 +1,208 @@ +/* +* arch/arm/kernel/kgdb.c +* +* ARM KGDB support +* +* Copyright (c) 2002-2004 MontaVista Software, Inc +* +* Authors: George Davis <[email protected]> +* Deepak Saxena <[email protected]> +*/ +#include <linux/config.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/spinlock.h> +#include <linux/personality.h> +#include <linux/ptrace.h> +#include <linux/elf.h> +#include <linux/interrupt.h> +#include <linux/init.h> +#include <linux/kgdb.h> + +#include <asm/atomic.h> +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/uaccess.h> +#include <asm/unistd.h> +#include <asm/ptrace.h> +#include <asm/traps.h> + +/* Make a local copy of the registers passed into the handler (bletch) */ +void regs_to_gdb_regs (unsigned long *gdb_regs,struct pt_regs *kernel_regs) +{ +int regno; + +/* Initialize all to zero (??) */ +for (regno =0 ; regno <GDB_MAX_REGS ; regno++) + gdb_regs[regno] =0 ; + + gdb_regs[_R0] = kernel_regs->ARM_r0; + gdb_regs[_R1] = kernel_regs->ARM_r1; + gdb_regs[_R2] = kernel_regs->ARM_r2; + gdb_regs[_R3] = kernel_regs->ARM_r3; + gdb_regs[_R4] = kernel_regs->ARM_r4; + gdb_regs[_R5] = kernel_regs->ARM_r5; + gdb_regs[_R6] = kernel_regs->ARM_r6; + gdb_regs[_R7] = kernel_regs->ARM_r7; + gdb_regs[_R8] = kernel_regs->ARM_r8; + gdb_regs[_R9] = kernel_regs->ARM_r9; + gdb_regs[_R10] = kernel_regs->ARM_r10; + gdb_regs[_FP] = kernel_regs->ARM_fp; + gdb_regs[_IP] = kernel_regs->ARM_ip; + gdb_regs[_SP] = kernel_regs->ARM_sp; + gdb_regs[_LR] = kernel_regs->ARM_lr; + gdb_regs[_PC] = kernel_regs->ARM_pc; + gdb_regs[_CPSR] = kernel_regs->ARM_cpsr; +} + +/* Copy local gdb registers back to kgdb regs, for later copy to kernel */ +void gdb_regs_to_regs (unsigned long *gdb_regs,struct pt_regs *kernel_regs) +{ + kernel_regs->ARM_r0 = gdb_regs[_R0]; + kernel_regs->ARM_r1 = gdb_regs[_R1]; + kernel_regs->ARM_r2 = gdb_regs[_R2]; + kernel_regs->ARM_r3 = gdb_regs[_R3]; + kernel_regs->ARM_r4 = gdb_regs[_R4]; + kernel_regs->ARM_r5 = gdb_regs[_R5]; + kernel_regs->ARM_r6 = gdb_regs[_R6]; + kernel_regs->ARM_r7 = gdb_regs[_R7]; + kernel_regs->ARM_r8 = gdb_regs[_R8]; + kernel_regs->ARM_r9 = gdb_regs[_R9]; + kernel_regs->ARM_r10 = gdb_regs[_R10]; + kernel_regs->ARM_fp = gdb_regs[_FP]; + kernel_regs->ARM_ip = gdb_regs[_IP]; + kernel_regs->ARM_sp = gdb_regs[_SP]; + kernel_regs->ARM_lr = gdb_regs[_LR]; + kernel_regs->ARM_pc = gdb_regs[_PC]; + kernel_regs->ARM_cpsr = gdb_regs[GDB_MAX_REGS -1 ]; +} + +static inline struct pt_regs *kgdb_get_user_regs (struct task_struct *task) +{ +return (struct pt_regs *) + ((unsigned long )task->thread_info +THREAD_SIZE - +8 -sizeof (struct pt_regs )); +} + +void sleeping_thread_to_gdb_regs (unsigned long *gdb_regs, +struct task_struct *task) +{ +int regno; +struct pt_regs *thread_regs; + +/* Just making sure... */ +if (task ==NULL ) +return ; + +/* Initialize to zero */ +for (regno =0 ; regno <GDB_MAX_REGS ; regno++) + gdb_regs[regno] =0 ; + +/* Otherwise, we have only some registers from switch_to() */ + thread_regs =kgdb_get_user_regs (task); + gdb_regs[_R0] = thread_regs->ARM_r0;/* Not really valid? */ + gdb_regs[_R1] = thread_regs->ARM_r1;/* " " */ + gdb_regs[_R2] = thread_regs->ARM_r2;/* " " */ + gdb_regs[_R3] = thread_regs->ARM_r3;/* " " */ + gdb_regs[_R4] = thread_regs->ARM_r4; + gdb_regs[_R5] = thread_regs->ARM_r5; + gdb_regs[_R6] = thread_regs->ARM_r6; + gdb_regs[_R7] = thread_regs->ARM_r7; + gdb_regs[_R8] = thread_regs->ARM_r8; + gdb_regs[_R9] = thread_regs->ARM_r9; + gdb_regs[_R10] = thread_regs->ARM_r10; + gdb_regs[_FP] = thread_regs->ARM_fp; + gdb_regs[_IP] = thread_regs->ARM_ip; + gdb_regs[_SP] = thread_regs->ARM_sp; + gdb_regs[_LR] = thread_regs->ARM_lr; + gdb_regs[_PC] = thread_regs->ARM_pc; + gdb_regs[_CPSR] = thread_regs->ARM_cpsr; +} + +static int compiled_break; + +int kgdb_arch_handle_exception (int exception_vector,int signo, +int err_code,char *remcom_in_buffer, +char *remcom_out_buffer, +struct pt_regs *linux_regs) +{ +long addr; +char *ptr; + +switch (remcom_in_buffer[0 ]) { +case 'c' : + kgdb_contthread =NULL ; + +/* +* Try to read optional parameter, pc unchanged if no parm. +* If this was a compiled breakpoint, we need to move +* to the next instruction or we will just breakpoint +* over and over again. +*/ + ptr = &remcom_in_buffer[1 ]; +if (kgdb_hex2long (&ptr, &addr)) { + linux_regs->ARM_pc = addr; + }else if (compiled_break ==1 ) { + linux_regs->ARM_pc +=4 ; + } + + compiled_break =0 ; + +return 0 ; + } + +return -1 ; +} + +static int kgdb_brk_fn (struct pt_regs *regs,unsigned int instr) +{ +kgdb_handle_exception (1 ,SIGTRAP ,0 , regs); + +return 0 ; +} + +static int kgdb_compiled_brk_fn (struct pt_regs *regs,unsigned int instr) +{ + compiled_break =1 ; +kgdb_handle_exception (1 ,SIGTRAP ,0 , regs); + +return 0 ; +} + +static struct undef_hook kgdb_brkpt_hook = { + .instr_mask =0xffffffff , + .instr_val =KGDB_BREAKINST , + .fn = kgdb_brk_fn +}; + +static struct undef_hook kgdb_compiled_brkpt_hook = { + .instr_mask =0xffffffff , + .instr_val =KGDB_COMPILED_BREAK , + .fn = kgdb_compiled_brk_fn +}; + +/* +* Register our undef instruction hooks with ARM undef core. +* We regsiter a hook specifically looking for the KGB break inst +* and we handle the normal undef case within the do_undefinstr +* handler. +*/ +int kgdb_arch_init (void ) +{ +register_undef_hook (&kgdb_brkpt_hook); +register_undef_hook (&kgdb_compiled_brkpt_hook); + +return 0 ; +} + +struct kgdb_arch arch_kgdb_ops = { +#ifndef __ARMEB__ + .gdb_bpt_instr = {0xfe, 0xde, 0xff, 0xe7} +#else + .gdb_bpt_instr = {0xe7 ,0xff ,0xde ,0xfe } +#endif +};
arch/arm/kernel/kgdb-jmp.S new file +30 -0
@@ -0,0 +1,30 @@ +/* + * 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] + ldmia r0,{r0-pc}^
arch/arm/kernel/Makefile renamed from arch/arm/kernel/Makefile~arm-lite +1 -0
@@ -19,6 +19,7 @@ obj-$(CONFIG_ARTHUR) += arthur.o obj-$(CONFIG_ISA_DMA) += dma-isa.o obj-$(CONFIG_PCI) += bios32.o obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_KGDB) += kgdb.o kgdb-jmp.o obj-$(CONFIG_IWMMXT) += iwmmxt.o AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
arch/arm/kernel/setup.c renamed from arch/arm/kernel/setup.c~arm-lite +5 -0
@@ -785,6 +785,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 renamed from arch/arm/kernel/traps.c~arm-lite +11 -0
@@ -270,6 +270,7 @@ asmlinkage void do_undefinstr(struct pt_unsigned int instr;struct undef_hook *hook;siginfo_t info; +mm_segment_t fs;void __user *pc;/*
@@ -279,12 +280,15 @@ asmlinkage void do_undefinstr(struct pt_*/ regs->ARM_pc -= correction; + fs =get_fs (); +set_fs (KERNEL_DS ); pc = (void __user *)instruction_pointer (regs);if (thumb_mode (regs)) {get_user (instr, (u16 __user *)pc); }else {get_user (instr, (u32 __user *)pc); } +set_fs (fs);spin_lock_irq (&undef_lock);list_for_each_entry (hook, &undef_hook, node) {
@@ -667,6 +671,13 @@ EXPORT_SYMBOL(abort);void __init trap_init (void ) { +#if defined(CONFIG_KGDB ) + return; +} + +void __init early_trap_init (void ) +{ +#endif extern char __stubs_start[], __stubs_end[];extern char __vectors_start[], __vectors_end[];extern char __kuser_helper_start[], __kuser_helper_end[];
arch/arm/mach-ixp2000/core.c renamed from arch/arm/mach-ixp2000/core.c~arm-lite +5 -0
@@ -35,6 +35,7 @@#include <asm/system.h> #include <asm/tlbflush.h> #include <asm/pgtable.h> +#include <asm/kgdb.h> #include <asm/mach/map.h> #include <asm/mach/time.h>
@@ -145,6 +146,10 @@ void __init ixp2000_map_io(void)iotable_init (ixp2000_io_desc,ARRAY_SIZE (ixp2000_io_desc)); +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (0 , &ixp2000_serial_port); +#endif +/* Set slowport to 8-bit mode. */ ixp2000_reg_write (IXP2000_SLOWPORT_FRM ,1 ); }
arch/arm/mach-ixp2000/ixdp2x01.c renamed from arch/arm/mach-ixp2000/ixdp2x01.c~arm-lite +6 -0
@@ -38,6 +38,7 @@#include <asm/system.h> #include <asm/hardware.h> #include <asm/mach-types.h> +#include <asm/kgdb.h> #include <asm/mach/pci.h> #include <asm/mach/map.h>
@@ -175,6 +176,11 @@ static void __init ixdp2x01_map_io(void)early_serial_setup (&ixdp2x01_serial_ports[0 ]);early_serial_setup (&ixdp2x01_serial_ports[1 ]); + +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (0 , &ixdp2x01_serial_ports[0 ]); +kgdb8250_add_port (1 , &ixdp2x01_serial_ports[1 ]); +#endif }
arch/arm/mach-ixp4xx/coyote-setup.c renamed from arch/arm/mach-ixp4xx/coyote-setup.c~arm-lite +4 -1
@@ -96,9 +96,12 @@ static void __init coyote_init(void) coyote_uart_data[0 ].irq =IRQ_IXP4XX_UART1 ; } -ixp4xx_sys_init ();platform_add_devices (coyote_devices,ARRAY_SIZE (coyote_devices)); + +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (0 , &coyote_serial_port); +#endif }#ifdef CONFIG_ARCH_ADI_COYOTE
arch/arm/mach-ixp4xx/ixdp425-setup.c renamed from arch/arm/mach-ixp4xx/ixdp425-setup.c~arm-lite +10 -2
@@ -23,6 +23,7 @@#include <asm/irq.h> #include <asm/mach/arch.h> #include <asm/mach/flash.h> +#include <asm/kgdb.h> void __init ixdp425_map_io (void ) {
@@ -82,7 +83,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,
@@ -91,7 +93,8 @@ static struct plat_serial8250_port ixdp4 .mapbase = IXP4XX_UART2_BASE_PHYS, .membase = (char *)IXP4XX_UART2_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,
@@ -126,6 +129,11 @@ static void __init ixdp425_init(void) }platform_add_devices (ixdp425_devices,ARRAY_SIZE (ixdp425_devices)); + +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (0 , &ixdp425_serial_ports[0 ]); +kgdb8250_add_port (1 , &ixdp425_serial_ports[1 ]); +#endif }MACHINE_START (IXDP425 ,"Intel IXDP425 Development Platform" )
arch/arm/mach-omap1/board-osk.c renamed from arch/arm/mach-omap1/board-osk.c~arm-lite +4 -2
@@ -41,12 +41,14 @@#include <asm/arch/tc.h> #include <asm/arch/common.h> +#if 0 static struct map_desc osk5912_io_desc[]__initdata = { {OMAP_OSK_NOR_FLASH_BASE ,OMAP_OSK_NOR_FLASH_START ,OMAP_OSK_NOR_FLASH_SIZE ,MT_DEVICE }, }; +#endif -static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS ] = {1 ,0 ,0 }; +static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS ] = {1 ,1 ,1 };static struct resource osk5912_smc91x_resources[] = { [0 ] = {
@@ -153,7 +155,7 @@ static void __init osk_init(void)static void __init osk_map_io (void ) {omap_map_common_io (); -iotable_init (osk5912_io_desc,ARRAY_SIZE (osk5912_io_desc)); +//iotable_init(osk5912_io_desc, ARRAY_SIZE(osk5912_io_desc)); omap_serial_init (osk_serial_ports); }
arch/arm/mach-omap1/serial.c renamed from arch/arm/mach-omap1/serial.c~arm-lite +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>
@@ -190,6 +191,9 @@ void __init omap_serial_init(int ports[Obreak ; }omap_serial_reset (&serial_platform_data[i]); +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_platform_port (i, &serial_platform_data[i]); +#endif } }
arch/arm/mach-pxa/kgdb-serial.c new file +98 -0
98 lines not on this page · raw message
arch/arm/mach-pxa/Makefile renamed from arch/arm/mach-pxa/Makefile~arm-lite +1 -0
@@ -24,6 +24,7 @@ obj-$(CONFIG_LEDS) += $(led-y) # Misc features obj-$(CONFIG_PM) += pm.o sleep.o +obj-$(CONFIG_KGDB_PXA_SERIAL) += kgdb-serial.o ifeq ($(CONFIG_PXA27x),y) obj-$(CONFIG_PM) += standby.o
arch/arm/mach-versatile/kgdb_serial.c new file +121 -0
121 lines not on this page · raw message
arch/arm/mm/extable.c renamed from arch/arm/mm/extable.c~arm-lite +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/amba-pl011.c renamed from drivers/serial/amba-pl011.c~arm-lite +1 -1
@@ -350,7 +350,7 @@ 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,SA_SHIRQ ,"uart-pl011" , uap);if (retval) goto clk_dis;
diff -puN drivers/serial/kgdb_8250.c~arm-lite drivers/serial/kgdb_8250.c
include/asm-arm/kgdb.h new file +90 -0
90 lines not on this page · raw message
include/asm-arm/system.h renamed from include/asm-arm/system.h~arm-lite +41 -0
47 lines not on this page · raw message
lib/Kconfig.debug renamed from lib/Kconfig.debug~arm-lite +34 -1
@@ -163,7 +163,7 @@ config FRAME_POINTER config KGDB bool "KGDB: kernel debugging with remote gdb" select WANT_EXTRA_DEBUG_INFORMATION - depends on DEBUG_KERNEL && (X86 || MIPS32 || (SUPERH && !SUPERH64) || IA64 || X86_64 || ((!SMP || BROKEN) && PPC32)) + depends on DEBUG_KERNEL && (ARM || X86 || MIPS32 || (SUPERH && !SUPERH64) || IA64 || X86_64 || ((!SMP || BROKEN) && PPC32)) help If you say Y here, it will be possible to remotely debug the kernel using gdb. It is strongly suggested that you enable
@@ -189,8 +189,10 @@ choice prompt "Method for KGDB communication" depends on KGDB default KGDB_8250_NOMODULE + default KGDB_ARM_VERSATILE if ARCH_VERSATILE default KGDB_SIBYTE if SIBYTE_SB1xxx_SOC default KGDB_MPSC if SERIAL_MPSC + default KGDB_PXA_SERIAL if ARCH_PXA help There are a number of different ways in which you can communicate with KGDB. The most common is via serial, with the 8250 driver
@@ -227,6 +229,16 @@ config KGDB_SIBYTE bool "KGDB: On the Broadcom SWARM serial port" depends on MIPS && SIBYTE_SB1xxx_SOC +config KGDB_ARM_VERSATILE + bool "KGDB: On ARM Versatile" + depends on ARM && ARCH_VERSATILE + help + Enables the KGDB serial driver for the ARM Versatile + +config KGDB_PXA_SERIAL + bool "KGDB: On the PXA2xx serial port" + depends on ARCH_PXA + config KGDB_SH_SCI bool "KGDB: On SH SCI(F) serial port" depends on SUPERH && SERIAL_SH_SCI
@@ -297,6 +309,27 @@ config KGDB_PORT_3 bool "Third serial port" endchoice +choice + prompt "PXA serial UART for KGDB" + depends on KGDB_PXA_SERIAL + default KGDB_PXA_FFUART + +config KGDB_PXA_FFUART + bool "FFUART" + +config KGDB_PXA_BTUART + bool "BTUART" + +config KGDB_PXA_STUART + bool "STUART" + +endchoice + +config KGDB_PXA_BAUDRATE + int "UART baudrate for KGDB" + depends on KGDB_PXA_SERIAL + default "115200" + config KGDB_PORT hex "hex I/O port address of the debug serial port" depends on !KGDB_SIMPLE_SERIAL && KGDB_8250 && !IA64
_
PATCH 14/16 Minor SysRq keyboard bugfix for KGDB
In reply to Tom RiniCC: George Anzginer <[email protected]>
It is possible that when SysRq-G is triggered via the keyboard that we will miss the "up" event and once KGDB lets the kernel go another SysRq will be required to clear this, without this change.
---
linux-2.6.13-trini/drivers/char/keyboard.c | 1 + 1 files changed, 1 insertion(+)
drivers/char/keyboard.c renamed from drivers/char/keyboard.c~sysrq_bugfix +1 -0
@@ -1070,6 +1070,7 @@ static void kbd_keycode(unsigned int key }if (sysrq_down && down && !rep) {handle_sysrq (kbd_sysrq_xlate[keycode], regs, tty); + sysrq_down =0 ;/* In case we miss the 'up' event. */ return ; }#endif
_
PATCH 9/16 Add support for SuperH platforms to KGDB
In reply to Tom RiniThis adds basic support for KGDB on SuperH as well as adding some architecture specific notes to the DocBook file and converting the 7751 to use this. I have tested all combinations of 8250 and SCI(F) ports being used as KGDB and console that I could (one of each usable to me).
arch/sh/boards/se/7751/setup.c +0 -139
@@ -18,10 +18,6 @@#include <asm/io.h> #include <asm/se7751/se7751.h> -#ifdef CONFIG_SH_KGDB -#include <asm/kgdb.h> -#endif -/* * Configure the Super I/O chip */
@@ -83,12 +79,6 @@ const char *get_system_type(void)return "7751 SolutionEngine" ; } -#ifdef CONFIG_SH_KGDB -static int kgdb_uart_setup (void ); -static struct kgdb_sermap kgdb_uart_sermap = -{"ttyS" ,0 , kgdb_uart_setup,NULL }; -#endif -/* * Initialize the board */
@@ -96,133 +86,4 @@ void __init platform_setup(void) {/* Call init_smsc() replacement to set up SuperIO. */ /* XXX: RTC setting comes here */ -#ifdef CONFIG_SH_KGDB -kgdb_register_sermap (&kgdb_uart_sermap); -#endif -} - -/********************************************************************* -* Currently a hack (e.g. does not interact well w/serial.c, lots of * -* hardcoded stuff) but may be useful if SCI/F needs debugging. * -* Mostly copied from x86 code (see files asm-i386/kgdb_local.h and * -* arch/i386/lib/kgdb_serial.c). * -*********************************************************************/ - -#ifdef CONFIG_SH_KGDB -#include <linux/types.h> -#include <linux/serial.h> -#include <linux/serialP.h> -#include <linux/serial_reg.h> - -#define COM1_PORT 0x3f8/* Base I/O address */ -#define COM1_IRQ 4/* IRQ not used yet */ -#define COM2_PORT 0x2f8/* Base I/O address */ -#define COM2_IRQ 3/* IRQ not used yet */ - -#define SB_CLOCK 1843200/* Serial baud clock */ -#define SB_BASE (SB_CLOCK/16) -#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS - -struct uart_port { -int base; -}; -#define UART_NPORTS 2 -struct uart_port uart_ports[] = { - {COM1_PORT }, - {COM2_PORT }, -}; -struct uart_port *kgdb_uart_port; - -#define UART_IN (reg) inb_p(kgdb_uart_port->base + reg) -#define UART_OUT (reg,v) outb_p((v), kgdb_uart_port->base + reg) - -/* Basic read/write functions for the UART */ -#define UART_LSR_RXCERR (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE) -static int kgdb_uart_getchar (void ) -{ -int lsr; -int c =-1 ; - -while (c ==-1 ) { - lsr =UART_IN (UART_LSR ); -if (lsr &UART_LSR_DR ) - c =UART_IN (UART_RX ); -if ((lsr &UART_LSR_RXCERR )) - c =-1 ; - } -return c; -} - -static void kgdb_uart_putchar (int c) -{ -while ((UART_IN (UART_LSR ) &UART_LSR_THRE ) ==0 ) - ; -UART_OUT (UART_TX , c); -} - -/* -* Initialize UART to configured/requested values. -* (But we don't interrupts yet, or interact w/serial.c) -*/ -static int kgdb_uart_setup (void ) -{ -int port; -int lcr =0 ; -int bdiv =0 ; - -if (kgdb_portnum >=UART_NPORTS ) { -KGDB_PRINTK ("uart port %d invalid.\n" , kgdb_portnum); -return -1 ; - } - - kgdb_uart_port = &uart_ports[kgdb_portnum]; - -/* Init sequence from gdb_hook_interrupt */ -UART_IN (UART_RX ); -UART_OUT (UART_IER ,0 ); - -UART_IN (UART_RX );/* Serial driver comments say */ -UART_IN (UART_IIR );/* this clears interrupt regs */ -UART_IN (UART_MSR ); - -/* Figure basic LCR values */ -switch (kgdb_bits) { -case '7' : - lcr |=UART_LCR_WLEN7 ; -break ; -default :case '8' : - lcr |=UART_LCR_WLEN8 ; -break ; - } -switch (kgdb_parity) { -case 'O' : - lcr |=UART_LCR_PARITY ; -break ; -case 'E' : - lcr |= (UART_LCR_PARITY |UART_LCR_EPAR ); -break ; -default :break ; - } - -/* Figure the baud rate divisor */ - bdiv = (SB_BASE /kgdb_baud); - -/* Set the baud rate and LCR values */ -UART_OUT (UART_LCR , (lcr |UART_LCR_DLAB )); -UART_OUT (UART_DLL , (bdiv &0xff )); -UART_OUT (UART_DLM , ((bdiv >>8 ) &0xff )); -UART_OUT (UART_LCR , lcr); - -/* Set the MCR */ -UART_OUT (UART_MCR ,SB_MCR ); - -/* Turn off FIFOs for now */ -UART_OUT (UART_FCR ,0 ); - -/* Setup complete: initialize function pointers */ - kgdb_getchar = kgdb_uart_getchar; - kgdb_putchar = kgdb_uart_putchar; - -return 0 ; } -#endif /* CONFIG_SH_KGDB */
arch/sh/Kconfig.debug +0 -92
96 lines not on this page · raw message
arch/sh/kernel/cpu/sh3/ex.S +1 -1
@@ -43,7 +43,7 @@ ENTRY(exception_handling_table) .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */ .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/ ENTRY(nmi_slot) -#if defined (CONFIG_KGDB_NMI) +#if defined (CONFIG_KGDB) .long debug_enter /* 1C0 */ ! Allow trap to debugger #else .long exception_none /* 1C0 */ ! Not implemented yet
arch/sh/kernel/cpu/sh4/ex.S +1 -1
@@ -47,7 +47,7 @@ ENTRY(exception_handling_table) .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */ .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/ ENTRY(nmi_slot) -#if defined (CONFIG_KGDB_NMI) +#if defined (CONFIG_KGDB) .long debug_enter /* 1C0 */ ! Allow trap to debugger #else .long exception_none /* 1C0 */ ! Not implemented yet
arch/sh/kernel/entry.S +16 -14
@@ -92,7 +92,7 @@ INTEVT = 0xff000028 MMU_TEA = 0xff00000c ! TLB Exception Address Register #endif -#if defined(CONFIG_KGDB_NMI) +#if defined(CONFIG_KGDB) NMI_VEC = 0x1c0 ! Must catch early for debounce #endif
@@ -244,31 +244,33 @@ call_dae: 2: .long do_address_error #endif /* CONFIG_MMU */ -#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) +#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_KGDB) ! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present. ! If both are configured, handle the debug traps (breakpoints) in SW, ! but still allow BIOS traps to FW. .align 2 debug_kernel: -#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB) +#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_KGDB) /* Force BIOS call to FW (debug_trap put TRA in r8) */ mov r8,r0 shlr2 r0 cmp/eq #0x3f,r0 bt debug_kernel_fw -#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */ +#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_KGDB */ -debug_enter: -#if defined(CONFIG_SH_KGDB) + .align 2 + .globl debug_enter +debug_enter: +#if defined(CONFIG_KGDB) /* Jump to kgdb, pass stacked regs as arg */ debug_kernel_sw: mov.l 3f, r0 jmp @r0 mov r15, r4 .align 2 -3: .long kgdb_handle_exception -#endif /* CONFIG_SH_KGDB */ +3: .long kgdb_exception_handler +#endif /* CONFIG_KGDB */ #if defined(CONFIG_SH_STANDARD_BIOS) /* Unwind the stack and jmp to the debug entry */
@@ -310,12 +312,12 @@ debug_kernel_fw: 2: .long gdb_vbr_vector #endif /* CONFIG_SH_STANDARD_BIOS */ -#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ +#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_KGDB */ .align 2 -debug_trap: -#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) +debug_trap: +#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_KGDB) mov #OFF_SR, r0 mov.l @(r0,r15), r0 ! get status register shll r0
@@ -659,7 +661,7 @@ skip_restore: 6: or k0, k2 ! Set the IMASK-bits ldc k2, ssr ! -#if defined(CONFIG_KGDB_NMI) +#if defined(CONFIG_KGDB) ! Clear in_nmi mov.l 4f, k0 mov #0, k1
@@ -711,7 +713,7 @@ tlb_miss: interrupt: mov.l 2f, k2 mov.l 3f, k3 -#if defined(CONFIG_KGDB_NMI) +#if defined(CONFIG_KGDB) ! Debounce (filter nested NMI) mov.l @k2, k0 mov.l 5f, k1
@@ -726,7 +728,7 @@ interrupt: 5: .long NMI_VEC 6: .long in_nmi 0: -#endif /* defined(CONFIG_KGDB_NMI) */ +#endif /* defined(CONFIG_KGDB) */ bra handle_exception mov.l @k2, k2
arch/sh/kernel/kgdb.c new file +363 -0
363 lines not on this page · raw message
arch/sh/kernel/kgdb_jmp.S deleted +0 -33
@@ -1,33 +0,0 @@ -#include <linux/linkage.h> - -ENTRY(setjmp) - add #(9*4), r4 - sts.l pr, @-r4 - mov.l r15, @-r4 - mov.l r14, @-r4 - mov.l r13, @-r4 - mov.l r12, @-r4 - mov.l r11, @-r4 - mov.l r10, @-r4 - mov.l r9, @-r4 - mov.l r8, @-r4 - rts - mov #0, r0 - -ENTRY(longjmp) - mov.l @r4+, r8 - mov.l @r4+, r9 - mov.l @r4+, r10 - mov.l @r4+, r11 - mov.l @r4+, r12 - mov.l @r4+, r13 - mov.l @r4+, r14 - mov.l @r4+, r15 - lds.l @r4+, pr - mov r5, r0 - tst r0, r0 - bf 1f - mov #1, r0 ! in case val==0 -1: rts - nop -
arch/sh/kernel/kgdb-jmp.S new file +32 -0
@@ -0,0 +1,32 @@ +#include <linux/linkage.h> + +ENTRY(kgdb_fault_setjmp) + add #(9*4), r4 + sts.l pr, @-r4 + mov.l r15, @-r4 + mov.l r14, @-r4 + mov.l r13, @-r4 + mov.l r12, @-r4 + mov.l r11, @-r4 + mov.l r10, @-r4 + mov.l r9, @-r4 + mov.l r8, @-r4 + rts + mov #0, r0 + +ENTRY(kgdb_fault_longjmp) + mov.l @r4+, r8 + mov.l @r4+, r9 + mov.l @r4+, r10 + mov.l @r4+, r11 + mov.l @r4+, r12 + mov.l @r4+, r13 + mov.l @r4+, r14 + mov.l @r4+, r15 + lds.l @r4+, pr + mov r5, r0 + tst r0, r0 + bf 1f + mov #1, r0 +1: rts + nop
arch/sh/kernel/kgdb_stub.c deleted +0 -1491
1,491 lines not on this page · raw message
arch/sh/kernel/Makefile +1 -1
@@ -13,7 +13,7 @@ obj-y += cpu/ obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_CF_ENABLER) += cf-enabler.o obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o -obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o +obj-$(CONFIG_KGDB) += kgdb.o kgdb-jmp.o obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
arch/sh/kernel/setup.c +0 -94
103 lines not on this page · raw message
arch/sh/kernel/time.c +0 -11
@@ -34,9 +34,6 @@#include <asm/rtc.h> #include <asm/freq.h> #include <asm/cpu/timer.h> -#ifdef CONFIG_SH_KGDB -#include <asm/kgdb.h> -#endif #include <linux/timex.h> #include <linux/irq.h>
@@ -646,12 +643,4 @@ void __init time_init(void)ctrl_outl (interval,TMU0_TCOR );ctrl_outl (interval,TMU0_TCNT );ctrl_outb (TMU_TSTR_INIT ,TMU_TSTR ); - -#if defined(CONFIG_SH_KGDB ) -/* -* Set up kgdb as requested. We do it here because the serial -* init uses the timer vars we just set up for figuring baud. -*/ -kgdb_init (); -#endif }
arch/sh/kernel/traps.c +7 -13
@@ -27,6 +27,7 @@#include <linux/spinlock.h> #include <linux/module.h> #include <linux/kallsyms.h> +#include <linux/kgdb.h> #include <asm/system.h> #include <asm/uaccess.h>
@@ -35,17 +36,8 @@#include <asm/processor.h> #include <asm/sections.h> -#ifdef CONFIG_SH_KGDB -#include <asm/kgdb.h> -#define CHK_REMOTE_DEBUG (regs) \ -{ \ - if ((kgdb_debug_hook != (kgdb_debug_hook_t *) NULL) && (!user_mode(regs))) \ - { \ - (*kgdb_debug_hook)(regs); \ - } \ -} -#else -#define CHK_REMOTE_DEBUG (regs) +#ifndef CONFIG_KGDB +#define kgdb_handle_exception (t, s, e, r)#endif #define DO_ERROR (trapnr, signr, str, name, tsk) \
@@ -66,7 +58,7 @@ asmlinkage void do_##name(unsigned longlocal_irq_enable (); \ tsk->thread.error_code = error_code; \ tsk->thread.trap_no = trapnr; \ -CHK_REMOTE_DEBUG (®s); \ +kgdb_handle_exception (trapnr, signr, error_code, ®s); \force_sig (signr, tsk); \die_if_no_fixup (str,®s,error_code); \ }
@@ -93,10 +85,12 @@ void die(const char * str, struct pt_reg {static int die_counter; +#ifdef CONFIG_KGDB +kgdb_handle_exception (1 ,SIGTRAP , err, regs); +#endif console_verbose ();spin_lock_irq (&die_lock);printk ("%s: %04lx [#%d]\n" , str, err &0xffff , ++die_counter); -CHK_REMOTE_DEBUG (regs);show_regs (regs);spin_unlock_irq (&die_lock);do_exit (SIGSEGV );
arch/sh/Makefile +0 -1
@@ -23,7 +23,6 @@ cflags-$(CONFIG_CPU_SH4) += -m4 \ $(call cc-option,-mno-implicit-fp,-m4-nofpu) cflags-$(CONFIG_SH_DSP) += -Wa,-dsp -cflags-$(CONFIG_SH_KGDB) += -g cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \ $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g')
arch/sh/mm/extable.c +7 -0
@@ -6,6 +6,7 @@#include <linux/config.h> #include <linux/module.h> +#include <linux/kgdb.h> #include <asm/uaccess.h> int fixup_exception (struct pt_regs *regs)
@@ -17,6 +18,12 @@ int fixup_exception(struct pt_regs *regs regs->pc = fixup->fixup;return 1 ; } +#ifdef CONFIG_KGDB +if (atomic_read (&debugger_active) && kgdb_may_fault) +/* Restore our previous state. */ +kgdb_fault_longjmp (kgdb_fault_jmp_regs); +/* Never reached. */ +#endif return 0 ; }
arch/sh/mm/fault.c +1 -11
@@ -28,7 +28,6 @@#include <asm/pgalloc.h> #include <asm/mmu_context.h> #include <asm/cacheflush.h> -#include <asm/kgdb.h> extern void die (const char *,struct pt_regs *,long );
@@ -45,11 +44,6 @@ asmlinkage void do_page_fault(struct pt_struct vm_area_struct * vma;unsigned long page; -#ifdef CONFIG_SH_KGDB -if (kgdb_nofault && kgdb_bus_err_hook) -kgdb_bus_err_hook (); -#endif - tsk = current; mm = tsk->mm;
@@ -153,6 +147,7 @@ no_context: }die ("Oops" , regs, writeaccess);do_exit (SIGKILL ); +dump_stack ();/* * We ran out of memory, or some other thing happened to us that made
@@ -199,11 +194,6 @@ asmlinkage int __do_page_fault(struct ptpte_t *pte;pte_t entry; -#ifdef CONFIG_SH_KGDB -if (kgdb_nofault && kgdb_bus_err_hook) -kgdb_bus_err_hook (); -#endif -#ifdef CONFIG_SH_STORE_QUEUES addrmax =P4SEG_STORE_QUE +0x04000000 ;#endif
arch/sh/mm/fault-nommu.c +0 -14
@@ -29,10 +29,6 @@#include <asm/mmu_context.h> #include <asm/cacheflush.h> -#if defined(CONFIG_SH_KGDB ) -#include <asm/kgdb.h> -#endif -extern void die (const char *,struct pt_regs *,long );/*
@@ -43,11 +39,6 @@ extern void die(const char *,struct pt_r asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,unsigned long address) { -#if defined(CONFIG_SH_KGDB ) -if (kgdb_nofault && kgdb_bus_err_hook) -kgdb_bus_err_hook (); -#endif -/* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice.
@@ -69,11 +60,6 @@ asmlinkage void do_page_fault(struct pt_ asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess,unsigned long address) { -#if defined(CONFIG_SH_KGDB ) -if (kgdb_nofault && kgdb_bus_err_hook) -kgdb_bus_err_hook (); -#endif -if (address >=TASK_SIZE )return 1 ;
Documentation/DocBook/kgdb.tmpl +16 -0
@@ -127,6 +127,10 @@ <constant>kgdbwait</constant> after this arguement. </para> <para> + To specify the values of the SH SCI(F) serial port at boot: + <constant>kgdbsci=0,115200</constant>. + </para> + <para> To configure the <symbol>CONFIG_KGDB_ETH</symbol> driver, pass in <constant>kgdboe=[src-port]@<src-ip>/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]</constant> where:
@@ -168,6 +172,18 @@ application program. </para> </chapter> + <chapter id="ArchitectureNotes"> + <title>Architecture specific notes</title> + <para> + SuperH: The NMI switch found on some boards can be used to trigger an + initial breakpoint. Subsequent triggers do nothing. If console + is enabled on the SCI(F) serial port, and that is the port being used + for KGDB, then you must trigger a breakpoint via sysrq, NMI, or + some other method prior to connecting, or echo a control-c to the + serial port. Also, to use the SCI(F) port for KGDB, the + <symbol>CONFIG_SERIAL_SH_SCI</symbol> driver must be enabled. + </para> + </chapter> <chapter id="CommonBackEndReq"> <title>The common backend (required)</title> <para>
drivers/serial/sh-sci.c +187 -127
426 lines not on this page · raw message
include/asm-sh/kgdb.h +20 -98
118 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Part of the diff is not shown here. View the raw message.
PATCH 11/16 Add support for PowerPC64 platforms to KGDB
In reply to Tom RiniThis adds basic KGDB support to ppc64, and support for kgdb8250 on the 'Maple' board. All of this was done by Frank Rowand (who is on vacation right now, but I'll try and answer for him). This should work on any ppc64 board via kgdboe, so long as there is an eth driver that supports netpoll. At the moment this is mutually exclusive with XMON. It is probably possible to allow them to be chained, but that sounds dangerous to me. This is similar to ppc32, but ppc32 does not explicitly test.
---
linux-2.6.13-trini/arch/ppc64/Kconfig.debug | 14 linux-2.6.13-trini/arch/ppc64/kernel/Makefile | 3 linux-2.6.13-trini/arch/ppc64/kernel/kgdb.c | 422 +++++++++++++++++ linux-2.6.13-trini/arch/ppc64/kernel/maple_setup.c | 5 linux-2.6.13-trini/arch/ppc64/kernel/setup.c | 14 linux-2.6.13-trini/arch/ppc64/mm/fault.c | 8 linux-2.6.13-trini/include/asm-ppc64/kgdb.h | 55 ++ linux-2.6.13-trini/lib/Kconfig.debug | 2 8 files changed, 513 insertions(+), 10 deletions(-)
arch/ppc64/Kconfig.debug renamed from arch/ppc64/Kconfig.debug~ppc64-lite +6 -8
@@ -28,16 +28,9 @@ config DEBUG_STACK_USAGE This option will slow down process creation somewhat. -config DEBUGGER - bool "Enable debugger hooks" - depends on DEBUG_KERNEL - help - Include in-kernel hooks for kernel debuggers. Unless you are - intending to debug the kernel, say N here. - config XMON bool "Include xmon kernel debugger" - depends on DEBUGGER && !PPC_ISERIES + depends on DEBUG_KERNEL && !PPC_ISERIES help Include in-kernel hooks for the xmon kernel monitor/debugger. Unless you are intending to debug the kernel, say N here.
@@ -46,6 +39,11 @@ config XMON_DEFAULT bool "Enable xmon by default" depends on XMON +config DEBUGGER + bool + depends on KGDB || XMON + default y + config PPCDBG bool "Include PPCDBG realtime debugging" depends on DEBUG_KERNEL
arch/ppc64/kernel/kgdb.c new file +422 -0
422 lines not on this page · raw message
arch/ppc64/kernel/Makefile renamed from arch/ppc64/kernel/Makefile~ppc64-lite +2 -1
@@ -2,7 +2,7 @@ # Makefile for the linux ppc64 kernel. # -EXTRA_CFLAGS += -mno-minimal-toc +#EXTRA_CFLAGS += -mno-minimal-toc extra-y := head.o vmlinux.lds obj-y := setup.o entry.o traps.o irq.o idle.o dma.o \
@@ -53,6 +53,7 @@ obj-$(CONFIG_HVCS) += hvcserver.o obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_XICS) += xics.o obj-$(CONFIG_MPIC) += mpic.o +obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_PPC_PMAC) += pmac_setup.o pmac_feature.o pmac_pci.o \ pmac_time.o pmac_nvram.o pmac_low_i2c.o
arch/ppc64/kernel/maple_setup.c renamed from arch/ppc64/kernel/maple_setup.c~ppc64-lite +5 -0
@@ -77,6 +77,7 @@ extern void maple_pcibios_fixup(void);extern int maple_pci_get_legacy_ide_irq (struct pci_dev *dev,int channel);extern void generic_find_legacy_serial_ports (u64 *physport,unsigned int *default_speed); +extern void add_kgdb_port (void );static void maple_restart (char *cmd) {
@@ -213,6 +214,10 @@ static void __init maple_init_early(voidDBG ("Hello World !\n" ); } +#ifdef CONFIG_KGDB_8250 +add_kgdb_port (); +#endif +/* Setup interrupt mapping options */ ppc64_interrupt_controller =IC_OPEN_PIC ;
arch/ppc64/kernel/setup.c renamed from arch/ppc64/kernel/setup.c~ppc64-lite +14 -0
@@ -33,6 +33,7 @@#include <linux/unistd.h> #include <linux/serial.h> #include <linux/serial_8250.h> +#include <linux/kgdb.h> #include <asm/io.h> #include <asm/prom.h> #include <asm/processor.h>
@@ -1258,6 +1259,7 @@ void __init generic_find_legacy_serial_p serial_ports[index].iobase = reg->address; serial_ports[index].irq = interrupts ? interrupts[0 ] :0 ; serial_ports[index].flags =ASYNC_BOOT_AUTOCONF ; + serial_ports[index].line = index; DBG("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n", index,
@@ -1311,6 +1313,18 @@ void __init generic_find_legacy_serial_pDBG (" <- generic_find_legacy_serial_port()\n" ); } + +#ifdef CONFIG_KGDB_8250 +void add_kgdb_port (void ) +{ +int ttyS; + + ttyS =kgdb8250_get_ttyS (); +if (ttyS < old_serial_count) +kgdb8250_add_platform_port (ttyS, &serial_ports[ttyS]); +} +#endif +static struct platform_device serial_device = { .name ="serial8250" , .id =0 ,
arch/ppc64/mm/fault.c renamed from arch/ppc64/mm/fault.c~ppc64-lite +8 -0
@@ -29,6 +29,7 @@#include <linux/interrupt.h> #include <linux/smp_lock.h> #include <linux/module.h> +#include <linux/kgdb.h> #include <asm/page.h> #include <asm/pgtable.h>
@@ -306,6 +307,13 @@ void bad_page_fault(struct pt_regs *regs regs->nip = entry->fixup;return ; } +#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 /* kernel has accessed a bad area */ die ("Kernel access of bad area" , regs, sig);
include/asm-ppc64/kgdb.h new file +55 -0
55 lines not on this page · raw message
lib/Kconfig.debug renamed from lib/Kconfig.debug~ppc64-lite +1 -1
@@ -163,7 +163,7 @@ config FRAME_POINTER config KGDB bool "KGDB: kernel debugging with remote gdb" select WANT_EXTRA_DEBUG_INFORMATION - depends on DEBUG_KERNEL && (ARM || X86 || MIPS32 || (SUPERH && !SUPERH64) || IA64 || X86_64 || ((!SMP || BROKEN) && PPC32)) + depends on DEBUG_KERNEL && (ARM || X86 || MIPS32 || PPC64 || (SUPERH && !SUPERH64) || IA64 || X86_64 || ((!SMP || BROKEN) && PPC32)) help If you say Y here, it will be possible to remotely debug the kernel using gdb. It is strongly suggested that you enable
_
PATCH 12/16 KGDBoE I/O driver
This is the simple KGDB over Ethernet I/O driver that uses netpoll for all of the heavy lifting. At one point this was very similar to the version Matt Mackall wrote and is currently in Andrew's tree. Since then it has been reworked to fit into our model.
---
linux-2.6.13-trini/drivers/net/Makefile | 1 linux-2.6.13-trini/drivers/net/kgdboe.c | 208 ++++++++++++++++++++++++++++ linux-2.6.13-trini/lib/Kconfig.debug | 24 +++ 3 files changed, 233 insertions(+)
drivers/net/kgdboe.c new file +208 -0
@@ -0,0 +1,208 @@ +/* +* drivers/net/kgdboe.c +* +* A network interface for GDB. +* Based upon 'gdbserial' by David Grothe <[email protected]> +* and Scott Foehner <[email protected]> +* +* Maintainers: Amit S. Kale <[email protected]> and +* Tom Rini <[email protected]> +* +* 2004 (c) Amit S. Kale <[email protected]> +* 2004-2005 (c) MontaVista Software, Inc. +* 2005 (c) Wind River Systems, Inc. +* +* Other folks: +* San Mehat <[email protected]> +* Robert Walsh <[email protected]> +* wangdi <[email protected]>. +* Matt Mackall <[email protected]> +* Pavel Machek <[email protected]> +* Jason Wessel <[email protected]> +* +* This file is licensed under the terms of the GNU General Public License +* version 2. This program is licensed "as is" without any warranty of any +* kind, whether express or implied. +* +* Changes: +* 3/10/05 - Jason Wessel <[email protected]> +* - Added ability to compile/load as module +* +* Known problems: +* - There is no way to deny the unloading of the module +* if KGDB is connected, but an attempt is made to handle it +*/ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/string.h> +#include <linux/kgdb.h> +#include <linux/netpoll.h> +#include <linux/init.h> + +#include <asm/atomic.h> + +#define IN_BUF_SIZE 512/* power of 2, please */ +#define OUT_BUF_SIZE 30/* We don't want to send too big of a packet. */ + +static char in_buf[IN_BUF_SIZE ], out_buf[OUT_BUF_SIZE ]; +static int in_head, in_tail, out_count; +static atomic_t in_count; +/* 0 = unconfigured, 1 = netpoll options parsed, 2 = fully configured. */ +static int configured; + +static void rx_hook (struct netpoll *np,int port,char *msg,int len); +static void eth_pre_exception_handler (void ); +static void eth_post_exception_handler (void ); +static int eth_get_char (void ); +static void eth_flush_buf (void ); +static void eth_put_char (int chr); +int init_kgdboe (void ); + +static struct netpoll np = { + .name ="kgdboe" , + .dev_name ="eth0" , + .rx_hook = rx_hook, + .local_port =6443 , + .remote_port =6442 , + .remote_mac = {0xff ,0xff ,0xff ,0xff ,0xff ,0xff }, +}; + +MODULE_DESCRIPTION ("KGDB driver for network interfaces" ); +MODULE_LICENSE ("GPL" ); +static char config[256 ]; +module_param_string (kgdboe, config,256 ,0 ); +MODULE_PARM_DESC (kgdboe," kgdboe=[src-port]@[src-ip]/[dev]," +"[tgt-port]@<tgt-ip>/<tgt-macaddr>\n" ); + +static struct kgdb_io local_kgdb_io_ops = { + .read_char = eth_get_char, + .write_char = eth_put_char, + .init = init_kgdboe, + .flush = eth_flush_buf, + .pre_exception = eth_pre_exception_handler, + .post_exception = eth_post_exception_handler +}; + +static void eth_pre_exception_handler (void ) +{ +netpoll_set_trap (1 ); +} + +static void eth_post_exception_handler (void ) +{ +netpoll_set_trap (0 ); +} + +static int eth_get_char (void ) +{ +int chr; + +while (atomic_read (&in_count) ==0 ) +netpoll_poll (&np); + + chr = in_buf[in_tail++]; + in_tail &= (IN_BUF_SIZE -1 ); +atomic_dec (&in_count); +return chr; +} + +static void eth_flush_buf (void ) +{ +if (out_count && np.dev) { +netpoll_send_udp (&np, out_buf, out_count); +memset (out_buf,0 ,sizeof (out_buf)); + out_count =0 ; + } +} + +static void eth_put_char (int chr) +{ + out_buf[out_count++] = chr; +if (out_count ==OUT_BUF_SIZE ) +eth_flush_buf (); +} + +static void rx_hook (struct netpoll *np,int port,char *msg,int len) +{ +int i; + + np->remote_port = port; + +/* +* This could be GDB trying to attach. But it could also be GDB +* finishing up a session, with kgdb_connected=0 but GDB sending +* an ACK for the final packet. To make sure we don't try and +* make a breakpoint when GDB is leaving, make sure that if +* !kgdb_connected the only len == 1 packet we allow is ^C. +*/ +if (!kgdb_connected && (len !=1 || msg[0 ] ==3 ) && + !atomic_read (&kgdb_setting_breakpoint)) +tasklet_schedule (&kgdb_tasklet_breakpoint); + +for (i =0 ; i < len; i++) { +if (msg[i] ==3 ) +tasklet_schedule (&kgdb_tasklet_breakpoint); + +if (atomic_read (&in_count) >=IN_BUF_SIZE ) { +/* buffer overflow, clear it */ + in_head = in_tail =0 ; +atomic_set (&in_count,0 ); +break ; + } + in_buf[in_head++] = msg[i]; + in_head &= (IN_BUF_SIZE -1 ); +atomic_inc (&in_count); + } +} + +static int option_setup (char *opt) +{ + configured = !netpoll_parse_options (&np, opt); +return 0 ; +} + +__setup ("kgdboe=" , option_setup); + +int init_kgdboe (void ) +{ +/* Already done? */ +if (configured ==2 ) +return 0 ; + +if (strlen (config)) +option_setup (config); + +if (!configured) { +printk ("kgdboe: configuration incorrect - kgdboe not " +"loaded.\n" ); +printk (" Usage: kgdboe=[src-port]@[src-ip]/[dev],[tgt-port]" +"@<tgt-ip>/[tgt-macaddr]\n" ); +return -EINVAL ; + } + +if (netpoll_setup (&np)) { +printk ("kgdboe: netpoll_setup failed kgdboe failed\n" ); +return -EINVAL ; + } + +if (kgdb_register_io_module (&local_kgdb_io_ops)) +return -EINVAL ; + +printk (KERN_INFO "kgdboe: debugging over ethernet enabled\n" ); + + configured =2 ; + +return 0 ; +} + +static void cleanup_kgdboe (void ) +{ +netpoll_cleanup (&np); + configured =0 ; + +kgdb_unregister_io_module (&local_kgdb_io_ops); +} + +module_init (init_kgdboe); +module_exit (cleanup_kgdboe);
drivers/net/Makefile renamed from drivers/net/Makefile~eth +1 -0
@@ -195,3 +195,4 @@ obj-$(CONFIG_IRDA) += irda/ obj-$(CONFIG_ETRAX_ETHERNET) += cris/ obj-$(CONFIG_NETCONSOLE) += netconsole.o +obj-$(CONFIG_KGDBOE) += kgdboe.o
lib/Kconfig.debug renamed from lib/Kconfig.debug~eth +24 -0
@@ -217,6 +217,18 @@ config KGDB_8250_NOMODULE GDB. This is independent of the normal (SERIAL_8250) driver for this chipset. +config KGDBOE_NOMODULE + bool "KGDB: On ethernet - in kernel" + select KGDBOE + select NETPOLL + select NETPOLL_TRAP + select NETPOLL_RX + help + Uses the NETPOLL API to communicate with the host GDB via UDP. + In order for this to work, the ethernet interface specified must + support the NETPOLL API, and this must be initialized at boot. + See the documentation for syntax. + config KGDB_MPSC bool "KGDB on MV64x60 MPSC" depends on SERIAL_MPSC
@@ -247,6 +259,18 @@ config KGDB_SH_SCI endchoice +config KGDBOE + tristate "KGDB: On ethernet" if !KGDBOE_NOMODULE + depends on m && KGDB_ONLY_MODULES + select NETPOLL + select NETPOLL_TRAP + select NETPOLL_RX + help + Uses the NETPOLL API to communicate with the host GDB via UDP. + In order for this to work, the ethernet interface specified must + support the NETPOLL API, and this must be initialized at boot. + See the documentation for syntax. + config KGDB_8250 tristate "KGDB: On generic serial port (8250)" if !KGDB_8250_NOMODULE depends on m && KGDB_ONLY_MODULES
_
PATCH 16/16 Add hardware breakpoint support for i386
In reply to Tom RiniThis adds hardware breakpoint support for i386. This is not as well tested as software breakpoints, but in some minimal testing appears to be functional.
---
linux-2.6.13-trini/arch/i386/kernel/kgdb.c | 49 +++++++++++++++++++++++++ 1 files changed, 49 insertions(+)
arch/i386/kernel/kgdb.c renamed from arch/i386/kernel/kgdb.c~i386 +49 -0
@@ -184,6 +184,54 @@ void kgdb_correct_hw_break(void) asmvolatile ("movl %0, %%db7\n" ::"r" (dr7)); } +int kgdb_remove_hw_break (unsigned long addr) +{ +int i, idx =-1 ; +for (i =0 ; i <4 ; i++) { +if (breakinfo[i].addr == addr && breakinfo[i].enabled) { + idx = i; +break ; + } + } +if (idx ==-1 ) +return -1 ; + + breakinfo[idx].enabled =0 ; +return 0 ; +} + +void kgdb_remove_all_hw_break (void ) +{ +int i; + +for (i =0 ; i <4 ; i++) { +if (breakinfo[i].enabled) { +/* Do what? */ + ; + } +memset (&breakinfo[i],0 ,sizeof (struct hw_breakpoint )); + } +} + +int kgdb_set_hw_break (unsigned long addr) +{ +int i, idx =-1 ; +for (i =0 ; i <4 ; i++) { +if (!breakinfo[i].enabled) { + idx = i; +break ; + } + } +if (idx ==-1 ) +return -1 ; + + breakinfo[idx].enabled =1 ; + breakinfo[idx].type =1 ; + breakinfo[idx].len =1 ; + breakinfo[idx].addr = addr; +return 0 ; +} +void kgdb_disable_hw_debug (struct pt_regs *regs) {/* Disable hardware debugging while we are in kgdb */
@@ -298,4 +346,5 @@ int kgdb_arch_init(void)struct kgdb_arch arch_kgdb_ops = { .gdb_bpt_instr = {0xcc }, + .flags =KGDB_HW_BREAKPOINT , };
_
PATCH 15/16 Allow KGDB to work well with loaded modules
In reply to Tom RiniThis allows for KGDB to better deal with autoloaded modules. The way this works, requires a patch to GDB. This patch can be found at ftp://source.mvista.com/pub/kgdb/gdb-6.3-kgdb-module-notification.patch
The way this works is that the solib-search-path must contain the location of any module to be debugged, and then when a module is loaded GDB acts like a shared library has been loaded now, and can be used that way.
---
linux-2.6.13-trini/include/linux/module.h | 16 ++++++++ linux-2.6.13-trini/kernel/module.c | 56 ++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+)
include/linux/module.h renamed from include/linux/module.h~module +16 -0
@@ -210,8 +210,17 @@ enum module_stateMODULE_STATE_LIVE ,MODULE_STATE_COMING ,MODULE_STATE_GOING , + MODULE_STATE_GONE, }; +#ifdef CONFIG_KGDB +#define MAX_SECTNAME 31 +struct mod_section { +void *address; +char name[MAX_SECTNAME +1 ]; +}; +#endif +/* Similar stuff for section attributes. */ #define MODULE_SECT_NAME_LEN 32struct module_sect_attr
@@ -239,6 +248,13 @@ struct module/* Unique handle for this module */ char name[MODULE_NAME_LEN ]; +#ifdef CONFIG_KGDB +/* keep kgdb info at the begining so that gdb doesn't have a chance to +* miss out any fields */ +unsigned long num_sections; +struct mod_section *mod_sections; +#endif +/* Sysfs stuff. */ struct module_kobject mkobj;struct module_param_attrs *param_attrs;
kernel/module.c renamed from kernel/module.c~module +56 -0
98 lines not on this page · raw message
_
PATCH 13/16 Add CFI DWARF2 annotation support
In reply to Tom RiniThere are some parts of the kernel where you simply cannot unwind past. This does not, however, stop GDB from trying, and getting stuck in an infinite loop (it will get garbage back, try and unwind that, repeat). The way to fix this is to manually insert some DWARF2 information into the kernel so that GDB will cleanly (or almost cleanly, it will get the same frame twice, and stop) stop. George wrote much of the IMHO hard part here (i386 & the macros) and I expanded this to all of the other arches. This adds a small amount to the DEBUG_INFO=y kernel size, but that's not unexpected.
---
linux-2.6.13-trini/Makefile | 5 linux-2.6.13-trini/arch/arm/kernel/entry-armv.S | 2 linux-2.6.13-trini/arch/i386/kernel/entry.S | 105 ++ linux-2.6.13-trini/arch/i386/kernel/head.S | 5 linux-2.6.13-trini/arch/i386/kernel/process.c | 20 linux-2.6.13-trini/arch/i386/kernel/smpboot.c | 3 linux-2.6.13-trini/arch/x86_64/kernel/entry.S | 2 linux-2.6.13-trini/include/asm-arm/kgdb.h | 7 linux-2.6.13-trini/include/asm-generic/kgdb.h | 34 linux-2.6.13-trini/include/asm-i386/kgdb.h | 60 - linux-2.6.13-trini/include/asm-mips/kgdb.h | 4 linux-2.6.13-trini/include/asm-ppc/kgdb.h | 1 linux-2.6.13-trini/include/asm-sh/kgdb.h | 1 linux-2.6.13-trini/include/asm-x86_64/kgdb.h | 4 linux-2.6.13-trini/include/linux/dwarf2-lang.h | 301 +++++++ linux-2.6.13-trini/include/linux/dwarf2.h | 775 ++++++++++++++++++++ linux-2.6.13-trini/scripts/dwarfh.awk | 19 17 files changed, 1319 insertions(+), 29 deletions(-)
arch/arm/kernel/entry-armv.S renamed from arch/arm/kernel/entry-armv.S~cfi_annotations +2 -0
@@ -15,6 +15,7 @@ */ #include <linux/config.h> +#include <asm/kgdb.h> #include <asm/glue.h> #include <asm/vfpmacros.h> #include <asm/hardware.h> /* should be moved into entry-macro.S */
@@ -215,6 +216,7 @@ svc_preempt: beq preempt_return @ go again b 1b #endif + CFI_END_FRAME(__irq_svc) .align 5 __und_svc:
arch/i386/kernel/entry.S renamed from arch/i386/kernel/entry.S~cfi_annotations +105 -0
108 lines not on this page · raw message
arch/i386/kernel/head.S renamed from arch/i386/kernel/head.S~cfi_annotations +4 -1
@@ -11,6 +11,7 @@ #include <linux/config.h> #include <linux/threads.h> #include <linux/linkage.h> +#include <asm/kgdb.h> #include <asm/segment.h> #include <asm/page.h> #include <asm/pgtable.h>
@@ -328,7 +329,9 @@ is386: movl $2,%ecx # set MP L6: jmp L6 # main should never return here, but # just in case, we know what happens. - + /* This dwarf code tells gdb that this is the end of the unwind */ + /* This uses the CFA set up for pc=1 located in entry.S */ + CFI_END_FRAME(is386) /* * We depend on ET to be correct. This checks for 287/387. */
arch/i386/kernel/process.c renamed from arch/i386/kernel/process.c~cfi_annotations +20 -0
@@ -341,7 +341,27 @@ __asm__(".section .text\n""call *%ebx\n\t" "pushl %eax\n\t" "call do_exit\n" +"kernel_thread_helper_end:\n\t" ".previous"); +#ifdef CONFIG_KGDB +#include <linux/dwarf2-lang.h> + +/* This dwarf code tells gdb that this is the end of the unwind */ +/* This uses the CFA set up for pc=1 located in entry.S */ +#define _ESP 4 +#define _PC 8 +#define _EIP 8 +__asm__( + QUOTE_THIS( + CFI_preamble(dwarf_4,_PC,1,1) + CFA_define_reference(_ESP,0) /* Stack pointer */ + CFA_undefine_reg(_EIP) + CFI_postamble() + + FDE_preamble(dwarf_4,kernel_thread_helper,kernel_thread_helper_end) + FDE_postamble() + )); +#endif /* * Create a kernel thread
arch/i386/kernel/smpboot.c renamed from arch/i386/kernel/smpboot.c~cfi_annotations +3 -0
@@ -537,6 +537,9 @@ void __devinit initialize_secondary(void asmvolatile ( "movl %0,%%esp\n\t" +#ifdef CONFIG_KGDB + "pushl end_of_stack_stop_unwind_function\n\t" +#endif"jmp *%1" : :"r" (current->thread.esp),"r" (current->thread.eip));
arch/x86_64/kernel/entry.S renamed from arch/x86_64/kernel/entry.S~cfi_annotations +2 -0
@@ -41,6 +41,7 @@ #include <asm/unistd.h> #include <asm/thread_info.h> #include <asm/hw_irq.h> +#include <asm/kgdb.h> .code64
@@ -741,6 +742,7 @@ ENTRY(kernel_thread) UNFAKE_STACK_FRAME ret CFI_ENDPROC + CFI_END_FRAME(kernel_thread) child_rip:
include/asm-arm/kgdb.h renamed from include/asm-arm/kgdb.h~cfi_annotations +5 -2
@@ -14,6 +14,7 @@#include <linux/config.h> #include <asm/ptrace.h> +#include <asm-generic/kgdb.h> /*
@@ -65,6 +66,7 @@ extern int kgdb_fault_expected;#define NUMREGBYTES (GDB_MAX_REGS << 2)#define NUMCRITREGBYTES (32 << 2)#define CHECK_EXCEPTION_STACK () 1 +#endif /* __ASSEMBLY__ */ #define _R0 0#define _R1 1
@@ -84,7 +86,8 @@ extern int kgdb_fault_expected;#define _PC 15#define _CPSR (GDB_MAX_REGS - 1) -#define CHECK_EXCEPTION_STACK () 1 +/* So that we can denote the end of a frame for tracing, in the simple +* case. */ +#define CFI_END_FRAME (func) __CFI_END_FRAME(_PC,_SP,func) -#endif // !__ASSEMBLY__ #endif // __ASM_KGDB_H__
include/asm-generic/kgdb.h new file +34 -0
@@ -0,0 +1,34 @@ +/* +* include/asm-generic/kgdb.h +* +* This provides the assembly level information so that KGDB can provide +* a GDB that has been patched with enough information to know to stop +* trying to unwind the function. +* +* Author: Tom Rini <[email protected]> +* +* 2005 (c) MontaVista Software, Inc. This file is licensed under the terms +* of the GNU General Public License version 2. This program is licensed +* "as is" without any warranty of any kind, whether express or implied. +*/ + +#ifndef __ASM_GENERIC_KGDB_H__ +#define __ASM_GENERIC_KGDB_H__ + +#include <linux/dwarf2-lang.h> +#ifdef __ASSEMBLY__ +#ifdef CONFIG_KGDB +/* This MUST be put at the end of a given assembly function */ +#define __CFI_END_FRAME (pc,sp,func) \ +CAT3(.Lend_,func,:) \ + CFI_preamble(func,pc,0x1,-DATA_ALIGN_FACTOR) \ + CFA_define_reference(sp, 0) \ + CFA_undefine_reg(pc) \ + CFI_postamble() \ + FDE_preamble(func,func,CAT3(.Lend,_,func)) \ + FDE_postamble() +#else +#define __CFI_END_FRAME (pc,sp,fn) +#endif /* CONFIG_KGDB */ +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_GENERIC_KGDB_H__ */
include/asm-i386/kgdb.h renamed from include/asm-i386/kgdb.h~cfi_annotations +35 -25
78 lines not on this page · raw message
include/asm-mips/kgdb.h renamed from include/asm-mips/kgdb.h~cfi_annotations +4 -0
@@ -2,6 +2,9 @@#ifndef _ASM_KGDB_H_#define _ASM_KGDB_H_ +#include <asm-generic/kgdb.h> + +#ifndef __ASSEMBLY__#define BUFMAX 2048#define NUMREGBYTES (90*sizeof(long))#define NUMCRITREGBYTES (12*sizeof(long))
@@ -18,5 +21,6 @@extern int kgdb_early_setup; +#endif /* !__ASSEMBLY__ */ #endif /* _ASM_KGDB_H_ */ #endif /* __KERNEL__ */
include/asm-ppc/kgdb.h renamed from include/asm-ppc/kgdb.h~cfi_annotations +1 -0
@@ -12,6 +12,7 @@#ifndef _PPC_KGDB_H#define _PPC_KGDB_H +#include <asm-generic/kgdb.h> #ifndef __ASSEMBLY__#define BREAK_INSTR_SIZE 4
include/asm-sh/kgdb.h renamed from include/asm-sh/kgdb.h~cfi_annotations +1 -0
@@ -15,6 +15,7 @@#define __KGDB_H#include <asm-generic/kgdb.h> +#include <asm-generic/kgdb.h> /* Based on sh-gdb.c from gdb-6.1, Glenn Engel at HP Ben Lee and Steve Chamberlain */ #define NUMREGBYTES 112/* 92 */
include/asm-x86_64/kgdb.h renamed from include/asm-x86_64/kgdb.h~cfi_annotations +4 -0
@@ -6,6 +6,8 @@* Copyright (C) 2001-2004 Amit S. Kale */ +#include <asm-generic/kgdb.h> +/* * Note that this register image is in a different order than * the register image that Linux produces at interrupt time.
@@ -36,6 +38,8 @@#define NUMREGBYTES ((_PS+1)*8)#define NUMCRITREGBYTES (8 * 8)/* 8 registers. */ +/* Help GDB to know when to stop backtracing. */ +#define CFI_END_FRAME (func) __CFI_END_FRAME(_PC,_RSP,func)#ifndef __ASSEMBLY__/* BUFMAX defines the maximum number of characters in inbound/outbound * buffers at least NUMREGBYTES*2 are needed for register packets, and
include/linux/dwarf2.h new file +775 -0
775 lines not on this page · raw message
include/linux/dwarf2-lang.h new file +301 -0
301 lines not on this page · raw message
Makefile renamed from Makefile~cfi_annotations +4 -1
@@ -1345,5 +1345,8 @@ clean := -f $(if $(KBUILD_SRC),$(srctree descend =$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=$(1) $(2) endif # skip-makefile +include/linux/dwarf2-defs.h: $(srctree)/include/linux/dwarf2.h $(srctree)/scripts/dwarfh.awk + mkdir -p include/linux/ + awk -f $(srctree)/scripts/dwarfh.awk $(srctree)/include/linux/dwarf2.h > include/linux/dwarf2-defs.h -FORCE: +FORCE: include/linux/dwarf2-defs.h
scripts/dwarfh.awk new file +19 -0
@@ -0,0 +1,19 @@ +BEGIN { + print "#ifndef _ELF_DWARF_H" + print "/* Machine generated from dwarf2.h by scripts/dwarfh.awk */" +} +$2 == "=" { + gsub(/,/, "", $3) + print "#define " $1 "\t " $3 +} +$1 == "#define" { + print $0 + while( index($0,"\\") == length($0)){ + getline + print $0 + } +} +/.*/ {} +END { + print "#endif" +}
_
Re: [patch 04/16] I/O driver for 8250-compatible UARTs
In reply to Tom RiniQuoted 1 line · Tom Rini
This is the I/O driver for any 8250-compatible UARTs.
Ah, obviously its patchbomb time. 2.6.13 must have been released! 8)
I wish for this stuff to wait until my queue of stuff has gone to Linus first - otherwise Linus will probably have a merge headache on his hands... unless these patches are against the -mm kernels.
Signature · 3 lines
Russell King Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/ maintainer of: 2.6 Serial core
Re: [patch 04/16] I/O driver for 8250-compatible UARTs
Quoted 8 lines · Russell King
Quoted 1 line · Tom Rini
This is the I/O driver for any 8250-compatible UARTs.
Ah, obviously its patchbomb time. 2.6.13 must have been released! 8)
I wish for this stuff to wait until my queue of stuff has gone to Linus first - otherwise Linus will probably have a merge headache on his hands... unless these patches are against the -mm kernels.
I forsee it as being unlikely that this will hit Linus' tree without sometime spent in -mm, and probably more time than it will take for your queue to drain. But, these are unlikey to cause a headache (new func, extern for said func, Kconfig around SERIAL_8250_NR_UARTS, it really is simplier than before :))
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [patch 08/16] Add support for X86_64 platforms to KGDB
In reply to Tom Riniarch/x86_64/kernel/setup64.c static int __init nonx32_setup(char *str · line 88
Quoted 9 lines · Tom Rini
arch/x86_64/kernel/setup64.c renamed from arch/x86_64/kernel/setup64.c~x86_64-lite +9
-0+void __init early_setup_per_cpu_area (void ) +{ + static char cpu0[PERCPU_ENOUGH_ROOM] + __attribute__ ((aligned (SMP_CACHE_BYTES))); +char *ptr = cpu0; + + cpu_pda[0 ].data_offset = ptr - __per_cpu_start; +memcpy (ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); +}
What is that? It looks totally bogus. Can you tell exactly where you believe early per cpu data is needed?
arch/x86_64/kernel/setup64.c void __init setup_per_cpu_areas(void) · line 111
Quoted 11 lines
arch/x86_64/kernel/setup64.c renamed from arch/x86_64/kernel/setup64.c~x86_64-lite +3
-1+/* * Great future plan: * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data. @@ -97,7 +107,9 @@ void __init setup_per_cpu_areas(void)for (i =0 ; i <NR_CPUS ; i++) {char *ptr; -if (!NODE_DATA (cpu_to_node (i))) { +if (cpu_pda[i].data_offset) +continue ;
And that looks broken too.
In general I would also advise to mix any other changes outside kgdb* into the x86-64 kgdb patch. Either the patch should be merged into mainline in a separate patch or kgdb reworked to not need this.
arch/x86_64/mm/fault.c no_context: · line 522
Quoted 4 lines
arch/x86_64/mm/fault.c renamed from arch/x86_64/mm/fault.c~x86_64-lite +4
-0+if (notify_die (DIE_PAGE_FAULT ,"no context" , regs, error_code,14 , +SIGSEGV ) ==NOTIFY_STOP ) +return ; +
I can see the point of that. It's ok if you submit it as a separate patch.
Regarding early trap init: I would have no problem to move all of traps_init into setup_arch (and leave traps_init empty for generic code). I actually don't know why it runs so late. But doing it half way is ugly.
-Andi
Re: [patch 08/16] Add support for X86_64 platforms to KGDB
Quoted 14 lines · Andi Kleen
arch/x86_64/kernel/setup64.c static int __init nonx32_setup(char *str · line 88
Quoted 9 lines · Tom Rini
arch/x86_64/kernel/setup64.c renamed from arch/x86_64/kernel/setup64.c~x86_64-lite +9
-0+void __init early_setup_per_cpu_area (void ) +{ + static char cpu0[PERCPU_ENOUGH_ROOM] + __attribute__ ((aligned (SMP_CACHE_BYTES))); +char *ptr = cpu0; + + cpu_pda[0 ].data_offset = ptr - __per_cpu_start; +memcpy (ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); +}What is that? It looks totally bogus. Can you tell exactly where you believe early per cpu data is needed?
Bob did this part (forgot to CC him, oops). But I believe it's needed for setting traps so much earlier.
Quoted 8 lines
Quoted 8 lines
arch/x86_64/kernel/setup64.c renamed from arch/x86_64/kernel/setup64.c~x86_64-lite +1
-0+/* * Great future plan: * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data. @@ -97,7 +107,9 @@ void __init setup_per_cpu_areas(void)for (i =0 ; i <NR_CPUS ; i++) {char *ptr;
Quoted 5 lines
arch/x86_64/kernel/setup64.c void __init setup_per_cpu_areas(void) · line 111
Quoted 3 lines
arch/x86_64/kernel/setup64.c renamed from arch/x86_64/kernel/setup64.c~x86_64-lite +2
-1-if (!NODE_DATA (cpu_to_node (i))) { +if (cpu_pda[i].data_offset) +continue ;And that looks broken too.
I believe that's to takecare of the case where something is covered in early_setup_cpu_areas().
Quoted 3 lines
In general I would also advise to mix any other changes outside kgdb* into the x86-64 kgdb patch. Either the patch should be merged into mainline in a separate patch or kgdb reworked to not need this.
ok.
Quoted 6 lines
arch/x86_64/mm/fault.c no_context: · line 522
Quoted 4 lines
arch/x86_64/mm/fault.c renamed from arch/x86_64/mm/fault.c~x86_64-lite +4
-0+if (notify_die (DIE_PAGE_FAULT ,"no context" , regs, error_code,14 , +SIGSEGV ) ==NOTIFY_STOP ) +return ; +I can see the point of that. It's ok if you submit it as a separate patch.
I can split that out into one that follows the KDB_VECTOR rename easily enough.
Quoted 3 lines
Regarding early trap init: I would have no problem to move all of
traps_initintosetup_arch(and leavetraps_initempty for generic code). I actually don't know why it runs so late. But doing it half way is ugly.
Should I make setup_per_cpu_area and trap_init empty and turn the real ones into early_foo?
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [patch 08/16] Add support for X86_64 platforms to KGDB
Quoted 3 lines · Tom Rini
Bob did this part (forgot to CC him, oops). But I believe it's needed for setting traps so much earlier.
Ok looking again I guess he needed it for the GDT access in cpu_init
Quoted 10 lines
Quoted 7 lines
arch/x86_64/mm/fault.c no_context: · line 522
Quoted 4 lines
arch/x86_64/mm/fault.c renamed from arch/x86_64/mm/fault.c~x86_64-lite +4
-0+if (notify_die (DIE_PAGE_FAULT ,"no context" , regs, error_code,14 , +SIGSEGV ) ==NOTIFY_STOP ) +return ; +I can see the point of that. It's ok if you submit it as a separate patch.
I can split that out into one that follows the
KDB_VECTORrename easily enough.
That's fine. The rename is fine for me too btw.
Quoted 7 lines
Quoted 4 lines
Regarding early trap init: I would have no problem to move all of
traps_initintosetup_arch(and leavetraps_initempty for generic code). I actually don't know why it runs so late. But doing it half way is ugly.Should I make
setup_per_cpu_areaandtrap_initempty and turn the real ones intoearly_foo?
setup_per_cpu_area is still needed later because it needs to allocate for non BP and you cannot do that that early.
-Andi
Re: [patch 08/16] Add support for X86_64 platforms to KGDB
Quoted 26 lines · Andi Kleen
Quoted 3 lines · Tom Rini
Bob did this part (forgot to CC him, oops). But I believe it's needed for setting traps so much earlier.
Ok looking again I guess he needed it for the GDT access in
cpu_initQuoted 10 lines
Quoted 7 lines
arch/x86_64/mm/fault.c no_context: · line 522
Quoted 4 lines
arch/x86_64/mm/fault.c renamed from arch/x86_64/mm/fault.c~x86_64-lite +4
-0+if (notify_die (DIE_PAGE_FAULT ,"no context" , regs, error_code,14 , +SIGSEGV ) ==NOTIFY_STOP ) +return ; +I can see the point of that. It's ok if you submit it as a separate patch.
I can split that out into one that follows the
KDB_VECTORrename easily enough.That's fine. The rename is fine for me too btw.
Quoted 5 lines
Quoted 4 lines
Regarding early trap init: I would have no problem to move all of
traps_initintosetup_arch(and leavetraps_initempty for generic code). I actually don't know why it runs so late. But doing it half way is ugly.
Quoted 5 lines
Quoted 2 lines
Should I make
setup_per_cpu_areaandtrap_initempty and turn the real ones intoearly_foo?
setup_per_cpu_areais still needed later because it needs to allocate for non BP and you cannot do that that early.
OK. So I'll send out a patch that makes trap_init() empty and use the early_setup_per_cpu_areas() Bob wrote as well.
Andrew: In sum, there will be 3 patches that replace the x86_64 main patch (2 split-out-stuff, 1 new kgdb patch).
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [patch 2/3] x86_64: Run setup_per_cpu_areas and trap_init sooner
In reply to Tom RiniReview
Quoted 5 lines
(quoted diff) +4
-0+void __init early_setup_per_cpu_areas(void) +{ + static char cpu0[PERCPU_ENOUGH_ROOM] + __attribute__ ((aligned (SMP_CACHE_BYTES)));
This needs a __cacheline_aligned too, otherwise there could be false sharing.
-Andi
Re: [patch 2/3] x86_64: Run setup_per_cpu_areas and trap_init sooner
Quoted 7 lines · Andi Kleen
Review
Quoted 5 lines
(quoted diff) +4
-0+void __init early_setup_per_cpu_areas(void) +{ + static char cpu0[PERCPU_ENOUGH_ROOM] + __attribute__ ((aligned (SMP_CACHE_BYTES)));This needs a
__cacheline_alignedtoo, otherwise there could be false sharing.
Done, thanks:
CC: Andi Kleen <[email protected]>, Bob Picco <[email protected]>
It can be handy in some situations to have run trap_init() sooner than the generic code does. In order to do this on x86_64 we need to add a custom early_setup_per_cpu_areas() call as well.
---
linux-2.6.13-trini/arch/x86_64/kernel/setup.c | 3 +++ linux-2.6.13-trini/arch/x86_64/kernel/setup64.c | 16 +++++++++++++++- linux-2.6.13-trini/arch/x86_64/kernel/traps.c | 4 ++++ linux-2.6.13-trini/include/asm-x86_64/proto.h | 2 ++ 4 files changed, 24 insertions(+), 1 deletion(-)
arch/x86_64/kernel/setup.c renamed from arch/x86_64/kernel/setup.c~x86_64-early_funcs +3 -0
@@ -525,6 +525,9 @@ void __init setup_arch(char **cmdline_p) {unsigned long kernel_end; +early_setup_per_cpu_areas (); +early_trap_init (); +ROOT_DEV =old_decode_dev (ORIG_ROOT_DEV ); drive_info =DRIVE_INFO ; screen_info =SCREEN_INFO ;
arch/x86_64/kernel/setup64.c renamed from arch/x86_64/kernel/setup64.c~x86_64-early_funcs +15 -1
@@ -77,7 +77,19 @@ static int __init nonx32_setup(char *str }__setup ("noexec32=" , nonx32_setup); +void __init early_setup_per_cpu_areas (void ) +{ + static char cpu0[PERCPU_ENOUGH_ROOM] __cacheline_aligned + __attribute__ ((aligned (SMP_CACHE_BYTES))); +char *ptr = cpu0; + + cpu_pda[0 ].data_offset = ptr - __per_cpu_start; +memcpy (ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); +} +/* +* We run this a bit sooner than the normal code, so provide a dummy +* function as well. * Great future plan: * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data. * Always point %gs to its beginning
@@ -97,7 +109,9 @@ void __init setup_per_cpu_areas(void)for (i =0 ; i <NR_CPUS ; i++) {char *ptr; -if (!NODE_DATA (cpu_to_node (i))) { +if (cpu_pda[i].data_offset) +continue ; +else if (!NODE_DATA (cpu_to_node (i))) {printk ("cpu with no node %d, num_online_nodes %d\n" , i,num_online_nodes ()); ptr =alloc_bootmem (size);
arch/x86_64/kernel/traps.c renamed from arch/x86_64/kernel/traps.c~x86_64-early_funcs +4 -0
@@ -904,6 +904,10 @@ void do_call_debug(struct pt_regs *regs)void __init trap_init (void ) { +} + +void __init early_trap_init (void ) +{set_intr_gate (0 ,÷_error);set_intr_gate_ist (1 ,&debug,DEBUG_STACK );set_intr_gate_ist (2 ,&nmi,NMI_STACK );
include/asm-x86_64/proto.h renamed from include/asm-x86_64/proto.h~x86_64-early_funcs +2 -0
@@ -10,6 +10,8 @@ struct pt_regs;extern void get_cpu_vendor (struct cpuinfo_x86 *);extern void start_kernel (void ); +extern void early_trap_init (void ); +extern void early_setup_per_cpu_areas (void );extern void pda_init (int );extern void early_idt_handler (void );
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [patch 16/16] Add hardware breakpoint support for i386
In reply to Tom RiniQuoted 2 lines · Tom Rini
This adds hardware breakpoint support for i386. This is not as well tested as software breakpoints, but in some minimal testing appears to be functional.
This really would need so coordination with user space using them. Otherwise it'll be quite unreliable because any user program can break it.
Long ago (in 2.4 time frame) there used to be a IBM patch floating around to reserve them globally and user space to use specific ones. I guess something like that would be needed again.
-Andi
Re: [patch 16/16] Add hardware breakpoint support for i386
In reply to Tom RiniQuoted 3 lines · Tom Rini
This adds hardware breakpoint support for i386. This is not as well tested as software breakpoints, but in some minimal testing appears to be functional.
Hardware breakpoints must be per cpu, not global. Also you will fall over applications that are using gdb, because gdb uses the same registers. KDB has never really supported kernel hardware breakpoints, they are hard to do without stamping on user space.
Re: [patch 1/3] x86_64: Add a notify_die() call to the "no context" part of do_page_fault()
In reply to Tom RiniQuoted 13 lines · Tom Rini
CC: Andi Kleen <[email protected]>
This adds a call tonotify_die()in the "no context" portion ofdo_page_fault()as someone on the chain might care and want to do a fixup.---
linux-2.6.13-trini/arch/x86_64/mm/fault.c | 4 ++++ 1 files changed, 4 insertions(+)diff -puN
arch/x86_64/mm/fault.c~x86_64-no_context_hookarch/x86_64/mm/fault.c
arch/x86_64/mm/fault.c no_context: · line 523
Quoted 10 lines
arch/x86_64/mm/fault.c renamed from arch/x86_64/mm/fault.c~x86_64-no_context_hook +4
-0@@ -514,6 +514,10 @@ no_context:if (is_errata93 (regs, address))return ; +if (notify_die (DIE_PAGE_FAULT ,"no context" , regs, error_code,14 , +SIGSEGV ) ==NOTIFY_STOP ) +return ; +/* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice.
Please use a more descriptive text than "no context". This bit of info SHOULD be available to the gdb/kgdb user and should indicate why kgdb was entered. It thus should be something like "bad kernel address" or "illegal kernel address".
Quoted 1 line
Signature · 2 lines
George Anzinger [email protected] HRT (High-res-timers): http://sourceforge.net/projects/high-res-timers/
Re: [patch 1/3] x86_64: Add a notify_die() call to the "no context" part of do_page_fault()
Quoted 20 lines · George Anzinger
Quoted 19 lines · Tom Rini
CC: Andi Kleen <[email protected]>
This adds a call tonotify_die()in the "no context" portion ofdo_page_fault()as someone on the chain might care and want to do a fixup.---
linux-2.6.13-trini/arch/x86_64/mm/fault.c| 4 ++++1 files changed, 4 insertions(+)diff -puN
arch/x86_64/mm/fault.c~x86_64-no_context_hookarch/x86_64/mm/fault.c
--- linux-2.6.13/arch/x86_64/mm/fault.c~x86_64-no_context_hook 2005-08-29 11:09:13.000000000 -0700
+++linux-2.6.13-trini/arch/x86_64/mm/fault.c2005-08-29
11:09:13.000000000 -0700(quoted diff) +0
-0@@ -514,6 +514,10 @@ no_context: if (is_errata93(regs, address)) return;
Quoted 12 lines
Review no_context: · line 523
Quoted 7 lines
(quoted diff) +4
-0+ if (notify_die(DIE_PAGE_FAULT, "no context", regs, error_code, 14, + SIGSEGV) == NOTIFY_STOP) + return; + /* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice.Please use a more descriptive text than "no context". This bit of info SHOULD be available to the gdb/kgdb user and should indicate why kgdb was entered. It thus should be something like "bad kernel address" or "illegal kernel address".
"no context" is the label we're in, in the code. What it's actually used for is "hey, we (== kgdb) tried to read/write a very very bogus addr, time to longjmp". If it's not true that kgdb is at fault then we drop to the debugger anyhow, and the user can see where they came from.
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [patch 1/3] x86_64: Add a notify_die() call to the "no context" part of do_page_fault()
Quoted 33 lines · Tom Rini
Quoted 20 lines · George Anzinger
Quoted 18 lines · Tom Rini
CC: Andi Kleen <[email protected]>
This adds a call tonotify_die()in the "no context" portion ofdo_page_fault()as someone on the chain might care and want to do a fixup.---
linux-2.6.13-trini/arch/x86_64/mm/fault.c| 4 ++++1 files changed, 4 insertions(+)diff -puN
arch/x86_64/mm/fault.c~x86_64-no_context_hookarch/x86_64/mm/fault.c--- linux-2.6.13/arch/x86_64/mm/fault.c~x86_64-no_context_hook 2005-08-29 11:09:13.000000000 -0700
+++linux-2.6.13-trini/arch/x86_64/mm/fault.c2005-08-29
11:09:13.000000000 -0700(quoted diff) +0
-0@@ -514,6 +514,10 @@ no_context: if (is_errata93(regs, address)) return;Quoted 9 lines
Review no_context: · line 523
Quoted 7 lines
(quoted diff) +4
-0+ if (notify_die(DIE_PAGE_FAULT, "no context", regs, error_code, 14, + SIGSEGV) == NOTIFY_STOP) + return; + /* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice.Please use a more descriptive text than "no context". This bit of info SHOULD be available to the gdb/kgdb user and should indicate why kgdb was entered. It thus should be something like "bad kernel address" or "illegal kernel address".
Quoted 5 lines
"no context" is the label we're in, in the code. What it's actually used for is "hey, we (== kgdb) tried to read/write a very very bogus addr, time to longjmp". If it's not true that kgdb is at fault then we drop to the debugger anyhow, and the user can see where they came from.
No. What the user sees is the offending code (i.e. prior to the trap to page_fault), NOT how kgdb happend to be called. The "no_context" is IN the _context_ of page_fault, but that is lost by the time you get to kgdb and ask to see _why_ (via, hint, hint: "p kgdb_info").
Signature · 2 lines
George Anzinger [email protected] HRT (High-res-timers): http://sourceforge.net/projects/high-res-timers/
Re: [patch 1/3] x86_64: Add a notify_die() call to the "no context" part of do_page_fault()
Quoted 1 line · George Anzinger
Tom Rini wrote:
[snip]
Quoted 9 lines
Quoted 5 lines
"no context" is the label we're in, in the code. What it's actually used for is "hey, we (== kgdb) tried to read/write a very very bogus addr, time to longjmp". If it's not true that kgdb is at fault then we drop to the debugger anyhow, and the user can see where they came from.
No. What the user sees is the offending code (i.e. prior to the trap to
page_fault), NOT how kgdb happend to be called. The "no_context" is IN the _context_ ofpage_fault, but that is lost by the time you get to kgdb and ask to see _why_ (via, hint, hint: "pkgdb_info").
So you're suggesting changing what we pass in so that if we also modify kgdb_info to contain the 'where' thing you talked about before, it would be more useful, yes? If so, I think that can wait just a bit. :)
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [patch 16/16] Add hardware breakpoint support for i386
In reply to Andi KleenQuoted 8 lines · Andi Kleen
Quoted 2 lines · Tom Rini
This adds hardware breakpoint support for i386. This is not as well tested as software breakpoints, but in some minimal testing appears to be functional.
This really would need so coordination with user space using them. Otherwise it'll be quite unreliable because any user program can break it.
Probably easiest to just drop this for now then, thanks.
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [patch 04/16] I/O driver for 8250-compatible UARTs
In reply to Tom RiniQuoted 1 line · Tom Rini
linux-2.6.13-trini/drivers/serial/kgdb_8250.c | 594 +++++++++++++++++++++
The existing stuff in drivers/serial is named "8250_*"; is there a reason you're using "kgdb_8250" rather than "8250_kgdb"?
Quoted 6 lines
+ *
serial8250_unregister_by_port- remove a 16x50 serial port
+ * at runtime.
+ * @port: A &structuart_portthat describes the port to remove.
+ *
+ * Remove one serial port. This may not be called from interrupt
+ * context. We hand the port back to the our control.
Hand the port back to whose control?
Quoted 1 line
+MODULE_PARM_DESC(kgdb8250, " kgdb8250=<port number>,<baud rate>\n");
Document IRQ/MMIO/IOport stuff here too (whatever it turns out to be, see below).
It seems wrong to me to have kgdb8250 use "ttyS" names for devices. In general you don't know the ttyS name for a device until after the 8250 driver claims it. Sure, it's a convenience to use "ttyS0" instead of "io,0x3f8", but it also makes it hard to run kgdb on a PCI or MMIO UART, because you don't know what its name will be.
If you gave up the convenience and just always required an I/O port or MMIO address, you could nuke all the old_rs_table[] and kgdb8250_ports[] stuff, not to mention a bunch of config options.
drivers/serial/kgdb_8250.c line 372
Quoted 4 lines
drivers/serial/kgdb_8250.c new file +4
-0+static int kgdb8250_local_init (void ) +{ +if (old_rs_table_copied ==0 ) +kgdb8250_copy_rs_table ();
This would be easier to maintain if the "if (old_rs_table_copied)" test were in the callee, not in every caller.
drivers/serial/kgdb_8250.c line 380
Quoted 7 lines
drivers/serial/kgdb_8250.c new file +7
-0+switch (CURRENTPORT .iotype) { +case UPIO_MEM : +if (CURRENTPORT .mapbase) + kgdb8250_needs_request_mem_region =1 ; +if (CURRENTPORT .flags &UPF_IOREMAP ) { +CURRENTPORT .membase =ioport_map (CURRENTPORT .mapbase, +8 <<KGDB8250_REG_SHIFT );
Shouldn't this be ioremap instead of ioport_map?
drivers/serial/kgdb_8250.c line 408
Quoted 12 lines
drivers/serial/kgdb_8250.c new file +12
-0+static int kgdb_init_io (void ) +{ +#ifdef CONFIG_KGDB_8250_MODULE +if (strlen (config)) { +if (kgdb8250_opt (config)) +return -EINVAL ; + }else { +printk (KERN_ERR "kgdb8250: argument error, usage: " +"kgdb8250=<port number>,<baud rate>" ); +#ifdef CONFIG_IA64 +printk (",<irq>,<iomem base>" ); +#endif
This isn't ia64-specific.
drivers/serial/kgdb_8250.c line 453
Quoted 13 lines
drivers/serial/kgdb_8250.c new file +13
-0+static void __init kgdb8250_hookup_irq (void ) +{ +#if defined(CONFIG_SERIAL_8250 ) || defined (CONFIG_SERIAL_8250_MODULE ) +/* Take the port away from the main driver. */ +serial8250_unregister_by_port (&CURRENTPORT ); + +/* Now reinit the port as the above has disabled things. */ +kgdb8250_init (); +#endif +/* We may need to call request_mem_region() first. */ +if (kgdb8250_needs_request_mem_region) +request_mem_region (CURRENTPORT .mapbase, +8 <<KGDB8250_REG_SHIFT ,"kgdb" );
The unregister/init/request_mem_region stuff doesn't sound very much like "hookup_irq".
Quoted 2 lines
+ * Syntax for this cmdline option is "kgdb8250=ttyno,baudrate"
+ * with ",irq,iomembase" tacked on the end on IA64.
This syntax doesn't really make sense on ia64, because there are no fixed "ttyno/iomembase" mappings. It would be unambiguous to specify either ttyno OR iomembase, but there's no good way to use both.
And there should be syntax to specify either MMIO or I/O port space devices. Intel ia64 boxes typically have I/O port UARTs (0x3f8, etc), and HP boxes typically have MMIO devices.
drivers/serial/kgdb_8250.c line 561
Quoted 12 lines
drivers/serial/kgdb_8250.c new file +12
-0+#ifdef CONFIG_IA64 +if (*str ==',' ) { + str++; +KGDB8250_IRQ =simple_strtoul (str, &str,10 ); +if (*str ==',' ) { + str++; +CURRENTPORT .iotype =SERIAL_IO_MEM ; +CURRENTPORT .membase = + (unsigned char *)simple_strtoul (str, &str,0 ); + } + } +#endif
Not ia64-specific.
lib/Kconfig.debug config KGDB_MPSC · line 244
Quoted 10 lines
lib/Kconfig.debug renamed from lib/Kconfig.debug~8250 +10
-0+config KGDB_SIMPLE_SERIAL + bool "Simple selection of KGDB serial port" + depends on KGDB_8250 + default y + help + If you say Y here, you will only have to pick the baud rate + and serial port (ttyS) that you wish to use for KGDB. If you + say N, you will have provide the I/O port and IRQ number. Note + that if your serial ports are iomapped, such as on ia64, then + you must say Y here. If in doubt, say Y.
How about: "... you will have to provide the address (I/O port or MMIO address) and IRQ ..."
I don't understand the "iomapped" bit -- does that mean MMIO? And why would it make any difference whether they're in I/O port or MMIO space?
I expect that if you use "ttyS" naming to select a port, that doesn't work early in boot on ia64, because ia64 doesn't have compiled-in knowledge of where ttyS devices live. Is that related to what this is trying to say?
lib/Kconfig.debug config KGDB_MPSC · line 297
Quoted 9 lines
lib/Kconfig.debug renamed from lib/Kconfig.debug~8250 +9
-0+config KGDB_PORT + hex "hex I/O port address of the debug serial port" + depends on !KGDB_SIMPLE_SERIAL && KGDB_8250 && !IA64 + default 3f8 + help + This is the unmapped (and on platforms with 1:1 mapping + this is typically, but not always the same as the mapped) + address of the serial port. The stanards on your architecture + may be found in include/asm-$(ARCH)/serial.h.
Not ia64-specific. The description sounds like it applies to MMIO,
not to I/O port space. And s/stanards/standards/.
lib/Kconfig.debug config KGDB_MPSC · line 306
Quoted 8 lines
lib/Kconfig.debug renamed from lib/Kconfig.debug~8250 +8
-0+config KGDB_IRQ + int "IRQ of the debug serial port" + depends on !KGDB_SIMPLE_SERIAL && KGDB_8250 && !IA64 + default 4 + help + This is the IRQ for the debug port. This must be known so that + KGDB can interrupt the running system (either for a new + connection or when in gdb and control-C is issued).
Not ia64-specific.
Re: [patch 04/16] I/O driver for 8250-compatible UARTs
Quoted 5 lines · Bjorn Helgaas
Quoted 1 line · Tom Rini
linux-2.6.13-trini/drivers/serial/kgdb_8250.c | 594 +++++++++++++++++++++The existing stuff in
drivers/serialis named "8250_*"; is there a reason you're using "kgdb_8250" rather than "8250_kgdb"?
All the other kgdb stuff tends to be prefixed, not suffixed. But I don't really care either way.
Quoted 8 lines
Quoted 6 lines
+ *
serial8250_unregister_by_port- remove a 16x50 serial port
+ * at runtime.
+ * @port: A &structuart_portthat describes the port to remove.
+ *
+ * Remove one serial port. This may not be called from interrupt
+ * context. We hand the port back to the our control.Hand the port back to whose control?
Ok, that is non-sensical. "We hand the port to the callers control." is what I meant to say.
Quoted 10 lines
Quoted 1 line
+MODULE_PARM_DESC(kgdb8250, " kgdb8250=<port number>,<baud rate>\n");
Document IRQ/MMIO/IOport stuff here too (whatever it turns out to be, see below).
It seems wrong to me to have kgdb8250 use "ttyS" names for devices. In general you don't know the ttyS name for a device until after the 8250 driver claims it. Sure, it's a convenience to use "ttyS0" instead of "io,0x3f8", but it also makes it hard to run kgdb on a PCI or MMIO UART, because you don't know what its name will be.
I've tried intentionally to not mention 'ttyS' anywhere (exposed to the user) because it's really not 'ttySN' but it is the port registered to us.
Quoted 3 lines
If you gave up the convenience and just always required an I/O port or MMIO address, you could nuke all the old_rs_table[] and kgdb8250_ports[] stuff, not to mention a bunch of config options.
But that's really rather handy so I'd rather not get rid of it.
There's really two cases we have to deal with. The first case is a known at compile time or can be registered at boot-time easily port (ie dumb old PC or ARM boards). The second case is "serial port over there". Perhaps we should change the kgdb8250 arg to be an override of the default port, so:
kgdb8250={io,mmio},<irq>,<token>,<baud rate>
Would that work?
Quoted 7 lines
drivers/serial/kgdb_8250.c line 372
Quoted 4 lines
drivers/serial/kgdb_8250.c new file +4
-0+static int kgdb8250_local_init (void ) +{ +if (old_rs_table_copied ==0 ) +kgdb8250_copy_rs_table ();This would be easier to maintain if the "if (
old_rs_table_copied)" test were in the callee, not in every caller.
I'm not sure. In the compiled-in case we know it's always been run prior to freeing __init data, and thus it's quasi-safe. I suppose it wouldn't be too big a deal to just remove the __init and do it like that.
Quoted 9 lines
drivers/serial/kgdb_8250.c line 380
Quoted 7 lines
drivers/serial/kgdb_8250.c new file +7
-0+switch (CURRENTPORT .iotype) { +case UPIO_MEM : +if (CURRENTPORT .mapbase) + kgdb8250_needs_request_mem_region =1 ; +if (CURRENTPORT .flags &UPF_IOREMAP ) { +CURRENTPORT .membase =ioport_map (CURRENTPORT .mapbase, +8 <<KGDB8250_REG_SHIFT );Shouldn't this be ioremap instead of
ioport_map?
If I remember right from the testing, no. Or if my memory is wrong and that's retorihcal, sure.
Quoted 6 lines
Quoted 6 lines
drivers/serial/kgdb_8250.c new file +6
-0+static int kgdb_init_io (void ) +{ +#ifdef CONFIG_KGDB_8250_MODULE +if (strlen (config)) { +if (kgdb8250_opt (config)) +return -EINVAL ;
Quoted 8 lines
drivers/serial/kgdb_8250.c line 408
Quoted 6 lines
drivers/serial/kgdb_8250.c new file +6
-0+ }else { +printk (KERN_ERR "kgdb8250: argument error, usage: " +"kgdb8250=<port number>,<baud rate>" ); +#ifdef CONFIG_IA64 +printk (",<irq>,<iomem base>" ); +#endif This isn't ia64-specific.
It is and it isn't. Since no one's tried a PCI card uart for KGDB nor had a case where we have to pass in the mmio addr except on ia64, it is ia64-specific. But as I said above, if we make kgdb8250= an override of the compiled in choice, it wouldn't be.
Quoted 8 lines
Quoted 8 lines
drivers/serial/kgdb_8250.c new file +8
-0+static void __init kgdb8250_hookup_irq (void ) +{ +#if defined(CONFIG_SERIAL_8250 ) || defined (CONFIG_SERIAL_8250_MODULE ) +/* Take the port away from the main driver. */ +serial8250_unregister_by_port (&CURRENTPORT ); + +/* Now reinit the port as the above has disabled things. */ +kgdb8250_init ();
Quoted 8 lines
drivers/serial/kgdb_8250.c line 453
Quoted 5 lines
drivers/serial/kgdb_8250.c new file +5
-0+#endif +/* We may need to call request_mem_region() first. */ +if (kgdb8250_needs_request_mem_region) +request_mem_region (CURRENTPORT .mapbase, +8 <<KGDB8250_REG_SHIFT ,"kgdb" );The unregister/init/request_mem_region stuff doesn't sound very much like "
hookup_irq".
All the stuff that's required before you can really hookup the IRQ. Suggested name appricated.
Quoted 7 lines
Quoted 2 lines
+ * Syntax for this cmdline option is "kgdb8250=ttyno,baudrate"
+ * with ",irq,iomembase" tacked on the end on IA64.This syntax doesn't really make sense on ia64, because there are no fixed "ttyno/iomembase" mappings. It would be unambiguous to specify either ttyno OR iomembase, but there's no good way to use both.
It's true that ttyno isn't really useful on ia64.
Quoted 5 lines
Quoted 5 lines
lib/Kconfig.debug renamed from lib/Kconfig.debug~8250 +5
-0+config KGDB_SIMPLE_SERIAL + bool "Simple selection of KGDB serial port" + depends on KGDB_8250 + default y + help
Quoted 8 lines
lib/Kconfig.debug config KGDB_MPSC · line 244
Quoted 5 lines
lib/Kconfig.debug renamed from lib/Kconfig.debug~8250 +5
-0+ If you say Y here, you will only have to pick the baud rate + and serial port (ttyS) that you wish to use for KGDB. If you + say N, you will have provide the I/O port and IRQ number. Note + that if your serial ports are iomapped, such as on ia64, then + you must say Y here. If in doubt, say Y.How about: "... you will have to provide the address (I/O port or MMIO address) and IRQ ..."
I'd really rather not force everyone to pass in the address token and IRQ#.
Quoted 2 lines
I don't understand the "iomapped" bit -- does that mean MMIO? And why would it make any difference whether they're in I/O port or MMIO space?
It's the special "boot once, figure out your I/O address and IRQ, reboot and pass it in" case of IA64. I'm under the impression that it's because of the more dynamic than other arches that we couldn't just register the ports as we find them to KGDB and let the user pick from a pre-registered port that we play that game.
Quoted 4 lines
I expect that if you use "ttyS" naming to select a port, that doesn't work early in boot on ia64, because ia64 doesn't have compiled-in knowledge of where ttyS devices live. Is that related to what this is trying to say?
Yes.
Quoted 4 lines
Quoted 4 lines
lib/Kconfig.debug renamed from lib/Kconfig.debug~8250 +4
-0+config KGDB_PORT + hex "hex I/O port address of the debug serial port" + depends on !KGDB_SIMPLE_SERIAL && KGDB_8250 && !IA64 + default 3f8
Quoted 8 lines
lib/Kconfig.debug config KGDB_MPSC · line 297
Quoted 5 lines
lib/Kconfig.debug renamed from lib/Kconfig.debug~8250 +5
-0+ help + This is the unmapped (and on platforms with 1:1 mapping + this is typically, but not always the same as the mapped) + address of the serial port. The stanards on your architecture + may be found in include/asm-$(ARCH)/serial.h.Not ia64-specific. The description sounds like it applies to MMIO,
not to I/O port space. And s/stanards/standards/.
Having !mmio uarts on ia64 is news to me (but I've never used an ia64 box), hence the depends line.
Quoted 10 lines
lib/Kconfig.debug config KGDB_MPSC · line 306
Quoted 8 lines
lib/Kconfig.debug renamed from lib/Kconfig.debug~8250 +8
-0+config KGDB_IRQ + int "IRQ of the debug serial port" + depends on !KGDB_SIMPLE_SERIAL && KGDB_8250 && !IA64 + default 4 + help + This is the IRQ for the debug port. This must be known so that + KGDB can interrupt the running system (either for a new + connection or when in gdb and control-C is issued).Not ia64-specific.
True, don't recall why I did that one like that now, thanks.
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [patch 04/16] I/O driver for 8250-compatible UARTs
Quoted 9 lines · Tom Rini
Quoted 5 lines · Bjorn Helgaas
Quoted 1 line · Tom Rini
linux-2.6.13-trini/drivers/serial/kgdb_8250.c | 594 +++++++++++++++++++++The existing stuff in
drivers/serialis named "8250_*"; is there a reason you're using "kgdb_8250" rather than "8250_kgdb"?All the other kgdb stuff tends to be prefixed, not suffixed. But I don't really care either way.
I'd prefer it was 8250_kgdb.c actually - that keeps it along side the other 8250 files.
Quoted 10 lines
Quoted 9 lines
drivers/serial/kgdb_8250.c line 380
Quoted 7 lines
drivers/serial/kgdb_8250.c new file +7
-0+switch (CURRENTPORT .iotype) { +case UPIO_MEM : +if (CURRENTPORT .mapbase) + kgdb8250_needs_request_mem_region =1 ; +if (CURRENTPORT .flags &UPF_IOREMAP ) { +CURRENTPORT .membase =ioport_map (CURRENTPORT .mapbase, +8 <<KGDB8250_REG_SHIFT );Shouldn't this be ioremap instead of
ioport_map?
Quoted 2 lines
If I remember right from the testing, no. Or if my memory is wrong and that's retorihcal, sure.
ioport_map() is supposed to be used to map the IO range for the ioread/ iowrite operations. IOW, it takes something compatible with inb() and friends and converts it to something compatible with ioread8() and friends.
It does not take a MMIO cookie, so the code above appears to be conceptually wrong.
Signature · 3 lines
Russell King Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/ maintainer of: 2.6 Serial core
Re: [patch 04/16] I/O driver for 8250-compatible UARTs
In reply to Tom RiniQuoted 5 lines · Tom Rini
Quoted 1 line · Bjorn Helgaas
On Monday 29 August 2005 10:09 am, Tom Rini wrote:
I've tried intentionally to not mention 'ttyS' anywhere (exposed to the user) because it's really not 'ttySN' but it is the port registered to us.
So kgdb's port N is different from ttySN? That sounds really confusing. And KGDB_SIMPLE_SERIAL does mention "ttyS".
Quoted 6 lines
There's really two cases we have to deal with. The first case is a known at compile time or can be registered at boot-time easily port (ie dumb old PC or ARM boards). The second case is "serial port over there". Perhaps we should change the kgdb8250 arg to be an override of the default port, so:
kgdb8250={io,mmio},<irq>,<token>,<baud rate>
That makes sense. But I'd make it {io,mmio},<token>,<baud>,<irq> so it's more like the existing "console=uart" argument.
Quoted 10 lines
Quoted 9 lines
drivers/serial/kgdb_8250.c line 380
Quoted 7 lines
drivers/serial/kgdb_8250.c new file +7
-0+switch (CURRENTPORT .iotype) { +case UPIO_MEM : +if (CURRENTPORT .mapbase) + kgdb8250_needs_request_mem_region =1 ; +if (CURRENTPORT .flags &UPF_IOREMAP ) { +CURRENTPORT .membase =ioport_map (CURRENTPORT .mapbase, +8 <<KGDB8250_REG_SHIFT );Shouldn't this be ioremap instead of
ioport_map?
Quoted 2 lines
If I remember right from the testing, no. Or if my memory is wrong and that's retorihcal, sure.
ioport_map() certainly isn't going to do anything good with an MMIO address.
Quoted 11 lines
Quoted 7 lines
drivers/serial/kgdb_8250.c line 408
Quoted 5 lines
drivers/serial/kgdb_8250.c new file +5
-0+printk (KERN_ERR "kgdb8250: argument error, usage: " +"kgdb8250=<port number>,<baud rate>" ); +#ifdef CONFIG_IA64 +printk (",<irq>,<iomem base>" ); +#endif This isn't ia64-specific.
It is and it isn't. Since no one's tried a PCI card uart for KGDB nor had a case where we have to pass in the mmio addr except on ia64, it is ia64-specific.
Maybe it's only been *tested* on ia64, but I don't think that's a reason to make it compiled only on ia64.
Quoted 9 lines
Quoted 7 lines
Quoted 2 lines
+ * Syntax for this cmdline option is "kgdb8250=ttyno,baudrate"
+ * with ",irq,iomembase" tacked on the end on IA64.This syntax doesn't really make sense on ia64, because there are no fixed "ttyno/iomembase" mappings. It would be unambiguous to specify either ttyno OR iomembase, but there's no good way to use both.
It's true that ttyno isn't really useful on ia64.
Then I think it would be a mistake to have syntax that requires both ttyno and iomembase in the same command-line option. I'm visualizing something like this:
kgdb8250=ttyS0,115200 kgdb8250=io,0x3f8,115200,49 kgdb8250=mmio,0xff5e0000,115200,49
where you can easily decide which type of device specification you've got.
Quoted 14 lines
Quoted 5 lines
Quoted 5 lines
lib/Kconfig.debug renamed from lib/Kconfig.debug~8250 +5
-0+config KGDB_SIMPLE_SERIAL + bool "Simple selection of KGDB serial port" + depends on KGDB_8250 + default y + helpQuoted 8 lines
lib/Kconfig.debug config KGDB_MPSC · line 244
Quoted 5 lines
lib/Kconfig.debug renamed from lib/Kconfig.debug~8250 +5
-0+ If you say Y here, you will only have to pick the baud rate + and serial port (ttyS) that you wish to use for KGDB. If you + say N, you will have provide the I/O port and IRQ number. Note + that if your serial ports are iomapped, such as on ia64, then + you must say Y here. If in doubt, say Y.How about: "... you will have to provide the address (I/O port or MMIO address) and IRQ ..."
Quoted 2 lines
I'd really rather not force everyone to pass in the address token and IRQ#.
My point was merely that you should support explicit MMIO addresses as well as explicit I/O ports. I guess it makes sense to accept ttyS names as well, and accept the limitation that before the 8250 driver initializes, ttyS names only work for devices defined at compile-time in SERIAL_PORT_DFNS.
Quoted 8 lines
Quoted 2 lines
I don't understand the "iomapped" bit -- does that mean MMIO? And why would it make any difference whether they're in I/O port or MMIO space?
It's the special "boot once, figure out your I/O address and IRQ, reboot and pass it in" case of IA64. I'm under the impression that it's because of the more dynamic than other arches that we couldn't just register the ports as we find them to KGDB and let the user pick from a pre-registered port that we play that game.
Yup, ia64 doesn't require serial ports at fixed addresses. They're all discovered via ACPI and PCI enumeration.
But "iomapped" doesn't suggest that to me. And I would expect the text to say that if you don't have any compiled-in UART names, you'd have to say "N". But it says use "Y" for ia64.
Actually, I think KGDB_SIMPLE_SERIAL, KGDB_*BAUD, KGDB_PORT_*, KGDB_PORT, and KGDB_IRQ are overkill. Could they all be nuked in favor of a KGDB_8250_DEVICE that could be set to things like "ttyS0,115200" or "io,0x3f8,115200,49"?
Quoted 13 lines
Quoted 4 lines
Quoted 4 lines
lib/Kconfig.debug renamed from lib/Kconfig.debug~8250 +4
-0+config KGDB_PORT + hex "hex I/O port address of the debug serial port" + depends on !KGDB_SIMPLE_SERIAL && KGDB_8250 && !IA64 + default 3f8Quoted 8 lines
lib/Kconfig.debug config KGDB_MPSC · line 297
Quoted 5 lines
lib/Kconfig.debug renamed from lib/Kconfig.debug~8250 +5
-0+ help + This is the unmapped (and on platforms with 1:1 mapping + this is typically, but not always the same as the mapped) + address of the serial port. The stanards on your architecture + may be found in include/asm-$(ARCH)/serial.h.Not ia64-specific. The description sounds like it applies to MMIO,
not to I/O port space. And s/stanards/standards/.
Quoted 2 lines
Having !mmio uarts on ia64 is news to me (but I've never used an ia64 box), hence the depends line.
Intel-based boxes have only I/O port UARTs. But regardless, the MMIO-ness or I/O port-ness of a UART is completely arch-independent.
The description point is that "unmapped" and "1:1 mapping" sound like things related to MMIO addresses, not to I/O port addresses.
Re: [patch 04/16] I/O driver for 8250-compatible UARTs
In reply to Russell KingQuoted 5 lines · Russell King
Quoted 4 lines · Tom Rini
Quoted 3 lines · Bjorn Helgaas
Quoted 1 line · Tom Rini
linux-2.6.13-trini/drivers/serial/kgdb_8250.c | 594 +++++++++++++++++++++
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
The existing stuff in
drivers/serialis named "8250_*"; is there a reason you're using "kgdb_8250" rather than "8250_kgdb"?All the other kgdb stuff tends to be prefixed, not suffixed. But I don't really care either way.
I'd prefer it was
8250_kgdb.cactually - that keeps it along side the other 8250 files.
Will do.
Quoted 13 lines
Quoted 10 lines
Quoted 9 lines
drivers/serial/kgdb_8250.c line 380
Quoted 7 lines
drivers/serial/kgdb_8250.c new file +7
-0+switch (CURRENTPORT .iotype) { +case UPIO_MEM : +if (CURRENTPORT .mapbase) + kgdb8250_needs_request_mem_region =1 ; +if (CURRENTPORT .flags &UPF_IOREMAP ) { +CURRENTPORT .membase =ioport_map (CURRENTPORT .mapbase, +8 <<KGDB8250_REG_SHIFT );Shouldn't this be ioremap instead of
ioport_map?Quoted 2 lines
If I remember right from the testing, no. Or if my memory is wrong and that's retorihcal, sure.
Quoted 8 lines
ioport_map()is supposed to be used to map the IO range for the ioread/ iowrite operations. IOW, it takes something compatible withinb()and friends and converts it to something compatible withioread8()and friends.It does not take a MMIO cookie, so the code above appears to be conceptually wrong.
So it's luck (or another mapping I didn't see elsewhere) that this worked, and it should still be ioremap(...) to use with ioread/write8 later on in the code?
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [patch 04/16] I/O driver for 8250-compatible UARTs
In reply to Bjorn HelgaasQuoted 9 lines · Bjorn Helgaas
Quoted 5 lines · Tom Rini
Quoted 1 line · Bjorn Helgaas
On Monday 29 August 2005 10:09 am, Tom Rini wrote:
I've tried intentionally to not mention 'ttyS' anywhere (exposed to the user) because it's really not 'ttySN' but it is the port registered to us.
So kgdb's port N is different from ttySN? That sounds really confusing. And
KGDB_SIMPLE_SERIALdoes mention "ttyS".
It's not intentionally different, and really only might be different in the we have ttySX case, but ttySX isn't registered to KGDB case.
Quoted 9 lines
Quoted 6 lines
There's really two cases we have to deal with. The first case is a known at compile time or can be registered at boot-time easily port (ie dumb old PC or ARM boards). The second case is "serial port over there". Perhaps we should change the kgdb8250 arg to be an override of the default port, so:
kgdb8250={io,mmio},<irq>,<token>,<baud rate>That makes sense. But I'd make it {io,mmio},<token>,<baud>,<irq> so it's more like the existing "console=uart" argument.
ok.
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
drivers/serial/kgdb_8250.c line 408
Quoted 5 lines
drivers/serial/kgdb_8250.c new file +5
-0+printk (KERN_ERR "kgdb8250: argument error, usage: " +"kgdb8250=<port number>,<baud rate>" ); +#ifdef CONFIG_IA64 +printk (",<irq>,<iomem base>" ); +#endif This isn't ia64-specific.
Quoted 6 lines
Quoted 3 lines
It is and it isn't. Since no one's tried a PCI card uart for KGDB nor had a case where we have to pass in the mmio addr except on ia64, it is ia64-specific.
Maybe it's only been *tested* on ia64, but I don't think that's a reason to make it compiled only on ia64.
It's only been needed on ia64. But it's moot since I've reworked things for kgdb8250= is always a complete override.
Quoted 4 lines
Actually, I think
KGDB_SIMPLE_SERIAL, KGDB_*BAUD, KGDB_PORT_*,KGDB_PORT, andKGDB_IRQare overkill. Could they all be nuked in favor of aKGDB_8250_DEVICEthat could be set to things like "ttyS0,115200" or "io,0x3f8,115200,49"?
Hmm. I'll give that a shot momentarily... That sounds like a good idea 'tho..
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/