Commit 95e14ed7fc4b2db62eb597a70850a0fede48b78a
Exists in
master
and in
4 other branches
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb: kdb: add usage string of 'per_cpu' command kgdb,x86_64: fix compile warning found with sparse kdb: code cleanup to use macro instead of value kgdboc,kgdbts: strlen() doesn't count the terminator
Showing 4 changed files Inline Diff
arch/x86/kernel/kgdb.c
1 | /* | 1 | /* |
2 | * This program is free software; you can redistribute it and/or modify it | 2 | * This program is free software; you can redistribute it and/or modify it |
3 | * under the terms of the GNU General Public License as published by the | 3 | * under the terms of the GNU General Public License as published by the |
4 | * Free Software Foundation; either version 2, or (at your option) any | 4 | * Free Software Foundation; either version 2, or (at your option) any |
5 | * later version. | 5 | * later version. |
6 | * | 6 | * |
7 | * This program is distributed in the hope that it will be useful, but | 7 | * This program is distributed in the hope that it will be useful, but |
8 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
10 | * General Public License for more details. | 10 | * General Public License for more details. |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* | 14 | /* |
15 | * Copyright (C) 2004 Amit S. Kale <amitkale@linsyssoft.com> | 15 | * Copyright (C) 2004 Amit S. Kale <amitkale@linsyssoft.com> |
16 | * Copyright (C) 2000-2001 VERITAS Software Corporation. | 16 | * Copyright (C) 2000-2001 VERITAS Software Corporation. |
17 | * Copyright (C) 2002 Andi Kleen, SuSE Labs | 17 | * Copyright (C) 2002 Andi Kleen, SuSE Labs |
18 | * Copyright (C) 2004 LinSysSoft Technologies Pvt. Ltd. | 18 | * Copyright (C) 2004 LinSysSoft Technologies Pvt. Ltd. |
19 | * Copyright (C) 2007 MontaVista Software, Inc. | 19 | * Copyright (C) 2007 MontaVista Software, Inc. |
20 | * Copyright (C) 2007-2008 Jason Wessel, Wind River Systems, Inc. | 20 | * Copyright (C) 2007-2008 Jason Wessel, Wind River Systems, Inc. |
21 | */ | 21 | */ |
22 | /**************************************************************************** | 22 | /**************************************************************************** |
23 | * Contributor: Lake Stevens Instrument Division$ | 23 | * Contributor: Lake Stevens Instrument Division$ |
24 | * Written by: Glenn Engel $ | 24 | * Written by: Glenn Engel $ |
25 | * Updated by: Amit Kale<akale@veritas.com> | 25 | * Updated by: Amit Kale<akale@veritas.com> |
26 | * Updated by: Tom Rini <trini@kernel.crashing.org> | 26 | * Updated by: Tom Rini <trini@kernel.crashing.org> |
27 | * Updated by: Jason Wessel <jason.wessel@windriver.com> | 27 | * Updated by: Jason Wessel <jason.wessel@windriver.com> |
28 | * Modified for 386 by Jim Kingdon, Cygnus Support. | 28 | * Modified for 386 by Jim Kingdon, Cygnus Support. |
29 | * Origianl kgdb, compatibility with 2.1.xx kernel by | 29 | * Origianl kgdb, compatibility with 2.1.xx kernel by |
30 | * David Grothe <dave@gcom.com> | 30 | * David Grothe <dave@gcom.com> |
31 | * Integrated into 2.2.5 kernel by Tigran Aivazian <tigran@sco.com> | 31 | * Integrated into 2.2.5 kernel by Tigran Aivazian <tigran@sco.com> |
32 | * X86_64 changes from Andi Kleen's patch merged by Jim Houston | 32 | * X86_64 changes from Andi Kleen's patch merged by Jim Houston |
33 | */ | 33 | */ |
34 | #include <linux/spinlock.h> | 34 | #include <linux/spinlock.h> |
35 | #include <linux/kdebug.h> | 35 | #include <linux/kdebug.h> |
36 | #include <linux/string.h> | 36 | #include <linux/string.h> |
37 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
38 | #include <linux/ptrace.h> | 38 | #include <linux/ptrace.h> |
39 | #include <linux/sched.h> | 39 | #include <linux/sched.h> |
40 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
41 | #include <linux/kgdb.h> | 41 | #include <linux/kgdb.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/smp.h> | 43 | #include <linux/smp.h> |
44 | #include <linux/nmi.h> | 44 | #include <linux/nmi.h> |
45 | #include <linux/hw_breakpoint.h> | 45 | #include <linux/hw_breakpoint.h> |
46 | 46 | ||
47 | #include <asm/debugreg.h> | 47 | #include <asm/debugreg.h> |
48 | #include <asm/apicdef.h> | 48 | #include <asm/apicdef.h> |
49 | #include <asm/system.h> | 49 | #include <asm/system.h> |
50 | #include <asm/apic.h> | 50 | #include <asm/apic.h> |
51 | #include <asm/nmi.h> | 51 | #include <asm/nmi.h> |
52 | 52 | ||
53 | struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = | 53 | struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = |
54 | { | 54 | { |
55 | #ifdef CONFIG_X86_32 | 55 | #ifdef CONFIG_X86_32 |
56 | { "ax", 4, offsetof(struct pt_regs, ax) }, | 56 | { "ax", 4, offsetof(struct pt_regs, ax) }, |
57 | { "cx", 4, offsetof(struct pt_regs, cx) }, | 57 | { "cx", 4, offsetof(struct pt_regs, cx) }, |
58 | { "dx", 4, offsetof(struct pt_regs, dx) }, | 58 | { "dx", 4, offsetof(struct pt_regs, dx) }, |
59 | { "bx", 4, offsetof(struct pt_regs, bx) }, | 59 | { "bx", 4, offsetof(struct pt_regs, bx) }, |
60 | { "sp", 4, offsetof(struct pt_regs, sp) }, | 60 | { "sp", 4, offsetof(struct pt_regs, sp) }, |
61 | { "bp", 4, offsetof(struct pt_regs, bp) }, | 61 | { "bp", 4, offsetof(struct pt_regs, bp) }, |
62 | { "si", 4, offsetof(struct pt_regs, si) }, | 62 | { "si", 4, offsetof(struct pt_regs, si) }, |
63 | { "di", 4, offsetof(struct pt_regs, di) }, | 63 | { "di", 4, offsetof(struct pt_regs, di) }, |
64 | { "ip", 4, offsetof(struct pt_regs, ip) }, | 64 | { "ip", 4, offsetof(struct pt_regs, ip) }, |
65 | { "flags", 4, offsetof(struct pt_regs, flags) }, | 65 | { "flags", 4, offsetof(struct pt_regs, flags) }, |
66 | { "cs", 4, offsetof(struct pt_regs, cs) }, | 66 | { "cs", 4, offsetof(struct pt_regs, cs) }, |
67 | { "ss", 4, offsetof(struct pt_regs, ss) }, | 67 | { "ss", 4, offsetof(struct pt_regs, ss) }, |
68 | { "ds", 4, offsetof(struct pt_regs, ds) }, | 68 | { "ds", 4, offsetof(struct pt_regs, ds) }, |
69 | { "es", 4, offsetof(struct pt_regs, es) }, | 69 | { "es", 4, offsetof(struct pt_regs, es) }, |
70 | { "fs", 4, -1 }, | 70 | { "fs", 4, -1 }, |
71 | { "gs", 4, -1 }, | 71 | { "gs", 4, -1 }, |
72 | #else | 72 | #else |
73 | { "ax", 8, offsetof(struct pt_regs, ax) }, | 73 | { "ax", 8, offsetof(struct pt_regs, ax) }, |
74 | { "bx", 8, offsetof(struct pt_regs, bx) }, | 74 | { "bx", 8, offsetof(struct pt_regs, bx) }, |
75 | { "cx", 8, offsetof(struct pt_regs, cx) }, | 75 | { "cx", 8, offsetof(struct pt_regs, cx) }, |
76 | { "dx", 8, offsetof(struct pt_regs, dx) }, | 76 | { "dx", 8, offsetof(struct pt_regs, dx) }, |
77 | { "si", 8, offsetof(struct pt_regs, dx) }, | 77 | { "si", 8, offsetof(struct pt_regs, dx) }, |
78 | { "di", 8, offsetof(struct pt_regs, di) }, | 78 | { "di", 8, offsetof(struct pt_regs, di) }, |
79 | { "bp", 8, offsetof(struct pt_regs, bp) }, | 79 | { "bp", 8, offsetof(struct pt_regs, bp) }, |
80 | { "sp", 8, offsetof(struct pt_regs, sp) }, | 80 | { "sp", 8, offsetof(struct pt_regs, sp) }, |
81 | { "r8", 8, offsetof(struct pt_regs, r8) }, | 81 | { "r8", 8, offsetof(struct pt_regs, r8) }, |
82 | { "r9", 8, offsetof(struct pt_regs, r9) }, | 82 | { "r9", 8, offsetof(struct pt_regs, r9) }, |
83 | { "r10", 8, offsetof(struct pt_regs, r10) }, | 83 | { "r10", 8, offsetof(struct pt_regs, r10) }, |
84 | { "r11", 8, offsetof(struct pt_regs, r11) }, | 84 | { "r11", 8, offsetof(struct pt_regs, r11) }, |
85 | { "r12", 8, offsetof(struct pt_regs, r12) }, | 85 | { "r12", 8, offsetof(struct pt_regs, r12) }, |
86 | { "r13", 8, offsetof(struct pt_regs, r13) }, | 86 | { "r13", 8, offsetof(struct pt_regs, r13) }, |
87 | { "r14", 8, offsetof(struct pt_regs, r14) }, | 87 | { "r14", 8, offsetof(struct pt_regs, r14) }, |
88 | { "r15", 8, offsetof(struct pt_regs, r15) }, | 88 | { "r15", 8, offsetof(struct pt_regs, r15) }, |
89 | { "ip", 8, offsetof(struct pt_regs, ip) }, | 89 | { "ip", 8, offsetof(struct pt_regs, ip) }, |
90 | { "flags", 4, offsetof(struct pt_regs, flags) }, | 90 | { "flags", 4, offsetof(struct pt_regs, flags) }, |
91 | { "cs", 4, offsetof(struct pt_regs, cs) }, | 91 | { "cs", 4, offsetof(struct pt_regs, cs) }, |
92 | { "ss", 4, offsetof(struct pt_regs, ss) }, | 92 | { "ss", 4, offsetof(struct pt_regs, ss) }, |
93 | #endif | 93 | #endif |
94 | }; | 94 | }; |
95 | 95 | ||
96 | int dbg_set_reg(int regno, void *mem, struct pt_regs *regs) | 96 | int dbg_set_reg(int regno, void *mem, struct pt_regs *regs) |
97 | { | 97 | { |
98 | if ( | 98 | if ( |
99 | #ifdef CONFIG_X86_32 | 99 | #ifdef CONFIG_X86_32 |
100 | regno == GDB_SS || regno == GDB_FS || regno == GDB_GS || | 100 | regno == GDB_SS || regno == GDB_FS || regno == GDB_GS || |
101 | #endif | 101 | #endif |
102 | regno == GDB_SP || regno == GDB_ORIG_AX) | 102 | regno == GDB_SP || regno == GDB_ORIG_AX) |
103 | return 0; | 103 | return 0; |
104 | 104 | ||
105 | if (dbg_reg_def[regno].offset != -1) | 105 | if (dbg_reg_def[regno].offset != -1) |
106 | memcpy((void *)regs + dbg_reg_def[regno].offset, mem, | 106 | memcpy((void *)regs + dbg_reg_def[regno].offset, mem, |
107 | dbg_reg_def[regno].size); | 107 | dbg_reg_def[regno].size); |
108 | return 0; | 108 | return 0; |
109 | } | 109 | } |
110 | 110 | ||
111 | char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs) | 111 | char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs) |
112 | { | 112 | { |
113 | if (regno == GDB_ORIG_AX) { | 113 | if (regno == GDB_ORIG_AX) { |
114 | memcpy(mem, ®s->orig_ax, sizeof(regs->orig_ax)); | 114 | memcpy(mem, ®s->orig_ax, sizeof(regs->orig_ax)); |
115 | return "orig_ax"; | 115 | return "orig_ax"; |
116 | } | 116 | } |
117 | if (regno >= DBG_MAX_REG_NUM || regno < 0) | 117 | if (regno >= DBG_MAX_REG_NUM || regno < 0) |
118 | return NULL; | 118 | return NULL; |
119 | 119 | ||
120 | if (dbg_reg_def[regno].offset != -1) | 120 | if (dbg_reg_def[regno].offset != -1) |
121 | memcpy(mem, (void *)regs + dbg_reg_def[regno].offset, | 121 | memcpy(mem, (void *)regs + dbg_reg_def[regno].offset, |
122 | dbg_reg_def[regno].size); | 122 | dbg_reg_def[regno].size); |
123 | 123 | ||
124 | switch (regno) { | ||
125 | #ifdef CONFIG_X86_32 | 124 | #ifdef CONFIG_X86_32 |
125 | switch (regno) { | ||
126 | case GDB_SS: | 126 | case GDB_SS: |
127 | if (!user_mode_vm(regs)) | 127 | if (!user_mode_vm(regs)) |
128 | *(unsigned long *)mem = __KERNEL_DS; | 128 | *(unsigned long *)mem = __KERNEL_DS; |
129 | break; | 129 | break; |
130 | case GDB_SP: | 130 | case GDB_SP: |
131 | if (!user_mode_vm(regs)) | 131 | if (!user_mode_vm(regs)) |
132 | *(unsigned long *)mem = kernel_stack_pointer(regs); | 132 | *(unsigned long *)mem = kernel_stack_pointer(regs); |
133 | break; | 133 | break; |
134 | case GDB_GS: | 134 | case GDB_GS: |
135 | case GDB_FS: | 135 | case GDB_FS: |
136 | *(unsigned long *)mem = 0xFFFF; | 136 | *(unsigned long *)mem = 0xFFFF; |
137 | break; | 137 | break; |
138 | #endif | ||
139 | } | 138 | } |
139 | #endif | ||
140 | return dbg_reg_def[regno].name; | 140 | return dbg_reg_def[regno].name; |
141 | } | 141 | } |
142 | 142 | ||
143 | /** | 143 | /** |
144 | * sleeping_thread_to_gdb_regs - Convert ptrace regs to GDB regs | 144 | * sleeping_thread_to_gdb_regs - Convert ptrace regs to GDB regs |
145 | * @gdb_regs: A pointer to hold the registers in the order GDB wants. | 145 | * @gdb_regs: A pointer to hold the registers in the order GDB wants. |
146 | * @p: The &struct task_struct of the desired process. | 146 | * @p: The &struct task_struct of the desired process. |
147 | * | 147 | * |
148 | * Convert the register values of the sleeping process in @p to | 148 | * Convert the register values of the sleeping process in @p to |
149 | * the format that GDB expects. | 149 | * the format that GDB expects. |
150 | * This function is called when kgdb does not have access to the | 150 | * This function is called when kgdb does not have access to the |
151 | * &struct pt_regs and therefore it should fill the gdb registers | 151 | * &struct pt_regs and therefore it should fill the gdb registers |
152 | * @gdb_regs with what has been saved in &struct thread_struct | 152 | * @gdb_regs with what has been saved in &struct thread_struct |
153 | * thread field during switch_to. | 153 | * thread field during switch_to. |
154 | */ | 154 | */ |
155 | void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) | 155 | void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) |
156 | { | 156 | { |
157 | #ifndef CONFIG_X86_32 | 157 | #ifndef CONFIG_X86_32 |
158 | u32 *gdb_regs32 = (u32 *)gdb_regs; | 158 | u32 *gdb_regs32 = (u32 *)gdb_regs; |
159 | #endif | 159 | #endif |
160 | gdb_regs[GDB_AX] = 0; | 160 | gdb_regs[GDB_AX] = 0; |
161 | gdb_regs[GDB_BX] = 0; | 161 | gdb_regs[GDB_BX] = 0; |
162 | gdb_regs[GDB_CX] = 0; | 162 | gdb_regs[GDB_CX] = 0; |
163 | gdb_regs[GDB_DX] = 0; | 163 | gdb_regs[GDB_DX] = 0; |
164 | gdb_regs[GDB_SI] = 0; | 164 | gdb_regs[GDB_SI] = 0; |
165 | gdb_regs[GDB_DI] = 0; | 165 | gdb_regs[GDB_DI] = 0; |
166 | gdb_regs[GDB_BP] = *(unsigned long *)p->thread.sp; | 166 | gdb_regs[GDB_BP] = *(unsigned long *)p->thread.sp; |
167 | #ifdef CONFIG_X86_32 | 167 | #ifdef CONFIG_X86_32 |
168 | gdb_regs[GDB_DS] = __KERNEL_DS; | 168 | gdb_regs[GDB_DS] = __KERNEL_DS; |
169 | gdb_regs[GDB_ES] = __KERNEL_DS; | 169 | gdb_regs[GDB_ES] = __KERNEL_DS; |
170 | gdb_regs[GDB_PS] = 0; | 170 | gdb_regs[GDB_PS] = 0; |
171 | gdb_regs[GDB_CS] = __KERNEL_CS; | 171 | gdb_regs[GDB_CS] = __KERNEL_CS; |
172 | gdb_regs[GDB_PC] = p->thread.ip; | 172 | gdb_regs[GDB_PC] = p->thread.ip; |
173 | gdb_regs[GDB_SS] = __KERNEL_DS; | 173 | gdb_regs[GDB_SS] = __KERNEL_DS; |
174 | gdb_regs[GDB_FS] = 0xFFFF; | 174 | gdb_regs[GDB_FS] = 0xFFFF; |
175 | gdb_regs[GDB_GS] = 0xFFFF; | 175 | gdb_regs[GDB_GS] = 0xFFFF; |
176 | #else | 176 | #else |
177 | gdb_regs32[GDB_PS] = *(unsigned long *)(p->thread.sp + 8); | 177 | gdb_regs32[GDB_PS] = *(unsigned long *)(p->thread.sp + 8); |
178 | gdb_regs32[GDB_CS] = __KERNEL_CS; | 178 | gdb_regs32[GDB_CS] = __KERNEL_CS; |
179 | gdb_regs32[GDB_SS] = __KERNEL_DS; | 179 | gdb_regs32[GDB_SS] = __KERNEL_DS; |
180 | gdb_regs[GDB_PC] = 0; | 180 | gdb_regs[GDB_PC] = 0; |
181 | gdb_regs[GDB_R8] = 0; | 181 | gdb_regs[GDB_R8] = 0; |
182 | gdb_regs[GDB_R9] = 0; | 182 | gdb_regs[GDB_R9] = 0; |
183 | gdb_regs[GDB_R10] = 0; | 183 | gdb_regs[GDB_R10] = 0; |
184 | gdb_regs[GDB_R11] = 0; | 184 | gdb_regs[GDB_R11] = 0; |
185 | gdb_regs[GDB_R12] = 0; | 185 | gdb_regs[GDB_R12] = 0; |
186 | gdb_regs[GDB_R13] = 0; | 186 | gdb_regs[GDB_R13] = 0; |
187 | gdb_regs[GDB_R14] = 0; | 187 | gdb_regs[GDB_R14] = 0; |
188 | gdb_regs[GDB_R15] = 0; | 188 | gdb_regs[GDB_R15] = 0; |
189 | #endif | 189 | #endif |
190 | gdb_regs[GDB_SP] = p->thread.sp; | 190 | gdb_regs[GDB_SP] = p->thread.sp; |
191 | } | 191 | } |
192 | 192 | ||
193 | static struct hw_breakpoint { | 193 | static struct hw_breakpoint { |
194 | unsigned enabled; | 194 | unsigned enabled; |
195 | unsigned long addr; | 195 | unsigned long addr; |
196 | int len; | 196 | int len; |
197 | int type; | 197 | int type; |
198 | struct perf_event * __percpu *pev; | 198 | struct perf_event * __percpu *pev; |
199 | } breakinfo[HBP_NUM]; | 199 | } breakinfo[HBP_NUM]; |
200 | 200 | ||
201 | static unsigned long early_dr7; | 201 | static unsigned long early_dr7; |
202 | 202 | ||
203 | static void kgdb_correct_hw_break(void) | 203 | static void kgdb_correct_hw_break(void) |
204 | { | 204 | { |
205 | int breakno; | 205 | int breakno; |
206 | 206 | ||
207 | for (breakno = 0; breakno < HBP_NUM; breakno++) { | 207 | for (breakno = 0; breakno < HBP_NUM; breakno++) { |
208 | struct perf_event *bp; | 208 | struct perf_event *bp; |
209 | struct arch_hw_breakpoint *info; | 209 | struct arch_hw_breakpoint *info; |
210 | int val; | 210 | int val; |
211 | int cpu = raw_smp_processor_id(); | 211 | int cpu = raw_smp_processor_id(); |
212 | if (!breakinfo[breakno].enabled) | 212 | if (!breakinfo[breakno].enabled) |
213 | continue; | 213 | continue; |
214 | if (dbg_is_early) { | 214 | if (dbg_is_early) { |
215 | set_debugreg(breakinfo[breakno].addr, breakno); | 215 | set_debugreg(breakinfo[breakno].addr, breakno); |
216 | early_dr7 |= encode_dr7(breakno, | 216 | early_dr7 |= encode_dr7(breakno, |
217 | breakinfo[breakno].len, | 217 | breakinfo[breakno].len, |
218 | breakinfo[breakno].type); | 218 | breakinfo[breakno].type); |
219 | set_debugreg(early_dr7, 7); | 219 | set_debugreg(early_dr7, 7); |
220 | continue; | 220 | continue; |
221 | } | 221 | } |
222 | bp = *per_cpu_ptr(breakinfo[breakno].pev, cpu); | 222 | bp = *per_cpu_ptr(breakinfo[breakno].pev, cpu); |
223 | info = counter_arch_bp(bp); | 223 | info = counter_arch_bp(bp); |
224 | if (bp->attr.disabled != 1) | 224 | if (bp->attr.disabled != 1) |
225 | continue; | 225 | continue; |
226 | bp->attr.bp_addr = breakinfo[breakno].addr; | 226 | bp->attr.bp_addr = breakinfo[breakno].addr; |
227 | bp->attr.bp_len = breakinfo[breakno].len; | 227 | bp->attr.bp_len = breakinfo[breakno].len; |
228 | bp->attr.bp_type = breakinfo[breakno].type; | 228 | bp->attr.bp_type = breakinfo[breakno].type; |
229 | info->address = breakinfo[breakno].addr; | 229 | info->address = breakinfo[breakno].addr; |
230 | info->len = breakinfo[breakno].len; | 230 | info->len = breakinfo[breakno].len; |
231 | info->type = breakinfo[breakno].type; | 231 | info->type = breakinfo[breakno].type; |
232 | val = arch_install_hw_breakpoint(bp); | 232 | val = arch_install_hw_breakpoint(bp); |
233 | if (!val) | 233 | if (!val) |
234 | bp->attr.disabled = 0; | 234 | bp->attr.disabled = 0; |
235 | } | 235 | } |
236 | if (!dbg_is_early) | 236 | if (!dbg_is_early) |
237 | hw_breakpoint_restore(); | 237 | hw_breakpoint_restore(); |
238 | } | 238 | } |
239 | 239 | ||
240 | static int hw_break_reserve_slot(int breakno) | 240 | static int hw_break_reserve_slot(int breakno) |
241 | { | 241 | { |
242 | int cpu; | 242 | int cpu; |
243 | int cnt = 0; | 243 | int cnt = 0; |
244 | struct perf_event **pevent; | 244 | struct perf_event **pevent; |
245 | 245 | ||
246 | if (dbg_is_early) | 246 | if (dbg_is_early) |
247 | return 0; | 247 | return 0; |
248 | 248 | ||
249 | for_each_online_cpu(cpu) { | 249 | for_each_online_cpu(cpu) { |
250 | cnt++; | 250 | cnt++; |
251 | pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu); | 251 | pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu); |
252 | if (dbg_reserve_bp_slot(*pevent)) | 252 | if (dbg_reserve_bp_slot(*pevent)) |
253 | goto fail; | 253 | goto fail; |
254 | } | 254 | } |
255 | 255 | ||
256 | return 0; | 256 | return 0; |
257 | 257 | ||
258 | fail: | 258 | fail: |
259 | for_each_online_cpu(cpu) { | 259 | for_each_online_cpu(cpu) { |
260 | cnt--; | 260 | cnt--; |
261 | if (!cnt) | 261 | if (!cnt) |
262 | break; | 262 | break; |
263 | pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu); | 263 | pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu); |
264 | dbg_release_bp_slot(*pevent); | 264 | dbg_release_bp_slot(*pevent); |
265 | } | 265 | } |
266 | return -1; | 266 | return -1; |
267 | } | 267 | } |
268 | 268 | ||
269 | static int hw_break_release_slot(int breakno) | 269 | static int hw_break_release_slot(int breakno) |
270 | { | 270 | { |
271 | struct perf_event **pevent; | 271 | struct perf_event **pevent; |
272 | int cpu; | 272 | int cpu; |
273 | 273 | ||
274 | if (dbg_is_early) | 274 | if (dbg_is_early) |
275 | return 0; | 275 | return 0; |
276 | 276 | ||
277 | for_each_online_cpu(cpu) { | 277 | for_each_online_cpu(cpu) { |
278 | pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu); | 278 | pevent = per_cpu_ptr(breakinfo[breakno].pev, cpu); |
279 | if (dbg_release_bp_slot(*pevent)) | 279 | if (dbg_release_bp_slot(*pevent)) |
280 | /* | 280 | /* |
281 | * The debugger is responsible for handing the retry on | 281 | * The debugger is responsible for handing the retry on |
282 | * remove failure. | 282 | * remove failure. |
283 | */ | 283 | */ |
284 | return -1; | 284 | return -1; |
285 | } | 285 | } |
286 | return 0; | 286 | return 0; |
287 | } | 287 | } |
288 | 288 | ||
289 | static int | 289 | static int |
290 | kgdb_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype bptype) | 290 | kgdb_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype bptype) |
291 | { | 291 | { |
292 | int i; | 292 | int i; |
293 | 293 | ||
294 | for (i = 0; i < HBP_NUM; i++) | 294 | for (i = 0; i < HBP_NUM; i++) |
295 | if (breakinfo[i].addr == addr && breakinfo[i].enabled) | 295 | if (breakinfo[i].addr == addr && breakinfo[i].enabled) |
296 | break; | 296 | break; |
297 | if (i == HBP_NUM) | 297 | if (i == HBP_NUM) |
298 | return -1; | 298 | return -1; |
299 | 299 | ||
300 | if (hw_break_release_slot(i)) { | 300 | if (hw_break_release_slot(i)) { |
301 | printk(KERN_ERR "Cannot remove hw breakpoint at %lx\n", addr); | 301 | printk(KERN_ERR "Cannot remove hw breakpoint at %lx\n", addr); |
302 | return -1; | 302 | return -1; |
303 | } | 303 | } |
304 | breakinfo[i].enabled = 0; | 304 | breakinfo[i].enabled = 0; |
305 | 305 | ||
306 | return 0; | 306 | return 0; |
307 | } | 307 | } |
308 | 308 | ||
309 | static void kgdb_remove_all_hw_break(void) | 309 | static void kgdb_remove_all_hw_break(void) |
310 | { | 310 | { |
311 | int i; | 311 | int i; |
312 | int cpu = raw_smp_processor_id(); | 312 | int cpu = raw_smp_processor_id(); |
313 | struct perf_event *bp; | 313 | struct perf_event *bp; |
314 | 314 | ||
315 | for (i = 0; i < HBP_NUM; i++) { | 315 | for (i = 0; i < HBP_NUM; i++) { |
316 | if (!breakinfo[i].enabled) | 316 | if (!breakinfo[i].enabled) |
317 | continue; | 317 | continue; |
318 | bp = *per_cpu_ptr(breakinfo[i].pev, cpu); | 318 | bp = *per_cpu_ptr(breakinfo[i].pev, cpu); |
319 | if (!bp->attr.disabled) { | 319 | if (!bp->attr.disabled) { |
320 | arch_uninstall_hw_breakpoint(bp); | 320 | arch_uninstall_hw_breakpoint(bp); |
321 | bp->attr.disabled = 1; | 321 | bp->attr.disabled = 1; |
322 | continue; | 322 | continue; |
323 | } | 323 | } |
324 | if (dbg_is_early) | 324 | if (dbg_is_early) |
325 | early_dr7 &= ~encode_dr7(i, breakinfo[i].len, | 325 | early_dr7 &= ~encode_dr7(i, breakinfo[i].len, |
326 | breakinfo[i].type); | 326 | breakinfo[i].type); |
327 | else if (hw_break_release_slot(i)) | 327 | else if (hw_break_release_slot(i)) |
328 | printk(KERN_ERR "KGDB: hw bpt remove failed %lx\n", | 328 | printk(KERN_ERR "KGDB: hw bpt remove failed %lx\n", |
329 | breakinfo[i].addr); | 329 | breakinfo[i].addr); |
330 | breakinfo[i].enabled = 0; | 330 | breakinfo[i].enabled = 0; |
331 | } | 331 | } |
332 | } | 332 | } |
333 | 333 | ||
334 | static int | 334 | static int |
335 | kgdb_set_hw_break(unsigned long addr, int len, enum kgdb_bptype bptype) | 335 | kgdb_set_hw_break(unsigned long addr, int len, enum kgdb_bptype bptype) |
336 | { | 336 | { |
337 | int i; | 337 | int i; |
338 | 338 | ||
339 | for (i = 0; i < HBP_NUM; i++) | 339 | for (i = 0; i < HBP_NUM; i++) |
340 | if (!breakinfo[i].enabled) | 340 | if (!breakinfo[i].enabled) |
341 | break; | 341 | break; |
342 | if (i == HBP_NUM) | 342 | if (i == HBP_NUM) |
343 | return -1; | 343 | return -1; |
344 | 344 | ||
345 | switch (bptype) { | 345 | switch (bptype) { |
346 | case BP_HARDWARE_BREAKPOINT: | 346 | case BP_HARDWARE_BREAKPOINT: |
347 | len = 1; | 347 | len = 1; |
348 | breakinfo[i].type = X86_BREAKPOINT_EXECUTE; | 348 | breakinfo[i].type = X86_BREAKPOINT_EXECUTE; |
349 | break; | 349 | break; |
350 | case BP_WRITE_WATCHPOINT: | 350 | case BP_WRITE_WATCHPOINT: |
351 | breakinfo[i].type = X86_BREAKPOINT_WRITE; | 351 | breakinfo[i].type = X86_BREAKPOINT_WRITE; |
352 | break; | 352 | break; |
353 | case BP_ACCESS_WATCHPOINT: | 353 | case BP_ACCESS_WATCHPOINT: |
354 | breakinfo[i].type = X86_BREAKPOINT_RW; | 354 | breakinfo[i].type = X86_BREAKPOINT_RW; |
355 | break; | 355 | break; |
356 | default: | 356 | default: |
357 | return -1; | 357 | return -1; |
358 | } | 358 | } |
359 | switch (len) { | 359 | switch (len) { |
360 | case 1: | 360 | case 1: |
361 | breakinfo[i].len = X86_BREAKPOINT_LEN_1; | 361 | breakinfo[i].len = X86_BREAKPOINT_LEN_1; |
362 | break; | 362 | break; |
363 | case 2: | 363 | case 2: |
364 | breakinfo[i].len = X86_BREAKPOINT_LEN_2; | 364 | breakinfo[i].len = X86_BREAKPOINT_LEN_2; |
365 | break; | 365 | break; |
366 | case 4: | 366 | case 4: |
367 | breakinfo[i].len = X86_BREAKPOINT_LEN_4; | 367 | breakinfo[i].len = X86_BREAKPOINT_LEN_4; |
368 | break; | 368 | break; |
369 | #ifdef CONFIG_X86_64 | 369 | #ifdef CONFIG_X86_64 |
370 | case 8: | 370 | case 8: |
371 | breakinfo[i].len = X86_BREAKPOINT_LEN_8; | 371 | breakinfo[i].len = X86_BREAKPOINT_LEN_8; |
372 | break; | 372 | break; |
373 | #endif | 373 | #endif |
374 | default: | 374 | default: |
375 | return -1; | 375 | return -1; |
376 | } | 376 | } |
377 | breakinfo[i].addr = addr; | 377 | breakinfo[i].addr = addr; |
378 | if (hw_break_reserve_slot(i)) { | 378 | if (hw_break_reserve_slot(i)) { |
379 | breakinfo[i].addr = 0; | 379 | breakinfo[i].addr = 0; |
380 | return -1; | 380 | return -1; |
381 | } | 381 | } |
382 | breakinfo[i].enabled = 1; | 382 | breakinfo[i].enabled = 1; |
383 | 383 | ||
384 | return 0; | 384 | return 0; |
385 | } | 385 | } |
386 | 386 | ||
387 | /** | 387 | /** |
388 | * kgdb_disable_hw_debug - Disable hardware debugging while we in kgdb. | 388 | * kgdb_disable_hw_debug - Disable hardware debugging while we in kgdb. |
389 | * @regs: Current &struct pt_regs. | 389 | * @regs: Current &struct pt_regs. |
390 | * | 390 | * |
391 | * This function will be called if the particular architecture must | 391 | * This function will be called if the particular architecture must |
392 | * disable hardware debugging while it is processing gdb packets or | 392 | * disable hardware debugging while it is processing gdb packets or |
393 | * handling exception. | 393 | * handling exception. |
394 | */ | 394 | */ |
395 | static void kgdb_disable_hw_debug(struct pt_regs *regs) | 395 | static void kgdb_disable_hw_debug(struct pt_regs *regs) |
396 | { | 396 | { |
397 | int i; | 397 | int i; |
398 | int cpu = raw_smp_processor_id(); | 398 | int cpu = raw_smp_processor_id(); |
399 | struct perf_event *bp; | 399 | struct perf_event *bp; |
400 | 400 | ||
401 | /* Disable hardware debugging while we are in kgdb: */ | 401 | /* Disable hardware debugging while we are in kgdb: */ |
402 | set_debugreg(0UL, 7); | 402 | set_debugreg(0UL, 7); |
403 | for (i = 0; i < HBP_NUM; i++) { | 403 | for (i = 0; i < HBP_NUM; i++) { |
404 | if (!breakinfo[i].enabled) | 404 | if (!breakinfo[i].enabled) |
405 | continue; | 405 | continue; |
406 | if (dbg_is_early) { | 406 | if (dbg_is_early) { |
407 | early_dr7 &= ~encode_dr7(i, breakinfo[i].len, | 407 | early_dr7 &= ~encode_dr7(i, breakinfo[i].len, |
408 | breakinfo[i].type); | 408 | breakinfo[i].type); |
409 | continue; | 409 | continue; |
410 | } | 410 | } |
411 | bp = *per_cpu_ptr(breakinfo[i].pev, cpu); | 411 | bp = *per_cpu_ptr(breakinfo[i].pev, cpu); |
412 | if (bp->attr.disabled == 1) | 412 | if (bp->attr.disabled == 1) |
413 | continue; | 413 | continue; |
414 | arch_uninstall_hw_breakpoint(bp); | 414 | arch_uninstall_hw_breakpoint(bp); |
415 | bp->attr.disabled = 1; | 415 | bp->attr.disabled = 1; |
416 | } | 416 | } |
417 | } | 417 | } |
418 | 418 | ||
419 | #ifdef CONFIG_SMP | 419 | #ifdef CONFIG_SMP |
420 | /** | 420 | /** |
421 | * kgdb_roundup_cpus - Get other CPUs into a holding pattern | 421 | * kgdb_roundup_cpus - Get other CPUs into a holding pattern |
422 | * @flags: Current IRQ state | 422 | * @flags: Current IRQ state |
423 | * | 423 | * |
424 | * On SMP systems, we need to get the attention of the other CPUs | 424 | * On SMP systems, we need to get the attention of the other CPUs |
425 | * and get them be in a known state. This should do what is needed | 425 | * and get them be in a known state. This should do what is needed |
426 | * to get the other CPUs to call kgdb_wait(). Note that on some arches, | 426 | * to get the other CPUs to call kgdb_wait(). Note that on some arches, |
427 | * the NMI approach is not used for rounding up all the CPUs. For example, | 427 | * the NMI approach is not used for rounding up all the CPUs. For example, |
428 | * in case of MIPS, smp_call_function() is used to roundup CPUs. In | 428 | * in case of MIPS, smp_call_function() is used to roundup CPUs. In |
429 | * this case, we have to make sure that interrupts are enabled before | 429 | * this case, we have to make sure that interrupts are enabled before |
430 | * calling smp_call_function(). The argument to this function is | 430 | * calling smp_call_function(). The argument to this function is |
431 | * the flags that will be used when restoring the interrupts. There is | 431 | * the flags that will be used when restoring the interrupts. There is |
432 | * local_irq_save() call before kgdb_roundup_cpus(). | 432 | * local_irq_save() call before kgdb_roundup_cpus(). |
433 | * | 433 | * |
434 | * On non-SMP systems, this is not called. | 434 | * On non-SMP systems, this is not called. |
435 | */ | 435 | */ |
436 | void kgdb_roundup_cpus(unsigned long flags) | 436 | void kgdb_roundup_cpus(unsigned long flags) |
437 | { | 437 | { |
438 | apic->send_IPI_allbutself(APIC_DM_NMI); | 438 | apic->send_IPI_allbutself(APIC_DM_NMI); |
439 | } | 439 | } |
440 | #endif | 440 | #endif |
441 | 441 | ||
442 | /** | 442 | /** |
443 | * kgdb_arch_handle_exception - Handle architecture specific GDB packets. | 443 | * kgdb_arch_handle_exception - Handle architecture specific GDB packets. |
444 | * @vector: The error vector of the exception that happened. | 444 | * @vector: The error vector of the exception that happened. |
445 | * @signo: The signal number of the exception that happened. | 445 | * @signo: The signal number of the exception that happened. |
446 | * @err_code: The error code of the exception that happened. | 446 | * @err_code: The error code of the exception that happened. |
447 | * @remcom_in_buffer: The buffer of the packet we have read. | 447 | * @remcom_in_buffer: The buffer of the packet we have read. |
448 | * @remcom_out_buffer: The buffer of %BUFMAX bytes to write a packet into. | 448 | * @remcom_out_buffer: The buffer of %BUFMAX bytes to write a packet into. |
449 | * @regs: The &struct pt_regs of the current process. | 449 | * @regs: The &struct pt_regs of the current process. |
450 | * | 450 | * |
451 | * This function MUST handle the 'c' and 's' command packets, | 451 | * This function MUST handle the 'c' and 's' command packets, |
452 | * as well packets to set / remove a hardware breakpoint, if used. | 452 | * as well packets to set / remove a hardware breakpoint, if used. |
453 | * If there are additional packets which the hardware needs to handle, | 453 | * If there are additional packets which the hardware needs to handle, |
454 | * they are handled here. The code should return -1 if it wants to | 454 | * they are handled here. The code should return -1 if it wants to |
455 | * process more packets, and a %0 or %1 if it wants to exit from the | 455 | * process more packets, and a %0 or %1 if it wants to exit from the |
456 | * kgdb callback. | 456 | * kgdb callback. |
457 | */ | 457 | */ |
458 | int kgdb_arch_handle_exception(int e_vector, int signo, int err_code, | 458 | int kgdb_arch_handle_exception(int e_vector, int signo, int err_code, |
459 | char *remcomInBuffer, char *remcomOutBuffer, | 459 | char *remcomInBuffer, char *remcomOutBuffer, |
460 | struct pt_regs *linux_regs) | 460 | struct pt_regs *linux_regs) |
461 | { | 461 | { |
462 | unsigned long addr; | 462 | unsigned long addr; |
463 | char *ptr; | 463 | char *ptr; |
464 | 464 | ||
465 | switch (remcomInBuffer[0]) { | 465 | switch (remcomInBuffer[0]) { |
466 | case 'c': | 466 | case 'c': |
467 | case 's': | 467 | case 's': |
468 | /* try to read optional parameter, pc unchanged if no parm */ | 468 | /* try to read optional parameter, pc unchanged if no parm */ |
469 | ptr = &remcomInBuffer[1]; | 469 | ptr = &remcomInBuffer[1]; |
470 | if (kgdb_hex2long(&ptr, &addr)) | 470 | if (kgdb_hex2long(&ptr, &addr)) |
471 | linux_regs->ip = addr; | 471 | linux_regs->ip = addr; |
472 | case 'D': | 472 | case 'D': |
473 | case 'k': | 473 | case 'k': |
474 | /* clear the trace bit */ | 474 | /* clear the trace bit */ |
475 | linux_regs->flags &= ~X86_EFLAGS_TF; | 475 | linux_regs->flags &= ~X86_EFLAGS_TF; |
476 | atomic_set(&kgdb_cpu_doing_single_step, -1); | 476 | atomic_set(&kgdb_cpu_doing_single_step, -1); |
477 | 477 | ||
478 | /* set the trace bit if we're stepping */ | 478 | /* set the trace bit if we're stepping */ |
479 | if (remcomInBuffer[0] == 's') { | 479 | if (remcomInBuffer[0] == 's') { |
480 | linux_regs->flags |= X86_EFLAGS_TF; | 480 | linux_regs->flags |= X86_EFLAGS_TF; |
481 | atomic_set(&kgdb_cpu_doing_single_step, | 481 | atomic_set(&kgdb_cpu_doing_single_step, |
482 | raw_smp_processor_id()); | 482 | raw_smp_processor_id()); |
483 | } | 483 | } |
484 | 484 | ||
485 | return 0; | 485 | return 0; |
486 | } | 486 | } |
487 | 487 | ||
488 | /* this means that we do not want to exit from the handler: */ | 488 | /* this means that we do not want to exit from the handler: */ |
489 | return -1; | 489 | return -1; |
490 | } | 490 | } |
491 | 491 | ||
492 | static inline int | 492 | static inline int |
493 | single_step_cont(struct pt_regs *regs, struct die_args *args) | 493 | single_step_cont(struct pt_regs *regs, struct die_args *args) |
494 | { | 494 | { |
495 | /* | 495 | /* |
496 | * Single step exception from kernel space to user space so | 496 | * Single step exception from kernel space to user space so |
497 | * eat the exception and continue the process: | 497 | * eat the exception and continue the process: |
498 | */ | 498 | */ |
499 | printk(KERN_ERR "KGDB: trap/step from kernel to user space, " | 499 | printk(KERN_ERR "KGDB: trap/step from kernel to user space, " |
500 | "resuming...\n"); | 500 | "resuming...\n"); |
501 | kgdb_arch_handle_exception(args->trapnr, args->signr, | 501 | kgdb_arch_handle_exception(args->trapnr, args->signr, |
502 | args->err, "c", "", regs); | 502 | args->err, "c", "", regs); |
503 | /* | 503 | /* |
504 | * Reset the BS bit in dr6 (pointed by args->err) to | 504 | * Reset the BS bit in dr6 (pointed by args->err) to |
505 | * denote completion of processing | 505 | * denote completion of processing |
506 | */ | 506 | */ |
507 | (*(unsigned long *)ERR_PTR(args->err)) &= ~DR_STEP; | 507 | (*(unsigned long *)ERR_PTR(args->err)) &= ~DR_STEP; |
508 | 508 | ||
509 | return NOTIFY_STOP; | 509 | return NOTIFY_STOP; |
510 | } | 510 | } |
511 | 511 | ||
512 | static int was_in_debug_nmi[NR_CPUS]; | 512 | static int was_in_debug_nmi[NR_CPUS]; |
513 | 513 | ||
514 | static int __kgdb_notify(struct die_args *args, unsigned long cmd) | 514 | static int __kgdb_notify(struct die_args *args, unsigned long cmd) |
515 | { | 515 | { |
516 | struct pt_regs *regs = args->regs; | 516 | struct pt_regs *regs = args->regs; |
517 | 517 | ||
518 | switch (cmd) { | 518 | switch (cmd) { |
519 | case DIE_NMI: | 519 | case DIE_NMI: |
520 | if (atomic_read(&kgdb_active) != -1) { | 520 | if (atomic_read(&kgdb_active) != -1) { |
521 | /* KGDB CPU roundup */ | 521 | /* KGDB CPU roundup */ |
522 | kgdb_nmicallback(raw_smp_processor_id(), regs); | 522 | kgdb_nmicallback(raw_smp_processor_id(), regs); |
523 | was_in_debug_nmi[raw_smp_processor_id()] = 1; | 523 | was_in_debug_nmi[raw_smp_processor_id()] = 1; |
524 | touch_nmi_watchdog(); | 524 | touch_nmi_watchdog(); |
525 | return NOTIFY_STOP; | 525 | return NOTIFY_STOP; |
526 | } | 526 | } |
527 | return NOTIFY_DONE; | 527 | return NOTIFY_DONE; |
528 | 528 | ||
529 | case DIE_NMIUNKNOWN: | 529 | case DIE_NMIUNKNOWN: |
530 | if (was_in_debug_nmi[raw_smp_processor_id()]) { | 530 | if (was_in_debug_nmi[raw_smp_processor_id()]) { |
531 | was_in_debug_nmi[raw_smp_processor_id()] = 0; | 531 | was_in_debug_nmi[raw_smp_processor_id()] = 0; |
532 | return NOTIFY_STOP; | 532 | return NOTIFY_STOP; |
533 | } | 533 | } |
534 | return NOTIFY_DONE; | 534 | return NOTIFY_DONE; |
535 | 535 | ||
536 | case DIE_DEBUG: | 536 | case DIE_DEBUG: |
537 | if (atomic_read(&kgdb_cpu_doing_single_step) != -1) { | 537 | if (atomic_read(&kgdb_cpu_doing_single_step) != -1) { |
538 | if (user_mode(regs)) | 538 | if (user_mode(regs)) |
539 | return single_step_cont(regs, args); | 539 | return single_step_cont(regs, args); |
540 | break; | 540 | break; |
541 | } else if (test_thread_flag(TIF_SINGLESTEP)) | 541 | } else if (test_thread_flag(TIF_SINGLESTEP)) |
542 | /* This means a user thread is single stepping | 542 | /* This means a user thread is single stepping |
543 | * a system call which should be ignored | 543 | * a system call which should be ignored |
544 | */ | 544 | */ |
545 | return NOTIFY_DONE; | 545 | return NOTIFY_DONE; |
546 | /* fall through */ | 546 | /* fall through */ |
547 | default: | 547 | default: |
548 | if (user_mode(regs)) | 548 | if (user_mode(regs)) |
549 | return NOTIFY_DONE; | 549 | return NOTIFY_DONE; |
550 | } | 550 | } |
551 | 551 | ||
552 | if (kgdb_handle_exception(args->trapnr, args->signr, cmd, regs)) | 552 | if (kgdb_handle_exception(args->trapnr, args->signr, cmd, regs)) |
553 | return NOTIFY_DONE; | 553 | return NOTIFY_DONE; |
554 | 554 | ||
555 | /* Must touch watchdog before return to normal operation */ | 555 | /* Must touch watchdog before return to normal operation */ |
556 | touch_nmi_watchdog(); | 556 | touch_nmi_watchdog(); |
557 | return NOTIFY_STOP; | 557 | return NOTIFY_STOP; |
558 | } | 558 | } |
559 | 559 | ||
560 | int kgdb_ll_trap(int cmd, const char *str, | 560 | int kgdb_ll_trap(int cmd, const char *str, |
561 | struct pt_regs *regs, long err, int trap, int sig) | 561 | struct pt_regs *regs, long err, int trap, int sig) |
562 | { | 562 | { |
563 | struct die_args args = { | 563 | struct die_args args = { |
564 | .regs = regs, | 564 | .regs = regs, |
565 | .str = str, | 565 | .str = str, |
566 | .err = err, | 566 | .err = err, |
567 | .trapnr = trap, | 567 | .trapnr = trap, |
568 | .signr = sig, | 568 | .signr = sig, |
569 | 569 | ||
570 | }; | 570 | }; |
571 | 571 | ||
572 | if (!kgdb_io_module_registered) | 572 | if (!kgdb_io_module_registered) |
573 | return NOTIFY_DONE; | 573 | return NOTIFY_DONE; |
574 | 574 | ||
575 | return __kgdb_notify(&args, cmd); | 575 | return __kgdb_notify(&args, cmd); |
576 | } | 576 | } |
577 | 577 | ||
578 | static int | 578 | static int |
579 | kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr) | 579 | kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr) |
580 | { | 580 | { |
581 | unsigned long flags; | 581 | unsigned long flags; |
582 | int ret; | 582 | int ret; |
583 | 583 | ||
584 | local_irq_save(flags); | 584 | local_irq_save(flags); |
585 | ret = __kgdb_notify(ptr, cmd); | 585 | ret = __kgdb_notify(ptr, cmd); |
586 | local_irq_restore(flags); | 586 | local_irq_restore(flags); |
587 | 587 | ||
588 | return ret; | 588 | return ret; |
589 | } | 589 | } |
590 | 590 | ||
591 | static struct notifier_block kgdb_notifier = { | 591 | static struct notifier_block kgdb_notifier = { |
592 | .notifier_call = kgdb_notify, | 592 | .notifier_call = kgdb_notify, |
593 | 593 | ||
594 | /* | 594 | /* |
595 | * Lowest-prio notifier priority, we want to be notified last: | 595 | * Lowest-prio notifier priority, we want to be notified last: |
596 | */ | 596 | */ |
597 | .priority = NMI_LOCAL_LOW_PRIOR, | 597 | .priority = NMI_LOCAL_LOW_PRIOR, |
598 | }; | 598 | }; |
599 | 599 | ||
600 | /** | 600 | /** |
601 | * kgdb_arch_init - Perform any architecture specific initalization. | 601 | * kgdb_arch_init - Perform any architecture specific initalization. |
602 | * | 602 | * |
603 | * This function will handle the initalization of any architecture | 603 | * This function will handle the initalization of any architecture |
604 | * specific callbacks. | 604 | * specific callbacks. |
605 | */ | 605 | */ |
606 | int kgdb_arch_init(void) | 606 | int kgdb_arch_init(void) |
607 | { | 607 | { |
608 | return register_die_notifier(&kgdb_notifier); | 608 | return register_die_notifier(&kgdb_notifier); |
609 | } | 609 | } |
610 | 610 | ||
611 | static void kgdb_hw_overflow_handler(struct perf_event *event, int nmi, | 611 | static void kgdb_hw_overflow_handler(struct perf_event *event, int nmi, |
612 | struct perf_sample_data *data, struct pt_regs *regs) | 612 | struct perf_sample_data *data, struct pt_regs *regs) |
613 | { | 613 | { |
614 | struct task_struct *tsk = current; | 614 | struct task_struct *tsk = current; |
615 | int i; | 615 | int i; |
616 | 616 | ||
617 | for (i = 0; i < 4; i++) | 617 | for (i = 0; i < 4; i++) |
618 | if (breakinfo[i].enabled) | 618 | if (breakinfo[i].enabled) |
619 | tsk->thread.debugreg6 |= (DR_TRAP0 << i); | 619 | tsk->thread.debugreg6 |= (DR_TRAP0 << i); |
620 | } | 620 | } |
621 | 621 | ||
622 | void kgdb_arch_late(void) | 622 | void kgdb_arch_late(void) |
623 | { | 623 | { |
624 | int i, cpu; | 624 | int i, cpu; |
625 | struct perf_event_attr attr; | 625 | struct perf_event_attr attr; |
626 | struct perf_event **pevent; | 626 | struct perf_event **pevent; |
627 | 627 | ||
628 | /* | 628 | /* |
629 | * Pre-allocate the hw breakpoint structions in the non-atomic | 629 | * Pre-allocate the hw breakpoint structions in the non-atomic |
630 | * portion of kgdb because this operation requires mutexs to | 630 | * portion of kgdb because this operation requires mutexs to |
631 | * complete. | 631 | * complete. |
632 | */ | 632 | */ |
633 | hw_breakpoint_init(&attr); | 633 | hw_breakpoint_init(&attr); |
634 | attr.bp_addr = (unsigned long)kgdb_arch_init; | 634 | attr.bp_addr = (unsigned long)kgdb_arch_init; |
635 | attr.bp_len = HW_BREAKPOINT_LEN_1; | 635 | attr.bp_len = HW_BREAKPOINT_LEN_1; |
636 | attr.bp_type = HW_BREAKPOINT_W; | 636 | attr.bp_type = HW_BREAKPOINT_W; |
637 | attr.disabled = 1; | 637 | attr.disabled = 1; |
638 | for (i = 0; i < HBP_NUM; i++) { | 638 | for (i = 0; i < HBP_NUM; i++) { |
639 | if (breakinfo[i].pev) | 639 | if (breakinfo[i].pev) |
640 | continue; | 640 | continue; |
641 | breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL); | 641 | breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL); |
642 | if (IS_ERR((void * __force)breakinfo[i].pev)) { | 642 | if (IS_ERR((void * __force)breakinfo[i].pev)) { |
643 | printk(KERN_ERR "kgdb: Could not allocate hw" | 643 | printk(KERN_ERR "kgdb: Could not allocate hw" |
644 | "breakpoints\nDisabling the kernel debugger\n"); | 644 | "breakpoints\nDisabling the kernel debugger\n"); |
645 | breakinfo[i].pev = NULL; | 645 | breakinfo[i].pev = NULL; |
646 | kgdb_arch_exit(); | 646 | kgdb_arch_exit(); |
647 | return; | 647 | return; |
648 | } | 648 | } |
649 | for_each_online_cpu(cpu) { | 649 | for_each_online_cpu(cpu) { |
650 | pevent = per_cpu_ptr(breakinfo[i].pev, cpu); | 650 | pevent = per_cpu_ptr(breakinfo[i].pev, cpu); |
651 | pevent[0]->hw.sample_period = 1; | 651 | pevent[0]->hw.sample_period = 1; |
652 | pevent[0]->overflow_handler = kgdb_hw_overflow_handler; | 652 | pevent[0]->overflow_handler = kgdb_hw_overflow_handler; |
653 | if (pevent[0]->destroy != NULL) { | 653 | if (pevent[0]->destroy != NULL) { |
654 | pevent[0]->destroy = NULL; | 654 | pevent[0]->destroy = NULL; |
655 | release_bp_slot(*pevent); | 655 | release_bp_slot(*pevent); |
656 | } | 656 | } |
657 | } | 657 | } |
658 | } | 658 | } |
659 | } | 659 | } |
660 | 660 | ||
661 | /** | 661 | /** |
662 | * kgdb_arch_exit - Perform any architecture specific uninitalization. | 662 | * kgdb_arch_exit - Perform any architecture specific uninitalization. |
663 | * | 663 | * |
664 | * This function will handle the uninitalization of any architecture | 664 | * This function will handle the uninitalization of any architecture |
665 | * specific callbacks, for dynamic registration and unregistration. | 665 | * specific callbacks, for dynamic registration and unregistration. |
666 | */ | 666 | */ |
667 | void kgdb_arch_exit(void) | 667 | void kgdb_arch_exit(void) |
668 | { | 668 | { |
669 | int i; | 669 | int i; |
670 | for (i = 0; i < 4; i++) { | 670 | for (i = 0; i < 4; i++) { |
671 | if (breakinfo[i].pev) { | 671 | if (breakinfo[i].pev) { |
672 | unregister_wide_hw_breakpoint(breakinfo[i].pev); | 672 | unregister_wide_hw_breakpoint(breakinfo[i].pev); |
673 | breakinfo[i].pev = NULL; | 673 | breakinfo[i].pev = NULL; |
674 | } | 674 | } |
675 | } | 675 | } |
676 | unregister_die_notifier(&kgdb_notifier); | 676 | unregister_die_notifier(&kgdb_notifier); |
677 | } | 677 | } |
678 | 678 | ||
679 | /** | 679 | /** |
680 | * | 680 | * |
681 | * kgdb_skipexception - Bail out of KGDB when we've been triggered. | 681 | * kgdb_skipexception - Bail out of KGDB when we've been triggered. |
682 | * @exception: Exception vector number | 682 | * @exception: Exception vector number |
683 | * @regs: Current &struct pt_regs. | 683 | * @regs: Current &struct pt_regs. |
684 | * | 684 | * |
685 | * On some architectures we need to skip a breakpoint exception when | 685 | * On some architectures we need to skip a breakpoint exception when |
686 | * it occurs after a breakpoint has been removed. | 686 | * it occurs after a breakpoint has been removed. |
687 | * | 687 | * |
688 | * Skip an int3 exception when it occurs after a breakpoint has been | 688 | * Skip an int3 exception when it occurs after a breakpoint has been |
689 | * removed. Backtrack eip by 1 since the int3 would have caused it to | 689 | * removed. Backtrack eip by 1 since the int3 would have caused it to |
690 | * increment by 1. | 690 | * increment by 1. |
691 | */ | 691 | */ |
692 | int kgdb_skipexception(int exception, struct pt_regs *regs) | 692 | int kgdb_skipexception(int exception, struct pt_regs *regs) |
693 | { | 693 | { |
694 | if (exception == 3 && kgdb_isremovedbreak(regs->ip - 1)) { | 694 | if (exception == 3 && kgdb_isremovedbreak(regs->ip - 1)) { |
695 | regs->ip -= 1; | 695 | regs->ip -= 1; |
696 | return 1; | 696 | return 1; |
697 | } | 697 | } |
698 | return 0; | 698 | return 0; |
699 | } | 699 | } |
700 | 700 | ||
701 | unsigned long kgdb_arch_pc(int exception, struct pt_regs *regs) | 701 | unsigned long kgdb_arch_pc(int exception, struct pt_regs *regs) |
702 | { | 702 | { |
703 | if (exception == 3) | 703 | if (exception == 3) |
704 | return instruction_pointer(regs) - 1; | 704 | return instruction_pointer(regs) - 1; |
705 | return instruction_pointer(regs); | 705 | return instruction_pointer(regs); |
706 | } | 706 | } |
707 | 707 | ||
708 | void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) | 708 | void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) |
709 | { | 709 | { |
710 | regs->ip = ip; | 710 | regs->ip = ip; |
711 | } | 711 | } |
712 | 712 | ||
713 | struct kgdb_arch arch_kgdb_ops = { | 713 | struct kgdb_arch arch_kgdb_ops = { |
714 | /* Breakpoint instruction: */ | 714 | /* Breakpoint instruction: */ |
715 | .gdb_bpt_instr = { 0xcc }, | 715 | .gdb_bpt_instr = { 0xcc }, |
716 | .flags = KGDB_HW_BREAKPOINT, | 716 | .flags = KGDB_HW_BREAKPOINT, |
717 | .set_hw_breakpoint = kgdb_set_hw_break, | 717 | .set_hw_breakpoint = kgdb_set_hw_break, |
718 | .remove_hw_breakpoint = kgdb_remove_hw_break, | 718 | .remove_hw_breakpoint = kgdb_remove_hw_break, |
719 | .disable_hw_break = kgdb_disable_hw_debug, | 719 | .disable_hw_break = kgdb_disable_hw_debug, |
720 | .remove_all_hw_break = kgdb_remove_all_hw_break, | 720 | .remove_all_hw_break = kgdb_remove_all_hw_break, |
721 | .correct_hw_break = kgdb_correct_hw_break, | 721 | .correct_hw_break = kgdb_correct_hw_break, |
drivers/misc/kgdbts.c
1 | /* | 1 | /* |
2 | * kgdbts is a test suite for kgdb for the sole purpose of validating | 2 | * kgdbts is a test suite for kgdb for the sole purpose of validating |
3 | * that key pieces of the kgdb internals are working properly such as | 3 | * that key pieces of the kgdb internals are working properly such as |
4 | * HW/SW breakpoints, single stepping, and NMI. | 4 | * HW/SW breakpoints, single stepping, and NMI. |
5 | * | 5 | * |
6 | * Created by: Jason Wessel <jason.wessel@windriver.com> | 6 | * Created by: Jason Wessel <jason.wessel@windriver.com> |
7 | * | 7 | * |
8 | * Copyright (c) 2008 Wind River Systems, Inc. | 8 | * Copyright (c) 2008 Wind River Systems, Inc. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | * | 13 | * |
14 | * This program is distributed in the hope that it will be useful, | 14 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | * See the GNU General Public License for more details. | 17 | * See the GNU General Public License for more details. |
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with this program; if not, write to the Free Software | 20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
22 | */ | 22 | */ |
23 | /* Information about the kgdb test suite. | 23 | /* Information about the kgdb test suite. |
24 | * ------------------------------------- | 24 | * ------------------------------------- |
25 | * | 25 | * |
26 | * The kgdb test suite is designed as a KGDB I/O module which | 26 | * The kgdb test suite is designed as a KGDB I/O module which |
27 | * simulates the communications that a debugger would have with kgdb. | 27 | * simulates the communications that a debugger would have with kgdb. |
28 | * The tests are broken up in to a line by line and referenced here as | 28 | * The tests are broken up in to a line by line and referenced here as |
29 | * a "get" which is kgdb requesting input and "put" which is kgdb | 29 | * a "get" which is kgdb requesting input and "put" which is kgdb |
30 | * sending a response. | 30 | * sending a response. |
31 | * | 31 | * |
32 | * The kgdb suite can be invoked from the kernel command line | 32 | * The kgdb suite can be invoked from the kernel command line |
33 | * arguments system or executed dynamically at run time. The test | 33 | * arguments system or executed dynamically at run time. The test |
34 | * suite uses the variable "kgdbts" to obtain the information about | 34 | * suite uses the variable "kgdbts" to obtain the information about |
35 | * which tests to run and to configure the verbosity level. The | 35 | * which tests to run and to configure the verbosity level. The |
36 | * following are the various characters you can use with the kgdbts= | 36 | * following are the various characters you can use with the kgdbts= |
37 | * line: | 37 | * line: |
38 | * | 38 | * |
39 | * When using the "kgdbts=" you only choose one of the following core | 39 | * When using the "kgdbts=" you only choose one of the following core |
40 | * test types: | 40 | * test types: |
41 | * A = Run all the core tests silently | 41 | * A = Run all the core tests silently |
42 | * V1 = Run all the core tests with minimal output | 42 | * V1 = Run all the core tests with minimal output |
43 | * V2 = Run all the core tests in debug mode | 43 | * V2 = Run all the core tests in debug mode |
44 | * | 44 | * |
45 | * You can also specify optional tests: | 45 | * You can also specify optional tests: |
46 | * N## = Go to sleep with interrupts of for ## seconds | 46 | * N## = Go to sleep with interrupts of for ## seconds |
47 | * to test the HW NMI watchdog | 47 | * to test the HW NMI watchdog |
48 | * F## = Break at do_fork for ## iterations | 48 | * F## = Break at do_fork for ## iterations |
49 | * S## = Break at sys_open for ## iterations | 49 | * S## = Break at sys_open for ## iterations |
50 | * I## = Run the single step test ## iterations | 50 | * I## = Run the single step test ## iterations |
51 | * | 51 | * |
52 | * NOTE: that the do_fork and sys_open tests are mutually exclusive. | 52 | * NOTE: that the do_fork and sys_open tests are mutually exclusive. |
53 | * | 53 | * |
54 | * To invoke the kgdb test suite from boot you use a kernel start | 54 | * To invoke the kgdb test suite from boot you use a kernel start |
55 | * argument as follows: | 55 | * argument as follows: |
56 | * kgdbts=V1 kgdbwait | 56 | * kgdbts=V1 kgdbwait |
57 | * Or if you wanted to perform the NMI test for 6 seconds and do_fork | 57 | * Or if you wanted to perform the NMI test for 6 seconds and do_fork |
58 | * test for 100 forks, you could use: | 58 | * test for 100 forks, you could use: |
59 | * kgdbts=V1N6F100 kgdbwait | 59 | * kgdbts=V1N6F100 kgdbwait |
60 | * | 60 | * |
61 | * The test suite can also be invoked at run time with: | 61 | * The test suite can also be invoked at run time with: |
62 | * echo kgdbts=V1N6F100 > /sys/module/kgdbts/parameters/kgdbts | 62 | * echo kgdbts=V1N6F100 > /sys/module/kgdbts/parameters/kgdbts |
63 | * Or as another example: | 63 | * Or as another example: |
64 | * echo kgdbts=V2 > /sys/module/kgdbts/parameters/kgdbts | 64 | * echo kgdbts=V2 > /sys/module/kgdbts/parameters/kgdbts |
65 | * | 65 | * |
66 | * When developing a new kgdb arch specific implementation or | 66 | * When developing a new kgdb arch specific implementation or |
67 | * using these tests for the purpose of regression testing, | 67 | * using these tests for the purpose of regression testing, |
68 | * several invocations are required. | 68 | * several invocations are required. |
69 | * | 69 | * |
70 | * 1) Boot with the test suite enabled by using the kernel arguments | 70 | * 1) Boot with the test suite enabled by using the kernel arguments |
71 | * "kgdbts=V1F100 kgdbwait" | 71 | * "kgdbts=V1F100 kgdbwait" |
72 | * ## If kgdb arch specific implementation has NMI use | 72 | * ## If kgdb arch specific implementation has NMI use |
73 | * "kgdbts=V1N6F100 | 73 | * "kgdbts=V1N6F100 |
74 | * | 74 | * |
75 | * 2) After the system boot run the basic test. | 75 | * 2) After the system boot run the basic test. |
76 | * echo kgdbts=V1 > /sys/module/kgdbts/parameters/kgdbts | 76 | * echo kgdbts=V1 > /sys/module/kgdbts/parameters/kgdbts |
77 | * | 77 | * |
78 | * 3) Run the concurrency tests. It is best to use n+1 | 78 | * 3) Run the concurrency tests. It is best to use n+1 |
79 | * while loops where n is the number of cpus you have | 79 | * while loops where n is the number of cpus you have |
80 | * in your system. The example below uses only two | 80 | * in your system. The example below uses only two |
81 | * loops. | 81 | * loops. |
82 | * | 82 | * |
83 | * ## This tests break points on sys_open | 83 | * ## This tests break points on sys_open |
84 | * while [ 1 ] ; do find / > /dev/null 2>&1 ; done & | 84 | * while [ 1 ] ; do find / > /dev/null 2>&1 ; done & |
85 | * while [ 1 ] ; do find / > /dev/null 2>&1 ; done & | 85 | * while [ 1 ] ; do find / > /dev/null 2>&1 ; done & |
86 | * echo kgdbts=V1S10000 > /sys/module/kgdbts/parameters/kgdbts | 86 | * echo kgdbts=V1S10000 > /sys/module/kgdbts/parameters/kgdbts |
87 | * fg # and hit control-c | 87 | * fg # and hit control-c |
88 | * fg # and hit control-c | 88 | * fg # and hit control-c |
89 | * ## This tests break points on do_fork | 89 | * ## This tests break points on do_fork |
90 | * while [ 1 ] ; do date > /dev/null ; done & | 90 | * while [ 1 ] ; do date > /dev/null ; done & |
91 | * while [ 1 ] ; do date > /dev/null ; done & | 91 | * while [ 1 ] ; do date > /dev/null ; done & |
92 | * echo kgdbts=V1F1000 > /sys/module/kgdbts/parameters/kgdbts | 92 | * echo kgdbts=V1F1000 > /sys/module/kgdbts/parameters/kgdbts |
93 | * fg # and hit control-c | 93 | * fg # and hit control-c |
94 | * | 94 | * |
95 | */ | 95 | */ |
96 | 96 | ||
97 | #include <linux/kernel.h> | 97 | #include <linux/kernel.h> |
98 | #include <linux/kgdb.h> | 98 | #include <linux/kgdb.h> |
99 | #include <linux/ctype.h> | 99 | #include <linux/ctype.h> |
100 | #include <linux/uaccess.h> | 100 | #include <linux/uaccess.h> |
101 | #include <linux/syscalls.h> | 101 | #include <linux/syscalls.h> |
102 | #include <linux/nmi.h> | 102 | #include <linux/nmi.h> |
103 | #include <linux/delay.h> | 103 | #include <linux/delay.h> |
104 | #include <linux/kthread.h> | 104 | #include <linux/kthread.h> |
105 | 105 | ||
106 | #define v1printk(a...) do { \ | 106 | #define v1printk(a...) do { \ |
107 | if (verbose) \ | 107 | if (verbose) \ |
108 | printk(KERN_INFO a); \ | 108 | printk(KERN_INFO a); \ |
109 | } while (0) | 109 | } while (0) |
110 | #define v2printk(a...) do { \ | 110 | #define v2printk(a...) do { \ |
111 | if (verbose > 1) \ | 111 | if (verbose > 1) \ |
112 | printk(KERN_INFO a); \ | 112 | printk(KERN_INFO a); \ |
113 | touch_nmi_watchdog(); \ | 113 | touch_nmi_watchdog(); \ |
114 | } while (0) | 114 | } while (0) |
115 | #define eprintk(a...) do { \ | 115 | #define eprintk(a...) do { \ |
116 | printk(KERN_ERR a); \ | 116 | printk(KERN_ERR a); \ |
117 | WARN_ON(1); \ | 117 | WARN_ON(1); \ |
118 | } while (0) | 118 | } while (0) |
119 | #define MAX_CONFIG_LEN 40 | 119 | #define MAX_CONFIG_LEN 40 |
120 | 120 | ||
121 | static struct kgdb_io kgdbts_io_ops; | 121 | static struct kgdb_io kgdbts_io_ops; |
122 | static char get_buf[BUFMAX]; | 122 | static char get_buf[BUFMAX]; |
123 | static int get_buf_cnt; | 123 | static int get_buf_cnt; |
124 | static char put_buf[BUFMAX]; | 124 | static char put_buf[BUFMAX]; |
125 | static int put_buf_cnt; | 125 | static int put_buf_cnt; |
126 | static char scratch_buf[BUFMAX]; | 126 | static char scratch_buf[BUFMAX]; |
127 | static int verbose; | 127 | static int verbose; |
128 | static int repeat_test; | 128 | static int repeat_test; |
129 | static int test_complete; | 129 | static int test_complete; |
130 | static int send_ack; | 130 | static int send_ack; |
131 | static int final_ack; | 131 | static int final_ack; |
132 | static int force_hwbrks; | 132 | static int force_hwbrks; |
133 | static int hwbreaks_ok; | 133 | static int hwbreaks_ok; |
134 | static int hw_break_val; | 134 | static int hw_break_val; |
135 | static int hw_break_val2; | 135 | static int hw_break_val2; |
136 | #if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_SPARC) | 136 | #if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_SPARC) |
137 | static int arch_needs_sstep_emulation = 1; | 137 | static int arch_needs_sstep_emulation = 1; |
138 | #else | 138 | #else |
139 | static int arch_needs_sstep_emulation; | 139 | static int arch_needs_sstep_emulation; |
140 | #endif | 140 | #endif |
141 | static unsigned long sstep_addr; | 141 | static unsigned long sstep_addr; |
142 | static int sstep_state; | 142 | static int sstep_state; |
143 | 143 | ||
144 | /* Storage for the registers, in GDB format. */ | 144 | /* Storage for the registers, in GDB format. */ |
145 | static unsigned long kgdbts_gdb_regs[(NUMREGBYTES + | 145 | static unsigned long kgdbts_gdb_regs[(NUMREGBYTES + |
146 | sizeof(unsigned long) - 1) / | 146 | sizeof(unsigned long) - 1) / |
147 | sizeof(unsigned long)]; | 147 | sizeof(unsigned long)]; |
148 | static struct pt_regs kgdbts_regs; | 148 | static struct pt_regs kgdbts_regs; |
149 | 149 | ||
150 | /* -1 = init not run yet, 0 = unconfigured, 1 = configured. */ | 150 | /* -1 = init not run yet, 0 = unconfigured, 1 = configured. */ |
151 | static int configured = -1; | 151 | static int configured = -1; |
152 | 152 | ||
153 | #ifdef CONFIG_KGDB_TESTS_BOOT_STRING | 153 | #ifdef CONFIG_KGDB_TESTS_BOOT_STRING |
154 | static char config[MAX_CONFIG_LEN] = CONFIG_KGDB_TESTS_BOOT_STRING; | 154 | static char config[MAX_CONFIG_LEN] = CONFIG_KGDB_TESTS_BOOT_STRING; |
155 | #else | 155 | #else |
156 | static char config[MAX_CONFIG_LEN]; | 156 | static char config[MAX_CONFIG_LEN]; |
157 | #endif | 157 | #endif |
158 | static struct kparam_string kps = { | 158 | static struct kparam_string kps = { |
159 | .string = config, | 159 | .string = config, |
160 | .maxlen = MAX_CONFIG_LEN, | 160 | .maxlen = MAX_CONFIG_LEN, |
161 | }; | 161 | }; |
162 | 162 | ||
163 | static void fill_get_buf(char *buf); | 163 | static void fill_get_buf(char *buf); |
164 | 164 | ||
165 | struct test_struct { | 165 | struct test_struct { |
166 | char *get; | 166 | char *get; |
167 | char *put; | 167 | char *put; |
168 | void (*get_handler)(char *); | 168 | void (*get_handler)(char *); |
169 | int (*put_handler)(char *, char *); | 169 | int (*put_handler)(char *, char *); |
170 | }; | 170 | }; |
171 | 171 | ||
172 | struct test_state { | 172 | struct test_state { |
173 | char *name; | 173 | char *name; |
174 | struct test_struct *tst; | 174 | struct test_struct *tst; |
175 | int idx; | 175 | int idx; |
176 | int (*run_test) (int, int); | 176 | int (*run_test) (int, int); |
177 | int (*validate_put) (char *); | 177 | int (*validate_put) (char *); |
178 | }; | 178 | }; |
179 | 179 | ||
180 | static struct test_state ts; | 180 | static struct test_state ts; |
181 | 181 | ||
182 | static int kgdbts_unreg_thread(void *ptr) | 182 | static int kgdbts_unreg_thread(void *ptr) |
183 | { | 183 | { |
184 | /* Wait until the tests are complete and then ungresiter the I/O | 184 | /* Wait until the tests are complete and then ungresiter the I/O |
185 | * driver. | 185 | * driver. |
186 | */ | 186 | */ |
187 | while (!final_ack) | 187 | while (!final_ack) |
188 | msleep_interruptible(1500); | 188 | msleep_interruptible(1500); |
189 | 189 | ||
190 | if (configured) | 190 | if (configured) |
191 | kgdb_unregister_io_module(&kgdbts_io_ops); | 191 | kgdb_unregister_io_module(&kgdbts_io_ops); |
192 | configured = 0; | 192 | configured = 0; |
193 | 193 | ||
194 | return 0; | 194 | return 0; |
195 | } | 195 | } |
196 | 196 | ||
197 | /* This is noinline such that it can be used for a single location to | 197 | /* This is noinline such that it can be used for a single location to |
198 | * place a breakpoint | 198 | * place a breakpoint |
199 | */ | 199 | */ |
200 | static noinline void kgdbts_break_test(void) | 200 | static noinline void kgdbts_break_test(void) |
201 | { | 201 | { |
202 | v2printk("kgdbts: breakpoint complete\n"); | 202 | v2printk("kgdbts: breakpoint complete\n"); |
203 | } | 203 | } |
204 | 204 | ||
205 | /* Lookup symbol info in the kernel */ | 205 | /* Lookup symbol info in the kernel */ |
206 | static unsigned long lookup_addr(char *arg) | 206 | static unsigned long lookup_addr(char *arg) |
207 | { | 207 | { |
208 | unsigned long addr = 0; | 208 | unsigned long addr = 0; |
209 | 209 | ||
210 | if (!strcmp(arg, "kgdbts_break_test")) | 210 | if (!strcmp(arg, "kgdbts_break_test")) |
211 | addr = (unsigned long)kgdbts_break_test; | 211 | addr = (unsigned long)kgdbts_break_test; |
212 | else if (!strcmp(arg, "sys_open")) | 212 | else if (!strcmp(arg, "sys_open")) |
213 | addr = (unsigned long)sys_open; | 213 | addr = (unsigned long)sys_open; |
214 | else if (!strcmp(arg, "do_fork")) | 214 | else if (!strcmp(arg, "do_fork")) |
215 | addr = (unsigned long)do_fork; | 215 | addr = (unsigned long)do_fork; |
216 | else if (!strcmp(arg, "hw_break_val")) | 216 | else if (!strcmp(arg, "hw_break_val")) |
217 | addr = (unsigned long)&hw_break_val; | 217 | addr = (unsigned long)&hw_break_val; |
218 | return addr; | 218 | return addr; |
219 | } | 219 | } |
220 | 220 | ||
221 | static void break_helper(char *bp_type, char *arg, unsigned long vaddr) | 221 | static void break_helper(char *bp_type, char *arg, unsigned long vaddr) |
222 | { | 222 | { |
223 | unsigned long addr; | 223 | unsigned long addr; |
224 | 224 | ||
225 | if (arg) | 225 | if (arg) |
226 | addr = lookup_addr(arg); | 226 | addr = lookup_addr(arg); |
227 | else | 227 | else |
228 | addr = vaddr; | 228 | addr = vaddr; |
229 | 229 | ||
230 | sprintf(scratch_buf, "%s,%lx,%i", bp_type, addr, | 230 | sprintf(scratch_buf, "%s,%lx,%i", bp_type, addr, |
231 | BREAK_INSTR_SIZE); | 231 | BREAK_INSTR_SIZE); |
232 | fill_get_buf(scratch_buf); | 232 | fill_get_buf(scratch_buf); |
233 | } | 233 | } |
234 | 234 | ||
235 | static void sw_break(char *arg) | 235 | static void sw_break(char *arg) |
236 | { | 236 | { |
237 | break_helper(force_hwbrks ? "Z1" : "Z0", arg, 0); | 237 | break_helper(force_hwbrks ? "Z1" : "Z0", arg, 0); |
238 | } | 238 | } |
239 | 239 | ||
240 | static void sw_rem_break(char *arg) | 240 | static void sw_rem_break(char *arg) |
241 | { | 241 | { |
242 | break_helper(force_hwbrks ? "z1" : "z0", arg, 0); | 242 | break_helper(force_hwbrks ? "z1" : "z0", arg, 0); |
243 | } | 243 | } |
244 | 244 | ||
245 | static void hw_break(char *arg) | 245 | static void hw_break(char *arg) |
246 | { | 246 | { |
247 | break_helper("Z1", arg, 0); | 247 | break_helper("Z1", arg, 0); |
248 | } | 248 | } |
249 | 249 | ||
250 | static void hw_rem_break(char *arg) | 250 | static void hw_rem_break(char *arg) |
251 | { | 251 | { |
252 | break_helper("z1", arg, 0); | 252 | break_helper("z1", arg, 0); |
253 | } | 253 | } |
254 | 254 | ||
255 | static void hw_write_break(char *arg) | 255 | static void hw_write_break(char *arg) |
256 | { | 256 | { |
257 | break_helper("Z2", arg, 0); | 257 | break_helper("Z2", arg, 0); |
258 | } | 258 | } |
259 | 259 | ||
260 | static void hw_rem_write_break(char *arg) | 260 | static void hw_rem_write_break(char *arg) |
261 | { | 261 | { |
262 | break_helper("z2", arg, 0); | 262 | break_helper("z2", arg, 0); |
263 | } | 263 | } |
264 | 264 | ||
265 | static void hw_access_break(char *arg) | 265 | static void hw_access_break(char *arg) |
266 | { | 266 | { |
267 | break_helper("Z4", arg, 0); | 267 | break_helper("Z4", arg, 0); |
268 | } | 268 | } |
269 | 269 | ||
270 | static void hw_rem_access_break(char *arg) | 270 | static void hw_rem_access_break(char *arg) |
271 | { | 271 | { |
272 | break_helper("z4", arg, 0); | 272 | break_helper("z4", arg, 0); |
273 | } | 273 | } |
274 | 274 | ||
275 | static void hw_break_val_access(void) | 275 | static void hw_break_val_access(void) |
276 | { | 276 | { |
277 | hw_break_val2 = hw_break_val; | 277 | hw_break_val2 = hw_break_val; |
278 | } | 278 | } |
279 | 279 | ||
280 | static void hw_break_val_write(void) | 280 | static void hw_break_val_write(void) |
281 | { | 281 | { |
282 | hw_break_val++; | 282 | hw_break_val++; |
283 | } | 283 | } |
284 | 284 | ||
285 | static int check_and_rewind_pc(char *put_str, char *arg) | 285 | static int check_and_rewind_pc(char *put_str, char *arg) |
286 | { | 286 | { |
287 | unsigned long addr = lookup_addr(arg); | 287 | unsigned long addr = lookup_addr(arg); |
288 | int offset = 0; | 288 | int offset = 0; |
289 | 289 | ||
290 | kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs, | 290 | kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs, |
291 | NUMREGBYTES); | 291 | NUMREGBYTES); |
292 | gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs); | 292 | gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs); |
293 | v2printk("Stopped at IP: %lx\n", instruction_pointer(&kgdbts_regs)); | 293 | v2printk("Stopped at IP: %lx\n", instruction_pointer(&kgdbts_regs)); |
294 | #ifdef CONFIG_X86 | 294 | #ifdef CONFIG_X86 |
295 | /* On x86 a breakpoint stop requires it to be decremented */ | 295 | /* On x86 a breakpoint stop requires it to be decremented */ |
296 | if (addr + 1 == kgdbts_regs.ip) | 296 | if (addr + 1 == kgdbts_regs.ip) |
297 | offset = -1; | 297 | offset = -1; |
298 | #elif defined(CONFIG_SUPERH) | 298 | #elif defined(CONFIG_SUPERH) |
299 | /* On SUPERH a breakpoint stop requires it to be decremented */ | 299 | /* On SUPERH a breakpoint stop requires it to be decremented */ |
300 | if (addr + 2 == kgdbts_regs.pc) | 300 | if (addr + 2 == kgdbts_regs.pc) |
301 | offset = -2; | 301 | offset = -2; |
302 | #endif | 302 | #endif |
303 | if (strcmp(arg, "silent") && | 303 | if (strcmp(arg, "silent") && |
304 | instruction_pointer(&kgdbts_regs) + offset != addr) { | 304 | instruction_pointer(&kgdbts_regs) + offset != addr) { |
305 | eprintk("kgdbts: BP mismatch %lx expected %lx\n", | 305 | eprintk("kgdbts: BP mismatch %lx expected %lx\n", |
306 | instruction_pointer(&kgdbts_regs) + offset, addr); | 306 | instruction_pointer(&kgdbts_regs) + offset, addr); |
307 | return 1; | 307 | return 1; |
308 | } | 308 | } |
309 | #ifdef CONFIG_X86 | 309 | #ifdef CONFIG_X86 |
310 | /* On x86 adjust the instruction pointer if needed */ | 310 | /* On x86 adjust the instruction pointer if needed */ |
311 | kgdbts_regs.ip += offset; | 311 | kgdbts_regs.ip += offset; |
312 | #elif defined(CONFIG_SUPERH) | 312 | #elif defined(CONFIG_SUPERH) |
313 | kgdbts_regs.pc += offset; | 313 | kgdbts_regs.pc += offset; |
314 | #endif | 314 | #endif |
315 | return 0; | 315 | return 0; |
316 | } | 316 | } |
317 | 317 | ||
318 | static int check_single_step(char *put_str, char *arg) | 318 | static int check_single_step(char *put_str, char *arg) |
319 | { | 319 | { |
320 | unsigned long addr = lookup_addr(arg); | 320 | unsigned long addr = lookup_addr(arg); |
321 | /* | 321 | /* |
322 | * From an arch indepent point of view the instruction pointer | 322 | * From an arch indepent point of view the instruction pointer |
323 | * should be on a different instruction | 323 | * should be on a different instruction |
324 | */ | 324 | */ |
325 | kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs, | 325 | kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs, |
326 | NUMREGBYTES); | 326 | NUMREGBYTES); |
327 | gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs); | 327 | gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs); |
328 | v2printk("Singlestep stopped at IP: %lx\n", | 328 | v2printk("Singlestep stopped at IP: %lx\n", |
329 | instruction_pointer(&kgdbts_regs)); | 329 | instruction_pointer(&kgdbts_regs)); |
330 | if (instruction_pointer(&kgdbts_regs) == addr) { | 330 | if (instruction_pointer(&kgdbts_regs) == addr) { |
331 | eprintk("kgdbts: SingleStep failed at %lx\n", | 331 | eprintk("kgdbts: SingleStep failed at %lx\n", |
332 | instruction_pointer(&kgdbts_regs)); | 332 | instruction_pointer(&kgdbts_regs)); |
333 | return 1; | 333 | return 1; |
334 | } | 334 | } |
335 | 335 | ||
336 | return 0; | 336 | return 0; |
337 | } | 337 | } |
338 | 338 | ||
339 | static void write_regs(char *arg) | 339 | static void write_regs(char *arg) |
340 | { | 340 | { |
341 | memset(scratch_buf, 0, sizeof(scratch_buf)); | 341 | memset(scratch_buf, 0, sizeof(scratch_buf)); |
342 | scratch_buf[0] = 'G'; | 342 | scratch_buf[0] = 'G'; |
343 | pt_regs_to_gdb_regs(kgdbts_gdb_regs, &kgdbts_regs); | 343 | pt_regs_to_gdb_regs(kgdbts_gdb_regs, &kgdbts_regs); |
344 | kgdb_mem2hex((char *)kgdbts_gdb_regs, &scratch_buf[1], NUMREGBYTES); | 344 | kgdb_mem2hex((char *)kgdbts_gdb_regs, &scratch_buf[1], NUMREGBYTES); |
345 | fill_get_buf(scratch_buf); | 345 | fill_get_buf(scratch_buf); |
346 | } | 346 | } |
347 | 347 | ||
348 | static void skip_back_repeat_test(char *arg) | 348 | static void skip_back_repeat_test(char *arg) |
349 | { | 349 | { |
350 | int go_back = simple_strtol(arg, NULL, 10); | 350 | int go_back = simple_strtol(arg, NULL, 10); |
351 | 351 | ||
352 | repeat_test--; | 352 | repeat_test--; |
353 | if (repeat_test <= 0) | 353 | if (repeat_test <= 0) |
354 | ts.idx++; | 354 | ts.idx++; |
355 | else | 355 | else |
356 | ts.idx -= go_back; | 356 | ts.idx -= go_back; |
357 | fill_get_buf(ts.tst[ts.idx].get); | 357 | fill_get_buf(ts.tst[ts.idx].get); |
358 | } | 358 | } |
359 | 359 | ||
360 | static int got_break(char *put_str, char *arg) | 360 | static int got_break(char *put_str, char *arg) |
361 | { | 361 | { |
362 | test_complete = 1; | 362 | test_complete = 1; |
363 | if (!strncmp(put_str+1, arg, 2)) { | 363 | if (!strncmp(put_str+1, arg, 2)) { |
364 | if (!strncmp(arg, "T0", 2)) | 364 | if (!strncmp(arg, "T0", 2)) |
365 | test_complete = 2; | 365 | test_complete = 2; |
366 | return 0; | 366 | return 0; |
367 | } | 367 | } |
368 | return 1; | 368 | return 1; |
369 | } | 369 | } |
370 | 370 | ||
371 | static void emul_sstep_get(char *arg) | 371 | static void emul_sstep_get(char *arg) |
372 | { | 372 | { |
373 | if (!arch_needs_sstep_emulation) { | 373 | if (!arch_needs_sstep_emulation) { |
374 | fill_get_buf(arg); | 374 | fill_get_buf(arg); |
375 | return; | 375 | return; |
376 | } | 376 | } |
377 | switch (sstep_state) { | 377 | switch (sstep_state) { |
378 | case 0: | 378 | case 0: |
379 | v2printk("Emulate single step\n"); | 379 | v2printk("Emulate single step\n"); |
380 | /* Start by looking at the current PC */ | 380 | /* Start by looking at the current PC */ |
381 | fill_get_buf("g"); | 381 | fill_get_buf("g"); |
382 | break; | 382 | break; |
383 | case 1: | 383 | case 1: |
384 | /* set breakpoint */ | 384 | /* set breakpoint */ |
385 | break_helper("Z0", NULL, sstep_addr); | 385 | break_helper("Z0", NULL, sstep_addr); |
386 | break; | 386 | break; |
387 | case 2: | 387 | case 2: |
388 | /* Continue */ | 388 | /* Continue */ |
389 | fill_get_buf("c"); | 389 | fill_get_buf("c"); |
390 | break; | 390 | break; |
391 | case 3: | 391 | case 3: |
392 | /* Clear breakpoint */ | 392 | /* Clear breakpoint */ |
393 | break_helper("z0", NULL, sstep_addr); | 393 | break_helper("z0", NULL, sstep_addr); |
394 | break; | 394 | break; |
395 | default: | 395 | default: |
396 | eprintk("kgdbts: ERROR failed sstep get emulation\n"); | 396 | eprintk("kgdbts: ERROR failed sstep get emulation\n"); |
397 | } | 397 | } |
398 | sstep_state++; | 398 | sstep_state++; |
399 | } | 399 | } |
400 | 400 | ||
401 | static int emul_sstep_put(char *put_str, char *arg) | 401 | static int emul_sstep_put(char *put_str, char *arg) |
402 | { | 402 | { |
403 | if (!arch_needs_sstep_emulation) { | 403 | if (!arch_needs_sstep_emulation) { |
404 | if (!strncmp(put_str+1, arg, 2)) | 404 | if (!strncmp(put_str+1, arg, 2)) |
405 | return 0; | 405 | return 0; |
406 | return 1; | 406 | return 1; |
407 | } | 407 | } |
408 | switch (sstep_state) { | 408 | switch (sstep_state) { |
409 | case 1: | 409 | case 1: |
410 | /* validate the "g" packet to get the IP */ | 410 | /* validate the "g" packet to get the IP */ |
411 | kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs, | 411 | kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs, |
412 | NUMREGBYTES); | 412 | NUMREGBYTES); |
413 | gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs); | 413 | gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs); |
414 | v2printk("Stopped at IP: %lx\n", | 414 | v2printk("Stopped at IP: %lx\n", |
415 | instruction_pointer(&kgdbts_regs)); | 415 | instruction_pointer(&kgdbts_regs)); |
416 | /* Want to stop at IP + break instruction size by default */ | 416 | /* Want to stop at IP + break instruction size by default */ |
417 | sstep_addr = instruction_pointer(&kgdbts_regs) + | 417 | sstep_addr = instruction_pointer(&kgdbts_regs) + |
418 | BREAK_INSTR_SIZE; | 418 | BREAK_INSTR_SIZE; |
419 | break; | 419 | break; |
420 | case 2: | 420 | case 2: |
421 | if (strncmp(put_str, "$OK", 3)) { | 421 | if (strncmp(put_str, "$OK", 3)) { |
422 | eprintk("kgdbts: failed sstep break set\n"); | 422 | eprintk("kgdbts: failed sstep break set\n"); |
423 | return 1; | 423 | return 1; |
424 | } | 424 | } |
425 | break; | 425 | break; |
426 | case 3: | 426 | case 3: |
427 | if (strncmp(put_str, "$T0", 3)) { | 427 | if (strncmp(put_str, "$T0", 3)) { |
428 | eprintk("kgdbts: failed continue sstep\n"); | 428 | eprintk("kgdbts: failed continue sstep\n"); |
429 | return 1; | 429 | return 1; |
430 | } | 430 | } |
431 | break; | 431 | break; |
432 | case 4: | 432 | case 4: |
433 | if (strncmp(put_str, "$OK", 3)) { | 433 | if (strncmp(put_str, "$OK", 3)) { |
434 | eprintk("kgdbts: failed sstep break unset\n"); | 434 | eprintk("kgdbts: failed sstep break unset\n"); |
435 | return 1; | 435 | return 1; |
436 | } | 436 | } |
437 | /* Single step is complete so continue on! */ | 437 | /* Single step is complete so continue on! */ |
438 | sstep_state = 0; | 438 | sstep_state = 0; |
439 | return 0; | 439 | return 0; |
440 | default: | 440 | default: |
441 | eprintk("kgdbts: ERROR failed sstep put emulation\n"); | 441 | eprintk("kgdbts: ERROR failed sstep put emulation\n"); |
442 | } | 442 | } |
443 | 443 | ||
444 | /* Continue on the same test line until emulation is complete */ | 444 | /* Continue on the same test line until emulation is complete */ |
445 | ts.idx--; | 445 | ts.idx--; |
446 | return 0; | 446 | return 0; |
447 | } | 447 | } |
448 | 448 | ||
449 | static int final_ack_set(char *put_str, char *arg) | 449 | static int final_ack_set(char *put_str, char *arg) |
450 | { | 450 | { |
451 | if (strncmp(put_str+1, arg, 2)) | 451 | if (strncmp(put_str+1, arg, 2)) |
452 | return 1; | 452 | return 1; |
453 | final_ack = 1; | 453 | final_ack = 1; |
454 | return 0; | 454 | return 0; |
455 | } | 455 | } |
456 | /* | 456 | /* |
457 | * Test to plant a breakpoint and detach, which should clear out the | 457 | * Test to plant a breakpoint and detach, which should clear out the |
458 | * breakpoint and restore the original instruction. | 458 | * breakpoint and restore the original instruction. |
459 | */ | 459 | */ |
460 | static struct test_struct plant_and_detach_test[] = { | 460 | static struct test_struct plant_and_detach_test[] = { |
461 | { "?", "S0*" }, /* Clear break points */ | 461 | { "?", "S0*" }, /* Clear break points */ |
462 | { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ | 462 | { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ |
463 | { "D", "OK" }, /* Detach */ | 463 | { "D", "OK" }, /* Detach */ |
464 | { "", "" }, | 464 | { "", "" }, |
465 | }; | 465 | }; |
466 | 466 | ||
467 | /* | 467 | /* |
468 | * Simple test to write in a software breakpoint, check for the | 468 | * Simple test to write in a software breakpoint, check for the |
469 | * correct stop location and detach. | 469 | * correct stop location and detach. |
470 | */ | 470 | */ |
471 | static struct test_struct sw_breakpoint_test[] = { | 471 | static struct test_struct sw_breakpoint_test[] = { |
472 | { "?", "S0*" }, /* Clear break points */ | 472 | { "?", "S0*" }, /* Clear break points */ |
473 | { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ | 473 | { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ |
474 | { "c", "T0*", }, /* Continue */ | 474 | { "c", "T0*", }, /* Continue */ |
475 | { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, | 475 | { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, |
476 | { "write", "OK", write_regs }, | 476 | { "write", "OK", write_regs }, |
477 | { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */ | 477 | { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */ |
478 | { "D", "OK" }, /* Detach */ | 478 | { "D", "OK" }, /* Detach */ |
479 | { "D", "OK", NULL, got_break }, /* On success we made it here */ | 479 | { "D", "OK", NULL, got_break }, /* On success we made it here */ |
480 | { "", "" }, | 480 | { "", "" }, |
481 | }; | 481 | }; |
482 | 482 | ||
483 | /* | 483 | /* |
484 | * Test a known bad memory read location to test the fault handler and | 484 | * Test a known bad memory read location to test the fault handler and |
485 | * read bytes 1-8 at the bad address | 485 | * read bytes 1-8 at the bad address |
486 | */ | 486 | */ |
487 | static struct test_struct bad_read_test[] = { | 487 | static struct test_struct bad_read_test[] = { |
488 | { "?", "S0*" }, /* Clear break points */ | 488 | { "?", "S0*" }, /* Clear break points */ |
489 | { "m0,1", "E*" }, /* read 1 byte at address 1 */ | 489 | { "m0,1", "E*" }, /* read 1 byte at address 1 */ |
490 | { "m0,2", "E*" }, /* read 1 byte at address 2 */ | 490 | { "m0,2", "E*" }, /* read 1 byte at address 2 */ |
491 | { "m0,3", "E*" }, /* read 1 byte at address 3 */ | 491 | { "m0,3", "E*" }, /* read 1 byte at address 3 */ |
492 | { "m0,4", "E*" }, /* read 1 byte at address 4 */ | 492 | { "m0,4", "E*" }, /* read 1 byte at address 4 */ |
493 | { "m0,5", "E*" }, /* read 1 byte at address 5 */ | 493 | { "m0,5", "E*" }, /* read 1 byte at address 5 */ |
494 | { "m0,6", "E*" }, /* read 1 byte at address 6 */ | 494 | { "m0,6", "E*" }, /* read 1 byte at address 6 */ |
495 | { "m0,7", "E*" }, /* read 1 byte at address 7 */ | 495 | { "m0,7", "E*" }, /* read 1 byte at address 7 */ |
496 | { "m0,8", "E*" }, /* read 1 byte at address 8 */ | 496 | { "m0,8", "E*" }, /* read 1 byte at address 8 */ |
497 | { "D", "OK" }, /* Detach which removes all breakpoints and continues */ | 497 | { "D", "OK" }, /* Detach which removes all breakpoints and continues */ |
498 | { "", "" }, | 498 | { "", "" }, |
499 | }; | 499 | }; |
500 | 500 | ||
501 | /* | 501 | /* |
502 | * Test for hitting a breakpoint, remove it, single step, plant it | 502 | * Test for hitting a breakpoint, remove it, single step, plant it |
503 | * again and detach. | 503 | * again and detach. |
504 | */ | 504 | */ |
505 | static struct test_struct singlestep_break_test[] = { | 505 | static struct test_struct singlestep_break_test[] = { |
506 | { "?", "S0*" }, /* Clear break points */ | 506 | { "?", "S0*" }, /* Clear break points */ |
507 | { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ | 507 | { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ |
508 | { "c", "T0*", }, /* Continue */ | 508 | { "c", "T0*", }, /* Continue */ |
509 | { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, | 509 | { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, |
510 | { "write", "OK", write_regs }, /* Write registers */ | 510 | { "write", "OK", write_regs }, /* Write registers */ |
511 | { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */ | 511 | { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */ |
512 | { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ | 512 | { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ |
513 | { "g", "kgdbts_break_test", NULL, check_single_step }, | 513 | { "g", "kgdbts_break_test", NULL, check_single_step }, |
514 | { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ | 514 | { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ |
515 | { "c", "T0*", }, /* Continue */ | 515 | { "c", "T0*", }, /* Continue */ |
516 | { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, | 516 | { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, |
517 | { "write", "OK", write_regs }, /* Write registers */ | 517 | { "write", "OK", write_regs }, /* Write registers */ |
518 | { "D", "OK" }, /* Remove all breakpoints and continues */ | 518 | { "D", "OK" }, /* Remove all breakpoints and continues */ |
519 | { "", "" }, | 519 | { "", "" }, |
520 | }; | 520 | }; |
521 | 521 | ||
522 | /* | 522 | /* |
523 | * Test for hitting a breakpoint at do_fork for what ever the number | 523 | * Test for hitting a breakpoint at do_fork for what ever the number |
524 | * of iterations required by the variable repeat_test. | 524 | * of iterations required by the variable repeat_test. |
525 | */ | 525 | */ |
526 | static struct test_struct do_fork_test[] = { | 526 | static struct test_struct do_fork_test[] = { |
527 | { "?", "S0*" }, /* Clear break points */ | 527 | { "?", "S0*" }, /* Clear break points */ |
528 | { "do_fork", "OK", sw_break, }, /* set sw breakpoint */ | 528 | { "do_fork", "OK", sw_break, }, /* set sw breakpoint */ |
529 | { "c", "T0*", }, /* Continue */ | 529 | { "c", "T0*", }, /* Continue */ |
530 | { "g", "do_fork", NULL, check_and_rewind_pc }, /* check location */ | 530 | { "g", "do_fork", NULL, check_and_rewind_pc }, /* check location */ |
531 | { "write", "OK", write_regs }, /* Write registers */ | 531 | { "write", "OK", write_regs }, /* Write registers */ |
532 | { "do_fork", "OK", sw_rem_break }, /*remove breakpoint */ | 532 | { "do_fork", "OK", sw_rem_break }, /*remove breakpoint */ |
533 | { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ | 533 | { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ |
534 | { "g", "do_fork", NULL, check_single_step }, | 534 | { "g", "do_fork", NULL, check_single_step }, |
535 | { "do_fork", "OK", sw_break, }, /* set sw breakpoint */ | 535 | { "do_fork", "OK", sw_break, }, /* set sw breakpoint */ |
536 | { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */ | 536 | { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */ |
537 | { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */ | 537 | { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */ |
538 | { "", "" }, | 538 | { "", "" }, |
539 | }; | 539 | }; |
540 | 540 | ||
541 | /* Test for hitting a breakpoint at sys_open for what ever the number | 541 | /* Test for hitting a breakpoint at sys_open for what ever the number |
542 | * of iterations required by the variable repeat_test. | 542 | * of iterations required by the variable repeat_test. |
543 | */ | 543 | */ |
544 | static struct test_struct sys_open_test[] = { | 544 | static struct test_struct sys_open_test[] = { |
545 | { "?", "S0*" }, /* Clear break points */ | 545 | { "?", "S0*" }, /* Clear break points */ |
546 | { "sys_open", "OK", sw_break, }, /* set sw breakpoint */ | 546 | { "sys_open", "OK", sw_break, }, /* set sw breakpoint */ |
547 | { "c", "T0*", }, /* Continue */ | 547 | { "c", "T0*", }, /* Continue */ |
548 | { "g", "sys_open", NULL, check_and_rewind_pc }, /* check location */ | 548 | { "g", "sys_open", NULL, check_and_rewind_pc }, /* check location */ |
549 | { "write", "OK", write_regs }, /* Write registers */ | 549 | { "write", "OK", write_regs }, /* Write registers */ |
550 | { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */ | 550 | { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */ |
551 | { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ | 551 | { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ |
552 | { "g", "sys_open", NULL, check_single_step }, | 552 | { "g", "sys_open", NULL, check_single_step }, |
553 | { "sys_open", "OK", sw_break, }, /* set sw breakpoint */ | 553 | { "sys_open", "OK", sw_break, }, /* set sw breakpoint */ |
554 | { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */ | 554 | { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */ |
555 | { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */ | 555 | { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */ |
556 | { "", "" }, | 556 | { "", "" }, |
557 | }; | 557 | }; |
558 | 558 | ||
559 | /* | 559 | /* |
560 | * Test for hitting a simple hw breakpoint | 560 | * Test for hitting a simple hw breakpoint |
561 | */ | 561 | */ |
562 | static struct test_struct hw_breakpoint_test[] = { | 562 | static struct test_struct hw_breakpoint_test[] = { |
563 | { "?", "S0*" }, /* Clear break points */ | 563 | { "?", "S0*" }, /* Clear break points */ |
564 | { "kgdbts_break_test", "OK", hw_break, }, /* set hw breakpoint */ | 564 | { "kgdbts_break_test", "OK", hw_break, }, /* set hw breakpoint */ |
565 | { "c", "T0*", }, /* Continue */ | 565 | { "c", "T0*", }, /* Continue */ |
566 | { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, | 566 | { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, |
567 | { "write", "OK", write_regs }, | 567 | { "write", "OK", write_regs }, |
568 | { "kgdbts_break_test", "OK", hw_rem_break }, /*remove breakpoint */ | 568 | { "kgdbts_break_test", "OK", hw_rem_break }, /*remove breakpoint */ |
569 | { "D", "OK" }, /* Detach */ | 569 | { "D", "OK" }, /* Detach */ |
570 | { "D", "OK", NULL, got_break }, /* On success we made it here */ | 570 | { "D", "OK", NULL, got_break }, /* On success we made it here */ |
571 | { "", "" }, | 571 | { "", "" }, |
572 | }; | 572 | }; |
573 | 573 | ||
574 | /* | 574 | /* |
575 | * Test for hitting a hw write breakpoint | 575 | * Test for hitting a hw write breakpoint |
576 | */ | 576 | */ |
577 | static struct test_struct hw_write_break_test[] = { | 577 | static struct test_struct hw_write_break_test[] = { |
578 | { "?", "S0*" }, /* Clear break points */ | 578 | { "?", "S0*" }, /* Clear break points */ |
579 | { "hw_break_val", "OK", hw_write_break, }, /* set hw breakpoint */ | 579 | { "hw_break_val", "OK", hw_write_break, }, /* set hw breakpoint */ |
580 | { "c", "T0*", NULL, got_break }, /* Continue */ | 580 | { "c", "T0*", NULL, got_break }, /* Continue */ |
581 | { "g", "silent", NULL, check_and_rewind_pc }, | 581 | { "g", "silent", NULL, check_and_rewind_pc }, |
582 | { "write", "OK", write_regs }, | 582 | { "write", "OK", write_regs }, |
583 | { "hw_break_val", "OK", hw_rem_write_break }, /*remove breakpoint */ | 583 | { "hw_break_val", "OK", hw_rem_write_break }, /*remove breakpoint */ |
584 | { "D", "OK" }, /* Detach */ | 584 | { "D", "OK" }, /* Detach */ |
585 | { "D", "OK", NULL, got_break }, /* On success we made it here */ | 585 | { "D", "OK", NULL, got_break }, /* On success we made it here */ |
586 | { "", "" }, | 586 | { "", "" }, |
587 | }; | 587 | }; |
588 | 588 | ||
589 | /* | 589 | /* |
590 | * Test for hitting a hw access breakpoint | 590 | * Test for hitting a hw access breakpoint |
591 | */ | 591 | */ |
592 | static struct test_struct hw_access_break_test[] = { | 592 | static struct test_struct hw_access_break_test[] = { |
593 | { "?", "S0*" }, /* Clear break points */ | 593 | { "?", "S0*" }, /* Clear break points */ |
594 | { "hw_break_val", "OK", hw_access_break, }, /* set hw breakpoint */ | 594 | { "hw_break_val", "OK", hw_access_break, }, /* set hw breakpoint */ |
595 | { "c", "T0*", NULL, got_break }, /* Continue */ | 595 | { "c", "T0*", NULL, got_break }, /* Continue */ |
596 | { "g", "silent", NULL, check_and_rewind_pc }, | 596 | { "g", "silent", NULL, check_and_rewind_pc }, |
597 | { "write", "OK", write_regs }, | 597 | { "write", "OK", write_regs }, |
598 | { "hw_break_val", "OK", hw_rem_access_break }, /*remove breakpoint */ | 598 | { "hw_break_val", "OK", hw_rem_access_break }, /*remove breakpoint */ |
599 | { "D", "OK" }, /* Detach */ | 599 | { "D", "OK" }, /* Detach */ |
600 | { "D", "OK", NULL, got_break }, /* On success we made it here */ | 600 | { "D", "OK", NULL, got_break }, /* On success we made it here */ |
601 | { "", "" }, | 601 | { "", "" }, |
602 | }; | 602 | }; |
603 | 603 | ||
604 | /* | 604 | /* |
605 | * Test for hitting a hw access breakpoint | 605 | * Test for hitting a hw access breakpoint |
606 | */ | 606 | */ |
607 | static struct test_struct nmi_sleep_test[] = { | 607 | static struct test_struct nmi_sleep_test[] = { |
608 | { "?", "S0*" }, /* Clear break points */ | 608 | { "?", "S0*" }, /* Clear break points */ |
609 | { "c", "T0*", NULL, got_break }, /* Continue */ | 609 | { "c", "T0*", NULL, got_break }, /* Continue */ |
610 | { "D", "OK" }, /* Detach */ | 610 | { "D", "OK" }, /* Detach */ |
611 | { "D", "OK", NULL, got_break }, /* On success we made it here */ | 611 | { "D", "OK", NULL, got_break }, /* On success we made it here */ |
612 | { "", "" }, | 612 | { "", "" }, |
613 | }; | 613 | }; |
614 | 614 | ||
615 | static void fill_get_buf(char *buf) | 615 | static void fill_get_buf(char *buf) |
616 | { | 616 | { |
617 | unsigned char checksum = 0; | 617 | unsigned char checksum = 0; |
618 | int count = 0; | 618 | int count = 0; |
619 | char ch; | 619 | char ch; |
620 | 620 | ||
621 | strcpy(get_buf, "$"); | 621 | strcpy(get_buf, "$"); |
622 | strcat(get_buf, buf); | 622 | strcat(get_buf, buf); |
623 | while ((ch = buf[count])) { | 623 | while ((ch = buf[count])) { |
624 | checksum += ch; | 624 | checksum += ch; |
625 | count++; | 625 | count++; |
626 | } | 626 | } |
627 | strcat(get_buf, "#"); | 627 | strcat(get_buf, "#"); |
628 | get_buf[count + 2] = hex_asc_hi(checksum); | 628 | get_buf[count + 2] = hex_asc_hi(checksum); |
629 | get_buf[count + 3] = hex_asc_lo(checksum); | 629 | get_buf[count + 3] = hex_asc_lo(checksum); |
630 | get_buf[count + 4] = '\0'; | 630 | get_buf[count + 4] = '\0'; |
631 | v2printk("get%i: %s\n", ts.idx, get_buf); | 631 | v2printk("get%i: %s\n", ts.idx, get_buf); |
632 | } | 632 | } |
633 | 633 | ||
634 | static int validate_simple_test(char *put_str) | 634 | static int validate_simple_test(char *put_str) |
635 | { | 635 | { |
636 | char *chk_str; | 636 | char *chk_str; |
637 | 637 | ||
638 | if (ts.tst[ts.idx].put_handler) | 638 | if (ts.tst[ts.idx].put_handler) |
639 | return ts.tst[ts.idx].put_handler(put_str, | 639 | return ts.tst[ts.idx].put_handler(put_str, |
640 | ts.tst[ts.idx].put); | 640 | ts.tst[ts.idx].put); |
641 | 641 | ||
642 | chk_str = ts.tst[ts.idx].put; | 642 | chk_str = ts.tst[ts.idx].put; |
643 | if (*put_str == '$') | 643 | if (*put_str == '$') |
644 | put_str++; | 644 | put_str++; |
645 | 645 | ||
646 | while (*chk_str != '\0' && *put_str != '\0') { | 646 | while (*chk_str != '\0' && *put_str != '\0') { |
647 | /* If someone does a * to match the rest of the string, allow | 647 | /* If someone does a * to match the rest of the string, allow |
648 | * it, or stop if the recieved string is complete. | 648 | * it, or stop if the recieved string is complete. |
649 | */ | 649 | */ |
650 | if (*put_str == '#' || *chk_str == '*') | 650 | if (*put_str == '#' || *chk_str == '*') |
651 | return 0; | 651 | return 0; |
652 | if (*put_str != *chk_str) | 652 | if (*put_str != *chk_str) |
653 | return 1; | 653 | return 1; |
654 | 654 | ||
655 | chk_str++; | 655 | chk_str++; |
656 | put_str++; | 656 | put_str++; |
657 | } | 657 | } |
658 | if (*chk_str == '\0' && (*put_str == '\0' || *put_str == '#')) | 658 | if (*chk_str == '\0' && (*put_str == '\0' || *put_str == '#')) |
659 | return 0; | 659 | return 0; |
660 | 660 | ||
661 | return 1; | 661 | return 1; |
662 | } | 662 | } |
663 | 663 | ||
664 | static int run_simple_test(int is_get_char, int chr) | 664 | static int run_simple_test(int is_get_char, int chr) |
665 | { | 665 | { |
666 | int ret = 0; | 666 | int ret = 0; |
667 | if (is_get_char) { | 667 | if (is_get_char) { |
668 | /* Send an ACK on the get if a prior put completed and set the | 668 | /* Send an ACK on the get if a prior put completed and set the |
669 | * send ack variable | 669 | * send ack variable |
670 | */ | 670 | */ |
671 | if (send_ack) { | 671 | if (send_ack) { |
672 | send_ack = 0; | 672 | send_ack = 0; |
673 | return '+'; | 673 | return '+'; |
674 | } | 674 | } |
675 | /* On the first get char, fill the transmit buffer and then | 675 | /* On the first get char, fill the transmit buffer and then |
676 | * take from the get_string. | 676 | * take from the get_string. |
677 | */ | 677 | */ |
678 | if (get_buf_cnt == 0) { | 678 | if (get_buf_cnt == 0) { |
679 | if (ts.tst[ts.idx].get_handler) | 679 | if (ts.tst[ts.idx].get_handler) |
680 | ts.tst[ts.idx].get_handler(ts.tst[ts.idx].get); | 680 | ts.tst[ts.idx].get_handler(ts.tst[ts.idx].get); |
681 | else | 681 | else |
682 | fill_get_buf(ts.tst[ts.idx].get); | 682 | fill_get_buf(ts.tst[ts.idx].get); |
683 | } | 683 | } |
684 | 684 | ||
685 | if (get_buf[get_buf_cnt] == '\0') { | 685 | if (get_buf[get_buf_cnt] == '\0') { |
686 | eprintk("kgdbts: ERROR GET: EOB on '%s' at %i\n", | 686 | eprintk("kgdbts: ERROR GET: EOB on '%s' at %i\n", |
687 | ts.name, ts.idx); | 687 | ts.name, ts.idx); |
688 | get_buf_cnt = 0; | 688 | get_buf_cnt = 0; |
689 | fill_get_buf("D"); | 689 | fill_get_buf("D"); |
690 | } | 690 | } |
691 | ret = get_buf[get_buf_cnt]; | 691 | ret = get_buf[get_buf_cnt]; |
692 | get_buf_cnt++; | 692 | get_buf_cnt++; |
693 | return ret; | 693 | return ret; |
694 | } | 694 | } |
695 | 695 | ||
696 | /* This callback is a put char which is when kgdb sends data to | 696 | /* This callback is a put char which is when kgdb sends data to |
697 | * this I/O module. | 697 | * this I/O module. |
698 | */ | 698 | */ |
699 | if (ts.tst[ts.idx].get[0] == '\0' && | 699 | if (ts.tst[ts.idx].get[0] == '\0' && |
700 | ts.tst[ts.idx].put[0] == '\0') { | 700 | ts.tst[ts.idx].put[0] == '\0') { |
701 | eprintk("kgdbts: ERROR: beyond end of test on" | 701 | eprintk("kgdbts: ERROR: beyond end of test on" |
702 | " '%s' line %i\n", ts.name, ts.idx); | 702 | " '%s' line %i\n", ts.name, ts.idx); |
703 | return 0; | 703 | return 0; |
704 | } | 704 | } |
705 | 705 | ||
706 | if (put_buf_cnt >= BUFMAX) { | 706 | if (put_buf_cnt >= BUFMAX) { |
707 | eprintk("kgdbts: ERROR: put buffer overflow on" | 707 | eprintk("kgdbts: ERROR: put buffer overflow on" |
708 | " '%s' line %i\n", ts.name, ts.idx); | 708 | " '%s' line %i\n", ts.name, ts.idx); |
709 | put_buf_cnt = 0; | 709 | put_buf_cnt = 0; |
710 | return 0; | 710 | return 0; |
711 | } | 711 | } |
712 | /* Ignore everything until the first valid packet start '$' */ | 712 | /* Ignore everything until the first valid packet start '$' */ |
713 | if (put_buf_cnt == 0 && chr != '$') | 713 | if (put_buf_cnt == 0 && chr != '$') |
714 | return 0; | 714 | return 0; |
715 | 715 | ||
716 | put_buf[put_buf_cnt] = chr; | 716 | put_buf[put_buf_cnt] = chr; |
717 | put_buf_cnt++; | 717 | put_buf_cnt++; |
718 | 718 | ||
719 | /* End of packet == #XX so look for the '#' */ | 719 | /* End of packet == #XX so look for the '#' */ |
720 | if (put_buf_cnt > 3 && put_buf[put_buf_cnt - 3] == '#') { | 720 | if (put_buf_cnt > 3 && put_buf[put_buf_cnt - 3] == '#') { |
721 | if (put_buf_cnt >= BUFMAX) { | 721 | if (put_buf_cnt >= BUFMAX) { |
722 | eprintk("kgdbts: ERROR: put buffer overflow on" | 722 | eprintk("kgdbts: ERROR: put buffer overflow on" |
723 | " '%s' line %i\n", ts.name, ts.idx); | 723 | " '%s' line %i\n", ts.name, ts.idx); |
724 | put_buf_cnt = 0; | 724 | put_buf_cnt = 0; |
725 | return 0; | 725 | return 0; |
726 | } | 726 | } |
727 | put_buf[put_buf_cnt] = '\0'; | 727 | put_buf[put_buf_cnt] = '\0'; |
728 | v2printk("put%i: %s\n", ts.idx, put_buf); | 728 | v2printk("put%i: %s\n", ts.idx, put_buf); |
729 | /* Trigger check here */ | 729 | /* Trigger check here */ |
730 | if (ts.validate_put && ts.validate_put(put_buf)) { | 730 | if (ts.validate_put && ts.validate_put(put_buf)) { |
731 | eprintk("kgdbts: ERROR PUT: end of test " | 731 | eprintk("kgdbts: ERROR PUT: end of test " |
732 | "buffer on '%s' line %i expected %s got %s\n", | 732 | "buffer on '%s' line %i expected %s got %s\n", |
733 | ts.name, ts.idx, ts.tst[ts.idx].put, put_buf); | 733 | ts.name, ts.idx, ts.tst[ts.idx].put, put_buf); |
734 | } | 734 | } |
735 | ts.idx++; | 735 | ts.idx++; |
736 | put_buf_cnt = 0; | 736 | put_buf_cnt = 0; |
737 | get_buf_cnt = 0; | 737 | get_buf_cnt = 0; |
738 | send_ack = 1; | 738 | send_ack = 1; |
739 | } | 739 | } |
740 | return 0; | 740 | return 0; |
741 | } | 741 | } |
742 | 742 | ||
743 | static void init_simple_test(void) | 743 | static void init_simple_test(void) |
744 | { | 744 | { |
745 | memset(&ts, 0, sizeof(ts)); | 745 | memset(&ts, 0, sizeof(ts)); |
746 | ts.run_test = run_simple_test; | 746 | ts.run_test = run_simple_test; |
747 | ts.validate_put = validate_simple_test; | 747 | ts.validate_put = validate_simple_test; |
748 | } | 748 | } |
749 | 749 | ||
750 | static void run_plant_and_detach_test(int is_early) | 750 | static void run_plant_and_detach_test(int is_early) |
751 | { | 751 | { |
752 | char before[BREAK_INSTR_SIZE]; | 752 | char before[BREAK_INSTR_SIZE]; |
753 | char after[BREAK_INSTR_SIZE]; | 753 | char after[BREAK_INSTR_SIZE]; |
754 | 754 | ||
755 | probe_kernel_read(before, (char *)kgdbts_break_test, | 755 | probe_kernel_read(before, (char *)kgdbts_break_test, |
756 | BREAK_INSTR_SIZE); | 756 | BREAK_INSTR_SIZE); |
757 | init_simple_test(); | 757 | init_simple_test(); |
758 | ts.tst = plant_and_detach_test; | 758 | ts.tst = plant_and_detach_test; |
759 | ts.name = "plant_and_detach_test"; | 759 | ts.name = "plant_and_detach_test"; |
760 | /* Activate test with initial breakpoint */ | 760 | /* Activate test with initial breakpoint */ |
761 | if (!is_early) | 761 | if (!is_early) |
762 | kgdb_breakpoint(); | 762 | kgdb_breakpoint(); |
763 | probe_kernel_read(after, (char *)kgdbts_break_test, | 763 | probe_kernel_read(after, (char *)kgdbts_break_test, |
764 | BREAK_INSTR_SIZE); | 764 | BREAK_INSTR_SIZE); |
765 | if (memcmp(before, after, BREAK_INSTR_SIZE)) { | 765 | if (memcmp(before, after, BREAK_INSTR_SIZE)) { |
766 | printk(KERN_CRIT "kgdbts: ERROR kgdb corrupted memory\n"); | 766 | printk(KERN_CRIT "kgdbts: ERROR kgdb corrupted memory\n"); |
767 | panic("kgdb memory corruption"); | 767 | panic("kgdb memory corruption"); |
768 | } | 768 | } |
769 | 769 | ||
770 | /* complete the detach test */ | 770 | /* complete the detach test */ |
771 | if (!is_early) | 771 | if (!is_early) |
772 | kgdbts_break_test(); | 772 | kgdbts_break_test(); |
773 | } | 773 | } |
774 | 774 | ||
775 | static void run_breakpoint_test(int is_hw_breakpoint) | 775 | static void run_breakpoint_test(int is_hw_breakpoint) |
776 | { | 776 | { |
777 | test_complete = 0; | 777 | test_complete = 0; |
778 | init_simple_test(); | 778 | init_simple_test(); |
779 | if (is_hw_breakpoint) { | 779 | if (is_hw_breakpoint) { |
780 | ts.tst = hw_breakpoint_test; | 780 | ts.tst = hw_breakpoint_test; |
781 | ts.name = "hw_breakpoint_test"; | 781 | ts.name = "hw_breakpoint_test"; |
782 | } else { | 782 | } else { |
783 | ts.tst = sw_breakpoint_test; | 783 | ts.tst = sw_breakpoint_test; |
784 | ts.name = "sw_breakpoint_test"; | 784 | ts.name = "sw_breakpoint_test"; |
785 | } | 785 | } |
786 | /* Activate test with initial breakpoint */ | 786 | /* Activate test with initial breakpoint */ |
787 | kgdb_breakpoint(); | 787 | kgdb_breakpoint(); |
788 | /* run code with the break point in it */ | 788 | /* run code with the break point in it */ |
789 | kgdbts_break_test(); | 789 | kgdbts_break_test(); |
790 | kgdb_breakpoint(); | 790 | kgdb_breakpoint(); |
791 | 791 | ||
792 | if (test_complete) | 792 | if (test_complete) |
793 | return; | 793 | return; |
794 | 794 | ||
795 | eprintk("kgdbts: ERROR %s test failed\n", ts.name); | 795 | eprintk("kgdbts: ERROR %s test failed\n", ts.name); |
796 | if (is_hw_breakpoint) | 796 | if (is_hw_breakpoint) |
797 | hwbreaks_ok = 0; | 797 | hwbreaks_ok = 0; |
798 | } | 798 | } |
799 | 799 | ||
800 | static void run_hw_break_test(int is_write_test) | 800 | static void run_hw_break_test(int is_write_test) |
801 | { | 801 | { |
802 | test_complete = 0; | 802 | test_complete = 0; |
803 | init_simple_test(); | 803 | init_simple_test(); |
804 | if (is_write_test) { | 804 | if (is_write_test) { |
805 | ts.tst = hw_write_break_test; | 805 | ts.tst = hw_write_break_test; |
806 | ts.name = "hw_write_break_test"; | 806 | ts.name = "hw_write_break_test"; |
807 | } else { | 807 | } else { |
808 | ts.tst = hw_access_break_test; | 808 | ts.tst = hw_access_break_test; |
809 | ts.name = "hw_access_break_test"; | 809 | ts.name = "hw_access_break_test"; |
810 | } | 810 | } |
811 | /* Activate test with initial breakpoint */ | 811 | /* Activate test with initial breakpoint */ |
812 | kgdb_breakpoint(); | 812 | kgdb_breakpoint(); |
813 | hw_break_val_access(); | 813 | hw_break_val_access(); |
814 | if (is_write_test) { | 814 | if (is_write_test) { |
815 | if (test_complete == 2) { | 815 | if (test_complete == 2) { |
816 | eprintk("kgdbts: ERROR %s broke on access\n", | 816 | eprintk("kgdbts: ERROR %s broke on access\n", |
817 | ts.name); | 817 | ts.name); |
818 | hwbreaks_ok = 0; | 818 | hwbreaks_ok = 0; |
819 | } | 819 | } |
820 | hw_break_val_write(); | 820 | hw_break_val_write(); |
821 | } | 821 | } |
822 | kgdb_breakpoint(); | 822 | kgdb_breakpoint(); |
823 | 823 | ||
824 | if (test_complete == 1) | 824 | if (test_complete == 1) |
825 | return; | 825 | return; |
826 | 826 | ||
827 | eprintk("kgdbts: ERROR %s test failed\n", ts.name); | 827 | eprintk("kgdbts: ERROR %s test failed\n", ts.name); |
828 | hwbreaks_ok = 0; | 828 | hwbreaks_ok = 0; |
829 | } | 829 | } |
830 | 830 | ||
831 | static void run_nmi_sleep_test(int nmi_sleep) | 831 | static void run_nmi_sleep_test(int nmi_sleep) |
832 | { | 832 | { |
833 | unsigned long flags; | 833 | unsigned long flags; |
834 | 834 | ||
835 | init_simple_test(); | 835 | init_simple_test(); |
836 | ts.tst = nmi_sleep_test; | 836 | ts.tst = nmi_sleep_test; |
837 | ts.name = "nmi_sleep_test"; | 837 | ts.name = "nmi_sleep_test"; |
838 | /* Activate test with initial breakpoint */ | 838 | /* Activate test with initial breakpoint */ |
839 | kgdb_breakpoint(); | 839 | kgdb_breakpoint(); |
840 | local_irq_save(flags); | 840 | local_irq_save(flags); |
841 | mdelay(nmi_sleep*1000); | 841 | mdelay(nmi_sleep*1000); |
842 | touch_nmi_watchdog(); | 842 | touch_nmi_watchdog(); |
843 | local_irq_restore(flags); | 843 | local_irq_restore(flags); |
844 | if (test_complete != 2) | 844 | if (test_complete != 2) |
845 | eprintk("kgdbts: ERROR nmi_test did not hit nmi\n"); | 845 | eprintk("kgdbts: ERROR nmi_test did not hit nmi\n"); |
846 | kgdb_breakpoint(); | 846 | kgdb_breakpoint(); |
847 | if (test_complete == 1) | 847 | if (test_complete == 1) |
848 | return; | 848 | return; |
849 | 849 | ||
850 | eprintk("kgdbts: ERROR %s test failed\n", ts.name); | 850 | eprintk("kgdbts: ERROR %s test failed\n", ts.name); |
851 | } | 851 | } |
852 | 852 | ||
853 | static void run_bad_read_test(void) | 853 | static void run_bad_read_test(void) |
854 | { | 854 | { |
855 | init_simple_test(); | 855 | init_simple_test(); |
856 | ts.tst = bad_read_test; | 856 | ts.tst = bad_read_test; |
857 | ts.name = "bad_read_test"; | 857 | ts.name = "bad_read_test"; |
858 | /* Activate test with initial breakpoint */ | 858 | /* Activate test with initial breakpoint */ |
859 | kgdb_breakpoint(); | 859 | kgdb_breakpoint(); |
860 | } | 860 | } |
861 | 861 | ||
862 | static void run_do_fork_test(void) | 862 | static void run_do_fork_test(void) |
863 | { | 863 | { |
864 | init_simple_test(); | 864 | init_simple_test(); |
865 | ts.tst = do_fork_test; | 865 | ts.tst = do_fork_test; |
866 | ts.name = "do_fork_test"; | 866 | ts.name = "do_fork_test"; |
867 | /* Activate test with initial breakpoint */ | 867 | /* Activate test with initial breakpoint */ |
868 | kgdb_breakpoint(); | 868 | kgdb_breakpoint(); |
869 | } | 869 | } |
870 | 870 | ||
871 | static void run_sys_open_test(void) | 871 | static void run_sys_open_test(void) |
872 | { | 872 | { |
873 | init_simple_test(); | 873 | init_simple_test(); |
874 | ts.tst = sys_open_test; | 874 | ts.tst = sys_open_test; |
875 | ts.name = "sys_open_test"; | 875 | ts.name = "sys_open_test"; |
876 | /* Activate test with initial breakpoint */ | 876 | /* Activate test with initial breakpoint */ |
877 | kgdb_breakpoint(); | 877 | kgdb_breakpoint(); |
878 | } | 878 | } |
879 | 879 | ||
880 | static void run_singlestep_break_test(void) | 880 | static void run_singlestep_break_test(void) |
881 | { | 881 | { |
882 | init_simple_test(); | 882 | init_simple_test(); |
883 | ts.tst = singlestep_break_test; | 883 | ts.tst = singlestep_break_test; |
884 | ts.name = "singlestep_breakpoint_test"; | 884 | ts.name = "singlestep_breakpoint_test"; |
885 | /* Activate test with initial breakpoint */ | 885 | /* Activate test with initial breakpoint */ |
886 | kgdb_breakpoint(); | 886 | kgdb_breakpoint(); |
887 | kgdbts_break_test(); | 887 | kgdbts_break_test(); |
888 | kgdbts_break_test(); | 888 | kgdbts_break_test(); |
889 | } | 889 | } |
890 | 890 | ||
891 | static void kgdbts_run_tests(void) | 891 | static void kgdbts_run_tests(void) |
892 | { | 892 | { |
893 | char *ptr; | 893 | char *ptr; |
894 | int fork_test = 0; | 894 | int fork_test = 0; |
895 | int do_sys_open_test = 0; | 895 | int do_sys_open_test = 0; |
896 | int sstep_test = 1000; | 896 | int sstep_test = 1000; |
897 | int nmi_sleep = 0; | 897 | int nmi_sleep = 0; |
898 | int i; | 898 | int i; |
899 | 899 | ||
900 | ptr = strchr(config, 'F'); | 900 | ptr = strchr(config, 'F'); |
901 | if (ptr) | 901 | if (ptr) |
902 | fork_test = simple_strtol(ptr + 1, NULL, 10); | 902 | fork_test = simple_strtol(ptr + 1, NULL, 10); |
903 | ptr = strchr(config, 'S'); | 903 | ptr = strchr(config, 'S'); |
904 | if (ptr) | 904 | if (ptr) |
905 | do_sys_open_test = simple_strtol(ptr + 1, NULL, 10); | 905 | do_sys_open_test = simple_strtol(ptr + 1, NULL, 10); |
906 | ptr = strchr(config, 'N'); | 906 | ptr = strchr(config, 'N'); |
907 | if (ptr) | 907 | if (ptr) |
908 | nmi_sleep = simple_strtol(ptr+1, NULL, 10); | 908 | nmi_sleep = simple_strtol(ptr+1, NULL, 10); |
909 | ptr = strchr(config, 'I'); | 909 | ptr = strchr(config, 'I'); |
910 | if (ptr) | 910 | if (ptr) |
911 | sstep_test = simple_strtol(ptr+1, NULL, 10); | 911 | sstep_test = simple_strtol(ptr+1, NULL, 10); |
912 | 912 | ||
913 | /* required internal KGDB tests */ | 913 | /* required internal KGDB tests */ |
914 | v1printk("kgdbts:RUN plant and detach test\n"); | 914 | v1printk("kgdbts:RUN plant and detach test\n"); |
915 | run_plant_and_detach_test(0); | 915 | run_plant_and_detach_test(0); |
916 | v1printk("kgdbts:RUN sw breakpoint test\n"); | 916 | v1printk("kgdbts:RUN sw breakpoint test\n"); |
917 | run_breakpoint_test(0); | 917 | run_breakpoint_test(0); |
918 | v1printk("kgdbts:RUN bad memory access test\n"); | 918 | v1printk("kgdbts:RUN bad memory access test\n"); |
919 | run_bad_read_test(); | 919 | run_bad_read_test(); |
920 | v1printk("kgdbts:RUN singlestep test %i iterations\n", sstep_test); | 920 | v1printk("kgdbts:RUN singlestep test %i iterations\n", sstep_test); |
921 | for (i = 0; i < sstep_test; i++) { | 921 | for (i = 0; i < sstep_test; i++) { |
922 | run_singlestep_break_test(); | 922 | run_singlestep_break_test(); |
923 | if (i % 100 == 0) | 923 | if (i % 100 == 0) |
924 | v1printk("kgdbts:RUN singlestep [%i/%i]\n", | 924 | v1printk("kgdbts:RUN singlestep [%i/%i]\n", |
925 | i, sstep_test); | 925 | i, sstep_test); |
926 | } | 926 | } |
927 | 927 | ||
928 | /* ===Optional tests=== */ | 928 | /* ===Optional tests=== */ |
929 | 929 | ||
930 | /* All HW break point tests */ | 930 | /* All HW break point tests */ |
931 | if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) { | 931 | if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) { |
932 | hwbreaks_ok = 1; | 932 | hwbreaks_ok = 1; |
933 | v1printk("kgdbts:RUN hw breakpoint test\n"); | 933 | v1printk("kgdbts:RUN hw breakpoint test\n"); |
934 | run_breakpoint_test(1); | 934 | run_breakpoint_test(1); |
935 | v1printk("kgdbts:RUN hw write breakpoint test\n"); | 935 | v1printk("kgdbts:RUN hw write breakpoint test\n"); |
936 | run_hw_break_test(1); | 936 | run_hw_break_test(1); |
937 | v1printk("kgdbts:RUN access write breakpoint test\n"); | 937 | v1printk("kgdbts:RUN access write breakpoint test\n"); |
938 | run_hw_break_test(0); | 938 | run_hw_break_test(0); |
939 | } | 939 | } |
940 | 940 | ||
941 | if (nmi_sleep) { | 941 | if (nmi_sleep) { |
942 | v1printk("kgdbts:RUN NMI sleep %i seconds test\n", nmi_sleep); | 942 | v1printk("kgdbts:RUN NMI sleep %i seconds test\n", nmi_sleep); |
943 | run_nmi_sleep_test(nmi_sleep); | 943 | run_nmi_sleep_test(nmi_sleep); |
944 | } | 944 | } |
945 | 945 | ||
946 | #ifdef CONFIG_DEBUG_RODATA | 946 | #ifdef CONFIG_DEBUG_RODATA |
947 | /* Until there is an api to write to read-only text segments, use | 947 | /* Until there is an api to write to read-only text segments, use |
948 | * HW breakpoints for the remainder of any tests, else print a | 948 | * HW breakpoints for the remainder of any tests, else print a |
949 | * failure message if hw breakpoints do not work. | 949 | * failure message if hw breakpoints do not work. |
950 | */ | 950 | */ |
951 | if (!(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT && hwbreaks_ok)) { | 951 | if (!(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT && hwbreaks_ok)) { |
952 | eprintk("kgdbts: HW breakpoints do not work," | 952 | eprintk("kgdbts: HW breakpoints do not work," |
953 | "skipping remaining tests\n"); | 953 | "skipping remaining tests\n"); |
954 | return; | 954 | return; |
955 | } | 955 | } |
956 | force_hwbrks = 1; | 956 | force_hwbrks = 1; |
957 | #endif /* CONFIG_DEBUG_RODATA */ | 957 | #endif /* CONFIG_DEBUG_RODATA */ |
958 | 958 | ||
959 | /* If the do_fork test is run it will be the last test that is | 959 | /* If the do_fork test is run it will be the last test that is |
960 | * executed because a kernel thread will be spawned at the very | 960 | * executed because a kernel thread will be spawned at the very |
961 | * end to unregister the debug hooks. | 961 | * end to unregister the debug hooks. |
962 | */ | 962 | */ |
963 | if (fork_test) { | 963 | if (fork_test) { |
964 | repeat_test = fork_test; | 964 | repeat_test = fork_test; |
965 | printk(KERN_INFO "kgdbts:RUN do_fork for %i breakpoints\n", | 965 | printk(KERN_INFO "kgdbts:RUN do_fork for %i breakpoints\n", |
966 | repeat_test); | 966 | repeat_test); |
967 | kthread_run(kgdbts_unreg_thread, NULL, "kgdbts_unreg"); | 967 | kthread_run(kgdbts_unreg_thread, NULL, "kgdbts_unreg"); |
968 | run_do_fork_test(); | 968 | run_do_fork_test(); |
969 | return; | 969 | return; |
970 | } | 970 | } |
971 | 971 | ||
972 | /* If the sys_open test is run it will be the last test that is | 972 | /* If the sys_open test is run it will be the last test that is |
973 | * executed because a kernel thread will be spawned at the very | 973 | * executed because a kernel thread will be spawned at the very |
974 | * end to unregister the debug hooks. | 974 | * end to unregister the debug hooks. |
975 | */ | 975 | */ |
976 | if (do_sys_open_test) { | 976 | if (do_sys_open_test) { |
977 | repeat_test = do_sys_open_test; | 977 | repeat_test = do_sys_open_test; |
978 | printk(KERN_INFO "kgdbts:RUN sys_open for %i breakpoints\n", | 978 | printk(KERN_INFO "kgdbts:RUN sys_open for %i breakpoints\n", |
979 | repeat_test); | 979 | repeat_test); |
980 | kthread_run(kgdbts_unreg_thread, NULL, "kgdbts_unreg"); | 980 | kthread_run(kgdbts_unreg_thread, NULL, "kgdbts_unreg"); |
981 | run_sys_open_test(); | 981 | run_sys_open_test(); |
982 | return; | 982 | return; |
983 | } | 983 | } |
984 | /* Shutdown and unregister */ | 984 | /* Shutdown and unregister */ |
985 | kgdb_unregister_io_module(&kgdbts_io_ops); | 985 | kgdb_unregister_io_module(&kgdbts_io_ops); |
986 | configured = 0; | 986 | configured = 0; |
987 | } | 987 | } |
988 | 988 | ||
989 | static int kgdbts_option_setup(char *opt) | 989 | static int kgdbts_option_setup(char *opt) |
990 | { | 990 | { |
991 | if (strlen(opt) > MAX_CONFIG_LEN) { | 991 | if (strlen(opt) >= MAX_CONFIG_LEN) { |
992 | printk(KERN_ERR "kgdbts: config string too long\n"); | 992 | printk(KERN_ERR "kgdbts: config string too long\n"); |
993 | return -ENOSPC; | 993 | return -ENOSPC; |
994 | } | 994 | } |
995 | strcpy(config, opt); | 995 | strcpy(config, opt); |
996 | 996 | ||
997 | verbose = 0; | 997 | verbose = 0; |
998 | if (strstr(config, "V1")) | 998 | if (strstr(config, "V1")) |
999 | verbose = 1; | 999 | verbose = 1; |
1000 | if (strstr(config, "V2")) | 1000 | if (strstr(config, "V2")) |
1001 | verbose = 2; | 1001 | verbose = 2; |
1002 | 1002 | ||
1003 | return 0; | 1003 | return 0; |
1004 | } | 1004 | } |
1005 | 1005 | ||
1006 | __setup("kgdbts=", kgdbts_option_setup); | 1006 | __setup("kgdbts=", kgdbts_option_setup); |
1007 | 1007 | ||
1008 | static int configure_kgdbts(void) | 1008 | static int configure_kgdbts(void) |
1009 | { | 1009 | { |
1010 | int err = 0; | 1010 | int err = 0; |
1011 | 1011 | ||
1012 | if (!strlen(config) || isspace(config[0])) | 1012 | if (!strlen(config) || isspace(config[0])) |
1013 | goto noconfig; | 1013 | goto noconfig; |
1014 | err = kgdbts_option_setup(config); | 1014 | err = kgdbts_option_setup(config); |
1015 | if (err) | 1015 | if (err) |
1016 | goto noconfig; | 1016 | goto noconfig; |
1017 | 1017 | ||
1018 | final_ack = 0; | 1018 | final_ack = 0; |
1019 | run_plant_and_detach_test(1); | 1019 | run_plant_and_detach_test(1); |
1020 | 1020 | ||
1021 | err = kgdb_register_io_module(&kgdbts_io_ops); | 1021 | err = kgdb_register_io_module(&kgdbts_io_ops); |
1022 | if (err) { | 1022 | if (err) { |
1023 | configured = 0; | 1023 | configured = 0; |
1024 | return err; | 1024 | return err; |
1025 | } | 1025 | } |
1026 | configured = 1; | 1026 | configured = 1; |
1027 | kgdbts_run_tests(); | 1027 | kgdbts_run_tests(); |
1028 | 1028 | ||
1029 | return err; | 1029 | return err; |
1030 | 1030 | ||
1031 | noconfig: | 1031 | noconfig: |
1032 | config[0] = 0; | 1032 | config[0] = 0; |
1033 | configured = 0; | 1033 | configured = 0; |
1034 | 1034 | ||
1035 | return err; | 1035 | return err; |
1036 | } | 1036 | } |
1037 | 1037 | ||
1038 | static int __init init_kgdbts(void) | 1038 | static int __init init_kgdbts(void) |
1039 | { | 1039 | { |
1040 | /* Already configured? */ | 1040 | /* Already configured? */ |
1041 | if (configured == 1) | 1041 | if (configured == 1) |
1042 | return 0; | 1042 | return 0; |
1043 | 1043 | ||
1044 | return configure_kgdbts(); | 1044 | return configure_kgdbts(); |
1045 | } | 1045 | } |
1046 | 1046 | ||
1047 | static int kgdbts_get_char(void) | 1047 | static int kgdbts_get_char(void) |
1048 | { | 1048 | { |
1049 | int val = 0; | 1049 | int val = 0; |
1050 | 1050 | ||
1051 | if (ts.run_test) | 1051 | if (ts.run_test) |
1052 | val = ts.run_test(1, 0); | 1052 | val = ts.run_test(1, 0); |
1053 | 1053 | ||
1054 | return val; | 1054 | return val; |
1055 | } | 1055 | } |
1056 | 1056 | ||
1057 | static void kgdbts_put_char(u8 chr) | 1057 | static void kgdbts_put_char(u8 chr) |
1058 | { | 1058 | { |
1059 | if (ts.run_test) | 1059 | if (ts.run_test) |
1060 | ts.run_test(0, chr); | 1060 | ts.run_test(0, chr); |
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | static int param_set_kgdbts_var(const char *kmessage, struct kernel_param *kp) | 1063 | static int param_set_kgdbts_var(const char *kmessage, struct kernel_param *kp) |
1064 | { | 1064 | { |
1065 | int len = strlen(kmessage); | 1065 | int len = strlen(kmessage); |
1066 | 1066 | ||
1067 | if (len >= MAX_CONFIG_LEN) { | 1067 | if (len >= MAX_CONFIG_LEN) { |
1068 | printk(KERN_ERR "kgdbts: config string too long\n"); | 1068 | printk(KERN_ERR "kgdbts: config string too long\n"); |
1069 | return -ENOSPC; | 1069 | return -ENOSPC; |
1070 | } | 1070 | } |
1071 | 1071 | ||
1072 | /* Only copy in the string if the init function has not run yet */ | 1072 | /* Only copy in the string if the init function has not run yet */ |
1073 | if (configured < 0) { | 1073 | if (configured < 0) { |
1074 | strcpy(config, kmessage); | 1074 | strcpy(config, kmessage); |
1075 | return 0; | 1075 | return 0; |
1076 | } | 1076 | } |
1077 | 1077 | ||
1078 | if (configured == 1) { | 1078 | if (configured == 1) { |
1079 | printk(KERN_ERR "kgdbts: ERROR: Already configured and running.\n"); | 1079 | printk(KERN_ERR "kgdbts: ERROR: Already configured and running.\n"); |
1080 | return -EBUSY; | 1080 | return -EBUSY; |
1081 | } | 1081 | } |
1082 | 1082 | ||
1083 | strcpy(config, kmessage); | 1083 | strcpy(config, kmessage); |
1084 | /* Chop out \n char as a result of echo */ | 1084 | /* Chop out \n char as a result of echo */ |
1085 | if (config[len - 1] == '\n') | 1085 | if (config[len - 1] == '\n') |
1086 | config[len - 1] = '\0'; | 1086 | config[len - 1] = '\0'; |
1087 | 1087 | ||
1088 | /* Go and configure with the new params. */ | 1088 | /* Go and configure with the new params. */ |
1089 | return configure_kgdbts(); | 1089 | return configure_kgdbts(); |
1090 | } | 1090 | } |
1091 | 1091 | ||
1092 | static void kgdbts_pre_exp_handler(void) | 1092 | static void kgdbts_pre_exp_handler(void) |
1093 | { | 1093 | { |
1094 | /* Increment the module count when the debugger is active */ | 1094 | /* Increment the module count when the debugger is active */ |
1095 | if (!kgdb_connected) | 1095 | if (!kgdb_connected) |
1096 | try_module_get(THIS_MODULE); | 1096 | try_module_get(THIS_MODULE); |
1097 | } | 1097 | } |
1098 | 1098 | ||
1099 | static void kgdbts_post_exp_handler(void) | 1099 | static void kgdbts_post_exp_handler(void) |
1100 | { | 1100 | { |
1101 | /* decrement the module count when the debugger detaches */ | 1101 | /* decrement the module count when the debugger detaches */ |
1102 | if (!kgdb_connected) | 1102 | if (!kgdb_connected) |
1103 | module_put(THIS_MODULE); | 1103 | module_put(THIS_MODULE); |
1104 | } | 1104 | } |
1105 | 1105 | ||
1106 | static struct kgdb_io kgdbts_io_ops = { | 1106 | static struct kgdb_io kgdbts_io_ops = { |
1107 | .name = "kgdbts", | 1107 | .name = "kgdbts", |
1108 | .read_char = kgdbts_get_char, | 1108 | .read_char = kgdbts_get_char, |
1109 | .write_char = kgdbts_put_char, | 1109 | .write_char = kgdbts_put_char, |
1110 | .pre_exception = kgdbts_pre_exp_handler, | 1110 | .pre_exception = kgdbts_pre_exp_handler, |
1111 | .post_exception = kgdbts_post_exp_handler, | 1111 | .post_exception = kgdbts_post_exp_handler, |
1112 | }; | 1112 | }; |
1113 | 1113 | ||
1114 | module_init(init_kgdbts); | 1114 | module_init(init_kgdbts); |
1115 | module_param_call(kgdbts, param_set_kgdbts_var, param_get_string, &kps, 0644); | 1115 | module_param_call(kgdbts, param_set_kgdbts_var, param_get_string, &kps, 0644); |
1116 | MODULE_PARM_DESC(kgdbts, "<A|V1|V2>[F#|S#][N#]"); | 1116 | MODULE_PARM_DESC(kgdbts, "<A|V1|V2>[F#|S#][N#]"); |
1117 | MODULE_DESCRIPTION("KGDB Test Suite"); | 1117 | MODULE_DESCRIPTION("KGDB Test Suite"); |
1118 | MODULE_LICENSE("GPL"); | 1118 | MODULE_LICENSE("GPL"); |
1119 | MODULE_AUTHOR("Wind River Systems, Inc."); | 1119 | MODULE_AUTHOR("Wind River Systems, Inc."); |
1120 | 1120 | ||
1121 | 1121 |
drivers/tty/serial/kgdboc.c
1 | /* | 1 | /* |
2 | * Based on the same principle as kgdboe using the NETPOLL api, this | 2 | * Based on the same principle as kgdboe using the NETPOLL api, this |
3 | * driver uses a console polling api to implement a gdb serial inteface | 3 | * driver uses a console polling api to implement a gdb serial inteface |
4 | * which is multiplexed on a console port. | 4 | * which is multiplexed on a console port. |
5 | * | 5 | * |
6 | * Maintainer: Jason Wessel <jason.wessel@windriver.com> | 6 | * Maintainer: Jason Wessel <jason.wessel@windriver.com> |
7 | * | 7 | * |
8 | * 2007-2008 (c) Jason Wessel - Wind River Systems, Inc. | 8 | * 2007-2008 (c) Jason Wessel - Wind River Systems, Inc. |
9 | * | 9 | * |
10 | * This file is licensed under the terms of the GNU General Public | 10 | * This file is licensed under the terms of the GNU General Public |
11 | * License version 2. This program is licensed "as is" without any | 11 | * License version 2. This program is licensed "as is" without any |
12 | * warranty of any kind, whether express or implied. | 12 | * warranty of any kind, whether express or implied. |
13 | */ | 13 | */ |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/ctype.h> | 15 | #include <linux/ctype.h> |
16 | #include <linux/kgdb.h> | 16 | #include <linux/kgdb.h> |
17 | #include <linux/kdb.h> | 17 | #include <linux/kdb.h> |
18 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
19 | #include <linux/console.h> | 19 | #include <linux/console.h> |
20 | #include <linux/vt_kern.h> | 20 | #include <linux/vt_kern.h> |
21 | #include <linux/input.h> | 21 | #include <linux/input.h> |
22 | 22 | ||
23 | #define MAX_CONFIG_LEN 40 | 23 | #define MAX_CONFIG_LEN 40 |
24 | 24 | ||
25 | static struct kgdb_io kgdboc_io_ops; | 25 | static struct kgdb_io kgdboc_io_ops; |
26 | 26 | ||
27 | /* -1 = init not run yet, 0 = unconfigured, 1 = configured. */ | 27 | /* -1 = init not run yet, 0 = unconfigured, 1 = configured. */ |
28 | static int configured = -1; | 28 | static int configured = -1; |
29 | 29 | ||
30 | static char config[MAX_CONFIG_LEN]; | 30 | static char config[MAX_CONFIG_LEN]; |
31 | static struct kparam_string kps = { | 31 | static struct kparam_string kps = { |
32 | .string = config, | 32 | .string = config, |
33 | .maxlen = MAX_CONFIG_LEN, | 33 | .maxlen = MAX_CONFIG_LEN, |
34 | }; | 34 | }; |
35 | 35 | ||
36 | static int kgdboc_use_kms; /* 1 if we use kernel mode switching */ | 36 | static int kgdboc_use_kms; /* 1 if we use kernel mode switching */ |
37 | static struct tty_driver *kgdb_tty_driver; | 37 | static struct tty_driver *kgdb_tty_driver; |
38 | static int kgdb_tty_line; | 38 | static int kgdb_tty_line; |
39 | 39 | ||
40 | #ifdef CONFIG_KDB_KEYBOARD | 40 | #ifdef CONFIG_KDB_KEYBOARD |
41 | static int kgdboc_reset_connect(struct input_handler *handler, | 41 | static int kgdboc_reset_connect(struct input_handler *handler, |
42 | struct input_dev *dev, | 42 | struct input_dev *dev, |
43 | const struct input_device_id *id) | 43 | const struct input_device_id *id) |
44 | { | 44 | { |
45 | input_reset_device(dev); | 45 | input_reset_device(dev); |
46 | 46 | ||
47 | /* Retrun an error - we do not want to bind, just to reset */ | 47 | /* Retrun an error - we do not want to bind, just to reset */ |
48 | return -ENODEV; | 48 | return -ENODEV; |
49 | } | 49 | } |
50 | 50 | ||
51 | static void kgdboc_reset_disconnect(struct input_handle *handle) | 51 | static void kgdboc_reset_disconnect(struct input_handle *handle) |
52 | { | 52 | { |
53 | /* We do not expect anyone to actually bind to us */ | 53 | /* We do not expect anyone to actually bind to us */ |
54 | BUG(); | 54 | BUG(); |
55 | } | 55 | } |
56 | 56 | ||
57 | static const struct input_device_id kgdboc_reset_ids[] = { | 57 | static const struct input_device_id kgdboc_reset_ids[] = { |
58 | { | 58 | { |
59 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, | 59 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, |
60 | .evbit = { BIT_MASK(EV_KEY) }, | 60 | .evbit = { BIT_MASK(EV_KEY) }, |
61 | }, | 61 | }, |
62 | { } | 62 | { } |
63 | }; | 63 | }; |
64 | 64 | ||
65 | static struct input_handler kgdboc_reset_handler = { | 65 | static struct input_handler kgdboc_reset_handler = { |
66 | .connect = kgdboc_reset_connect, | 66 | .connect = kgdboc_reset_connect, |
67 | .disconnect = kgdboc_reset_disconnect, | 67 | .disconnect = kgdboc_reset_disconnect, |
68 | .name = "kgdboc_reset", | 68 | .name = "kgdboc_reset", |
69 | .id_table = kgdboc_reset_ids, | 69 | .id_table = kgdboc_reset_ids, |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static DEFINE_MUTEX(kgdboc_reset_mutex); | 72 | static DEFINE_MUTEX(kgdboc_reset_mutex); |
73 | 73 | ||
74 | static void kgdboc_restore_input_helper(struct work_struct *dummy) | 74 | static void kgdboc_restore_input_helper(struct work_struct *dummy) |
75 | { | 75 | { |
76 | /* | 76 | /* |
77 | * We need to take a mutex to prevent several instances of | 77 | * We need to take a mutex to prevent several instances of |
78 | * this work running on different CPUs so they don't try | 78 | * this work running on different CPUs so they don't try |
79 | * to register again already registered handler. | 79 | * to register again already registered handler. |
80 | */ | 80 | */ |
81 | mutex_lock(&kgdboc_reset_mutex); | 81 | mutex_lock(&kgdboc_reset_mutex); |
82 | 82 | ||
83 | if (input_register_handler(&kgdboc_reset_handler) == 0) | 83 | if (input_register_handler(&kgdboc_reset_handler) == 0) |
84 | input_unregister_handler(&kgdboc_reset_handler); | 84 | input_unregister_handler(&kgdboc_reset_handler); |
85 | 85 | ||
86 | mutex_unlock(&kgdboc_reset_mutex); | 86 | mutex_unlock(&kgdboc_reset_mutex); |
87 | } | 87 | } |
88 | 88 | ||
89 | static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper); | 89 | static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper); |
90 | 90 | ||
91 | static void kgdboc_restore_input(void) | 91 | static void kgdboc_restore_input(void) |
92 | { | 92 | { |
93 | if (likely(system_state == SYSTEM_RUNNING)) | 93 | if (likely(system_state == SYSTEM_RUNNING)) |
94 | schedule_work(&kgdboc_restore_input_work); | 94 | schedule_work(&kgdboc_restore_input_work); |
95 | } | 95 | } |
96 | 96 | ||
97 | static int kgdboc_register_kbd(char **cptr) | 97 | static int kgdboc_register_kbd(char **cptr) |
98 | { | 98 | { |
99 | if (strncmp(*cptr, "kbd", 3) == 0) { | 99 | if (strncmp(*cptr, "kbd", 3) == 0) { |
100 | if (kdb_poll_idx < KDB_POLL_FUNC_MAX) { | 100 | if (kdb_poll_idx < KDB_POLL_FUNC_MAX) { |
101 | kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char; | 101 | kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char; |
102 | kdb_poll_idx++; | 102 | kdb_poll_idx++; |
103 | if (cptr[0][3] == ',') | 103 | if (cptr[0][3] == ',') |
104 | *cptr += 4; | 104 | *cptr += 4; |
105 | else | 105 | else |
106 | return 1; | 106 | return 1; |
107 | } | 107 | } |
108 | } | 108 | } |
109 | return 0; | 109 | return 0; |
110 | } | 110 | } |
111 | 111 | ||
112 | static void kgdboc_unregister_kbd(void) | 112 | static void kgdboc_unregister_kbd(void) |
113 | { | 113 | { |
114 | int i; | 114 | int i; |
115 | 115 | ||
116 | for (i = 0; i < kdb_poll_idx; i++) { | 116 | for (i = 0; i < kdb_poll_idx; i++) { |
117 | if (kdb_poll_funcs[i] == kdb_get_kbd_char) { | 117 | if (kdb_poll_funcs[i] == kdb_get_kbd_char) { |
118 | kdb_poll_idx--; | 118 | kdb_poll_idx--; |
119 | kdb_poll_funcs[i] = kdb_poll_funcs[kdb_poll_idx]; | 119 | kdb_poll_funcs[i] = kdb_poll_funcs[kdb_poll_idx]; |
120 | kdb_poll_funcs[kdb_poll_idx] = NULL; | 120 | kdb_poll_funcs[kdb_poll_idx] = NULL; |
121 | i--; | 121 | i--; |
122 | } | 122 | } |
123 | } | 123 | } |
124 | flush_work_sync(&kgdboc_restore_input_work); | 124 | flush_work_sync(&kgdboc_restore_input_work); |
125 | } | 125 | } |
126 | #else /* ! CONFIG_KDB_KEYBOARD */ | 126 | #else /* ! CONFIG_KDB_KEYBOARD */ |
127 | #define kgdboc_register_kbd(x) 0 | 127 | #define kgdboc_register_kbd(x) 0 |
128 | #define kgdboc_unregister_kbd() | 128 | #define kgdboc_unregister_kbd() |
129 | #define kgdboc_restore_input() | 129 | #define kgdboc_restore_input() |
130 | #endif /* ! CONFIG_KDB_KEYBOARD */ | 130 | #endif /* ! CONFIG_KDB_KEYBOARD */ |
131 | 131 | ||
132 | static int kgdboc_option_setup(char *opt) | 132 | static int kgdboc_option_setup(char *opt) |
133 | { | 133 | { |
134 | if (strlen(opt) > MAX_CONFIG_LEN) { | 134 | if (strlen(opt) >= MAX_CONFIG_LEN) { |
135 | printk(KERN_ERR "kgdboc: config string too long\n"); | 135 | printk(KERN_ERR "kgdboc: config string too long\n"); |
136 | return -ENOSPC; | 136 | return -ENOSPC; |
137 | } | 137 | } |
138 | strcpy(config, opt); | 138 | strcpy(config, opt); |
139 | 139 | ||
140 | return 0; | 140 | return 0; |
141 | } | 141 | } |
142 | 142 | ||
143 | __setup("kgdboc=", kgdboc_option_setup); | 143 | __setup("kgdboc=", kgdboc_option_setup); |
144 | 144 | ||
145 | static void cleanup_kgdboc(void) | 145 | static void cleanup_kgdboc(void) |
146 | { | 146 | { |
147 | kgdboc_unregister_kbd(); | 147 | kgdboc_unregister_kbd(); |
148 | if (configured == 1) | 148 | if (configured == 1) |
149 | kgdb_unregister_io_module(&kgdboc_io_ops); | 149 | kgdb_unregister_io_module(&kgdboc_io_ops); |
150 | } | 150 | } |
151 | 151 | ||
152 | static int configure_kgdboc(void) | 152 | static int configure_kgdboc(void) |
153 | { | 153 | { |
154 | struct tty_driver *p; | 154 | struct tty_driver *p; |
155 | int tty_line = 0; | 155 | int tty_line = 0; |
156 | int err; | 156 | int err; |
157 | char *cptr = config; | 157 | char *cptr = config; |
158 | struct console *cons; | 158 | struct console *cons; |
159 | 159 | ||
160 | err = kgdboc_option_setup(config); | 160 | err = kgdboc_option_setup(config); |
161 | if (err || !strlen(config) || isspace(config[0])) | 161 | if (err || !strlen(config) || isspace(config[0])) |
162 | goto noconfig; | 162 | goto noconfig; |
163 | 163 | ||
164 | err = -ENODEV; | 164 | err = -ENODEV; |
165 | kgdboc_io_ops.is_console = 0; | 165 | kgdboc_io_ops.is_console = 0; |
166 | kgdb_tty_driver = NULL; | 166 | kgdb_tty_driver = NULL; |
167 | 167 | ||
168 | kgdboc_use_kms = 0; | 168 | kgdboc_use_kms = 0; |
169 | if (strncmp(cptr, "kms,", 4) == 0) { | 169 | if (strncmp(cptr, "kms,", 4) == 0) { |
170 | cptr += 4; | 170 | cptr += 4; |
171 | kgdboc_use_kms = 1; | 171 | kgdboc_use_kms = 1; |
172 | } | 172 | } |
173 | 173 | ||
174 | if (kgdboc_register_kbd(&cptr)) | 174 | if (kgdboc_register_kbd(&cptr)) |
175 | goto do_register; | 175 | goto do_register; |
176 | 176 | ||
177 | p = tty_find_polling_driver(cptr, &tty_line); | 177 | p = tty_find_polling_driver(cptr, &tty_line); |
178 | if (!p) | 178 | if (!p) |
179 | goto noconfig; | 179 | goto noconfig; |
180 | 180 | ||
181 | cons = console_drivers; | 181 | cons = console_drivers; |
182 | while (cons) { | 182 | while (cons) { |
183 | int idx; | 183 | int idx; |
184 | if (cons->device && cons->device(cons, &idx) == p && | 184 | if (cons->device && cons->device(cons, &idx) == p && |
185 | idx == tty_line) { | 185 | idx == tty_line) { |
186 | kgdboc_io_ops.is_console = 1; | 186 | kgdboc_io_ops.is_console = 1; |
187 | break; | 187 | break; |
188 | } | 188 | } |
189 | cons = cons->next; | 189 | cons = cons->next; |
190 | } | 190 | } |
191 | 191 | ||
192 | kgdb_tty_driver = p; | 192 | kgdb_tty_driver = p; |
193 | kgdb_tty_line = tty_line; | 193 | kgdb_tty_line = tty_line; |
194 | 194 | ||
195 | do_register: | 195 | do_register: |
196 | err = kgdb_register_io_module(&kgdboc_io_ops); | 196 | err = kgdb_register_io_module(&kgdboc_io_ops); |
197 | if (err) | 197 | if (err) |
198 | goto noconfig; | 198 | goto noconfig; |
199 | 199 | ||
200 | configured = 1; | 200 | configured = 1; |
201 | 201 | ||
202 | return 0; | 202 | return 0; |
203 | 203 | ||
204 | noconfig: | 204 | noconfig: |
205 | config[0] = 0; | 205 | config[0] = 0; |
206 | configured = 0; | 206 | configured = 0; |
207 | cleanup_kgdboc(); | 207 | cleanup_kgdboc(); |
208 | 208 | ||
209 | return err; | 209 | return err; |
210 | } | 210 | } |
211 | 211 | ||
212 | static int __init init_kgdboc(void) | 212 | static int __init init_kgdboc(void) |
213 | { | 213 | { |
214 | /* Already configured? */ | 214 | /* Already configured? */ |
215 | if (configured == 1) | 215 | if (configured == 1) |
216 | return 0; | 216 | return 0; |
217 | 217 | ||
218 | return configure_kgdboc(); | 218 | return configure_kgdboc(); |
219 | } | 219 | } |
220 | 220 | ||
221 | static int kgdboc_get_char(void) | 221 | static int kgdboc_get_char(void) |
222 | { | 222 | { |
223 | if (!kgdb_tty_driver) | 223 | if (!kgdb_tty_driver) |
224 | return -1; | 224 | return -1; |
225 | return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver, | 225 | return kgdb_tty_driver->ops->poll_get_char(kgdb_tty_driver, |
226 | kgdb_tty_line); | 226 | kgdb_tty_line); |
227 | } | 227 | } |
228 | 228 | ||
229 | static void kgdboc_put_char(u8 chr) | 229 | static void kgdboc_put_char(u8 chr) |
230 | { | 230 | { |
231 | if (!kgdb_tty_driver) | 231 | if (!kgdb_tty_driver) |
232 | return; | 232 | return; |
233 | kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver, | 233 | kgdb_tty_driver->ops->poll_put_char(kgdb_tty_driver, |
234 | kgdb_tty_line, chr); | 234 | kgdb_tty_line, chr); |
235 | } | 235 | } |
236 | 236 | ||
237 | static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp) | 237 | static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp) |
238 | { | 238 | { |
239 | int len = strlen(kmessage); | 239 | int len = strlen(kmessage); |
240 | 240 | ||
241 | if (len >= MAX_CONFIG_LEN) { | 241 | if (len >= MAX_CONFIG_LEN) { |
242 | printk(KERN_ERR "kgdboc: config string too long\n"); | 242 | printk(KERN_ERR "kgdboc: config string too long\n"); |
243 | return -ENOSPC; | 243 | return -ENOSPC; |
244 | } | 244 | } |
245 | 245 | ||
246 | /* Only copy in the string if the init function has not run yet */ | 246 | /* Only copy in the string if the init function has not run yet */ |
247 | if (configured < 0) { | 247 | if (configured < 0) { |
248 | strcpy(config, kmessage); | 248 | strcpy(config, kmessage); |
249 | return 0; | 249 | return 0; |
250 | } | 250 | } |
251 | 251 | ||
252 | if (kgdb_connected) { | 252 | if (kgdb_connected) { |
253 | printk(KERN_ERR | 253 | printk(KERN_ERR |
254 | "kgdboc: Cannot reconfigure while KGDB is connected.\n"); | 254 | "kgdboc: Cannot reconfigure while KGDB is connected.\n"); |
255 | 255 | ||
256 | return -EBUSY; | 256 | return -EBUSY; |
257 | } | 257 | } |
258 | 258 | ||
259 | strcpy(config, kmessage); | 259 | strcpy(config, kmessage); |
260 | /* Chop out \n char as a result of echo */ | 260 | /* Chop out \n char as a result of echo */ |
261 | if (config[len - 1] == '\n') | 261 | if (config[len - 1] == '\n') |
262 | config[len - 1] = '\0'; | 262 | config[len - 1] = '\0'; |
263 | 263 | ||
264 | if (configured == 1) | 264 | if (configured == 1) |
265 | cleanup_kgdboc(); | 265 | cleanup_kgdboc(); |
266 | 266 | ||
267 | /* Go and configure with the new params. */ | 267 | /* Go and configure with the new params. */ |
268 | return configure_kgdboc(); | 268 | return configure_kgdboc(); |
269 | } | 269 | } |
270 | 270 | ||
271 | static int dbg_restore_graphics; | 271 | static int dbg_restore_graphics; |
272 | 272 | ||
273 | static void kgdboc_pre_exp_handler(void) | 273 | static void kgdboc_pre_exp_handler(void) |
274 | { | 274 | { |
275 | if (!dbg_restore_graphics && kgdboc_use_kms) { | 275 | if (!dbg_restore_graphics && kgdboc_use_kms) { |
276 | dbg_restore_graphics = 1; | 276 | dbg_restore_graphics = 1; |
277 | con_debug_enter(vc_cons[fg_console].d); | 277 | con_debug_enter(vc_cons[fg_console].d); |
278 | } | 278 | } |
279 | /* Increment the module count when the debugger is active */ | 279 | /* Increment the module count when the debugger is active */ |
280 | if (!kgdb_connected) | 280 | if (!kgdb_connected) |
281 | try_module_get(THIS_MODULE); | 281 | try_module_get(THIS_MODULE); |
282 | } | 282 | } |
283 | 283 | ||
284 | static void kgdboc_post_exp_handler(void) | 284 | static void kgdboc_post_exp_handler(void) |
285 | { | 285 | { |
286 | /* decrement the module count when the debugger detaches */ | 286 | /* decrement the module count when the debugger detaches */ |
287 | if (!kgdb_connected) | 287 | if (!kgdb_connected) |
288 | module_put(THIS_MODULE); | 288 | module_put(THIS_MODULE); |
289 | if (kgdboc_use_kms && dbg_restore_graphics) { | 289 | if (kgdboc_use_kms && dbg_restore_graphics) { |
290 | dbg_restore_graphics = 0; | 290 | dbg_restore_graphics = 0; |
291 | con_debug_leave(); | 291 | con_debug_leave(); |
292 | } | 292 | } |
293 | kgdboc_restore_input(); | 293 | kgdboc_restore_input(); |
294 | } | 294 | } |
295 | 295 | ||
296 | static struct kgdb_io kgdboc_io_ops = { | 296 | static struct kgdb_io kgdboc_io_ops = { |
297 | .name = "kgdboc", | 297 | .name = "kgdboc", |
298 | .read_char = kgdboc_get_char, | 298 | .read_char = kgdboc_get_char, |
299 | .write_char = kgdboc_put_char, | 299 | .write_char = kgdboc_put_char, |
300 | .pre_exception = kgdboc_pre_exp_handler, | 300 | .pre_exception = kgdboc_pre_exp_handler, |
301 | .post_exception = kgdboc_post_exp_handler, | 301 | .post_exception = kgdboc_post_exp_handler, |
302 | }; | 302 | }; |
303 | 303 | ||
304 | #ifdef CONFIG_KGDB_SERIAL_CONSOLE | 304 | #ifdef CONFIG_KGDB_SERIAL_CONSOLE |
305 | /* This is only available if kgdboc is a built in for early debugging */ | 305 | /* This is only available if kgdboc is a built in for early debugging */ |
306 | static int __init kgdboc_early_init(char *opt) | 306 | static int __init kgdboc_early_init(char *opt) |
307 | { | 307 | { |
308 | /* save the first character of the config string because the | 308 | /* save the first character of the config string because the |
309 | * init routine can destroy it. | 309 | * init routine can destroy it. |
310 | */ | 310 | */ |
311 | char save_ch; | 311 | char save_ch; |
312 | 312 | ||
313 | kgdboc_option_setup(opt); | 313 | kgdboc_option_setup(opt); |
314 | save_ch = config[0]; | 314 | save_ch = config[0]; |
315 | init_kgdboc(); | 315 | init_kgdboc(); |
316 | config[0] = save_ch; | 316 | config[0] = save_ch; |
317 | return 0; | 317 | return 0; |
318 | } | 318 | } |
319 | 319 | ||
320 | early_param("ekgdboc", kgdboc_early_init); | 320 | early_param("ekgdboc", kgdboc_early_init); |
321 | #endif /* CONFIG_KGDB_SERIAL_CONSOLE */ | 321 | #endif /* CONFIG_KGDB_SERIAL_CONSOLE */ |
322 | 322 | ||
323 | module_init(init_kgdboc); | 323 | module_init(init_kgdboc); |
324 | module_exit(cleanup_kgdboc); | 324 | module_exit(cleanup_kgdboc); |
325 | module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644); | 325 | module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644); |
326 | MODULE_PARM_DESC(kgdboc, "<serial_device>[,baud]"); | 326 | MODULE_PARM_DESC(kgdboc, "<serial_device>[,baud]"); |
327 | MODULE_DESCRIPTION("KGDB Console TTY Driver"); | 327 | MODULE_DESCRIPTION("KGDB Console TTY Driver"); |
328 | MODULE_LICENSE("GPL"); | 328 | MODULE_LICENSE("GPL"); |
329 | 329 |
kernel/debug/kdb/kdb_main.c
1 | /* | 1 | /* |
2 | * Kernel Debugger Architecture Independent Main Code | 2 | * Kernel Debugger Architecture Independent Main Code |
3 | * | 3 | * |
4 | * This file is subject to the terms and conditions of the GNU General Public | 4 | * This file is subject to the terms and conditions of the GNU General Public |
5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 1999-2004 Silicon Graphics, Inc. All Rights Reserved. | 8 | * Copyright (C) 1999-2004 Silicon Graphics, Inc. All Rights Reserved. |
9 | * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com> | 9 | * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com> |
10 | * Xscale (R) modifications copyright (C) 2003 Intel Corporation. | 10 | * Xscale (R) modifications copyright (C) 2003 Intel Corporation. |
11 | * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. | 11 | * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/ctype.h> | 14 | #include <linux/ctype.h> |
15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/reboot.h> | 17 | #include <linux/reboot.h> |
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/sysrq.h> | 19 | #include <linux/sysrq.h> |
20 | #include <linux/smp.h> | 20 | #include <linux/smp.h> |
21 | #include <linux/utsname.h> | 21 | #include <linux/utsname.h> |
22 | #include <linux/vmalloc.h> | 22 | #include <linux/vmalloc.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/kallsyms.h> | 26 | #include <linux/kallsyms.h> |
27 | #include <linux/kgdb.h> | 27 | #include <linux/kgdb.h> |
28 | #include <linux/kdb.h> | 28 | #include <linux/kdb.h> |
29 | #include <linux/notifier.h> | 29 | #include <linux/notifier.h> |
30 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/nmi.h> | 32 | #include <linux/nmi.h> |
33 | #include <linux/time.h> | 33 | #include <linux/time.h> |
34 | #include <linux/ptrace.h> | 34 | #include <linux/ptrace.h> |
35 | #include <linux/sysctl.h> | 35 | #include <linux/sysctl.h> |
36 | #include <linux/cpu.h> | 36 | #include <linux/cpu.h> |
37 | #include <linux/kdebug.h> | 37 | #include <linux/kdebug.h> |
38 | #include <linux/proc_fs.h> | 38 | #include <linux/proc_fs.h> |
39 | #include <linux/uaccess.h> | 39 | #include <linux/uaccess.h> |
40 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
41 | #include "kdb_private.h" | 41 | #include "kdb_private.h" |
42 | 42 | ||
43 | #define GREP_LEN 256 | 43 | #define GREP_LEN 256 |
44 | char kdb_grep_string[GREP_LEN]; | 44 | char kdb_grep_string[GREP_LEN]; |
45 | int kdb_grepping_flag; | 45 | int kdb_grepping_flag; |
46 | EXPORT_SYMBOL(kdb_grepping_flag); | 46 | EXPORT_SYMBOL(kdb_grepping_flag); |
47 | int kdb_grep_leading; | 47 | int kdb_grep_leading; |
48 | int kdb_grep_trailing; | 48 | int kdb_grep_trailing; |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * Kernel debugger state flags | 51 | * Kernel debugger state flags |
52 | */ | 52 | */ |
53 | int kdb_flags; | 53 | int kdb_flags; |
54 | atomic_t kdb_event; | 54 | atomic_t kdb_event; |
55 | 55 | ||
56 | /* | 56 | /* |
57 | * kdb_lock protects updates to kdb_initial_cpu. Used to | 57 | * kdb_lock protects updates to kdb_initial_cpu. Used to |
58 | * single thread processors through the kernel debugger. | 58 | * single thread processors through the kernel debugger. |
59 | */ | 59 | */ |
60 | int kdb_initial_cpu = -1; /* cpu number that owns kdb */ | 60 | int kdb_initial_cpu = -1; /* cpu number that owns kdb */ |
61 | int kdb_nextline = 1; | 61 | int kdb_nextline = 1; |
62 | int kdb_state; /* General KDB state */ | 62 | int kdb_state; /* General KDB state */ |
63 | 63 | ||
64 | struct task_struct *kdb_current_task; | 64 | struct task_struct *kdb_current_task; |
65 | EXPORT_SYMBOL(kdb_current_task); | 65 | EXPORT_SYMBOL(kdb_current_task); |
66 | struct pt_regs *kdb_current_regs; | 66 | struct pt_regs *kdb_current_regs; |
67 | 67 | ||
68 | const char *kdb_diemsg; | 68 | const char *kdb_diemsg; |
69 | static int kdb_go_count; | 69 | static int kdb_go_count; |
70 | #ifdef CONFIG_KDB_CONTINUE_CATASTROPHIC | 70 | #ifdef CONFIG_KDB_CONTINUE_CATASTROPHIC |
71 | static unsigned int kdb_continue_catastrophic = | 71 | static unsigned int kdb_continue_catastrophic = |
72 | CONFIG_KDB_CONTINUE_CATASTROPHIC; | 72 | CONFIG_KDB_CONTINUE_CATASTROPHIC; |
73 | #else | 73 | #else |
74 | static unsigned int kdb_continue_catastrophic; | 74 | static unsigned int kdb_continue_catastrophic; |
75 | #endif | 75 | #endif |
76 | 76 | ||
77 | /* kdb_commands describes the available commands. */ | 77 | /* kdb_commands describes the available commands. */ |
78 | static kdbtab_t *kdb_commands; | 78 | static kdbtab_t *kdb_commands; |
79 | #define KDB_BASE_CMD_MAX 50 | 79 | #define KDB_BASE_CMD_MAX 50 |
80 | static int kdb_max_commands = KDB_BASE_CMD_MAX; | 80 | static int kdb_max_commands = KDB_BASE_CMD_MAX; |
81 | static kdbtab_t kdb_base_commands[50]; | 81 | static kdbtab_t kdb_base_commands[KDB_BASE_CMD_MAX]; |
82 | #define for_each_kdbcmd(cmd, num) \ | 82 | #define for_each_kdbcmd(cmd, num) \ |
83 | for ((cmd) = kdb_base_commands, (num) = 0; \ | 83 | for ((cmd) = kdb_base_commands, (num) = 0; \ |
84 | num < kdb_max_commands; \ | 84 | num < kdb_max_commands; \ |
85 | num++, num == KDB_BASE_CMD_MAX ? cmd = kdb_commands : cmd++) | 85 | num++, num == KDB_BASE_CMD_MAX ? cmd = kdb_commands : cmd++) |
86 | 86 | ||
87 | typedef struct _kdbmsg { | 87 | typedef struct _kdbmsg { |
88 | int km_diag; /* kdb diagnostic */ | 88 | int km_diag; /* kdb diagnostic */ |
89 | char *km_msg; /* Corresponding message text */ | 89 | char *km_msg; /* Corresponding message text */ |
90 | } kdbmsg_t; | 90 | } kdbmsg_t; |
91 | 91 | ||
92 | #define KDBMSG(msgnum, text) \ | 92 | #define KDBMSG(msgnum, text) \ |
93 | { KDB_##msgnum, text } | 93 | { KDB_##msgnum, text } |
94 | 94 | ||
95 | static kdbmsg_t kdbmsgs[] = { | 95 | static kdbmsg_t kdbmsgs[] = { |
96 | KDBMSG(NOTFOUND, "Command Not Found"), | 96 | KDBMSG(NOTFOUND, "Command Not Found"), |
97 | KDBMSG(ARGCOUNT, "Improper argument count, see usage."), | 97 | KDBMSG(ARGCOUNT, "Improper argument count, see usage."), |
98 | KDBMSG(BADWIDTH, "Illegal value for BYTESPERWORD use 1, 2, 4 or 8, " | 98 | KDBMSG(BADWIDTH, "Illegal value for BYTESPERWORD use 1, 2, 4 or 8, " |
99 | "8 is only allowed on 64 bit systems"), | 99 | "8 is only allowed on 64 bit systems"), |
100 | KDBMSG(BADRADIX, "Illegal value for RADIX use 8, 10 or 16"), | 100 | KDBMSG(BADRADIX, "Illegal value for RADIX use 8, 10 or 16"), |
101 | KDBMSG(NOTENV, "Cannot find environment variable"), | 101 | KDBMSG(NOTENV, "Cannot find environment variable"), |
102 | KDBMSG(NOENVVALUE, "Environment variable should have value"), | 102 | KDBMSG(NOENVVALUE, "Environment variable should have value"), |
103 | KDBMSG(NOTIMP, "Command not implemented"), | 103 | KDBMSG(NOTIMP, "Command not implemented"), |
104 | KDBMSG(ENVFULL, "Environment full"), | 104 | KDBMSG(ENVFULL, "Environment full"), |
105 | KDBMSG(ENVBUFFULL, "Environment buffer full"), | 105 | KDBMSG(ENVBUFFULL, "Environment buffer full"), |
106 | KDBMSG(TOOMANYBPT, "Too many breakpoints defined"), | 106 | KDBMSG(TOOMANYBPT, "Too many breakpoints defined"), |
107 | #ifdef CONFIG_CPU_XSCALE | 107 | #ifdef CONFIG_CPU_XSCALE |
108 | KDBMSG(TOOMANYDBREGS, "More breakpoints than ibcr registers defined"), | 108 | KDBMSG(TOOMANYDBREGS, "More breakpoints than ibcr registers defined"), |
109 | #else | 109 | #else |
110 | KDBMSG(TOOMANYDBREGS, "More breakpoints than db registers defined"), | 110 | KDBMSG(TOOMANYDBREGS, "More breakpoints than db registers defined"), |
111 | #endif | 111 | #endif |
112 | KDBMSG(DUPBPT, "Duplicate breakpoint address"), | 112 | KDBMSG(DUPBPT, "Duplicate breakpoint address"), |
113 | KDBMSG(BPTNOTFOUND, "Breakpoint not found"), | 113 | KDBMSG(BPTNOTFOUND, "Breakpoint not found"), |
114 | KDBMSG(BADMODE, "Invalid IDMODE"), | 114 | KDBMSG(BADMODE, "Invalid IDMODE"), |
115 | KDBMSG(BADINT, "Illegal numeric value"), | 115 | KDBMSG(BADINT, "Illegal numeric value"), |
116 | KDBMSG(INVADDRFMT, "Invalid symbolic address format"), | 116 | KDBMSG(INVADDRFMT, "Invalid symbolic address format"), |
117 | KDBMSG(BADREG, "Invalid register name"), | 117 | KDBMSG(BADREG, "Invalid register name"), |
118 | KDBMSG(BADCPUNUM, "Invalid cpu number"), | 118 | KDBMSG(BADCPUNUM, "Invalid cpu number"), |
119 | KDBMSG(BADLENGTH, "Invalid length field"), | 119 | KDBMSG(BADLENGTH, "Invalid length field"), |
120 | KDBMSG(NOBP, "No Breakpoint exists"), | 120 | KDBMSG(NOBP, "No Breakpoint exists"), |
121 | KDBMSG(BADADDR, "Invalid address"), | 121 | KDBMSG(BADADDR, "Invalid address"), |
122 | }; | 122 | }; |
123 | #undef KDBMSG | 123 | #undef KDBMSG |
124 | 124 | ||
125 | static const int __nkdb_err = sizeof(kdbmsgs) / sizeof(kdbmsg_t); | 125 | static const int __nkdb_err = sizeof(kdbmsgs) / sizeof(kdbmsg_t); |
126 | 126 | ||
127 | 127 | ||
128 | /* | 128 | /* |
129 | * Initial environment. This is all kept static and local to | 129 | * Initial environment. This is all kept static and local to |
130 | * this file. We don't want to rely on the memory allocation | 130 | * this file. We don't want to rely on the memory allocation |
131 | * mechanisms in the kernel, so we use a very limited allocate-only | 131 | * mechanisms in the kernel, so we use a very limited allocate-only |
132 | * heap for new and altered environment variables. The entire | 132 | * heap for new and altered environment variables. The entire |
133 | * environment is limited to a fixed number of entries (add more | 133 | * environment is limited to a fixed number of entries (add more |
134 | * to __env[] if required) and a fixed amount of heap (add more to | 134 | * to __env[] if required) and a fixed amount of heap (add more to |
135 | * KDB_ENVBUFSIZE if required). | 135 | * KDB_ENVBUFSIZE if required). |
136 | */ | 136 | */ |
137 | 137 | ||
138 | static char *__env[] = { | 138 | static char *__env[] = { |
139 | #if defined(CONFIG_SMP) | 139 | #if defined(CONFIG_SMP) |
140 | "PROMPT=[%d]kdb> ", | 140 | "PROMPT=[%d]kdb> ", |
141 | "MOREPROMPT=[%d]more> ", | 141 | "MOREPROMPT=[%d]more> ", |
142 | #else | 142 | #else |
143 | "PROMPT=kdb> ", | 143 | "PROMPT=kdb> ", |
144 | "MOREPROMPT=more> ", | 144 | "MOREPROMPT=more> ", |
145 | #endif | 145 | #endif |
146 | "RADIX=16", | 146 | "RADIX=16", |
147 | "MDCOUNT=8", /* lines of md output */ | 147 | "MDCOUNT=8", /* lines of md output */ |
148 | "BTARGS=9", /* 9 possible args in bt */ | 148 | "BTARGS=9", /* 9 possible args in bt */ |
149 | KDB_PLATFORM_ENV, | 149 | KDB_PLATFORM_ENV, |
150 | "DTABCOUNT=30", | 150 | "DTABCOUNT=30", |
151 | "NOSECT=1", | 151 | "NOSECT=1", |
152 | (char *)0, | 152 | (char *)0, |
153 | (char *)0, | 153 | (char *)0, |
154 | (char *)0, | 154 | (char *)0, |
155 | (char *)0, | 155 | (char *)0, |
156 | (char *)0, | 156 | (char *)0, |
157 | (char *)0, | 157 | (char *)0, |
158 | (char *)0, | 158 | (char *)0, |
159 | (char *)0, | 159 | (char *)0, |
160 | (char *)0, | 160 | (char *)0, |
161 | (char *)0, | 161 | (char *)0, |
162 | (char *)0, | 162 | (char *)0, |
163 | (char *)0, | 163 | (char *)0, |
164 | (char *)0, | 164 | (char *)0, |
165 | (char *)0, | 165 | (char *)0, |
166 | (char *)0, | 166 | (char *)0, |
167 | (char *)0, | 167 | (char *)0, |
168 | (char *)0, | 168 | (char *)0, |
169 | (char *)0, | 169 | (char *)0, |
170 | (char *)0, | 170 | (char *)0, |
171 | (char *)0, | 171 | (char *)0, |
172 | (char *)0, | 172 | (char *)0, |
173 | (char *)0, | 173 | (char *)0, |
174 | (char *)0, | 174 | (char *)0, |
175 | }; | 175 | }; |
176 | 176 | ||
177 | static const int __nenv = (sizeof(__env) / sizeof(char *)); | 177 | static const int __nenv = (sizeof(__env) / sizeof(char *)); |
178 | 178 | ||
179 | struct task_struct *kdb_curr_task(int cpu) | 179 | struct task_struct *kdb_curr_task(int cpu) |
180 | { | 180 | { |
181 | struct task_struct *p = curr_task(cpu); | 181 | struct task_struct *p = curr_task(cpu); |
182 | #ifdef _TIF_MCA_INIT | 182 | #ifdef _TIF_MCA_INIT |
183 | if ((task_thread_info(p)->flags & _TIF_MCA_INIT) && KDB_TSK(cpu)) | 183 | if ((task_thread_info(p)->flags & _TIF_MCA_INIT) && KDB_TSK(cpu)) |
184 | p = krp->p; | 184 | p = krp->p; |
185 | #endif | 185 | #endif |
186 | return p; | 186 | return p; |
187 | } | 187 | } |
188 | 188 | ||
189 | /* | 189 | /* |
190 | * kdbgetenv - This function will return the character string value of | 190 | * kdbgetenv - This function will return the character string value of |
191 | * an environment variable. | 191 | * an environment variable. |
192 | * Parameters: | 192 | * Parameters: |
193 | * match A character string representing an environment variable. | 193 | * match A character string representing an environment variable. |
194 | * Returns: | 194 | * Returns: |
195 | * NULL No environment variable matches 'match' | 195 | * NULL No environment variable matches 'match' |
196 | * char* Pointer to string value of environment variable. | 196 | * char* Pointer to string value of environment variable. |
197 | */ | 197 | */ |
198 | char *kdbgetenv(const char *match) | 198 | char *kdbgetenv(const char *match) |
199 | { | 199 | { |
200 | char **ep = __env; | 200 | char **ep = __env; |
201 | int matchlen = strlen(match); | 201 | int matchlen = strlen(match); |
202 | int i; | 202 | int i; |
203 | 203 | ||
204 | for (i = 0; i < __nenv; i++) { | 204 | for (i = 0; i < __nenv; i++) { |
205 | char *e = *ep++; | 205 | char *e = *ep++; |
206 | 206 | ||
207 | if (!e) | 207 | if (!e) |
208 | continue; | 208 | continue; |
209 | 209 | ||
210 | if ((strncmp(match, e, matchlen) == 0) | 210 | if ((strncmp(match, e, matchlen) == 0) |
211 | && ((e[matchlen] == '\0') | 211 | && ((e[matchlen] == '\0') |
212 | || (e[matchlen] == '='))) { | 212 | || (e[matchlen] == '='))) { |
213 | char *cp = strchr(e, '='); | 213 | char *cp = strchr(e, '='); |
214 | return cp ? ++cp : ""; | 214 | return cp ? ++cp : ""; |
215 | } | 215 | } |
216 | } | 216 | } |
217 | return NULL; | 217 | return NULL; |
218 | } | 218 | } |
219 | 219 | ||
220 | /* | 220 | /* |
221 | * kdballocenv - This function is used to allocate bytes for | 221 | * kdballocenv - This function is used to allocate bytes for |
222 | * environment entries. | 222 | * environment entries. |
223 | * Parameters: | 223 | * Parameters: |
224 | * match A character string representing a numeric value | 224 | * match A character string representing a numeric value |
225 | * Outputs: | 225 | * Outputs: |
226 | * *value the unsigned long representation of the env variable 'match' | 226 | * *value the unsigned long representation of the env variable 'match' |
227 | * Returns: | 227 | * Returns: |
228 | * Zero on success, a kdb diagnostic on failure. | 228 | * Zero on success, a kdb diagnostic on failure. |
229 | * Remarks: | 229 | * Remarks: |
230 | * We use a static environment buffer (envbuffer) to hold the values | 230 | * We use a static environment buffer (envbuffer) to hold the values |
231 | * of dynamically generated environment variables (see kdb_set). Buffer | 231 | * of dynamically generated environment variables (see kdb_set). Buffer |
232 | * space once allocated is never free'd, so over time, the amount of space | 232 | * space once allocated is never free'd, so over time, the amount of space |
233 | * (currently 512 bytes) will be exhausted if env variables are changed | 233 | * (currently 512 bytes) will be exhausted if env variables are changed |
234 | * frequently. | 234 | * frequently. |
235 | */ | 235 | */ |
236 | static char *kdballocenv(size_t bytes) | 236 | static char *kdballocenv(size_t bytes) |
237 | { | 237 | { |
238 | #define KDB_ENVBUFSIZE 512 | 238 | #define KDB_ENVBUFSIZE 512 |
239 | static char envbuffer[KDB_ENVBUFSIZE]; | 239 | static char envbuffer[KDB_ENVBUFSIZE]; |
240 | static int envbufsize; | 240 | static int envbufsize; |
241 | char *ep = NULL; | 241 | char *ep = NULL; |
242 | 242 | ||
243 | if ((KDB_ENVBUFSIZE - envbufsize) >= bytes) { | 243 | if ((KDB_ENVBUFSIZE - envbufsize) >= bytes) { |
244 | ep = &envbuffer[envbufsize]; | 244 | ep = &envbuffer[envbufsize]; |
245 | envbufsize += bytes; | 245 | envbufsize += bytes; |
246 | } | 246 | } |
247 | return ep; | 247 | return ep; |
248 | } | 248 | } |
249 | 249 | ||
250 | /* | 250 | /* |
251 | * kdbgetulenv - This function will return the value of an unsigned | 251 | * kdbgetulenv - This function will return the value of an unsigned |
252 | * long-valued environment variable. | 252 | * long-valued environment variable. |
253 | * Parameters: | 253 | * Parameters: |
254 | * match A character string representing a numeric value | 254 | * match A character string representing a numeric value |
255 | * Outputs: | 255 | * Outputs: |
256 | * *value the unsigned long represntation of the env variable 'match' | 256 | * *value the unsigned long represntation of the env variable 'match' |
257 | * Returns: | 257 | * Returns: |
258 | * Zero on success, a kdb diagnostic on failure. | 258 | * Zero on success, a kdb diagnostic on failure. |
259 | */ | 259 | */ |
260 | static int kdbgetulenv(const char *match, unsigned long *value) | 260 | static int kdbgetulenv(const char *match, unsigned long *value) |
261 | { | 261 | { |
262 | char *ep; | 262 | char *ep; |
263 | 263 | ||
264 | ep = kdbgetenv(match); | 264 | ep = kdbgetenv(match); |
265 | if (!ep) | 265 | if (!ep) |
266 | return KDB_NOTENV; | 266 | return KDB_NOTENV; |
267 | if (strlen(ep) == 0) | 267 | if (strlen(ep) == 0) |
268 | return KDB_NOENVVALUE; | 268 | return KDB_NOENVVALUE; |
269 | 269 | ||
270 | *value = simple_strtoul(ep, NULL, 0); | 270 | *value = simple_strtoul(ep, NULL, 0); |
271 | 271 | ||
272 | return 0; | 272 | return 0; |
273 | } | 273 | } |
274 | 274 | ||
275 | /* | 275 | /* |
276 | * kdbgetintenv - This function will return the value of an | 276 | * kdbgetintenv - This function will return the value of an |
277 | * integer-valued environment variable. | 277 | * integer-valued environment variable. |
278 | * Parameters: | 278 | * Parameters: |
279 | * match A character string representing an integer-valued env variable | 279 | * match A character string representing an integer-valued env variable |
280 | * Outputs: | 280 | * Outputs: |
281 | * *value the integer representation of the environment variable 'match' | 281 | * *value the integer representation of the environment variable 'match' |
282 | * Returns: | 282 | * Returns: |
283 | * Zero on success, a kdb diagnostic on failure. | 283 | * Zero on success, a kdb diagnostic on failure. |
284 | */ | 284 | */ |
285 | int kdbgetintenv(const char *match, int *value) | 285 | int kdbgetintenv(const char *match, int *value) |
286 | { | 286 | { |
287 | unsigned long val; | 287 | unsigned long val; |
288 | int diag; | 288 | int diag; |
289 | 289 | ||
290 | diag = kdbgetulenv(match, &val); | 290 | diag = kdbgetulenv(match, &val); |
291 | if (!diag) | 291 | if (!diag) |
292 | *value = (int) val; | 292 | *value = (int) val; |
293 | return diag; | 293 | return diag; |
294 | } | 294 | } |
295 | 295 | ||
296 | /* | 296 | /* |
297 | * kdbgetularg - This function will convert a numeric string into an | 297 | * kdbgetularg - This function will convert a numeric string into an |
298 | * unsigned long value. | 298 | * unsigned long value. |
299 | * Parameters: | 299 | * Parameters: |
300 | * arg A character string representing a numeric value | 300 | * arg A character string representing a numeric value |
301 | * Outputs: | 301 | * Outputs: |
302 | * *value the unsigned long represntation of arg. | 302 | * *value the unsigned long represntation of arg. |
303 | * Returns: | 303 | * Returns: |
304 | * Zero on success, a kdb diagnostic on failure. | 304 | * Zero on success, a kdb diagnostic on failure. |
305 | */ | 305 | */ |
306 | int kdbgetularg(const char *arg, unsigned long *value) | 306 | int kdbgetularg(const char *arg, unsigned long *value) |
307 | { | 307 | { |
308 | char *endp; | 308 | char *endp; |
309 | unsigned long val; | 309 | unsigned long val; |
310 | 310 | ||
311 | val = simple_strtoul(arg, &endp, 0); | 311 | val = simple_strtoul(arg, &endp, 0); |
312 | 312 | ||
313 | if (endp == arg) { | 313 | if (endp == arg) { |
314 | /* | 314 | /* |
315 | * Also try base 16, for us folks too lazy to type the | 315 | * Also try base 16, for us folks too lazy to type the |
316 | * leading 0x... | 316 | * leading 0x... |
317 | */ | 317 | */ |
318 | val = simple_strtoul(arg, &endp, 16); | 318 | val = simple_strtoul(arg, &endp, 16); |
319 | if (endp == arg) | 319 | if (endp == arg) |
320 | return KDB_BADINT; | 320 | return KDB_BADINT; |
321 | } | 321 | } |
322 | 322 | ||
323 | *value = val; | 323 | *value = val; |
324 | 324 | ||
325 | return 0; | 325 | return 0; |
326 | } | 326 | } |
327 | 327 | ||
328 | int kdbgetu64arg(const char *arg, u64 *value) | 328 | int kdbgetu64arg(const char *arg, u64 *value) |
329 | { | 329 | { |
330 | char *endp; | 330 | char *endp; |
331 | u64 val; | 331 | u64 val; |
332 | 332 | ||
333 | val = simple_strtoull(arg, &endp, 0); | 333 | val = simple_strtoull(arg, &endp, 0); |
334 | 334 | ||
335 | if (endp == arg) { | 335 | if (endp == arg) { |
336 | 336 | ||
337 | val = simple_strtoull(arg, &endp, 16); | 337 | val = simple_strtoull(arg, &endp, 16); |
338 | if (endp == arg) | 338 | if (endp == arg) |
339 | return KDB_BADINT; | 339 | return KDB_BADINT; |
340 | } | 340 | } |
341 | 341 | ||
342 | *value = val; | 342 | *value = val; |
343 | 343 | ||
344 | return 0; | 344 | return 0; |
345 | } | 345 | } |
346 | 346 | ||
347 | /* | 347 | /* |
348 | * kdb_set - This function implements the 'set' command. Alter an | 348 | * kdb_set - This function implements the 'set' command. Alter an |
349 | * existing environment variable or create a new one. | 349 | * existing environment variable or create a new one. |
350 | */ | 350 | */ |
351 | int kdb_set(int argc, const char **argv) | 351 | int kdb_set(int argc, const char **argv) |
352 | { | 352 | { |
353 | int i; | 353 | int i; |
354 | char *ep; | 354 | char *ep; |
355 | size_t varlen, vallen; | 355 | size_t varlen, vallen; |
356 | 356 | ||
357 | /* | 357 | /* |
358 | * we can be invoked two ways: | 358 | * we can be invoked two ways: |
359 | * set var=value argv[1]="var", argv[2]="value" | 359 | * set var=value argv[1]="var", argv[2]="value" |
360 | * set var = value argv[1]="var", argv[2]="=", argv[3]="value" | 360 | * set var = value argv[1]="var", argv[2]="=", argv[3]="value" |
361 | * - if the latter, shift 'em down. | 361 | * - if the latter, shift 'em down. |
362 | */ | 362 | */ |
363 | if (argc == 3) { | 363 | if (argc == 3) { |
364 | argv[2] = argv[3]; | 364 | argv[2] = argv[3]; |
365 | argc--; | 365 | argc--; |
366 | } | 366 | } |
367 | 367 | ||
368 | if (argc != 2) | 368 | if (argc != 2) |
369 | return KDB_ARGCOUNT; | 369 | return KDB_ARGCOUNT; |
370 | 370 | ||
371 | /* | 371 | /* |
372 | * Check for internal variables | 372 | * Check for internal variables |
373 | */ | 373 | */ |
374 | if (strcmp(argv[1], "KDBDEBUG") == 0) { | 374 | if (strcmp(argv[1], "KDBDEBUG") == 0) { |
375 | unsigned int debugflags; | 375 | unsigned int debugflags; |
376 | char *cp; | 376 | char *cp; |
377 | 377 | ||
378 | debugflags = simple_strtoul(argv[2], &cp, 0); | 378 | debugflags = simple_strtoul(argv[2], &cp, 0); |
379 | if (cp == argv[2] || debugflags & ~KDB_DEBUG_FLAG_MASK) { | 379 | if (cp == argv[2] || debugflags & ~KDB_DEBUG_FLAG_MASK) { |
380 | kdb_printf("kdb: illegal debug flags '%s'\n", | 380 | kdb_printf("kdb: illegal debug flags '%s'\n", |
381 | argv[2]); | 381 | argv[2]); |
382 | return 0; | 382 | return 0; |
383 | } | 383 | } |
384 | kdb_flags = (kdb_flags & | 384 | kdb_flags = (kdb_flags & |
385 | ~(KDB_DEBUG_FLAG_MASK << KDB_DEBUG_FLAG_SHIFT)) | 385 | ~(KDB_DEBUG_FLAG_MASK << KDB_DEBUG_FLAG_SHIFT)) |
386 | | (debugflags << KDB_DEBUG_FLAG_SHIFT); | 386 | | (debugflags << KDB_DEBUG_FLAG_SHIFT); |
387 | 387 | ||
388 | return 0; | 388 | return 0; |
389 | } | 389 | } |
390 | 390 | ||
391 | /* | 391 | /* |
392 | * Tokenizer squashed the '=' sign. argv[1] is variable | 392 | * Tokenizer squashed the '=' sign. argv[1] is variable |
393 | * name, argv[2] = value. | 393 | * name, argv[2] = value. |
394 | */ | 394 | */ |
395 | varlen = strlen(argv[1]); | 395 | varlen = strlen(argv[1]); |
396 | vallen = strlen(argv[2]); | 396 | vallen = strlen(argv[2]); |
397 | ep = kdballocenv(varlen + vallen + 2); | 397 | ep = kdballocenv(varlen + vallen + 2); |
398 | if (ep == (char *)0) | 398 | if (ep == (char *)0) |
399 | return KDB_ENVBUFFULL; | 399 | return KDB_ENVBUFFULL; |
400 | 400 | ||
401 | sprintf(ep, "%s=%s", argv[1], argv[2]); | 401 | sprintf(ep, "%s=%s", argv[1], argv[2]); |
402 | 402 | ||
403 | ep[varlen+vallen+1] = '\0'; | 403 | ep[varlen+vallen+1] = '\0'; |
404 | 404 | ||
405 | for (i = 0; i < __nenv; i++) { | 405 | for (i = 0; i < __nenv; i++) { |
406 | if (__env[i] | 406 | if (__env[i] |
407 | && ((strncmp(__env[i], argv[1], varlen) == 0) | 407 | && ((strncmp(__env[i], argv[1], varlen) == 0) |
408 | && ((__env[i][varlen] == '\0') | 408 | && ((__env[i][varlen] == '\0') |
409 | || (__env[i][varlen] == '=')))) { | 409 | || (__env[i][varlen] == '=')))) { |
410 | __env[i] = ep; | 410 | __env[i] = ep; |
411 | return 0; | 411 | return 0; |
412 | } | 412 | } |
413 | } | 413 | } |
414 | 414 | ||
415 | /* | 415 | /* |
416 | * Wasn't existing variable. Fit into slot. | 416 | * Wasn't existing variable. Fit into slot. |
417 | */ | 417 | */ |
418 | for (i = 0; i < __nenv-1; i++) { | 418 | for (i = 0; i < __nenv-1; i++) { |
419 | if (__env[i] == (char *)0) { | 419 | if (__env[i] == (char *)0) { |
420 | __env[i] = ep; | 420 | __env[i] = ep; |
421 | return 0; | 421 | return 0; |
422 | } | 422 | } |
423 | } | 423 | } |
424 | 424 | ||
425 | return KDB_ENVFULL; | 425 | return KDB_ENVFULL; |
426 | } | 426 | } |
427 | 427 | ||
428 | static int kdb_check_regs(void) | 428 | static int kdb_check_regs(void) |
429 | { | 429 | { |
430 | if (!kdb_current_regs) { | 430 | if (!kdb_current_regs) { |
431 | kdb_printf("No current kdb registers." | 431 | kdb_printf("No current kdb registers." |
432 | " You may need to select another task\n"); | 432 | " You may need to select another task\n"); |
433 | return KDB_BADREG; | 433 | return KDB_BADREG; |
434 | } | 434 | } |
435 | return 0; | 435 | return 0; |
436 | } | 436 | } |
437 | 437 | ||
438 | /* | 438 | /* |
439 | * kdbgetaddrarg - This function is responsible for parsing an | 439 | * kdbgetaddrarg - This function is responsible for parsing an |
440 | * address-expression and returning the value of the expression, | 440 | * address-expression and returning the value of the expression, |
441 | * symbol name, and offset to the caller. | 441 | * symbol name, and offset to the caller. |
442 | * | 442 | * |
443 | * The argument may consist of a numeric value (decimal or | 443 | * The argument may consist of a numeric value (decimal or |
444 | * hexidecimal), a symbol name, a register name (preceeded by the | 444 | * hexidecimal), a symbol name, a register name (preceeded by the |
445 | * percent sign), an environment variable with a numeric value | 445 | * percent sign), an environment variable with a numeric value |
446 | * (preceeded by a dollar sign) or a simple arithmetic expression | 446 | * (preceeded by a dollar sign) or a simple arithmetic expression |
447 | * consisting of a symbol name, +/-, and a numeric constant value | 447 | * consisting of a symbol name, +/-, and a numeric constant value |
448 | * (offset). | 448 | * (offset). |
449 | * Parameters: | 449 | * Parameters: |
450 | * argc - count of arguments in argv | 450 | * argc - count of arguments in argv |
451 | * argv - argument vector | 451 | * argv - argument vector |
452 | * *nextarg - index to next unparsed argument in argv[] | 452 | * *nextarg - index to next unparsed argument in argv[] |
453 | * regs - Register state at time of KDB entry | 453 | * regs - Register state at time of KDB entry |
454 | * Outputs: | 454 | * Outputs: |
455 | * *value - receives the value of the address-expression | 455 | * *value - receives the value of the address-expression |
456 | * *offset - receives the offset specified, if any | 456 | * *offset - receives the offset specified, if any |
457 | * *name - receives the symbol name, if any | 457 | * *name - receives the symbol name, if any |
458 | * *nextarg - index to next unparsed argument in argv[] | 458 | * *nextarg - index to next unparsed argument in argv[] |
459 | * Returns: | 459 | * Returns: |
460 | * zero is returned on success, a kdb diagnostic code is | 460 | * zero is returned on success, a kdb diagnostic code is |
461 | * returned on error. | 461 | * returned on error. |
462 | */ | 462 | */ |
463 | int kdbgetaddrarg(int argc, const char **argv, int *nextarg, | 463 | int kdbgetaddrarg(int argc, const char **argv, int *nextarg, |
464 | unsigned long *value, long *offset, | 464 | unsigned long *value, long *offset, |
465 | char **name) | 465 | char **name) |
466 | { | 466 | { |
467 | unsigned long addr; | 467 | unsigned long addr; |
468 | unsigned long off = 0; | 468 | unsigned long off = 0; |
469 | int positive; | 469 | int positive; |
470 | int diag; | 470 | int diag; |
471 | int found = 0; | 471 | int found = 0; |
472 | char *symname; | 472 | char *symname; |
473 | char symbol = '\0'; | 473 | char symbol = '\0'; |
474 | char *cp; | 474 | char *cp; |
475 | kdb_symtab_t symtab; | 475 | kdb_symtab_t symtab; |
476 | 476 | ||
477 | /* | 477 | /* |
478 | * Process arguments which follow the following syntax: | 478 | * Process arguments which follow the following syntax: |
479 | * | 479 | * |
480 | * symbol | numeric-address [+/- numeric-offset] | 480 | * symbol | numeric-address [+/- numeric-offset] |
481 | * %register | 481 | * %register |
482 | * $environment-variable | 482 | * $environment-variable |
483 | */ | 483 | */ |
484 | 484 | ||
485 | if (*nextarg > argc) | 485 | if (*nextarg > argc) |
486 | return KDB_ARGCOUNT; | 486 | return KDB_ARGCOUNT; |
487 | 487 | ||
488 | symname = (char *)argv[*nextarg]; | 488 | symname = (char *)argv[*nextarg]; |
489 | 489 | ||
490 | /* | 490 | /* |
491 | * If there is no whitespace between the symbol | 491 | * If there is no whitespace between the symbol |
492 | * or address and the '+' or '-' symbols, we | 492 | * or address and the '+' or '-' symbols, we |
493 | * remember the character and replace it with a | 493 | * remember the character and replace it with a |
494 | * null so the symbol/value can be properly parsed | 494 | * null so the symbol/value can be properly parsed |
495 | */ | 495 | */ |
496 | cp = strpbrk(symname, "+-"); | 496 | cp = strpbrk(symname, "+-"); |
497 | if (cp != NULL) { | 497 | if (cp != NULL) { |
498 | symbol = *cp; | 498 | symbol = *cp; |
499 | *cp++ = '\0'; | 499 | *cp++ = '\0'; |
500 | } | 500 | } |
501 | 501 | ||
502 | if (symname[0] == '$') { | 502 | if (symname[0] == '$') { |
503 | diag = kdbgetulenv(&symname[1], &addr); | 503 | diag = kdbgetulenv(&symname[1], &addr); |
504 | if (diag) | 504 | if (diag) |
505 | return diag; | 505 | return diag; |
506 | } else if (symname[0] == '%') { | 506 | } else if (symname[0] == '%') { |
507 | diag = kdb_check_regs(); | 507 | diag = kdb_check_regs(); |
508 | if (diag) | 508 | if (diag) |
509 | return diag; | 509 | return diag; |
510 | /* Implement register values with % at a later time as it is | 510 | /* Implement register values with % at a later time as it is |
511 | * arch optional. | 511 | * arch optional. |
512 | */ | 512 | */ |
513 | return KDB_NOTIMP; | 513 | return KDB_NOTIMP; |
514 | } else { | 514 | } else { |
515 | found = kdbgetsymval(symname, &symtab); | 515 | found = kdbgetsymval(symname, &symtab); |
516 | if (found) { | 516 | if (found) { |
517 | addr = symtab.sym_start; | 517 | addr = symtab.sym_start; |
518 | } else { | 518 | } else { |
519 | diag = kdbgetularg(argv[*nextarg], &addr); | 519 | diag = kdbgetularg(argv[*nextarg], &addr); |
520 | if (diag) | 520 | if (diag) |
521 | return diag; | 521 | return diag; |
522 | } | 522 | } |
523 | } | 523 | } |
524 | 524 | ||
525 | if (!found) | 525 | if (!found) |
526 | found = kdbnearsym(addr, &symtab); | 526 | found = kdbnearsym(addr, &symtab); |
527 | 527 | ||
528 | (*nextarg)++; | 528 | (*nextarg)++; |
529 | 529 | ||
530 | if (name) | 530 | if (name) |
531 | *name = symname; | 531 | *name = symname; |
532 | if (value) | 532 | if (value) |
533 | *value = addr; | 533 | *value = addr; |
534 | if (offset && name && *name) | 534 | if (offset && name && *name) |
535 | *offset = addr - symtab.sym_start; | 535 | *offset = addr - symtab.sym_start; |
536 | 536 | ||
537 | if ((*nextarg > argc) | 537 | if ((*nextarg > argc) |
538 | && (symbol == '\0')) | 538 | && (symbol == '\0')) |
539 | return 0; | 539 | return 0; |
540 | 540 | ||
541 | /* | 541 | /* |
542 | * check for +/- and offset | 542 | * check for +/- and offset |
543 | */ | 543 | */ |
544 | 544 | ||
545 | if (symbol == '\0') { | 545 | if (symbol == '\0') { |
546 | if ((argv[*nextarg][0] != '+') | 546 | if ((argv[*nextarg][0] != '+') |
547 | && (argv[*nextarg][0] != '-')) { | 547 | && (argv[*nextarg][0] != '-')) { |
548 | /* | 548 | /* |
549 | * Not our argument. Return. | 549 | * Not our argument. Return. |
550 | */ | 550 | */ |
551 | return 0; | 551 | return 0; |
552 | } else { | 552 | } else { |
553 | positive = (argv[*nextarg][0] == '+'); | 553 | positive = (argv[*nextarg][0] == '+'); |
554 | (*nextarg)++; | 554 | (*nextarg)++; |
555 | } | 555 | } |
556 | } else | 556 | } else |
557 | positive = (symbol == '+'); | 557 | positive = (symbol == '+'); |
558 | 558 | ||
559 | /* | 559 | /* |
560 | * Now there must be an offset! | 560 | * Now there must be an offset! |
561 | */ | 561 | */ |
562 | if ((*nextarg > argc) | 562 | if ((*nextarg > argc) |
563 | && (symbol == '\0')) { | 563 | && (symbol == '\0')) { |
564 | return KDB_INVADDRFMT; | 564 | return KDB_INVADDRFMT; |
565 | } | 565 | } |
566 | 566 | ||
567 | if (!symbol) { | 567 | if (!symbol) { |
568 | cp = (char *)argv[*nextarg]; | 568 | cp = (char *)argv[*nextarg]; |
569 | (*nextarg)++; | 569 | (*nextarg)++; |
570 | } | 570 | } |
571 | 571 | ||
572 | diag = kdbgetularg(cp, &off); | 572 | diag = kdbgetularg(cp, &off); |
573 | if (diag) | 573 | if (diag) |
574 | return diag; | 574 | return diag; |
575 | 575 | ||
576 | if (!positive) | 576 | if (!positive) |
577 | off = -off; | 577 | off = -off; |
578 | 578 | ||
579 | if (offset) | 579 | if (offset) |
580 | *offset += off; | 580 | *offset += off; |
581 | 581 | ||
582 | if (value) | 582 | if (value) |
583 | *value += off; | 583 | *value += off; |
584 | 584 | ||
585 | return 0; | 585 | return 0; |
586 | } | 586 | } |
587 | 587 | ||
588 | static void kdb_cmderror(int diag) | 588 | static void kdb_cmderror(int diag) |
589 | { | 589 | { |
590 | int i; | 590 | int i; |
591 | 591 | ||
592 | if (diag >= 0) { | 592 | if (diag >= 0) { |
593 | kdb_printf("no error detected (diagnostic is %d)\n", diag); | 593 | kdb_printf("no error detected (diagnostic is %d)\n", diag); |
594 | return; | 594 | return; |
595 | } | 595 | } |
596 | 596 | ||
597 | for (i = 0; i < __nkdb_err; i++) { | 597 | for (i = 0; i < __nkdb_err; i++) { |
598 | if (kdbmsgs[i].km_diag == diag) { | 598 | if (kdbmsgs[i].km_diag == diag) { |
599 | kdb_printf("diag: %d: %s\n", diag, kdbmsgs[i].km_msg); | 599 | kdb_printf("diag: %d: %s\n", diag, kdbmsgs[i].km_msg); |
600 | return; | 600 | return; |
601 | } | 601 | } |
602 | } | 602 | } |
603 | 603 | ||
604 | kdb_printf("Unknown diag %d\n", -diag); | 604 | kdb_printf("Unknown diag %d\n", -diag); |
605 | } | 605 | } |
606 | 606 | ||
607 | /* | 607 | /* |
608 | * kdb_defcmd, kdb_defcmd2 - This function implements the 'defcmd' | 608 | * kdb_defcmd, kdb_defcmd2 - This function implements the 'defcmd' |
609 | * command which defines one command as a set of other commands, | 609 | * command which defines one command as a set of other commands, |
610 | * terminated by endefcmd. kdb_defcmd processes the initial | 610 | * terminated by endefcmd. kdb_defcmd processes the initial |
611 | * 'defcmd' command, kdb_defcmd2 is invoked from kdb_parse for | 611 | * 'defcmd' command, kdb_defcmd2 is invoked from kdb_parse for |
612 | * the following commands until 'endefcmd'. | 612 | * the following commands until 'endefcmd'. |
613 | * Inputs: | 613 | * Inputs: |
614 | * argc argument count | 614 | * argc argument count |
615 | * argv argument vector | 615 | * argv argument vector |
616 | * Returns: | 616 | * Returns: |
617 | * zero for success, a kdb diagnostic if error | 617 | * zero for success, a kdb diagnostic if error |
618 | */ | 618 | */ |
619 | struct defcmd_set { | 619 | struct defcmd_set { |
620 | int count; | 620 | int count; |
621 | int usable; | 621 | int usable; |
622 | char *name; | 622 | char *name; |
623 | char *usage; | 623 | char *usage; |
624 | char *help; | 624 | char *help; |
625 | char **command; | 625 | char **command; |
626 | }; | 626 | }; |
627 | static struct defcmd_set *defcmd_set; | 627 | static struct defcmd_set *defcmd_set; |
628 | static int defcmd_set_count; | 628 | static int defcmd_set_count; |
629 | static int defcmd_in_progress; | 629 | static int defcmd_in_progress; |
630 | 630 | ||
631 | /* Forward references */ | 631 | /* Forward references */ |
632 | static int kdb_exec_defcmd(int argc, const char **argv); | 632 | static int kdb_exec_defcmd(int argc, const char **argv); |
633 | 633 | ||
634 | static int kdb_defcmd2(const char *cmdstr, const char *argv0) | 634 | static int kdb_defcmd2(const char *cmdstr, const char *argv0) |
635 | { | 635 | { |
636 | struct defcmd_set *s = defcmd_set + defcmd_set_count - 1; | 636 | struct defcmd_set *s = defcmd_set + defcmd_set_count - 1; |
637 | char **save_command = s->command; | 637 | char **save_command = s->command; |
638 | if (strcmp(argv0, "endefcmd") == 0) { | 638 | if (strcmp(argv0, "endefcmd") == 0) { |
639 | defcmd_in_progress = 0; | 639 | defcmd_in_progress = 0; |
640 | if (!s->count) | 640 | if (!s->count) |
641 | s->usable = 0; | 641 | s->usable = 0; |
642 | if (s->usable) | 642 | if (s->usable) |
643 | kdb_register(s->name, kdb_exec_defcmd, | 643 | kdb_register(s->name, kdb_exec_defcmd, |
644 | s->usage, s->help, 0); | 644 | s->usage, s->help, 0); |
645 | return 0; | 645 | return 0; |
646 | } | 646 | } |
647 | if (!s->usable) | 647 | if (!s->usable) |
648 | return KDB_NOTIMP; | 648 | return KDB_NOTIMP; |
649 | s->command = kzalloc((s->count + 1) * sizeof(*(s->command)), GFP_KDB); | 649 | s->command = kzalloc((s->count + 1) * sizeof(*(s->command)), GFP_KDB); |
650 | if (!s->command) { | 650 | if (!s->command) { |
651 | kdb_printf("Could not allocate new kdb_defcmd table for %s\n", | 651 | kdb_printf("Could not allocate new kdb_defcmd table for %s\n", |
652 | cmdstr); | 652 | cmdstr); |
653 | s->usable = 0; | 653 | s->usable = 0; |
654 | return KDB_NOTIMP; | 654 | return KDB_NOTIMP; |
655 | } | 655 | } |
656 | memcpy(s->command, save_command, s->count * sizeof(*(s->command))); | 656 | memcpy(s->command, save_command, s->count * sizeof(*(s->command))); |
657 | s->command[s->count++] = kdb_strdup(cmdstr, GFP_KDB); | 657 | s->command[s->count++] = kdb_strdup(cmdstr, GFP_KDB); |
658 | kfree(save_command); | 658 | kfree(save_command); |
659 | return 0; | 659 | return 0; |
660 | } | 660 | } |
661 | 661 | ||
662 | static int kdb_defcmd(int argc, const char **argv) | 662 | static int kdb_defcmd(int argc, const char **argv) |
663 | { | 663 | { |
664 | struct defcmd_set *save_defcmd_set = defcmd_set, *s; | 664 | struct defcmd_set *save_defcmd_set = defcmd_set, *s; |
665 | if (defcmd_in_progress) { | 665 | if (defcmd_in_progress) { |
666 | kdb_printf("kdb: nested defcmd detected, assuming missing " | 666 | kdb_printf("kdb: nested defcmd detected, assuming missing " |
667 | "endefcmd\n"); | 667 | "endefcmd\n"); |
668 | kdb_defcmd2("endefcmd", "endefcmd"); | 668 | kdb_defcmd2("endefcmd", "endefcmd"); |
669 | } | 669 | } |
670 | if (argc == 0) { | 670 | if (argc == 0) { |
671 | int i; | 671 | int i; |
672 | for (s = defcmd_set; s < defcmd_set + defcmd_set_count; ++s) { | 672 | for (s = defcmd_set; s < defcmd_set + defcmd_set_count; ++s) { |
673 | kdb_printf("defcmd %s \"%s\" \"%s\"\n", s->name, | 673 | kdb_printf("defcmd %s \"%s\" \"%s\"\n", s->name, |
674 | s->usage, s->help); | 674 | s->usage, s->help); |
675 | for (i = 0; i < s->count; ++i) | 675 | for (i = 0; i < s->count; ++i) |
676 | kdb_printf("%s", s->command[i]); | 676 | kdb_printf("%s", s->command[i]); |
677 | kdb_printf("endefcmd\n"); | 677 | kdb_printf("endefcmd\n"); |
678 | } | 678 | } |
679 | return 0; | 679 | return 0; |
680 | } | 680 | } |
681 | if (argc != 3) | 681 | if (argc != 3) |
682 | return KDB_ARGCOUNT; | 682 | return KDB_ARGCOUNT; |
683 | defcmd_set = kmalloc((defcmd_set_count + 1) * sizeof(*defcmd_set), | 683 | defcmd_set = kmalloc((defcmd_set_count + 1) * sizeof(*defcmd_set), |
684 | GFP_KDB); | 684 | GFP_KDB); |
685 | if (!defcmd_set) { | 685 | if (!defcmd_set) { |
686 | kdb_printf("Could not allocate new defcmd_set entry for %s\n", | 686 | kdb_printf("Could not allocate new defcmd_set entry for %s\n", |
687 | argv[1]); | 687 | argv[1]); |
688 | defcmd_set = save_defcmd_set; | 688 | defcmd_set = save_defcmd_set; |
689 | return KDB_NOTIMP; | 689 | return KDB_NOTIMP; |
690 | } | 690 | } |
691 | memcpy(defcmd_set, save_defcmd_set, | 691 | memcpy(defcmd_set, save_defcmd_set, |
692 | defcmd_set_count * sizeof(*defcmd_set)); | 692 | defcmd_set_count * sizeof(*defcmd_set)); |
693 | kfree(save_defcmd_set); | 693 | kfree(save_defcmd_set); |
694 | s = defcmd_set + defcmd_set_count; | 694 | s = defcmd_set + defcmd_set_count; |
695 | memset(s, 0, sizeof(*s)); | 695 | memset(s, 0, sizeof(*s)); |
696 | s->usable = 1; | 696 | s->usable = 1; |
697 | s->name = kdb_strdup(argv[1], GFP_KDB); | 697 | s->name = kdb_strdup(argv[1], GFP_KDB); |
698 | s->usage = kdb_strdup(argv[2], GFP_KDB); | 698 | s->usage = kdb_strdup(argv[2], GFP_KDB); |
699 | s->help = kdb_strdup(argv[3], GFP_KDB); | 699 | s->help = kdb_strdup(argv[3], GFP_KDB); |
700 | if (s->usage[0] == '"') { | 700 | if (s->usage[0] == '"') { |
701 | strcpy(s->usage, s->usage+1); | 701 | strcpy(s->usage, s->usage+1); |
702 | s->usage[strlen(s->usage)-1] = '\0'; | 702 | s->usage[strlen(s->usage)-1] = '\0'; |
703 | } | 703 | } |
704 | if (s->help[0] == '"') { | 704 | if (s->help[0] == '"') { |
705 | strcpy(s->help, s->help+1); | 705 | strcpy(s->help, s->help+1); |
706 | s->help[strlen(s->help)-1] = '\0'; | 706 | s->help[strlen(s->help)-1] = '\0'; |
707 | } | 707 | } |
708 | ++defcmd_set_count; | 708 | ++defcmd_set_count; |
709 | defcmd_in_progress = 1; | 709 | defcmd_in_progress = 1; |
710 | return 0; | 710 | return 0; |
711 | } | 711 | } |
712 | 712 | ||
713 | /* | 713 | /* |
714 | * kdb_exec_defcmd - Execute the set of commands associated with this | 714 | * kdb_exec_defcmd - Execute the set of commands associated with this |
715 | * defcmd name. | 715 | * defcmd name. |
716 | * Inputs: | 716 | * Inputs: |
717 | * argc argument count | 717 | * argc argument count |
718 | * argv argument vector | 718 | * argv argument vector |
719 | * Returns: | 719 | * Returns: |
720 | * zero for success, a kdb diagnostic if error | 720 | * zero for success, a kdb diagnostic if error |
721 | */ | 721 | */ |
722 | static int kdb_exec_defcmd(int argc, const char **argv) | 722 | static int kdb_exec_defcmd(int argc, const char **argv) |
723 | { | 723 | { |
724 | int i, ret; | 724 | int i, ret; |
725 | struct defcmd_set *s; | 725 | struct defcmd_set *s; |
726 | if (argc != 0) | 726 | if (argc != 0) |
727 | return KDB_ARGCOUNT; | 727 | return KDB_ARGCOUNT; |
728 | for (s = defcmd_set, i = 0; i < defcmd_set_count; ++i, ++s) { | 728 | for (s = defcmd_set, i = 0; i < defcmd_set_count; ++i, ++s) { |
729 | if (strcmp(s->name, argv[0]) == 0) | 729 | if (strcmp(s->name, argv[0]) == 0) |
730 | break; | 730 | break; |
731 | } | 731 | } |
732 | if (i == defcmd_set_count) { | 732 | if (i == defcmd_set_count) { |
733 | kdb_printf("kdb_exec_defcmd: could not find commands for %s\n", | 733 | kdb_printf("kdb_exec_defcmd: could not find commands for %s\n", |
734 | argv[0]); | 734 | argv[0]); |
735 | return KDB_NOTIMP; | 735 | return KDB_NOTIMP; |
736 | } | 736 | } |
737 | for (i = 0; i < s->count; ++i) { | 737 | for (i = 0; i < s->count; ++i) { |
738 | /* Recursive use of kdb_parse, do not use argv after | 738 | /* Recursive use of kdb_parse, do not use argv after |
739 | * this point */ | 739 | * this point */ |
740 | argv = NULL; | 740 | argv = NULL; |
741 | kdb_printf("[%s]kdb> %s\n", s->name, s->command[i]); | 741 | kdb_printf("[%s]kdb> %s\n", s->name, s->command[i]); |
742 | ret = kdb_parse(s->command[i]); | 742 | ret = kdb_parse(s->command[i]); |
743 | if (ret) | 743 | if (ret) |
744 | return ret; | 744 | return ret; |
745 | } | 745 | } |
746 | return 0; | 746 | return 0; |
747 | } | 747 | } |
748 | 748 | ||
749 | /* Command history */ | 749 | /* Command history */ |
750 | #define KDB_CMD_HISTORY_COUNT 32 | 750 | #define KDB_CMD_HISTORY_COUNT 32 |
751 | #define CMD_BUFLEN 200 /* kdb_printf: max printline | 751 | #define CMD_BUFLEN 200 /* kdb_printf: max printline |
752 | * size == 256 */ | 752 | * size == 256 */ |
753 | static unsigned int cmd_head, cmd_tail; | 753 | static unsigned int cmd_head, cmd_tail; |
754 | static unsigned int cmdptr; | 754 | static unsigned int cmdptr; |
755 | static char cmd_hist[KDB_CMD_HISTORY_COUNT][CMD_BUFLEN]; | 755 | static char cmd_hist[KDB_CMD_HISTORY_COUNT][CMD_BUFLEN]; |
756 | static char cmd_cur[CMD_BUFLEN]; | 756 | static char cmd_cur[CMD_BUFLEN]; |
757 | 757 | ||
758 | /* | 758 | /* |
759 | * The "str" argument may point to something like | grep xyz | 759 | * The "str" argument may point to something like | grep xyz |
760 | */ | 760 | */ |
761 | static void parse_grep(const char *str) | 761 | static void parse_grep(const char *str) |
762 | { | 762 | { |
763 | int len; | 763 | int len; |
764 | char *cp = (char *)str, *cp2; | 764 | char *cp = (char *)str, *cp2; |
765 | 765 | ||
766 | /* sanity check: we should have been called with the \ first */ | 766 | /* sanity check: we should have been called with the \ first */ |
767 | if (*cp != '|') | 767 | if (*cp != '|') |
768 | return; | 768 | return; |
769 | cp++; | 769 | cp++; |
770 | while (isspace(*cp)) | 770 | while (isspace(*cp)) |
771 | cp++; | 771 | cp++; |
772 | if (strncmp(cp, "grep ", 5)) { | 772 | if (strncmp(cp, "grep ", 5)) { |
773 | kdb_printf("invalid 'pipe', see grephelp\n"); | 773 | kdb_printf("invalid 'pipe', see grephelp\n"); |
774 | return; | 774 | return; |
775 | } | 775 | } |
776 | cp += 5; | 776 | cp += 5; |
777 | while (isspace(*cp)) | 777 | while (isspace(*cp)) |
778 | cp++; | 778 | cp++; |
779 | cp2 = strchr(cp, '\n'); | 779 | cp2 = strchr(cp, '\n'); |
780 | if (cp2) | 780 | if (cp2) |
781 | *cp2 = '\0'; /* remove the trailing newline */ | 781 | *cp2 = '\0'; /* remove the trailing newline */ |
782 | len = strlen(cp); | 782 | len = strlen(cp); |
783 | if (len == 0) { | 783 | if (len == 0) { |
784 | kdb_printf("invalid 'pipe', see grephelp\n"); | 784 | kdb_printf("invalid 'pipe', see grephelp\n"); |
785 | return; | 785 | return; |
786 | } | 786 | } |
787 | /* now cp points to a nonzero length search string */ | 787 | /* now cp points to a nonzero length search string */ |
788 | if (*cp == '"') { | 788 | if (*cp == '"') { |
789 | /* allow it be "x y z" by removing the "'s - there must | 789 | /* allow it be "x y z" by removing the "'s - there must |
790 | be two of them */ | 790 | be two of them */ |
791 | cp++; | 791 | cp++; |
792 | cp2 = strchr(cp, '"'); | 792 | cp2 = strchr(cp, '"'); |
793 | if (!cp2) { | 793 | if (!cp2) { |
794 | kdb_printf("invalid quoted string, see grephelp\n"); | 794 | kdb_printf("invalid quoted string, see grephelp\n"); |
795 | return; | 795 | return; |
796 | } | 796 | } |
797 | *cp2 = '\0'; /* end the string where the 2nd " was */ | 797 | *cp2 = '\0'; /* end the string where the 2nd " was */ |
798 | } | 798 | } |
799 | kdb_grep_leading = 0; | 799 | kdb_grep_leading = 0; |
800 | if (*cp == '^') { | 800 | if (*cp == '^') { |
801 | kdb_grep_leading = 1; | 801 | kdb_grep_leading = 1; |
802 | cp++; | 802 | cp++; |
803 | } | 803 | } |
804 | len = strlen(cp); | 804 | len = strlen(cp); |
805 | kdb_grep_trailing = 0; | 805 | kdb_grep_trailing = 0; |
806 | if (*(cp+len-1) == '$') { | 806 | if (*(cp+len-1) == '$') { |
807 | kdb_grep_trailing = 1; | 807 | kdb_grep_trailing = 1; |
808 | *(cp+len-1) = '\0'; | 808 | *(cp+len-1) = '\0'; |
809 | } | 809 | } |
810 | len = strlen(cp); | 810 | len = strlen(cp); |
811 | if (!len) | 811 | if (!len) |
812 | return; | 812 | return; |
813 | if (len >= GREP_LEN) { | 813 | if (len >= GREP_LEN) { |
814 | kdb_printf("search string too long\n"); | 814 | kdb_printf("search string too long\n"); |
815 | return; | 815 | return; |
816 | } | 816 | } |
817 | strcpy(kdb_grep_string, cp); | 817 | strcpy(kdb_grep_string, cp); |
818 | kdb_grepping_flag++; | 818 | kdb_grepping_flag++; |
819 | return; | 819 | return; |
820 | } | 820 | } |
821 | 821 | ||
822 | /* | 822 | /* |
823 | * kdb_parse - Parse the command line, search the command table for a | 823 | * kdb_parse - Parse the command line, search the command table for a |
824 | * matching command and invoke the command function. This | 824 | * matching command and invoke the command function. This |
825 | * function may be called recursively, if it is, the second call | 825 | * function may be called recursively, if it is, the second call |
826 | * will overwrite argv and cbuf. It is the caller's | 826 | * will overwrite argv and cbuf. It is the caller's |
827 | * responsibility to save their argv if they recursively call | 827 | * responsibility to save their argv if they recursively call |
828 | * kdb_parse(). | 828 | * kdb_parse(). |
829 | * Parameters: | 829 | * Parameters: |
830 | * cmdstr The input command line to be parsed. | 830 | * cmdstr The input command line to be parsed. |
831 | * regs The registers at the time kdb was entered. | 831 | * regs The registers at the time kdb was entered. |
832 | * Returns: | 832 | * Returns: |
833 | * Zero for success, a kdb diagnostic if failure. | 833 | * Zero for success, a kdb diagnostic if failure. |
834 | * Remarks: | 834 | * Remarks: |
835 | * Limited to 20 tokens. | 835 | * Limited to 20 tokens. |
836 | * | 836 | * |
837 | * Real rudimentary tokenization. Basically only whitespace | 837 | * Real rudimentary tokenization. Basically only whitespace |
838 | * is considered a token delimeter (but special consideration | 838 | * is considered a token delimeter (but special consideration |
839 | * is taken of the '=' sign as used by the 'set' command). | 839 | * is taken of the '=' sign as used by the 'set' command). |
840 | * | 840 | * |
841 | * The algorithm used to tokenize the input string relies on | 841 | * The algorithm used to tokenize the input string relies on |
842 | * there being at least one whitespace (or otherwise useless) | 842 | * there being at least one whitespace (or otherwise useless) |
843 | * character between tokens as the character immediately following | 843 | * character between tokens as the character immediately following |
844 | * the token is altered in-place to a null-byte to terminate the | 844 | * the token is altered in-place to a null-byte to terminate the |
845 | * token string. | 845 | * token string. |
846 | */ | 846 | */ |
847 | 847 | ||
848 | #define MAXARGC 20 | 848 | #define MAXARGC 20 |
849 | 849 | ||
850 | int kdb_parse(const char *cmdstr) | 850 | int kdb_parse(const char *cmdstr) |
851 | { | 851 | { |
852 | static char *argv[MAXARGC]; | 852 | static char *argv[MAXARGC]; |
853 | static int argc; | 853 | static int argc; |
854 | static char cbuf[CMD_BUFLEN+2]; | 854 | static char cbuf[CMD_BUFLEN+2]; |
855 | char *cp; | 855 | char *cp; |
856 | char *cpp, quoted; | 856 | char *cpp, quoted; |
857 | kdbtab_t *tp; | 857 | kdbtab_t *tp; |
858 | int i, escaped, ignore_errors = 0, check_grep; | 858 | int i, escaped, ignore_errors = 0, check_grep; |
859 | 859 | ||
860 | /* | 860 | /* |
861 | * First tokenize the command string. | 861 | * First tokenize the command string. |
862 | */ | 862 | */ |
863 | cp = (char *)cmdstr; | 863 | cp = (char *)cmdstr; |
864 | kdb_grepping_flag = check_grep = 0; | 864 | kdb_grepping_flag = check_grep = 0; |
865 | 865 | ||
866 | if (KDB_FLAG(CMD_INTERRUPT)) { | 866 | if (KDB_FLAG(CMD_INTERRUPT)) { |
867 | /* Previous command was interrupted, newline must not | 867 | /* Previous command was interrupted, newline must not |
868 | * repeat the command */ | 868 | * repeat the command */ |
869 | KDB_FLAG_CLEAR(CMD_INTERRUPT); | 869 | KDB_FLAG_CLEAR(CMD_INTERRUPT); |
870 | KDB_STATE_SET(PAGER); | 870 | KDB_STATE_SET(PAGER); |
871 | argc = 0; /* no repeat */ | 871 | argc = 0; /* no repeat */ |
872 | } | 872 | } |
873 | 873 | ||
874 | if (*cp != '\n' && *cp != '\0') { | 874 | if (*cp != '\n' && *cp != '\0') { |
875 | argc = 0; | 875 | argc = 0; |
876 | cpp = cbuf; | 876 | cpp = cbuf; |
877 | while (*cp) { | 877 | while (*cp) { |
878 | /* skip whitespace */ | 878 | /* skip whitespace */ |
879 | while (isspace(*cp)) | 879 | while (isspace(*cp)) |
880 | cp++; | 880 | cp++; |
881 | if ((*cp == '\0') || (*cp == '\n') || | 881 | if ((*cp == '\0') || (*cp == '\n') || |
882 | (*cp == '#' && !defcmd_in_progress)) | 882 | (*cp == '#' && !defcmd_in_progress)) |
883 | break; | 883 | break; |
884 | /* special case: check for | grep pattern */ | 884 | /* special case: check for | grep pattern */ |
885 | if (*cp == '|') { | 885 | if (*cp == '|') { |
886 | check_grep++; | 886 | check_grep++; |
887 | break; | 887 | break; |
888 | } | 888 | } |
889 | if (cpp >= cbuf + CMD_BUFLEN) { | 889 | if (cpp >= cbuf + CMD_BUFLEN) { |
890 | kdb_printf("kdb_parse: command buffer " | 890 | kdb_printf("kdb_parse: command buffer " |
891 | "overflow, command ignored\n%s\n", | 891 | "overflow, command ignored\n%s\n", |
892 | cmdstr); | 892 | cmdstr); |
893 | return KDB_NOTFOUND; | 893 | return KDB_NOTFOUND; |
894 | } | 894 | } |
895 | if (argc >= MAXARGC - 1) { | 895 | if (argc >= MAXARGC - 1) { |
896 | kdb_printf("kdb_parse: too many arguments, " | 896 | kdb_printf("kdb_parse: too many arguments, " |
897 | "command ignored\n%s\n", cmdstr); | 897 | "command ignored\n%s\n", cmdstr); |
898 | return KDB_NOTFOUND; | 898 | return KDB_NOTFOUND; |
899 | } | 899 | } |
900 | argv[argc++] = cpp; | 900 | argv[argc++] = cpp; |
901 | escaped = 0; | 901 | escaped = 0; |
902 | quoted = '\0'; | 902 | quoted = '\0'; |
903 | /* Copy to next unquoted and unescaped | 903 | /* Copy to next unquoted and unescaped |
904 | * whitespace or '=' */ | 904 | * whitespace or '=' */ |
905 | while (*cp && *cp != '\n' && | 905 | while (*cp && *cp != '\n' && |
906 | (escaped || quoted || !isspace(*cp))) { | 906 | (escaped || quoted || !isspace(*cp))) { |
907 | if (cpp >= cbuf + CMD_BUFLEN) | 907 | if (cpp >= cbuf + CMD_BUFLEN) |
908 | break; | 908 | break; |
909 | if (escaped) { | 909 | if (escaped) { |
910 | escaped = 0; | 910 | escaped = 0; |
911 | *cpp++ = *cp++; | 911 | *cpp++ = *cp++; |
912 | continue; | 912 | continue; |
913 | } | 913 | } |
914 | if (*cp == '\\') { | 914 | if (*cp == '\\') { |
915 | escaped = 1; | 915 | escaped = 1; |
916 | ++cp; | 916 | ++cp; |
917 | continue; | 917 | continue; |
918 | } | 918 | } |
919 | if (*cp == quoted) | 919 | if (*cp == quoted) |
920 | quoted = '\0'; | 920 | quoted = '\0'; |
921 | else if (*cp == '\'' || *cp == '"') | 921 | else if (*cp == '\'' || *cp == '"') |
922 | quoted = *cp; | 922 | quoted = *cp; |
923 | *cpp = *cp++; | 923 | *cpp = *cp++; |
924 | if (*cpp == '=' && !quoted) | 924 | if (*cpp == '=' && !quoted) |
925 | break; | 925 | break; |
926 | ++cpp; | 926 | ++cpp; |
927 | } | 927 | } |
928 | *cpp++ = '\0'; /* Squash a ws or '=' character */ | 928 | *cpp++ = '\0'; /* Squash a ws or '=' character */ |
929 | } | 929 | } |
930 | } | 930 | } |
931 | if (!argc) | 931 | if (!argc) |
932 | return 0; | 932 | return 0; |
933 | if (check_grep) | 933 | if (check_grep) |
934 | parse_grep(cp); | 934 | parse_grep(cp); |
935 | if (defcmd_in_progress) { | 935 | if (defcmd_in_progress) { |
936 | int result = kdb_defcmd2(cmdstr, argv[0]); | 936 | int result = kdb_defcmd2(cmdstr, argv[0]); |
937 | if (!defcmd_in_progress) { | 937 | if (!defcmd_in_progress) { |
938 | argc = 0; /* avoid repeat on endefcmd */ | 938 | argc = 0; /* avoid repeat on endefcmd */ |
939 | *(argv[0]) = '\0'; | 939 | *(argv[0]) = '\0'; |
940 | } | 940 | } |
941 | return result; | 941 | return result; |
942 | } | 942 | } |
943 | if (argv[0][0] == '-' && argv[0][1] && | 943 | if (argv[0][0] == '-' && argv[0][1] && |
944 | (argv[0][1] < '0' || argv[0][1] > '9')) { | 944 | (argv[0][1] < '0' || argv[0][1] > '9')) { |
945 | ignore_errors = 1; | 945 | ignore_errors = 1; |
946 | ++argv[0]; | 946 | ++argv[0]; |
947 | } | 947 | } |
948 | 948 | ||
949 | for_each_kdbcmd(tp, i) { | 949 | for_each_kdbcmd(tp, i) { |
950 | if (tp->cmd_name) { | 950 | if (tp->cmd_name) { |
951 | /* | 951 | /* |
952 | * If this command is allowed to be abbreviated, | 952 | * If this command is allowed to be abbreviated, |
953 | * check to see if this is it. | 953 | * check to see if this is it. |
954 | */ | 954 | */ |
955 | 955 | ||
956 | if (tp->cmd_minlen | 956 | if (tp->cmd_minlen |
957 | && (strlen(argv[0]) <= tp->cmd_minlen)) { | 957 | && (strlen(argv[0]) <= tp->cmd_minlen)) { |
958 | if (strncmp(argv[0], | 958 | if (strncmp(argv[0], |
959 | tp->cmd_name, | 959 | tp->cmd_name, |
960 | tp->cmd_minlen) == 0) { | 960 | tp->cmd_minlen) == 0) { |
961 | break; | 961 | break; |
962 | } | 962 | } |
963 | } | 963 | } |
964 | 964 | ||
965 | if (strcmp(argv[0], tp->cmd_name) == 0) | 965 | if (strcmp(argv[0], tp->cmd_name) == 0) |
966 | break; | 966 | break; |
967 | } | 967 | } |
968 | } | 968 | } |
969 | 969 | ||
970 | /* | 970 | /* |
971 | * If we don't find a command by this name, see if the first | 971 | * If we don't find a command by this name, see if the first |
972 | * few characters of this match any of the known commands. | 972 | * few characters of this match any of the known commands. |
973 | * e.g., md1c20 should match md. | 973 | * e.g., md1c20 should match md. |
974 | */ | 974 | */ |
975 | if (i == kdb_max_commands) { | 975 | if (i == kdb_max_commands) { |
976 | for_each_kdbcmd(tp, i) { | 976 | for_each_kdbcmd(tp, i) { |
977 | if (tp->cmd_name) { | 977 | if (tp->cmd_name) { |
978 | if (strncmp(argv[0], | 978 | if (strncmp(argv[0], |
979 | tp->cmd_name, | 979 | tp->cmd_name, |
980 | strlen(tp->cmd_name)) == 0) { | 980 | strlen(tp->cmd_name)) == 0) { |
981 | break; | 981 | break; |
982 | } | 982 | } |
983 | } | 983 | } |
984 | } | 984 | } |
985 | } | 985 | } |
986 | 986 | ||
987 | if (i < kdb_max_commands) { | 987 | if (i < kdb_max_commands) { |
988 | int result; | 988 | int result; |
989 | KDB_STATE_SET(CMD); | 989 | KDB_STATE_SET(CMD); |
990 | result = (*tp->cmd_func)(argc-1, (const char **)argv); | 990 | result = (*tp->cmd_func)(argc-1, (const char **)argv); |
991 | if (result && ignore_errors && result > KDB_CMD_GO) | 991 | if (result && ignore_errors && result > KDB_CMD_GO) |
992 | result = 0; | 992 | result = 0; |
993 | KDB_STATE_CLEAR(CMD); | 993 | KDB_STATE_CLEAR(CMD); |
994 | switch (tp->cmd_repeat) { | 994 | switch (tp->cmd_repeat) { |
995 | case KDB_REPEAT_NONE: | 995 | case KDB_REPEAT_NONE: |
996 | argc = 0; | 996 | argc = 0; |
997 | if (argv[0]) | 997 | if (argv[0]) |
998 | *(argv[0]) = '\0'; | 998 | *(argv[0]) = '\0'; |
999 | break; | 999 | break; |
1000 | case KDB_REPEAT_NO_ARGS: | 1000 | case KDB_REPEAT_NO_ARGS: |
1001 | argc = 1; | 1001 | argc = 1; |
1002 | if (argv[1]) | 1002 | if (argv[1]) |
1003 | *(argv[1]) = '\0'; | 1003 | *(argv[1]) = '\0'; |
1004 | break; | 1004 | break; |
1005 | case KDB_REPEAT_WITH_ARGS: | 1005 | case KDB_REPEAT_WITH_ARGS: |
1006 | break; | 1006 | break; |
1007 | } | 1007 | } |
1008 | return result; | 1008 | return result; |
1009 | } | 1009 | } |
1010 | 1010 | ||
1011 | /* | 1011 | /* |
1012 | * If the input with which we were presented does not | 1012 | * If the input with which we were presented does not |
1013 | * map to an existing command, attempt to parse it as an | 1013 | * map to an existing command, attempt to parse it as an |
1014 | * address argument and display the result. Useful for | 1014 | * address argument and display the result. Useful for |
1015 | * obtaining the address of a variable, or the nearest symbol | 1015 | * obtaining the address of a variable, or the nearest symbol |
1016 | * to an address contained in a register. | 1016 | * to an address contained in a register. |
1017 | */ | 1017 | */ |
1018 | { | 1018 | { |
1019 | unsigned long value; | 1019 | unsigned long value; |
1020 | char *name = NULL; | 1020 | char *name = NULL; |
1021 | long offset; | 1021 | long offset; |
1022 | int nextarg = 0; | 1022 | int nextarg = 0; |
1023 | 1023 | ||
1024 | if (kdbgetaddrarg(0, (const char **)argv, &nextarg, | 1024 | if (kdbgetaddrarg(0, (const char **)argv, &nextarg, |
1025 | &value, &offset, &name)) { | 1025 | &value, &offset, &name)) { |
1026 | return KDB_NOTFOUND; | 1026 | return KDB_NOTFOUND; |
1027 | } | 1027 | } |
1028 | 1028 | ||
1029 | kdb_printf("%s = ", argv[0]); | 1029 | kdb_printf("%s = ", argv[0]); |
1030 | kdb_symbol_print(value, NULL, KDB_SP_DEFAULT); | 1030 | kdb_symbol_print(value, NULL, KDB_SP_DEFAULT); |
1031 | kdb_printf("\n"); | 1031 | kdb_printf("\n"); |
1032 | return 0; | 1032 | return 0; |
1033 | } | 1033 | } |
1034 | } | 1034 | } |
1035 | 1035 | ||
1036 | 1036 | ||
1037 | static int handle_ctrl_cmd(char *cmd) | 1037 | static int handle_ctrl_cmd(char *cmd) |
1038 | { | 1038 | { |
1039 | #define CTRL_P 16 | 1039 | #define CTRL_P 16 |
1040 | #define CTRL_N 14 | 1040 | #define CTRL_N 14 |
1041 | 1041 | ||
1042 | /* initial situation */ | 1042 | /* initial situation */ |
1043 | if (cmd_head == cmd_tail) | 1043 | if (cmd_head == cmd_tail) |
1044 | return 0; | 1044 | return 0; |
1045 | switch (*cmd) { | 1045 | switch (*cmd) { |
1046 | case CTRL_P: | 1046 | case CTRL_P: |
1047 | if (cmdptr != cmd_tail) | 1047 | if (cmdptr != cmd_tail) |
1048 | cmdptr = (cmdptr-1) % KDB_CMD_HISTORY_COUNT; | 1048 | cmdptr = (cmdptr-1) % KDB_CMD_HISTORY_COUNT; |
1049 | strncpy(cmd_cur, cmd_hist[cmdptr], CMD_BUFLEN); | 1049 | strncpy(cmd_cur, cmd_hist[cmdptr], CMD_BUFLEN); |
1050 | return 1; | 1050 | return 1; |
1051 | case CTRL_N: | 1051 | case CTRL_N: |
1052 | if (cmdptr != cmd_head) | 1052 | if (cmdptr != cmd_head) |
1053 | cmdptr = (cmdptr+1) % KDB_CMD_HISTORY_COUNT; | 1053 | cmdptr = (cmdptr+1) % KDB_CMD_HISTORY_COUNT; |
1054 | strncpy(cmd_cur, cmd_hist[cmdptr], CMD_BUFLEN); | 1054 | strncpy(cmd_cur, cmd_hist[cmdptr], CMD_BUFLEN); |
1055 | return 1; | 1055 | return 1; |
1056 | } | 1056 | } |
1057 | return 0; | 1057 | return 0; |
1058 | } | 1058 | } |
1059 | 1059 | ||
1060 | /* | 1060 | /* |
1061 | * kdb_reboot - This function implements the 'reboot' command. Reboot | 1061 | * kdb_reboot - This function implements the 'reboot' command. Reboot |
1062 | * the system immediately, or loop for ever on failure. | 1062 | * the system immediately, or loop for ever on failure. |
1063 | */ | 1063 | */ |
1064 | static int kdb_reboot(int argc, const char **argv) | 1064 | static int kdb_reboot(int argc, const char **argv) |
1065 | { | 1065 | { |
1066 | emergency_restart(); | 1066 | emergency_restart(); |
1067 | kdb_printf("Hmm, kdb_reboot did not reboot, spinning here\n"); | 1067 | kdb_printf("Hmm, kdb_reboot did not reboot, spinning here\n"); |
1068 | while (1) | 1068 | while (1) |
1069 | cpu_relax(); | 1069 | cpu_relax(); |
1070 | /* NOTREACHED */ | 1070 | /* NOTREACHED */ |
1071 | return 0; | 1071 | return 0; |
1072 | } | 1072 | } |
1073 | 1073 | ||
1074 | static void kdb_dumpregs(struct pt_regs *regs) | 1074 | static void kdb_dumpregs(struct pt_regs *regs) |
1075 | { | 1075 | { |
1076 | int old_lvl = console_loglevel; | 1076 | int old_lvl = console_loglevel; |
1077 | console_loglevel = 15; | 1077 | console_loglevel = 15; |
1078 | kdb_trap_printk++; | 1078 | kdb_trap_printk++; |
1079 | show_regs(regs); | 1079 | show_regs(regs); |
1080 | kdb_trap_printk--; | 1080 | kdb_trap_printk--; |
1081 | kdb_printf("\n"); | 1081 | kdb_printf("\n"); |
1082 | console_loglevel = old_lvl; | 1082 | console_loglevel = old_lvl; |
1083 | } | 1083 | } |
1084 | 1084 | ||
1085 | void kdb_set_current_task(struct task_struct *p) | 1085 | void kdb_set_current_task(struct task_struct *p) |
1086 | { | 1086 | { |
1087 | kdb_current_task = p; | 1087 | kdb_current_task = p; |
1088 | 1088 | ||
1089 | if (kdb_task_has_cpu(p)) { | 1089 | if (kdb_task_has_cpu(p)) { |
1090 | kdb_current_regs = KDB_TSKREGS(kdb_process_cpu(p)); | 1090 | kdb_current_regs = KDB_TSKREGS(kdb_process_cpu(p)); |
1091 | return; | 1091 | return; |
1092 | } | 1092 | } |
1093 | kdb_current_regs = NULL; | 1093 | kdb_current_regs = NULL; |
1094 | } | 1094 | } |
1095 | 1095 | ||
1096 | /* | 1096 | /* |
1097 | * kdb_local - The main code for kdb. This routine is invoked on a | 1097 | * kdb_local - The main code for kdb. This routine is invoked on a |
1098 | * specific processor, it is not global. The main kdb() routine | 1098 | * specific processor, it is not global. The main kdb() routine |
1099 | * ensures that only one processor at a time is in this routine. | 1099 | * ensures that only one processor at a time is in this routine. |
1100 | * This code is called with the real reason code on the first | 1100 | * This code is called with the real reason code on the first |
1101 | * entry to a kdb session, thereafter it is called with reason | 1101 | * entry to a kdb session, thereafter it is called with reason |
1102 | * SWITCH, even if the user goes back to the original cpu. | 1102 | * SWITCH, even if the user goes back to the original cpu. |
1103 | * Inputs: | 1103 | * Inputs: |
1104 | * reason The reason KDB was invoked | 1104 | * reason The reason KDB was invoked |
1105 | * error The hardware-defined error code | 1105 | * error The hardware-defined error code |
1106 | * regs The exception frame at time of fault/breakpoint. | 1106 | * regs The exception frame at time of fault/breakpoint. |
1107 | * db_result Result code from the break or debug point. | 1107 | * db_result Result code from the break or debug point. |
1108 | * Returns: | 1108 | * Returns: |
1109 | * 0 KDB was invoked for an event which it wasn't responsible | 1109 | * 0 KDB was invoked for an event which it wasn't responsible |
1110 | * 1 KDB handled the event for which it was invoked. | 1110 | * 1 KDB handled the event for which it was invoked. |
1111 | * KDB_CMD_GO User typed 'go'. | 1111 | * KDB_CMD_GO User typed 'go'. |
1112 | * KDB_CMD_CPU User switched to another cpu. | 1112 | * KDB_CMD_CPU User switched to another cpu. |
1113 | * KDB_CMD_SS Single step. | 1113 | * KDB_CMD_SS Single step. |
1114 | * KDB_CMD_SSB Single step until branch. | 1114 | * KDB_CMD_SSB Single step until branch. |
1115 | */ | 1115 | */ |
1116 | static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, | 1116 | static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, |
1117 | kdb_dbtrap_t db_result) | 1117 | kdb_dbtrap_t db_result) |
1118 | { | 1118 | { |
1119 | char *cmdbuf; | 1119 | char *cmdbuf; |
1120 | int diag; | 1120 | int diag; |
1121 | struct task_struct *kdb_current = | 1121 | struct task_struct *kdb_current = |
1122 | kdb_curr_task(raw_smp_processor_id()); | 1122 | kdb_curr_task(raw_smp_processor_id()); |
1123 | 1123 | ||
1124 | KDB_DEBUG_STATE("kdb_local 1", reason); | 1124 | KDB_DEBUG_STATE("kdb_local 1", reason); |
1125 | kdb_go_count = 0; | 1125 | kdb_go_count = 0; |
1126 | if (reason == KDB_REASON_DEBUG) { | 1126 | if (reason == KDB_REASON_DEBUG) { |
1127 | /* special case below */ | 1127 | /* special case below */ |
1128 | } else { | 1128 | } else { |
1129 | kdb_printf("\nEntering kdb (current=0x%p, pid %d) ", | 1129 | kdb_printf("\nEntering kdb (current=0x%p, pid %d) ", |
1130 | kdb_current, kdb_current ? kdb_current->pid : 0); | 1130 | kdb_current, kdb_current ? kdb_current->pid : 0); |
1131 | #if defined(CONFIG_SMP) | 1131 | #if defined(CONFIG_SMP) |
1132 | kdb_printf("on processor %d ", raw_smp_processor_id()); | 1132 | kdb_printf("on processor %d ", raw_smp_processor_id()); |
1133 | #endif | 1133 | #endif |
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | switch (reason) { | 1136 | switch (reason) { |
1137 | case KDB_REASON_DEBUG: | 1137 | case KDB_REASON_DEBUG: |
1138 | { | 1138 | { |
1139 | /* | 1139 | /* |
1140 | * If re-entering kdb after a single step | 1140 | * If re-entering kdb after a single step |
1141 | * command, don't print the message. | 1141 | * command, don't print the message. |
1142 | */ | 1142 | */ |
1143 | switch (db_result) { | 1143 | switch (db_result) { |
1144 | case KDB_DB_BPT: | 1144 | case KDB_DB_BPT: |
1145 | kdb_printf("\nEntering kdb (0x%p, pid %d) ", | 1145 | kdb_printf("\nEntering kdb (0x%p, pid %d) ", |
1146 | kdb_current, kdb_current->pid); | 1146 | kdb_current, kdb_current->pid); |
1147 | #if defined(CONFIG_SMP) | 1147 | #if defined(CONFIG_SMP) |
1148 | kdb_printf("on processor %d ", raw_smp_processor_id()); | 1148 | kdb_printf("on processor %d ", raw_smp_processor_id()); |
1149 | #endif | 1149 | #endif |
1150 | kdb_printf("due to Debug @ " kdb_machreg_fmt "\n", | 1150 | kdb_printf("due to Debug @ " kdb_machreg_fmt "\n", |
1151 | instruction_pointer(regs)); | 1151 | instruction_pointer(regs)); |
1152 | break; | 1152 | break; |
1153 | case KDB_DB_SSB: | 1153 | case KDB_DB_SSB: |
1154 | /* | 1154 | /* |
1155 | * In the midst of ssb command. Just return. | 1155 | * In the midst of ssb command. Just return. |
1156 | */ | 1156 | */ |
1157 | KDB_DEBUG_STATE("kdb_local 3", reason); | 1157 | KDB_DEBUG_STATE("kdb_local 3", reason); |
1158 | return KDB_CMD_SSB; /* Continue with SSB command */ | 1158 | return KDB_CMD_SSB; /* Continue with SSB command */ |
1159 | 1159 | ||
1160 | break; | 1160 | break; |
1161 | case KDB_DB_SS: | 1161 | case KDB_DB_SS: |
1162 | break; | 1162 | break; |
1163 | case KDB_DB_SSBPT: | 1163 | case KDB_DB_SSBPT: |
1164 | KDB_DEBUG_STATE("kdb_local 4", reason); | 1164 | KDB_DEBUG_STATE("kdb_local 4", reason); |
1165 | return 1; /* kdba_db_trap did the work */ | 1165 | return 1; /* kdba_db_trap did the work */ |
1166 | default: | 1166 | default: |
1167 | kdb_printf("kdb: Bad result from kdba_db_trap: %d\n", | 1167 | kdb_printf("kdb: Bad result from kdba_db_trap: %d\n", |
1168 | db_result); | 1168 | db_result); |
1169 | break; | 1169 | break; |
1170 | } | 1170 | } |
1171 | 1171 | ||
1172 | } | 1172 | } |
1173 | break; | 1173 | break; |
1174 | case KDB_REASON_ENTER: | 1174 | case KDB_REASON_ENTER: |
1175 | if (KDB_STATE(KEYBOARD)) | 1175 | if (KDB_STATE(KEYBOARD)) |
1176 | kdb_printf("due to Keyboard Entry\n"); | 1176 | kdb_printf("due to Keyboard Entry\n"); |
1177 | else | 1177 | else |
1178 | kdb_printf("due to KDB_ENTER()\n"); | 1178 | kdb_printf("due to KDB_ENTER()\n"); |
1179 | break; | 1179 | break; |
1180 | case KDB_REASON_KEYBOARD: | 1180 | case KDB_REASON_KEYBOARD: |
1181 | KDB_STATE_SET(KEYBOARD); | 1181 | KDB_STATE_SET(KEYBOARD); |
1182 | kdb_printf("due to Keyboard Entry\n"); | 1182 | kdb_printf("due to Keyboard Entry\n"); |
1183 | break; | 1183 | break; |
1184 | case KDB_REASON_ENTER_SLAVE: | 1184 | case KDB_REASON_ENTER_SLAVE: |
1185 | /* drop through, slaves only get released via cpu switch */ | 1185 | /* drop through, slaves only get released via cpu switch */ |
1186 | case KDB_REASON_SWITCH: | 1186 | case KDB_REASON_SWITCH: |
1187 | kdb_printf("due to cpu switch\n"); | 1187 | kdb_printf("due to cpu switch\n"); |
1188 | break; | 1188 | break; |
1189 | case KDB_REASON_OOPS: | 1189 | case KDB_REASON_OOPS: |
1190 | kdb_printf("Oops: %s\n", kdb_diemsg); | 1190 | kdb_printf("Oops: %s\n", kdb_diemsg); |
1191 | kdb_printf("due to oops @ " kdb_machreg_fmt "\n", | 1191 | kdb_printf("due to oops @ " kdb_machreg_fmt "\n", |
1192 | instruction_pointer(regs)); | 1192 | instruction_pointer(regs)); |
1193 | kdb_dumpregs(regs); | 1193 | kdb_dumpregs(regs); |
1194 | break; | 1194 | break; |
1195 | case KDB_REASON_NMI: | 1195 | case KDB_REASON_NMI: |
1196 | kdb_printf("due to NonMaskable Interrupt @ " | 1196 | kdb_printf("due to NonMaskable Interrupt @ " |
1197 | kdb_machreg_fmt "\n", | 1197 | kdb_machreg_fmt "\n", |
1198 | instruction_pointer(regs)); | 1198 | instruction_pointer(regs)); |
1199 | kdb_dumpregs(regs); | 1199 | kdb_dumpregs(regs); |
1200 | break; | 1200 | break; |
1201 | case KDB_REASON_SSTEP: | 1201 | case KDB_REASON_SSTEP: |
1202 | case KDB_REASON_BREAK: | 1202 | case KDB_REASON_BREAK: |
1203 | kdb_printf("due to %s @ " kdb_machreg_fmt "\n", | 1203 | kdb_printf("due to %s @ " kdb_machreg_fmt "\n", |
1204 | reason == KDB_REASON_BREAK ? | 1204 | reason == KDB_REASON_BREAK ? |
1205 | "Breakpoint" : "SS trap", instruction_pointer(regs)); | 1205 | "Breakpoint" : "SS trap", instruction_pointer(regs)); |
1206 | /* | 1206 | /* |
1207 | * Determine if this breakpoint is one that we | 1207 | * Determine if this breakpoint is one that we |
1208 | * are interested in. | 1208 | * are interested in. |
1209 | */ | 1209 | */ |
1210 | if (db_result != KDB_DB_BPT) { | 1210 | if (db_result != KDB_DB_BPT) { |
1211 | kdb_printf("kdb: error return from kdba_bp_trap: %d\n", | 1211 | kdb_printf("kdb: error return from kdba_bp_trap: %d\n", |
1212 | db_result); | 1212 | db_result); |
1213 | KDB_DEBUG_STATE("kdb_local 6", reason); | 1213 | KDB_DEBUG_STATE("kdb_local 6", reason); |
1214 | return 0; /* Not for us, dismiss it */ | 1214 | return 0; /* Not for us, dismiss it */ |
1215 | } | 1215 | } |
1216 | break; | 1216 | break; |
1217 | case KDB_REASON_RECURSE: | 1217 | case KDB_REASON_RECURSE: |
1218 | kdb_printf("due to Recursion @ " kdb_machreg_fmt "\n", | 1218 | kdb_printf("due to Recursion @ " kdb_machreg_fmt "\n", |
1219 | instruction_pointer(regs)); | 1219 | instruction_pointer(regs)); |
1220 | break; | 1220 | break; |
1221 | default: | 1221 | default: |
1222 | kdb_printf("kdb: unexpected reason code: %d\n", reason); | 1222 | kdb_printf("kdb: unexpected reason code: %d\n", reason); |
1223 | KDB_DEBUG_STATE("kdb_local 8", reason); | 1223 | KDB_DEBUG_STATE("kdb_local 8", reason); |
1224 | return 0; /* Not for us, dismiss it */ | 1224 | return 0; /* Not for us, dismiss it */ |
1225 | } | 1225 | } |
1226 | 1226 | ||
1227 | while (1) { | 1227 | while (1) { |
1228 | /* | 1228 | /* |
1229 | * Initialize pager context. | 1229 | * Initialize pager context. |
1230 | */ | 1230 | */ |
1231 | kdb_nextline = 1; | 1231 | kdb_nextline = 1; |
1232 | KDB_STATE_CLEAR(SUPPRESS); | 1232 | KDB_STATE_CLEAR(SUPPRESS); |
1233 | 1233 | ||
1234 | cmdbuf = cmd_cur; | 1234 | cmdbuf = cmd_cur; |
1235 | *cmdbuf = '\0'; | 1235 | *cmdbuf = '\0'; |
1236 | *(cmd_hist[cmd_head]) = '\0'; | 1236 | *(cmd_hist[cmd_head]) = '\0'; |
1237 | 1237 | ||
1238 | if (KDB_FLAG(ONLY_DO_DUMP)) { | 1238 | if (KDB_FLAG(ONLY_DO_DUMP)) { |
1239 | /* kdb is off but a catastrophic error requires a dump. | 1239 | /* kdb is off but a catastrophic error requires a dump. |
1240 | * Take the dump and reboot. | 1240 | * Take the dump and reboot. |
1241 | * Turn on logging so the kdb output appears in the log | 1241 | * Turn on logging so the kdb output appears in the log |
1242 | * buffer in the dump. | 1242 | * buffer in the dump. |
1243 | */ | 1243 | */ |
1244 | const char *setargs[] = { "set", "LOGGING", "1" }; | 1244 | const char *setargs[] = { "set", "LOGGING", "1" }; |
1245 | kdb_set(2, setargs); | 1245 | kdb_set(2, setargs); |
1246 | kdb_reboot(0, NULL); | 1246 | kdb_reboot(0, NULL); |
1247 | /*NOTREACHED*/ | 1247 | /*NOTREACHED*/ |
1248 | } | 1248 | } |
1249 | 1249 | ||
1250 | do_full_getstr: | 1250 | do_full_getstr: |
1251 | #if defined(CONFIG_SMP) | 1251 | #if defined(CONFIG_SMP) |
1252 | snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT"), | 1252 | snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT"), |
1253 | raw_smp_processor_id()); | 1253 | raw_smp_processor_id()); |
1254 | #else | 1254 | #else |
1255 | snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT")); | 1255 | snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT")); |
1256 | #endif | 1256 | #endif |
1257 | if (defcmd_in_progress) | 1257 | if (defcmd_in_progress) |
1258 | strncat(kdb_prompt_str, "[defcmd]", CMD_BUFLEN); | 1258 | strncat(kdb_prompt_str, "[defcmd]", CMD_BUFLEN); |
1259 | 1259 | ||
1260 | /* | 1260 | /* |
1261 | * Fetch command from keyboard | 1261 | * Fetch command from keyboard |
1262 | */ | 1262 | */ |
1263 | cmdbuf = kdb_getstr(cmdbuf, CMD_BUFLEN, kdb_prompt_str); | 1263 | cmdbuf = kdb_getstr(cmdbuf, CMD_BUFLEN, kdb_prompt_str); |
1264 | if (*cmdbuf != '\n') { | 1264 | if (*cmdbuf != '\n') { |
1265 | if (*cmdbuf < 32) { | 1265 | if (*cmdbuf < 32) { |
1266 | if (cmdptr == cmd_head) { | 1266 | if (cmdptr == cmd_head) { |
1267 | strncpy(cmd_hist[cmd_head], cmd_cur, | 1267 | strncpy(cmd_hist[cmd_head], cmd_cur, |
1268 | CMD_BUFLEN); | 1268 | CMD_BUFLEN); |
1269 | *(cmd_hist[cmd_head] + | 1269 | *(cmd_hist[cmd_head] + |
1270 | strlen(cmd_hist[cmd_head])-1) = '\0'; | 1270 | strlen(cmd_hist[cmd_head])-1) = '\0'; |
1271 | } | 1271 | } |
1272 | if (!handle_ctrl_cmd(cmdbuf)) | 1272 | if (!handle_ctrl_cmd(cmdbuf)) |
1273 | *(cmd_cur+strlen(cmd_cur)-1) = '\0'; | 1273 | *(cmd_cur+strlen(cmd_cur)-1) = '\0'; |
1274 | cmdbuf = cmd_cur; | 1274 | cmdbuf = cmd_cur; |
1275 | goto do_full_getstr; | 1275 | goto do_full_getstr; |
1276 | } else { | 1276 | } else { |
1277 | strncpy(cmd_hist[cmd_head], cmd_cur, | 1277 | strncpy(cmd_hist[cmd_head], cmd_cur, |
1278 | CMD_BUFLEN); | 1278 | CMD_BUFLEN); |
1279 | } | 1279 | } |
1280 | 1280 | ||
1281 | cmd_head = (cmd_head+1) % KDB_CMD_HISTORY_COUNT; | 1281 | cmd_head = (cmd_head+1) % KDB_CMD_HISTORY_COUNT; |
1282 | if (cmd_head == cmd_tail) | 1282 | if (cmd_head == cmd_tail) |
1283 | cmd_tail = (cmd_tail+1) % KDB_CMD_HISTORY_COUNT; | 1283 | cmd_tail = (cmd_tail+1) % KDB_CMD_HISTORY_COUNT; |
1284 | } | 1284 | } |
1285 | 1285 | ||
1286 | cmdptr = cmd_head; | 1286 | cmdptr = cmd_head; |
1287 | diag = kdb_parse(cmdbuf); | 1287 | diag = kdb_parse(cmdbuf); |
1288 | if (diag == KDB_NOTFOUND) { | 1288 | if (diag == KDB_NOTFOUND) { |
1289 | kdb_printf("Unknown kdb command: '%s'\n", cmdbuf); | 1289 | kdb_printf("Unknown kdb command: '%s'\n", cmdbuf); |
1290 | diag = 0; | 1290 | diag = 0; |
1291 | } | 1291 | } |
1292 | if (diag == KDB_CMD_GO | 1292 | if (diag == KDB_CMD_GO |
1293 | || diag == KDB_CMD_CPU | 1293 | || diag == KDB_CMD_CPU |
1294 | || diag == KDB_CMD_SS | 1294 | || diag == KDB_CMD_SS |
1295 | || diag == KDB_CMD_SSB | 1295 | || diag == KDB_CMD_SSB |
1296 | || diag == KDB_CMD_KGDB) | 1296 | || diag == KDB_CMD_KGDB) |
1297 | break; | 1297 | break; |
1298 | 1298 | ||
1299 | if (diag) | 1299 | if (diag) |
1300 | kdb_cmderror(diag); | 1300 | kdb_cmderror(diag); |
1301 | } | 1301 | } |
1302 | KDB_DEBUG_STATE("kdb_local 9", diag); | 1302 | KDB_DEBUG_STATE("kdb_local 9", diag); |
1303 | return diag; | 1303 | return diag; |
1304 | } | 1304 | } |
1305 | 1305 | ||
1306 | 1306 | ||
1307 | /* | 1307 | /* |
1308 | * kdb_print_state - Print the state data for the current processor | 1308 | * kdb_print_state - Print the state data for the current processor |
1309 | * for debugging. | 1309 | * for debugging. |
1310 | * Inputs: | 1310 | * Inputs: |
1311 | * text Identifies the debug point | 1311 | * text Identifies the debug point |
1312 | * value Any integer value to be printed, e.g. reason code. | 1312 | * value Any integer value to be printed, e.g. reason code. |
1313 | */ | 1313 | */ |
1314 | void kdb_print_state(const char *text, int value) | 1314 | void kdb_print_state(const char *text, int value) |
1315 | { | 1315 | { |
1316 | kdb_printf("state: %s cpu %d value %d initial %d state %x\n", | 1316 | kdb_printf("state: %s cpu %d value %d initial %d state %x\n", |
1317 | text, raw_smp_processor_id(), value, kdb_initial_cpu, | 1317 | text, raw_smp_processor_id(), value, kdb_initial_cpu, |
1318 | kdb_state); | 1318 | kdb_state); |
1319 | } | 1319 | } |
1320 | 1320 | ||
1321 | /* | 1321 | /* |
1322 | * kdb_main_loop - After initial setup and assignment of the | 1322 | * kdb_main_loop - After initial setup and assignment of the |
1323 | * controlling cpu, all cpus are in this loop. One cpu is in | 1323 | * controlling cpu, all cpus are in this loop. One cpu is in |
1324 | * control and will issue the kdb prompt, the others will spin | 1324 | * control and will issue the kdb prompt, the others will spin |
1325 | * until 'go' or cpu switch. | 1325 | * until 'go' or cpu switch. |
1326 | * | 1326 | * |
1327 | * To get a consistent view of the kernel stacks for all | 1327 | * To get a consistent view of the kernel stacks for all |
1328 | * processes, this routine is invoked from the main kdb code via | 1328 | * processes, this routine is invoked from the main kdb code via |
1329 | * an architecture specific routine. kdba_main_loop is | 1329 | * an architecture specific routine. kdba_main_loop is |
1330 | * responsible for making the kernel stacks consistent for all | 1330 | * responsible for making the kernel stacks consistent for all |
1331 | * processes, there should be no difference between a blocked | 1331 | * processes, there should be no difference between a blocked |
1332 | * process and a running process as far as kdb is concerned. | 1332 | * process and a running process as far as kdb is concerned. |
1333 | * Inputs: | 1333 | * Inputs: |
1334 | * reason The reason KDB was invoked | 1334 | * reason The reason KDB was invoked |
1335 | * error The hardware-defined error code | 1335 | * error The hardware-defined error code |
1336 | * reason2 kdb's current reason code. | 1336 | * reason2 kdb's current reason code. |
1337 | * Initially error but can change | 1337 | * Initially error but can change |
1338 | * acording to kdb state. | 1338 | * acording to kdb state. |
1339 | * db_result Result code from break or debug point. | 1339 | * db_result Result code from break or debug point. |
1340 | * regs The exception frame at time of fault/breakpoint. | 1340 | * regs The exception frame at time of fault/breakpoint. |
1341 | * should always be valid. | 1341 | * should always be valid. |
1342 | * Returns: | 1342 | * Returns: |
1343 | * 0 KDB was invoked for an event which it wasn't responsible | 1343 | * 0 KDB was invoked for an event which it wasn't responsible |
1344 | * 1 KDB handled the event for which it was invoked. | 1344 | * 1 KDB handled the event for which it was invoked. |
1345 | */ | 1345 | */ |
1346 | int kdb_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error, | 1346 | int kdb_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error, |
1347 | kdb_dbtrap_t db_result, struct pt_regs *regs) | 1347 | kdb_dbtrap_t db_result, struct pt_regs *regs) |
1348 | { | 1348 | { |
1349 | int result = 1; | 1349 | int result = 1; |
1350 | /* Stay in kdb() until 'go', 'ss[b]' or an error */ | 1350 | /* Stay in kdb() until 'go', 'ss[b]' or an error */ |
1351 | while (1) { | 1351 | while (1) { |
1352 | /* | 1352 | /* |
1353 | * All processors except the one that is in control | 1353 | * All processors except the one that is in control |
1354 | * will spin here. | 1354 | * will spin here. |
1355 | */ | 1355 | */ |
1356 | KDB_DEBUG_STATE("kdb_main_loop 1", reason); | 1356 | KDB_DEBUG_STATE("kdb_main_loop 1", reason); |
1357 | while (KDB_STATE(HOLD_CPU)) { | 1357 | while (KDB_STATE(HOLD_CPU)) { |
1358 | /* state KDB is turned off by kdb_cpu to see if the | 1358 | /* state KDB is turned off by kdb_cpu to see if the |
1359 | * other cpus are still live, each cpu in this loop | 1359 | * other cpus are still live, each cpu in this loop |
1360 | * turns it back on. | 1360 | * turns it back on. |
1361 | */ | 1361 | */ |
1362 | if (!KDB_STATE(KDB)) | 1362 | if (!KDB_STATE(KDB)) |
1363 | KDB_STATE_SET(KDB); | 1363 | KDB_STATE_SET(KDB); |
1364 | } | 1364 | } |
1365 | 1365 | ||
1366 | KDB_STATE_CLEAR(SUPPRESS); | 1366 | KDB_STATE_CLEAR(SUPPRESS); |
1367 | KDB_DEBUG_STATE("kdb_main_loop 2", reason); | 1367 | KDB_DEBUG_STATE("kdb_main_loop 2", reason); |
1368 | if (KDB_STATE(LEAVING)) | 1368 | if (KDB_STATE(LEAVING)) |
1369 | break; /* Another cpu said 'go' */ | 1369 | break; /* Another cpu said 'go' */ |
1370 | /* Still using kdb, this processor is in control */ | 1370 | /* Still using kdb, this processor is in control */ |
1371 | result = kdb_local(reason2, error, regs, db_result); | 1371 | result = kdb_local(reason2, error, regs, db_result); |
1372 | KDB_DEBUG_STATE("kdb_main_loop 3", result); | 1372 | KDB_DEBUG_STATE("kdb_main_loop 3", result); |
1373 | 1373 | ||
1374 | if (result == KDB_CMD_CPU) | 1374 | if (result == KDB_CMD_CPU) |
1375 | break; | 1375 | break; |
1376 | 1376 | ||
1377 | if (result == KDB_CMD_SS) { | 1377 | if (result == KDB_CMD_SS) { |
1378 | KDB_STATE_SET(DOING_SS); | 1378 | KDB_STATE_SET(DOING_SS); |
1379 | break; | 1379 | break; |
1380 | } | 1380 | } |
1381 | 1381 | ||
1382 | if (result == KDB_CMD_SSB) { | 1382 | if (result == KDB_CMD_SSB) { |
1383 | KDB_STATE_SET(DOING_SS); | 1383 | KDB_STATE_SET(DOING_SS); |
1384 | KDB_STATE_SET(DOING_SSB); | 1384 | KDB_STATE_SET(DOING_SSB); |
1385 | break; | 1385 | break; |
1386 | } | 1386 | } |
1387 | 1387 | ||
1388 | if (result == KDB_CMD_KGDB) { | 1388 | if (result == KDB_CMD_KGDB) { |
1389 | if (!(KDB_STATE(DOING_KGDB) || KDB_STATE(DOING_KGDB2))) | 1389 | if (!(KDB_STATE(DOING_KGDB) || KDB_STATE(DOING_KGDB2))) |
1390 | kdb_printf("Entering please attach debugger " | 1390 | kdb_printf("Entering please attach debugger " |
1391 | "or use $D#44+ or $3#33\n"); | 1391 | "or use $D#44+ or $3#33\n"); |
1392 | break; | 1392 | break; |
1393 | } | 1393 | } |
1394 | if (result && result != 1 && result != KDB_CMD_GO) | 1394 | if (result && result != 1 && result != KDB_CMD_GO) |
1395 | kdb_printf("\nUnexpected kdb_local return code %d\n", | 1395 | kdb_printf("\nUnexpected kdb_local return code %d\n", |
1396 | result); | 1396 | result); |
1397 | KDB_DEBUG_STATE("kdb_main_loop 4", reason); | 1397 | KDB_DEBUG_STATE("kdb_main_loop 4", reason); |
1398 | break; | 1398 | break; |
1399 | } | 1399 | } |
1400 | if (KDB_STATE(DOING_SS)) | 1400 | if (KDB_STATE(DOING_SS)) |
1401 | KDB_STATE_CLEAR(SSBPT); | 1401 | KDB_STATE_CLEAR(SSBPT); |
1402 | 1402 | ||
1403 | return result; | 1403 | return result; |
1404 | } | 1404 | } |
1405 | 1405 | ||
1406 | /* | 1406 | /* |
1407 | * kdb_mdr - This function implements the guts of the 'mdr', memory | 1407 | * kdb_mdr - This function implements the guts of the 'mdr', memory |
1408 | * read command. | 1408 | * read command. |
1409 | * mdr <addr arg>,<byte count> | 1409 | * mdr <addr arg>,<byte count> |
1410 | * Inputs: | 1410 | * Inputs: |
1411 | * addr Start address | 1411 | * addr Start address |
1412 | * count Number of bytes | 1412 | * count Number of bytes |
1413 | * Returns: | 1413 | * Returns: |
1414 | * Always 0. Any errors are detected and printed by kdb_getarea. | 1414 | * Always 0. Any errors are detected and printed by kdb_getarea. |
1415 | */ | 1415 | */ |
1416 | static int kdb_mdr(unsigned long addr, unsigned int count) | 1416 | static int kdb_mdr(unsigned long addr, unsigned int count) |
1417 | { | 1417 | { |
1418 | unsigned char c; | 1418 | unsigned char c; |
1419 | while (count--) { | 1419 | while (count--) { |
1420 | if (kdb_getarea(c, addr)) | 1420 | if (kdb_getarea(c, addr)) |
1421 | return 0; | 1421 | return 0; |
1422 | kdb_printf("%02x", c); | 1422 | kdb_printf("%02x", c); |
1423 | addr++; | 1423 | addr++; |
1424 | } | 1424 | } |
1425 | kdb_printf("\n"); | 1425 | kdb_printf("\n"); |
1426 | return 0; | 1426 | return 0; |
1427 | } | 1427 | } |
1428 | 1428 | ||
1429 | /* | 1429 | /* |
1430 | * kdb_md - This function implements the 'md', 'md1', 'md2', 'md4', | 1430 | * kdb_md - This function implements the 'md', 'md1', 'md2', 'md4', |
1431 | * 'md8' 'mdr' and 'mds' commands. | 1431 | * 'md8' 'mdr' and 'mds' commands. |
1432 | * | 1432 | * |
1433 | * md|mds [<addr arg> [<line count> [<radix>]]] | 1433 | * md|mds [<addr arg> [<line count> [<radix>]]] |
1434 | * mdWcN [<addr arg> [<line count> [<radix>]]] | 1434 | * mdWcN [<addr arg> [<line count> [<radix>]]] |
1435 | * where W = is the width (1, 2, 4 or 8) and N is the count. | 1435 | * where W = is the width (1, 2, 4 or 8) and N is the count. |
1436 | * for eg., md1c20 reads 20 bytes, 1 at a time. | 1436 | * for eg., md1c20 reads 20 bytes, 1 at a time. |
1437 | * mdr <addr arg>,<byte count> | 1437 | * mdr <addr arg>,<byte count> |
1438 | */ | 1438 | */ |
1439 | static void kdb_md_line(const char *fmtstr, unsigned long addr, | 1439 | static void kdb_md_line(const char *fmtstr, unsigned long addr, |
1440 | int symbolic, int nosect, int bytesperword, | 1440 | int symbolic, int nosect, int bytesperword, |
1441 | int num, int repeat, int phys) | 1441 | int num, int repeat, int phys) |
1442 | { | 1442 | { |
1443 | /* print just one line of data */ | 1443 | /* print just one line of data */ |
1444 | kdb_symtab_t symtab; | 1444 | kdb_symtab_t symtab; |
1445 | char cbuf[32]; | 1445 | char cbuf[32]; |
1446 | char *c = cbuf; | 1446 | char *c = cbuf; |
1447 | int i; | 1447 | int i; |
1448 | unsigned long word; | 1448 | unsigned long word; |
1449 | 1449 | ||
1450 | memset(cbuf, '\0', sizeof(cbuf)); | 1450 | memset(cbuf, '\0', sizeof(cbuf)); |
1451 | if (phys) | 1451 | if (phys) |
1452 | kdb_printf("phys " kdb_machreg_fmt0 " ", addr); | 1452 | kdb_printf("phys " kdb_machreg_fmt0 " ", addr); |
1453 | else | 1453 | else |
1454 | kdb_printf(kdb_machreg_fmt0 " ", addr); | 1454 | kdb_printf(kdb_machreg_fmt0 " ", addr); |
1455 | 1455 | ||
1456 | for (i = 0; i < num && repeat--; i++) { | 1456 | for (i = 0; i < num && repeat--; i++) { |
1457 | if (phys) { | 1457 | if (phys) { |
1458 | if (kdb_getphysword(&word, addr, bytesperword)) | 1458 | if (kdb_getphysword(&word, addr, bytesperword)) |
1459 | break; | 1459 | break; |
1460 | } else if (kdb_getword(&word, addr, bytesperword)) | 1460 | } else if (kdb_getword(&word, addr, bytesperword)) |
1461 | break; | 1461 | break; |
1462 | kdb_printf(fmtstr, word); | 1462 | kdb_printf(fmtstr, word); |
1463 | if (symbolic) | 1463 | if (symbolic) |
1464 | kdbnearsym(word, &symtab); | 1464 | kdbnearsym(word, &symtab); |
1465 | else | 1465 | else |
1466 | memset(&symtab, 0, sizeof(symtab)); | 1466 | memset(&symtab, 0, sizeof(symtab)); |
1467 | if (symtab.sym_name) { | 1467 | if (symtab.sym_name) { |
1468 | kdb_symbol_print(word, &symtab, 0); | 1468 | kdb_symbol_print(word, &symtab, 0); |
1469 | if (!nosect) { | 1469 | if (!nosect) { |
1470 | kdb_printf("\n"); | 1470 | kdb_printf("\n"); |
1471 | kdb_printf(" %s %s " | 1471 | kdb_printf(" %s %s " |
1472 | kdb_machreg_fmt " " | 1472 | kdb_machreg_fmt " " |
1473 | kdb_machreg_fmt " " | 1473 | kdb_machreg_fmt " " |
1474 | kdb_machreg_fmt, symtab.mod_name, | 1474 | kdb_machreg_fmt, symtab.mod_name, |
1475 | symtab.sec_name, symtab.sec_start, | 1475 | symtab.sec_name, symtab.sec_start, |
1476 | symtab.sym_start, symtab.sym_end); | 1476 | symtab.sym_start, symtab.sym_end); |
1477 | } | 1477 | } |
1478 | addr += bytesperword; | 1478 | addr += bytesperword; |
1479 | } else { | 1479 | } else { |
1480 | union { | 1480 | union { |
1481 | u64 word; | 1481 | u64 word; |
1482 | unsigned char c[8]; | 1482 | unsigned char c[8]; |
1483 | } wc; | 1483 | } wc; |
1484 | unsigned char *cp; | 1484 | unsigned char *cp; |
1485 | #ifdef __BIG_ENDIAN | 1485 | #ifdef __BIG_ENDIAN |
1486 | cp = wc.c + 8 - bytesperword; | 1486 | cp = wc.c + 8 - bytesperword; |
1487 | #else | 1487 | #else |
1488 | cp = wc.c; | 1488 | cp = wc.c; |
1489 | #endif | 1489 | #endif |
1490 | wc.word = word; | 1490 | wc.word = word; |
1491 | #define printable_char(c) \ | 1491 | #define printable_char(c) \ |
1492 | ({unsigned char __c = c; isascii(__c) && isprint(__c) ? __c : '.'; }) | 1492 | ({unsigned char __c = c; isascii(__c) && isprint(__c) ? __c : '.'; }) |
1493 | switch (bytesperword) { | 1493 | switch (bytesperword) { |
1494 | case 8: | 1494 | case 8: |
1495 | *c++ = printable_char(*cp++); | 1495 | *c++ = printable_char(*cp++); |
1496 | *c++ = printable_char(*cp++); | 1496 | *c++ = printable_char(*cp++); |
1497 | *c++ = printable_char(*cp++); | 1497 | *c++ = printable_char(*cp++); |
1498 | *c++ = printable_char(*cp++); | 1498 | *c++ = printable_char(*cp++); |
1499 | addr += 4; | 1499 | addr += 4; |
1500 | case 4: | 1500 | case 4: |
1501 | *c++ = printable_char(*cp++); | 1501 | *c++ = printable_char(*cp++); |
1502 | *c++ = printable_char(*cp++); | 1502 | *c++ = printable_char(*cp++); |
1503 | addr += 2; | 1503 | addr += 2; |
1504 | case 2: | 1504 | case 2: |
1505 | *c++ = printable_char(*cp++); | 1505 | *c++ = printable_char(*cp++); |
1506 | addr++; | 1506 | addr++; |
1507 | case 1: | 1507 | case 1: |
1508 | *c++ = printable_char(*cp++); | 1508 | *c++ = printable_char(*cp++); |
1509 | addr++; | 1509 | addr++; |
1510 | break; | 1510 | break; |
1511 | } | 1511 | } |
1512 | #undef printable_char | 1512 | #undef printable_char |
1513 | } | 1513 | } |
1514 | } | 1514 | } |
1515 | kdb_printf("%*s %s\n", (int)((num-i)*(2*bytesperword + 1)+1), | 1515 | kdb_printf("%*s %s\n", (int)((num-i)*(2*bytesperword + 1)+1), |
1516 | " ", cbuf); | 1516 | " ", cbuf); |
1517 | } | 1517 | } |
1518 | 1518 | ||
1519 | static int kdb_md(int argc, const char **argv) | 1519 | static int kdb_md(int argc, const char **argv) |
1520 | { | 1520 | { |
1521 | static unsigned long last_addr; | 1521 | static unsigned long last_addr; |
1522 | static int last_radix, last_bytesperword, last_repeat; | 1522 | static int last_radix, last_bytesperword, last_repeat; |
1523 | int radix = 16, mdcount = 8, bytesperword = KDB_WORD_SIZE, repeat; | 1523 | int radix = 16, mdcount = 8, bytesperword = KDB_WORD_SIZE, repeat; |
1524 | int nosect = 0; | 1524 | int nosect = 0; |
1525 | char fmtchar, fmtstr[64]; | 1525 | char fmtchar, fmtstr[64]; |
1526 | unsigned long addr; | 1526 | unsigned long addr; |
1527 | unsigned long word; | 1527 | unsigned long word; |
1528 | long offset = 0; | 1528 | long offset = 0; |
1529 | int symbolic = 0; | 1529 | int symbolic = 0; |
1530 | int valid = 0; | 1530 | int valid = 0; |
1531 | int phys = 0; | 1531 | int phys = 0; |
1532 | 1532 | ||
1533 | kdbgetintenv("MDCOUNT", &mdcount); | 1533 | kdbgetintenv("MDCOUNT", &mdcount); |
1534 | kdbgetintenv("RADIX", &radix); | 1534 | kdbgetintenv("RADIX", &radix); |
1535 | kdbgetintenv("BYTESPERWORD", &bytesperword); | 1535 | kdbgetintenv("BYTESPERWORD", &bytesperword); |
1536 | 1536 | ||
1537 | /* Assume 'md <addr>' and start with environment values */ | 1537 | /* Assume 'md <addr>' and start with environment values */ |
1538 | repeat = mdcount * 16 / bytesperword; | 1538 | repeat = mdcount * 16 / bytesperword; |
1539 | 1539 | ||
1540 | if (strcmp(argv[0], "mdr") == 0) { | 1540 | if (strcmp(argv[0], "mdr") == 0) { |
1541 | if (argc != 2) | 1541 | if (argc != 2) |
1542 | return KDB_ARGCOUNT; | 1542 | return KDB_ARGCOUNT; |
1543 | valid = 1; | 1543 | valid = 1; |
1544 | } else if (isdigit(argv[0][2])) { | 1544 | } else if (isdigit(argv[0][2])) { |
1545 | bytesperword = (int)(argv[0][2] - '0'); | 1545 | bytesperword = (int)(argv[0][2] - '0'); |
1546 | if (bytesperword == 0) { | 1546 | if (bytesperword == 0) { |
1547 | bytesperword = last_bytesperword; | 1547 | bytesperword = last_bytesperword; |
1548 | if (bytesperword == 0) | 1548 | if (bytesperword == 0) |
1549 | bytesperword = 4; | 1549 | bytesperword = 4; |
1550 | } | 1550 | } |
1551 | last_bytesperword = bytesperword; | 1551 | last_bytesperword = bytesperword; |
1552 | repeat = mdcount * 16 / bytesperword; | 1552 | repeat = mdcount * 16 / bytesperword; |
1553 | if (!argv[0][3]) | 1553 | if (!argv[0][3]) |
1554 | valid = 1; | 1554 | valid = 1; |
1555 | else if (argv[0][3] == 'c' && argv[0][4]) { | 1555 | else if (argv[0][3] == 'c' && argv[0][4]) { |
1556 | char *p; | 1556 | char *p; |
1557 | repeat = simple_strtoul(argv[0] + 4, &p, 10); | 1557 | repeat = simple_strtoul(argv[0] + 4, &p, 10); |
1558 | mdcount = ((repeat * bytesperword) + 15) / 16; | 1558 | mdcount = ((repeat * bytesperword) + 15) / 16; |
1559 | valid = !*p; | 1559 | valid = !*p; |
1560 | } | 1560 | } |
1561 | last_repeat = repeat; | 1561 | last_repeat = repeat; |
1562 | } else if (strcmp(argv[0], "md") == 0) | 1562 | } else if (strcmp(argv[0], "md") == 0) |
1563 | valid = 1; | 1563 | valid = 1; |
1564 | else if (strcmp(argv[0], "mds") == 0) | 1564 | else if (strcmp(argv[0], "mds") == 0) |
1565 | valid = 1; | 1565 | valid = 1; |
1566 | else if (strcmp(argv[0], "mdp") == 0) { | 1566 | else if (strcmp(argv[0], "mdp") == 0) { |
1567 | phys = valid = 1; | 1567 | phys = valid = 1; |
1568 | } | 1568 | } |
1569 | if (!valid) | 1569 | if (!valid) |
1570 | return KDB_NOTFOUND; | 1570 | return KDB_NOTFOUND; |
1571 | 1571 | ||
1572 | if (argc == 0) { | 1572 | if (argc == 0) { |
1573 | if (last_addr == 0) | 1573 | if (last_addr == 0) |
1574 | return KDB_ARGCOUNT; | 1574 | return KDB_ARGCOUNT; |
1575 | addr = last_addr; | 1575 | addr = last_addr; |
1576 | radix = last_radix; | 1576 | radix = last_radix; |
1577 | bytesperword = last_bytesperword; | 1577 | bytesperword = last_bytesperword; |
1578 | repeat = last_repeat; | 1578 | repeat = last_repeat; |
1579 | mdcount = ((repeat * bytesperword) + 15) / 16; | 1579 | mdcount = ((repeat * bytesperword) + 15) / 16; |
1580 | } | 1580 | } |
1581 | 1581 | ||
1582 | if (argc) { | 1582 | if (argc) { |
1583 | unsigned long val; | 1583 | unsigned long val; |
1584 | int diag, nextarg = 1; | 1584 | int diag, nextarg = 1; |
1585 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, | 1585 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, |
1586 | &offset, NULL); | 1586 | &offset, NULL); |
1587 | if (diag) | 1587 | if (diag) |
1588 | return diag; | 1588 | return diag; |
1589 | if (argc > nextarg+2) | 1589 | if (argc > nextarg+2) |
1590 | return KDB_ARGCOUNT; | 1590 | return KDB_ARGCOUNT; |
1591 | 1591 | ||
1592 | if (argc >= nextarg) { | 1592 | if (argc >= nextarg) { |
1593 | diag = kdbgetularg(argv[nextarg], &val); | 1593 | diag = kdbgetularg(argv[nextarg], &val); |
1594 | if (!diag) { | 1594 | if (!diag) { |
1595 | mdcount = (int) val; | 1595 | mdcount = (int) val; |
1596 | repeat = mdcount * 16 / bytesperword; | 1596 | repeat = mdcount * 16 / bytesperword; |
1597 | } | 1597 | } |
1598 | } | 1598 | } |
1599 | if (argc >= nextarg+1) { | 1599 | if (argc >= nextarg+1) { |
1600 | diag = kdbgetularg(argv[nextarg+1], &val); | 1600 | diag = kdbgetularg(argv[nextarg+1], &val); |
1601 | if (!diag) | 1601 | if (!diag) |
1602 | radix = (int) val; | 1602 | radix = (int) val; |
1603 | } | 1603 | } |
1604 | } | 1604 | } |
1605 | 1605 | ||
1606 | if (strcmp(argv[0], "mdr") == 0) | 1606 | if (strcmp(argv[0], "mdr") == 0) |
1607 | return kdb_mdr(addr, mdcount); | 1607 | return kdb_mdr(addr, mdcount); |
1608 | 1608 | ||
1609 | switch (radix) { | 1609 | switch (radix) { |
1610 | case 10: | 1610 | case 10: |
1611 | fmtchar = 'd'; | 1611 | fmtchar = 'd'; |
1612 | break; | 1612 | break; |
1613 | case 16: | 1613 | case 16: |
1614 | fmtchar = 'x'; | 1614 | fmtchar = 'x'; |
1615 | break; | 1615 | break; |
1616 | case 8: | 1616 | case 8: |
1617 | fmtchar = 'o'; | 1617 | fmtchar = 'o'; |
1618 | break; | 1618 | break; |
1619 | default: | 1619 | default: |
1620 | return KDB_BADRADIX; | 1620 | return KDB_BADRADIX; |
1621 | } | 1621 | } |
1622 | 1622 | ||
1623 | last_radix = radix; | 1623 | last_radix = radix; |
1624 | 1624 | ||
1625 | if (bytesperword > KDB_WORD_SIZE) | 1625 | if (bytesperword > KDB_WORD_SIZE) |
1626 | return KDB_BADWIDTH; | 1626 | return KDB_BADWIDTH; |
1627 | 1627 | ||
1628 | switch (bytesperword) { | 1628 | switch (bytesperword) { |
1629 | case 8: | 1629 | case 8: |
1630 | sprintf(fmtstr, "%%16.16l%c ", fmtchar); | 1630 | sprintf(fmtstr, "%%16.16l%c ", fmtchar); |
1631 | break; | 1631 | break; |
1632 | case 4: | 1632 | case 4: |
1633 | sprintf(fmtstr, "%%8.8l%c ", fmtchar); | 1633 | sprintf(fmtstr, "%%8.8l%c ", fmtchar); |
1634 | break; | 1634 | break; |
1635 | case 2: | 1635 | case 2: |
1636 | sprintf(fmtstr, "%%4.4l%c ", fmtchar); | 1636 | sprintf(fmtstr, "%%4.4l%c ", fmtchar); |
1637 | break; | 1637 | break; |
1638 | case 1: | 1638 | case 1: |
1639 | sprintf(fmtstr, "%%2.2l%c ", fmtchar); | 1639 | sprintf(fmtstr, "%%2.2l%c ", fmtchar); |
1640 | break; | 1640 | break; |
1641 | default: | 1641 | default: |
1642 | return KDB_BADWIDTH; | 1642 | return KDB_BADWIDTH; |
1643 | } | 1643 | } |
1644 | 1644 | ||
1645 | last_repeat = repeat; | 1645 | last_repeat = repeat; |
1646 | last_bytesperword = bytesperword; | 1646 | last_bytesperword = bytesperword; |
1647 | 1647 | ||
1648 | if (strcmp(argv[0], "mds") == 0) { | 1648 | if (strcmp(argv[0], "mds") == 0) { |
1649 | symbolic = 1; | 1649 | symbolic = 1; |
1650 | /* Do not save these changes as last_*, they are temporary mds | 1650 | /* Do not save these changes as last_*, they are temporary mds |
1651 | * overrides. | 1651 | * overrides. |
1652 | */ | 1652 | */ |
1653 | bytesperword = KDB_WORD_SIZE; | 1653 | bytesperword = KDB_WORD_SIZE; |
1654 | repeat = mdcount; | 1654 | repeat = mdcount; |
1655 | kdbgetintenv("NOSECT", &nosect); | 1655 | kdbgetintenv("NOSECT", &nosect); |
1656 | } | 1656 | } |
1657 | 1657 | ||
1658 | /* Round address down modulo BYTESPERWORD */ | 1658 | /* Round address down modulo BYTESPERWORD */ |
1659 | 1659 | ||
1660 | addr &= ~(bytesperword-1); | 1660 | addr &= ~(bytesperword-1); |
1661 | 1661 | ||
1662 | while (repeat > 0) { | 1662 | while (repeat > 0) { |
1663 | unsigned long a; | 1663 | unsigned long a; |
1664 | int n, z, num = (symbolic ? 1 : (16 / bytesperword)); | 1664 | int n, z, num = (symbolic ? 1 : (16 / bytesperword)); |
1665 | 1665 | ||
1666 | if (KDB_FLAG(CMD_INTERRUPT)) | 1666 | if (KDB_FLAG(CMD_INTERRUPT)) |
1667 | return 0; | 1667 | return 0; |
1668 | for (a = addr, z = 0; z < repeat; a += bytesperword, ++z) { | 1668 | for (a = addr, z = 0; z < repeat; a += bytesperword, ++z) { |
1669 | if (phys) { | 1669 | if (phys) { |
1670 | if (kdb_getphysword(&word, a, bytesperword) | 1670 | if (kdb_getphysword(&word, a, bytesperword) |
1671 | || word) | 1671 | || word) |
1672 | break; | 1672 | break; |
1673 | } else if (kdb_getword(&word, a, bytesperword) || word) | 1673 | } else if (kdb_getword(&word, a, bytesperword) || word) |
1674 | break; | 1674 | break; |
1675 | } | 1675 | } |
1676 | n = min(num, repeat); | 1676 | n = min(num, repeat); |
1677 | kdb_md_line(fmtstr, addr, symbolic, nosect, bytesperword, | 1677 | kdb_md_line(fmtstr, addr, symbolic, nosect, bytesperword, |
1678 | num, repeat, phys); | 1678 | num, repeat, phys); |
1679 | addr += bytesperword * n; | 1679 | addr += bytesperword * n; |
1680 | repeat -= n; | 1680 | repeat -= n; |
1681 | z = (z + num - 1) / num; | 1681 | z = (z + num - 1) / num; |
1682 | if (z > 2) { | 1682 | if (z > 2) { |
1683 | int s = num * (z-2); | 1683 | int s = num * (z-2); |
1684 | kdb_printf(kdb_machreg_fmt0 "-" kdb_machreg_fmt0 | 1684 | kdb_printf(kdb_machreg_fmt0 "-" kdb_machreg_fmt0 |
1685 | " zero suppressed\n", | 1685 | " zero suppressed\n", |
1686 | addr, addr + bytesperword * s - 1); | 1686 | addr, addr + bytesperword * s - 1); |
1687 | addr += bytesperword * s; | 1687 | addr += bytesperword * s; |
1688 | repeat -= s; | 1688 | repeat -= s; |
1689 | } | 1689 | } |
1690 | } | 1690 | } |
1691 | last_addr = addr; | 1691 | last_addr = addr; |
1692 | 1692 | ||
1693 | return 0; | 1693 | return 0; |
1694 | } | 1694 | } |
1695 | 1695 | ||
1696 | /* | 1696 | /* |
1697 | * kdb_mm - This function implements the 'mm' command. | 1697 | * kdb_mm - This function implements the 'mm' command. |
1698 | * mm address-expression new-value | 1698 | * mm address-expression new-value |
1699 | * Remarks: | 1699 | * Remarks: |
1700 | * mm works on machine words, mmW works on bytes. | 1700 | * mm works on machine words, mmW works on bytes. |
1701 | */ | 1701 | */ |
1702 | static int kdb_mm(int argc, const char **argv) | 1702 | static int kdb_mm(int argc, const char **argv) |
1703 | { | 1703 | { |
1704 | int diag; | 1704 | int diag; |
1705 | unsigned long addr; | 1705 | unsigned long addr; |
1706 | long offset = 0; | 1706 | long offset = 0; |
1707 | unsigned long contents; | 1707 | unsigned long contents; |
1708 | int nextarg; | 1708 | int nextarg; |
1709 | int width; | 1709 | int width; |
1710 | 1710 | ||
1711 | if (argv[0][2] && !isdigit(argv[0][2])) | 1711 | if (argv[0][2] && !isdigit(argv[0][2])) |
1712 | return KDB_NOTFOUND; | 1712 | return KDB_NOTFOUND; |
1713 | 1713 | ||
1714 | if (argc < 2) | 1714 | if (argc < 2) |
1715 | return KDB_ARGCOUNT; | 1715 | return KDB_ARGCOUNT; |
1716 | 1716 | ||
1717 | nextarg = 1; | 1717 | nextarg = 1; |
1718 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL); | 1718 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL); |
1719 | if (diag) | 1719 | if (diag) |
1720 | return diag; | 1720 | return diag; |
1721 | 1721 | ||
1722 | if (nextarg > argc) | 1722 | if (nextarg > argc) |
1723 | return KDB_ARGCOUNT; | 1723 | return KDB_ARGCOUNT; |
1724 | diag = kdbgetaddrarg(argc, argv, &nextarg, &contents, NULL, NULL); | 1724 | diag = kdbgetaddrarg(argc, argv, &nextarg, &contents, NULL, NULL); |
1725 | if (diag) | 1725 | if (diag) |
1726 | return diag; | 1726 | return diag; |
1727 | 1727 | ||
1728 | if (nextarg != argc + 1) | 1728 | if (nextarg != argc + 1) |
1729 | return KDB_ARGCOUNT; | 1729 | return KDB_ARGCOUNT; |
1730 | 1730 | ||
1731 | width = argv[0][2] ? (argv[0][2] - '0') : (KDB_WORD_SIZE); | 1731 | width = argv[0][2] ? (argv[0][2] - '0') : (KDB_WORD_SIZE); |
1732 | diag = kdb_putword(addr, contents, width); | 1732 | diag = kdb_putword(addr, contents, width); |
1733 | if (diag) | 1733 | if (diag) |
1734 | return diag; | 1734 | return diag; |
1735 | 1735 | ||
1736 | kdb_printf(kdb_machreg_fmt " = " kdb_machreg_fmt "\n", addr, contents); | 1736 | kdb_printf(kdb_machreg_fmt " = " kdb_machreg_fmt "\n", addr, contents); |
1737 | 1737 | ||
1738 | return 0; | 1738 | return 0; |
1739 | } | 1739 | } |
1740 | 1740 | ||
1741 | /* | 1741 | /* |
1742 | * kdb_go - This function implements the 'go' command. | 1742 | * kdb_go - This function implements the 'go' command. |
1743 | * go [address-expression] | 1743 | * go [address-expression] |
1744 | */ | 1744 | */ |
1745 | static int kdb_go(int argc, const char **argv) | 1745 | static int kdb_go(int argc, const char **argv) |
1746 | { | 1746 | { |
1747 | unsigned long addr; | 1747 | unsigned long addr; |
1748 | int diag; | 1748 | int diag; |
1749 | int nextarg; | 1749 | int nextarg; |
1750 | long offset; | 1750 | long offset; |
1751 | 1751 | ||
1752 | if (raw_smp_processor_id() != kdb_initial_cpu) { | 1752 | if (raw_smp_processor_id() != kdb_initial_cpu) { |
1753 | kdb_printf("go must execute on the entry cpu, " | 1753 | kdb_printf("go must execute on the entry cpu, " |
1754 | "please use \"cpu %d\" and then execute go\n", | 1754 | "please use \"cpu %d\" and then execute go\n", |
1755 | kdb_initial_cpu); | 1755 | kdb_initial_cpu); |
1756 | return KDB_BADCPUNUM; | 1756 | return KDB_BADCPUNUM; |
1757 | } | 1757 | } |
1758 | if (argc == 1) { | 1758 | if (argc == 1) { |
1759 | nextarg = 1; | 1759 | nextarg = 1; |
1760 | diag = kdbgetaddrarg(argc, argv, &nextarg, | 1760 | diag = kdbgetaddrarg(argc, argv, &nextarg, |
1761 | &addr, &offset, NULL); | 1761 | &addr, &offset, NULL); |
1762 | if (diag) | 1762 | if (diag) |
1763 | return diag; | 1763 | return diag; |
1764 | } else if (argc) { | 1764 | } else if (argc) { |
1765 | return KDB_ARGCOUNT; | 1765 | return KDB_ARGCOUNT; |
1766 | } | 1766 | } |
1767 | 1767 | ||
1768 | diag = KDB_CMD_GO; | 1768 | diag = KDB_CMD_GO; |
1769 | if (KDB_FLAG(CATASTROPHIC)) { | 1769 | if (KDB_FLAG(CATASTROPHIC)) { |
1770 | kdb_printf("Catastrophic error detected\n"); | 1770 | kdb_printf("Catastrophic error detected\n"); |
1771 | kdb_printf("kdb_continue_catastrophic=%d, ", | 1771 | kdb_printf("kdb_continue_catastrophic=%d, ", |
1772 | kdb_continue_catastrophic); | 1772 | kdb_continue_catastrophic); |
1773 | if (kdb_continue_catastrophic == 0 && kdb_go_count++ == 0) { | 1773 | if (kdb_continue_catastrophic == 0 && kdb_go_count++ == 0) { |
1774 | kdb_printf("type go a second time if you really want " | 1774 | kdb_printf("type go a second time if you really want " |
1775 | "to continue\n"); | 1775 | "to continue\n"); |
1776 | return 0; | 1776 | return 0; |
1777 | } | 1777 | } |
1778 | if (kdb_continue_catastrophic == 2) { | 1778 | if (kdb_continue_catastrophic == 2) { |
1779 | kdb_printf("forcing reboot\n"); | 1779 | kdb_printf("forcing reboot\n"); |
1780 | kdb_reboot(0, NULL); | 1780 | kdb_reboot(0, NULL); |
1781 | } | 1781 | } |
1782 | kdb_printf("attempting to continue\n"); | 1782 | kdb_printf("attempting to continue\n"); |
1783 | } | 1783 | } |
1784 | return diag; | 1784 | return diag; |
1785 | } | 1785 | } |
1786 | 1786 | ||
1787 | /* | 1787 | /* |
1788 | * kdb_rd - This function implements the 'rd' command. | 1788 | * kdb_rd - This function implements the 'rd' command. |
1789 | */ | 1789 | */ |
1790 | static int kdb_rd(int argc, const char **argv) | 1790 | static int kdb_rd(int argc, const char **argv) |
1791 | { | 1791 | { |
1792 | int len = kdb_check_regs(); | 1792 | int len = kdb_check_regs(); |
1793 | #if DBG_MAX_REG_NUM > 0 | 1793 | #if DBG_MAX_REG_NUM > 0 |
1794 | int i; | 1794 | int i; |
1795 | char *rname; | 1795 | char *rname; |
1796 | int rsize; | 1796 | int rsize; |
1797 | u64 reg64; | 1797 | u64 reg64; |
1798 | u32 reg32; | 1798 | u32 reg32; |
1799 | u16 reg16; | 1799 | u16 reg16; |
1800 | u8 reg8; | 1800 | u8 reg8; |
1801 | 1801 | ||
1802 | if (len) | 1802 | if (len) |
1803 | return len; | 1803 | return len; |
1804 | 1804 | ||
1805 | for (i = 0; i < DBG_MAX_REG_NUM; i++) { | 1805 | for (i = 0; i < DBG_MAX_REG_NUM; i++) { |
1806 | rsize = dbg_reg_def[i].size * 2; | 1806 | rsize = dbg_reg_def[i].size * 2; |
1807 | if (rsize > 16) | 1807 | if (rsize > 16) |
1808 | rsize = 2; | 1808 | rsize = 2; |
1809 | if (len + strlen(dbg_reg_def[i].name) + 4 + rsize > 80) { | 1809 | if (len + strlen(dbg_reg_def[i].name) + 4 + rsize > 80) { |
1810 | len = 0; | 1810 | len = 0; |
1811 | kdb_printf("\n"); | 1811 | kdb_printf("\n"); |
1812 | } | 1812 | } |
1813 | if (len) | 1813 | if (len) |
1814 | len += kdb_printf(" "); | 1814 | len += kdb_printf(" "); |
1815 | switch(dbg_reg_def[i].size * 8) { | 1815 | switch(dbg_reg_def[i].size * 8) { |
1816 | case 8: | 1816 | case 8: |
1817 | rname = dbg_get_reg(i, ®8, kdb_current_regs); | 1817 | rname = dbg_get_reg(i, ®8, kdb_current_regs); |
1818 | if (!rname) | 1818 | if (!rname) |
1819 | break; | 1819 | break; |
1820 | len += kdb_printf("%s: %02x", rname, reg8); | 1820 | len += kdb_printf("%s: %02x", rname, reg8); |
1821 | break; | 1821 | break; |
1822 | case 16: | 1822 | case 16: |
1823 | rname = dbg_get_reg(i, ®16, kdb_current_regs); | 1823 | rname = dbg_get_reg(i, ®16, kdb_current_regs); |
1824 | if (!rname) | 1824 | if (!rname) |
1825 | break; | 1825 | break; |
1826 | len += kdb_printf("%s: %04x", rname, reg16); | 1826 | len += kdb_printf("%s: %04x", rname, reg16); |
1827 | break; | 1827 | break; |
1828 | case 32: | 1828 | case 32: |
1829 | rname = dbg_get_reg(i, ®32, kdb_current_regs); | 1829 | rname = dbg_get_reg(i, ®32, kdb_current_regs); |
1830 | if (!rname) | 1830 | if (!rname) |
1831 | break; | 1831 | break; |
1832 | len += kdb_printf("%s: %08x", rname, reg32); | 1832 | len += kdb_printf("%s: %08x", rname, reg32); |
1833 | break; | 1833 | break; |
1834 | case 64: | 1834 | case 64: |
1835 | rname = dbg_get_reg(i, ®64, kdb_current_regs); | 1835 | rname = dbg_get_reg(i, ®64, kdb_current_regs); |
1836 | if (!rname) | 1836 | if (!rname) |
1837 | break; | 1837 | break; |
1838 | len += kdb_printf("%s: %016llx", rname, reg64); | 1838 | len += kdb_printf("%s: %016llx", rname, reg64); |
1839 | break; | 1839 | break; |
1840 | default: | 1840 | default: |
1841 | len += kdb_printf("%s: ??", dbg_reg_def[i].name); | 1841 | len += kdb_printf("%s: ??", dbg_reg_def[i].name); |
1842 | } | 1842 | } |
1843 | } | 1843 | } |
1844 | kdb_printf("\n"); | 1844 | kdb_printf("\n"); |
1845 | #else | 1845 | #else |
1846 | if (len) | 1846 | if (len) |
1847 | return len; | 1847 | return len; |
1848 | 1848 | ||
1849 | kdb_dumpregs(kdb_current_regs); | 1849 | kdb_dumpregs(kdb_current_regs); |
1850 | #endif | 1850 | #endif |
1851 | return 0; | 1851 | return 0; |
1852 | } | 1852 | } |
1853 | 1853 | ||
1854 | /* | 1854 | /* |
1855 | * kdb_rm - This function implements the 'rm' (register modify) command. | 1855 | * kdb_rm - This function implements the 'rm' (register modify) command. |
1856 | * rm register-name new-contents | 1856 | * rm register-name new-contents |
1857 | * Remarks: | 1857 | * Remarks: |
1858 | * Allows register modification with the same restrictions as gdb | 1858 | * Allows register modification with the same restrictions as gdb |
1859 | */ | 1859 | */ |
1860 | static int kdb_rm(int argc, const char **argv) | 1860 | static int kdb_rm(int argc, const char **argv) |
1861 | { | 1861 | { |
1862 | #if DBG_MAX_REG_NUM > 0 | 1862 | #if DBG_MAX_REG_NUM > 0 |
1863 | int diag; | 1863 | int diag; |
1864 | const char *rname; | 1864 | const char *rname; |
1865 | int i; | 1865 | int i; |
1866 | u64 reg64; | 1866 | u64 reg64; |
1867 | u32 reg32; | 1867 | u32 reg32; |
1868 | u16 reg16; | 1868 | u16 reg16; |
1869 | u8 reg8; | 1869 | u8 reg8; |
1870 | 1870 | ||
1871 | if (argc != 2) | 1871 | if (argc != 2) |
1872 | return KDB_ARGCOUNT; | 1872 | return KDB_ARGCOUNT; |
1873 | /* | 1873 | /* |
1874 | * Allow presence or absence of leading '%' symbol. | 1874 | * Allow presence or absence of leading '%' symbol. |
1875 | */ | 1875 | */ |
1876 | rname = argv[1]; | 1876 | rname = argv[1]; |
1877 | if (*rname == '%') | 1877 | if (*rname == '%') |
1878 | rname++; | 1878 | rname++; |
1879 | 1879 | ||
1880 | diag = kdbgetu64arg(argv[2], ®64); | 1880 | diag = kdbgetu64arg(argv[2], ®64); |
1881 | if (diag) | 1881 | if (diag) |
1882 | return diag; | 1882 | return diag; |
1883 | 1883 | ||
1884 | diag = kdb_check_regs(); | 1884 | diag = kdb_check_regs(); |
1885 | if (diag) | 1885 | if (diag) |
1886 | return diag; | 1886 | return diag; |
1887 | 1887 | ||
1888 | diag = KDB_BADREG; | 1888 | diag = KDB_BADREG; |
1889 | for (i = 0; i < DBG_MAX_REG_NUM; i++) { | 1889 | for (i = 0; i < DBG_MAX_REG_NUM; i++) { |
1890 | if (strcmp(rname, dbg_reg_def[i].name) == 0) { | 1890 | if (strcmp(rname, dbg_reg_def[i].name) == 0) { |
1891 | diag = 0; | 1891 | diag = 0; |
1892 | break; | 1892 | break; |
1893 | } | 1893 | } |
1894 | } | 1894 | } |
1895 | if (!diag) { | 1895 | if (!diag) { |
1896 | switch(dbg_reg_def[i].size * 8) { | 1896 | switch(dbg_reg_def[i].size * 8) { |
1897 | case 8: | 1897 | case 8: |
1898 | reg8 = reg64; | 1898 | reg8 = reg64; |
1899 | dbg_set_reg(i, ®8, kdb_current_regs); | 1899 | dbg_set_reg(i, ®8, kdb_current_regs); |
1900 | break; | 1900 | break; |
1901 | case 16: | 1901 | case 16: |
1902 | reg16 = reg64; | 1902 | reg16 = reg64; |
1903 | dbg_set_reg(i, ®16, kdb_current_regs); | 1903 | dbg_set_reg(i, ®16, kdb_current_regs); |
1904 | break; | 1904 | break; |
1905 | case 32: | 1905 | case 32: |
1906 | reg32 = reg64; | 1906 | reg32 = reg64; |
1907 | dbg_set_reg(i, ®32, kdb_current_regs); | 1907 | dbg_set_reg(i, ®32, kdb_current_regs); |
1908 | break; | 1908 | break; |
1909 | case 64: | 1909 | case 64: |
1910 | dbg_set_reg(i, ®64, kdb_current_regs); | 1910 | dbg_set_reg(i, ®64, kdb_current_regs); |
1911 | break; | 1911 | break; |
1912 | } | 1912 | } |
1913 | } | 1913 | } |
1914 | return diag; | 1914 | return diag; |
1915 | #else | 1915 | #else |
1916 | kdb_printf("ERROR: Register set currently not implemented\n"); | 1916 | kdb_printf("ERROR: Register set currently not implemented\n"); |
1917 | return 0; | 1917 | return 0; |
1918 | #endif | 1918 | #endif |
1919 | } | 1919 | } |
1920 | 1920 | ||
1921 | #if defined(CONFIG_MAGIC_SYSRQ) | 1921 | #if defined(CONFIG_MAGIC_SYSRQ) |
1922 | /* | 1922 | /* |
1923 | * kdb_sr - This function implements the 'sr' (SYSRQ key) command | 1923 | * kdb_sr - This function implements the 'sr' (SYSRQ key) command |
1924 | * which interfaces to the soi-disant MAGIC SYSRQ functionality. | 1924 | * which interfaces to the soi-disant MAGIC SYSRQ functionality. |
1925 | * sr <magic-sysrq-code> | 1925 | * sr <magic-sysrq-code> |
1926 | */ | 1926 | */ |
1927 | static int kdb_sr(int argc, const char **argv) | 1927 | static int kdb_sr(int argc, const char **argv) |
1928 | { | 1928 | { |
1929 | if (argc != 1) | 1929 | if (argc != 1) |
1930 | return KDB_ARGCOUNT; | 1930 | return KDB_ARGCOUNT; |
1931 | kdb_trap_printk++; | 1931 | kdb_trap_printk++; |
1932 | __handle_sysrq(*argv[1], false); | 1932 | __handle_sysrq(*argv[1], false); |
1933 | kdb_trap_printk--; | 1933 | kdb_trap_printk--; |
1934 | 1934 | ||
1935 | return 0; | 1935 | return 0; |
1936 | } | 1936 | } |
1937 | #endif /* CONFIG_MAGIC_SYSRQ */ | 1937 | #endif /* CONFIG_MAGIC_SYSRQ */ |
1938 | 1938 | ||
1939 | /* | 1939 | /* |
1940 | * kdb_ef - This function implements the 'regs' (display exception | 1940 | * kdb_ef - This function implements the 'regs' (display exception |
1941 | * frame) command. This command takes an address and expects to | 1941 | * frame) command. This command takes an address and expects to |
1942 | * find an exception frame at that address, formats and prints | 1942 | * find an exception frame at that address, formats and prints |
1943 | * it. | 1943 | * it. |
1944 | * regs address-expression | 1944 | * regs address-expression |
1945 | * Remarks: | 1945 | * Remarks: |
1946 | * Not done yet. | 1946 | * Not done yet. |
1947 | */ | 1947 | */ |
1948 | static int kdb_ef(int argc, const char **argv) | 1948 | static int kdb_ef(int argc, const char **argv) |
1949 | { | 1949 | { |
1950 | int diag; | 1950 | int diag; |
1951 | unsigned long addr; | 1951 | unsigned long addr; |
1952 | long offset; | 1952 | long offset; |
1953 | int nextarg; | 1953 | int nextarg; |
1954 | 1954 | ||
1955 | if (argc != 1) | 1955 | if (argc != 1) |
1956 | return KDB_ARGCOUNT; | 1956 | return KDB_ARGCOUNT; |
1957 | 1957 | ||
1958 | nextarg = 1; | 1958 | nextarg = 1; |
1959 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL); | 1959 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL); |
1960 | if (diag) | 1960 | if (diag) |
1961 | return diag; | 1961 | return diag; |
1962 | show_regs((struct pt_regs *)addr); | 1962 | show_regs((struct pt_regs *)addr); |
1963 | return 0; | 1963 | return 0; |
1964 | } | 1964 | } |
1965 | 1965 | ||
1966 | #if defined(CONFIG_MODULES) | 1966 | #if defined(CONFIG_MODULES) |
1967 | /* | 1967 | /* |
1968 | * kdb_lsmod - This function implements the 'lsmod' command. Lists | 1968 | * kdb_lsmod - This function implements the 'lsmod' command. Lists |
1969 | * currently loaded kernel modules. | 1969 | * currently loaded kernel modules. |
1970 | * Mostly taken from userland lsmod. | 1970 | * Mostly taken from userland lsmod. |
1971 | */ | 1971 | */ |
1972 | static int kdb_lsmod(int argc, const char **argv) | 1972 | static int kdb_lsmod(int argc, const char **argv) |
1973 | { | 1973 | { |
1974 | struct module *mod; | 1974 | struct module *mod; |
1975 | 1975 | ||
1976 | if (argc != 0) | 1976 | if (argc != 0) |
1977 | return KDB_ARGCOUNT; | 1977 | return KDB_ARGCOUNT; |
1978 | 1978 | ||
1979 | kdb_printf("Module Size modstruct Used by\n"); | 1979 | kdb_printf("Module Size modstruct Used by\n"); |
1980 | list_for_each_entry(mod, kdb_modules, list) { | 1980 | list_for_each_entry(mod, kdb_modules, list) { |
1981 | 1981 | ||
1982 | kdb_printf("%-20s%8u 0x%p ", mod->name, | 1982 | kdb_printf("%-20s%8u 0x%p ", mod->name, |
1983 | mod->core_size, (void *)mod); | 1983 | mod->core_size, (void *)mod); |
1984 | #ifdef CONFIG_MODULE_UNLOAD | 1984 | #ifdef CONFIG_MODULE_UNLOAD |
1985 | kdb_printf("%4d ", module_refcount(mod)); | 1985 | kdb_printf("%4d ", module_refcount(mod)); |
1986 | #endif | 1986 | #endif |
1987 | if (mod->state == MODULE_STATE_GOING) | 1987 | if (mod->state == MODULE_STATE_GOING) |
1988 | kdb_printf(" (Unloading)"); | 1988 | kdb_printf(" (Unloading)"); |
1989 | else if (mod->state == MODULE_STATE_COMING) | 1989 | else if (mod->state == MODULE_STATE_COMING) |
1990 | kdb_printf(" (Loading)"); | 1990 | kdb_printf(" (Loading)"); |
1991 | else | 1991 | else |
1992 | kdb_printf(" (Live)"); | 1992 | kdb_printf(" (Live)"); |
1993 | kdb_printf(" 0x%p", mod->module_core); | 1993 | kdb_printf(" 0x%p", mod->module_core); |
1994 | 1994 | ||
1995 | #ifdef CONFIG_MODULE_UNLOAD | 1995 | #ifdef CONFIG_MODULE_UNLOAD |
1996 | { | 1996 | { |
1997 | struct module_use *use; | 1997 | struct module_use *use; |
1998 | kdb_printf(" [ "); | 1998 | kdb_printf(" [ "); |
1999 | list_for_each_entry(use, &mod->source_list, | 1999 | list_for_each_entry(use, &mod->source_list, |
2000 | source_list) | 2000 | source_list) |
2001 | kdb_printf("%s ", use->target->name); | 2001 | kdb_printf("%s ", use->target->name); |
2002 | kdb_printf("]\n"); | 2002 | kdb_printf("]\n"); |
2003 | } | 2003 | } |
2004 | #endif | 2004 | #endif |
2005 | } | 2005 | } |
2006 | 2006 | ||
2007 | return 0; | 2007 | return 0; |
2008 | } | 2008 | } |
2009 | 2009 | ||
2010 | #endif /* CONFIG_MODULES */ | 2010 | #endif /* CONFIG_MODULES */ |
2011 | 2011 | ||
2012 | /* | 2012 | /* |
2013 | * kdb_env - This function implements the 'env' command. Display the | 2013 | * kdb_env - This function implements the 'env' command. Display the |
2014 | * current environment variables. | 2014 | * current environment variables. |
2015 | */ | 2015 | */ |
2016 | 2016 | ||
2017 | static int kdb_env(int argc, const char **argv) | 2017 | static int kdb_env(int argc, const char **argv) |
2018 | { | 2018 | { |
2019 | int i; | 2019 | int i; |
2020 | 2020 | ||
2021 | for (i = 0; i < __nenv; i++) { | 2021 | for (i = 0; i < __nenv; i++) { |
2022 | if (__env[i]) | 2022 | if (__env[i]) |
2023 | kdb_printf("%s\n", __env[i]); | 2023 | kdb_printf("%s\n", __env[i]); |
2024 | } | 2024 | } |
2025 | 2025 | ||
2026 | if (KDB_DEBUG(MASK)) | 2026 | if (KDB_DEBUG(MASK)) |
2027 | kdb_printf("KDBFLAGS=0x%x\n", kdb_flags); | 2027 | kdb_printf("KDBFLAGS=0x%x\n", kdb_flags); |
2028 | 2028 | ||
2029 | return 0; | 2029 | return 0; |
2030 | } | 2030 | } |
2031 | 2031 | ||
2032 | #ifdef CONFIG_PRINTK | 2032 | #ifdef CONFIG_PRINTK |
2033 | /* | 2033 | /* |
2034 | * kdb_dmesg - This function implements the 'dmesg' command to display | 2034 | * kdb_dmesg - This function implements the 'dmesg' command to display |
2035 | * the contents of the syslog buffer. | 2035 | * the contents of the syslog buffer. |
2036 | * dmesg [lines] [adjust] | 2036 | * dmesg [lines] [adjust] |
2037 | */ | 2037 | */ |
2038 | static int kdb_dmesg(int argc, const char **argv) | 2038 | static int kdb_dmesg(int argc, const char **argv) |
2039 | { | 2039 | { |
2040 | char *syslog_data[4], *start, *end, c = '\0', *p; | 2040 | char *syslog_data[4], *start, *end, c = '\0', *p; |
2041 | int diag, logging, logsize, lines = 0, adjust = 0, n; | 2041 | int diag, logging, logsize, lines = 0, adjust = 0, n; |
2042 | 2042 | ||
2043 | if (argc > 2) | 2043 | if (argc > 2) |
2044 | return KDB_ARGCOUNT; | 2044 | return KDB_ARGCOUNT; |
2045 | if (argc) { | 2045 | if (argc) { |
2046 | char *cp; | 2046 | char *cp; |
2047 | lines = simple_strtol(argv[1], &cp, 0); | 2047 | lines = simple_strtol(argv[1], &cp, 0); |
2048 | if (*cp) | 2048 | if (*cp) |
2049 | lines = 0; | 2049 | lines = 0; |
2050 | if (argc > 1) { | 2050 | if (argc > 1) { |
2051 | adjust = simple_strtoul(argv[2], &cp, 0); | 2051 | adjust = simple_strtoul(argv[2], &cp, 0); |
2052 | if (*cp || adjust < 0) | 2052 | if (*cp || adjust < 0) |
2053 | adjust = 0; | 2053 | adjust = 0; |
2054 | } | 2054 | } |
2055 | } | 2055 | } |
2056 | 2056 | ||
2057 | /* disable LOGGING if set */ | 2057 | /* disable LOGGING if set */ |
2058 | diag = kdbgetintenv("LOGGING", &logging); | 2058 | diag = kdbgetintenv("LOGGING", &logging); |
2059 | if (!diag && logging) { | 2059 | if (!diag && logging) { |
2060 | const char *setargs[] = { "set", "LOGGING", "0" }; | 2060 | const char *setargs[] = { "set", "LOGGING", "0" }; |
2061 | kdb_set(2, setargs); | 2061 | kdb_set(2, setargs); |
2062 | } | 2062 | } |
2063 | 2063 | ||
2064 | /* syslog_data[0,1] physical start, end+1. syslog_data[2,3] | 2064 | /* syslog_data[0,1] physical start, end+1. syslog_data[2,3] |
2065 | * logical start, end+1. */ | 2065 | * logical start, end+1. */ |
2066 | kdb_syslog_data(syslog_data); | 2066 | kdb_syslog_data(syslog_data); |
2067 | if (syslog_data[2] == syslog_data[3]) | 2067 | if (syslog_data[2] == syslog_data[3]) |
2068 | return 0; | 2068 | return 0; |
2069 | logsize = syslog_data[1] - syslog_data[0]; | 2069 | logsize = syslog_data[1] - syslog_data[0]; |
2070 | start = syslog_data[2]; | 2070 | start = syslog_data[2]; |
2071 | end = syslog_data[3]; | 2071 | end = syslog_data[3]; |
2072 | #define KDB_WRAP(p) (((p - syslog_data[0]) % logsize) + syslog_data[0]) | 2072 | #define KDB_WRAP(p) (((p - syslog_data[0]) % logsize) + syslog_data[0]) |
2073 | for (n = 0, p = start; p < end; ++p) { | 2073 | for (n = 0, p = start; p < end; ++p) { |
2074 | c = *KDB_WRAP(p); | 2074 | c = *KDB_WRAP(p); |
2075 | if (c == '\n') | 2075 | if (c == '\n') |
2076 | ++n; | 2076 | ++n; |
2077 | } | 2077 | } |
2078 | if (c != '\n') | 2078 | if (c != '\n') |
2079 | ++n; | 2079 | ++n; |
2080 | if (lines < 0) { | 2080 | if (lines < 0) { |
2081 | if (adjust >= n) | 2081 | if (adjust >= n) |
2082 | kdb_printf("buffer only contains %d lines, nothing " | 2082 | kdb_printf("buffer only contains %d lines, nothing " |
2083 | "printed\n", n); | 2083 | "printed\n", n); |
2084 | else if (adjust - lines >= n) | 2084 | else if (adjust - lines >= n) |
2085 | kdb_printf("buffer only contains %d lines, last %d " | 2085 | kdb_printf("buffer only contains %d lines, last %d " |
2086 | "lines printed\n", n, n - adjust); | 2086 | "lines printed\n", n, n - adjust); |
2087 | if (adjust) { | 2087 | if (adjust) { |
2088 | for (; start < end && adjust; ++start) { | 2088 | for (; start < end && adjust; ++start) { |
2089 | if (*KDB_WRAP(start) == '\n') | 2089 | if (*KDB_WRAP(start) == '\n') |
2090 | --adjust; | 2090 | --adjust; |
2091 | } | 2091 | } |
2092 | if (start < end) | 2092 | if (start < end) |
2093 | ++start; | 2093 | ++start; |
2094 | } | 2094 | } |
2095 | for (p = start; p < end && lines; ++p) { | 2095 | for (p = start; p < end && lines; ++p) { |
2096 | if (*KDB_WRAP(p) == '\n') | 2096 | if (*KDB_WRAP(p) == '\n') |
2097 | ++lines; | 2097 | ++lines; |
2098 | } | 2098 | } |
2099 | end = p; | 2099 | end = p; |
2100 | } else if (lines > 0) { | 2100 | } else if (lines > 0) { |
2101 | int skip = n - (adjust + lines); | 2101 | int skip = n - (adjust + lines); |
2102 | if (adjust >= n) { | 2102 | if (adjust >= n) { |
2103 | kdb_printf("buffer only contains %d lines, " | 2103 | kdb_printf("buffer only contains %d lines, " |
2104 | "nothing printed\n", n); | 2104 | "nothing printed\n", n); |
2105 | skip = n; | 2105 | skip = n; |
2106 | } else if (skip < 0) { | 2106 | } else if (skip < 0) { |
2107 | lines += skip; | 2107 | lines += skip; |
2108 | skip = 0; | 2108 | skip = 0; |
2109 | kdb_printf("buffer only contains %d lines, first " | 2109 | kdb_printf("buffer only contains %d lines, first " |
2110 | "%d lines printed\n", n, lines); | 2110 | "%d lines printed\n", n, lines); |
2111 | } | 2111 | } |
2112 | for (; start < end && skip; ++start) { | 2112 | for (; start < end && skip; ++start) { |
2113 | if (*KDB_WRAP(start) == '\n') | 2113 | if (*KDB_WRAP(start) == '\n') |
2114 | --skip; | 2114 | --skip; |
2115 | } | 2115 | } |
2116 | for (p = start; p < end && lines; ++p) { | 2116 | for (p = start; p < end && lines; ++p) { |
2117 | if (*KDB_WRAP(p) == '\n') | 2117 | if (*KDB_WRAP(p) == '\n') |
2118 | --lines; | 2118 | --lines; |
2119 | } | 2119 | } |
2120 | end = p; | 2120 | end = p; |
2121 | } | 2121 | } |
2122 | /* Do a line at a time (max 200 chars) to reduce protocol overhead */ | 2122 | /* Do a line at a time (max 200 chars) to reduce protocol overhead */ |
2123 | c = '\n'; | 2123 | c = '\n'; |
2124 | while (start != end) { | 2124 | while (start != end) { |
2125 | char buf[201]; | 2125 | char buf[201]; |
2126 | p = buf; | 2126 | p = buf; |
2127 | if (KDB_FLAG(CMD_INTERRUPT)) | 2127 | if (KDB_FLAG(CMD_INTERRUPT)) |
2128 | return 0; | 2128 | return 0; |
2129 | while (start < end && (c = *KDB_WRAP(start)) && | 2129 | while (start < end && (c = *KDB_WRAP(start)) && |
2130 | (p - buf) < sizeof(buf)-1) { | 2130 | (p - buf) < sizeof(buf)-1) { |
2131 | ++start; | 2131 | ++start; |
2132 | *p++ = c; | 2132 | *p++ = c; |
2133 | if (c == '\n') | 2133 | if (c == '\n') |
2134 | break; | 2134 | break; |
2135 | } | 2135 | } |
2136 | *p = '\0'; | 2136 | *p = '\0'; |
2137 | kdb_printf("%s", buf); | 2137 | kdb_printf("%s", buf); |
2138 | } | 2138 | } |
2139 | if (c != '\n') | 2139 | if (c != '\n') |
2140 | kdb_printf("\n"); | 2140 | kdb_printf("\n"); |
2141 | 2141 | ||
2142 | return 0; | 2142 | return 0; |
2143 | } | 2143 | } |
2144 | #endif /* CONFIG_PRINTK */ | 2144 | #endif /* CONFIG_PRINTK */ |
2145 | /* | 2145 | /* |
2146 | * kdb_cpu - This function implements the 'cpu' command. | 2146 | * kdb_cpu - This function implements the 'cpu' command. |
2147 | * cpu [<cpunum>] | 2147 | * cpu [<cpunum>] |
2148 | * Returns: | 2148 | * Returns: |
2149 | * KDB_CMD_CPU for success, a kdb diagnostic if error | 2149 | * KDB_CMD_CPU for success, a kdb diagnostic if error |
2150 | */ | 2150 | */ |
2151 | static void kdb_cpu_status(void) | 2151 | static void kdb_cpu_status(void) |
2152 | { | 2152 | { |
2153 | int i, start_cpu, first_print = 1; | 2153 | int i, start_cpu, first_print = 1; |
2154 | char state, prev_state = '?'; | 2154 | char state, prev_state = '?'; |
2155 | 2155 | ||
2156 | kdb_printf("Currently on cpu %d\n", raw_smp_processor_id()); | 2156 | kdb_printf("Currently on cpu %d\n", raw_smp_processor_id()); |
2157 | kdb_printf("Available cpus: "); | 2157 | kdb_printf("Available cpus: "); |
2158 | for (start_cpu = -1, i = 0; i < NR_CPUS; i++) { | 2158 | for (start_cpu = -1, i = 0; i < NR_CPUS; i++) { |
2159 | if (!cpu_online(i)) { | 2159 | if (!cpu_online(i)) { |
2160 | state = 'F'; /* cpu is offline */ | 2160 | state = 'F'; /* cpu is offline */ |
2161 | } else { | 2161 | } else { |
2162 | state = ' '; /* cpu is responding to kdb */ | 2162 | state = ' '; /* cpu is responding to kdb */ |
2163 | if (kdb_task_state_char(KDB_TSK(i)) == 'I') | 2163 | if (kdb_task_state_char(KDB_TSK(i)) == 'I') |
2164 | state = 'I'; /* idle task */ | 2164 | state = 'I'; /* idle task */ |
2165 | } | 2165 | } |
2166 | if (state != prev_state) { | 2166 | if (state != prev_state) { |
2167 | if (prev_state != '?') { | 2167 | if (prev_state != '?') { |
2168 | if (!first_print) | 2168 | if (!first_print) |
2169 | kdb_printf(", "); | 2169 | kdb_printf(", "); |
2170 | first_print = 0; | 2170 | first_print = 0; |
2171 | kdb_printf("%d", start_cpu); | 2171 | kdb_printf("%d", start_cpu); |
2172 | if (start_cpu < i-1) | 2172 | if (start_cpu < i-1) |
2173 | kdb_printf("-%d", i-1); | 2173 | kdb_printf("-%d", i-1); |
2174 | if (prev_state != ' ') | 2174 | if (prev_state != ' ') |
2175 | kdb_printf("(%c)", prev_state); | 2175 | kdb_printf("(%c)", prev_state); |
2176 | } | 2176 | } |
2177 | prev_state = state; | 2177 | prev_state = state; |
2178 | start_cpu = i; | 2178 | start_cpu = i; |
2179 | } | 2179 | } |
2180 | } | 2180 | } |
2181 | /* print the trailing cpus, ignoring them if they are all offline */ | 2181 | /* print the trailing cpus, ignoring them if they are all offline */ |
2182 | if (prev_state != 'F') { | 2182 | if (prev_state != 'F') { |
2183 | if (!first_print) | 2183 | if (!first_print) |
2184 | kdb_printf(", "); | 2184 | kdb_printf(", "); |
2185 | kdb_printf("%d", start_cpu); | 2185 | kdb_printf("%d", start_cpu); |
2186 | if (start_cpu < i-1) | 2186 | if (start_cpu < i-1) |
2187 | kdb_printf("-%d", i-1); | 2187 | kdb_printf("-%d", i-1); |
2188 | if (prev_state != ' ') | 2188 | if (prev_state != ' ') |
2189 | kdb_printf("(%c)", prev_state); | 2189 | kdb_printf("(%c)", prev_state); |
2190 | } | 2190 | } |
2191 | kdb_printf("\n"); | 2191 | kdb_printf("\n"); |
2192 | } | 2192 | } |
2193 | 2193 | ||
2194 | static int kdb_cpu(int argc, const char **argv) | 2194 | static int kdb_cpu(int argc, const char **argv) |
2195 | { | 2195 | { |
2196 | unsigned long cpunum; | 2196 | unsigned long cpunum; |
2197 | int diag; | 2197 | int diag; |
2198 | 2198 | ||
2199 | if (argc == 0) { | 2199 | if (argc == 0) { |
2200 | kdb_cpu_status(); | 2200 | kdb_cpu_status(); |
2201 | return 0; | 2201 | return 0; |
2202 | } | 2202 | } |
2203 | 2203 | ||
2204 | if (argc != 1) | 2204 | if (argc != 1) |
2205 | return KDB_ARGCOUNT; | 2205 | return KDB_ARGCOUNT; |
2206 | 2206 | ||
2207 | diag = kdbgetularg(argv[1], &cpunum); | 2207 | diag = kdbgetularg(argv[1], &cpunum); |
2208 | if (diag) | 2208 | if (diag) |
2209 | return diag; | 2209 | return diag; |
2210 | 2210 | ||
2211 | /* | 2211 | /* |
2212 | * Validate cpunum | 2212 | * Validate cpunum |
2213 | */ | 2213 | */ |
2214 | if ((cpunum > NR_CPUS) || !cpu_online(cpunum)) | 2214 | if ((cpunum > NR_CPUS) || !cpu_online(cpunum)) |
2215 | return KDB_BADCPUNUM; | 2215 | return KDB_BADCPUNUM; |
2216 | 2216 | ||
2217 | dbg_switch_cpu = cpunum; | 2217 | dbg_switch_cpu = cpunum; |
2218 | 2218 | ||
2219 | /* | 2219 | /* |
2220 | * Switch to other cpu | 2220 | * Switch to other cpu |
2221 | */ | 2221 | */ |
2222 | return KDB_CMD_CPU; | 2222 | return KDB_CMD_CPU; |
2223 | } | 2223 | } |
2224 | 2224 | ||
2225 | /* The user may not realize that ps/bta with no parameters does not print idle | 2225 | /* The user may not realize that ps/bta with no parameters does not print idle |
2226 | * or sleeping system daemon processes, so tell them how many were suppressed. | 2226 | * or sleeping system daemon processes, so tell them how many were suppressed. |
2227 | */ | 2227 | */ |
2228 | void kdb_ps_suppressed(void) | 2228 | void kdb_ps_suppressed(void) |
2229 | { | 2229 | { |
2230 | int idle = 0, daemon = 0; | 2230 | int idle = 0, daemon = 0; |
2231 | unsigned long mask_I = kdb_task_state_string("I"), | 2231 | unsigned long mask_I = kdb_task_state_string("I"), |
2232 | mask_M = kdb_task_state_string("M"); | 2232 | mask_M = kdb_task_state_string("M"); |
2233 | unsigned long cpu; | 2233 | unsigned long cpu; |
2234 | const struct task_struct *p, *g; | 2234 | const struct task_struct *p, *g; |
2235 | for_each_online_cpu(cpu) { | 2235 | for_each_online_cpu(cpu) { |
2236 | p = kdb_curr_task(cpu); | 2236 | p = kdb_curr_task(cpu); |
2237 | if (kdb_task_state(p, mask_I)) | 2237 | if (kdb_task_state(p, mask_I)) |
2238 | ++idle; | 2238 | ++idle; |
2239 | } | 2239 | } |
2240 | kdb_do_each_thread(g, p) { | 2240 | kdb_do_each_thread(g, p) { |
2241 | if (kdb_task_state(p, mask_M)) | 2241 | if (kdb_task_state(p, mask_M)) |
2242 | ++daemon; | 2242 | ++daemon; |
2243 | } kdb_while_each_thread(g, p); | 2243 | } kdb_while_each_thread(g, p); |
2244 | if (idle || daemon) { | 2244 | if (idle || daemon) { |
2245 | if (idle) | 2245 | if (idle) |
2246 | kdb_printf("%d idle process%s (state I)%s\n", | 2246 | kdb_printf("%d idle process%s (state I)%s\n", |
2247 | idle, idle == 1 ? "" : "es", | 2247 | idle, idle == 1 ? "" : "es", |
2248 | daemon ? " and " : ""); | 2248 | daemon ? " and " : ""); |
2249 | if (daemon) | 2249 | if (daemon) |
2250 | kdb_printf("%d sleeping system daemon (state M) " | 2250 | kdb_printf("%d sleeping system daemon (state M) " |
2251 | "process%s", daemon, | 2251 | "process%s", daemon, |
2252 | daemon == 1 ? "" : "es"); | 2252 | daemon == 1 ? "" : "es"); |
2253 | kdb_printf(" suppressed,\nuse 'ps A' to see all.\n"); | 2253 | kdb_printf(" suppressed,\nuse 'ps A' to see all.\n"); |
2254 | } | 2254 | } |
2255 | } | 2255 | } |
2256 | 2256 | ||
2257 | /* | 2257 | /* |
2258 | * kdb_ps - This function implements the 'ps' command which shows a | 2258 | * kdb_ps - This function implements the 'ps' command which shows a |
2259 | * list of the active processes. | 2259 | * list of the active processes. |
2260 | * ps [DRSTCZEUIMA] All processes, optionally filtered by state | 2260 | * ps [DRSTCZEUIMA] All processes, optionally filtered by state |
2261 | */ | 2261 | */ |
2262 | void kdb_ps1(const struct task_struct *p) | 2262 | void kdb_ps1(const struct task_struct *p) |
2263 | { | 2263 | { |
2264 | int cpu; | 2264 | int cpu; |
2265 | unsigned long tmp; | 2265 | unsigned long tmp; |
2266 | 2266 | ||
2267 | if (!p || probe_kernel_read(&tmp, (char *)p, sizeof(unsigned long))) | 2267 | if (!p || probe_kernel_read(&tmp, (char *)p, sizeof(unsigned long))) |
2268 | return; | 2268 | return; |
2269 | 2269 | ||
2270 | cpu = kdb_process_cpu(p); | 2270 | cpu = kdb_process_cpu(p); |
2271 | kdb_printf("0x%p %8d %8d %d %4d %c 0x%p %c%s\n", | 2271 | kdb_printf("0x%p %8d %8d %d %4d %c 0x%p %c%s\n", |
2272 | (void *)p, p->pid, p->parent->pid, | 2272 | (void *)p, p->pid, p->parent->pid, |
2273 | kdb_task_has_cpu(p), kdb_process_cpu(p), | 2273 | kdb_task_has_cpu(p), kdb_process_cpu(p), |
2274 | kdb_task_state_char(p), | 2274 | kdb_task_state_char(p), |
2275 | (void *)(&p->thread), | 2275 | (void *)(&p->thread), |
2276 | p == kdb_curr_task(raw_smp_processor_id()) ? '*' : ' ', | 2276 | p == kdb_curr_task(raw_smp_processor_id()) ? '*' : ' ', |
2277 | p->comm); | 2277 | p->comm); |
2278 | if (kdb_task_has_cpu(p)) { | 2278 | if (kdb_task_has_cpu(p)) { |
2279 | if (!KDB_TSK(cpu)) { | 2279 | if (!KDB_TSK(cpu)) { |
2280 | kdb_printf(" Error: no saved data for this cpu\n"); | 2280 | kdb_printf(" Error: no saved data for this cpu\n"); |
2281 | } else { | 2281 | } else { |
2282 | if (KDB_TSK(cpu) != p) | 2282 | if (KDB_TSK(cpu) != p) |
2283 | kdb_printf(" Error: does not match running " | 2283 | kdb_printf(" Error: does not match running " |
2284 | "process table (0x%p)\n", KDB_TSK(cpu)); | 2284 | "process table (0x%p)\n", KDB_TSK(cpu)); |
2285 | } | 2285 | } |
2286 | } | 2286 | } |
2287 | } | 2287 | } |
2288 | 2288 | ||
2289 | static int kdb_ps(int argc, const char **argv) | 2289 | static int kdb_ps(int argc, const char **argv) |
2290 | { | 2290 | { |
2291 | struct task_struct *g, *p; | 2291 | struct task_struct *g, *p; |
2292 | unsigned long mask, cpu; | 2292 | unsigned long mask, cpu; |
2293 | 2293 | ||
2294 | if (argc == 0) | 2294 | if (argc == 0) |
2295 | kdb_ps_suppressed(); | 2295 | kdb_ps_suppressed(); |
2296 | kdb_printf("%-*s Pid Parent [*] cpu State %-*s Command\n", | 2296 | kdb_printf("%-*s Pid Parent [*] cpu State %-*s Command\n", |
2297 | (int)(2*sizeof(void *))+2, "Task Addr", | 2297 | (int)(2*sizeof(void *))+2, "Task Addr", |
2298 | (int)(2*sizeof(void *))+2, "Thread"); | 2298 | (int)(2*sizeof(void *))+2, "Thread"); |
2299 | mask = kdb_task_state_string(argc ? argv[1] : NULL); | 2299 | mask = kdb_task_state_string(argc ? argv[1] : NULL); |
2300 | /* Run the active tasks first */ | 2300 | /* Run the active tasks first */ |
2301 | for_each_online_cpu(cpu) { | 2301 | for_each_online_cpu(cpu) { |
2302 | if (KDB_FLAG(CMD_INTERRUPT)) | 2302 | if (KDB_FLAG(CMD_INTERRUPT)) |
2303 | return 0; | 2303 | return 0; |
2304 | p = kdb_curr_task(cpu); | 2304 | p = kdb_curr_task(cpu); |
2305 | if (kdb_task_state(p, mask)) | 2305 | if (kdb_task_state(p, mask)) |
2306 | kdb_ps1(p); | 2306 | kdb_ps1(p); |
2307 | } | 2307 | } |
2308 | kdb_printf("\n"); | 2308 | kdb_printf("\n"); |
2309 | /* Now the real tasks */ | 2309 | /* Now the real tasks */ |
2310 | kdb_do_each_thread(g, p) { | 2310 | kdb_do_each_thread(g, p) { |
2311 | if (KDB_FLAG(CMD_INTERRUPT)) | 2311 | if (KDB_FLAG(CMD_INTERRUPT)) |
2312 | return 0; | 2312 | return 0; |
2313 | if (kdb_task_state(p, mask)) | 2313 | if (kdb_task_state(p, mask)) |
2314 | kdb_ps1(p); | 2314 | kdb_ps1(p); |
2315 | } kdb_while_each_thread(g, p); | 2315 | } kdb_while_each_thread(g, p); |
2316 | 2316 | ||
2317 | return 0; | 2317 | return 0; |
2318 | } | 2318 | } |
2319 | 2319 | ||
2320 | /* | 2320 | /* |
2321 | * kdb_pid - This function implements the 'pid' command which switches | 2321 | * kdb_pid - This function implements the 'pid' command which switches |
2322 | * the currently active process. | 2322 | * the currently active process. |
2323 | * pid [<pid> | R] | 2323 | * pid [<pid> | R] |
2324 | */ | 2324 | */ |
2325 | static int kdb_pid(int argc, const char **argv) | 2325 | static int kdb_pid(int argc, const char **argv) |
2326 | { | 2326 | { |
2327 | struct task_struct *p; | 2327 | struct task_struct *p; |
2328 | unsigned long val; | 2328 | unsigned long val; |
2329 | int diag; | 2329 | int diag; |
2330 | 2330 | ||
2331 | if (argc > 1) | 2331 | if (argc > 1) |
2332 | return KDB_ARGCOUNT; | 2332 | return KDB_ARGCOUNT; |
2333 | 2333 | ||
2334 | if (argc) { | 2334 | if (argc) { |
2335 | if (strcmp(argv[1], "R") == 0) { | 2335 | if (strcmp(argv[1], "R") == 0) { |
2336 | p = KDB_TSK(kdb_initial_cpu); | 2336 | p = KDB_TSK(kdb_initial_cpu); |
2337 | } else { | 2337 | } else { |
2338 | diag = kdbgetularg(argv[1], &val); | 2338 | diag = kdbgetularg(argv[1], &val); |
2339 | if (diag) | 2339 | if (diag) |
2340 | return KDB_BADINT; | 2340 | return KDB_BADINT; |
2341 | 2341 | ||
2342 | p = find_task_by_pid_ns((pid_t)val, &init_pid_ns); | 2342 | p = find_task_by_pid_ns((pid_t)val, &init_pid_ns); |
2343 | if (!p) { | 2343 | if (!p) { |
2344 | kdb_printf("No task with pid=%d\n", (pid_t)val); | 2344 | kdb_printf("No task with pid=%d\n", (pid_t)val); |
2345 | return 0; | 2345 | return 0; |
2346 | } | 2346 | } |
2347 | } | 2347 | } |
2348 | kdb_set_current_task(p); | 2348 | kdb_set_current_task(p); |
2349 | } | 2349 | } |
2350 | kdb_printf("KDB current process is %s(pid=%d)\n", | 2350 | kdb_printf("KDB current process is %s(pid=%d)\n", |
2351 | kdb_current_task->comm, | 2351 | kdb_current_task->comm, |
2352 | kdb_current_task->pid); | 2352 | kdb_current_task->pid); |
2353 | 2353 | ||
2354 | return 0; | 2354 | return 0; |
2355 | } | 2355 | } |
2356 | 2356 | ||
2357 | /* | 2357 | /* |
2358 | * kdb_ll - This function implements the 'll' command which follows a | 2358 | * kdb_ll - This function implements the 'll' command which follows a |
2359 | * linked list and executes an arbitrary command for each | 2359 | * linked list and executes an arbitrary command for each |
2360 | * element. | 2360 | * element. |
2361 | */ | 2361 | */ |
2362 | static int kdb_ll(int argc, const char **argv) | 2362 | static int kdb_ll(int argc, const char **argv) |
2363 | { | 2363 | { |
2364 | int diag = 0; | 2364 | int diag = 0; |
2365 | unsigned long addr; | 2365 | unsigned long addr; |
2366 | long offset = 0; | 2366 | long offset = 0; |
2367 | unsigned long va; | 2367 | unsigned long va; |
2368 | unsigned long linkoffset; | 2368 | unsigned long linkoffset; |
2369 | int nextarg; | 2369 | int nextarg; |
2370 | const char *command; | 2370 | const char *command; |
2371 | 2371 | ||
2372 | if (argc != 3) | 2372 | if (argc != 3) |
2373 | return KDB_ARGCOUNT; | 2373 | return KDB_ARGCOUNT; |
2374 | 2374 | ||
2375 | nextarg = 1; | 2375 | nextarg = 1; |
2376 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL); | 2376 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL); |
2377 | if (diag) | 2377 | if (diag) |
2378 | return diag; | 2378 | return diag; |
2379 | 2379 | ||
2380 | diag = kdbgetularg(argv[2], &linkoffset); | 2380 | diag = kdbgetularg(argv[2], &linkoffset); |
2381 | if (diag) | 2381 | if (diag) |
2382 | return diag; | 2382 | return diag; |
2383 | 2383 | ||
2384 | /* | 2384 | /* |
2385 | * Using the starting address as | 2385 | * Using the starting address as |
2386 | * the first element in the list, and assuming that | 2386 | * the first element in the list, and assuming that |
2387 | * the list ends with a null pointer. | 2387 | * the list ends with a null pointer. |
2388 | */ | 2388 | */ |
2389 | 2389 | ||
2390 | va = addr; | 2390 | va = addr; |
2391 | command = kdb_strdup(argv[3], GFP_KDB); | 2391 | command = kdb_strdup(argv[3], GFP_KDB); |
2392 | if (!command) { | 2392 | if (!command) { |
2393 | kdb_printf("%s: cannot duplicate command\n", __func__); | 2393 | kdb_printf("%s: cannot duplicate command\n", __func__); |
2394 | return 0; | 2394 | return 0; |
2395 | } | 2395 | } |
2396 | /* Recursive use of kdb_parse, do not use argv after this point */ | 2396 | /* Recursive use of kdb_parse, do not use argv after this point */ |
2397 | argv = NULL; | 2397 | argv = NULL; |
2398 | 2398 | ||
2399 | while (va) { | 2399 | while (va) { |
2400 | char buf[80]; | 2400 | char buf[80]; |
2401 | 2401 | ||
2402 | if (KDB_FLAG(CMD_INTERRUPT)) | 2402 | if (KDB_FLAG(CMD_INTERRUPT)) |
2403 | goto out; | 2403 | goto out; |
2404 | 2404 | ||
2405 | sprintf(buf, "%s " kdb_machreg_fmt "\n", command, va); | 2405 | sprintf(buf, "%s " kdb_machreg_fmt "\n", command, va); |
2406 | diag = kdb_parse(buf); | 2406 | diag = kdb_parse(buf); |
2407 | if (diag) | 2407 | if (diag) |
2408 | goto out; | 2408 | goto out; |
2409 | 2409 | ||
2410 | addr = va + linkoffset; | 2410 | addr = va + linkoffset; |
2411 | if (kdb_getword(&va, addr, sizeof(va))) | 2411 | if (kdb_getword(&va, addr, sizeof(va))) |
2412 | goto out; | 2412 | goto out; |
2413 | } | 2413 | } |
2414 | 2414 | ||
2415 | out: | 2415 | out: |
2416 | kfree(command); | 2416 | kfree(command); |
2417 | return diag; | 2417 | return diag; |
2418 | } | 2418 | } |
2419 | 2419 | ||
2420 | static int kdb_kgdb(int argc, const char **argv) | 2420 | static int kdb_kgdb(int argc, const char **argv) |
2421 | { | 2421 | { |
2422 | return KDB_CMD_KGDB; | 2422 | return KDB_CMD_KGDB; |
2423 | } | 2423 | } |
2424 | 2424 | ||
2425 | /* | 2425 | /* |
2426 | * kdb_help - This function implements the 'help' and '?' commands. | 2426 | * kdb_help - This function implements the 'help' and '?' commands. |
2427 | */ | 2427 | */ |
2428 | static int kdb_help(int argc, const char **argv) | 2428 | static int kdb_help(int argc, const char **argv) |
2429 | { | 2429 | { |
2430 | kdbtab_t *kt; | 2430 | kdbtab_t *kt; |
2431 | int i; | 2431 | int i; |
2432 | 2432 | ||
2433 | kdb_printf("%-15.15s %-20.20s %s\n", "Command", "Usage", "Description"); | 2433 | kdb_printf("%-15.15s %-20.20s %s\n", "Command", "Usage", "Description"); |
2434 | kdb_printf("-----------------------------" | 2434 | kdb_printf("-----------------------------" |
2435 | "-----------------------------\n"); | 2435 | "-----------------------------\n"); |
2436 | for_each_kdbcmd(kt, i) { | 2436 | for_each_kdbcmd(kt, i) { |
2437 | if (kt->cmd_name) | 2437 | if (kt->cmd_name) |
2438 | kdb_printf("%-15.15s %-20.20s %s\n", kt->cmd_name, | 2438 | kdb_printf("%-15.15s %-20.20s %s\n", kt->cmd_name, |
2439 | kt->cmd_usage, kt->cmd_help); | 2439 | kt->cmd_usage, kt->cmd_help); |
2440 | if (KDB_FLAG(CMD_INTERRUPT)) | 2440 | if (KDB_FLAG(CMD_INTERRUPT)) |
2441 | return 0; | 2441 | return 0; |
2442 | } | 2442 | } |
2443 | return 0; | 2443 | return 0; |
2444 | } | 2444 | } |
2445 | 2445 | ||
2446 | /* | 2446 | /* |
2447 | * kdb_kill - This function implements the 'kill' commands. | 2447 | * kdb_kill - This function implements the 'kill' commands. |
2448 | */ | 2448 | */ |
2449 | static int kdb_kill(int argc, const char **argv) | 2449 | static int kdb_kill(int argc, const char **argv) |
2450 | { | 2450 | { |
2451 | long sig, pid; | 2451 | long sig, pid; |
2452 | char *endp; | 2452 | char *endp; |
2453 | struct task_struct *p; | 2453 | struct task_struct *p; |
2454 | struct siginfo info; | 2454 | struct siginfo info; |
2455 | 2455 | ||
2456 | if (argc != 2) | 2456 | if (argc != 2) |
2457 | return KDB_ARGCOUNT; | 2457 | return KDB_ARGCOUNT; |
2458 | 2458 | ||
2459 | sig = simple_strtol(argv[1], &endp, 0); | 2459 | sig = simple_strtol(argv[1], &endp, 0); |
2460 | if (*endp) | 2460 | if (*endp) |
2461 | return KDB_BADINT; | 2461 | return KDB_BADINT; |
2462 | if (sig >= 0) { | 2462 | if (sig >= 0) { |
2463 | kdb_printf("Invalid signal parameter.<-signal>\n"); | 2463 | kdb_printf("Invalid signal parameter.<-signal>\n"); |
2464 | return 0; | 2464 | return 0; |
2465 | } | 2465 | } |
2466 | sig = -sig; | 2466 | sig = -sig; |
2467 | 2467 | ||
2468 | pid = simple_strtol(argv[2], &endp, 0); | 2468 | pid = simple_strtol(argv[2], &endp, 0); |
2469 | if (*endp) | 2469 | if (*endp) |
2470 | return KDB_BADINT; | 2470 | return KDB_BADINT; |
2471 | if (pid <= 0) { | 2471 | if (pid <= 0) { |
2472 | kdb_printf("Process ID must be large than 0.\n"); | 2472 | kdb_printf("Process ID must be large than 0.\n"); |
2473 | return 0; | 2473 | return 0; |
2474 | } | 2474 | } |
2475 | 2475 | ||
2476 | /* Find the process. */ | 2476 | /* Find the process. */ |
2477 | p = find_task_by_pid_ns(pid, &init_pid_ns); | 2477 | p = find_task_by_pid_ns(pid, &init_pid_ns); |
2478 | if (!p) { | 2478 | if (!p) { |
2479 | kdb_printf("The specified process isn't found.\n"); | 2479 | kdb_printf("The specified process isn't found.\n"); |
2480 | return 0; | 2480 | return 0; |
2481 | } | 2481 | } |
2482 | p = p->group_leader; | 2482 | p = p->group_leader; |
2483 | info.si_signo = sig; | 2483 | info.si_signo = sig; |
2484 | info.si_errno = 0; | 2484 | info.si_errno = 0; |
2485 | info.si_code = SI_USER; | 2485 | info.si_code = SI_USER; |
2486 | info.si_pid = pid; /* same capabilities as process being signalled */ | 2486 | info.si_pid = pid; /* same capabilities as process being signalled */ |
2487 | info.si_uid = 0; /* kdb has root authority */ | 2487 | info.si_uid = 0; /* kdb has root authority */ |
2488 | kdb_send_sig_info(p, &info); | 2488 | kdb_send_sig_info(p, &info); |
2489 | return 0; | 2489 | return 0; |
2490 | } | 2490 | } |
2491 | 2491 | ||
2492 | struct kdb_tm { | 2492 | struct kdb_tm { |
2493 | int tm_sec; /* seconds */ | 2493 | int tm_sec; /* seconds */ |
2494 | int tm_min; /* minutes */ | 2494 | int tm_min; /* minutes */ |
2495 | int tm_hour; /* hours */ | 2495 | int tm_hour; /* hours */ |
2496 | int tm_mday; /* day of the month */ | 2496 | int tm_mday; /* day of the month */ |
2497 | int tm_mon; /* month */ | 2497 | int tm_mon; /* month */ |
2498 | int tm_year; /* year */ | 2498 | int tm_year; /* year */ |
2499 | }; | 2499 | }; |
2500 | 2500 | ||
2501 | static void kdb_gmtime(struct timespec *tv, struct kdb_tm *tm) | 2501 | static void kdb_gmtime(struct timespec *tv, struct kdb_tm *tm) |
2502 | { | 2502 | { |
2503 | /* This will work from 1970-2099, 2100 is not a leap year */ | 2503 | /* This will work from 1970-2099, 2100 is not a leap year */ |
2504 | static int mon_day[] = { 31, 29, 31, 30, 31, 30, 31, | 2504 | static int mon_day[] = { 31, 29, 31, 30, 31, 30, 31, |
2505 | 31, 30, 31, 30, 31 }; | 2505 | 31, 30, 31, 30, 31 }; |
2506 | memset(tm, 0, sizeof(*tm)); | 2506 | memset(tm, 0, sizeof(*tm)); |
2507 | tm->tm_sec = tv->tv_sec % (24 * 60 * 60); | 2507 | tm->tm_sec = tv->tv_sec % (24 * 60 * 60); |
2508 | tm->tm_mday = tv->tv_sec / (24 * 60 * 60) + | 2508 | tm->tm_mday = tv->tv_sec / (24 * 60 * 60) + |
2509 | (2 * 365 + 1); /* shift base from 1970 to 1968 */ | 2509 | (2 * 365 + 1); /* shift base from 1970 to 1968 */ |
2510 | tm->tm_min = tm->tm_sec / 60 % 60; | 2510 | tm->tm_min = tm->tm_sec / 60 % 60; |
2511 | tm->tm_hour = tm->tm_sec / 60 / 60; | 2511 | tm->tm_hour = tm->tm_sec / 60 / 60; |
2512 | tm->tm_sec = tm->tm_sec % 60; | 2512 | tm->tm_sec = tm->tm_sec % 60; |
2513 | tm->tm_year = 68 + 4*(tm->tm_mday / (4*365+1)); | 2513 | tm->tm_year = 68 + 4*(tm->tm_mday / (4*365+1)); |
2514 | tm->tm_mday %= (4*365+1); | 2514 | tm->tm_mday %= (4*365+1); |
2515 | mon_day[1] = 29; | 2515 | mon_day[1] = 29; |
2516 | while (tm->tm_mday >= mon_day[tm->tm_mon]) { | 2516 | while (tm->tm_mday >= mon_day[tm->tm_mon]) { |
2517 | tm->tm_mday -= mon_day[tm->tm_mon]; | 2517 | tm->tm_mday -= mon_day[tm->tm_mon]; |
2518 | if (++tm->tm_mon == 12) { | 2518 | if (++tm->tm_mon == 12) { |
2519 | tm->tm_mon = 0; | 2519 | tm->tm_mon = 0; |
2520 | ++tm->tm_year; | 2520 | ++tm->tm_year; |
2521 | mon_day[1] = 28; | 2521 | mon_day[1] = 28; |
2522 | } | 2522 | } |
2523 | } | 2523 | } |
2524 | ++tm->tm_mday; | 2524 | ++tm->tm_mday; |
2525 | } | 2525 | } |
2526 | 2526 | ||
2527 | /* | 2527 | /* |
2528 | * Most of this code has been lifted from kernel/timer.c::sys_sysinfo(). | 2528 | * Most of this code has been lifted from kernel/timer.c::sys_sysinfo(). |
2529 | * I cannot call that code directly from kdb, it has an unconditional | 2529 | * I cannot call that code directly from kdb, it has an unconditional |
2530 | * cli()/sti() and calls routines that take locks which can stop the debugger. | 2530 | * cli()/sti() and calls routines that take locks which can stop the debugger. |
2531 | */ | 2531 | */ |
2532 | static void kdb_sysinfo(struct sysinfo *val) | 2532 | static void kdb_sysinfo(struct sysinfo *val) |
2533 | { | 2533 | { |
2534 | struct timespec uptime; | 2534 | struct timespec uptime; |
2535 | do_posix_clock_monotonic_gettime(&uptime); | 2535 | do_posix_clock_monotonic_gettime(&uptime); |
2536 | memset(val, 0, sizeof(*val)); | 2536 | memset(val, 0, sizeof(*val)); |
2537 | val->uptime = uptime.tv_sec; | 2537 | val->uptime = uptime.tv_sec; |
2538 | val->loads[0] = avenrun[0]; | 2538 | val->loads[0] = avenrun[0]; |
2539 | val->loads[1] = avenrun[1]; | 2539 | val->loads[1] = avenrun[1]; |
2540 | val->loads[2] = avenrun[2]; | 2540 | val->loads[2] = avenrun[2]; |
2541 | val->procs = nr_threads-1; | 2541 | val->procs = nr_threads-1; |
2542 | si_meminfo(val); | 2542 | si_meminfo(val); |
2543 | 2543 | ||
2544 | return; | 2544 | return; |
2545 | } | 2545 | } |
2546 | 2546 | ||
2547 | /* | 2547 | /* |
2548 | * kdb_summary - This function implements the 'summary' command. | 2548 | * kdb_summary - This function implements the 'summary' command. |
2549 | */ | 2549 | */ |
2550 | static int kdb_summary(int argc, const char **argv) | 2550 | static int kdb_summary(int argc, const char **argv) |
2551 | { | 2551 | { |
2552 | struct timespec now; | 2552 | struct timespec now; |
2553 | struct kdb_tm tm; | 2553 | struct kdb_tm tm; |
2554 | struct sysinfo val; | 2554 | struct sysinfo val; |
2555 | 2555 | ||
2556 | if (argc) | 2556 | if (argc) |
2557 | return KDB_ARGCOUNT; | 2557 | return KDB_ARGCOUNT; |
2558 | 2558 | ||
2559 | kdb_printf("sysname %s\n", init_uts_ns.name.sysname); | 2559 | kdb_printf("sysname %s\n", init_uts_ns.name.sysname); |
2560 | kdb_printf("release %s\n", init_uts_ns.name.release); | 2560 | kdb_printf("release %s\n", init_uts_ns.name.release); |
2561 | kdb_printf("version %s\n", init_uts_ns.name.version); | 2561 | kdb_printf("version %s\n", init_uts_ns.name.version); |
2562 | kdb_printf("machine %s\n", init_uts_ns.name.machine); | 2562 | kdb_printf("machine %s\n", init_uts_ns.name.machine); |
2563 | kdb_printf("nodename %s\n", init_uts_ns.name.nodename); | 2563 | kdb_printf("nodename %s\n", init_uts_ns.name.nodename); |
2564 | kdb_printf("domainname %s\n", init_uts_ns.name.domainname); | 2564 | kdb_printf("domainname %s\n", init_uts_ns.name.domainname); |
2565 | kdb_printf("ccversion %s\n", __stringify(CCVERSION)); | 2565 | kdb_printf("ccversion %s\n", __stringify(CCVERSION)); |
2566 | 2566 | ||
2567 | now = __current_kernel_time(); | 2567 | now = __current_kernel_time(); |
2568 | kdb_gmtime(&now, &tm); | 2568 | kdb_gmtime(&now, &tm); |
2569 | kdb_printf("date %04d-%02d-%02d %02d:%02d:%02d " | 2569 | kdb_printf("date %04d-%02d-%02d %02d:%02d:%02d " |
2570 | "tz_minuteswest %d\n", | 2570 | "tz_minuteswest %d\n", |
2571 | 1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday, | 2571 | 1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday, |
2572 | tm.tm_hour, tm.tm_min, tm.tm_sec, | 2572 | tm.tm_hour, tm.tm_min, tm.tm_sec, |
2573 | sys_tz.tz_minuteswest); | 2573 | sys_tz.tz_minuteswest); |
2574 | 2574 | ||
2575 | kdb_sysinfo(&val); | 2575 | kdb_sysinfo(&val); |
2576 | kdb_printf("uptime "); | 2576 | kdb_printf("uptime "); |
2577 | if (val.uptime > (24*60*60)) { | 2577 | if (val.uptime > (24*60*60)) { |
2578 | int days = val.uptime / (24*60*60); | 2578 | int days = val.uptime / (24*60*60); |
2579 | val.uptime %= (24*60*60); | 2579 | val.uptime %= (24*60*60); |
2580 | kdb_printf("%d day%s ", days, days == 1 ? "" : "s"); | 2580 | kdb_printf("%d day%s ", days, days == 1 ? "" : "s"); |
2581 | } | 2581 | } |
2582 | kdb_printf("%02ld:%02ld\n", val.uptime/(60*60), (val.uptime/60)%60); | 2582 | kdb_printf("%02ld:%02ld\n", val.uptime/(60*60), (val.uptime/60)%60); |
2583 | 2583 | ||
2584 | /* lifted from fs/proc/proc_misc.c::loadavg_read_proc() */ | 2584 | /* lifted from fs/proc/proc_misc.c::loadavg_read_proc() */ |
2585 | 2585 | ||
2586 | #define LOAD_INT(x) ((x) >> FSHIFT) | 2586 | #define LOAD_INT(x) ((x) >> FSHIFT) |
2587 | #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) | 2587 | #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) |
2588 | kdb_printf("load avg %ld.%02ld %ld.%02ld %ld.%02ld\n", | 2588 | kdb_printf("load avg %ld.%02ld %ld.%02ld %ld.%02ld\n", |
2589 | LOAD_INT(val.loads[0]), LOAD_FRAC(val.loads[0]), | 2589 | LOAD_INT(val.loads[0]), LOAD_FRAC(val.loads[0]), |
2590 | LOAD_INT(val.loads[1]), LOAD_FRAC(val.loads[1]), | 2590 | LOAD_INT(val.loads[1]), LOAD_FRAC(val.loads[1]), |
2591 | LOAD_INT(val.loads[2]), LOAD_FRAC(val.loads[2])); | 2591 | LOAD_INT(val.loads[2]), LOAD_FRAC(val.loads[2])); |
2592 | #undef LOAD_INT | 2592 | #undef LOAD_INT |
2593 | #undef LOAD_FRAC | 2593 | #undef LOAD_FRAC |
2594 | /* Display in kilobytes */ | 2594 | /* Display in kilobytes */ |
2595 | #define K(x) ((x) << (PAGE_SHIFT - 10)) | 2595 | #define K(x) ((x) << (PAGE_SHIFT - 10)) |
2596 | kdb_printf("\nMemTotal: %8lu kB\nMemFree: %8lu kB\n" | 2596 | kdb_printf("\nMemTotal: %8lu kB\nMemFree: %8lu kB\n" |
2597 | "Buffers: %8lu kB\n", | 2597 | "Buffers: %8lu kB\n", |
2598 | val.totalram, val.freeram, val.bufferram); | 2598 | val.totalram, val.freeram, val.bufferram); |
2599 | return 0; | 2599 | return 0; |
2600 | } | 2600 | } |
2601 | 2601 | ||
2602 | /* | 2602 | /* |
2603 | * kdb_per_cpu - This function implements the 'per_cpu' command. | 2603 | * kdb_per_cpu - This function implements the 'per_cpu' command. |
2604 | */ | 2604 | */ |
2605 | static int kdb_per_cpu(int argc, const char **argv) | 2605 | static int kdb_per_cpu(int argc, const char **argv) |
2606 | { | 2606 | { |
2607 | char fmtstr[64]; | 2607 | char fmtstr[64]; |
2608 | int cpu, diag, nextarg = 1; | 2608 | int cpu, diag, nextarg = 1; |
2609 | unsigned long addr, symaddr, val, bytesperword = 0, whichcpu = ~0UL; | 2609 | unsigned long addr, symaddr, val, bytesperword = 0, whichcpu = ~0UL; |
2610 | 2610 | ||
2611 | if (argc < 1 || argc > 3) | 2611 | if (argc < 1 || argc > 3) |
2612 | return KDB_ARGCOUNT; | 2612 | return KDB_ARGCOUNT; |
2613 | 2613 | ||
2614 | diag = kdbgetaddrarg(argc, argv, &nextarg, &symaddr, NULL, NULL); | 2614 | diag = kdbgetaddrarg(argc, argv, &nextarg, &symaddr, NULL, NULL); |
2615 | if (diag) | 2615 | if (diag) |
2616 | return diag; | 2616 | return diag; |
2617 | 2617 | ||
2618 | if (argc >= 2) { | 2618 | if (argc >= 2) { |
2619 | diag = kdbgetularg(argv[2], &bytesperword); | 2619 | diag = kdbgetularg(argv[2], &bytesperword); |
2620 | if (diag) | 2620 | if (diag) |
2621 | return diag; | 2621 | return diag; |
2622 | } | 2622 | } |
2623 | if (!bytesperword) | 2623 | if (!bytesperword) |
2624 | bytesperword = KDB_WORD_SIZE; | 2624 | bytesperword = KDB_WORD_SIZE; |
2625 | else if (bytesperword > KDB_WORD_SIZE) | 2625 | else if (bytesperword > KDB_WORD_SIZE) |
2626 | return KDB_BADWIDTH; | 2626 | return KDB_BADWIDTH; |
2627 | sprintf(fmtstr, "%%0%dlx ", (int)(2*bytesperword)); | 2627 | sprintf(fmtstr, "%%0%dlx ", (int)(2*bytesperword)); |
2628 | if (argc >= 3) { | 2628 | if (argc >= 3) { |
2629 | diag = kdbgetularg(argv[3], &whichcpu); | 2629 | diag = kdbgetularg(argv[3], &whichcpu); |
2630 | if (diag) | 2630 | if (diag) |
2631 | return diag; | 2631 | return diag; |
2632 | if (!cpu_online(whichcpu)) { | 2632 | if (!cpu_online(whichcpu)) { |
2633 | kdb_printf("cpu %ld is not online\n", whichcpu); | 2633 | kdb_printf("cpu %ld is not online\n", whichcpu); |
2634 | return KDB_BADCPUNUM; | 2634 | return KDB_BADCPUNUM; |
2635 | } | 2635 | } |
2636 | } | 2636 | } |
2637 | 2637 | ||
2638 | /* Most architectures use __per_cpu_offset[cpu], some use | 2638 | /* Most architectures use __per_cpu_offset[cpu], some use |
2639 | * __per_cpu_offset(cpu), smp has no __per_cpu_offset. | 2639 | * __per_cpu_offset(cpu), smp has no __per_cpu_offset. |
2640 | */ | 2640 | */ |
2641 | #ifdef __per_cpu_offset | 2641 | #ifdef __per_cpu_offset |
2642 | #define KDB_PCU(cpu) __per_cpu_offset(cpu) | 2642 | #define KDB_PCU(cpu) __per_cpu_offset(cpu) |
2643 | #else | 2643 | #else |
2644 | #ifdef CONFIG_SMP | 2644 | #ifdef CONFIG_SMP |
2645 | #define KDB_PCU(cpu) __per_cpu_offset[cpu] | 2645 | #define KDB_PCU(cpu) __per_cpu_offset[cpu] |
2646 | #else | 2646 | #else |
2647 | #define KDB_PCU(cpu) 0 | 2647 | #define KDB_PCU(cpu) 0 |
2648 | #endif | 2648 | #endif |
2649 | #endif | 2649 | #endif |
2650 | for_each_online_cpu(cpu) { | 2650 | for_each_online_cpu(cpu) { |
2651 | if (KDB_FLAG(CMD_INTERRUPT)) | 2651 | if (KDB_FLAG(CMD_INTERRUPT)) |
2652 | return 0; | 2652 | return 0; |
2653 | 2653 | ||
2654 | if (whichcpu != ~0UL && whichcpu != cpu) | 2654 | if (whichcpu != ~0UL && whichcpu != cpu) |
2655 | continue; | 2655 | continue; |
2656 | addr = symaddr + KDB_PCU(cpu); | 2656 | addr = symaddr + KDB_PCU(cpu); |
2657 | diag = kdb_getword(&val, addr, bytesperword); | 2657 | diag = kdb_getword(&val, addr, bytesperword); |
2658 | if (diag) { | 2658 | if (diag) { |
2659 | kdb_printf("%5d " kdb_bfd_vma_fmt0 " - unable to " | 2659 | kdb_printf("%5d " kdb_bfd_vma_fmt0 " - unable to " |
2660 | "read, diag=%d\n", cpu, addr, diag); | 2660 | "read, diag=%d\n", cpu, addr, diag); |
2661 | continue; | 2661 | continue; |
2662 | } | 2662 | } |
2663 | kdb_printf("%5d ", cpu); | 2663 | kdb_printf("%5d ", cpu); |
2664 | kdb_md_line(fmtstr, addr, | 2664 | kdb_md_line(fmtstr, addr, |
2665 | bytesperword == KDB_WORD_SIZE, | 2665 | bytesperword == KDB_WORD_SIZE, |
2666 | 1, bytesperword, 1, 1, 0); | 2666 | 1, bytesperword, 1, 1, 0); |
2667 | } | 2667 | } |
2668 | #undef KDB_PCU | 2668 | #undef KDB_PCU |
2669 | return 0; | 2669 | return 0; |
2670 | } | 2670 | } |
2671 | 2671 | ||
2672 | /* | 2672 | /* |
2673 | * display help for the use of cmd | grep pattern | 2673 | * display help for the use of cmd | grep pattern |
2674 | */ | 2674 | */ |
2675 | static int kdb_grep_help(int argc, const char **argv) | 2675 | static int kdb_grep_help(int argc, const char **argv) |
2676 | { | 2676 | { |
2677 | kdb_printf("Usage of cmd args | grep pattern:\n"); | 2677 | kdb_printf("Usage of cmd args | grep pattern:\n"); |
2678 | kdb_printf(" Any command's output may be filtered through an "); | 2678 | kdb_printf(" Any command's output may be filtered through an "); |
2679 | kdb_printf("emulated 'pipe'.\n"); | 2679 | kdb_printf("emulated 'pipe'.\n"); |
2680 | kdb_printf(" 'grep' is just a key word.\n"); | 2680 | kdb_printf(" 'grep' is just a key word.\n"); |
2681 | kdb_printf(" The pattern may include a very limited set of " | 2681 | kdb_printf(" The pattern may include a very limited set of " |
2682 | "metacharacters:\n"); | 2682 | "metacharacters:\n"); |
2683 | kdb_printf(" pattern or ^pattern or pattern$ or ^pattern$\n"); | 2683 | kdb_printf(" pattern or ^pattern or pattern$ or ^pattern$\n"); |
2684 | kdb_printf(" And if there are spaces in the pattern, you may " | 2684 | kdb_printf(" And if there are spaces in the pattern, you may " |
2685 | "quote it:\n"); | 2685 | "quote it:\n"); |
2686 | kdb_printf(" \"pat tern\" or \"^pat tern\" or \"pat tern$\"" | 2686 | kdb_printf(" \"pat tern\" or \"^pat tern\" or \"pat tern$\"" |
2687 | " or \"^pat tern$\"\n"); | 2687 | " or \"^pat tern$\"\n"); |
2688 | return 0; | 2688 | return 0; |
2689 | } | 2689 | } |
2690 | 2690 | ||
2691 | /* | 2691 | /* |
2692 | * kdb_register_repeat - This function is used to register a kernel | 2692 | * kdb_register_repeat - This function is used to register a kernel |
2693 | * debugger command. | 2693 | * debugger command. |
2694 | * Inputs: | 2694 | * Inputs: |
2695 | * cmd Command name | 2695 | * cmd Command name |
2696 | * func Function to execute the command | 2696 | * func Function to execute the command |
2697 | * usage A simple usage string showing arguments | 2697 | * usage A simple usage string showing arguments |
2698 | * help A simple help string describing command | 2698 | * help A simple help string describing command |
2699 | * repeat Does the command auto repeat on enter? | 2699 | * repeat Does the command auto repeat on enter? |
2700 | * Returns: | 2700 | * Returns: |
2701 | * zero for success, one if a duplicate command. | 2701 | * zero for success, one if a duplicate command. |
2702 | */ | 2702 | */ |
2703 | #define kdb_command_extend 50 /* arbitrary */ | 2703 | #define kdb_command_extend 50 /* arbitrary */ |
2704 | int kdb_register_repeat(char *cmd, | 2704 | int kdb_register_repeat(char *cmd, |
2705 | kdb_func_t func, | 2705 | kdb_func_t func, |
2706 | char *usage, | 2706 | char *usage, |
2707 | char *help, | 2707 | char *help, |
2708 | short minlen, | 2708 | short minlen, |
2709 | kdb_repeat_t repeat) | 2709 | kdb_repeat_t repeat) |
2710 | { | 2710 | { |
2711 | int i; | 2711 | int i; |
2712 | kdbtab_t *kp; | 2712 | kdbtab_t *kp; |
2713 | 2713 | ||
2714 | /* | 2714 | /* |
2715 | * Brute force method to determine duplicates | 2715 | * Brute force method to determine duplicates |
2716 | */ | 2716 | */ |
2717 | for_each_kdbcmd(kp, i) { | 2717 | for_each_kdbcmd(kp, i) { |
2718 | if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) { | 2718 | if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) { |
2719 | kdb_printf("Duplicate kdb command registered: " | 2719 | kdb_printf("Duplicate kdb command registered: " |
2720 | "%s, func %p help %s\n", cmd, func, help); | 2720 | "%s, func %p help %s\n", cmd, func, help); |
2721 | return 1; | 2721 | return 1; |
2722 | } | 2722 | } |
2723 | } | 2723 | } |
2724 | 2724 | ||
2725 | /* | 2725 | /* |
2726 | * Insert command into first available location in table | 2726 | * Insert command into first available location in table |
2727 | */ | 2727 | */ |
2728 | for_each_kdbcmd(kp, i) { | 2728 | for_each_kdbcmd(kp, i) { |
2729 | if (kp->cmd_name == NULL) | 2729 | if (kp->cmd_name == NULL) |
2730 | break; | 2730 | break; |
2731 | } | 2731 | } |
2732 | 2732 | ||
2733 | if (i >= kdb_max_commands) { | 2733 | if (i >= kdb_max_commands) { |
2734 | kdbtab_t *new = kmalloc((kdb_max_commands - KDB_BASE_CMD_MAX + | 2734 | kdbtab_t *new = kmalloc((kdb_max_commands - KDB_BASE_CMD_MAX + |
2735 | kdb_command_extend) * sizeof(*new), GFP_KDB); | 2735 | kdb_command_extend) * sizeof(*new), GFP_KDB); |
2736 | if (!new) { | 2736 | if (!new) { |
2737 | kdb_printf("Could not allocate new kdb_command " | 2737 | kdb_printf("Could not allocate new kdb_command " |
2738 | "table\n"); | 2738 | "table\n"); |
2739 | return 1; | 2739 | return 1; |
2740 | } | 2740 | } |
2741 | if (kdb_commands) { | 2741 | if (kdb_commands) { |
2742 | memcpy(new, kdb_commands, | 2742 | memcpy(new, kdb_commands, |
2743 | (kdb_max_commands - KDB_BASE_CMD_MAX) * sizeof(*new)); | 2743 | (kdb_max_commands - KDB_BASE_CMD_MAX) * sizeof(*new)); |
2744 | kfree(kdb_commands); | 2744 | kfree(kdb_commands); |
2745 | } | 2745 | } |
2746 | memset(new + kdb_max_commands, 0, | 2746 | memset(new + kdb_max_commands, 0, |
2747 | kdb_command_extend * sizeof(*new)); | 2747 | kdb_command_extend * sizeof(*new)); |
2748 | kdb_commands = new; | 2748 | kdb_commands = new; |
2749 | kp = kdb_commands + kdb_max_commands - KDB_BASE_CMD_MAX; | 2749 | kp = kdb_commands + kdb_max_commands - KDB_BASE_CMD_MAX; |
2750 | kdb_max_commands += kdb_command_extend; | 2750 | kdb_max_commands += kdb_command_extend; |
2751 | } | 2751 | } |
2752 | 2752 | ||
2753 | kp->cmd_name = cmd; | 2753 | kp->cmd_name = cmd; |
2754 | kp->cmd_func = func; | 2754 | kp->cmd_func = func; |
2755 | kp->cmd_usage = usage; | 2755 | kp->cmd_usage = usage; |
2756 | kp->cmd_help = help; | 2756 | kp->cmd_help = help; |
2757 | kp->cmd_flags = 0; | 2757 | kp->cmd_flags = 0; |
2758 | kp->cmd_minlen = minlen; | 2758 | kp->cmd_minlen = minlen; |
2759 | kp->cmd_repeat = repeat; | 2759 | kp->cmd_repeat = repeat; |
2760 | 2760 | ||
2761 | return 0; | 2761 | return 0; |
2762 | } | 2762 | } |
2763 | EXPORT_SYMBOL_GPL(kdb_register_repeat); | 2763 | EXPORT_SYMBOL_GPL(kdb_register_repeat); |
2764 | 2764 | ||
2765 | 2765 | ||
2766 | /* | 2766 | /* |
2767 | * kdb_register - Compatibility register function for commands that do | 2767 | * kdb_register - Compatibility register function for commands that do |
2768 | * not need to specify a repeat state. Equivalent to | 2768 | * not need to specify a repeat state. Equivalent to |
2769 | * kdb_register_repeat with KDB_REPEAT_NONE. | 2769 | * kdb_register_repeat with KDB_REPEAT_NONE. |
2770 | * Inputs: | 2770 | * Inputs: |
2771 | * cmd Command name | 2771 | * cmd Command name |
2772 | * func Function to execute the command | 2772 | * func Function to execute the command |
2773 | * usage A simple usage string showing arguments | 2773 | * usage A simple usage string showing arguments |
2774 | * help A simple help string describing command | 2774 | * help A simple help string describing command |
2775 | * Returns: | 2775 | * Returns: |
2776 | * zero for success, one if a duplicate command. | 2776 | * zero for success, one if a duplicate command. |
2777 | */ | 2777 | */ |
2778 | int kdb_register(char *cmd, | 2778 | int kdb_register(char *cmd, |
2779 | kdb_func_t func, | 2779 | kdb_func_t func, |
2780 | char *usage, | 2780 | char *usage, |
2781 | char *help, | 2781 | char *help, |
2782 | short minlen) | 2782 | short minlen) |
2783 | { | 2783 | { |
2784 | return kdb_register_repeat(cmd, func, usage, help, minlen, | 2784 | return kdb_register_repeat(cmd, func, usage, help, minlen, |
2785 | KDB_REPEAT_NONE); | 2785 | KDB_REPEAT_NONE); |
2786 | } | 2786 | } |
2787 | EXPORT_SYMBOL_GPL(kdb_register); | 2787 | EXPORT_SYMBOL_GPL(kdb_register); |
2788 | 2788 | ||
2789 | /* | 2789 | /* |
2790 | * kdb_unregister - This function is used to unregister a kernel | 2790 | * kdb_unregister - This function is used to unregister a kernel |
2791 | * debugger command. It is generally called when a module which | 2791 | * debugger command. It is generally called when a module which |
2792 | * implements kdb commands is unloaded. | 2792 | * implements kdb commands is unloaded. |
2793 | * Inputs: | 2793 | * Inputs: |
2794 | * cmd Command name | 2794 | * cmd Command name |
2795 | * Returns: | 2795 | * Returns: |
2796 | * zero for success, one command not registered. | 2796 | * zero for success, one command not registered. |
2797 | */ | 2797 | */ |
2798 | int kdb_unregister(char *cmd) | 2798 | int kdb_unregister(char *cmd) |
2799 | { | 2799 | { |
2800 | int i; | 2800 | int i; |
2801 | kdbtab_t *kp; | 2801 | kdbtab_t *kp; |
2802 | 2802 | ||
2803 | /* | 2803 | /* |
2804 | * find the command. | 2804 | * find the command. |
2805 | */ | 2805 | */ |
2806 | for_each_kdbcmd(kp, i) { | 2806 | for_each_kdbcmd(kp, i) { |
2807 | if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) { | 2807 | if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) { |
2808 | kp->cmd_name = NULL; | 2808 | kp->cmd_name = NULL; |
2809 | return 0; | 2809 | return 0; |
2810 | } | 2810 | } |
2811 | } | 2811 | } |
2812 | 2812 | ||
2813 | /* Couldn't find it. */ | 2813 | /* Couldn't find it. */ |
2814 | return 1; | 2814 | return 1; |
2815 | } | 2815 | } |
2816 | EXPORT_SYMBOL_GPL(kdb_unregister); | 2816 | EXPORT_SYMBOL_GPL(kdb_unregister); |
2817 | 2817 | ||
2818 | /* Initialize the kdb command table. */ | 2818 | /* Initialize the kdb command table. */ |
2819 | static void __init kdb_inittab(void) | 2819 | static void __init kdb_inittab(void) |
2820 | { | 2820 | { |
2821 | int i; | 2821 | int i; |
2822 | kdbtab_t *kp; | 2822 | kdbtab_t *kp; |
2823 | 2823 | ||
2824 | for_each_kdbcmd(kp, i) | 2824 | for_each_kdbcmd(kp, i) |
2825 | kp->cmd_name = NULL; | 2825 | kp->cmd_name = NULL; |
2826 | 2826 | ||
2827 | kdb_register_repeat("md", kdb_md, "<vaddr>", | 2827 | kdb_register_repeat("md", kdb_md, "<vaddr>", |
2828 | "Display Memory Contents, also mdWcN, e.g. md8c1", 1, | 2828 | "Display Memory Contents, also mdWcN, e.g. md8c1", 1, |
2829 | KDB_REPEAT_NO_ARGS); | 2829 | KDB_REPEAT_NO_ARGS); |
2830 | kdb_register_repeat("mdr", kdb_md, "<vaddr> <bytes>", | 2830 | kdb_register_repeat("mdr", kdb_md, "<vaddr> <bytes>", |
2831 | "Display Raw Memory", 0, KDB_REPEAT_NO_ARGS); | 2831 | "Display Raw Memory", 0, KDB_REPEAT_NO_ARGS); |
2832 | kdb_register_repeat("mdp", kdb_md, "<paddr> <bytes>", | 2832 | kdb_register_repeat("mdp", kdb_md, "<paddr> <bytes>", |
2833 | "Display Physical Memory", 0, KDB_REPEAT_NO_ARGS); | 2833 | "Display Physical Memory", 0, KDB_REPEAT_NO_ARGS); |
2834 | kdb_register_repeat("mds", kdb_md, "<vaddr>", | 2834 | kdb_register_repeat("mds", kdb_md, "<vaddr>", |
2835 | "Display Memory Symbolically", 0, KDB_REPEAT_NO_ARGS); | 2835 | "Display Memory Symbolically", 0, KDB_REPEAT_NO_ARGS); |
2836 | kdb_register_repeat("mm", kdb_mm, "<vaddr> <contents>", | 2836 | kdb_register_repeat("mm", kdb_mm, "<vaddr> <contents>", |
2837 | "Modify Memory Contents", 0, KDB_REPEAT_NO_ARGS); | 2837 | "Modify Memory Contents", 0, KDB_REPEAT_NO_ARGS); |
2838 | kdb_register_repeat("go", kdb_go, "[<vaddr>]", | 2838 | kdb_register_repeat("go", kdb_go, "[<vaddr>]", |
2839 | "Continue Execution", 1, KDB_REPEAT_NONE); | 2839 | "Continue Execution", 1, KDB_REPEAT_NONE); |
2840 | kdb_register_repeat("rd", kdb_rd, "", | 2840 | kdb_register_repeat("rd", kdb_rd, "", |
2841 | "Display Registers", 0, KDB_REPEAT_NONE); | 2841 | "Display Registers", 0, KDB_REPEAT_NONE); |
2842 | kdb_register_repeat("rm", kdb_rm, "<reg> <contents>", | 2842 | kdb_register_repeat("rm", kdb_rm, "<reg> <contents>", |
2843 | "Modify Registers", 0, KDB_REPEAT_NONE); | 2843 | "Modify Registers", 0, KDB_REPEAT_NONE); |
2844 | kdb_register_repeat("ef", kdb_ef, "<vaddr>", | 2844 | kdb_register_repeat("ef", kdb_ef, "<vaddr>", |
2845 | "Display exception frame", 0, KDB_REPEAT_NONE); | 2845 | "Display exception frame", 0, KDB_REPEAT_NONE); |
2846 | kdb_register_repeat("bt", kdb_bt, "[<vaddr>]", | 2846 | kdb_register_repeat("bt", kdb_bt, "[<vaddr>]", |
2847 | "Stack traceback", 1, KDB_REPEAT_NONE); | 2847 | "Stack traceback", 1, KDB_REPEAT_NONE); |
2848 | kdb_register_repeat("btp", kdb_bt, "<pid>", | 2848 | kdb_register_repeat("btp", kdb_bt, "<pid>", |
2849 | "Display stack for process <pid>", 0, KDB_REPEAT_NONE); | 2849 | "Display stack for process <pid>", 0, KDB_REPEAT_NONE); |
2850 | kdb_register_repeat("bta", kdb_bt, "[DRSTCZEUIMA]", | 2850 | kdb_register_repeat("bta", kdb_bt, "[DRSTCZEUIMA]", |
2851 | "Display stack all processes", 0, KDB_REPEAT_NONE); | 2851 | "Display stack all processes", 0, KDB_REPEAT_NONE); |
2852 | kdb_register_repeat("btc", kdb_bt, "", | 2852 | kdb_register_repeat("btc", kdb_bt, "", |
2853 | "Backtrace current process on each cpu", 0, KDB_REPEAT_NONE); | 2853 | "Backtrace current process on each cpu", 0, KDB_REPEAT_NONE); |
2854 | kdb_register_repeat("btt", kdb_bt, "<vaddr>", | 2854 | kdb_register_repeat("btt", kdb_bt, "<vaddr>", |
2855 | "Backtrace process given its struct task address", 0, | 2855 | "Backtrace process given its struct task address", 0, |
2856 | KDB_REPEAT_NONE); | 2856 | KDB_REPEAT_NONE); |
2857 | kdb_register_repeat("ll", kdb_ll, "<first-element> <linkoffset> <cmd>", | 2857 | kdb_register_repeat("ll", kdb_ll, "<first-element> <linkoffset> <cmd>", |
2858 | "Execute cmd for each element in linked list", 0, KDB_REPEAT_NONE); | 2858 | "Execute cmd for each element in linked list", 0, KDB_REPEAT_NONE); |
2859 | kdb_register_repeat("env", kdb_env, "", | 2859 | kdb_register_repeat("env", kdb_env, "", |
2860 | "Show environment variables", 0, KDB_REPEAT_NONE); | 2860 | "Show environment variables", 0, KDB_REPEAT_NONE); |
2861 | kdb_register_repeat("set", kdb_set, "", | 2861 | kdb_register_repeat("set", kdb_set, "", |
2862 | "Set environment variables", 0, KDB_REPEAT_NONE); | 2862 | "Set environment variables", 0, KDB_REPEAT_NONE); |
2863 | kdb_register_repeat("help", kdb_help, "", | 2863 | kdb_register_repeat("help", kdb_help, "", |
2864 | "Display Help Message", 1, KDB_REPEAT_NONE); | 2864 | "Display Help Message", 1, KDB_REPEAT_NONE); |
2865 | kdb_register_repeat("?", kdb_help, "", | 2865 | kdb_register_repeat("?", kdb_help, "", |
2866 | "Display Help Message", 0, KDB_REPEAT_NONE); | 2866 | "Display Help Message", 0, KDB_REPEAT_NONE); |
2867 | kdb_register_repeat("cpu", kdb_cpu, "<cpunum>", | 2867 | kdb_register_repeat("cpu", kdb_cpu, "<cpunum>", |
2868 | "Switch to new cpu", 0, KDB_REPEAT_NONE); | 2868 | "Switch to new cpu", 0, KDB_REPEAT_NONE); |
2869 | kdb_register_repeat("kgdb", kdb_kgdb, "", | 2869 | kdb_register_repeat("kgdb", kdb_kgdb, "", |
2870 | "Enter kgdb mode", 0, KDB_REPEAT_NONE); | 2870 | "Enter kgdb mode", 0, KDB_REPEAT_NONE); |
2871 | kdb_register_repeat("ps", kdb_ps, "[<flags>|A]", | 2871 | kdb_register_repeat("ps", kdb_ps, "[<flags>|A]", |
2872 | "Display active task list", 0, KDB_REPEAT_NONE); | 2872 | "Display active task list", 0, KDB_REPEAT_NONE); |
2873 | kdb_register_repeat("pid", kdb_pid, "<pidnum>", | 2873 | kdb_register_repeat("pid", kdb_pid, "<pidnum>", |
2874 | "Switch to another task", 0, KDB_REPEAT_NONE); | 2874 | "Switch to another task", 0, KDB_REPEAT_NONE); |
2875 | kdb_register_repeat("reboot", kdb_reboot, "", | 2875 | kdb_register_repeat("reboot", kdb_reboot, "", |
2876 | "Reboot the machine immediately", 0, KDB_REPEAT_NONE); | 2876 | "Reboot the machine immediately", 0, KDB_REPEAT_NONE); |
2877 | #if defined(CONFIG_MODULES) | 2877 | #if defined(CONFIG_MODULES) |
2878 | kdb_register_repeat("lsmod", kdb_lsmod, "", | 2878 | kdb_register_repeat("lsmod", kdb_lsmod, "", |
2879 | "List loaded kernel modules", 0, KDB_REPEAT_NONE); | 2879 | "List loaded kernel modules", 0, KDB_REPEAT_NONE); |
2880 | #endif | 2880 | #endif |
2881 | #if defined(CONFIG_MAGIC_SYSRQ) | 2881 | #if defined(CONFIG_MAGIC_SYSRQ) |
2882 | kdb_register_repeat("sr", kdb_sr, "<key>", | 2882 | kdb_register_repeat("sr", kdb_sr, "<key>", |
2883 | "Magic SysRq key", 0, KDB_REPEAT_NONE); | 2883 | "Magic SysRq key", 0, KDB_REPEAT_NONE); |
2884 | #endif | 2884 | #endif |
2885 | #if defined(CONFIG_PRINTK) | 2885 | #if defined(CONFIG_PRINTK) |
2886 | kdb_register_repeat("dmesg", kdb_dmesg, "[lines]", | 2886 | kdb_register_repeat("dmesg", kdb_dmesg, "[lines]", |
2887 | "Display syslog buffer", 0, KDB_REPEAT_NONE); | 2887 | "Display syslog buffer", 0, KDB_REPEAT_NONE); |
2888 | #endif | 2888 | #endif |
2889 | kdb_register_repeat("defcmd", kdb_defcmd, "name \"usage\" \"help\"", | 2889 | kdb_register_repeat("defcmd", kdb_defcmd, "name \"usage\" \"help\"", |
2890 | "Define a set of commands, down to endefcmd", 0, KDB_REPEAT_NONE); | 2890 | "Define a set of commands, down to endefcmd", 0, KDB_REPEAT_NONE); |
2891 | kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>", | 2891 | kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>", |
2892 | "Send a signal to a process", 0, KDB_REPEAT_NONE); | 2892 | "Send a signal to a process", 0, KDB_REPEAT_NONE); |
2893 | kdb_register_repeat("summary", kdb_summary, "", | 2893 | kdb_register_repeat("summary", kdb_summary, "", |
2894 | "Summarize the system", 4, KDB_REPEAT_NONE); | 2894 | "Summarize the system", 4, KDB_REPEAT_NONE); |
2895 | kdb_register_repeat("per_cpu", kdb_per_cpu, "", | 2895 | kdb_register_repeat("per_cpu", kdb_per_cpu, "<sym> [<bytes>] [<cpu>]", |
2896 | "Display per_cpu variables", 3, KDB_REPEAT_NONE); | 2896 | "Display per_cpu variables", 3, KDB_REPEAT_NONE); |
2897 | kdb_register_repeat("grephelp", kdb_grep_help, "", | 2897 | kdb_register_repeat("grephelp", kdb_grep_help, "", |
2898 | "Display help on | grep", 0, KDB_REPEAT_NONE); | 2898 | "Display help on | grep", 0, KDB_REPEAT_NONE); |
2899 | } | 2899 | } |
2900 | 2900 | ||
2901 | /* Execute any commands defined in kdb_cmds. */ | 2901 | /* Execute any commands defined in kdb_cmds. */ |
2902 | static void __init kdb_cmd_init(void) | 2902 | static void __init kdb_cmd_init(void) |
2903 | { | 2903 | { |
2904 | int i, diag; | 2904 | int i, diag; |
2905 | for (i = 0; kdb_cmds[i]; ++i) { | 2905 | for (i = 0; kdb_cmds[i]; ++i) { |
2906 | diag = kdb_parse(kdb_cmds[i]); | 2906 | diag = kdb_parse(kdb_cmds[i]); |
2907 | if (diag) | 2907 | if (diag) |
2908 | kdb_printf("kdb command %s failed, kdb diag %d\n", | 2908 | kdb_printf("kdb command %s failed, kdb diag %d\n", |
2909 | kdb_cmds[i], diag); | 2909 | kdb_cmds[i], diag); |
2910 | } | 2910 | } |
2911 | if (defcmd_in_progress) { | 2911 | if (defcmd_in_progress) { |
2912 | kdb_printf("Incomplete 'defcmd' set, forcing endefcmd\n"); | 2912 | kdb_printf("Incomplete 'defcmd' set, forcing endefcmd\n"); |
2913 | kdb_parse("endefcmd"); | 2913 | kdb_parse("endefcmd"); |
2914 | } | 2914 | } |
2915 | } | 2915 | } |
2916 | 2916 | ||
2917 | /* Initialize kdb_printf, breakpoint tables and kdb state */ | 2917 | /* Initialize kdb_printf, breakpoint tables and kdb state */ |
2918 | void __init kdb_init(int lvl) | 2918 | void __init kdb_init(int lvl) |
2919 | { | 2919 | { |
2920 | static int kdb_init_lvl = KDB_NOT_INITIALIZED; | 2920 | static int kdb_init_lvl = KDB_NOT_INITIALIZED; |
2921 | int i; | 2921 | int i; |
2922 | 2922 | ||
2923 | if (kdb_init_lvl == KDB_INIT_FULL || lvl <= kdb_init_lvl) | 2923 | if (kdb_init_lvl == KDB_INIT_FULL || lvl <= kdb_init_lvl) |
2924 | return; | 2924 | return; |
2925 | for (i = kdb_init_lvl; i < lvl; i++) { | 2925 | for (i = kdb_init_lvl; i < lvl; i++) { |
2926 | switch (i) { | 2926 | switch (i) { |
2927 | case KDB_NOT_INITIALIZED: | 2927 | case KDB_NOT_INITIALIZED: |
2928 | kdb_inittab(); /* Initialize Command Table */ | 2928 | kdb_inittab(); /* Initialize Command Table */ |
2929 | kdb_initbptab(); /* Initialize Breakpoints */ | 2929 | kdb_initbptab(); /* Initialize Breakpoints */ |
2930 | break; | 2930 | break; |
2931 | case KDB_INIT_EARLY: | 2931 | case KDB_INIT_EARLY: |
2932 | kdb_cmd_init(); /* Build kdb_cmds tables */ | 2932 | kdb_cmd_init(); /* Build kdb_cmds tables */ |
2933 | break; | 2933 | break; |
2934 | } | 2934 | } |
2935 | } | 2935 | } |
2936 | kdb_init_lvl = lvl; | 2936 | kdb_init_lvl = lvl; |
2937 | } | 2937 | } |
2938 | 2938 |