KGDB: Core files
Subsystems (19)
PATCH 1/15 KGDB: Core files
CC: Amit Kale <[email protected]>
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-rc3-trini/Documentation/DocBook/Makefile | 2 linux-2.6.13-rc3-trini/Documentation/DocBook/kgdb.tmpl | 231 ++ linux-2.6.13-rc3-trini/MAINTAINERS | 9 linux-2.6.13-rc3-trini/include/linux/kgdb.h | 260 ++ linux-2.6.13-rc3-trini/kernel/Makefile | 1 linux-2.6.13-rc3-trini/kernel/kgdb.c | 1835 +++++++++++++++++ linux-2.6.13-rc3-trini/kernel/pid.c | 11 linux-2.6.13-rc3-trini/kernel/sched.c | 4 linux-2.6.13-rc3-trini/lib/Kconfig.debug | 47 9 files changed, 2398 insertions(+), 2 deletions(-)
Documentation/DocBook/kgdb.tmpl new file +231 -0
@@ -0,0 +1,231 @@ +<?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> + <listitem> + <para> + CHECK_EXCEPTION_STACK(): It is possible for the kernel to be + trying to use KGDB before our exception stacks are setup. In + this case, we must not let the KGDB happen yet. If we do not + have to worry about this, it should be set to one. If we do + have to worry about this, it should be set to a suitable + check. + </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 +1835 -0
1,835 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>
@@ -5215,6 +5216,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 +47 -0
62 lines not on this page · raw message
MAINTAINERS renamed from MAINTAINERS~core-lite +9 -0
@@ -1343,6 +1343,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/15 KGDB: i386 core functionality.
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-rc3-trini/arch/i386/kernel/Makefile | 1 linux-2.6.13-rc3-trini/arch/i386/kernel/kgdb-jmp.S | 74 +++++ linux-2.6.13-rc3-trini/arch/i386/kernel/kgdb.c | 301 +++++++++++++++++++++ linux-2.6.13-rc3-trini/arch/i386/kernel/setup.c | 3 linux-2.6.13-rc3-trini/arch/i386/kernel/traps.c | 15 - linux-2.6.13-rc3-trini/arch/i386/mm/fault.c | 4 linux-2.6.13-rc3-trini/include/asm-i386/kgdb.h | 50 +++ linux-2.6.13-rc3-trini/include/asm-i386/system.h | 10 linux-2.6.13-rc3-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;
@@ -1485,6 +1486,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
@@ -1541,6 +1543,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" - 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/15 Basic PowerPC32 support
CC: Paul Mackerras <[email protected]>
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.
---
linux-2.6.13-rc3-trini/arch/ppc/Kconfig.debug | 36 linux-2.6.13-rc3-trini/arch/ppc/kernel/Makefile | 2 linux-2.6.13-rc3-trini/arch/ppc/kernel/kgdb.c | 329 ++++ linux-2.6.13-rc3-trini/arch/ppc/kernel/setup.c | 16 linux-2.6.13-rc3-trini/arch/ppc/mm/fault.c | 9 linux-2.6.13-rc3-trini/arch/ppc/platforms/4xx/bubinga.c | 23 linux-2.6.13-rc3-trini/arch/ppc/platforms/4xx/ebony.c | 27 linux-2.6.13-rc3-trini/arch/ppc/platforms/4xx/ocotea.c | 22 linux-2.6.13-rc3-trini/arch/ppc/platforms/4xx/xilinx_ml300.c | 18 linux-2.6.13-rc3-trini/arch/ppc/platforms/85xx/sbc8560.c | 36 linux-2.6.13-rc3-trini/arch/ppc/platforms/chestnut.c | 5 linux-2.6.13-rc3-trini/arch/ppc/platforms/cpci690.c | 10 linux-2.6.13-rc3-trini/arch/ppc/platforms/mcpn765.c | 5 linux-2.6.13-rc3-trini/arch/ppc/platforms/pcore.c | 3 linux-2.6.13-rc3-trini/arch/ppc/platforms/pplus.c | 3 linux-2.6.13-rc3-trini/arch/ppc/platforms/sandpoint.c | 3 linux-2.6.13-rc3-trini/arch/ppc/platforms/spruce.c | 21 linux-2.6.13-rc3-trini/arch/ppc/syslib/Makefile | 1 linux-2.6.13-rc3-trini/arch/ppc/syslib/gen550.h | 1 linux-2.6.13-rc3-trini/arch/ppc/syslib/ibm44x_common.c | 3 linux-2.6.13-rc3-trini/arch/ppc/syslib/mv64x60.c | 56 linux-2.6.13-rc3-trini/arch/ppc/syslib/mv64x60_dbg.c | 52 linux-2.6.13-rc3-trini/arch/ppc/syslib/ppc85xx_setup.c | 13 linux-2.6.13-rc3-trini/drivers/serial/Makefile | 1 linux-2.6.13-rc3-trini/drivers/serial/kgdb_mpsc.c | 313 +++ linux-2.6.13-rc3-trini/drivers/serial/mpsc.h | 4 linux-2.6.13-rc3-trini/include/asm-ppc/kgdb.h | 48 linux-2.6.13-rc3-trini/include/asm-ppc/machdep.h | 2 linux-2.6.13-rc3-trini/include/asm-ppc/mv64x60.h | 2 linux-2.6.13-rc3-trini/include/asm-ppc/mv64x60_defs.h | 3 linux-2.6.13-rc3-trini/lib/Kconfig.debug | 10 linux-2.6.13-rc3/arch/ppc/kernel/ppc-stub.c | 867 ----------- linux-2.6.13-rc3/arch/ppc/syslib/gen550_kgdb.c | 86 - 33 files changed, 837 insertions(+), 1193 deletions(-)
arch/ppc/Kconfig.debug renamed from arch/ppc/Kconfig.debug~ppc-lite +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 renamed from arch/ppc/kernel/Makefile~ppc-lite +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 renamed from arch/ppc/kernel/setup.c~ppc-lite +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);
@@ -709,18 +705,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 renamed from arch/ppc/mm/fault.c~ppc-lite +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 renamed from arch/ppc/platforms/4xx/bubinga.c~ppc-lite +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 renamed from arch/ppc/platforms/4xx/ebony.c~ppc-lite +15 -12
@@ -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>
@@ -241,28 +242,34 @@ 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" ); - } - -#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB ) +#endif +#ifdef CONFIG_SERIAL_TEXT_DEBUG /* Configure debug serial access */ gen550_init (0 , &port);#endif +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (0 , &port); +#endif port.membase =ioremap64 (PPC440GP_UART1_ADDR ,8 ); port.irq =1 ; port.uartclk = clocks.uart1; 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" ); - } - -#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB ) +#endif +#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
@@ -348,8 +355,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 renamed from arch/ppc/platforms/4xx/ocotea.c~ppc-lite +14 -8
@@ -259,28 +259,34 @@ 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" ); - } - -#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB ) +#endif +#ifdef CONFIG_SERIAL_TEXT_DEBUG /* Configure debug serial access */ gen550_init (0 , &port);#endif +#ifdef CONFIG_KGDB_8250 +kgdb8250_add_port (0 , &port); +#endif port.membase =ioremap64 (PPC440GX_UART1_ADDR ,8 ); port.irq =UART1_INT ; port.uartclk = clocks.uart1; 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" ); - } - -#if defined(CONFIG_SERIAL_TEXT_DEBUG ) || defined(CONFIG_KGDB ) +#endif +#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
arch/ppc/platforms/4xx/xilinx_ml300.c renamed from arch/ppc/platforms/4xx/xilinx_ml300.c~ppc-lite +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 renamed from arch/ppc/platforms/85xx/sbc8560.c~ppc-lite +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 renamed from arch/ppc/platforms/chestnut.c~ppc-lite +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 renamed from arch/ppc/platforms/cpci690.c~ppc-lite +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 renamed from arch/ppc/platforms/mcpn765.c~ppc-lite +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 renamed from arch/ppc/platforms/pcore.c~ppc-lite +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 renamed from arch/ppc/platforms/pplus.c~ppc-lite +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 renamed from arch/ppc/platforms/sandpoint.c~ppc-lite +0 -3
@@ -748,9 +748,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 renamed from arch/ppc/platforms/spruce.c~ppc-lite +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 renamed from arch/ppc/syslib/gen550.h~ppc-lite +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 renamed from arch/ppc/syslib/ibm44x_common.c~ppc-lite +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 renamed from arch/ppc/syslib/Makefile~ppc-lite +0 -1
@@ -85,7 +85,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 renamed from arch/ppc/syslib/mv64x60.c~ppc-lite +54 -2
84 lines not on this page · raw message
arch/ppc/syslib/mv64x60_dbg.c renamed from arch/ppc/syslib/mv64x60_dbg.c~ppc-lite +1 -51
61 lines not on this page · raw message
arch/ppc/syslib/ppc85xx_setup.c renamed from arch/ppc/syslib/ppc85xx_setup.c~ppc-lite +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 renamed from drivers/serial/Makefile~ppc-lite +1 -0
@@ -51,6 +51,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 renamed from drivers/serial/mpsc.h~ppc-lite +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 renamed from include/asm-ppc/kgdb.h~ppc-lite +18 -30
70 lines not on this page · raw message
include/asm-ppc/machdep.h renamed from include/asm-ppc/machdep.h~ppc-lite +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 renamed from include/asm-ppc/mv64x60_defs.h~ppc-lite +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 renamed from include/asm-ppc/mv64x60.h~ppc-lite +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 renamed from lib/Kconfig.debug~ppc-lite +9 -1
@@ -163,7 +163,7 @@ config FRAME_POINTER config KGDB bool "KGDB: kernel debugging with remote gdb" - 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
@@ -189,6 +189,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
@@ -205,4 +206,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/15 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.
---
linux-2.6.13-rc3-trini/drivers/serial/8250.c | 86 ++ linux-2.6.13-rc3-trini/drivers/serial/Kconfig | 4 linux-2.6.13-rc3-trini/drivers/serial/Makefile | 1 linux-2.6.13-rc3-trini/drivers/serial/kgdb_8250.c | 610 ++++++++++++++++++++ linux-2.6.13-rc3-trini/drivers/serial/serial_core.c | 6 linux-2.6.13-rc3-trini/include/linux/kgdb.h | 1 linux-2.6.13-rc3-trini/include/linux/serial_8250.h | 1 linux-2.6.13-rc3-trini/lib/Kconfig.debug | 89 ++ 8 files changed, 795 insertions(+), 3 deletions(-)
drivers/serial/8250.c renamed from drivers/serial/8250.c~8250 +86 -0
@@ -1432,6 +1432,8 @@ static void serial8250_break_ctl(structspin_unlock_irqrestore (&up->port.lock, flags); } +static int released_irq =-1 ; +static int serial8250_startup (struct uart_port *port) {struct uart_8250_port *up = (struct uart_8250_port *)port;
@@ -1439,6 +1441,9 @@ static int serial8250_startup(struct uarunsigned char lsr, iir;int retval; +if (up->port.irq == released_irq) +return -EBUSY ; + up->capabilities = uart_config[up->port.type].flags; up->mcr =0 ;
@@ -2087,6 +2092,9 @@ serial8250_register_ports(struct uart_drfor (i =0 ; i <UART_NR ; i++) {struct uart_8250_port *up = &serial8250_ports[i]; +if (up->port.irq == released_irq) +continue ; + up->port.dev = dev;uart_add_one_port (drv, &up->port); }
@@ -2463,6 +2471,9 @@ int serial8250_register_port(struct uartif (port->uartclk ==0 )return -EINVAL ; +if (port->irq == released_irq) +return -EBUSY ; +down (&serial_sem); uart =serial8250_find_match_or_unused (port);
@@ -2516,6 +2527,38 @@ void serial8250_unregister_port(int line }EXPORT_SYMBOL (serial8250_unregister_port); +/** +* serial8250_release_irq - remove a 16x50 serial port at runtime based +* on IRQ +* @irq: IRQ number +* +* Remove one serial port. This may not be called from interrupt +* context. This is called when the caller know the IRQ of the +* port they want, but not where it is in our table. This allows +* for one port, based on IRQ, to be permanently released from us. +*/ + +int serial8250_release_irq (int irq) +{ +struct uart_8250_port *up; +int ttyS; + +if (released_irq == irq) +return 0 ; + +if (released_irq !=-1 ) +return -EBUSY ; + + released_irq = irq; +for (ttyS =0 ; ttyS <UART_NR ; ttyS++){ + up = &serial8250_ports[ttyS]; +if (up->port.irq == irq && (irq_lists + irq)->head) +serial8250_unregister_port (up->port.line); + } +return 0 ; +} +EXPORT_SYMBOL (serial8250_release_irq); +static int __init serial8250_init (void ) {int ret, i;
@@ -2665,3 +2708,46 @@ void unregister_serial(int line)serial8250_unregister_port (line); }EXPORT_SYMBOL (unregister_serial); + +/** +* debug_request_serial_line - disable a 16x50 serial port at runtime +* @line: serial line number +* +* Disable one serial port. This may not be called from +* interrupt context. This function is for the explicit purpose +* of giving the serial line over to the debugger. +*/ +static struct uart_port debug_port; +void debug_request_serial_line (int line) +{ +struct uart_8250_port *uart = &serial8250_ports[line]; +/* For now, irq sharing doesn't seem to be supported so the +* irq that the debug port is on is marked as released +*/ + released_irq = uart->port.irq; + debug_port.flags = uart->port.flags; + debug_port.type = uart->port.type; + debug_port.dev = uart->port.dev; +serial8250_unregister_port (line); +} +EXPORT_SYMBOL (debug_request_serial_line); + +/** +* debug_release_serial_line - re-enable a 16x50 serial port at runtime +* @line: serial line number +* +* Re-enable one serial port. This may not be called from +* interrupt context. This function is for the explicit purpose +* of the debugger giving the serial line back to the standard +* serial driver. +*/ +void debug_release_serial_line (int line) +{ +struct uart_port *port = &serial8250_ports[line].port; + released_irq =-1 ; + port->flags = debug_port.flags; + port->type = debug_port.type; + port->dev = debug_port.dev; +serial8250_register_port (port); +} +EXPORT_SYMBOL (debug_release_serial_line);
drivers/serial/Kconfig renamed from drivers/serial/Kconfig~8250 +2 -2
@@ -86,8 +86,8 @@ config SERIAL_8250_ACPI namespace, say Y here. If unsure, say N. config SERIAL_8250_NR_UARTS - int "Maximum number of 8250/16550 serial ports" - depends on SERIAL_8250 + int "Maximum number of 8250/16550 serial ports" if 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 +610 -0
610 lines not on this page · raw message
drivers/serial/Makefile renamed from drivers/serial/Makefile~8250 +1 -0
@@ -58,3 +58,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
drivers/serial/serial_core.c renamed from drivers/serial/serial_core.c~8250 +5 -1
@@ -866,7 +866,11 @@ uart_tiocmset(struct tty_struct *tty, ststatic void uart_break_ctl (struct tty_struct *tty,int break_state) {struct uart_state *state = tty->driver_data; -struct uart_port *port = state->port; +struct uart_port *port; + +if (!state) +return ; + port = state->port;BUG_ON (!kernel_locked ());
include/linux/kgdb.h renamed from include/linux/kgdb.h~8250 +1 -0
@@ -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 +89 -0
99 lines not on this page · raw message
_
PATCH 5/15 Basic MIPS support
CC: Manish Lachwani <[email protected]>, Ralf Baechle <[email protected]> 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-rc3-trini/arch/mips/Kconfig.debug | 19 linux-2.6.13-rc3-trini/arch/mips/kernel/Makefile | 3 linux-2.6.13-rc3-trini/arch/mips/kernel/irq.c | 32 linux-2.6.13-rc3-trini/arch/mips/kernel/kgdb-jmp.c | 62 linux-2.6.13-rc3-trini/arch/mips/kernel/kgdb-setjmp.S | 23 linux-2.6.13-rc3-trini/arch/mips/kernel/kgdb.c | 292 ++ linux-2.6.13-rc3-trini/arch/mips/kernel/kgdb_handler.S | 58 linux-2.6.13-rc3-trini/arch/mips/kernel/traps.c | 26 linux-2.6.13-rc3-trini/arch/mips/mips-boards/generic/Makefile | 1 linux-2.6.13-rc3-trini/arch/mips/mips-boards/generic/init.c | 62 linux-2.6.13-rc3-trini/arch/mips/mips-boards/malta/malta_setup.c | 8 linux-2.6.13-rc3-trini/arch/mips/mm/extable.c | 7 linux-2.6.13-rc3-trini/arch/mips/sibyte/cfe/setup.c | 14 linux-2.6.13-rc3-trini/arch/mips/sibyte/sb1250/Makefile | 1 linux-2.6.13-rc3-trini/arch/mips/sibyte/sb1250/irq.c | 57 linux-2.6.13-rc3-trini/arch/mips/sibyte/sb1250/irq_handler.S | 2 linux-2.6.13-rc3-trini/arch/mips/sibyte/sb1250/kgdb_sibyte.c | 164 + linux-2.6.13-rc3-trini/arch/mips/sibyte/swarm/Makefile | 2 linux-2.6.13-rc3-trini/include/asm-mips/kdebug.h | 47 linux-2.6.13-rc3-trini/include/asm-mips/kgdb.h | 22 linux-2.6.13-rc3-trini/lib/Kconfig.debug | 7 linux-2.6.13-rc3/arch/mips/kernel/gdb-low.S | 370 --- linux-2.6.13-rc3/arch/mips/kernel/gdb-stub.c | 1091 ---------- linux-2.6.13-rc3/arch/mips/sibyte/swarm/dbg_io.c | 76 24 files changed, 729 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 +292 -0
292 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 +62 -0
62 lines not on this page · raw message
arch/mips/kernel/kgdb-setjmp.S new file +23 -0
@@ -0,0 +1,23 @@ +/* + * 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. + * + * 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 + 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" - 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_ONLY_MODULES + 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/15 Basic IA64 support
CC: Robert Picco <[email protected]>, Tony Luck <[email protected]> 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-rc3-trini/arch/ia64/kernel/Makefile | 1 linux-2.6.13-rc3-trini/arch/ia64/kernel/entry.S | 4 linux-2.6.13-rc3-trini/arch/ia64/kernel/ivt.S | 15 linux-2.6.13-rc3-trini/arch/ia64/kernel/kgdb-jmp.S | 238 ++++ linux-2.6.13-rc3-trini/arch/ia64/kernel/kgdb.c | 1038 +++++++++++++++++++++ linux-2.6.13-rc3-trini/arch/ia64/kernel/mca.c | 10 linux-2.6.13-rc3-trini/arch/ia64/kernel/process.c | 6 linux-2.6.13-rc3-trini/arch/ia64/kernel/smp.c | 17 linux-2.6.13-rc3-trini/arch/ia64/kernel/traps.c | 36 linux-2.6.13-rc3-trini/arch/ia64/kernel/unwind.c | 87 + linux-2.6.13-rc3-trini/arch/ia64/mm/extable.c | 6 linux-2.6.13-rc3-trini/arch/ia64/mm/fault.c | 5 linux-2.6.13-rc3-trini/include/asm-ia64/kgdb.h | 37 linux-2.6.13-rc3-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" - 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/15 Basic x86_64 support
CC: Andi Kleen <[email protected]>, Amit S Kale <[email protected]> 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-rc3-trini/arch/x86_64/Kconfig.debug | 3 linux-2.6.13-rc3-trini/arch/x86_64/kernel/Makefile | 2 linux-2.6.13-rc3-trini/arch/x86_64/kernel/kgdb-jmp.S | 65 ++ linux-2.6.13-rc3-trini/arch/x86_64/kernel/kgdb.c | 462 +++++++++++++++++++ linux-2.6.13-rc3-trini/arch/x86_64/kernel/traps.c | 9 linux-2.6.13-rc3-trini/include/asm-x86_64/hw_irq.h | 1 linux-2.6.13-rc3-trini/include/asm-x86_64/ipi.h | 12 linux-2.6.13-rc3-trini/include/asm-x86_64/kgdb.h | 50 ++ linux-2.6.13-rc3-trini/include/asm-x86_64/system.h | 6 linux-2.6.13-rc3-trini/lib/Kconfig.debug | 2 10 files changed, 607 insertions(+), 5 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 +462 -0
462 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 +9 -0
@@ -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>
@@ -940,6 +941,14 @@ void __init trap_init(void)* Should be a barrier for any external CPU state. */ cpu_init (); + +#ifdef CONFIG_KGDB +/* +* Has KGDB been told to break as soon as possible? +*/ +if (kgdb_initialized ==-1 ) +tasklet_schedule (&kgdb_tasklet_breakpoint); +#endif }
diff -puN arch/x86_64/mm/extable.c~x86_64-lite arch/x86_64/mm/extable.c
include/asm-x86_64/hw_irq.h renamed from include/asm-x86_64/hw_irq.h~x86_64-lite +1 -0
@@ -55,6 +55,7 @@ struct hw_interrupt_type;#define TASK_MIGRATION_VECTOR 0xfb#define CALL_FUNCTION_VECTOR 0xfa#define KDB_VECTOR 0xf9 +#define KGDB_VECTOR 0xf8#define THERMAL_APIC_VECTOR 0xf0
include/asm-x86_64/ipi.h renamed from include/asm-x86_64/ipi.h~x86_64-lite +12 -0
@@ -62,6 +62,12 @@ static inline void __send_IPI_shortcut(u* No need to touch the target chip field */ cfg =__prepare_ICR (shortcut, vector, dest); +if (vector ==KGDB_VECTOR ) { +/* +* KGDB IPI is to be delivered as a NMI +*/ + cfg = (cfg&~APIC_VECTOR_MASK )|APIC_DM_NMI ; + }/* * Send the IPI. The write to APIC_ICR fires this off.
@@ -100,6 +106,12 @@ static inline void send_IPI_mask_sequenc* program the ICR */ cfg =__prepare_ICR (0 , vector,APIC_DEST_PHYSICAL ); +if (vector ==KGDB_VECTOR ) { +/* +* KGDB IPI is to be delivered as a NMI +*/ + cfg = (cfg&~APIC_VECTOR_MASK )|APIC_DM_NMI ; + }/* * Send the IPI. The write to APIC_ICR fires this off.
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" - 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
_
PATCH 8/15 Basic SuperH support
CC: Paul Mundt <[email protected]>, Kazumoto Kojima <[email protected]> This 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).
---
linux-2.6.13-rc3-trini/Documentation/DocBook/kgdb.tmpl | 16 linux-2.6.13-rc3-trini/arch/sh/Kconfig.debug | 92 - linux-2.6.13-rc3-trini/arch/sh/Makefile | 1 linux-2.6.13-rc3-trini/arch/sh/boards/se/7751/setup.c | 139 - linux-2.6.13-rc3-trini/arch/sh/kernel/Makefile | 2 linux-2.6.13-rc3-trini/arch/sh/kernel/cpu/sh3/ex.S | 2 linux-2.6.13-rc3-trini/arch/sh/kernel/cpu/sh4/ex.S | 2 linux-2.6.13-rc3-trini/arch/sh/kernel/entry.S | 30 linux-2.6.13-rc3-trini/arch/sh/kernel/kgdb-jmp.S | 32 linux-2.6.13-rc3-trini/arch/sh/kernel/kgdb.c | 363 ++++ linux-2.6.13-rc3-trini/arch/sh/kernel/setup.c | 94 - linux-2.6.13-rc3-trini/arch/sh/kernel/time.c | 11 linux-2.6.13-rc3-trini/arch/sh/kernel/traps.c | 20 linux-2.6.13-rc3-trini/arch/sh/mm/extable.c | 7 linux-2.6.13-rc3-trini/arch/sh/mm/fault-nommu.c | 14 linux-2.6.13-rc3-trini/arch/sh/mm/fault.c | 12 linux-2.6.13-rc3-trini/drivers/serial/sh-sci.c | 314 ++- linux-2.6.13-rc3-trini/include/asm-sh/kgdb.h | 118 - linux-2.6.13-rc3-trini/include/asm-sh/system.h | 40 linux-2.6.13-rc3-trini/lib/Kconfig.debug | 14 linux-2.6.13-rc3/arch/sh/kernel/kgdb_jmp.S | 33 linux-2.6.13-rc3/arch/sh/kernel/kgdb_stub.c | 1491 ----------------- 22 files changed, 702 insertions(+), 2145 deletions(-)
arch/sh/boards/se/7751/setup.c renamed from arch/sh/boards/se/7751/setup.c~sh-lite +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 renamed from arch/sh/Kconfig.debug~sh-lite +0 -92
96 lines not on this page · raw message
arch/sh/kernel/cpu/sh3/ex.S renamed from arch/sh/kernel/cpu/sh3/ex.S~sh-lite +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 renamed from arch/sh/kernel/cpu/sh4/ex.S~sh-lite +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 renamed from arch/sh/kernel/entry.S~sh-lite +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 renamed from arch/sh/kernel/Makefile~sh-lite +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 renamed from arch/sh/kernel/setup.c~sh-lite +0 -94
103 lines not on this page · raw message
arch/sh/kernel/time.c renamed from arch/sh/kernel/time.c~sh-lite +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 renamed from arch/sh/kernel/traps.c~sh-lite +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 renamed from arch/sh/Makefile~sh-lite +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 renamed from arch/sh/mm/extable.c~sh-lite +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 renamed from arch/sh/mm/fault.c~sh-lite +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 renamed from arch/sh/mm/fault-nommu.c~sh-lite +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 renamed from Documentation/DocBook/kgdb.tmpl~sh-lite +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 renamed from drivers/serial/sh-sci.c~sh-lite +187 -127
426 lines not on this page · raw message
include/asm-sh/kgdb.h renamed from include/asm-sh/kgdb.h~sh-lite +20 -98
118 lines not on this page · raw message
include/asm-sh/system.h renamed from include/asm-sh/system.h~sh-lite +40 -0
Lines of this file are not shown. View the raw message.
lib/Kconfig.debug renamed from lib/Kconfig.debug~sh-lite +10 -4
Lines of this file are not shown. View the 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 9/15 KGDB: Basic ARM support.
CC: Russell King <[email protected]>, Deepak Saxena <[email protected]>, George Davis <[email protected]>, Geoff Levand <[email protected]>, Nicolas Pitre <[email protected]> This adds a backend, written by Deepak Saxena <[email protected]> and George
Davis <[email protected]> as well as support for the TI OMAP boards, ADI
Coyote, PXA2xx, 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-rc3-trini/arch/arm/kernel/Makefile | 1 linux-2.6.13-rc3-trini/arch/arm/kernel/kgdb-jmp.S | 30 + linux-2.6.13-rc3-trini/arch/arm/kernel/kgdb.c | 208 +++++++++++ linux-2.6.13-rc3-trini/arch/arm/kernel/setup.c | 5 linux-2.6.13-rc3-trini/arch/arm/kernel/traps.c | 11 linux-2.6.13-rc3-trini/arch/arm/mach-ixp2000/core.c | 5 linux-2.6.13-rc3-trini/arch/arm/mach-ixp2000/ixdp2x01.c | 6 linux-2.6.13-rc3-trini/arch/arm/mach-ixp4xx/coyote-setup.c | 5 linux-2.6.13-rc3-trini/arch/arm/mach-ixp4xx/ixdp425-setup.c | 10 linux-2.6.13-rc3-trini/arch/arm/mach-omap1/board-osk.c | 6 linux-2.6.13-rc3-trini/arch/arm/mach-omap1/serial.c | 4 linux-2.6.13-rc3-trini/arch/arm/mach-pxa/Makefile | 1 linux-2.6.13-rc3-trini/arch/arm/mach-pxa/kgdb-serial.c | 98 +++++ linux-2.6.13-rc3-trini/arch/arm/mach-versatile/kgdb_serial.c | 121 ++++++ linux-2.6.13-rc3-trini/arch/arm/mm/extable.c | 7 linux-2.6.13-rc3-trini/drivers/serial/amba-pl011.c | 2 linux-2.6.13-rc3-trini/drivers/serial/kgdb_8250.c | 16 linux-2.6.13-rc3-trini/include/asm-arm/kgdb.h | 90 ++++ linux-2.6.13-rc3-trini/include/asm-arm/system.h | 41 ++ linux-2.6.13-rc3-trini/lib/Kconfig.debug | 35 + 20 files changed, 695 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
@@ -266,6 +266,7 @@ asmlinkage void do_undefinstr(struct pt_unsigned int instr;struct undef_hook *hook;siginfo_t info; +mm_segment_t fs;void __user *pc;/*
@@ -275,12 +276,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) {
@@ -663,6 +667,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 +8 -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,7 @@ 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, + .flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ, .iotype = UPIO_MEM, .regshift = 2, .uartclk = IXP4XX_UART_XTAL,
@@ -91,7 +92,7 @@ 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, + .flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ, .iotype = UPIO_MEM, .regshift = 2, .uartclk = IXP4XX_UART_XTAL,
@@ -126,6 +127,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;
drivers/serial/kgdb_8250.c renamed from drivers/serial/kgdb_8250.c~arm-lite +16 -0
@@ -319,6 +319,22 @@ static int kgdb8250_init(void)/* Disable UART interrupts, set DTR and RTS high and set speed. */ cval =0x3 ; +#if defined(CONFIG_ARCH_OMAP1510 ) +/* Workaround to enable 115200 baud on OMAP1510 internal ports */ +if (cpu_is_omap1510 () &&is_omap_port ((void *)kgdb8250_addr)) { +if (kgdb8250_baud ==115200 ) { + base_baud =1 ; + kgdb8250_baud =1 ; +serial_outb (1 , kgdb8250_addr + + (UART_OMAP_OSC_12M_SEL << +KGDB8250_REG_SHIFT )); + }else { +serial_outb (0 , kgdb8250_addr + + (UART_OMAP_OSC_12M_SEL << +KGDB8250_REG_SHIFT )); + } + } +#endif /* set DLAB */ serial_outb (cval |UART_LCR_DLAB , kgdb8250_addr + (UART_LCR <<KGDB8250_REG_SHIFT ));
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" - 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_ONLY_MODULES + 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
@@ -296,6 +308,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 10/15 Basic support for PowerPC64
CC: Frank Rowand <[email protected]>, Paul Mackerras <[email protected]> This 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-rc3-trini/arch/ppc64/Kconfig.debug | 14 linux-2.6.13-rc3-trini/arch/ppc64/kernel/Makefile | 3 linux-2.6.13-rc3-trini/arch/ppc64/kernel/kgdb.c | 422 +++++++++++++++++ linux-2.6.13-rc3-trini/arch/ppc64/kernel/maple_setup.c | 5 linux-2.6.13-rc3-trini/arch/ppc64/kernel/setup.c | 14 linux-2.6.13-rc3-trini/arch/ppc64/mm/fault.c | 8 linux-2.6.13-rc3-trini/include/asm-ppc64/kgdb.h | 55 ++ linux-2.6.13-rc3-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>
@@ -1259,6 +1260,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,
@@ -1312,6 +1314,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" - 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 11/15 KGDB: 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.
---
Makefile | 0 linux-2.6.13-rc3-trini/drivers/net/Makefile | 1 linux-2.6.13-rc3-trini/drivers/net/kgdboe.c | 208 ++++++++++++++++++++++++++++ linux-2.6.13-rc3-trini/lib/Kconfig.debug | 24 +++ 4 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
diff -puN Makefile~eth Makefile
_
PATCH 12/15 KGDB: Add CFI DWARF2 annotation support.
CC: George Anzginer <[email protected]>
There 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-rc3-trini/Makefile | 5 linux-2.6.13-rc3-trini/arch/arm/kernel/entry-armv.S | 2 linux-2.6.13-rc3-trini/arch/i386/kernel/entry.S | 105 ++ linux-2.6.13-rc3-trini/arch/i386/kernel/head.S | 5 linux-2.6.13-rc3-trini/arch/i386/kernel/process.c | 20 linux-2.6.13-rc3-trini/arch/i386/kernel/smpboot.c | 3 linux-2.6.13-rc3-trini/arch/x86_64/kernel/entry.S | 2 linux-2.6.13-rc3-trini/include/asm-arm/kgdb.h | 7 linux-2.6.13-rc3-trini/include/asm-generic/kgdb.h | 34 linux-2.6.13-rc3-trini/include/asm-i386/kgdb.h | 60 - linux-2.6.13-rc3-trini/include/asm-mips/kgdb.h | 4 linux-2.6.13-rc3-trini/include/asm-ppc/kgdb.h | 1 linux-2.6.13-rc3-trini/include/asm-sh/kgdb.h | 1 linux-2.6.13-rc3-trini/include/asm-x86_64/kgdb.h | 4 linux-2.6.13-rc3-trini/include/linux/dwarf2-lang.h | 301 +++++++ linux-2.6.13-rc3-trini/include/linux/dwarf2.h | 775 ++++++++++++++++++++ linux-2.6.13-rc3-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" +}
_
PATCH 13/15 Minor SysRq keyboard bugfix for KGDB
CC: 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-rc3-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 14/15 Allow KGDB to work well with loaded modules
CC: Amit S. Kale <[email protected]>
This allows for KGDB to better deal with autoloaded modules.
---
linux-2.6.13-rc3-trini/include/linux/module.h | 16 +++++++ linux-2.6.13-rc3-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 15/15 Add hardware breakpoint support for i386
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.
---
linux-2.6.13-rc3-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 , };
_
Re: [patch 11/15] KGDB: KGDBoE I/O driver
In reply to Tom RiniQuoted 5 lines · Tom Rini
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.
Looks good to me.
Signature · 1 line
Mathematics is the supreme nostalgia of our time.
Re: [patch 07/15] Basic x86_64 support
In reply to Tom RiniOnly reading the changes outside kgdb.c....
arch/x86_64/kernel/traps.c void __init trap_init(void) · line 950
Quoted 7 lines
arch/x86_64/kernel/traps.c renamed from arch/x86_64/kernel/traps.c~x86_64-lite +7
-0+ +#ifdef CONFIG_KGDB +/* +* Has KGDB been told to break as soon as possible? +*/ +if (kgdb_initialized ==-1 ) +tasklet_schedule (&kgdb_tasklet_breakpoint);
That doesn't make much sense here. tasklet will only run when interrupts are enabled, and that is much later. You could move it to there.
include/asm-x86_64/hw_irq.h struct hw_interrupt_type; · line 58
Quoted 8 lines
diff -puN
include/asm-x86_64/hw_irq.h~x86_64-liteinclude/asm-x86_64/hw_irq.hinclude/asm-x86_64/hw_irq.h renamed from include/asm-x86_64/hw_irq.h~x86_64-lite +1
-0@@ -55,6 +55,7 @@ struct hw_interrupt_type;#define TASK_MIGRATION_VECTOR 0xfb#define CALL_FUNCTION_VECTOR 0xfa#define KDB_VECTOR 0xf9 +#define KGDB_VECTOR 0xf8
I already allocated these vectors for something else.
Quoted 6 lines
include/asm-x86_64/hw_irq.h renamed from include/asm-x86_64/hw_irq.h~x86_64-lite +0
-0#define THERMAL_APIC_VECTOR 0xf0diff -puN
include/asm-x86_64/ipi.h~x86_64-liteinclude/asm-x86_64/ipi.h
include/asm-x86_64/ipi.h static inline void __send_IPI_shortcut(u · line 70
Quoted 9 lines
include/asm-x86_64/ipi.h renamed from include/asm-x86_64/ipi.h~x86_64-lite +6
-0@@ -62,6 +62,12 @@ static inline void __send_IPI_shortcut(u* No need to touch the target chip field */ cfg =__prepare_ICR (shortcut, vector, dest); +if (vector ==KGDB_VECTOR ) { +/* +* KGDB IPI is to be delivered as a NMI +*/ + cfg = (cfg&~APIC_VECTOR_MASK )|APIC_DM_NMI ; + }
No way adding another ugly special case like this. I wanted to rip out the KDB version for a long time.
If anything pass a flag.
include/asm-x86_64/ipi.h static inline void __send_IPI_shortcut(u
Quoted 7 lines
include/asm-x86_64/ipi.h renamed from include/asm-x86_64/ipi.h~x86_64-lite +3
-1,"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 \
Why is this needed?
-Andi
Re: [patch 07/15] Basic x86_64 support
Quoted 13 lines · Andi Kleen
Only reading the changes outside
kgdb.c....arch/x86_64/kernel/traps.c void __init trap_init(void) · line 950
Quoted 7 lines
arch/x86_64/kernel/traps.c renamed from arch/x86_64/kernel/traps.c~x86_64-lite +7
-0+ +#ifdef CONFIG_KGDB +/* +* Has KGDB been told to break as soon as possible? +*/ +if (kgdb_initialized ==-1 ) +tasklet_schedule (&kgdb_tasklet_breakpoint);That doesn't make much sense here. tasklet will only run when interrupts are enabled, and that is much later. You could move it to there.
Where? Keep in mind it's really only x86_64 that isn't able to break sooner.
Quoted 10 lines
include/asm-x86_64/hw_irq.h struct hw_interrupt_type; · line 58
Quoted 8 lines
diff -puN
include/asm-x86_64/hw_irq.h~x86_64-liteinclude/asm-x86_64/hw_irq.hinclude/asm-x86_64/hw_irq.h renamed from include/asm-x86_64/hw_irq.h~x86_64-lite +1
-0@@ -55,6 +55,7 @@ struct hw_interrupt_type;#define TASK_MIGRATION_VECTOR 0xfb#define CALL_FUNCTION_VECTOR 0xfa#define KDB_VECTOR 0xf9 +#define KGDB_VECTOR 0xf8I already allocated these vectors for something else.
Is there another we can use? Just following what looked to be the logical order.
Quoted 18 lines
Quoted 6 lines
include/asm-x86_64/hw_irq.h renamed from include/asm-x86_64/hw_irq.h~x86_64-lite +0
-0#define THERMAL_APIC_VECTOR 0xf0diff -puN
include/asm-x86_64/ipi.h~x86_64-liteinclude/asm-x86_64/ipi.hinclude/asm-x86_64/ipi.h static inline void __send_IPI_shortcut(u · line 70
Quoted 9 lines
include/asm-x86_64/ipi.h renamed from include/asm-x86_64/ipi.h~x86_64-lite +6
-0@@ -62,6 +62,12 @@ static inline void __send_IPI_shortcut(u* No need to touch the target chip field */ cfg =__prepare_ICR (shortcut, vector, dest); +if (vector ==KGDB_VECTOR ) { +/* +* KGDB IPI is to be delivered as a NMI +*/ + cfg = (cfg&~APIC_VECTOR_MASK )|APIC_DM_NMI ; + }No way adding another ugly special case like this. I wanted to rip out the KDB version for a long time.
I'd be happy to rework it in a cleaner manner, just point me at an example please.
Quoted 1 line
If anything pass a flag.
In __send_IPI_shortcut? OK.
Quoted 9 lines
include/asm-x86_64/ipi.h static inline void __send_IPI_shortcut(u
Quoted 7 lines
include/asm-x86_64/ipi.h renamed from include/asm-x86_64/ipi.h~x86_64-lite +3
-1,"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 \Why is this needed?
So that backtraces show they're in switch_to rather than somewhere else (since it's a #define we wouldn't know otherwise).
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [patch 07/15] Basic x86_64 support
Quoted 5 lines
Quoted 2 lines
That doesn't make much sense here. tasklet will only run when interrupts are enabled, and that is much later. You could move it to there.
Where? Keep in mind it's really only
x86_64that isn't able to break sooner.
The local_irq_enable() call in init/main.c:start_kernel()
If you want to run gdb earlier you need to do it without a tasklet.
Quoted 10 lines
Quoted 9 lines
include/asm-x86_64/hw_irq.h struct hw_interrupt_type; · line 58
Quoted 7 lines
include/asm-x86_64/hw_irq.h renamed from include/asm-x86_64/hw_irq.h~x86_64-lite +1
-0@@ -55,6 +55,7 @@ struct hw_interrupt_type;#define TASK_MIGRATION_VECTOR 0xfb#define CALL_FUNCTION_VECTOR 0xfa#define KDB_VECTOR 0xf9 +#define KGDB_VECTOR 0xf8I already allocated these vectors for something else.
Quoted 2 lines
Is there another we can use? Just following what looked to be the logical order.
How about you use KDB_VECTOR and rename it to DEBUG_VECTOR and then just check if kgdb is currently active?
KDB can do the same.
I changed the assignment in my tree like this:
#define SPURIOUS_APIC_VECTOR 0xff #define ERROR_APIC_VECTOR 0xfe #define RESCHEDULE_VECTOR 0xfd #define CALL_FUNCTION_VECTOR 0xfc #define KDB_VECTOR 0xfb /* reserved for KDB */ #define THERMAL_APIC_VECTOR 0xfa
/* 0xf9 free */
#define INVALIDATE_TLB_VECTOR_END 0xf8
#define INVALIDATE_TLB_VECTOR_START 0xf0 /* f0-f8 used for TLB flush */
but that can be merged later. THere will be probably more changes with the per CPU IDT planned.
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
include/asm-x86_64/hw_irq.h renamed from include/asm-x86_64/hw_irq.h~x86_64-lite +6
-0cfg =__prepare_ICR (shortcut, vector, dest); +if (vector ==KGDB_VECTOR ) { +/* +* KGDB IPI is to be delivered as a NMI +*/ + cfg = (cfg&~APIC_VECTOR_MASK )|APIC_DM_NMI ; + }
Quoted 5 lines
Quoted 2 lines
No way adding another ugly special case like this. I wanted to rip out the KDB version for a long time.
I'd be happy to rework it in a cleaner manner, just point me at an example please.
The code is equivalent to passing shortcut|APIC_DM_NMI and vector == 0
Quoted 9 lines
Quoted 6 lines
include/asm-x86_64/hw_irq.h
Quoted 4 lines
include/asm-x86_64/hw_irq.h renamed from include/asm-x86_64/hw_irq.h~x86_64-lite +3
-1- asm volatile(SAVE_CONTEXT \ + asmvolatile (".globl __switch_to_begin\n\t" \ +"__switch_to_begin:\n\t" \ + SAVE_CONTEXT \Why is this needed?
So that backtraces show they're in
switch_torather than somewhere else (since it's a #define we wouldn't know otherwise).
Ok.
-Andi
Re: [patch 07/15] Basic x86_64 support
Quoted 7 lines · Andi Kleen
Quoted 5 lines
Quoted 2 lines
That doesn't make much sense here. tasklet will only run when interrupts are enabled, and that is much later. You could move it to there.
Where? Keep in mind it's really only
x86_64that isn't able to break sooner.The
local_irq_enable()call in init/main.c:start_kernel()
But as I say, only x86_64 needs this kind of delay.
Quoted 1 line
If you want to run gdb earlier you need to do it without a tasklet.
We really would like to try again once stacks are setup (IOW, once if ((&__get_cpu_var(init_tss))[0].ist[0])) is true).
Quoted 10 lines
Quoted 10 lines
Quoted 9 lines
include/asm-x86_64/hw_irq.h struct hw_interrupt_type; · line 58
Quoted 7 lines
include/asm-x86_64/hw_irq.h renamed from include/asm-x86_64/hw_irq.h~x86_64-lite +1
-0@@ -55,6 +55,7 @@ struct hw_interrupt_type;#define TASK_MIGRATION_VECTOR 0xfb#define CALL_FUNCTION_VECTOR 0xfa#define KDB_VECTOR 0xf9 +#define KGDB_VECTOR 0xf8I already allocated these vectors for something else.
Quoted 5 lines
Quoted 2 lines
Is there another we can use? Just following what looked to be the logical order.
How about you use
KDB_VECTORand rename it toDEBUG_VECTORand then just check if kgdb is currently active?
I can do the kgdb and generic changes at least.
[snip]
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
include/asm-x86_64/hw_irq.h renamed from include/asm-x86_64/hw_irq.h~x86_64-lite +6
-0cfg =__prepare_ICR (shortcut, vector, dest); +if (vector ==KGDB_VECTOR ) { +/* +* KGDB IPI is to be delivered as a NMI +*/ + cfg = (cfg&~APIC_VECTOR_MASK )|APIC_DM_NMI ; + }
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
No way adding another ugly special case like this. I wanted to rip out the KDB version for a long time.
I'd be happy to rework it in a cleaner manner, just point me at an example please.
The code is equivalent to passing shortcut|APIC_DM_NMI and vector == 0
OK. I'll see if I can change things around then, thanks.
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [patch 07/15] Basic x86_64 support
Quoted 10 lines · Tom Rini
Quoted 7 lines · Andi Kleen
Quoted 5 lines
Quoted 2 lines
That doesn't make much sense here. tasklet will only run when interrupts are enabled, and that is much later. You could move it to there.
Where? Keep in mind it's really only
x86_64that isn't able to break sooner.The
local_irq_enable()call in init/main.c:start_kernel()But as I say, only
x86_64needs this kind of delay.
I don't think that's correct. Interrupts should be disabled on all architectures until that.
-Andi
Re: [patch 07/15] Basic x86_64 support
Quoted 8 lines · Andi Kleen
Quoted 7 lines · Tom Rini
Quoted 6 lines · Andi Kleen
Quoted 5 lines
Quoted 2 lines
That doesn't make much sense here. tasklet will only run when interrupts are enabled, and that is much later. You could move it to there.
Where? Keep in mind it's really only
x86_64that isn't able to break sooner.
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
The
local_irq_enable()call in init/main.c:start_kernel()But as I say, only
x86_64needs this kind of delay.I don't think that's correct. Interrupts should be disabled on all architectures until that.
Right, but we can run sooner elsewhere. It's only x86_64 where we can't run when our commandline bits are parsed and need to wait.
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [patch 07/15] Basic x86_64 support
Quoted 11 lines · Tom Rini
Quoted 10 lines · Andi Kleen
Quoted 9 lines · Tom Rini
Quoted 7 lines · Andi Kleen
Quoted 5 lines
Quoted 2 lines
That doesn't make much sense here. tasklet will only run when interrupts are enabled, and that is much later. You could move it to there.
Where? Keep in mind it's really only
x86_64that isn't able to break sooner.The
local_irq_enable()call in init/main.c:start_kernel()
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
But as I say, only
x86_64needs this kind of delay.I don't think that's correct. Interrupts should be disabled on all architectures until that.
Right, but we can run sooner elsewhere. It's only
x86_64where we can't run when our commandline bits are parsed and need to wait.
Why can't you run on x86-64 early?
-Andi
Re: [patch 07/15] Basic x86_64 support
Quoted 14 lines · Andi Kleen
Quoted 13 lines · Tom Rini
Quoted 12 lines · Andi Kleen
Quoted 10 lines · Tom Rini
Quoted 7 lines · Andi Kleen
Quoted 5 lines
Quoted 2 lines
That doesn't make much sense here. tasklet will only run when interrupts are enabled, and that is much later. You could move it to there.
Where? Keep in mind it's really only
x86_64that isn't able to break sooner.The
local_irq_enable()call in init/main.c:start_kernel()But as I say, only
x86_64needs this kind of delay.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
I don't think that's correct. Interrupts should be disabled on all architectures until that.
Right, but we can run sooner elsewhere. It's only
x86_64where we can't run when our commandline bits are parsed and need to wait.Why can't you run on x86-64 early?
As I said earlier:
"
Quoted 1 line
If you want to run gdb earlier you need to do it without a tasklet.
We really would like to try again once stacks are setup (IOW, once if ((&__get_cpu_var(init_tss))[0].ist[0])) is true).
"
IOW, when we parse the params on x86_64 this isn't true (or rather it wasn't true as of 2.6.9'ish, if this has changed I'd be glad to retest things).
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [patch 07/15] Basic x86_64 support
Quoted 7 lines · Tom Rini
Quoted 2 lines
Why can't you run on x86-64 early?
As I said earlier:
"Quoted 1 line
If you want to run gdb earlier you need to do it without a tasklet.
Quoted 7 lines
We really would like to try again once stacks are setup (IOW, once if ((&__get_cpu_var(init_tss))[0].ist[0])) is true).
"IOW, when we parse the params on
x86_64this isn't true (or rather it wasn't true as of 2.6.9'ish, if this has changed I'd be glad to retest things).
The ISTs are set up for the boot processor extremly early - even before start_kernel. But they are useless before trap_init() runs because you won't get any exceptions that need an IDT (or rather they will all still point to the early exception handler that just panics)
-Andi
Re: [patch 07/15] Basic x86_64 support
Quoted 12 lines · Andi Kleen
Quoted 11 lines · Tom Rini
Quoted 2 lines
Why can't you run on x86-64 early?
As I said earlier:
"Quoted 1 line
If you want to run gdb earlier you need to do it without a tasklet.
We really would like to try again once stacks are setup (IOW, once if ((&__get_cpu_var(init_tss))[0].ist[0])) is true).
"
Quoted 8 lines
Quoted 3 lines
IOW, when we parse the params on
x86_64this isn't true (or rather it wasn't true as of 2.6.9'ish, if this has changed I'd be glad to retest things).The ISTs are set up for the boot processor extremly early - even before
start_kernel. But they are useless beforetrap_init()runs because you won't get any exceptions that need an IDT (or rather they will all still point to the early exception handler that just panics)
I wonder if there was a reason we couldn't do what we did with i386 and make an early_trap_init() so that we can get what we care about that early at least. I'll have to poke at this a bit more, thanks!
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [patch 07/15] Basic x86_64 support
In reply to Andi KleenQuoted 36 lines · Andi Kleen
Quoted 5 lines
Quoted 2 lines
That doesn't make much sense here. tasklet will only run when interrupts are enabled, and that is much later. You could move it to there.
Where? Keep in mind it's really only
x86_64that isn't able to break sooner.The
local_irq_enable()call in init/main.c:start_kernel()If you want to run gdb earlier you need to do it without a tasklet.
Quoted 10 lines
Quoted 9 lines
include/asm-x86_64/hw_irq.h struct hw_interrupt_type; · line 58
Quoted 7 lines
include/asm-x86_64/hw_irq.h renamed from include/asm-x86_64/hw_irq.h~x86_64-lite +1
-0@@ -55,6 +55,7 @@ struct hw_interrupt_type;#define TASK_MIGRATION_VECTOR 0xfb#define CALL_FUNCTION_VECTOR 0xfa#define KDB_VECTOR 0xf9 +#define KGDB_VECTOR 0xf8I already allocated these vectors for something else.
Quoted 2 lines
Is there another we can use? Just following what looked to be the logical order.
How about you use
KDB_VECTORand rename it toDEBUG_VECTORand then just check if kgdb is currently active?KDB can do the same.
I changed the assignment in my tree like this:
#define SPURIOUS_APIC_VECTOR 0xff #define ERROR_APIC_VECTOR 0xfe #define RESCHEDULE_VECTOR 0xfd #define CALL_FUNCTION_VECTOR 0xfc #define KDB_VECTOR 0xfb /* reserved for KDB */ #define THERMAL_APIC_VECTOR 0xfa
Quoted 3 lines
/*
0xf9free */
#defineINVALIDATE_TLB_VECTOR_END0xf8
#defineINVALIDATE_TLB_VECTOR_START0xf0/* f0-f8 used for TLB flush */
Don't call it {KDB,KGDB,DEBUG}_VECTOR, call it NMI_VECTOR, which is what it really is. default_do_nmi() determines if the nmi is due to a debugger or some other event. That requires the debuggers to record if they are expecting their own nmi, putting all the load on the debuggers, where it belongs.
IOW, add NMI_VECTOR to the base code, then add debugger support on top of NMI_VECTOR.
Re: [patch 07/15] Basic x86_64 support
Quoted 42 lines · Keith Owens
Quoted 36 lines · Andi Kleen
Quoted 5 lines
Quoted 2 lines
That doesn't make much sense here. tasklet will only run when interrupts are enabled, and that is much later. You could move it to there.
Where? Keep in mind it's really only
x86_64that isn't able to break sooner.The
local_irq_enable()call in init/main.c:start_kernel()If you want to run gdb earlier you need to do it without a tasklet.
Quoted 10 lines
Quoted 9 lines
include/asm-x86_64/hw_irq.h struct hw_interrupt_type; · line 58
Quoted 7 lines
include/asm-x86_64/hw_irq.h renamed from include/asm-x86_64/hw_irq.h~x86_64-lite +1
-0@@ -55,6 +55,7 @@ struct hw_interrupt_type;#define TASK_MIGRATION_VECTOR 0xfb#define CALL_FUNCTION_VECTOR 0xfa#define KDB_VECTOR 0xf9 +#define KGDB_VECTOR 0xf8I already allocated these vectors for something else.
Quoted 2 lines
Is there another we can use? Just following what looked to be the logical order.
How about you use
KDB_VECTORand rename it toDEBUG_VECTORand then just check if kgdb is currently active?KDB can do the same.
I changed the assignment in my tree like this:
#define SPURIOUS_APIC_VECTOR 0xff #define ERROR_APIC_VECTOR 0xfe #define RESCHEDULE_VECTOR 0xfd #define CALL_FUNCTION_VECTOR 0xfc #define KDB_VECTOR 0xfb /* reserved for KDB */ #define THERMAL_APIC_VECTOR 0xfaQuoted 3 lines
/*
0xf9free */
#defineINVALIDATE_TLB_VECTOR_END0xf8
#defineINVALIDATE_TLB_VECTOR_START0xf0/* f0-f8 used for TLB flush */
Quoted 8 lines
Don't call it {KDB,KGDB,DEBUG}_VECTOR, call it
NMI_VECTOR, which is what it really is.default_do_nmi()determines if the nmi is due to a debugger or some other event. That requires the debuggers to record if they are expecting their own nmi, putting all the load on the debuggers, where it belongs.IOW, add
NMI_VECTORto the base code, then add debugger support on top ofNMI_VECTOR.
Works for me. I'll post something vs 2.6.13-rc6 later today hopefully that does the rename.
Signature · 2 lines
Tom Rini http://gate.crashing.org/~trini/
Re: [patch 05/15] Basic MIPS support
In reply to Tom RiniForwarding this as a heads up. Who cares about kgdb may want to start working on the necessary bits as the patchset from below will be in 2.6.13.
Ralf
Quoted 2,777 lines · Tom Rini
CC: Manish Lachwani <[email protected]>, Ralf Baechle <[email protected]> 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-rc3-trini/arch/mips/Kconfig.debug | 19 linux-2.6.13-rc3-trini/arch/mips/kernel/Makefile | 3 linux-2.6.13-rc3-trini/arch/mips/kernel/irq.c | 32 linux-2.6.13-rc3-trini/arch/mips/kernel/kgdb-jmp.c | 62 linux-2.6.13-rc3-trini/arch/mips/kernel/kgdb-setjmp.S | 23 linux-2.6.13-rc3-trini/arch/mips/kernel/kgdb.c | 292 ++ linux-2.6.13-rc3-trini/arch/mips/kernel/kgdb_handler.S | 58 linux-2.6.13-rc3-trini/arch/mips/kernel/traps.c | 26 linux-2.6.13-rc3-trini/arch/mips/mips-boards/generic/Makefile | 1 linux-2.6.13-rc3-trini/arch/mips/mips-boards/generic/init.c | 62 linux-2.6.13-rc3-trini/arch/mips/mips-boards/malta/malta_setup.c | 8 linux-2.6.13-rc3-trini/arch/mips/mm/extable.c | 7 linux-2.6.13-rc3-trini/arch/mips/sibyte/cfe/setup.c | 14 linux-2.6.13-rc3-trini/arch/mips/sibyte/sb1250/Makefile | 1 linux-2.6.13-rc3-trini/arch/mips/sibyte/sb1250/irq.c | 57 linux-2.6.13-rc3-trini/arch/mips/sibyte/sb1250/irq_handler.S | 2 linux-2.6.13-rc3-trini/arch/mips/sibyte/sb1250/kgdb_sibyte.c | 164 + linux-2.6.13-rc3-trini/arch/mips/sibyte/swarm/Makefile | 2 linux-2.6.13-rc3-trini/include/asm-mips/kdebug.h | 47 linux-2.6.13-rc3-trini/include/asm-mips/kgdb.h | 22 linux-2.6.13-rc3-trini/lib/Kconfig.debug | 7 linux-2.6.13-rc3/arch/mips/kernel/gdb-low.S | 370 --- linux-2.6.13-rc3/arch/mips/kernel/gdb-stub.c | 1091 ---------- linux-2.6.13-rc3/arch/mips/sibyte/swarm/dbg_io.c | 76 24 files changed, 729 insertions(+), 1717 deletions(-)diff -puN
arch/mips/Kconfig.debug~mips-litearch/mips/Kconfig.debugarch/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_SOCdiff -L
arch/mips/kernel/gdb-low.S-puNarch/mips/kernel/gdb-low.S~mips-lite/dev/nullarch/mips/kernel/gdb-low.S deleted +0
-370@@ -1,370 +0,0 @@ -/* - * gdb-low.S contains the low-level trap handler for the GDB stub. - * - * Copyright (C) 1995 Andreas Busse - */ -#include <linux/config.h> -#include <linux/sys.h> - -#include <asm/asm.h> -#include <asm/errno.h> -#include <asm/mipsregs.h> -#include <asm/regdef.h> -#include <asm/stackframe.h> -#include <asm/gdb-stub.h> - -#ifdef CONFIG_MIPS32 -#define DMFC0 mfc0 -#define DMTC0 mtc0 -#define LDC1 lwc1 -#define SDC1 lwc1 -#endif -#ifdef CONFIG_MIPS64 -#define DMFC0 dmfc0 -#define DMTC0 dmtc0 -#define LDC1 ldc1 -#define SDC1 ldc1 -#endif - -/* - * [jsun] We reserves about 2x GDB_FR_SIZE in stack. The lower (addressed) - * part is used to store registers and passed to exception handler. - * The upper part is reserved for "call func" feature where gdb client - * saves some of the regs, setups call frame and passes args. - * - * A trace shows about 200 bytes are used to store about half of all regs. - * The rest should be big enough for frame setup and passing args. - */ - -/* - * The low level trap handler - */ - .align 5 - NESTED(trap_low, GDB_FR_SIZE, sp) - .set noat - .set noreorder - - mfc0 k0, CP0_STATUS - sll k0, 3 /* extract cu0 bit */ - bltz k0, 1f - move k1, sp - - /* - * Called from user mode, go somewhere else. - */ - lui k1, %hi(saved_vectors) - mfc0 k0, CP0_CAUSE - andi k0, k0, 0x7c - add k1, k1, k0 - lw k0, %lo(saved_vectors)(k1) - jr k0 - nop -1: - move k0, sp - subu sp, k1, GDB_FR_SIZE*2 # see comment above - LONG_S k0, GDB_FR_REG29(sp) - LONG_S $2, GDB_FR_REG2(sp) - -/* - * First save the CP0 and special registers - */ - - mfc0 v0, CP0_STATUS - LONG_S v0, GDB_FR_STATUS(sp) - mfc0 v0, CP0_CAUSE - LONG_S v0, GDB_FR_CAUSE(sp) - DMFC0 v0, CP0_EPC - LONG_S v0, GDB_FR_EPC(sp) - DMFC0 v0, CP0_BADVADDR - LONG_S v0, GDB_FR_BADVADDR(sp) - mfhi v0 - LONG_S v0, GDB_FR_HI(sp) - mflo v0 - LONG_S v0, GDB_FR_LO(sp) - -/* - * Now the integer registers - */ - - LONG_S zero, GDB_FR_REG0(sp) /* I know... */ - LONG_S $1, GDB_FR_REG1(sp) - /* v0 already saved */ - LONG_S $3, GDB_FR_REG3(sp) - LONG_S $4, GDB_FR_REG4(sp) - LONG_S $5, GDB_FR_REG5(sp) - LONG_S $6, GDB_FR_REG6(sp) - LONG_S $7, GDB_FR_REG7(sp) - LONG_S $8, GDB_FR_REG8(sp) - LONG_S $9, GDB_FR_REG9(sp) - LONG_S $10, GDB_FR_REG10(sp) - LONG_S $11, GDB_FR_REG11(sp) - LONG_S $12, GDB_FR_REG12(sp) - LONG_S $13, GDB_FR_REG13(sp) - LONG_S $14, GDB_FR_REG14(sp) - LONG_S $15, GDB_FR_REG15(sp) - LONG_S $16, GDB_FR_REG16(sp) - LONG_S $17, GDB_FR_REG17(sp) - LONG_S $18, GDB_FR_REG18(sp) - LONG_S $19, GDB_FR_REG19(sp) - LONG_S $20, GDB_FR_REG20(sp) - LONG_S $21, GDB_FR_REG21(sp) - LONG_S $22, GDB_FR_REG22(sp) - LONG_S $23, GDB_FR_REG23(sp) - LONG_S $24, GDB_FR_REG24(sp) - LONG_S $25, GDB_FR_REG25(sp) - LONG_S $26, GDB_FR_REG26(sp) - LONG_S $27, GDB_FR_REG27(sp) - LONG_S $28, GDB_FR_REG28(sp) - /* sp already saved */ - LONG_S $30, GDB_FR_REG30(sp) - LONG_S $31, GDB_FR_REG31(sp) - - CLI /* disable interrupts */ - -/* - * Followed by the floating point registers - */ - mfc0 v0, CP0_STATUS /* FPU enabled? */ - srl v0, v0, 16 - andi v0, v0, (ST0_CU1 >> 16) - - beqz v0,2f /* disabled, skip */ - nop - - SDC1 $0, GDB_FR_FPR0(sp) - SDC1 $1, GDB_FR_FPR1(sp) - SDC1 $2, GDB_FR_FPR2(sp) - SDC1 $3, GDB_FR_FPR3(sp) - SDC1 $4, GDB_FR_FPR4(sp) - SDC1 $5, GDB_FR_FPR5(sp) - SDC1 $6, GDB_FR_FPR6(sp) - SDC1 $7, GDB_FR_FPR7(sp) - SDC1 $8, GDB_FR_FPR8(sp) - SDC1 $9, GDB_FR_FPR9(sp) - SDC1 $10, GDB_FR_FPR10(sp) - SDC1 $11, GDB_FR_FPR11(sp) - SDC1 $12, GDB_FR_FPR12(sp) - SDC1 $13, GDB_FR_FPR13(sp) - SDC1 $14, GDB_FR_FPR14(sp) - SDC1 $15, GDB_FR_FPR15(sp) - SDC1 $16, GDB_FR_FPR16(sp) - SDC1 $17, GDB_FR_FPR17(sp) - SDC1 $18, GDB_FR_FPR18(sp) - SDC1 $19, GDB_FR_FPR19(sp) - SDC1 $20, GDB_FR_FPR20(sp) - SDC1 $21, GDB_FR_FPR21(sp) - SDC1 $22, GDB_FR_FPR22(sp) - SDC1 $23, GDB_FR_FPR23(sp) - SDC1 $24, GDB_FR_FPR24(sp) - SDC1 $25, GDB_FR_FPR25(sp) - SDC1 $26, GDB_FR_FPR26(sp) - SDC1 $27, GDB_FR_FPR27(sp) - SDC1 $28, GDB_FR_FPR28(sp) - SDC1 $29, GDB_FR_FPR29(sp) - SDC1 $30, GDB_FR_FPR30(sp) - SDC1 $31, GDB_FR_FPR31(sp) - -/* - * FPU control registers - */ - - cfc1 v0, CP1_STATUS - LONG_S v0, GDB_FR_FSR(sp) - cfc1 v0, CP1_REVISION - LONG_S v0, GDB_FR_FIR(sp) - -/* - * Current stack frame ptr - */ - -2: - LONG_S sp, GDB_FR_FRP(sp) - -/* - * CP0 registers (R4000/R4400 unused registers skipped) - */ - - mfc0 v0, CP0_INDEX - LONG_S v0, GDB_FR_CP0_INDEX(sp) - mfc0 v0, CP0_RANDOM - LONG_S v0, GDB_FR_CP0_RANDOM(sp) - DMFC0 v0, CP0_ENTRYLO0 - LONG_S v0, GDB_FR_CP0_ENTRYLO0(sp) - DMFC0 v0, CP0_ENTRYLO1 - LONG_S v0, GDB_FR_CP0_ENTRYLO1(sp) - DMFC0 v0, CP0_CONTEXT - LONG_S v0, GDB_FR_CP0_CONTEXT(sp) - mfc0 v0, CP0_PAGEMASK - LONG_S v0, GDB_FR_CP0_PAGEMASK(sp) - mfc0 v0, CP0_WIRED - LONG_S v0, GDB_FR_CP0_WIRED(sp) - DMFC0 v0, CP0_ENTRYHI - LONG_S v0, GDB_FR_CP0_ENTRYHI(sp) - mfc0 v0, CP0_PRID - LONG_S v0, GDB_FR_CP0_PRID(sp) - - .set at - -/* - * Continue with the higher level handler - */ - - move a0,sp - - jal handle_exception - nop - -/* - * Restore all writable registers, in reverse order - */ - - .set noat - - LONG_L v0, GDB_FR_CP0_ENTRYHI(sp) - LONG_L v1, GDB_FR_CP0_WIRED(sp) - DMTC0 v0, CP0_ENTRYHI - mtc0 v1, CP0_WIRED - LONG_L v0, GDB_FR_CP0_PAGEMASK(sp) - LONG_L v1, GDB_FR_CP0_ENTRYLO1(sp) - mtc0 v0, CP0_PAGEMASK - DMTC0 v1, CP0_ENTRYLO1 - LONG_L v0, GDB_FR_CP0_ENTRYLO0(sp) - LONG_L v1, GDB_FR_CP0_INDEX(sp) - DMTC0 v0, CP0_ENTRYLO0 - LONG_L v0, GDB_FR_CP0_CONTEXT(sp) - mtc0 v1, CP0_INDEX - DMTC0 v0, CP0_CONTEXT - - -/* - * Next, the floating point registers - */ - mfc0 v0, CP0_STATUS /* check if the FPU is enabled */ - srl v0, v0, 16 - andi v0, v0, (ST0_CU1 >> 16) - - beqz v0, 3f /* disabled, skip */ - nop - - LDC1 $31, GDB_FR_FPR31(sp) - LDC1 $30, GDB_FR_FPR30(sp) - LDC1 $29, GDB_FR_FPR29(sp) - LDC1 $28, GDB_FR_FPR28(sp) - LDC1 $27, GDB_FR_FPR27(sp) - LDC1 $26, GDB_FR_FPR26(sp) - LDC1 $25, GDB_FR_FPR25(sp) - LDC1 $24, GDB_FR_FPR24(sp) - LDC1 $23, GDB_FR_FPR23(sp) - LDC1 $22, GDB_FR_FPR22(sp) - LDC1 $21, GDB_FR_FPR21(sp) - LDC1 $20, GDB_FR_FPR20(sp) - LDC1 $19, GDB_FR_FPR19(sp) - LDC1 $18, GDB_FR_FPR18(sp) - LDC1 $17, GDB_FR_FPR17(sp) - LDC1 $16, GDB_FR_FPR16(sp) - LDC1 $15, GDB_FR_FPR15(sp) - LDC1 $14, GDB_FR_FPR14(sp) - LDC1 $13, GDB_FR_FPR13(sp) - LDC1 $12, GDB_FR_FPR12(sp) - LDC1 $11, GDB_FR_FPR11(sp) - LDC1 $10, GDB_FR_FPR10(sp) - LDC1 $9, GDB_FR_FPR9(sp) - LDC1 $8, GDB_FR_FPR8(sp) - LDC1 $7, GDB_FR_FPR7(sp) - LDC1 $6, GDB_FR_FPR6(sp) - LDC1 $5, GDB_FR_FPR5(sp) - LDC1 $4, GDB_FR_FPR4(sp) - LDC1 $3, GDB_FR_FPR3(sp) - LDC1 $2, GDB_FR_FPR2(sp) - LDC1 $1, GDB_FR_FPR1(sp) - LDC1 $0, GDB_FR_FPR0(sp) - -/* - * Now the CP0 and integer registers - */ - -3: - mfc0 t0, CP0_STATUS - ori t0, 0x1f - xori t0, 0x1f - mtc0 t0, CP0_STATUS - - LONG_L v0, GDB_FR_STATUS(sp) - LONG_L v1, GDB_FR_EPC(sp) - mtc0 v0, CP0_STATUS - DMTC0 v1, CP0_EPC - LONG_L v0, GDB_FR_HI(sp) - LONG_L v1, GDB_FR_LO(sp) - mthi v0 - mtlo v1 - LONG_L $31, GDB_FR_REG31(sp) - LONG_L $30, GDB_FR_REG30(sp) - LONG_L $28, GDB_FR_REG28(sp) - LONG_L $27, GDB_FR_REG27(sp) - LONG_L $26, GDB_FR_REG26(sp) - LONG_L $25, GDB_FR_REG25(sp) - LONG_L $24, GDB_FR_REG24(sp) - LONG_L $23, GDB_FR_REG23(sp) - LONG_L $22, GDB_FR_REG22(sp) - LONG_L $21, GDB_FR_REG21(sp) - LONG_L $20, GDB_FR_REG20(sp) - LONG_L $19, GDB_FR_REG19(sp) - LONG_L $18, GDB_FR_REG18(sp) - LONG_L $17, GDB_FR_REG17(sp) - LONG_L $16, GDB_FR_REG16(sp) - LONG_L $15, GDB_FR_REG15(sp) - LONG_L $14, GDB_FR_REG14(sp) - LONG_L $13, GDB_FR_REG13(sp) - LONG_L $12, GDB_FR_REG12(sp) - LONG_L $11, GDB_FR_REG11(sp) - LONG_L $10, GDB_FR_REG10(sp) - LONG_L $9, GDB_FR_REG9(sp) - LONG_L $8, GDB_FR_REG8(sp) - LONG_L $7, GDB_FR_REG7(sp) - LONG_L $6, GDB_FR_REG6(sp) - LONG_L $5, GDB_FR_REG5(sp) - LONG_L $4, GDB_FR_REG4(sp) - LONG_L $3, GDB_FR_REG3(sp) - LONG_L $2, GDB_FR_REG2(sp) - LONG_L $1, GDB_FR_REG1(sp) -#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) - LONG_L k0, GDB_FR_EPC(sp) - LONG_L $29, GDB_FR_REG29(sp) /* Deallocate stack */ - jr k0 - rfe -#else - LONG_L sp, GDB_FR_REG29(sp) /* Deallocate stack */ - - .set mips3 - eret - .set mips0 -#endif - .set at - .set reorder - END(trap_low) - -LEAF(kgdb_read_byte) -4: lb t0, (a0) - sb t0, (a1) - li v0, 0 - jr ra - .section __ex_table,"a" - PTR 4b, kgdbfault - .previous - END(kgdb_read_byte) - -LEAF(kgdb_write_byte) -5: sb a0, (a1) - li v0, 0 - jr ra - .section __ex_table,"a" - PTR 5b, kgdbfault - .previous - END(kgdb_write_byte) - - .type kgdbfault@function - .ent kgdbfault - -kgdbfault: li v0, -EFAULT - jr ra - .end kgdbfaultdiff -L
arch/mips/kernel/gdb-stub.c-puNarch/mips/kernel/gdb-stub.c~mips-lite/dev/nullarch/mips/kernel/gdb-stub.c deleted +0
-1091@@ -1,1091 +0,0 @@ -/* -* arch/mips/kernel/gdb-stub.c -* -* Originally written by Glenn Engel, Lake Stevens Instrument Division -* -* Contributed by HP Systems -* -* Modified for SPARC by Stu Grossman, Cygnus Support. -* -* Modified for Linux/MIPS (and MIPS in general) by Andreas Busse -* Send complaints, suggestions etc. to <[email protected]> -* -* Copyright (C) 1995 Andreas Busse -* -* Copyright (C) 2003 MontaVista Software Inc. -* Author: Jun Sun, [email protected] or [email protected] -*/ - -/* -* To enable debugger support, two things need to happen. One, a -* call to set_debug_traps() is necessary in order to allow any breakpoints -* or error conditions to be properly intercepted and reported to gdb. -* Two, a breakpoint needs to be generated to begin communication. This -* is most easily accomplished by a call to breakpoint(). Breakpoint() -* simulates a breakpoint by executing a BREAK instruction. -* -* -* The following gdb commands are supported: -* -* command function Return value -* -* g return the value of the CPU registers hex data or ENN -* G set the value of the CPU registers OK or ENN -* -* mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN -* MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN -* -* c Resume at current address SNN ( signal NN) -* cAA..AA Continue at address AA..AA SNN -* -* s Step one instruction SNN -* sAA..AA Step one instruction from AA..AA SNN -* -* k kill -* -* ? What was the last sigval ? SNN (signal NN) -* -* bBB..BB Set baud rate to BB..BB OK or BNN, then sets -* baud rate -* -* All commands and responses are sent with a packet which includes a -* checksum. A packet consists of -* -* $<packet info>#<checksum>. -* -* where -* <packet info> :: <characters representing the command or response> -* <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>> -* -* When a packet is received, it is first acknowledged with either '+' or '-'. -* '+' indicates a successful transfer. '-' indicates a failed transfer. -* -* Example: -* -* Host: Reply: -* $m0,10#2a +$00010203040506070809101112131415#42 -* -* -* ============== -* MORE EXAMPLES: -* ============== -* -* For reference -- the following are the steps that one -* company took (RidgeRun Inc) to get remote gdb debugging -* going. In this scenario the host machine was a PC and the -* target platform was a Galileo EVB64120A MIPS evaluation -* board. -* -* Step 1: -* First download gdb-5.0.tar.gz from the internet. -* and then build/install the package. -* -* Example: -* $ tar zxf gdb-5.0.tar.gz -* $ cd gdb-5.0 -* $ ./configure --target=mips-linux-elf -* $ make -* $ install -* $ which mips-linux-elf-gdb -* /usr/local/bin/mips-linux-elf-gdb -* -* Step 2: -* Configure linux for remote debugging and build it. -* -* Example: -* $ cd ~/linux -* $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging> -* $ make -* -* Step 3: -* Download the kernel to the remote target and start -* the kernel running. It will promptly halt and wait -* for the host gdb session to connect. It does this -* since the "Kernel Hacking" option has defined -* CONFIG_KGDB which in turn enables your calls -* to: -* set_debug_traps(); -* breakpoint(); -* -* Step 4: -* Start the gdb session on the host. -* -* Example: -* $ mips-linux-elf-gdb vmlinux -* (gdb) set remotebaud 115200 -* (gdb) target remote /dev/ttyS1 -* ...at this point you are connected to -* the remote target and can use gdb -* in the normal fasion. Setting -* breakpoints, single stepping, -* printing variables, etc. -*/ -#include <linux/config.h> -#include <linux/string.h> -#include <linux/kernel.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/console.h> -#include <linux/init.h> -#include <linux/smp.h> -#include <linux/spinlock.h> -#include <linux/slab.h> -#include <linux/reboot.h> - -#include <asm/asm.h> -#include <asm/cacheflush.h> -#include <asm/mipsregs.h> -#include <asm/pgtable.h> -#include <asm/system.h> -#include <asm/gdb-stub.h> -#include <asm/inst.h> - -/* -* external low-level support routines -*/ - -extern int putDebugChar (char c);/* write a single character */ -extern char getDebugChar (void );/* read and return a single char */ -extern void trap_low (void ); - -/* -* breakpoint and test functions -*/ -extern void breakpoint (void ); -extern void breakinst (void ); -extern void async_breakpoint (void ); -extern void async_breakinst (void ); -extern void adel (void ); - -/* -* local prototypes -*/ - -static void getpacket (char *buffer); -static void putpacket (char *buffer); -static int computeSignal (int tt); -static int hex (unsigned char ch); -static int hexToInt (char **ptr,int *intValue); -static int hexToLong (char **ptr,long *longValue); -static unsigned char *mem2hex (char *mem,char *buf,int count,int may_fault); -void handle_exception (struct gdb_regs *regs); - -int kgdb_enabled; - -/* -* spin locks for smp case -*/ -static spinlock_t kgdb_lock =SPIN_LOCK_UNLOCKED ; -static spinlock_t kgdb_cpulock[NR_CPUS ] = { [0 ...NR_CPUS -1 ] =SPIN_LOCK_UNLOCKED }; - -/* -* BUFMAX defines the maximum number of characters in inbound/outbound buffers -* at least NUMREGBYTES*2 are needed for register packets -*/ -#define BUFMAX 2048 - -static char input_buffer[BUFMAX ]; -static char output_buffer[BUFMAX ]; -static int initialized;/* !0 means we've been initialized */ -static int kgdb_started; -static const char hexchars[]="0123456789abcdef" ; - -/* Used to prevent crashes in memory access. Note that they'll crash anyway if -we haven't set up fault handlers yet... */ -int kgdb_read_byte (unsigned char *address,unsigned char *dest); -int kgdb_write_byte (unsigned char val,unsigned char *dest); - -/* -* Convert ch from a hex digit to an int -*/ -static int hex (unsigned char ch) -{ -if (ch >='a' && ch <='f' ) -return ch-'a' +10 ; -if (ch >='0' && ch <='9' ) -return ch-'0' ; -if (ch >='A' && ch <='F' ) -return ch-'A' +10 ; -return -1 ; -} - -/* -* scan for the sequence $<data>#<checksum> -*/ -static void getpacket (char *buffer) -{ -unsigned char checksum; -unsigned char xmitcsum; -int i; -int count; -unsigned char ch; - -do { -/* -* wait around for the start character, -* ignore all other characters -*/ -while ((ch = (getDebugChar () &0x7f )) !='$' ) ; - - checksum =0 ; - xmitcsum =-1 ; - count =0 ; - -/* -* now, read until a # or end of buffer is found -*/ -while (count <BUFMAX ) { - ch =getDebugChar (); -if (ch =='#' ) -break ; - checksum = checksum + ch; - buffer[count] = ch; - count = count +1 ; - } - -if (count >=BUFMAX ) -continue ; - - buffer[count] =0 ; - -if (ch =='#' ) { - xmitcsum =hex (getDebugChar () &0x7f ) <<4 ; - xmitcsum |=hex (getDebugChar () &0x7f ); - -if (checksum != xmitcsum) -putDebugChar ('-' );/* failed checksum */ -else { -putDebugChar ('+' );/* successful transfer */ - -/* -* if a sequence char is present, -* reply the sequence ID -*/ -if (buffer[2 ] ==':' ) { -putDebugChar (buffer[0 ]); -putDebugChar (buffer[1 ]); - -/* -* remove sequence chars from buffer -*/ - count =strlen (buffer); -for (i=3 ; i <= count; i++) - buffer[i-3 ] = buffer[i]; - } - } - } - } -while (checksum != xmitcsum); -} - -/* -* send the packet in buffer. -*/ -static void putpacket (char *buffer) -{ -unsigned char checksum; -int count; -unsigned char ch; - -/* -* $<packet info>#<checksum>. -*/ - -do { -putDebugChar ('$' ); - checksum =0 ; - count =0 ; - -while ((ch = buffer[count]) !=0 ) { -if (!(putDebugChar (ch))) -return ; - checksum += ch; - count +=1 ; - } - -putDebugChar ('#' ); -putDebugChar (hexchars[checksum >>4 ]); -putDebugChar (hexchars[checksum &0xf ]); - - } -while ((getDebugChar () &0x7f ) !='+' ); -} - - -/* -* Convert the memory pointed to by mem into hex, placing result in buf. -* Return a pointer to the last char put in buf (null), in case of mem fault, -* return 0. -* may_fault is non-zero if we are reading from arbitrary memory, but is currently -* not used. -*/ -static unsigned char *mem2hex (char *mem,char *buf,int count,int may_fault) -{ -unsigned char ch; - -while (count-- >0 ) { -if (kgdb_read_byte (mem++, &ch) !=0 ) -return 0 ; - *buf++ = hexchars[ch >>4 ]; - *buf++ = hexchars[ch &0xf ]; - } - - *buf =0 ; - -return buf; -} - -/* -* convert the hex array pointed to by buf into binary to be placed in mem -* return a pointer to the character AFTER the last byte written -* may_fault is non-zero if we are reading from arbitrary memory, but is currently -* not used. -*/ -static char *hex2mem (char *buf,char *mem,int count,int binary,int may_fault) -{ -int i; -unsigned char ch; - -for (i=0 ; i<count; i++) - { -if (binary) { - ch = *buf++; -if (ch ==0x7d ) - ch =0x20 ^ *buf++; - } -else { - ch =hex (*buf++) <<4 ; - ch |=hex (*buf++); - } -if (kgdb_write_byte (ch, mem++) !=0 ) -return 0 ; - } - -return mem; -} - -/* -* This table contains the mapping between SPARC hardware trap types, and -* signals, which are primarily what GDB understands. It also indicates -* which hardware traps we need to commandeer when initializing the stub. -*/ -static struct hard_trap_info { -unsigned char tt;/* Trap type code for MIPS R3xxx and R4xxx */ -unsigned char signo;/* Signal that we map this trap into */ -} hard_trap_info[] = { - {6 ,SIGBUS },/* instruction bus error */ - {7 ,SIGBUS },/* data bus error */ - {9 ,SIGTRAP },/* break */ - {10 ,SIGILL },/* reserved instruction */ -/* { 11, SIGILL }, */ /* CPU unusable */ - {12 ,SIGFPE },/* overflow */ - {13 ,SIGTRAP },/* trap */ - {14 ,SIGSEGV },/* virtual instruction cache coherency */ - {15 ,SIGFPE },/* floating point exception */ - {23 ,SIGSEGV },/* watch */ - {31 ,SIGSEGV },/* virtual data cache coherency */ - {0 ,0 }/* Must be last */ -}; - -/* Save the normal trap handlers for user-mode traps. */ -void *saved_vectors[32 ]; - -/* -* Set up exception handlers for tracing and breakpoints -*/ -void set_debug_traps (void ) -{ -struct hard_trap_info *ht; -unsigned long flags; -unsigned char c; - -local_irq_save (flags); -for (ht = hard_trap_info; ht->tt && ht->signo; ht++) - saved_vectors[ht->tt] =set_except_vector (ht->tt, trap_low); - -putDebugChar ('+' );/* 'hello world' */ -/* -* In case GDB is started before us, ack any packets -* (presumably "$?#xx") sitting there. -*/ -while ((c =getDebugChar ()) !='$' ); -while ((c =getDebugChar ()) !='#' ); - c =getDebugChar ();/* eat first csum byte */ - c =getDebugChar ();/* eat second csum byte */ -putDebugChar ('+' );/* ack it */ - - initialized =1 ; -local_irq_restore (flags); -} - -void restore_debug_traps (void ) -{ -struct hard_trap_info *ht; -unsigned long flags; - -local_irq_save (flags); -for (ht = hard_trap_info; ht->tt && ht->signo; ht++) -set_except_vector (ht->tt, saved_vectors[ht->tt]); -local_irq_restore (flags); -} - -/* -* Convert the MIPS hardware trap type code to a Unix signal number. -*/ -static int computeSignal (int tt) -{ -struct hard_trap_info *ht; - -for (ht = hard_trap_info; ht->tt && ht->signo; ht++) -if (ht->tt == tt) -return ht->signo; - -return SIGHUP ;/* default for things we don't know about */ -} - -/* -* While we find nice hex chars, build an int. -* Return number of chars processed. -*/ -static int hexToInt (char **ptr,int *intValue) -{ -int numChars =0 ; -int hexValue; - - *intValue =0 ; - -while (**ptr) { - hexValue =hex (**ptr); -if (hexValue <0 ) -break ; - - *intValue = (*intValue <<4 ) | hexValue; - numChars ++; - - (*ptr)++; - } - -return (numChars); -} - -static int hexToLong (char **ptr,long *longValue) -{ -int numChars =0 ; -int hexValue; - - *longValue =0 ; - -while (**ptr) { - hexValue =hex (**ptr); -if (hexValue <0 ) -break ; - - *longValue = (*longValue <<4 ) | hexValue; - numChars ++; - - (*ptr)++; - } - -return numChars; -} - - -#if 0 -/* -* Print registers (on target console) -* Used only to debug the stub... -*/ -void show_gdbregs (struct gdb_regs * regs) -{ -/* -* Saved main processor registers -*/ -printk ("$0 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n" , - regs->reg0, regs->reg1, regs->reg2, regs->reg3, - regs->reg4, regs->reg5, regs->reg6, regs->reg7); -printk ("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n" , - regs->reg8, regs->reg9, regs->reg10, regs->reg11, - regs->reg12, regs->reg13, regs->reg14, regs->reg15); -printk ("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n" , - regs->reg16, regs->reg17, regs->reg18, regs->reg19, - regs->reg20, regs->reg21, regs->reg22, regs->reg23); -printk ("$24: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n" , - regs->reg24, regs->reg25, regs->reg26, regs->reg27, - regs->reg28, regs->reg29, regs->reg30, regs->reg31); - -/* -* Saved cp0 registers -*/ -printk ("epc : %08lx\nStatus: %08lx\nCause : %08lx\n" , - regs->cp0_epc, regs->cp0_status, regs->cp0_cause); -} -#endif /* dead code */ - -/* -* We single-step by setting breakpoints. When an exception -* is handled, we need to restore the instructions hoisted -* when the breakpoints were set. -* -* This is where we save the original instructions. -*/ -static struct gdb_bp_save { -unsigned long addr; -unsigned int val; -} step_bp[2 ]; - -#define BP 0x0000000d/* break opcode */ - -/* -* Set breakpoint instructions for single stepping. -*/ -static void single_step (struct gdb_regs *regs) -{ -union mips_instruction insn; -unsigned long targ; -int is_branch, is_cond, i; - - targ = regs->cp0_epc; - insn.word = *(unsigned int *)targ; - is_branch = is_cond =0 ; - -switch (insn.i_format.opcode) { -/* -* jr and jalr are in r_format format. -*/ -case spec_op: -switch (insn.r_format.func) { -case jalr_op: -case jr_op: - targ = *(®s->reg0 + insn.r_format.rs); - is_branch =1 ; -break ; - } -break ; - -/* -* This group contains: -* bltz_op, bgez_op, bltzl_op, bgezl_op, -* bltzal_op, bgezal_op, bltzall_op, bgezall_op. -*/ -case bcond_op: - is_branch = is_cond =1 ; - targ +=4 + (insn.i_format.simmediate <<2 ); -break ; - -/* -* These are unconditional and in j_format. -*/ -case jal_op: -case j_op: - is_branch =1 ; - targ +=4 ; - targ >>=28 ; - targ <<=28 ; - targ |= (insn.j_format.target <<2 ); -break ; - -/* -* These are conditional. -*/ -case beq_op: -case beql_op: -case bne_op: -case bnel_op: -case blez_op: -case blezl_op: -case bgtz_op: -case bgtzl_op: -case cop0_op: -case cop1_op: -case cop2_op: -case cop1x_op: - is_branch = is_cond =1 ; - targ +=4 + (insn.i_format.simmediate <<2 ); -break ; - } - -if (is_branch) { - i =0 ; -if (is_cond && targ != (regs->cp0_epc +8 )) { - step_bp[i].addr = regs->cp0_epc +8 ; - step_bp[i++].val = *(unsigned *)(regs->cp0_epc +8 ); - *(unsigned *)(regs->cp0_epc +8 ) =BP ; - } - step_bp[i].addr = targ; - step_bp[i].val = *(unsigned *)targ; - *(unsigned *)targ =BP ; - }else { - step_bp[0 ].addr = regs->cp0_epc +4 ; - step_bp[0 ].val = *(unsigned *)(regs->cp0_epc +4 ); - *(unsigned *)(regs->cp0_epc +4 ) =BP ; - } -} - -/* -* If asynchronously interrupted by gdb, then we need to set a breakpoint -* at the interrupted instruction so that we wind up stopped with a -* reasonable stack frame. -*/ -static struct gdb_bp_save async_bp; - -/* -* Swap the interrupted EPC with our asynchronous breakpoint routine. -* This is safer than stuffing the breakpoint in-place, since no cache -* flushes (or resulting smp_call_functions) are required. The -* assumption is that only one CPU will be handling asynchronous bp's, -* and only one can be active at a time. -*/ -extern spinlock_t smp_call_lock; -void set_async_breakpoint (unsigned long *epc) -{ -/* skip breaking into userland */ -if ((*epc &0x80000000 ) ==0 ) -return ; - -/* avoid deadlock if someone is make IPC */ -if (spin_is_locked (&smp_call_lock)) -return ; - - async_bp.addr = *epc; - *epc = (unsigned long )async_breakpoint; -} - -void kgdb_wait (void *arg) -{ -unsigned flags; -int cpu =smp_processor_id (); - -local_irq_save (flags); - -spin_lock (&kgdb_cpulock[cpu]); -spin_unlock (&kgdb_cpulock[cpu]); - -local_irq_restore (flags); -} - - -/* -* This function does all command processing for interfacing to gdb. It -* returns 1 if you should skip the instruction at the trap address, 0 -* otherwise. -*/ -void handle_exception (struct gdb_regs *regs) -{ -int trap;/* Trap type */ -int sigval; -long addr; -int length; -char *ptr; -unsigned long *stack; -int i; -int bflag =0 ; - - kgdb_started =1 ; - -/* -* acquire the big kgdb spinlock -*/ -if (!spin_trylock (&kgdb_lock)) { -/* -* some other CPU has the lock, we should go back to -* receive the gdb_wait IPC -*/ -return ; - } - -/* -* If we're in async_breakpoint(), restore the real EPC from -* the breakpoint. -*/ -if (regs->cp0_epc == (unsigned long )async_breakinst) { - regs->cp0_epc = async_bp.addr; - async_bp.addr =0 ; - } - -/* -* acquire the CPU spinlocks -*/ -for (i =num_online_cpus ()-1 ; i >=0 ; i--) -if (spin_trylock (&kgdb_cpulock[i]) ==0 ) -panic ("kgdb: couldn't get cpulock %d\n" , i); - -/* -* force other cpus to enter kgdb -*/ -smp_call_function (kgdb_wait,NULL ,0 ,0 ); - -/* -* If we're in breakpoint() increment the PC -*/ - trap = (regs->cp0_cause &0x7c ) >>2 ; -if (trap ==9 && regs->cp0_epc == (unsigned long )breakinst) - regs->cp0_epc +=4 ; - -/* -* If we were single_stepping, restore the opcodes hoisted -* for the breakpoint[s]. -*/ -if (step_bp[0 ].addr) { - *(unsigned *)step_bp[0 ].addr = step_bp[0 ].val; - step_bp[0 ].addr =0 ; - -if (step_bp[1 ].addr) { - *(unsigned *)step_bp[1 ].addr = step_bp[1 ].val; - step_bp[1 ].addr =0 ; - } - } - - stack = (long *)regs->reg29;/* stack ptr */ - sigval =computeSignal (trap); - -/* -* reply to host that an exception has occurred -*/ - ptr = output_buffer; - -/* -* Send trap type (converted to signal) -*/ - *ptr++ ='T' ; - *ptr++ = hexchars[sigval >>4 ]; - *ptr++ = hexchars[sigval &0xf ]; - -/* -* Send Error PC -*/ - *ptr++ = hexchars[REG_EPC >>4 ]; - *ptr++ = hexchars[REG_EPC &0xf ]; - *ptr++ =':' ; - ptr =mem2hex ((char *)®s->cp0_epc, ptr,sizeof (long ),0 ); - *ptr++ =';' ; - -/* -* Send frame pointer -*/ - *ptr++ = hexchars[REG_FP >>4 ]; - *ptr++ = hexchars[REG_FP &0xf ]; - *ptr++ =':' ; - ptr =mem2hex ((char *)®s->reg30, ptr,sizeof (long ),0 ); - *ptr++ =';' ; - -/* -* Send stack pointer -*/ - *ptr++ = hexchars[REG_SP >>4 ]; - *ptr++ = hexchars[REG_SP &0xf ]; - *ptr++ =':' ; - ptr =mem2hex ((char *)®s->reg29, ptr,sizeof (long ),0 ); - *ptr++ =';' ; - - *ptr++ =0 ; -putpacket (output_buffer);/* send it off... */ - -/* -* Wait for input from remote GDB -*/ -while (1 ) { - output_buffer[0 ] =0 ; -getpacket (input_buffer); - -switch (input_buffer[0 ]) - { -case '?' : - output_buffer[0 ] ='S' ; - output_buffer[1 ] = hexchars[sigval >>4 ]; - output_buffer[2 ] = hexchars[sigval &0xf ]; - output_buffer[3 ] =0 ; -break ; - -/* -* Detach debugger; let CPU run -*/ -case 'D' : -putpacket (output_buffer); - goto finish_kgdb; -break ; - -case 'd' : -/* toggle debug flag */ -break ; - -/* -* Return the value of the CPU registers -*/ -case 'g' : - ptr = output_buffer; - ptr =mem2hex ((char *)®s->reg0, ptr,32 *sizeof (long ),0 );/* r0...r31 */ - ptr =mem2hex ((char *)®s->cp0_status, ptr,6 *sizeof (long ),0 );/* cp0 */ - ptr =mem2hex ((char *)®s->fpr0, ptr,32 *sizeof (long ),0 );/* f0...31 */ - ptr =mem2hex ((char *)®s->cp1_fsr, ptr,2 *sizeof (long ),0 );/* cp1 */ - ptr =mem2hex ((char *)®s->frame_ptr, ptr,2 *sizeof (long ),0 );/* frp */ - ptr =mem2hex ((char *)®s->cp0_index, ptr,16 *sizeof (long ),0 );/* cp0 */ -break ; - -/* -* set the value of the CPU registers - return OK -*/ -case 'G' : - { - ptr = &input_buffer[1 ]; -hex2mem (ptr, (char *)®s->reg0,32 *sizeof (long ),0 ,0 ); - ptr +=32 *(2 *sizeof (long )); -hex2mem (ptr, (char *)®s->cp0_status,6 *sizeof (long ),0 ,0 ); - ptr +=6 *(2 *sizeof (long )); -hex2mem (ptr, (char *)®s->fpr0,32 *sizeof (long ),0 ,0 ); - ptr +=32 *(2 *sizeof (long )); -hex2mem (ptr, (char *)®s->cp1_fsr,2 *sizeof (long ),0 ,0 ); - ptr +=2 *(2 *sizeof (long )); -hex2mem (ptr, (char *)®s->frame_ptr,2 *sizeof (long ),0 ,0 ); - ptr +=2 *(2 *sizeof (long )); -hex2mem (ptr, (char *)®s->cp0_index,16 *sizeof (long ),0 ,0 ); -strcpy (output_buffer,"OK" ); - } -break ; - -/* -* mAA..AA,LLLL Read LLLL bytes at address AA..AA -*/ -case 'm' : - ptr = &input_buffer[1 ]; - -if (hexToLong (&ptr, &addr) - && *ptr++ ==',' - &&hexToInt (&ptr, &length)) { -if (mem2hex ((char *)addr, output_buffer, length,1 )) -break ; -strcpy (output_buffer,"E03" ); - }else -strcpy (output_buffer,"E01" ); -break ; - -/* -* XAA..AA,LLLL: Write LLLL escaped binary bytes at address AA.AA -*/ -case 'X' : - bflag =1 ; -/* fall through */ - -/* -* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK -*/ -case 'M' : - ptr = &input_buffer[1 ]; - -if (hexToLong (&ptr, &addr) - && *ptr++ ==',' - &&hexToInt (&ptr, &length) - && *ptr++ ==':' ) { -if (hex2mem (ptr, (char *)addr, length, bflag,1 )) -strcpy (output_buffer,"OK" ); -else -strcpy (output_buffer,"E03" ); - } -else -strcpy (output_buffer,"E02" ); -break ; - -/* -* cAA..AA Continue at address AA..AA(optional) -*/ -case 'c' : -/* try to read optional parameter, pc unchanged if no parm */ - - ptr = &input_buffer[1 ]; -if (hexToLong (&ptr, &addr)) - regs->cp0_epc = addr; - - goto exit_kgdb_exception; -break ; - -/* -* kill the program; let us try to restart the machine -* Reset the whole machine. -*/ -case 'k' : -case 'r' : -machine_restart ("kgdb restarts machine" ); -break ; - -/* -* Step to next instruction -*/ -case 's' : -/* -* There is no single step insn in the MIPS ISA, so we -* use breakpoints and continue, instead. -*/ -single_step (regs); - goto exit_kgdb_exception; -/* NOTREACHED */ -break ; - -/* -* Set baud rate (bBB) -* FIXME: Needs to be written -*/ -case 'b' : - { -#if 0 -int baudrate; -extern void set_timer_3 (); - - ptr = &input_buffer[1 ]; -if (!hexToInt (&ptr, &baudrate)) - { -strcpy (output_buffer,"B01" ); -break ; - } - -/* Convert baud rate to uart clock divider */ - -switch (baudrate) - { -case 38400 : - baudrate =16 ; -break ; -case 19200 : - baudrate =33 ; -break ; -case 9600 : - baudrate =65 ; -break ; -default : - baudrate =0 ; -strcpy (output_buffer,"B02" ); - goto x1; - } - -if (baudrate) { -putpacket ("OK" );/* Ack before changing speed */ -set_timer_3 (baudrate);/* Set it */ - } -#endif - } -break ; - - }/* switch */ - -/* -* reply to the request -*/ - -putpacket (output_buffer); - - }/* while */ - -return ; - -finish_kgdb: -restore_debug_traps (); - -exit_kgdb_exception: -/* release locks so other CPUs can go */ -for (i =num_online_cpus ()-1 ; i >=0 ; i--) -spin_unlock (&kgdb_cpulock[i]); -spin_unlock (&kgdb_lock); - -__flush_cache_all (); -return ; -} - -/* -* This function will generate a breakpoint exception. It is used at the -* beginning of a program to sync up with a debugger and can be used -* otherwise as a quick means to stop program execution and "break" into -* the debugger. -*/ -void breakpoint (void ) -{ -if (!initialized) -return ; - - __asm__ __volatile__( -".globl breakinst\n\t" -".set\tnoreorder\n\t" -"nop\n" -"breakinst:\tbreak\n\t" -"nop\n\t" -".set\treorder" - ); -} - -/* Nothing but the break; don't pollute any registers */ -void async_breakpoint (void ) -{ - __asm__ __volatile__( -".globl async_breakinst\n\t" -".set\tnoreorder\n\t" -"nop\n" -"async_breakinst:\tbreak\n\t" -"nop\n\t" -".set\treorder" - ); -} - -void adel (void ) -{ - __asm__ __volatile__( -".globl\tadel\n\t" -"lui\t$8,0x8000\n\t" -"lw\t$9,1($8)\n\t" - ); -} - -/* -* malloc is needed by gdb client in "call func()", even a private one -* will make gdb happy -*/ -static void *malloc (size_t size) -{ -return kmalloc (size,GFP_ATOMIC ); -} - -static void free (void *where) -{ -kfree (where); -} - -#ifdef CONFIG_GDB_CONSOLE - -void gdb_putsn (const char *str,int l) -{ -char outbuf[18 ]; - -if (!kgdb_started) -return ; - - outbuf[0 ]='O' ; - -while (l) { -int i = (l>8 )?8 :l; -mem2hex ((char *)str, &outbuf[1 ], i,0 ); - outbuf[(i*2 )+1 ]=0 ; -putpacket (outbuf); - str += i; - l -= i; - } -} - -static void gdb_console_write (struct console *con,const char *s,unsigned n) -{ -gdb_putsn (s, n); -} - -static struct console gdb_console = { - .name ="gdb" , - .write = gdb_console_write, - .flags =CON_PRINTBUFFER , - .index =-1 -}; - -static int __init register_gdb_console (void ) -{ -register_console (&gdb_console); - -return 0 ; -} - -console_initcall (register_gdb_console); - -#endif diff -puN
arch/mips/kernel/irq.c~mips-litearch/mips/kernel/irq.carch/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 }diff -puN
/dev/nullarch/mips/kernel/kgdb.carch/mips/kernel/kgdb.c new file +292
-0@@ -0,0 +1,292 @@ +/* +* arch/mips/kernel/kgdb.c +* +* Originally written by Glenn Engel, Lake Stevens Instrument Division +* +* Contributed by HP Systems +* +* Modified for SPARC by Stu Grossman, Cygnus Support. +* +* Modified for Linux/MIPS (and MIPS in general) by Andreas Busse +* Send complaints, suggestions etc. to <[email protected]> +* +* Copyright (C) 1995 Andreas Busse +* +* Copyright (C) 2003 MontaVista Software Inc. +* Author: Jun Sun, [email protected] or [email protected] +* +* Copyright (C) 2004-2005 MontaVista Software Inc. +* Author: Manish Lachwani, [email protected] or [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. +*/ + +#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/system.h> +#include <asm/ptrace.h> /* for linux pt_regs struct */ +#include <linux/kgdb.h> +#include <linux/init.h> +#include <asm/inst.h> +#include <asm/gdb-stub.h> +#include <asm/cacheflush.h> +#include <asm/kdebug.h> + +static struct hard_trap_info { +unsigned char tt;/* Trap type code for MIPS R3xxx and R4xxx */ +unsigned char signo;/* Signal that we map this trap into */ +} hard_trap_info[] = { + {6 ,SIGBUS },/* instruction bus error */ + {7 ,SIGBUS },/* data bus error */ + {9 ,SIGTRAP },/* break */ +/* { 11, SIGILL }, */ /* CPU unusable */ + {12 ,SIGFPE },/* overflow */ + {13 ,SIGTRAP },/* trap */ + {14 ,SIGSEGV },/* virtual instruction cache coherency */ + {15 ,SIGFPE },/* floating point exception */ + {23 ,SIGSEGV },/* watch */ + {31 ,SIGSEGV },/* virtual data cache coherency */ + {0 ,0 }/* Must be last */ +}; + +/* Save the normal trap handlers for user-mode traps. */ +void *saved_vectors[32 ]; + +extern void trap_low (void ); +extern void breakinst (void ); +extern void init_IRQ (void ); + +void kgdb_call_nmi_hook (void *ignored) +{ +kgdb_nmihook (smp_processor_id (), (void *)0 ); +} + +void kgdb_roundup_cpus (unsigned long flags) +{ +local_irq_restore (flags); +smp_call_function (kgdb_call_nmi_hook,0 ,0 ,0 ); +local_irq_save (flags); +} + +static int compute_signal (int tt) +{ +struct hard_trap_info *ht; + +for (ht = hard_trap_info; ht->tt && ht->signo; ht++) +if (ht->tt == tt) +return ht->signo; + +return SIGHUP ;/* default for things we don't know about */ +} + +/* +* Set up exception handlers for tracing and breakpoints +*/ +void handle_exception (struct pt_regs *regs) +{ +int trap = (regs->cp0_cause &0x7c ) >>2 ; + +if (atomic_read (&debugger_active)) +kgdb_nmihook (smp_processor_id (), regs); + +if (atomic_read (&kgdb_setting_breakpoint)) +if ((trap ==9 ) && (regs->cp0_epc == (unsigned long )breakinst)) + regs->cp0_epc +=4 ; + +kgdb_handle_exception (0 ,compute_signal (trap),0 , regs); + +/* In SMP mode, __flush_cache_all does IPI */ +__flush_cache_all (); +} + +void set_debug_traps (void ) +{ +struct hard_trap_info *ht; +unsigned long flags; + +local_irq_save (flags); + +for (ht = hard_trap_info; ht->tt && ht->signo; ht++) + saved_vectors[ht->tt] =set_except_vector (ht->tt, trap_low); + +local_irq_restore (flags); +} + +#if 0 +/* This should be called before we exit kgdb_handle_exception() I believe. +* -- Tom +*/ +void restore_debug_traps (void ) +{ +struct hard_trap_info *ht; +unsigned long flags; + +local_irq_save (flags); +for (ht = hard_trap_info; ht->tt && ht->signo; ht++) +set_except_vector (ht->tt, saved_vectors[ht->tt]); +local_irq_restore (flags); +} +#endif + +void regs_to_gdb_regs (unsigned long *gdb_regs,struct pt_regs *regs) +{ +int reg =0 ; +unsigned long *ptr = gdb_regs; + +for (reg =0 ; reg <32 ; reg++) + *(ptr++) = regs->regs[reg]; + + *(ptr++) = regs->cp0_status; + *(ptr++) = regs->lo; + *(ptr++) = regs->hi; + *(ptr++) = regs->cp0_badvaddr; + *(ptr++) = regs->cp0_cause; + *(ptr++) = regs->cp0_epc; + +return ; +} + +void gdb_regs_to_regs (unsigned long *gdb_regs,struct pt_regs *regs) +{ +int reg =0 ; +unsigned long *ptr = gdb_regs; + +for (reg =0 ; reg <32 ; reg++) + regs->regs[reg] = *(ptr++); + + regs->cp0_status = *(ptr++); + regs->lo = *(ptr++); + regs->hi = *(ptr++); + regs->cp0_badvaddr = *(ptr++); + regs->cp0_cause = *(ptr++); + regs->cp0_epc = *(ptr++); + +return ; +} + +/* +* Similar to regs_to_gdb_regs() except that process is sleeping and so +* we may not be able to get all the info. +*/ +void sleeping_thread_to_gdb_regs (unsigned long *gdb_regs,struct task_struct *p) +{ +int reg =0 ; +struct thread_info *ti = p->thread_info; +unsigned long ksp = (unsigned long )ti +THREAD_SIZE -32 ; +struct pt_regs *regs = (struct pt_regs *)ksp -1 ; +unsigned long *ptr = gdb_regs; + +for (reg =0 ; reg <16 ; reg++) + *(ptr++) = regs->regs[reg]; + +/* S0 - S7 */ +for (reg =16 ; reg <24 ; reg++) + *(ptr++) = regs->regs[reg]; + +for (reg =24 ; reg <28 ; reg++) + *(ptr++) =0 ; + +/* GP, SP, FP, RA */ +for (reg =28 ; reg <32 ; reg++) + *(ptr++) = regs->regs[reg]; + + *(ptr++) = regs->cp0_status; + *(ptr++) = regs->lo; + *(ptr++) = regs->hi; + *(ptr++) = regs->cp0_badvaddr; + *(ptr++) = regs->cp0_cause; + *(ptr++) = regs->cp0_epc; + +return ; +} + +/* +* Calls linux_debug_hook before the kernel dies. If KGDB is enabled, +* then try to fall into the debugger +*/ +static int kgdb_mips_notify (struct notifier_block *self,unsigned long cmd, +void *ptr) +{ +struct die_args *args = (struct die_args *)ptr; +struct pt_regs *regs = args->regs; +int trap = (regs->cp0_cause &0x7c ) >>2 ; + +/* See if KGDB is interested. */ +if (user_mode (regs)) +/* Userpace events, ignore. */ +return NOTIFY_DONE ; + +kgdb_handle_exception (trap,compute_signal (trap),0 , regs); +return NOTIFY_OK ; +} + +static struct notifier_block kgdb_notifier = { + .notifier_call = kgdb_mips_notify, +}; + +/* +* Handle the 's' and 'c' commands +*/ +int kgdb_arch_handle_exception (int vector,int signo,int err_code, +char *remcom_in_buffer,char *remcom_out_buffer, +struct pt_regs *regs) +{ +char *ptr; +unsigned long address; +int cpu =smp_processor_id (); + +switch (remcom_in_buffer[0 ]) { +case 's' : +case 'c' : +/* handle the optional parameter */ + ptr = &remcom_in_buffer[1 ]; +if (kgdb_hex2long (&ptr, &address)) + regs->cp0_epc = address; + +atomic_set (&cpu_doing_single_step,-1 ); +if (remcom_in_buffer[0 ] =='s' ) +if (kgdb_contthread) +atomic_set (&cpu_doing_single_step, cpu); + +return 0 ; + } + +return -1 ; +} + +struct kgdb_arch arch_kgdb_ops = { +#ifdef CONFIG_CPU_LITTLE_ENDIAN + .gdb_bpt_instr = {0xd}, +#else + .gdb_bpt_instr = {0x00 ,0x00 ,0x00 ,0x0d }, +#endif +}; + +/* +* We use kgdb_early_setup so that functions we need to call now don't +* cause trouble when called again later. +*/ +int kgdb_arch_init (void ) +{ +/* Board-specifics. */ +/* Force some calls to happen earlier. */ +if (kgdb_early_setup ==0 ) { +trap_init (); +init_IRQ (); + kgdb_early_setup =1 ; + } + +/* Set our traps. */ +/* This needs to be done more finely grained again, paired in +* a before/after in kgdb_handle_exception(...) -- Tom */ +set_debug_traps (); +notifier_chain_register (&mips_die_chain, &kgdb_notifier); + +return 0 ; +}diff -puN
/dev/nullarch/mips/kernel/kgdb_handler.Sarch/mips/kernel/kgdb_handler.S new file +58
-0@@ -0,0 +1,58 @@ +/* + * arch/mips/kernel/kgdb_handler.S + * + * Copyright (C) 2004 MontaVista Software Inc. + * Author: Manish Lachwani, [email protected] or [email protected] + * + * This file is licensed under the terms of the GNU General Public + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/* + * Trap Handler for the new KGDB framework. The main KGDB handler is + * handle_exception that will be called from here + * + */ + +#include <linux/config.h> +#include <linux/sys.h> + +#include <asm/asm.h> +#include <asm/errno.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + + .align 5 + NESTED(trap_low, PT_SIZE, sp) + .set noat + .set noreorder + SAVE_ALL + /* + * Check for privileged instructions in user mode. For + * this, check the cu0 bit in the CPU status register. + */ + mfc0 k0, CP0_STATUS + sll k0, 3 + bltz k0, 1f + move k1, sp + + /* + * GDB userland from within KGDB. If a user mode address + * then jump to the saved exception handler + */ + lui k1, %hi(saved_vectors) + mfc0 k0, CP0_CAUSE + andi k0, k0, 0x7c + add k1, k1, k0 + lw k0, %lo(saved_vectors)(k1) + jr k0 + nop +1: + .set at + .set reorder + move a0, sp + jal handle_exception + j ret_from_exception + END(trap_low)diff -puN
/dev/nullarch/mips/kernel/kgdb-jmp.carch/mips/kernel/kgdb-jmp.c new file +62
-0@@ -0,0 +1,62 @@ +/* +* 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. +* +* Author: Tom Rini <[email protected]> +* +* Cribbed from glibc, which carries the following: +* Copyright (C) 1996, 1997, 2000, 2002, 2003 Free Software Foundation, Inc. +* Copyright (C) 2005 by MontaVista Software. +* +* 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/kgdb.h> +#include <asm/interrupt.h> + +int kgdb_fault_setjmp_aux (unsigned long *curr_context,int sp,int fp) +{ + __asm__ __volatile__("sw $gp, %0" : :"m" (curr_context[0 ])); + __asm__ __volatile__("sw $16, %0" : :"m" (curr_context[1 ])); + __asm__ __volatile__("sw $17, %0" : :"m" (curr_context[2 ])); + __asm__ __volatile__("sw $18, %0" : :"m" (curr_context[3 ])); + __asm__ __volatile__("sw $19, %0" : :"m" (curr_context[4 ])); + __asm__ __volatile__("sw $20, %0" : :"m" (curr_context[5 ])); + __asm__ __volatile__("sw $21, %0" : :"m" (curr_context[6 ])); + __asm__ __volatile__("sw $22, %0" : :"m" (curr_context[7 ])); + __asm__ __volatile__("sw $23, %0" : :"m" (curr_context[8 ])); + __asm__ __volatile__("sw $31, %0" : :"m" (curr_context[9 ])); + curr_context[10 ] = (long *)sp; + curr_context[11 ] = (long *)fp; + +return 0 ; +} + +void kgdb_fault_longjmp (unsigned long *curr_context) +{ +unsigned long sp_val, fp_val; + + __asm__ __volatile__("lw $gp, %0" : :"m" (curr_context[0 ])); + __asm__ __volatile__("lw $16, %0" : :"m" (curr_context[1 ])); + __asm__ __volatile__("lw $17, %0" : :"m" (curr_context[2 ])); + __asm__ __volatile__("lw $18, %0" : :"m" (curr_context[3 ])); + __asm__ __volatile__("lw $19, %0" : :"m" (curr_context[4 ])); + __asm__ __volatile__("lw $20, %0" : :"m" (curr_context[5 ])); + __asm__ __volatile__("lw $21, %0" : :"m" (curr_context[6 ])); + __asm__ __volatile__("lw $22, %0" : :"m" (curr_context[7 ])); + __asm__ __volatile__("lw $23, %0" : :"m" (curr_context[8 ])); + __asm__ __volatile__("lw $25, %0" : :"m" (curr_context[9 ])); + sp_val = curr_context[10 ]; + fp_val = curr_context[11 ]; + __asm__ __volatile__("lw $29, %0\n\t" +"lw $30, %1\n\t" : :"m" (sp_val),"m" (fp_val)); + + __asm__ __volatile__("li $2, 1" ); + __asm__ __volatile__("jr $25" ); + +for (;;); +}diff -puN
/dev/nullarch/mips/kernel/kgdb-setjmp.Sarch/mips/kernel/kgdb-setjmp.S new file +23
-0@@ -0,0 +1,23 @@ +/* + * 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. + * + * 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 + j kgdb_fault_setjmp_aux + .end kgdb_fault_setjmpdiff -puN
arch/mips/kernel/Makefile~mips-litearch/mips/kernel/Makefilearch/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.odiff -puN
arch/mips/kernel/traps.c~mips-litearch/mips/kernel/traps.carch/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 ();/* diff -puN
arch/mips/mips-boards/generic/init.c~mips-litearch/mips/mips-boards/generic/init.carch/mips/mips-boards/generic/init.c renamed from arch/mips/mips-boards/generic/init.c~mips-lite +0
-62@@ -35,15 +35,6 @@#include <asm/mips-boards/malta.h> #endif -#ifdef CONFIG_KGDB -extern int rs_kgdb_hook (int ,int ); -extern int rs_putDebugChar (char ); -extern char rs_getDebugChar (void ); -extern int saa9730_kgdb_hook (int ); -extern int saa9730_putDebugChar (char ); -extern char saa9730_getDebugChar (void ); -#endif -int prom_argc;int *_prom_argv, *_prom_envp;@@ -170,59 +161,6 @@ static void __init console_config(void) }#endif -#ifdef CONFIG_KGDB -void __init kgdb_config (void ) -{ -extern int (*generic_putDebugChar)(char ); -extern char (*generic_getDebugChar)(void ); -char *argptr; -int line, speed; - - argptr =prom_getcmdline (); -if ((argptr =strstr (argptr,"kgdb=ttyS" )) !=NULL ) { - argptr +=strlen ("kgdb=ttyS" ); -if (*argptr !='0' && *argptr !='1' ) -printk ("KGDB: Unknown serial line /dev/ttyS%c, " -"falling back to /dev/ttyS1\n" , *argptr); - line = *argptr =='0' ?0 :1 ; -printk ("KGDB: Using serial line /dev/ttyS%d for session\n" , line); - - speed =0 ; -if (*++argptr ==',' ) - { -int c; -while ((c = *++argptr) && ('0' <= c && c <='9' )) - speed = speed *10 + c -'0' ; - } -#ifdef CONFIG_MIPS_ATLAS -if (line ==1 ) { - speed =saa9730_kgdb_hook (speed); - generic_putDebugChar = saa9730_putDebugChar; - generic_getDebugChar = saa9730_getDebugChar; - } - else -#endif - { - speed =rs_kgdb_hook (line, speed); - generic_putDebugChar = rs_putDebugChar; - generic_getDebugChar = rs_getDebugChar; - } - -prom_printf ("KGDB: Using serial line /dev/ttyS%d at %d for session, " -"please connect your debugger\n" , line ?1 :0 , speed); - - { -char *s; -for (s ="Please connect GDB to this port\r\n" ; *s; ) -generic_putDebugChar (*s++); - } - - kgdb_enabled =1 ; -/* Breakpoint is invoked after interrupts are initialised */ - } -} -#endif -void __init prom_init (void ) { prom_argc = fw_arg0;diff -puN
arch/mips/mips-boards/generic/Makefile~mips-litearch/mips/mips-boards/generic/Makefilearch/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)diff -puN
arch/mips/mips-boards/malta/malta_setup.c~mips-litearch/mips/mips-boards/malta/malta_setup.carch/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 )) {diff -puN
arch/mips/mm/extable.c~mips-litearch/mips/mm/extable.carch/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 ; }diff -puN
arch/mips/sibyte/cfe/setup.c~mips-litearch/mips/sibyte/cfe/setup.carch/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;diff -puN
arch/mips/sibyte/sb1250/irq.c~mips-litearch/mips/sibyte/sb1250/irq.carch/mips/sibyte/sb1250/irq.c renamed from arch/mips/sibyte/sb1250/irq.c~mips-lite +6
-51@@ -31,6 +31,7 @@#include <asm/system.h> #include <asm/ptrace.h> #include <asm/io.h> +#include <asm/kgdb.h> #include <asm/sibyte/sb1250_regs.h> #include <asm/sibyte/sb1250_int.h> @@ -60,16 +61,6 @@ static void sb1250_set_affinity(unsignedextern unsigned long ldt_eoi_space;#endif -#ifdef CONFIG_KGDB -static int kgdb_irq; - -/* Default to UART1 */ -int kgdb_port =1 ; -#ifdef CONFIG_SIBYTE_SB1250_DUART -extern char sb1250_duart_present[]; -#endif -#endif -static struct hw_interrupt_type sb1250_irq_type = {"SB1250-IMR" , startup_sb1250_irq,@@ -338,6 +329,11 @@ void __init arch_init_irq(void)unsigned int imask =STATUSF_IP4 |STATUSF_IP3 |STATUSF_IP2 |STATUSF_IP1 |STATUSF_IP0 ; +#ifdef CONFIG_KGDB +if (kgdb_early_setup) +return ; +#endif +/* Default everything to IP2 */ for (i =0 ; i <SB1250_NR_IRQS ; i++) {/* was I0 */ bus_writeq(IMR_IP2_VAL,@@ -387,45 +383,4 @@ void __init arch_init_irq(void)/* Enable necessary IPs, disable the rest */ change_c0_status (ST0_IM , imask);set_except_vector (0 , sb1250_irq_handler); - -#ifdef CONFIG_KGDB -if (kgdb_flag) { - kgdb_irq =K_INT_UART_0 + kgdb_port; - -#ifdef CONFIG_SIBYTE_SB1250_DUART - sb1250_duart_present[kgdb_port] =0 ; -#endif -/* Setup uart 1 settings, mapper */ -bus_writeq (M_DUART_IMR_BRK ,IOADDR (A_DUART_IMRREG (kgdb_port))); - -sb1250_steal_irq (kgdb_irq); -bus_writeq (IMR_IP6_VAL , -IOADDR (A_IMR_REGISTER (0 ,R_IMR_INTERRUPT_MAP_BASE ) + - (kgdb_irq<<3 ))); -sb1250_unmask_irq (0 , kgdb_irq); - } -#endif } - -#ifdef CONFIG_KGDB - -#include <linux/delay.h> - -#define duart_out (reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg))) -#define duart_in (reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg))) - -void sb1250_kgdb_interrupt (struct pt_regs *regs) -{ -/* -* Clear break-change status (allow some time for the remote -* host to stop the break, since we would see another -* interrupt on the end-of-break too) -*/ - kstat_this_cpu.irqs[kgdb_irq]++; -mdelay (500 ); -duart_out (R_DUART_CMD ,V_DUART_MISC_CMD_RESET_BREAK_INT | -M_DUART_RX_EN |M_DUART_TX_EN ); -set_async_breakpoint (®s->cp0_epc); -} - -#endif /* CONFIG_KGDB */ diff -puN
arch/mips/sibyte/sb1250/irq_handler.S~mips-litearch/mips/sibyte/sb1250/irq_handler.Sarch/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, 1fdiff -puN
/dev/nullarch/mips/sibyte/sb1250/kgdb_sibyte.carch/mips/sibyte/sb1250/kgdb_sibyte.c new file +164
-0@@ -0,0 +1,164 @@ +/* +* arch/mips/sibyte/sb1250/kgdb_sibyte.c +* +* Author: Manish Lachwani, [email protected] or [email protected] +* +* 2004 (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. +*/ + +/* +* Support for KGDB on the Broadcom Sibyte. The SWARM board +* for example does not have a 8250/16550 compatible serial +* port. Hence, we need to have a driver for the serial +* ports to handle KGDB. This board needs nothing in addition +* to what is normally provided by the gdb portion of the stub. +*/ + +#include <linux/delay.h> +#include <linux/kernel_stat.h> +#include <linux/init.h> +#include <linux/kgdb.h> + +#include <asm/io.h> +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_uart.h> +#include <asm/sibyte/sb1250_int.h> +#include <asm/addrspace.h> + +int kgdb_port =1 ; +static int kgdb_irq; + +extern char sb1250_duart_present[]; +extern int sb1250_steal_irq (int irq); + +/* Forward declarations. */ +static void kgdbsibyte_init_duart (void ); +static int kgdb_init_io (void ); + +#define IMR_IP6_VAL K_INT_MAP_I4 +#define duart_out (reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg))) +#define duart_in (reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg))) + +static void kgdb_swarm_write_char (int c) +{ +while ((duart_in (R_DUART_STATUS ) &M_DUART_TX_RDY ) ==0 ) ; +duart_out (R_DUART_TX_HOLD , c); +} + +static int kgdb_swarm_read_char (void ) +{ +int ret_char; +unsigned int status; + + status =duart_in (R_DUART_STATUS ); +while ((status &M_DUART_RX_RDY ) ==0 ) { + status =duart_in (R_DUART_STATUS ); + } + +/* +* Check for framing error +*/ +if (status &M_DUART_FRM_ERR ) { +kgdbsibyte_init_duart (); +kgdb_swarm_write_char ('-' ); +return '-' ; + } + + ret_char =duart_in (R_DUART_RX_HOLD ); + +return ret_char; +} + +void sb1250_kgdb_interrupt (struct pt_regs *regs) +{ +int kgdb_irq =K_INT_UART_0 + kgdb_port; +/* +* Clear break-change status (allow some time for the remote +* host to stop the break, since we would see another +* interrupt on the end-of-break too) +*/ + kstat_this_cpu.irqs[kgdb_irq]++; +mdelay (500 ); +duart_out (R_DUART_CMD ,V_DUART_MISC_CMD_RESET_BREAK_INT | +M_DUART_RX_EN |M_DUART_TX_EN ); +if (kgdb_io_ops.init != kgdb_init_io) { +/* Throw away the data if another I/O routine is +* active. +*/ +unsigned int status; + + status =duart_in (R_DUART_STATUS ); +while ((status &M_DUART_RX_RDY ) ==0 ) { + status =duart_in (R_DUART_STATUS ); + } +/* +* Check for framing error +*/ +if (status &M_DUART_FRM_ERR ) { +kgdbsibyte_init_duart (); + } +duart_in (R_DUART_RX_HOLD ); + }else +breakpoint (); + +} + +/* +* We use port #1 and we set it for 115200 BAUD, 8n1. +*/ +static void kgdbsibyte_init_duart (void ) +{ +/* Set 8n1. */ +duart_out (R_DUART_MODE_REG_1 , +V_DUART_BITS_PER_CHAR_8 |V_DUART_PARITY_MODE_NONE ); +duart_out (R_DUART_MODE_REG_2 ,M_DUART_STOP_BIT_LEN_1 ); +/* Set baud rate of 115200. */ +duart_out (R_DUART_CLK_SEL ,V_DUART_BAUD_RATE (115200 )); +/* Enable rx and tx */ +duart_out (R_DUART_CMD ,M_DUART_RX_EN |M_DUART_TX_EN ); +} + +static int kgdb_init_io (void ) +{ +#ifdef CONFIG_SIBYTE_SB1250_DUART + sb1250_duart_present[kgdb_port] =0 ; +#endif + +kgdbsibyte_init_duart (); + +return 0 ; +} + +/* +* Hookup our IRQ line. We will already have been initialized a +* this point. +*/ +static void __init kgdbsibyte_hookup_irq (void ) +{ +/* Steal the IRQ. */ + kgdb_irq =K_INT_UART_0 + kgdb_port; + +/* Setup uart 1 settings, mapper */ +__raw_writeq (M_DUART_IMR_BRK ,IOADDR (A_DUART_IMRREG (kgdb_port))); + +sb1250_steal_irq (kgdb_irq); + +__raw_writeq (IMR_IP6_VAL , +IOADDR (A_IMR_REGISTER (0 ,R_IMR_INTERRUPT_MAP_BASE ) + + (kgdb_irq <<3 ))); + +sb1250_unmask_irq (0 , kgdb_irq); +} + +struct kgdb_io kgdb_io_ops = { + .read_char = kgdb_swarm_read_char, + .write_char = kgdb_swarm_write_char, + .init = kgdb_init_io, + .late_init = kgdbsibyte_hookup_irq, + .pre_exception =NULL , + .post_exception =NULL +};diff -puN
arch/mips/sibyte/sb1250/Makefile~mips-litearch/mips/sibyte/sb1250/Makefilearch/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)diff -L
arch/mips/sibyte/swarm/dbg_io.c-puNarch/mips/sibyte/swarm/dbg_io.c~mips-lite/dev/nullarch/mips/sibyte/swarm/dbg_io.c deleted +0
-76@@ -1,76 +0,0 @@ -/* -* kgdb debug routines for SiByte boards. -* -* Copyright (C) 2001 MontaVista Software Inc. -* Author: Jun Sun, [email protected] or [email protected] -* -* 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 of the License, or (at your -* option) any later version. -* -*/ - -/* -------------------- BEGINNING OF CONFIG --------------------- */ - -#include <linux/delay.h> -#include <asm/io.h> -#include <asm/sibyte/sb1250.h> -#include <asm/sibyte/sb1250_regs.h> -#include <asm/sibyte/sb1250_uart.h> -#include <asm/sibyte/sb1250_int.h> -#include <asm/addrspace.h> - -/* -* We use the second serial port for kgdb traffic. -* 115200, 8, N, 1. -*/ - -#define BAUD_RATE 115200 -#define CLK_DIVISOR V_DUART_BAUD_RATE(BAUD_RATE) -#define DATA_BITS V_DUART_BITS_PER_CHAR_8/* or 7 */ -#define PARITY V_DUART_PARITY_MODE_NONE/* or even */ -#define STOP_BITS M_DUART_STOP_BIT_LEN_1/* or 2 */ - -static int duart_initialized =0 ;/* 0: need to be init'ed by kgdb */ - -/* -------------------- END OF CONFIG --------------------- */ -extern int kgdb_port; - -#define duart_out (reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg))) -#define duart_in (reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg))) - -void putDebugChar (unsigned char c); -unsigned char getDebugChar (void ); -static void -duart_init (int clk_divisor,int data,int parity,int stop) -{ -duart_out (R_DUART_MODE_REG_1 , data | parity); -duart_out (R_DUART_MODE_REG_2 , stop); -duart_out (R_DUART_CLK_SEL , clk_divisor); - -duart_out (R_DUART_CMD ,M_DUART_RX_EN |M_DUART_TX_EN );/* enable rx and tx */ -} - -void -putDebugChar (unsigned char c) -{ -if (!duart_initialized) { - duart_initialized =1 ; -duart_init (CLK_DIVISOR ,DATA_BITS ,PARITY ,STOP_BITS ); - } -while ((duart_in (R_DUART_STATUS ) &M_DUART_TX_RDY ) ==0 ); -duart_out (R_DUART_TX_HOLD , c); -} - -unsigned char -getDebugChar (void ) -{ -if (!duart_initialized) { - duart_initialized =1 ; -duart_init (CLK_DIVISOR ,DATA_BITS ,PARITY ,STOP_BITS ); - } -while ((duart_in (R_DUART_STATUS ) &M_DUART_RX_RDY ) ==0 ) ; -return duart_in (R_DUART_RX_HOLD ); -} -diff -puN
arch/mips/sibyte/swarm/Makefile~mips-litearch/mips/sibyte/swarm/Makefilearch/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.odiff -puN
/dev/nullinclude/asm-mips/kdebug.hinclude/asm-mips/kdebug.h new file +47
-0@@ -0,0 +1,47 @@ +/* +* +* Copyright (C) 2004 MontaVista Software Inc. +* Author: Manish Lachwani, [email protected] or [email protected] +* +* 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 of the License, or (at your +* option) any later version. +* +*/ +#ifndef _MIPS_KDEBUG_H +#define _MIPS_KDEBUG_H + +#include <linux/notifier.h> + +struct pt_regs ; + +struct die_args { +struct pt_regs *regs; +const char *str; +long err; +}; + +int register_die_notifier (struct notifier_block *nb); +extern struct notifier_block *mips_die_chain; + +enum die_val { +DIE_OOPS =1 , +DIE_PANIC , +DIE_DIE , +DIE_KERNELDEBUG , +DIE_TRAP , +DIE_PAGE_FAULT , +}; + +/* +* trap number can be computed from regs and signr can be computed using +* compute_signal() +*/ +static inline int notify_die (enum die_val val,char *str,struct pt_regs *regs,long err) +{ +struct die_args args = { .regs=regs, .str=str, .err=err }; +return notifier_call_chain (&mips_die_chain, val, &args); +} + +#endif /* _MIPS_KDEBUG_H */ diff -puN
/dev/nullinclude/asm-mips/kgdb.hinclude/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__ */ diff -puN
lib/Kconfig.debug~mips-litelib/Kconfig.debuglib/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" - 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_ONLY_MODULES + 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_
Re: [patch 05/15] Basic MIPS support
Quoted 2 lines · Ralf Baechle
Forwarding this as a heads up. Who cares about kgdb may want to start working on the necessary bits as the patchset from below will be in 2.6.13.
I doubt it'll be in 2.6.13..