From e80963b97ac214db1425b66de5229cbad22aba49 Mon Sep 17 00:00:00 2001 From: phil Date: Sun, 3 Aug 2003 21:32:12 +0000 Subject: [PATCH] merge b_llnl_devel into b_multinet in preparation for landing --- .../patches/ext3-map_inode_page.patch | 2 - .../patches/ext3_map_inode_page_chaos.patch | 85 - .../patches/linux-2.4.18-14-kgdb-1.6.patch | 3165 -------------------- .../kernel_patches/pc/ext3_map_inode_page_chaos.pc | 2 - .../kernel_patches/pc/linux-2.4.18-14-kgdb-1.6.pc | 26 - lustre/kernel_patches/series/chaos-kgdb | 22 - .../txt/ext3_map_inode_page_chaos.txt | 3 - 7 files changed, 3305 deletions(-) delete mode 100644 lustre/kernel_patches/patches/ext3_map_inode_page_chaos.patch delete mode 100644 lustre/kernel_patches/patches/linux-2.4.18-14-kgdb-1.6.patch delete mode 100644 lustre/kernel_patches/pc/ext3_map_inode_page_chaos.pc delete mode 100644 lustre/kernel_patches/pc/linux-2.4.18-14-kgdb-1.6.pc delete mode 100644 lustre/kernel_patches/series/chaos-kgdb delete mode 100644 lustre/kernel_patches/txt/ext3_map_inode_page_chaos.txt diff --git a/lustre/kernel_patches/patches/ext3-map_inode_page.patch b/lustre/kernel_patches/patches/ext3-map_inode_page.patch index c9b7c15..80f14de 100644 --- a/lustre/kernel_patches/patches/ext3-map_inode_page.patch +++ b/lustre/kernel_patches/patches/ext3-map_inode_page.patch @@ -82,5 +82,3 @@ EXPORT_SYMBOL(ext3_xattr_set); EXPORT_SYMBOL(ext3_prep_san_write); +EXPORT_SYMBOL(ext3_map_inode_page); - -_ diff --git a/lustre/kernel_patches/patches/ext3_map_inode_page_chaos.patch b/lustre/kernel_patches/patches/ext3_map_inode_page_chaos.patch deleted file mode 100644 index 1b9296b..0000000 --- a/lustre/kernel_patches/patches/ext3_map_inode_page_chaos.patch +++ /dev/null @@ -1,85 +0,0 @@ - - - - fs/ext3/ext3-exports.c | 12 ++++++++++ - fs/ext3/inode.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 67 insertions(+) - ---- linux-2.4.18-p4smp/fs/ext3/inode.c~ext3_map_inode_page_chaos 2003-07-09 13:32:38.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/fs/ext3/inode.c 2003-07-09 17:11:19.000000000 -0600 -@@ -2892,3 +2892,58 @@ int ext3_prep_san_write(struct inode *in - ret = ret2; - return ret; - } -+ -+int ext3_map_inode_page(struct inode *inode, struct page *page, -+ unsigned long *blocks, int *created, int create) -+{ -+ unsigned int blocksize, blocks_per_page; -+ unsigned long iblock; -+ struct buffer_head dummy; -+ void *handle; -+ int i, rc = 0, failed = 0, needed_blocks; -+ -+ blocksize = inode->i_sb->s_blocksize; -+ blocks_per_page = PAGE_SIZE >> inode->i_sb->s_blocksize_bits; -+ iblock = page->index >> (PAGE_SHIFT - inode->i_sb->s_blocksize_bits); -+ -+ for (i = 0; i < blocks_per_page; i++, iblock++) { -+ blocks[i] = ext3_bmap(inode->i_mapping, iblock); -+ if (blocks[i] == 0) { -+ failed++; -+ created[i] = -1; -+ } else { -+ created[i] = 0; -+ } -+ } -+ -+ if (failed == 0 || create == 0) -+ return 0; -+ -+ needed_blocks = ext3_writepage_trans_blocks(inode) * failed; -+ lock_kernel(); -+ handle = ext3_journal_start(inode, needed_blocks); -+ unlock_kernel(); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ -+ iblock = page->index >> (PAGE_SHIFT - inode->i_sb->s_blocksize_bits); -+ for (i = 0; i < blocks_per_page; i++, iblock++) { -+ if (blocks[i] != 0) -+ continue; -+ -+ rc = ext3_get_block_handle(handle, inode, iblock, &dummy, 1); -+ if (rc) { -+ printk(KERN_INFO "ext3_map_inode_page: error reading " -+ "block %ld\n", iblock); -+ goto out; -+ } -+ blocks[i] = dummy.b_blocknr; -+ created[i] = 1; -+ } -+ -+ out: -+ lock_kernel(); -+ ext3_journal_stop(handle, inode); -+ unlock_kernel(); -+ return rc; -+} ---- /dev/null 2003-01-30 03:24:37.000000000 -0700 -+++ linux-2.4.18-p4smp-braam/fs/ext3/ext3-exports.c 2003-07-09 17:11:19.000000000 -0600 -@@ -0,0 +1,12 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+extern int ext3_map_inode_page(struct inode *inode, struct page *page, -+ unsigned long *blocks, int *created, int create); -+EXPORT_SYMBOL(ext3_map_inode_page); - -_ diff --git a/lustre/kernel_patches/patches/linux-2.4.18-14-kgdb-1.6.patch b/lustre/kernel_patches/patches/linux-2.4.18-14-kgdb-1.6.patch deleted file mode 100644 index deca885..0000000 --- a/lustre/kernel_patches/patches/linux-2.4.18-14-kgdb-1.6.patch +++ /dev/null @@ -1,3165 +0,0 @@ - Documentation/Configure.help | 23 - Documentation/i386/gdb-serial.txt | 386 ++++++++++ - Makefile | 4 - arch/i386/Makefile | 6 - arch/i386/config.in | 39 - - arch/i386/kernel/Makefile | 18 - arch/i386/kernel/entry.S | 27 - arch/i386/kernel/gdbstart.c | 148 ++++ - arch/i386/kernel/gdbstub.c | 1402 ++++++++++++++++++++++++++++++++++++++ - arch/i386/kernel/nmi.c | 30 - arch/i386/kernel/signal.c | 3 - arch/i386/kernel/traps.c | 44 + - arch/i386/mm/fault.c | 31 - drivers/char/Makefile | 1 - drivers/char/gdbserial.c | 280 +++++++ - drivers/char/serial.c | 147 +++ - drivers/char/tty_io.c | 6 - include/asm-i386/ioctls.h | 1 - include/asm-i386/page.h | 4 - include/asm-i386/processor.h | 3 - include/linux/dcache.h | 1 - include/linux/gdb.h | 63 + - include/linux/sched.h | 13 - init/main.c | 9 - kernel/ksyms.c | 5 - kernel/sched.c | 18 - 26 files changed, 2679 insertions(+), 33 deletions(-) - ---- linux-2.4.18-p4smp/arch/i386/config.in~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/arch/i386/config.in 2003-07-09 13:18:12.000000000 -0600 -@@ -456,25 +456,26 @@ mainmenu_option next_comment - comment 'Kernel hacking' - - bool 'Kernel debugging' CONFIG_DEBUG_KERNEL --if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then -- bool ' Compile the kernel with frame pointers' CONFIG_FRAME_POINTER -- bool ' Use Scan technique for doing stack trace' CONFIG_STACK_TRACE_SCAN -- if [ "$CONFIG_FRAME_POINTER" = "y" ]; then -- bool ' Use Frame Pointer Walk technique for doing stack trace' CONFIG_STACK_TRACE_FPTR -- fi -- int 'Number of parameters to show in stack trace' CONFIG_STACK_TRACE_PARAM_COUNT 4 -- bool ' Debug high memory support' CONFIG_DEBUG_HIGHMEM -- bool ' Debug memory allocations' CONFIG_DEBUG_SLAB -- bool ' Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT -- bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ -- bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK -- bool ' Kernel Core Dump Facility' CONFIG_MCL_COREDUMP -- if [ "$CONFIG_MCL_COREDUMP" = "y" ]; then -- bool ' Reboot using bootimg' CONFIG_BOOTIMG -- fi -- bool ' OPROFILE support' CONFIG_OPROFILE --fi -- -+bool 'KGDB: Remote (serial) kernel debugging with gdb' CONFIG_X86_REMOTE_DEBUG -+ if [ "$CONFIG_X86_REMOTE_DEBUG" != "n" ]; then -+ bool 'KGDB: Thread analysis' CONFIG_KGDB_THREAD -+ bool 'KGDB: Console messages through gdb' CONFIG_GDB_CONSOLE -+ else -+ bool 'Kernel debugging' CONFIG_DEBUG_KERNEL -+ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then -+ bool ' Compile the kernel with frame pointers' CONFIG_FRAME_POINTER -+ bool ' Debug high memory support' CONFIG_DEBUG_HIGHMEM -+ bool ' Debug memory allocations' CONFIG_DEBUG_SLAB -+ bool ' Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT -+ bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ -+ bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK -+ bool ' Kernel Core Dump Facility' CONFIG_MCL_COREDUMP -+ if [ "$CONFIG_MCL_COREDUMP" = "y" ]; then -+ bool ' Reboot using bootimg' CONFIG_BOOTIMG -+ fi -+ bool ' OPROFILE support' CONFIG_OPROFILE -+ fi -+ fi - endmenu - - source lib/Config.in ---- linux-2.4.18-p4smp/arch/i386/kernel/entry.S~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/arch/i386/kernel/entry.S 2003-07-09 13:15:23.000000000 -0600 -@@ -266,7 +266,7 @@ ret_from_exception: - - ALIGN - reschedule: -- call SYMBOL_NAME(schedule) # test -+ call SYMBOL_NAME(user_schedule) # test - jmp ret_from_sys_call - - ENTRY(divide_error) -@@ -404,6 +404,31 @@ ENTRY(spurious_interrupt_bug) - pushl $ SYMBOL_NAME(do_spurious_interrupt_bug) - jmp error_code - -+#ifdef CONFIG_KGDB_THREAD -+ENTRY(kern_schedule) -+ pushl %ebp -+ movl %esp, %ebp -+ pushl %ss -+ pushl %ebp -+ pushfl -+ pushl %cs -+ pushl 4(%ebp) -+ pushl %eax -+ pushl %es -+ pushl %ds -+ pushl %eax -+ pushl (%ebp) -+ pushl %edi -+ pushl %esi -+ pushl %edx -+ pushl %ecx -+ pushl %ebx -+ call kern_do_schedule -+ movl %ebp, %esp -+ pop %ebp -+ ret -+#endif -+ - .data - ENTRY(sys_call_table) - .long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/ ---- /dev/null 2003-01-30 03:24:37.000000000 -0700 -+++ linux-2.4.18-p4smp-braam/arch/i386/kernel/gdbstart.c 2003-07-09 13:15:23.000000000 -0600 -@@ -0,0 +1,148 @@ -+/* -+ * This program opens a tty file and issues the GDB stub activating -+ * ioctl on it. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define TIOCGDB 0x547F -+ -+char *tty_name = "/dev/ttyS0" ; /* COM1 port */ -+int speed = 9600 ; /* default speed */ -+struct termios save_ts ; /* original term struct */ -+ -+void print_usage(void) -+{ -+ printf("gdbstub [-s speed] [-t tty-dev]\n") ; -+ printf(" defaults: /dev/ttyS0 with speed unmodified by this program\n"); -+ -+} /* print_usage */ -+ -+void tty_err(char *msg) -+{ -+ char buf[100] ; -+ -+ strcpy(buf, msg) ; -+ strcat(buf, ": ") ; -+ strcat(buf, tty_name) ; -+ perror(buf) ; -+ exit(1) ; -+ -+} /* tty_err */ -+ -+ -+void setup_term(int fd) -+{ -+ struct termios ts ; -+ int speed_code ; -+ -+ if (tcgetattr(fd, &ts) < 0) tty_err("tcgetattr") ; -+ -+ save_ts = ts ; -+ switch (speed) -+ { -+ case 4800: -+ speed_code = B4800 ; -+ break ; -+ case 9600: -+ speed_code = B9600 ; -+ break ; -+ case 19200: -+ speed_code = B19200 ; -+ break ; -+ case 38400: -+ speed_code = B38400 ; -+ break ; -+ case 57600: -+ speed_code = B57600 ; -+ break ; -+ case 115200: -+ speed_code = B115200 ; -+ break ; -+ case 230400: -+ speed_code = B230400 ; -+ break ; -+ default: -+ printf("Invalid speed: %d\n", speed) ; -+ exit(1) ; -+ } -+ -+ ts.c_cflag = CS8 | CREAD | CLOCAL ; -+ if (cfsetospeed(&ts, speed_code) < 0) tty_err("cfsetospeed") ; -+ if (cfsetispeed(&ts, speed_code) < 0) tty_err("cfsetispeed") ; -+ -+ if (tcsetattr(fd, TCSANOW, &ts) < 0) tty_err("tcsetattr") ; -+ -+} /* setup_term */ -+ -+void main(int argc, char **argv) -+{ -+ int opt ; -+ int fil ; -+ int rslt ; -+ -+ while ((opt = getopt(argc, argv, "hs:t:")) > 0) -+ { -+ switch (opt) -+ { -+ case 's': -+ speed = atol(optarg) ; -+ break ; -+ case 't': -+ tty_name = optarg ; -+ break ; -+ case ':': -+ printf("Invalid option\n") ; -+ break ; -+ case '?': -+ case 'h': -+ default: -+ print_usage() ; -+ return ; -+ } -+ } -+ -+ fil = open(tty_name, O_RDWR) ; -+ if (fil < 0) -+ { -+ perror(tty_name) ; -+ return ; -+ } -+ -+ -+ setup_term(fil) ; -+ -+ /* -+ * When we issue this ioctl, control will not return until -+ * the debugger running on the remote host machine says "go". -+ */ -+ printf("\nAbout to activate GDB stub in the kernel on %s\n", tty_name) ; -+ printf("Hit CR to continue, kill program to abort -- ") ; -+ getchar() ; -+ sync() ; -+ rslt = ioctl(fil, TIOCGDB, 0) ; -+ if (rslt < 0) -+ { -+ perror("TIOCGDB ioctl") ; -+ return ; -+ } -+ -+ printf("\nGDB stub successfully activated\n") ; -+ -+ for (;;) -+ { -+ pause() ; -+ } -+ -+ if (tcsetattr(fil, TCSANOW, &save_ts) < 0) tty_err("tcsetattr") ; -+ -+} /* main */ ---- /dev/null 2003-01-30 03:24:37.000000000 -0700 -+++ linux-2.4.18-p4smp-braam/arch/i386/kernel/gdbstub.c 2003-07-09 13:15:23.000000000 -0600 -@@ -0,0 +1,1402 @@ -+/* -+ * -+ * 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. -+ */ -+/**************************************************************************** -+ * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ -+ * -+ * Module name: remcom.c $ -+ * Revision: 1.34 $ -+ * Date: 91/03/09 12:29:49 $ -+ * Contributor: Lake Stevens Instrument Division$ -+ * -+ * Description: low level support for gdb debugger. $ -+ * -+ * Considerations: only works on target hardware $ -+ * -+ * Written by: Glenn Engel $ -+ * Updated by: Amit Kale -+ * ModuleState: Experimental $ -+ * -+ * NOTES: See Below $ -+ * -+ * Modified for 386 by Jim Kingdon, Cygnus Support. -+ * Origianl kgdb, compatibility with 2.1.xx kernel by David Grothe -+ * Integrated into 2.2.5 kernel by Tigran Aivazian -+ * thread support, -+ * support for multiple processors, -+ * support for ia-32(x86) hardware debugging, -+ * Console support, -+ * handling nmi watchdog -+ * Amit S. Kale ( akale@veritas.com ) -+ * -+ * -+ * 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 an int 3. -+ * -+ ************* -+ * -+ * 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) -+ * -+ * All commands and responses are sent with a packet which includes a -+ * checksum. A packet consists of -+ * -+ * $#. -+ * -+ * where -+ * :: -+ * :: < two hex digits computed as modulo 256 sum of > -+ * -+ * 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 -+ * -+ ****************************************************************************/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include /* for linux pt_regs struct */ -+#include -+#ifdef CONFIG_GDB_CONSOLE -+#include -+#endif -+#include -+ -+/************************************************************************ -+ * -+ * external low-level support routines -+ */ -+typedef void (*Function)(void); /* pointer to a function */ -+ -+/* Thread reference */ -+typedef unsigned char threadref[8]; -+ -+extern int putDebugChar(int); /* write a single character */ -+extern int getDebugChar(void); /* read and return a single char */ -+ -+/************************************************************************/ -+/* 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 -+ -+static char initialized; /* boolean flag. != 0 means we've been initialized */ -+ -+static const char hexchars[]="0123456789abcdef"; -+ -+/* Number of bytes of registers. */ -+#define NUMREGBYTES 64 -+/* -+ * Note that this register image is in a different order than -+ * the register image that Linux produces at interrupt time. -+ * -+ * Linux's register image is defined by struct pt_regs in ptrace.h. -+ * Just why GDB uses a different order is a historical mystery. -+ */ -+enum regnames {_EAX, /* 0 */ -+ _ECX, /* 1 */ -+ _EDX, /* 2 */ -+ _EBX, /* 3 */ -+ _ESP, /* 4 */ -+ _EBP, /* 5 */ -+ _ESI, /* 6 */ -+ _EDI, /* 7 */ -+ _PC /* 8 also known as eip */, -+ _PS /* 9 also known as eflags */, -+ _CS, /* 10 */ -+ _SS, /* 11 */ -+ _DS, /* 12 */ -+ _ES, /* 13 */ -+ _FS, /* 14 */ -+ _GS}; /* 15 */ -+ -+ -+ -+/*************************** ASSEMBLY CODE MACROS *************************/ -+/* */ -+ -+#define BREAKPOINT() asm(" int $3"); -+ -+/* 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; -+ -+#if KGDB_MAX_NO_CPUS != 8 -+#error change the definition of slavecpulocks -+#endif -+ -+static spinlock_t slavecpulocks[KGDB_MAX_NO_CPUS] = { SPIN_LOCK_UNLOCKED, -+ SPIN_LOCK_UNLOCKED, SPIN_LOCK_UNLOCKED, SPIN_LOCK_UNLOCKED, -+ SPIN_LOCK_UNLOCKED, SPIN_LOCK_UNLOCKED, SPIN_LOCK_UNLOCKED, -+ SPIN_LOCK_UNLOCKED }; -+volatile int procindebug[KGDB_MAX_NO_CPUS]; -+ -+volatile unsigned kgdb_step = 0; -+ -+volatile unsigned kgdb_lock = 0; -+ -+enum gdb_bptype -+{ -+ bp_breakpoint = '0', -+ bp_hardware_breakpoint, -+ bp_write_watchpoint, -+ bp_read_watchpoint, -+ bp_access_watchpoint -+}; -+ -+enum gdb_bpstate -+{ -+ bp_disabled, -+ bp_enabled -+}; -+ -+#define BREAK_INSTR_SIZE 1 -+ -+struct gdb_breakpoint -+{ -+ unsigned int bpt_addr; -+ unsigned char saved_instr[BREAK_INSTR_SIZE]; -+ enum gdb_bptype type; -+ enum gdb_bpstate state; -+}; -+ -+typedef struct gdb_breakpoint gdb_breakpoint_t; -+ -+#define MAX_BREAKPOINTS 16 -+ -+gdb_breakpoint_t kgdb_break[MAX_BREAKPOINTS]; -+static char gdb_bpt_instr[BREAK_INSTR_SIZE] = {0xcc}; -+ -+static void kgdb_usercode (void) -+{ -+} -+ -+int hex(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 $# */ -+void getpacket(char * buffer) -+{ -+ unsigned char checksum; -+ unsigned char xmitcsum; -+ int i; -+ int count; -+ 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() & 0x7f; -+ if (ch == '#') break; -+ checksum = checksum + ch; -+ buffer[count] = ch; -+ count = count + 1; -+ } -+ 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. */ -+ -+ -+void putpacket(char * buffer) -+{ -+ unsigned char checksum; -+ int count; -+ char ch; -+ -+ /* $#. */ -+ do { -+ putDebugChar('$'); -+ checksum = 0; -+ count = 0; -+ -+ while ((ch=buffer[count])) { -+ if (! putDebugChar(ch)) return; -+ checksum += ch; -+ count += 1; -+ } -+ -+ putDebugChar('#'); -+ putDebugChar(hexchars[checksum >> 4]); -+ putDebugChar(hexchars[checksum % 16]); -+ -+ } while ((getDebugChar() & 0x7f) != '+'); -+ -+} -+ -+static char remcomInBuffer[BUFMAX]; -+static char remcomOutBuffer[BUFMAX]; -+static short error; -+ -+static void regs_to_gdb_regs(int *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; -+} /* regs_to_gdb_regs */ -+ -+static void gdb_regs_to_regs(int *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] ; -+#if 0 /* can't change these */ -+ regs->esp = gdb_regs[_ESP] ; -+ regs->xss = gdb_regs[ _SS] ; -+ regs->fs = gdb_regs[ _FS] ; -+ regs->gs = gdb_regs[ _GS] ; -+#endif -+ -+} /* gdb_regs_to_regs */ -+ -+/* Indicate to caller of mem2hex or hex2mem that there has been an -+ error. */ -+static volatile int kgdb_memerr = 0; -+volatile int kgdb_memerr_expected = 0; -+static volatile int kgdb_memerr_cnt = 0; -+static int garbage_loc = -1 ; -+ -+int -+get_char (char *addr) -+{ -+ return *addr; -+} -+ -+void -+set_char ( char *addr, int val) -+{ -+ *addr = val; -+} -+ -+static void -+get_mem (char *addr, -+ unsigned char *buf, -+ int count) -+{ -+ while (count) { -+ *buf++ = get_char(addr++); -+ if (kgdb_memerr) -+ return; -+ count--; -+ } -+} -+ -+static void -+set_mem (char *addr, -+ char *buf, -+ int count) -+{ -+ while (count) { -+ set_char(addr++,*buf++); -+ if (kgdb_memerr) -+ return; -+ count--; -+ } -+} -+ -+/* convert the memory pointed to by mem into hex, placing result in buf */ -+/* return a pointer to the last char put in buf (null) */ -+/* If MAY_FAULT is non-zero, then we should set kgdb_memerr in response to -+ a fault; if zero treat a fault like any other fault in the stub. */ -+char* mem2hex( char* mem, -+ char* buf, -+ int count, -+ int may_fault) -+{ -+ int i; -+ unsigned char ch; -+ -+ if (may_fault) -+ { -+ kgdb_memerr_expected = 1 ; -+ kgdb_memerr = 0 ; -+ } -+ for (i=0;i> 4]; -+ *buf++ = hexchars[ch % 16]; -+ } -+ *buf = 0; -+ if (may_fault) -+ kgdb_memerr_expected = 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 */ -+char* hex2mem( char* buf, -+ char* mem, -+ int count, -+ int may_fault) -+{ -+ int i; -+ unsigned char ch; -+ -+ if (may_fault) -+ { -+ kgdb_memerr_expected = 1 ; -+ kgdb_memerr = 0 ; -+ } -+ for (i=0;i=0) -+ { -+ *intValue = (*intValue <<4) | hexValue; -+ numChars ++; -+ } -+ else -+ break; -+ -+ (*ptr)++; -+ } -+ -+ return (numChars); -+} -+ -+#ifdef CONFIG_KGDB_THREAD -+static int -+stubhex ( -+ int 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; -+} -+ -+ -+static int -+stub_unpack_int ( -+ char *buff, -+ int fieldlength) -+{ -+ int nibble; -+ int retval = 0; -+ -+ while (fieldlength) -+ { -+ nibble = stubhex (*buff++); -+ retval |= nibble; -+ fieldlength--; -+ if (fieldlength) -+ retval = retval << 4; -+ } -+ return retval; -+} -+#endif -+ -+static char * -+pack_hex_byte ( -+ char *pkt, -+ int byte) -+{ -+ *pkt++ = hexchars[(byte >> 4) & 0xf]; -+ *pkt++ = hexchars[(byte & 0xf)]; -+ return pkt; -+} -+ -+#define BUF_THREAD_ID_SIZE 16 -+ -+#ifdef CONFIG_KGDB_THREAD -+static char * -+pack_threadid ( -+ char *pkt, -+ threadref *id) -+{ -+ char *limit; -+ unsigned char *altid; -+ -+ altid = (unsigned char *) id; -+ limit = pkt + BUF_THREAD_ID_SIZE; -+ while (pkt < limit) -+ pkt = pack_hex_byte (pkt, *altid++); -+ return pkt; -+} -+ -+static char * -+unpack_byte ( -+ char *buf, -+ int *value) -+{ -+ *value = stub_unpack_int (buf, 2); -+ return buf + 2; -+} -+ -+static char * -+unpack_threadid ( -+ char *inbuf, -+ threadref *id) -+{ -+ char *altref; -+ char *limit = inbuf + BUF_THREAD_ID_SIZE; -+ int x, y; -+ -+ altref = (char *) id; -+ -+ while (inbuf < limit) -+ { -+ x = stubhex (*inbuf++); -+ y = stubhex (*inbuf++); -+ *altref++ = (x << 4) | y; -+ } -+ return inbuf; -+} -+#endif -+ -+void -+int_to_threadref ( -+ threadref *id, -+ int value) -+{ -+ unsigned char *scan; -+ -+ scan = (unsigned char *) id; -+ { -+ int i = 4; -+ while (i--) -+ *scan++ = 0; -+ } -+ *scan++ = (value >> 24) & 0xff; -+ *scan++ = (value >> 16) & 0xff; -+ *scan++ = (value >> 8) & 0xff; -+ *scan++ = (value & 0xff); -+} -+ -+#ifdef CONFIG_KGDB_THREAD -+static int -+threadref_to_int ( -+ threadref *ref) -+{ -+ int i, value = 0; -+ unsigned char *scan; -+ -+ scan = (char *) ref; -+ scan += 4; -+ i = 4; -+ while (i-- > 0) -+ value = (value << 8) | ((*scan++) & 0xff); -+ return value; -+} -+ -+ -+struct task_struct * -+getthread ( -+ int pid) -+{ -+ task_t *thread; -+ thread = find_task_by_pid(pid); -+ if (thread) { -+ return thread; -+ } -+ thread = &init_task; -+ do { -+ if (thread->pid == pid) { -+ return thread; -+ } -+ thread = thread->next_task; -+ } while (thread != &init_task); -+ return NULL; -+} -+#endif -+ -+struct hw_breakpoint { -+ unsigned enabled; -+ unsigned type; -+ unsigned len; -+ unsigned addr; -+} breakinfo[4] = { { enabled:0 }, { enabled:0 }, { enabled:0 }, { enabled:0 }}; -+ -+void correct_hw_break( void ) -+{ -+ int breakno; -+ int correctit; -+ int breakbit; -+ unsigned dr7; -+ -+ asm volatile ( -+ "movl %%db7, %0\n" -+ : "=r" (dr7) -+ : ); -+ do -+ { -+ unsigned addr0, addr1, addr2, addr3; -+ asm volatile ( -+ "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: -+ asm volatile ("movl %0, %%dr0\n" -+ : -+ : "r" (breakinfo[breakno].addr) ); -+ break; -+ -+ case 1: -+ asm volatile ("movl %0, %%dr1\n" -+ : -+ : "r" (breakinfo[breakno].addr) ); -+ break; -+ -+ case 2: -+ asm volatile ("movl %0, %%dr2\n" -+ : -+ : "r" (breakinfo[breakno].addr) ); -+ break; -+ -+ case 3: -+ asm volatile ("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) { -+ asm volatile ( "movl %0, %%db7\n" -+ : -+ : "r" (dr7)); -+ } -+} -+ -+int remove_hw_break( -+ unsigned breakno) -+{ -+ if (!breakinfo[breakno].enabled) { -+ return -1; -+ } -+ breakinfo[breakno].enabled = 0; -+ return 0; -+} -+ -+int set_hw_break( -+ unsigned breakno, -+ unsigned type, -+ unsigned len, -+ unsigned addr) -+{ -+ if (breakinfo[breakno].enabled) { -+ return -1; -+ } -+ breakinfo[breakno].enabled = 1; -+ breakinfo[breakno].type = type; -+ breakinfo[breakno].len = len; -+ breakinfo[breakno].addr = addr; -+ return 0; -+} -+ -+static int -+set_break ( -+ unsigned addr) -+{ -+ int i, breakno = -1; -+ -+ for (i = 0; i < MAX_BREAKPOINTS; i++) { -+ if ((kgdb_break[i].state == bp_enabled) && -+ (kgdb_break[i].bpt_addr == addr)) { -+ breakno = -1; -+ break; -+ } -+ -+ if (kgdb_break[i].state == bp_disabled) { -+ if ((breakno == -1) || (kgdb_break[i].bpt_addr == addr)) -+ breakno = i; -+ } -+ } -+ if (breakno == -1) -+ return -1; -+ -+ get_mem((char *)addr,kgdb_break[breakno].saved_instr,BREAK_INSTR_SIZE); -+ if (kgdb_memerr) -+ return -1; -+ -+ set_mem((char *)addr,gdb_bpt_instr,BREAK_INSTR_SIZE); -+ if (kgdb_memerr) -+ return -1; -+ -+ kgdb_break[breakno].state = bp_enabled; -+ kgdb_break[breakno].type = bp_breakpoint; -+ kgdb_break[breakno].bpt_addr = addr; -+ -+ return 0; -+} -+ -+static int -+remove_break (unsigned addr) -+{ -+ int i; -+ -+ for (i=0; ithread.kgdbregs = regs; -+ -+ /* Wait till master processor goes completely into the debugger */ -+ while (!procindebug[kgdb_lock - 1]) { -+ int i = 10; /* an arbitrary number */ -+ -+ while (--i) -+ asm volatile ("nop": : : "memory"); -+ -+ } -+ -+ /* Wait till master processor is done with debugging */ -+ spin_lock(slavecpulocks + processor); -+ correct_hw_break(); -+ -+ /* Signal the master processor that we are done */ -+ procindebug[processor] = 0; -+ spin_unlock(slavecpulocks + processor); -+ local_irq_restore(flags); -+} -+ -+void -+printexceptioninfo( -+ int exceptionNo, -+ int errorcode, -+ char *buffer) -+{ -+ unsigned dr6; -+ int i; -+ switch (exceptionNo) { -+ case 1: /* debug exception */ -+ break; -+ case 3: /* breakpoint */ -+ sprintf(buffer, "Software breakpoint"); -+ return; -+ default: -+ sprintf(buffer, "Details not available"); -+ return; -+ } -+ asm volatile ("movl %%db6, %0\n" -+ : "=r" (dr6) -+ : ); -+ if (dr6 & 0x4000) { -+ sprintf(buffer, "Single step"); -+ return; -+ } -+ for (i = 0; i < 4; ++i) { -+ if (dr6 & (1 << i)) { -+ sprintf(buffer, "Hardware breakpoint %d", i); -+ return; -+ } -+ } -+ sprintf(buffer, "Unknown trap"); -+ return; -+} -+ -+/* -+ * This function does all command procesing for interfacing to gdb. -+ * -+ * NOTE: The INT nn instruction leaves the state of the interrupt -+ * enable flag UNCHANGED. That means that when this routine -+ * is entered via a breakpoint (INT 3) instruction from code -+ * that has interrupts enabled, then interrupts will STILL BE -+ * enabled when this routine is entered. The first thing that -+ * we do here is disable interrupts so as to prevent recursive -+ * entries and bothersome serial interrupts while we are -+ * trying to run the serial port in polled mode. -+ * -+ * For kernel version 2.1.xx the cli() actually gets a spin lock so -+ * it is always necessary to do a restore_flags before returning -+ * so as to let go of that lock. -+ */ -+int handle_exception(int exceptionVector, -+ int signo, -+ int err_code, -+ struct pt_regs *linux_regs) -+{ -+ struct task_struct *usethread = NULL; -+ int addr, length; -+ int breakno, breaktype; -+ char *ptr; -+ int newPC; -+ unsigned long flags; -+ int gdb_regs[NUMREGBYTES/4]; -+ int i; -+ int dr6; -+ int ret; -+ int maxbpt, bpt_done; -+ unsigned long bptaddr; -+ struct pt_regs tempregs; -+#ifdef CONFIG_KGDB_THREAD -+ int nothreads; -+ int maxthreads; -+ int threadid; -+ threadref thref; -+ struct task_struct *thread = NULL; -+#endif -+ unsigned procid; -+ -+#define regs (*linux_regs) -+ -+ /* -+ * If the entry is not from the kernel then return to the Linux -+ * trap handler and let it process the interrupt normally. -+ */ -+ if ((linux_regs->eflags & VM_MASK) || (3 & linux_regs->xcs)) { -+ return(0); -+ } -+ -+ if (kgdb_memerr_expected) -+ { -+ /* -+ * This fault occured because of the get_char or set_char -+ * routines. These two routines use either eax of edx to -+ * indirectly reference the location in memory that they -+ * are working with. For a page fault, when we return -+ * the instruction will be retried, so we have to make -+ * sure that these registers point to valid memory. -+ */ -+ kgdb_memerr = 1 ; /* set mem error flag */ -+ kgdb_memerr_expected = 0 ; -+ kgdb_memerr_cnt++ ; /* helps in debugging */ -+ regs.eax = (long) &garbage_loc ; /* make valid address */ -+ regs.edx = (long) &garbage_loc ; /* make valid address */ -+ return(0) ; -+ } -+ -+ /* Hold kgdb_lock */ -+ procid = smp_processor_id(); -+ while (cmpxchg(&kgdb_lock, 0, (procid + 1)) != 0) { -+ int i = 25; /* an arbitrary number */ -+ -+ while (--i) -+ asm volatile ("nop": : : "memory"); -+ } -+ -+ kgdb_step = 0; -+ -+ local_irq_save(flags); -+ -+ /* Disable hardware debugging while we are in kgdb */ -+ __asm__("movl %0,%%db7" -+ : /* no output */ -+ : "r" (0)); -+ -+ for (i = 0; i < smp_num_cpus; i++) { -+ spin_lock(&slavecpulocks[i]); -+ } -+ -+ /* spin_lock code is good enough as a barrier so we don't -+ * need one here */ -+ procindebug[smp_processor_id()] = 1; -+ -+ /* Master processor is completely in the debugger */ -+ -+ gdb_i386vector = exceptionVector; -+ gdb_i386errcode = err_code ; -+ -+ /* reply to host that an exception has occurred */ -+ remcomOutBuffer[0] = 'S'; -+ remcomOutBuffer[1] = hexchars[signo >> 4]; -+ remcomOutBuffer[2] = hexchars[signo % 16]; -+ remcomOutBuffer[3] = 0; -+ -+ putpacket(remcomOutBuffer); -+ -+ while (1==1) { -+ error = 0; -+ remcomOutBuffer[0] = 0; -+ getpacket(remcomInBuffer); -+ switch (remcomInBuffer[0]) { -+ case '?' : -+ remcomOutBuffer[0] = 'S'; -+ remcomOutBuffer[1] = hexchars[signo >> 4]; -+ remcomOutBuffer[2] = hexchars[signo % 16]; -+ remcomOutBuffer[3] = 0; -+ break; -+ case 'g' : /* return the value of the CPU registers */ -+ if (!usethread || usethread == current) { -+ regs_to_gdb_regs(gdb_regs, ®s) ; -+ } else { -+ memset(gdb_regs, 0, NUMREGBYTES); -+ if (usethread->thread.kgdbregs) { -+ kgdb_memerr_expected = 1 ; -+ kgdb_memerr = 0; -+ get_char((char *)usethread->thread.kgdbregs); -+ kgdb_memerr_expected = 0; -+ if (kgdb_memerr) { -+ *(((char *)&tempregs) + i) = '\0'; -+ gdb_regs[_PC] = kgdb_usercode; -+ } else { -+ regs_to_gdb_regs(gdb_regs, -+ usethread->thread.kgdbregs); -+ } -+ } else { -+ gdb_regs[_PC] = kgdb_usercode; -+ } -+ } -+ mem2hex((char*) gdb_regs, remcomOutBuffer, NUMREGBYTES, 0); -+ break; -+ case 'G' : /* set the value of the CPU registers - return OK */ -+ hex2mem(&remcomInBuffer[1], (char*) gdb_regs, NUMREGBYTES, 0); -+ if (!usethread || usethread == current) { -+ gdb_regs_to_regs(gdb_regs, ®s) ; -+ strcpy(remcomOutBuffer,"OK"); -+ } else { -+ strcpy(remcomOutBuffer,"E00"); -+ } -+ break; -+ -+ /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ -+ case 'm' : -+ /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ -+ ptr = &remcomInBuffer[1]; -+ if (hexToInt(&ptr,&addr)) -+ if (*(ptr++) == ',') -+ if (hexToInt(&ptr,&length)) -+ { -+ ptr = 0; -+ mem2hex((char*) addr, remcomOutBuffer, length, 1); -+ if (kgdb_memerr) { -+ strcpy (remcomOutBuffer, "E03"); -+ } -+ } -+ -+ if (ptr) -+ { -+ strcpy(remcomOutBuffer,"E01"); -+ } -+ break; -+ -+ /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ -+ case 'M' : -+ /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ -+ ptr = &remcomInBuffer[1]; -+ if (hexToInt(&ptr,&addr)) -+ if (*(ptr++) == ',') -+ if (hexToInt(&ptr,&length)) -+ if (*(ptr++) == ':') -+ { -+ hex2mem(ptr, (char*) addr, length, 1); -+ -+ if (kgdb_memerr) { -+ strcpy (remcomOutBuffer, "E03"); -+ } else { -+ strcpy(remcomOutBuffer,"OK"); -+ } -+ -+ ptr = 0; -+ } -+ if (ptr) -+ { -+ strcpy(remcomOutBuffer,"E02"); -+ } -+ break; -+ -+ /* cAA..AA Continue at address AA..AA(optional) */ -+ /* sAA..AA Step one instruction from AA..AA(optional) */ -+ /* D Detach from debugger */ -+ case 'c' : -+ case 's' : -+ case 'D' : -+ -+ /* try to read optional parameter, pc unchanged if no parm */ -+ ptr = &remcomInBuffer[1]; -+ if (hexToInt(&ptr,&addr)) -+ { -+ regs.eip = addr; -+ } -+ -+ newPC = regs.eip ; -+ -+ /* clear the trace bit */ -+ regs.eflags &= 0xfffffeff; -+ -+ /* set the trace bit if we're stepping */ -+ if (remcomInBuffer[0] == 's') { -+ regs.eflags |= 0x100; -+ kgdb_step = 1; -+ } -+ if (remcomInBuffer[0] == 'D') { -+ clear_disabled_break(); -+ strcpy(remcomOutBuffer,"+"); -+ putpacket(remcomOutBuffer); -+ } -+ -+ asm volatile ("movl %%db6, %0\n" -+ : "=r" (dr6) -+ : ); -+ if (!(dr6 & 0x4000)) { -+ for (breakno = 0; breakno < 4; ++breakno) { -+ if (dr6 & (1 << breakno)) { -+ if (breakinfo[breakno].type == 0) { -+ /* Set restore flag */ -+ regs.eflags |= 0x10000; -+ break; -+ } -+ } -+ } -+ } -+ correct_hw_break(); -+ asm volatile ( -+ "movl %0, %%db6\n" -+ : -+ : "r" (0) ); -+ -+ procindebug[smp_processor_id()] = 0; -+ -+ /* Signal the slave processors to quit from -+ * the debugger */ -+ for (i = 0; i < smp_num_cpus; i++) { -+ spin_unlock(&slavecpulocks[i]); -+ } -+ -+ /* Wait till all the processors have quit -+ * from the debugger */ -+ -+ for (i = 0; i < smp_num_cpus; i++) { -+ while (procindebug[i]) { -+ int j = 10; /* an arbitrary number */ -+ -+ while (--j) { -+ asm volatile ("nop" -+ : : : "memory"); -+ } -+ } -+ } -+ -+ /* Release kgdb_lock */ -+ asm volatile ( -+#ifndef CONFIG_X86_OOSTORE -+ "movb $0,%0" -+#else -+ "lock movb $0,%0" -+#endif -+ : "=m" (kgdb_lock) : : "memory"); -+ -+ local_irq_restore(flags) ; -+ return(0) ; -+ -+ /* kill the program */ -+ case 'k' : /* do nothing */ -+ break; -+ -+ /* query */ -+ case 'q' : -+ switch (remcomInBuffer[1]) { -+#ifdef CONFIG_KGDB_THREAD -+ case 'L': -+ /* List threads */ -+ unpack_byte(remcomInBuffer+3, &maxthreads); -+ unpack_threadid(remcomInBuffer+5, &thref); -+ -+ remcomOutBuffer[0] = 'q'; -+ remcomOutBuffer[1] = 'M'; -+ remcomOutBuffer[4] = '0'; -+ pack_threadid(remcomOutBuffer+5, &thref); -+ -+ threadid = threadref_to_int(&thref); -+ for (nothreads = 0; -+ nothreads < maxthreads && threadid< PID_MAX; -+ threadid++ ) -+ { -+ read_lock(&tasklist_lock); -+ thread = getthread(threadid); -+ read_unlock(&tasklist_lock); -+ if (thread) { -+ int_to_threadref(&thref, threadid); -+ pack_threadid(remcomOutBuffer+21+nothreads*16, -+ &thref); -+ nothreads++; -+ } -+ } -+ if (threadid == PID_MAX) { -+ remcomOutBuffer[4] = '1'; -+ } -+ pack_hex_byte(remcomOutBuffer+2, nothreads); -+ remcomOutBuffer[21+nothreads*16] = '\0'; -+ break; -+ -+ case 'C': -+ /* Current thread id */ -+ remcomOutBuffer[0] = 'Q'; -+ remcomOutBuffer[1] = 'C'; -+ threadid = current->pid; -+ int_to_threadref(&thref, threadid); -+ pack_threadid(remcomOutBuffer+2, &thref); -+ remcomOutBuffer[18] = '\0'; -+ break; -+#endif -+ -+ case 'E': -+ /* Print exception info */ -+ printexceptioninfo(exceptionVector, err_code, remcomOutBuffer); -+ break; -+ } -+ break; -+ -+#ifdef CONFIG_KGDB_THREAD -+ /* task related */ -+ case 'H' : -+ switch (remcomInBuffer[1]) { -+ case 'g': -+ ptr = &remcomInBuffer[2]; -+ hexToInt(&ptr, &threadid); -+ thread = getthread(threadid); -+ if (!thread) { -+ remcomOutBuffer[0] = 'E'; -+ remcomOutBuffer[1] = '\0'; -+ break; -+ } -+ usethread = thread; -+ /* follow through */ -+ case 'c': -+ remcomOutBuffer[0] = 'O'; -+ remcomOutBuffer[1] = 'K'; -+ remcomOutBuffer[2] = '\0'; -+ break; -+ } -+ break; -+ -+ /* Query thread status */ -+ case 'T': -+ ptr = &remcomInBuffer[1]; -+ hexToInt(&ptr, &threadid); -+ thread = getthread(threadid); -+ if (thread) { -+ remcomOutBuffer[0] = 'O'; -+ remcomOutBuffer[1] = 'K'; -+ remcomOutBuffer[2] = '\0'; -+ } else { -+ remcomOutBuffer[0] = 'E'; -+ remcomOutBuffer[1] = '\0'; -+ } -+ break; -+#endif -+ -+ case 'Y': -+ ptr = &remcomInBuffer[1]; -+ hexToInt(&ptr, &breakno); -+ ptr++; -+ hexToInt(&ptr, &breaktype); -+ ptr++; -+ hexToInt(&ptr, &length); -+ ptr++; -+ hexToInt(&ptr, &addr); -+ if (set_hw_break(breakno & 0x3, breaktype & 0x3 , length & 0x3, addr) -+ == 0) { -+ strcpy(remcomOutBuffer, "OK"); -+ } else { -+ strcpy(remcomOutBuffer, "ERROR"); -+ } -+ break; -+ -+ /* Remove hardware breakpoint */ -+ case 'y': -+ ptr = &remcomInBuffer[1]; -+ hexToInt(&ptr, &breakno); -+ if (remove_hw_break(breakno & 0x3) == 0) { -+ strcpy(remcomOutBuffer, "OK"); -+ } else { -+ strcpy(remcomOutBuffer, "ERROR"); -+ } -+ break; -+ case 'Z': -+ case 'z': -+ ptr = &remcomInBuffer[1]; -+ if (*ptr++ != bp_breakpoint) -+ break; -+ if (*(ptr++) != ',') { -+ strcpy(remcomOutBuffer, "ERROR"); -+ break; -+ } -+ hexToInt(&ptr, &addr); -+ if (remcomInBuffer[0] == 'Z') -+ ret = set_break(addr); -+ else -+ ret = remove_break(addr); -+ -+ if (ret == 0) { -+ strcpy(remcomOutBuffer, "OK"); -+ } else { -+ strcpy(remcomOutBuffer, "ERROR"); -+ } -+ break; -+ -+ } /* switch */ -+ -+ /* reply to the request */ -+ putpacket(remcomOutBuffer); -+ } -+} -+ -+/* this function is used to set up exception handlers for tracing and -+ breakpoints */ -+void set_debug_traps(void) -+{ -+ int i = 0; -+ /* -+ * linux_debug_hook is defined in traps.c. We store a pointer -+ * to our own exception handler into it. -+ */ -+ linux_debug_hook = handle_exception ; -+ -+ for (i=0; i 0) { -+ if ((count << 1) > (BUFMAX - 2)) { -+ wcount = (BUFMAX - 2) >> 1; -+ } else { -+ wcount = count; -+ } -+ count -= wcount; -+ for (i = 0; i < wcount; i++) { -+ bufptr = pack_hex_byte(bufptr, s[i]); -+ } -+ *bufptr = '\0'; -+ s += wcount; -+ -+ putpacket(gdbconbuf); -+ -+ } -+} -+#endif -+static int __init kgdb_opt_gdb(void) -+{ -+ gdb_enter = 1; -+ return 1; -+} -+static int __init kgdb_opt_gdbttyS(char *str) -+{ -+ gdb_ttyS = simple_strtoul(str,NULL,10); -+ return 1; -+} -+static int __init kgdb_opt_gdbbaud(char *str) -+{ -+ gdb_baud = simple_strtoul(str,NULL,10); -+ return 1; -+} -+ -+/* -+ * Sequence of these lines has to be maintained because gdb option is a prefix -+ * of the other two options -+ */ -+ -+__setup("gdbttyS=", kgdb_opt_gdbttyS); -+__setup("gdbbaud=", kgdb_opt_gdbbaud); -+__setup("gdb", kgdb_opt_gdb); ---- linux-2.4.18-p4smp/arch/i386/kernel/Makefile~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/arch/i386/kernel/Makefile 2003-07-09 13:15:23.000000000 -0600 -@@ -10,7 +10,15 @@ - .S.o: - $(CC) $(AFLAGS) -traditional -c $< -o $*.o - --all: kernel.o head.o init_task.o -+ifeq ($(CONFIG_X86_REMOTE_DEBUG),y) -+GDBSTART=gdbstart -+GDBCLEAN= -rm -f gdbstart /sbin/gdbstart -+else -+GDBSTART= -+GDBCLEAN= -+endif -+ -+all: kernel.o head.o init_task.o $(GDBSTART) - - O_TARGET := kernel.o - -@@ -33,6 +41,7 @@ endif - obj-$(CONFIG_MCA) += mca.o - obj-$(CONFIG_E820_PROC) += e820.o rpmhelper.o - obj-$(CONFIG_MTRR) += mtrr.o -+obj-$(CONFIG_X86_REMOTE_DEBUG) += gdbstub.o - obj-$(CONFIG_X86_MSR) += msr.o - obj-$(CONFIG_X86_CPUID) += cpuid.o - obj-$(CONFIG_MICROCODE) += microcode.o -@@ -51,4 +60,11 @@ obj-$(CONFIG_ABI) += lcall7.o - obj-$(CONFIG_MCL_COREDUMP) += crash.o - - -+gdbstart: gdbstart.o -+ ${HOSTCC} -o gdbstart gdbstart.o -+gdbstart.o: gdbstart.c -+ ${HOSTCC} -c -o gdbstart.o gdbstart.c -+ -+kernelclean: dummy -+ - include $(TOPDIR)/Rules.make ---- linux-2.4.18-p4smp/arch/i386/kernel/nmi.c~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/arch/i386/kernel/nmi.c 2003-07-09 13:15:23.000000000 -0600 -@@ -25,6 +25,20 @@ - #include - #include - -+#ifdef CONFIG_X86_REMOTE_DEBUG -+extern gdb_debug_hook * linux_debug_hook; -+#define CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after) \ -+ { \ -+ if (linux_debug_hook != (gdb_debug_hook *) NULL && !user_mode(regs)) \ -+ { \ -+ (*linux_debug_hook)(trapnr, signr, error_code, regs) ; \ -+ after; \ -+ } \ -+ } -+#else -+#define CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after) -+#endif -+ - unsigned int nmi_watchdog = NMI_NONE; - static unsigned int nmi_hz = HZ; - unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ -@@ -347,7 +361,20 @@ void nmi_watchdog_tick (struct pt_regs * - x86_do_profile(regs->eip); - - sum = irq_stat[cpu].apic_timer_irqs; -+#ifdef CONFIG_X86_REMOTE_DEBUG -+ if (kgdb_lock) { -+ -+ /* -+ * The machine is in kgdb, hold this cpu if already -+ * not held. -+ */ - -+ if (!procindebug[cpu] && kgdb_lock != (cpu + 1)) { -+ gdb_wait(regs); -+ } -+ alert_counter[cpu] = 0; -+ } else -+#endif - if (last_irq_sums[cpu] == sum) { - /* - * Ayiee, looks like this CPU is stuck ... -@@ -355,6 +382,9 @@ void nmi_watchdog_tick (struct pt_regs * - */ - alert_counter[cpu]++; - if (alert_counter[cpu] == 5*nmi_hz) { -+ -+ CHK_REMOTE_DEBUG(2,SIGSEGV,0,regs,) -+ - spin_lock(&nmi_print_lock); - /* - * We are in trouble anyway, lets at least try ---- linux-2.4.18-p4smp/arch/i386/kernel/signal.c~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/arch/i386/kernel/signal.c 2003-07-09 13:15:23.000000000 -0600 -@@ -701,7 +701,8 @@ int do_signal(struct pt_regs *regs, sigs - * have been cleared if the watchpoint triggered - * inside the kernel. - */ -- __asm__("movl %0,%%db7" : : "r" (current->thread.debugreg[7])); -+ if (current->thread.debugreg[7]) -+ __asm__("movl %0,%%db7" : : "r" (current->thread.debugreg[7])); - - /* Whee! Actually deliver the signal. */ - handle_signal(signr, ka, &info, oldset, regs); ---- linux-2.4.18-p4smp/arch/i386/kernel/traps.c~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/arch/i386/kernel/traps.c 2003-07-09 13:19:30.000000000 -0600 -@@ -49,12 +49,33 @@ - #endif - - #include -+#ifdef CONFIG_X86_REMOTE_DEBUG -+#include -+#endif - #include - - #ifdef CONFIG_MCL_COREDUMP - #include - #endif - -+#ifdef CONFIG_X86_REMOTE_DEBUG -+#include -+#endif -+ -+#ifdef CONFIG_X86_REMOTE_DEBUG -+gdb_debug_hook * linux_debug_hook; -+#define CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after) \ -+ { \ -+ if (linux_debug_hook != (gdb_debug_hook *) NULL && !user_mode(regs)) \ -+ { \ -+ (*linux_debug_hook)(trapnr, signr, error_code, regs) ; \ -+ after; \ -+ } \ -+ } -+#else -+#define CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after) -+#endif -+ - asmlinkage int system_call(void); - asmlinkage void lcall7(void); - asmlinkage void lcall27(void); -@@ -409,6 +430,7 @@ void die(const char * str, struct pt_reg - bust_spinlocks(1); - handle_BUG(regs); - printk("%s: %04lx\n", str, err & 0xffff); -+ CHK_REMOTE_DEBUG(1,SIGTRAP,err,regs,) - show_registers(regs); - if (netdump_func) - netdump_func(regs); -@@ -479,6 +501,7 @@ static void inline do_trap(int trapnr, i - #define DO_ERROR(trapnr, signr, str, name) \ - asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ - { \ -+ CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,)\ - do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \ - } - -@@ -496,7 +519,10 @@ asmlinkage void do_##name(struct pt_regs - #define DO_VM86_ERROR(trapnr, signr, str, name) \ - asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ - { \ -+ CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,goto skip_trap)\ - do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \ -+skip_trap: \ -+ return; \ - } - - #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ -@@ -548,6 +574,7 @@ gp_in_kernel: - regs->eip = fixup; - return; - } -+ CHK_REMOTE_DEBUG(13,SIGSEGV,error_code,regs,) - die("general protection fault", regs, error_code); - } - } -@@ -659,7 +686,7 @@ asmlinkage void do_debug(struct pt_regs - __asm__ __volatile__("movl %%db6,%0" : "=r" (condition)); - - /* If the user set TF, it's simplest to clear it right away. */ -- if ((eip >=PAGE_OFFSET) && (regs->eflags & TF_MASK)) -+ if ((eip >=PAGE_OFFSET) && (regs->eflags & TF_MASK) && !kgdb_step) - goto clear_TF; - - /* Mask out spurious debug traps due to lazy DR7 setting */ -@@ -675,7 +702,7 @@ asmlinkage void do_debug(struct pt_regs - tsk->thread.debugreg[6] = condition; - - /* Mask out spurious TF errors due to lazy TF clearing */ -- if (condition & DR_STEP) { -+ if (condition & DR_STEP && !kgdb_step) { - /* - * The TF error should be masked out only if the current - * process is not traced and if the TRAP flag has been set -@@ -698,11 +725,13 @@ asmlinkage void do_debug(struct pt_regs - info.si_errno = 0; - info.si_code = TRAP_BRKPT; - -- /* If this is a kernel mode trap, save the user PC on entry to -- * the kernel, that's what the debugger can make sense of. -- */ -- info.si_addr = ((regs->xcs & 3) == 0) ? (void *)tsk->thread.eip : -- (void *)regs->eip; -+ -+ /* If this is a kernel mode trap, we need to reset db7 to allow us -+ * to continue sanely */ -+ if ((regs->xcs & 3) == 0) -+ goto clear_dr7; -+ -+ info.si_addr = (void *)regs->eip; - force_sig_info(SIGTRAP, &info, tsk); - - /* Disable additional traps. They'll be re-enabled when -@@ -712,6 +741,7 @@ clear_dr7: - __asm__("movl %0,%%db7" - : /* no output */ - : "r" (0)); -+ CHK_REMOTE_DEBUG(1,SIGTRAP,error_code,regs,) - return; - - debug_vm86: ---- linux-2.4.18-p4smp/arch/i386/Makefile~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/arch/i386/Makefile 2003-07-09 13:15:23.000000000 -0600 -@@ -105,6 +105,11 @@ arch/i386/mm: dummy - $(MAKE) linuxsubdirs SUBDIRS=arch/i386/mm - - MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot -+ifeq ($(CONFIG_X86_REMOTE_DEBUG),y) -+CLEANKERNEL = $(MAKE) -C arch/$(ARCH)/kernel kernelclean -+else -+CLEANKERNEL = -+endif - - vmlinux: arch/i386/vmlinux.lds - -@@ -140,6 +145,7 @@ install: vmlinux - - archclean: - @$(MAKEBOOT) clean -+ @$(CLEANKERNEL) - - archmrproper: - ---- linux-2.4.18-p4smp/arch/i386/mm/fault.c~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/arch/i386/mm/fault.c 2003-07-09 13:15:23.000000000 -0600 -@@ -2,6 +2,11 @@ - * linux/arch/i386/mm/fault.c - * - * Copyright (C) 1995 Linus Torvalds -+ * -+ * Change History -+ * -+ * Tigran Aivazian Remote debugging support. -+ * - */ - - #include -@@ -19,6 +24,9 @@ - #include - #include - #include /* For unblank_screen() */ -+#ifdef CONFIG_X86_REMOTE_DEBUG -+#include -+#endif - - #include - #include -@@ -183,6 +191,15 @@ asmlinkage void do_page_fault(struct pt_ - if (in_interrupt() || !mm) - goto no_context; - -+#ifdef CONFIG_X86_REMOTE_DEBUG -+ if (kgdb_memerr_expected) { -+ if (linux_debug_hook != (gdb_debug_hook *) NULL) { -+ (*linux_debug_hook)(14, SIGSEGV, error_code, regs) ; -+ return; /* return w/modified regs */ -+ } -+ } -+#endif -+ - down_read(&mm->mmap_sem); - - vma = find_vma(mm, address); -@@ -301,6 +318,19 @@ no_context: - return; - } - -+#ifdef CONFIG_X86_REMOTE_DEBUG -+ if (kgdb_memerr_expected) { -+ if (linux_debug_hook != (gdb_debug_hook *) NULL) { -+ (*linux_debug_hook)(14, SIGSEGV, error_code, regs); -+ return; /* Return with modified registers */ -+ } -+ } else { -+ if (linux_debug_hook != (gdb_debug_hook *) NULL) { -+ (*linux_debug_hook)(14, SIGSEGV, error_code, regs); -+ } -+ } -+#endif -+ - /* - * Oops. The kernel tried to access some bad page. We'll have to - * terminate things with extreme prejudice. -@@ -308,6 +338,7 @@ no_context: - - bust_spinlocks(1); - -+ - if (address < PAGE_SIZE) - printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); - else ---- linux-2.4.18-p4smp/Documentation/Configure.help~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/Documentation/Configure.help 2003-07-09 13:15:23.000000000 -0600 -@@ -20274,6 +20274,29 @@ CONFIG_SGIWD93_SCSI - If you have a Western Digital WD93 SCSI controller on - an SGI MIPS system, say Y. Otherwise, say N. - -+KGDB: Remote (serial) kernel debugging with gdb -+CONFIG_X86_REMOTE_DEBUG -+ If you say Y here, it will be possible to remotely debug the x86 -+ 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. -+ To use this feature you need to perform some basic setup described -+ briefly in Documentation/i386/gdb-serial.txt. -+ This is only useful for kernel hackers. If unsure, say N. -+ -+KGDB: Thread analysis -+CONFIG_KGDB_THREAD -+ With thread analysis enabled, gdb can talk to kgdb stub to list -+ threads and to get stack trace for a thread. This option also enables -+ some code which helps gdb get exact status of thread. Thread analysis -+ adds some overhead to schedule and down functions. You can disable this -+ option if you do not want to compromise on speed. -+ -+KGDB: Console messagegs through gdb -+CONFIG_GDB_CONSOLE -+ If you say Y here, console messages will appear through gdb. -+ Other consoles such as tty or ttyS will continue to work as usual. -+ - Magic System Request Key support - CONFIG_MAGIC_SYSRQ - If you say Y here, you will have some control over the system even ---- /dev/null 2003-01-30 03:24:37.000000000 -0700 -+++ linux-2.4.18-p4smp-braam/Documentation/i386/gdb-serial.txt 2003-07-09 13:15:23.000000000 -0600 -@@ -0,0 +1,386 @@ -+Version -+======= -+ -+This version of the gdbstub package was developed and tested on -+kernel version 2.3.48. It will not install on a 2.2 kernel. It may -+not work on earlier versions of 2.3 kernels. It is possible that -+it will continue to work on later versions of 2.3 and then -+versions of 2.4 (I hope). -+ -+ -+Debugging Setup -+=============== -+ -+Designate one machine as the "development" machine. This is the -+machine on which you run your compiles and which has your source -+code for the kernel. Designate a second machine as the "target" -+machine. This is the machine that will run your experimental -+kernel. -+ -+The two machines will be connected together via a serial line out -+one or the other of the COM ports of the PC. You will need a modem -+eliminator and the appropriate cables. -+ -+On the DEVELOPMENT machine you need to apply the patch for the gdb -+hooks. You have probably already done that if you are reading this -+file. -+ -+On your DEVELOPMENT machine, go to your kernel source directory and -+do "make menuconfig". Go down to the kernel hacking menu item and -+open it up. Enable the kernel gdb stub code by selecting that item. -+ -+Save and exit the menuconfig program. Then do "make clean" and -+"make bzImage" (or whatever target you want to make). This gets -+the kernel compiled with the "-g" option set -- necessary for -+debugging. -+ -+You have just built the kernel on your DEVELOPMENT machine that you -+intend to run on our TARGET machine. -+ -+To install this new kernel, use the following installation procedure. -+Remember, you are on the DEVELOPMENT machine patching the kernel source -+for the kernel that you intend to run on the TARGET machine. -+ -+Copy this kernel to your target machine using your usual procedures. -+I usually arrange to copy development:/usr/src/linux/arch/i386/boot/zImage -+to /vmlinuz on the TARGET machine via a LAN based NFS access. That is, -+I run the cp command on the target and copy from the development machine -+via the LAN. Run Lilo on the new kernel on the target machine so that it -+will boot! Then boot the kernel on the target machine. -+ -+There is an utility program named "gdbstart" in the -+development:/usr/src/linux/arch/i386/kernel directory. -+You should copy this program over to your target machine, probably into -+/sbin. This utility program is run on the target machine to -+activate the kernel hooks for the debugger. It is invoked as follows: -+ -+ gdbstart [-s speed] [-t tty-dev] -+ defaults: /dev/ttyS0 with speed unmodified by gdbstart -+ -+Don't run the program just yet. We'll get to that in a bit. -+ -+Decide on which tty port you want the machines to communicate, then -+cable them up back-to-back using the null modem. COM1 is /dev/ttyS0 -+and COM2 is /dev/ttyS1. -+ -+On the DEVELOPMENT machine, create a file called .gdbinit in the -+directory /usr/src/linux. An example .gdbinit file looks like this: -+ -+define rmt -+set remotebaud 38400 -+target remote /dev/ttyS0 -+end -+ -+Assuming that you added my gdbinit stuff to your .gdbinit, edit .gdbinit -+and find the section that looks like this: -+ -+ define rmt -+ set remotebaud 38400 -+ target remote /dev/ttyS0 -+ end -+ -+Change the "target" definition so that it specifies the tty port that -+you intend to use. Change the "remotebaud" definition to match the -+data rate that you are going to use for the com line. -+ -+On the TARGET machine I find it helpful to create shell script file -+named "debug" in the root home directory with the following contents: -+ -+ gdbstart -s 38400 -t /dev/ttyS0 < -+ EOF -+ -+This runs the gdbstart program and gives it the carriage return that -+it prompts for. This sets the data rate from the target machine's side. -+ -+You are now ready to try it out. -+ -+On your TARGET machine, freshly rebooted with your gdbstub-equipped -+kernel, type "debug" in the root home directory. The system will appear -+to hang with some messages on the screen from the debug stub. What -+it is doing is waiting for contact from the development machine. -+ -+On your DEVELOPMENT machine, cd /usr/src/linux and enter "gdb vmlinux". -+When gdb gets the symbols loaded and prompts you, enter "rmt" (that's -+the macro from the .gdbinit file that you just edited). If everything -+is working correctly you should see gdb print out a few lines indicating -+that a breakpoint has been taken. It will actually show a line of -+code in the target kernel inside the gdbstub activation code. -+ -+The gdb interaction should look something like this: -+ -+ linux-dev:/usr/src/linux# gdb vmlinux -+ GDB is free software and you are welcome to distribute copies of it -+ under certain conditions; type "show copying" to see the conditions. -+ There is absolutely no warranty for GDB; type "show warranty" for details. -+ GDB 4.15.1 (i486-slackware-linux), -+ Copyright 1995 Free Software Foundation, Inc... -+ (gdb) rmt -+ breakpoint () at i386-stub.c:750 -+ 750 } -+ (gdb) -+ -+ -+You can now use whatever gdb commands you like to set breakpoints. -+Enter "continue" to start your target machine executing again. At this -+point the target system will run at full speed until it encounters -+your breakpoint or gets a segment violation in the kernel, or whatever. -+ -+ -+Triggering gdbstub at Kernel Boot Time -+====================================== -+ -+The gdbstub patch now has the ability for gdb to connect to the kernel during -+bootup (as opposed to waiting for the system to come all the way up and then -+running the gdbstart program on the target machine). This new functionality was -+added by Scott Foehner at SGI. -+ -+To force a kernel that has been compiled with gdbstub to pause during the boot -+process and wait for a connection from gdb, the paramter "gdb" should be passed -+to the kernel. This can be done by typing "gdb" after the name of the kernel -+on the LILO command line. The patch defaults to use ttyS1 at a baud rate of -+38400. These parameters can be changed by using "gdbttyS=" and -+"gdbbaud=" on the command line. -+ -+Example: -+ -+LILO boot: linux gdb gdbttyS=1 gdbbaud=38400 -+ -+Note that this command is entered on the TARGET machine as it is booting -+the kernel that was compiled on the DEVELOPMENT machine. -+ -+An alternate approach is to place a line in the /etc/lilo.conf file on -+your TARGET machine. Under the heading for the kernel that you intend -+to boot, place a line that looks like this: -+ -+ append = "gdb gdbttyS=1 gdbbaud=38400" -+ -+This will cause the kernel to enter the gdbstub automatically at boot -+time. -+ -+BE SURE to run "lilo" after changing the /etc/lilo.conf file. -+ -+ -+The "gdbstart" Program -+===================== -+ -+This utility program is used to set up the com port and data rate -+for the connection from the target system to the development system. -+Its usage has been described above. -+ -+This version of the patch uses the same tty ioctl for kernel versions -+2.0.30 onwards. Thus, the gdbstart utility does not need to be re-compiled -+to install the patch in a later version of the kernel. The ioctl added -+to the kernel for this purpose is far enough "off the end" of existing -+ioctls (as of 2.1.120) that it should not interfere with any new kernel -+tty ioctls for quite some time (famous last words). -+ -+The source for the gdbstart program resides in the arch/i386/kernel directory. -+ -+ -+Debugging hints -+=============== -+ -+You can break into the target machine at any time from the development -+machine by typing ^C. If the target machine has interrupts enabled -+this will stop it in the kernel and enter the debugger. -+ -+There is unfortunately no way of breaking into the kernel if it is -+in a loop with interrupts disabled, so if this happens to you then -+you need to place exploratory breakpoints or printk's into the kernel -+to find out where it is looping. -+ -+There is a copy of an e-mail in the kgdb distribution directory which -+describes how to create an NMI on an ISA bus machine using a paper -+clip. I have a sophisticated version of this made by wiring a push -+button switch into a PC104/ISA bus adapter card. The adapter card -+nicely furnishes wire wrap pins for all the ISA bus signals. -+ -+When you are done debugging the kernel on the target machine it is -+a good idea to leave it in a running state. This makes reboots -+faster, bypassing the fsck. So do a gdb "continue" as the last gdb -+command if this is possible. To terminate gdb itself on the development -+machine and leave the target machine running, type ^Z to suspend gdb -+and then kill it with "kill %1" or something similar. -+ -+If gdbstub Does Not Work -+======================== -+ -+If it doesn't work, you will have to troubleshoot it. Do the easy things -+first like double checking your cabling and data rates. You might -+try some non-kernel based programs to see if the back-to-back connection -+works properly. Just something simple like cat /etc/hosts >/dev/ttyS0 -+on one machine and cat /dev/ttyS0 on the other will tell you if you -+can send data from one machine to the other. There is no point in tearing -+out your hair in the kernel if the line doesn't work. -+ -+All of the real action takes place in the file -+/usr/src/linux/arch/i386/kernel/gdbstub.c. That is the code on the target -+machine that interacts with gdb on the development machine. In gdb you can -+turn on a debug switch with the following command: -+ -+ set remotedebug -+ -+This will print out the protocol messages that gdb is exchanging with -+the target machine. -+ -+Another place to look is /usr/src/linux/drivers/char/gdbserial.c -+That is the code that talks to the serial port on the target side. -+There might be a problem there. -+ -+If you are really desperate you can use printk debugging in the -+gdbstub code in the target kernel until you get it working. In particular, -+there is a global variable in /usr/src/linux/arch/i386/kernel/gdbstub.c -+named "remote_debug". Compile your kernel with this set to 1, rather -+than 0 and the debug stub will print out lots of stuff as it does -+what it does. -+ -+ -+Debugging Loadable Modules -+========================== -+ -+This technique comes courtesy of Edouard Parmelan -+ -+ -+When you run gdb, enter the command -+ -+source gdbinit-modules -+ -+This will read in a file of gdb macros that was installed in your -+kernel source directory with kgdb was installed. This file implements -+the following commands: -+ -+mod-list -+ Lists the loaded modules in the form -+ -+mod-print-symbols -+ Prints all the symbols in the indicated module. -+ -+mod-add-symbols -+ Loads the symbols from the object file and associates them -+ with the indicated module. -+ -+After you have loaded the module that you want to debug, use the command -+mod-list to find the of your module. Then use that -+address in the mod-add-symbols command to load your module's symbols. -+From that point onward you can debug your module as if it were a part -+of the kernel. -+ -+The file gdbinit-modules also contains a command named mod-add-lis as -+an example of how to construct a command of your own to load your -+favorite module. The idea is to "can" the pathname of the module -+in the command so you don't have to type so much. -+ -+Threads -+======= -+ -+Each process in a target machine is seen as a gdb thread. gdb thread related -+commands (info threads, thread n) can be used. -+ -+ia-32 hardware breakpoints -+========================== -+ -+gdb stub contains support for hardware breakpoints using debugging features -+of ia-32(x86) processors. These breakpoints do not need code modification. -+They use debugging registers. 4 hardware breakpoints are available in ia-32 -+processors. -+ -+Each hardware breakpoint can be of one of the following three types. -+1. Execution breakpoint - An Execution breakpoint is triggered when code at the -+ breakpoint address is executed. -+ -+ As limited number of hardware breakpoints are available, it is advisable -+ to use software breakpoints ( break command ) instead of execution -+ hardware breakpoints, unless modification of code is to be avoided. -+ -+2. Write breakpoint - A write breakpoint is triggered when memory location at the -+ breakpoint address is written. -+ -+ A write or can be placed for data of variable length. Length of a write -+ breakpoint indicates length of the datatype to be watched. Length is 1 -+ for 1 byte data , 2 for 2 byte data, 3 for 4 byte data. -+ -+3. Access breakpoint - An access breakpoint is triggered when memory location at -+ the breakpoint address is either read or written. -+ -+ Access breakpoints also have lengths similar to write breakpoints. -+ -+IO breakpoints in ia-32 are not supported. -+ -+Since gdb stub at present does not use the protocol used by gdb for hardware -+breakpoints, hardware breakpoints are accessed through gdb macros. gdb macros -+for hardware breakpoints are described below. -+ -+hwebrk - Places an execution breakpoint -+ hwebrk breakpointno address -+hwwbrk - Places a write breakpoint -+ hwwbrk breakpointno length address -+hwabrk - Places an access breakpoint -+ hwabrk breakpointno length address -+hwrmbrk - Removes a breakpoint -+ hwrmbrk breakpointno -+exinfo - Tells whether a software or hardware breakpoint has occured. -+ Prints number of the hardware breakpoint if a hardware breakpoint has -+ occured. -+ -+Arguments required by these commands are as follows -+breakpointno - 0 to 3 -+length - 1 to 3 -+address - Memory location in hex digits ( without 0x ) e.g c015e9bc -+ -+MP support -+========== -+ -+When a breakpoint occurs or user issues a break ( Ctrl + C ) to gdb client, -+all the processors are forced to enter the debugger. Current thread -+corresponds to the thread running on the processor where breakpoint occured. -+Threads running on other processor(s) appear similar to other non running -+threads in the 'info threads' output. -+ -+ia-32 hardware debugging registers on all processors are set to same values. -+Hence any hardware breakpoints may occur on any processor. -+ -+gdb troubleshooting -+=================== -+ -+1. gdb hangs -+Kill it. restart gdb. Connect to target machine. -+ -+2. gdb cannot connect to target machine (after killing a gdb and restarting -+another) -+If the target machine was not inside debugger when you killed gdb, gdb cannot -+connect because the target machine won't respond. -+In this case echo "Ctrl+C"(ascii 3) in the serial line. -+e.g. echo -e "\003" > /dev/ttyS1 -+This forces that target machine into debugger after which you can connect. -+ -+3. gdb cannot connect even after echoing Ctrl+C into serial line -+Try changing serial line settings min to 1 and time to 0 -+e.g. stty min 1 time 0 < /dev/ttyS1 -+Try echoing again -+ -+check serial line speed and set it to correct value if required -+e.g. stty ispeed 115200 ospeed 115200 < /dev/ttyS1 -+ -+Final Items -+=========== -+ -+I picked up this code from Dave Grothe and enhanced it. -+ -+If you make some really cool modification to this stuff, or if you -+fix a bug, please let me know. -+ -+Amit S. Kale -+ -+ -+(First kgdb by David Grothe ) -+ -+(modified by Tigran Aivazian ) -+ Putting gdbstub into the kernel config menu. -+ -+(modified by Scott Foehner ) -+ Hooks for entering gdbstub at boot time. -+ -+(modified by Amit S. Kale ) -+ Threads, ia-32 hw debugging, mp support, console support, -+ nmi watchdog handling. ---- /dev/null 2003-01-30 03:24:37.000000000 -0700 -+++ linux-2.4.18-p4smp-braam/drivers/char/gdbserial.c 2003-07-09 13:15:23.000000000 -0600 -@@ -0,0 +1,280 @@ -+/* -+ * Serial interface GDB stub -+ * -+ * Written (hacked together) by David Grothe (dave@gcom.com) -+ * -+ * Modified by Scott Foehner (sfoehner@engr.sgi.com) to allow connect -+ * on boot-up -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#undef PRNT /* define for debug printing */ -+ -+#define GDB_BUF_SIZE 512 /* power of 2, please */ -+ -+static char gdb_buf[GDB_BUF_SIZE] ; -+static int gdb_buf_in_inx ; -+static atomic_t gdb_buf_in_cnt ; -+static int gdb_buf_out_inx ; -+ -+extern void set_debug_traps(void) ; /* GDB routine */ -+extern struct serial_state * gdb_serial_setup(int ttyS, int baud); -+extern void shutdown_for_gdb(struct async_struct * info) ; -+ /* in serial.c */ -+ -+int gdb_irq; -+int gdb_port; -+int gdb_ttyS = 1; /* Default: ttyS1 */ -+int gdb_baud = 38400; -+int gdb_enter = 0; /* Default: do not do gdb_hook on boot */ -+int gdb_initialized = 0; -+ -+static int initialized = -1; -+ -+/* -+ * Get a byte from the hardware data buffer and return it -+ */ -+static int read_data_bfr(void) -+{ -+ if (inb(gdb_port + UART_LSR) & UART_LSR_DR) -+ return(inb(gdb_port + UART_RX)); -+ -+ return( -1 ) ; -+ -+} /* read_data_bfr */ -+ -+ -+/* -+ * Get a char if available, return -1 if nothing available. -+ * Empty the receive buffer first, then look at the interface hardware. -+ */ -+static int read_char(void) -+{ -+ if (atomic_read(&gdb_buf_in_cnt) != 0) /* intr routine has q'd chars */ -+ { -+ int chr ; -+ -+ chr = gdb_buf[gdb_buf_out_inx++] ; -+ gdb_buf_out_inx &= (GDB_BUF_SIZE - 1) ; -+ atomic_dec(&gdb_buf_in_cnt) ; -+ return(chr) ; -+ } -+ -+ return(read_data_bfr()) ; /* read from hardware */ -+ -+} /* read_char */ -+ -+/* -+ * Wait until the interface can accept a char, then write it. -+ */ -+static void write_char(int chr) -+{ -+ while ( !(inb(gdb_port + UART_LSR) & UART_LSR_THRE) ) ; -+ -+ outb(chr, gdb_port+UART_TX); -+ -+} /* write_char */ -+ -+/* -+ * This is the receiver interrupt routine for the GDB stub. -+ * It will receive a limited number of characters of input -+ * from the gdb host machine and save them up in a buffer. -+ * -+ * When the gdb stub routine getDebugChar() is called it -+ * draws characters out of the buffer until it is empty and -+ * then reads directly from the serial port. -+ * -+ * We do not attempt to write chars from the interrupt routine -+ * since the stubs do all of that via putDebugChar() which -+ * writes one byte after waiting for the interface to become -+ * ready. -+ * -+ * The debug stubs like to run with interrupts disabled since, -+ * after all, they run as a consequence of a breakpoint in -+ * the kernel. -+ * -+ * Perhaps someone who knows more about the tty driver than I -+ * care to learn can make this work for any low level serial -+ * driver. -+ */ -+static void gdb_interrupt(int irq, void *dev_id, struct pt_regs * regs) -+{ -+ int chr ; -+ int iir ; -+ -+ do -+ { -+ chr = read_data_bfr() ; -+ iir = inb(gdb_port + UART_IIR) ; -+#ifdef PRNT -+ printk("gdb_interrupt: chr=%02x '%c' after read iir=%02x\n", chr, -+ chr > ' ' && chr < 0x7F ? chr : ' ', iir) ; -+#endif -+ if (chr < 0) continue ; -+ -+ if (chr == 3) /* Ctrl-C means remote interrupt */ -+ { -+ breakpoint(); -+ continue ; -+ } -+ -+ if (atomic_read(&gdb_buf_in_cnt) >= GDB_BUF_SIZE) -+ { /* buffer overflow, clear it */ -+ gdb_buf_in_inx = 0 ; -+ atomic_set(&gdb_buf_in_cnt, 0) ; -+ gdb_buf_out_inx = 0 ; -+ break ; -+ } -+ -+ gdb_buf[gdb_buf_in_inx++] = chr ; -+ gdb_buf_in_inx &= (GDB_BUF_SIZE - 1) ; -+ atomic_inc(&gdb_buf_in_cnt) ; -+ } -+ while (iir & UART_IIR_RDI); -+ -+} /* gdb_interrupt */ -+ -+/* -+ * Just a NULL routine for testing. -+ */ -+void gdb_null(void) -+{ -+} /* gdb_null */ -+ -+ -+int gdb_hook(void) -+{ -+ int retval ; -+ struct serial_state *ser; -+ -+#ifdef CONFIG_SMP -+ if (smp_num_cpus > KGDB_MAX_NO_CPUS) { -+ printk("kgdb: too manu cpus. Cannot enable debugger with more than 8 cpus\n"); -+ return (-1); -+ } -+#endif -+ -+ /* -+ * Call first time just to get the ser ptr -+ */ -+ if((ser = gdb_serial_setup(gdb_ttyS, gdb_baud)) == 0) { -+ printk ("gdb_serial_setup() error"); -+ return(-1); -+ } -+ -+ gdb_port = ser->port; -+ gdb_irq = ser->irq; -+ -+ if (ser->info != NULL) -+ { -+ shutdown_for_gdb(ser->info) ; -+ /* -+ * Call second time to do the setup now that we have -+ * shut down the previous user of the interface. -+ */ -+ gdb_serial_setup(gdb_ttyS, gdb_baud) ; -+ } -+ -+ retval = request_irq(gdb_irq, -+ gdb_interrupt, -+ SA_INTERRUPT, -+ "GDB-stub", NULL); -+ if (retval == 0) -+ initialized = 1; -+ else -+ { -+ initialized = 0; -+ printk("gdb_hook: request_irq(irq=%d) failed: %d\n", gdb_irq, retval); -+ } -+ -+ /* -+ * Call GDB routine to setup the exception vectors for the debugger -+ */ -+ set_debug_traps() ; -+ -+ /* -+ * Call the breakpoint() routine in GDB to start the debugging -+ * session. -+ */ -+ printk("Waiting for connection from remote gdb... ") ; -+ breakpoint() ; -+ gdb_null() ; -+ -+ printk("Connected.\n"); -+ -+ gdb_initialized = 1; -+ return(0) ; -+ -+} /* gdb_hook_interrupt2 */ -+ -+/* -+ * getDebugChar -+ * -+ * This is a GDB stub routine. It waits for a character from the -+ * serial interface and then returns it. If there is no serial -+ * interface connection then it returns a bogus value which will -+ * almost certainly cause the system to hang. -+ */ -+int getDebugChar(void) -+{ -+ volatile int chr ; -+ -+#ifdef PRNT -+ printk("getDebugChar: ") ; -+#endif -+ -+ while ( (chr = read_char()) < 0 ) ; -+ -+ -+#ifdef PRNT -+ printk("%c\n", chr > ' ' && chr < 0x7F ? chr : ' ') ; -+#endif -+ return(chr) ; -+ -+} /* getDebugChar */ -+ -+/* -+ * putDebugChar -+ * -+ * This is a GDB stub routine. It waits until the interface is ready -+ * to transmit a char and then sends it. If there is no serial -+ * interface connection then it simply returns to its caller, having -+ * pretended to send the char. -+ */ -+void putDebugChar(int chr) -+{ -+#ifdef PRNT -+ printk("putDebugChar: chr=%02x '%c'\n", chr, -+ chr > ' ' && chr < 0x7F ? chr : ' ') ; -+#endif -+ -+ write_char(chr) ; /* this routine will wait */ -+ -+} /* putDebugChar */ -+ ---- linux-2.4.18-p4smp/drivers/char/Makefile~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/drivers/char/Makefile 2003-07-09 13:15:23.000000000 -0600 -@@ -142,6 +142,7 @@ ifeq ($(CONFIG_DUMMY_KEYB),y) - KEYBD = dummy_keyb.o - endif - -+obj-$(CONFIG_X86_REMOTE_DEBUG) += gdbserial.o - obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o $(CONSOLE) selection.o - obj-$(CONFIG_SERIAL) += $(SERIAL) - obj-$(CONFIG_SERIAL_HCDP) += hcdp_serial.o ---- linux-2.4.18-p4smp/drivers/char/serial.c~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/drivers/char/serial.c 2003-07-09 13:15:23.000000000 -0600 -@@ -4,6 +4,7 @@ - * Copyright (C) 1991, 1992 Linus Torvalds - * Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, - * 1998, 1999 Theodore Ts'o -+ * Copyright (C) 2000 VERITAS Software Corporation. - * - * Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92. Now - * much more extensible to support other serial cards based on the -@@ -34,6 +35,10 @@ - * 4/98: Added changes to support the ARM architecture proposed by - * Russell King - * -+ * 3/99: Added TIOCGDB for remote debugging with gdb if compiled with -+ * CONFIG_X86_REMOTE_DEBUG -+ * Tigran Aivazian -+ * - * 5/99: Updated to include support for the XR16C850 and ST16C654 - * uarts. Stuart MacDonald - * -@@ -66,6 +71,8 @@ - * to waiting processes - * Sapan Bhatia - * -+ * 10/00: added console support for kgdb. Amit Kale -+ * - */ - - static char *serial_version = "5.05c"; -@@ -215,7 +222,7 @@ static char *serial_revdate = "2001-07-0 - #include - #endif - #include --#ifdef CONFIG_SERIAL_CONSOLE -+#if defined(CONFIG_SERIAL_CONSOLE) || defined (CONFIG_GDB_CONSOLE) - #include - #endif - #ifdef ENABLE_SERIAL_PCI -@@ -235,6 +242,9 @@ static char *serial_revdate = "2001-07-0 - #if defined(LOCAL_HEADERS) || (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */ - #include "serial_compat.h" - #endif -+#ifdef CONFIG_X86_REMOTE_DEBUG -+#include -+#endif - - #include - #include -@@ -1586,6 +1596,12 @@ static void shutdown(struct async_struct - - spin_unlock_irqrestore( &info->irq_spinlock, flags); - } -+#ifdef CONFIG_X86_REMOTE_DEBUG -+void shutdown_for_gdb(struct async_struct * info) -+{ -+ shutdown(info) ; -+} -+#endif - - #if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */ - static int baud_table[] = { -@@ -2698,6 +2714,12 @@ static int rs_ioctl(struct tty_struct *t - printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); - return 0; - -+#ifdef CONFIG_X86_REMOTE_DEBUG -+ case TIOCGDB: -+ gdb_ttyS = MINOR(tty->device) & 0x03F ; -+ gdb_baud = tty_get_baud_rate(tty) ; -+ return gdb_hook(); -+#endif - default: - return -ENOIOCTLCMD; - } -@@ -6043,6 +6065,129 @@ void __init serial_console_init(void) - #endif - - /* -+ * ------------------------------------------------------------ -+ * Serial GDB driver (most in gdbserial.c) -+ * ------------------------------------------------------------ -+ */ -+ -+#ifdef CONFIG_X86_REMOTE_DEBUG -+#ifdef CONFIG_GDB_CONSOLE -+static struct console gdbcons = { -+ name: "gdb", -+ write: gdb_console_write, -+ flags: CON_PRINTBUFFER | CON_ENABLED, -+ index: -1, -+}; -+#endif -+ -+ -+/* -+ * Takes: -+ * ttyS - integer specifying which serial port to use for debugging -+ * baud - baud rate of specified serial port -+ * Returns: -+ * port for use by the gdb serial driver -+ */ -+struct serial_state * -+gdb_serial_setup(int ttyS, int baud) -+{ -+ struct serial_state *ser; -+ unsigned cval; -+ int bits = 8; -+ int parity = 'n'; -+ int cflag = CREAD | HUPCL | CLOCAL; -+ int quot = 0; -+ -+ /* -+ * Now construct a cflag setting. -+ */ -+ switch(baud) { -+ case 1200: -+ cflag |= B1200; -+ break; -+ case 2400: -+ cflag |= B2400; -+ break; -+ case 4800: -+ cflag |= B4800; -+ break; -+ case 19200: -+ cflag |= B19200; -+ break; -+ case 38400: -+ cflag |= B38400; -+ break; -+ case 57600: -+ cflag |= B57600; -+ break; -+ case 115200: -+ cflag |= B115200; -+ break; -+ case 9600: -+ default: -+ cflag |= B9600; -+ break; -+ } -+ switch(bits) { -+ case 7: -+ cflag |= CS7; -+ break; -+ default: -+ case 8: -+ cflag |= CS8; -+ break; -+ } -+ switch(parity) { -+ case 'o': case 'O': -+ cflag |= PARODD; -+ break; -+ case 'e': case 'E': -+ cflag |= PARENB; -+ break; -+ } -+ -+ /* -+ * Divisor, bytesize and parity -+ */ -+ -+ ser = rs_table + ttyS; -+ ser->flags &= ~ASYNC_BOOT_AUTOCONF; -+ quot = ser->baud_base / baud; -+ cval = cflag & (CSIZE | CSTOPB); -+ cval >>= 4; -+ if (cflag & PARENB) -+ cval |= UART_LCR_PARITY; -+ if (!(cflag & PARODD)) -+ cval |= UART_LCR_EPAR; -+ -+ /* -+ * Disable UART interrupts, set DTR and RTS high -+ * and set speed. -+ */ -+ cval = 0x3; -+ outb(cval | UART_LCR_DLAB, ser->port + UART_LCR); /* set DLAB */ -+ outb(quot & 0xff, ser->port + UART_DLL); /* LS of divisor */ -+ outb(quot >> 8, ser->port + UART_DLM); /* MS of divisor */ -+ outb(cval, ser->port + UART_LCR); /* reset DLAB */ -+ outb(UART_IER_RDI, ser->port + UART_IER); /* turn on interrupts*/ -+ outb(UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS, ser->port + UART_MCR); -+ -+ /* -+ * If we read 0xff from the LSR, there is no UART here. -+ */ -+ if (inb(ser->port + UART_LSR) == 0xff) -+ return 0; -+ return ser; -+} -+#ifdef CONFIG_GDB_CONSOLE -+void __init gdb_console_init(void) -+{ -+ register_console(&gdbcons); -+} -+#endif -+#endif /* CONFIG_X86_REMOTE_DEBUG */ -+ -+/* - Local variables: - compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -march=i586 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h -DEXPORT_SYMTAB -c serial.c" - End: ---- linux-2.4.18-p4smp/drivers/char/tty_io.c~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/drivers/char/tty_io.c 2003-07-09 13:15:23.000000000 -0600 -@@ -90,6 +90,9 @@ - #include - #include - #include -+#ifdef CONFIG_GDB_CONSOLE -+#include -+#endif - - #include - #include -@@ -2233,6 +2236,9 @@ void __init console_init(void) - #ifdef CONFIG_AU1000_SERIAL_CONSOLE - au1000_serial_console_init(); - #endif -+#ifdef CONFIG_GDB_CONSOLE -+ gdb_console_init(); -+#endif - #ifdef CONFIG_SERIAL_CONSOLE - #if (defined(CONFIG_8xx) || defined(CONFIG_8260)) - console_8xx_init(); ---- linux-2.4.18-p4smp/include/asm-i386/ioctls.h~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/include/asm-i386/ioctls.h 2003-07-09 13:15:23.000000000 -0600 -@@ -68,6 +68,7 @@ - #define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ - #define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ - #define FIOQSIZE 0x5460 -+#define TIOCGDB 0x547F /* enable GDB stub mode on this tty */ - - /* Used for packet mode */ - #define TIOCPKT_DATA 0 ---- linux-2.4.18-p4smp/include/asm-i386/page.h~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/include/asm-i386/page.h 2003-07-09 13:15:23.000000000 -0600 -@@ -95,6 +95,9 @@ typedef struct { unsigned long pgprot; } - * undefined" opcode for parsing in the trap handler. - */ - -+#ifdef CONFIG_X86_REMOTE_DEBUG -+#define BUG() KGDB_ASSERT("BUG", 0) -+#else - #if 1 /* Set to zero for a slightly smaller kernel */ - #define BUG() \ - __asm__ __volatile__( "ud2\n" \ -@@ -104,6 +107,7 @@ typedef struct { unsigned long pgprot; } - #else - #define BUG() __asm__ __volatile__("ud2\n") - #endif -+#endif - - #define PAGE_BUG(page) do { \ - BUG(); \ ---- linux-2.4.18-p4smp/include/asm-i386/processor.h~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/include/asm-i386/processor.h 2003-07-09 13:20:27.000000000 -0600 -@@ -390,6 +390,9 @@ struct thread_struct { - /* IO permissions */ - int ioperm; - unsigned long io_bitmap[IO_BITMAP_SIZE+1]; -+#ifdef CONFIG_X86_REMOTE_DEBUG -+ struct pt_regs *kgdbregs; -+#endif - /* performance counters */ - struct vperfctr *perfctr; - }; ---- linux-2.4.18-p4smp/include/linux/dcache.h~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/include/linux/dcache.h 2003-07-09 13:15:23.000000000 -0600 -@@ -4,6 +4,7 @@ - #ifdef __KERNEL__ - - #include -+#include - #include - - /* ---- /dev/null 2003-01-30 03:24:37.000000000 -0700 -+++ linux-2.4.18-p4smp-braam/include/linux/gdb.h 2003-07-09 13:15:23.000000000 -0600 -@@ -0,0 +1,63 @@ -+#ifndef _GDB_H_ -+#define _GDB_H_ -+ -+/* -+ * Copyright (C) 2001 Amit S. Kale -+ */ -+ -+/* gdb locks */ -+#define KGDB_MAX_NO_CPUS 8 -+ -+extern int gdb_enter; /* 1 = enter debugger on boot */ -+extern int gdb_ttyS; -+extern int gdb_baud; -+extern int gdb_initialized; -+ -+extern int gdb_hook(void); -+extern void breakpoint(void); -+ -+typedef int gdb_debug_hook(int trapno, -+ int signo, -+ int err_code, -+ struct pt_regs *regs); -+extern gdb_debug_hook *linux_debug_hook; -+ -+extern volatile unsigned kgdb_lock; -+ -+extern volatile int kgdb_memerr_expected; -+ -+extern volatile unsigned kgdb_step; -+ -+struct console; -+void gdb_console_write(struct console *co, const char *s, -+ unsigned count); -+void gdb_console_init(void); -+ -+extern volatile int procindebug[KGDB_MAX_NO_CPUS]; -+ -+void gdb_wait(struct pt_regs *regs); -+ -+#define KGDB_ASSERT(message, condition) do { \ -+ if (!(condition)) { \ -+ printk("kgdb assertion failed: %s\n", message); \ -+ asm ("int $0x3"); \ -+ } \ -+} while (0) -+ -+#define KA_VALID_ERRNO(errno) ((errno) > 0 && (errno) <= EMEDIUMTYPE) -+ -+#define KA_VALID_PTR_ERR(ptr) KA_VALID_ERRNO(-PTR_ERR(ptr)) -+ -+#define KA_VALID_KPTR(ptr) (!(ptr) || \ -+ ((void *)(ptr) >= (void *)PAGE_OFFSET && \ -+ (void *)(ptr) < ERR_PTR(-EMEDIUMTYPE))) -+ -+#define KA_VALID_PTRORERR(errptr) (KA_VALID_KPTR(errptr) || KA_VALID_PTR_ERR(errptr)) -+ -+#ifndef CONFIG_SMP -+#define KA_HELD_GKL() 1 -+#else -+#define KA_HELD_GKL() (current->lock_depth >= 0) -+#endif -+ -+#endif /* _GDB_H_ */ ---- linux-2.4.18-p4smp/include/linux/sched.h~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/include/linux/sched.h 2003-07-09 13:15:23.000000000 -0600 -@@ -159,7 +159,9 @@ extern int set_user(uid_t new_ruid, int - - #define MAX_SCHEDULE_TIMEOUT LONG_MAX - extern signed long FASTCALL(schedule_timeout(signed long timeout)); --asmlinkage void schedule(void); -+asmlinkage void do_schedule(void); -+asmlinkage void kern_schedule(void); -+asmlinkage void kern_do_schedule(struct pt_regs); - - extern int schedule_task(struct tq_struct *task); - extern void flush_scheduled_tasks(void); -@@ -1025,6 +1027,15 @@ static inline int need_resched(void) - return unlikely(current->need_resched); - } - -+static inline void schedule(void) -+{ -+#ifdef CONFIG_KGDB_THREAD -+ kern_schedule(); -+#else -+ do_schedule(); -+#endif -+} -+ - #endif /* __KERNEL__ */ - - #endif ---- linux-2.4.18-p4smp/init/main.c~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/init/main.c 2003-07-09 13:15:23.000000000 -0600 -@@ -57,6 +57,10 @@ - #include - #endif - -+#ifdef CONFIG_X86_REMOTE_DEBUG -+#include -+#endif -+ - #ifdef CONFIG_ISAPNP - #include - #endif -@@ -476,6 +480,11 @@ asmlinkage void __init start_kernel(void - * make syscalls (and thus be locked). - */ - smp_init(); -+#ifdef CONFIG_X86_REMOTE_DEBUG -+ if (gdb_enter) { -+ gdb_hook(); /* right at boot time */ -+ } -+#endif - - /* Do the rest non-__init'ed, we're now alive */ - rest_init(); ---- linux-2.4.18-p4smp/kernel/ksyms.c~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/kernel/ksyms.c 2003-07-09 13:15:23.000000000 -0600 -@@ -478,7 +478,10 @@ EXPORT_SYMBOL(sleep_on); - EXPORT_SYMBOL(sleep_on_timeout); - EXPORT_SYMBOL(interruptible_sleep_on); - EXPORT_SYMBOL(interruptible_sleep_on_timeout); --EXPORT_SYMBOL(schedule); -+EXPORT_SYMBOL(do_schedule); -+#ifdef CONFIG_KGDB_THREAD -+EXPORT_SYMBOL(kern_schedule); -+#endif - EXPORT_SYMBOL(schedule_timeout); - EXPORT_SYMBOL(sys_sched_yield); - EXPORT_SYMBOL(set_user_nice); ---- linux-2.4.18-p4smp/kernel/sched.c~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/kernel/sched.c 2003-07-09 13:15:23.000000000 -0600 -@@ -797,7 +797,7 @@ void scheduling_functions_start_here(voi - /* - * 'schedule()' is the main scheduler function. - */ --asmlinkage void schedule(void) -+asmlinkage void do_schedule(void) - { - task_t *prev, *next; - runqueue_t *rq; -@@ -879,6 +879,22 @@ switch_tasks: - goto need_resched; - } - -+asmlinkage void user_schedule(void) -+{ -+#ifdef CONFIG_KGDB_THREAD -+ current->thread.kgdbregs = NULL; -+#endif -+ do_schedule(); -+} -+ -+#ifdef CONFIG_KGDB_THREAD -+asmlinkage void kern_do_schedule(struct pt_regs regs) -+{ -+ current->thread.kgdbregs = ®s; -+ do_schedule(); -+} -+#endif -+ - /* - * The core wakeup function. Non-exclusive wakeups (nr_exclusive == 0) just - * wake everything up. If it's an exclusive wakeup (nr_exclusive == small +ve ---- linux-2.4.18-p4smp/Makefile~linux-2.4.18-14-kgdb-1.6 2003-07-09 13:14:53.000000000 -0600 -+++ linux-2.4.18-p4smp-braam/Makefile 2003-07-09 13:15:23.000000000 -0600 -@@ -101,9 +101,13 @@ CPPFLAGS := -D__KERNEL__ -I$(HPATH) - - CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ - -fno-strict-aliasing -fno-common -+ifeq ($(CONFIG_X86_REMOTE_DEBUG),y) -+CFLAGS += -g -+else - ifndef CONFIG_FRAME_POINTER - CFLAGS += -fomit-frame-pointer - endif -+endif - AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS) - - ifeq ($(CONFIG_MCL_COREDUMP),y) - -_ diff --git a/lustre/kernel_patches/pc/ext3_map_inode_page_chaos.pc b/lustre/kernel_patches/pc/ext3_map_inode_page_chaos.pc deleted file mode 100644 index 9ed5141..0000000 --- a/lustre/kernel_patches/pc/ext3_map_inode_page_chaos.pc +++ /dev/null @@ -1,2 +0,0 @@ -fs/ext3/inode.c -fs/ext3/ext3-exports.c diff --git a/lustre/kernel_patches/pc/linux-2.4.18-14-kgdb-1.6.pc b/lustre/kernel_patches/pc/linux-2.4.18-14-kgdb-1.6.pc deleted file mode 100644 index 44dc7de..0000000 --- a/lustre/kernel_patches/pc/linux-2.4.18-14-kgdb-1.6.pc +++ /dev/null @@ -1,26 +0,0 @@ -arch/i386/config.in -arch/i386/kernel/entry.S -arch/i386/kernel/gdbstart.c -arch/i386/kernel/gdbstub.c -arch/i386/kernel/Makefile -arch/i386/kernel/nmi.c -arch/i386/kernel/signal.c -arch/i386/kernel/traps.c -arch/i386/Makefile -arch/i386/mm/fault.c -Documentation/Configure.help -Documentation/i386/gdb-serial.txt -drivers/char/gdbserial.c -drivers/char/Makefile -drivers/char/serial.c -drivers/char/tty_io.c -include/asm-i386/ioctls.h -include/asm-i386/page.h -include/asm-i386/processor.h -include/linux/dcache.h -include/linux/gdb.h -include/linux/sched.h -init/main.c -kernel/ksyms.c -kernel/sched.c -Makefile diff --git a/lustre/kernel_patches/series/chaos-kgdb b/lustre/kernel_patches/series/chaos-kgdb deleted file mode 100644 index 933af4a1..0000000 --- a/lustre/kernel_patches/series/chaos-kgdb +++ /dev/null @@ -1,22 +0,0 @@ -linux-2.4.18-14-kgdb-1.6.patch -dev_read_only.patch -exports.patch -kmem_cache_validate.patch -lustre_version.patch -vfs_intent-2.4.18-18-chaos65.patch -invalidate_show.patch -iod-rmap-exports.patch -export-truncate.patch -htree-ext3-2.4.18.patch -linux-2.4.18ea-0.8.26.patch -ext3-2.4-ino_t.patch -ext3-2.4.18-ino_sb_macro.patch -ext3-orphan_lock.patch -ext3-delete_thread-2.4.18.patch -extN-misc-fixup.patch -extN-noread.patch -extN-wantedi.patch -extN-san.patch -extN-2.4.18-ino_sb_fixup.patch -ext3_map_inode_page_chaos.patch -iopen-2.4.18.patch diff --git a/lustre/kernel_patches/txt/ext3_map_inode_page_chaos.txt b/lustre/kernel_patches/txt/ext3_map_inode_page_chaos.txt deleted file mode 100644 index 010cdb7..0000000 --- a/lustre/kernel_patches/txt/ext3_map_inode_page_chaos.txt +++ /dev/null @@ -1,3 +0,0 @@ -DESC -(undescribed patch) -EDESC -- 1.8.3.1