📄 ia64-lite.patch
字号:
+ case 'P':+ {+ unsigned int regno;+ long v;+ char *ptr;++ ptr = &remcom_in_buffer[1];+ if ((!kgdb_usethread || kgdb_usethread == current) &&+ kgdb_hex2long(&ptr, &v) &&+ *ptr++ == '=' && (v >= 0)) {+ regno = (unsigned int)v;+ regno = (regno >= NUM_REGS ? 0 : regno);+ kgdb_put_reg(ptr, remcom_out_buffer, regno,+ unw_info, linux_regs);+ } else+ strcpy(remcom_out_buffer, "E01");+ break;+ }+ case 'c':+ case 's':+ if (e_vector == TRAP_BRKPT && err_code == KGDBBREAKNUM) {+ if (ia64_psr(linux_regs)->ri < 2)+ kgdb_pc(linux_regs, linux_regs->cr_iip ++ ia64_psr(linux_regs)->ri + 1);+ else+ kgdb_pc(linux_regs, linux_regs->cr_iip + 16);+ }++ /* try to read optional parameter, pc unchanged if no parm */+ ptr = &remcom_in_buffer[1];+ if (kgdb_hex2long(&ptr, &addr)) {+ linux_regs->cr_iip = addr;+ }+ newPC = linux_regs->cr_iip;++ /* clear the trace bit */+ linux_regs->cr_ipsr &= ~IA64_PSR_SS;++ atomic_set(&cpu_doing_single_step, -1);++ /* set the trace bit if we're stepping or took a hardware break */+ if (remcom_in_buffer[0] == 's' || e_vector == TRAP_HWBKPT) {+ linux_regs->cr_ipsr |= IA64_PSR_SS;+ debugger_step = 1;+ if (kgdb_contthread)+ atomic_set(&cpu_doing_single_step,+ smp_processor_id());+ }++ kgdb_correct_hw_break();++ /* if not hardware breakpoint, then reenable them */+ if (e_vector != TRAP_HWBKPT)+ linux_regs->cr_ipsr |= IA64_PSR_DB;+ else {+ kgdb_hwbreak_sstep[smp_processor_id()] = 1;+ linux_regs->cr_ipsr &= ~IA64_PSR_DB;+ }++ info->ret = 0;+ break;+ default:+ break;+ }++ return;+}++struct kgdb_arch arch_kgdb_ops = {+ .set_hw_breakpoint = kgdb_arch_set_hw_breakpoint,+ .remove_hw_breakpoint = kgdb_arch_remove_hw_breakpoint,+ .gdb_bpt_instr = {0xcc},+ .flags = KGDB_HW_BREAKPOINT,+};Index: linux-2.6.14-5-new-remove_all/arch/ia64/kernel/process.c===================================================================--- linux-2.6.14-5-new-remove_all.orig/arch/ia64/kernel/process.c 2006-02-02 09:03:12.000000000 +0530+++ linux-2.6.14-5-new-remove_all/arch/ia64/kernel/process.c 2006-02-02 09:08:07.000000000 +0530@@ -460,6 +460,9 @@ */ 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@@ -688,6 +691,9 @@ 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;Index: linux-2.6.14-5-new-remove_all/arch/ia64/kernel/smp.c===================================================================--- linux-2.6.14-5-new-remove_all.orig/arch/ia64/kernel/smp.c 2006-02-02 09:03:12.000000000 +0530+++ linux-2.6.14-5-new-remove_all/arch/ia64/kernel/smp.c 2006-02-02 09:08:07.000000000 +0530@@ -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 @@ #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 @@ case 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 @@ } 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.Index: linux-2.6.14-5-new-remove_all/arch/ia64/kernel/traps.c===================================================================--- linux-2.6.14-5-new-remove_all.orig/arch/ia64/kernel/traps.c 2006-02-02 09:03:12.000000000 +0530+++ linux-2.6.14-5-new-remove_all/arch/ia64/kernel/traps.c 2006-02-02 09:08:07.000000000 +0530@@ -196,8 +196,12 @@ break; default:- if (break_num < 0x40000 || break_num > 0x100000)+ if (break_num < 0x40000 || break_num > 0x100000) {+ if (notify_die(DIE_BREAK, "bad break", regs,+ break_num, TRAP_BRKPT, SIGTRAP) == NOTIFY_STOP)+ return; die_if_kernel("Bad break", regs, break_num);+ } if (break_num < 0x80000) { sig = SIGILL; code = __ILL_BREAK;Index: linux-2.6.14-5-new-remove_all/arch/ia64/kernel/Makefile===================================================================--- linux-2.6.14-5-new-remove_all.orig/arch/ia64/kernel/Makefile 2006-02-02 09:03:12.000000000 +0530+++ linux-2.6.14-5-new-remove_all/arch/ia64/kernel/Makefile 2006-02-02 09:08:07.000000000 +0530@@ -25,6 +25,7 @@ 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.oIndex: linux-2.6.14-5-new-remove_all/arch/ia64/kernel/unwind.c===================================================================--- linux-2.6.14-5-new-remove_all.orig/arch/ia64/kernel/unwind.c 2006-02-02 09:03:12.000000000 +0530+++ linux-2.6.14-5-new-remove_all/arch/ia64/kernel/unwind.c 2006-02-02 09:08:07.000000000 +0530@@ -72,10 +72,68 @@ # define STAT(x...) #endif +#ifdef CONFIG_KGDB+#define KGDB_EARLY_SIZE 100+static struct unw_reg_state __initdata kgdb_reg_state[KGDB_EARLY_SIZE];+static struct unw_labeled_state __initdata kgdb_labeled_state[KGDB_EARLY_SIZE];+void __initdata *kgdb_reg_state_free, __initdata *kgdb_labeled_state_free;++static void __init+kgdb_malloc_init(void)+{+ int i;++ kgdb_reg_state_free = kgdb_reg_state;+ for (i = 1; i < KGDB_EARLY_SIZE; i++) {+ *((unsigned long *) &kgdb_reg_state[i]) = (unsigned long) kgdb_reg_state_free;+ kgdb_reg_state_free = &kgdb_reg_state[i];+ }++ kgdb_labeled_state_free = kgdb_labeled_state;+ for (i = 1; i < KGDB_EARLY_SIZE; i++) {+ *((unsigned long *) &kgdb_labeled_state[i]) =+ (unsigned long) kgdb_labeled_state_free;+ kgdb_labeled_state_free = &kgdb_labeled_state[i];+ }++}++static void * __init+kgdb_malloc(void **mem)+{+ void *p;++ p = *mem;+ *mem = *((void **) p);+ return p;+}++static void __init+kgdb_free(void **mem, void *p)+{+ *((void **)p) = *mem;+ *mem = p;+}++#define alloc_reg_state() (!malloc_sizes[0].cs_cachep ? \+ kgdb_malloc(&kgdb_reg_state_free) : \+ kmalloc(sizeof(struct unw_reg_state), GFP_ATOMIC))+#define free_reg_state(usr) (!malloc_sizes[0].cs_cachep ? \+ kgdb_free(&kgdb_reg_state_free, usr) : \+ kfree(usr))+#define alloc_labeled_state() (!malloc_sizes[0].cs_cachep ? \+ kgdb_malloc(&kgdb_labeled_state_free) : \+ kmalloc(sizeof(struct unw_labeled_state), GFP_ATOMIC))+#define free_labeled_state(usr) (!malloc_sizes[0].cs_cachep ? \+ kgdb_free(&kgdb_labeled_state_free, usr) : \+ kfree(usr))++#else #define alloc_reg_state() kmalloc(sizeof(struct unw_reg_state), GFP_ATOMIC) #define free_reg_state(usr) kfree(usr) #define alloc_labeled_state() kmalloc(sizeof(struct unw_labeled_state), GFP_ATOMIC) #define free_labeled_state(usr) kfree(usr)+#endif typedef unsigned long unw_word; typedef unsigned char unw_hash_index_t;@@ -238,6 +296,24 @@ #endif }; +#ifdef CONFIG_KGDB+/*+ * This makes it safe to call breakpoint() very early+ * in setup_arch providing:+ * 1) breakpoint isn't called between lines in cpu_init+ * where init_mm.mm_count is incremented and ia64_mmu_init+ * is called. Otherwise the test below is invalid.+ * 2) the memory examined doesn't result in tlbmiss.+ */+static unsigned long inline kgdb_unimpl_va_mask(void)+{+ if (atomic_read(&init_mm.mm_count) > 1)+ return local_cpu_data->unimpl_va_mask;+ else+ return 0UL;+}+#endif+ static inline int read_only (void *addr) {@@ -1786,7 +1862,11 @@ case UNW_INSN_LOAD: #ifdef UNW_DEBUG+#ifdef CONFIG_KGDB+ if ((s[val] & (kgdb_unimpl_va_mask() | 0x7)) != 0+#else if ((s[val] & (local_cpu_data->unimpl_va_mask | 0x7)) != 0+#endif || s[val] < TASK_SIZE) { UNW_DPRINT(0, "unwind.%s: rejecting bad psp=0x%lx\n",@@ -1821,7 +1901,11 @@ struct unw_script *scr; unsigned long flags = 0; +#ifdef CONFIG_KGDB+ if ((info->ip & (kgdb_unimpl_va_mask() | 0xf)) || info->ip < TASK_SIZE) {+#else if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf)) || info->ip < TASK_SIZE) {+#endif /* don't let obviously bad addresses pollute the cache */ /* FIXME: should really be level 0 but it occurs too often. KAO */ UNW_DPRINT(1, "unwind.%s: rejecting bad ip=0x%lx\n", __FUNCTION__, info->ip);@@ -2249,6 +2333,9 @@ init_unwind_table(&unw.kernel_table, "kernel", KERNEL_START, (unsigned long) __gp, __start_unwind, __end_unwind);+#ifdef CONFIG_KGDB+ kgdb_malloc_init();+#endif } /*Index: linux-2.6.14-5-new-remove_all/arch/ia64/kernel/entry.S===================================================================--- linux-2.6.14-5-new-remove_all.orig/arch/ia64/kernel/entry.S 2006-02-02 09:03:12.000000000 +0530+++ linux-2.6.14-5-new-remove_all/arch/ia64/kernel/entry.S 2006-02-02 09:08:07.000000000 +0530@@ -952,9 +952,9 @@ 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 /*Index: linux-2.6.14-5-new-remove_all/arch/ia64/kernel/ivt.S===================================================================--- linux-2.6.14-5-new-remove_all.orig/arch/ia64/kernel/ivt.S 2006-02-02 09:03:12.000000000 +0530+++ linux-2.6.14-5-new-remove_all/arch/ia64/kernel/ivt.S 2006-02-02 09:08:07.000000000 +0530@@ -53,6 +53,14 @@ #include <asm/unistd.h> #include <asm/errno.h> +#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+ #if 1 # define PSR_DEFAULT_BITS psr.ac #else@@ -520,6 +528,7 @@ movl r14=ia64_leave_kernel ;; SAVE_REST+ KGDB_ENABLE_PSR_DB mov rp=r14 ;; adds out2=16,r12 // out2 = pointer to pt_regs@@ -861,6 +870,7 @@ 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@@ -1107,6 +1117,7 @@ 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@@ -1140,6 +1151,7 @@ adds r3=8,r2 // set up second base pointer ;; SAVE_REST+ KGDB_ENABLE_PSR_DB movl r14=ia64_leave_kernel ;; mov rp=r14@@ -1182,6 +1194,10 @@ 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=r14Index: linux-2.6.14-5-new-remove_all/lib/Kconfig.debug===================================================================--- linux-2.6.14-5-new-remove_all.orig/lib/Kconfig.debug 2006-02-02 09:08:06.000000000 +0530+++ linux-2.6.14-5-new-remove_all/lib/Kconfig.debug 2006-02-02 09:08:07.000000000 +0530@@ -209,7 +209,7 @@ config KGDB bool "KGDB: kernel debugging with remote gdb" select WANT_EXTRA_DEBUG_INFORMATION- depends on DEBUG_KERNEL && (X86 || MIPS || PPC)+ depends on DEBUG_KERNEL && (X86 || MIPS || IA64 || PPC) help If you say Y here, it will be possible to remotely debug the kernel using gdb. It is strongly suggested that you enableIndex: linux-2.6.14-5-new-remove_all/include/asm-ia64/kgdb.h===================================================================--- /dev/null 1970-01-01 00:00:00.000000000 +0000+++ linux-2.6.14-5-new-remove_all/include/asm-ia64/kgdb.h 2006-02-02 09:08:07.000000000 +0530@@ -0,0 +1,36 @@+#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 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__ */Index: linux-2.6.14-5-new-remove_all/include/asm-ia64/kdebug.h===================================================================--- linux-2.6.14-5-new-remove_all.orig/include/asm-ia64/kdebug.h 2006-02-02 09:03:12.000000000 +0530+++ linux-2.6.14-5-new-remove_all/include/asm-ia64/kdebug.h 2006-02-02 09:08:07.000000000 +0530@@ -68,6 +68,7 @@ DIE_KDEBUG_LEAVE, DIE_KDUMP_ENTER, DIE_KDUMP_LEAVE,+ DIE_PAGE_FAULT_NO_CONTEXT, }; static inline int notify_die(enum die_val val, char *str, struct pt_regs *regs,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -