Commit 931ea24819f2bd40cca2dc214558bfcc3c91549e
1 parent
4aad8f51d0
Exists in
master
and in
39 other branches
kdb: fix per_cpu command to remove supress mask
Rusty pointed out that the per_cpu command uses up lots of space on the stack and the cpu supress mask is probably not needed. This patch removes the need for the supress mask as well as fixing up the following problems with the kdb per_cpu command: * The per_cpu command should allow an address as an argument * When you have more data than can be displayed on one screen allow the user to break out of the print loop. Reported-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Showing 1 changed file with 11 additions and 35 deletions Inline Diff
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[50]; |
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 == KDB_BASE_CMD_MAX ? cmd = kdb_commands : cmd++, num++) | 85 | num == KDB_BASE_CMD_MAX ? cmd = kdb_commands : cmd++, num++) |
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 = kmalloc((s->count + 1) * sizeof(*(s->command)), GFP_KDB); | 649 | s->command = kmalloc((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->pid); | 1130 | kdb_current, kdb_current->pid); |
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; | 2364 | int diag; |
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 | return 0; | 2403 | return 0; |
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 | return diag; | 2408 | return diag; |
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 | return 0; | 2412 | return 0; |
2413 | } | 2413 | } |
2414 | kfree(command); | 2414 | kfree(command); |
2415 | 2415 | ||
2416 | return 0; | 2416 | return 0; |
2417 | } | 2417 | } |
2418 | 2418 | ||
2419 | static int kdb_kgdb(int argc, const char **argv) | 2419 | static int kdb_kgdb(int argc, const char **argv) |
2420 | { | 2420 | { |
2421 | return KDB_CMD_KGDB; | 2421 | return KDB_CMD_KGDB; |
2422 | } | 2422 | } |
2423 | 2423 | ||
2424 | /* | 2424 | /* |
2425 | * kdb_help - This function implements the 'help' and '?' commands. | 2425 | * kdb_help - This function implements the 'help' and '?' commands. |
2426 | */ | 2426 | */ |
2427 | static int kdb_help(int argc, const char **argv) | 2427 | static int kdb_help(int argc, const char **argv) |
2428 | { | 2428 | { |
2429 | kdbtab_t *kt; | 2429 | kdbtab_t *kt; |
2430 | int i; | 2430 | int i; |
2431 | 2431 | ||
2432 | kdb_printf("%-15.15s %-20.20s %s\n", "Command", "Usage", "Description"); | 2432 | kdb_printf("%-15.15s %-20.20s %s\n", "Command", "Usage", "Description"); |
2433 | kdb_printf("-----------------------------" | 2433 | kdb_printf("-----------------------------" |
2434 | "-----------------------------\n"); | 2434 | "-----------------------------\n"); |
2435 | for_each_kdbcmd(kt, i) { | 2435 | for_each_kdbcmd(kt, i) { |
2436 | if (kt->cmd_name) | 2436 | if (kt->cmd_name) |
2437 | kdb_printf("%-15.15s %-20.20s %s\n", kt->cmd_name, | 2437 | kdb_printf("%-15.15s %-20.20s %s\n", kt->cmd_name, |
2438 | kt->cmd_usage, kt->cmd_help); | 2438 | kt->cmd_usage, kt->cmd_help); |
2439 | if (KDB_FLAG(CMD_INTERRUPT)) | 2439 | if (KDB_FLAG(CMD_INTERRUPT)) |
2440 | return 0; | 2440 | return 0; |
2441 | } | 2441 | } |
2442 | return 0; | 2442 | return 0; |
2443 | } | 2443 | } |
2444 | 2444 | ||
2445 | /* | 2445 | /* |
2446 | * kdb_kill - This function implements the 'kill' commands. | 2446 | * kdb_kill - This function implements the 'kill' commands. |
2447 | */ | 2447 | */ |
2448 | static int kdb_kill(int argc, const char **argv) | 2448 | static int kdb_kill(int argc, const char **argv) |
2449 | { | 2449 | { |
2450 | long sig, pid; | 2450 | long sig, pid; |
2451 | char *endp; | 2451 | char *endp; |
2452 | struct task_struct *p; | 2452 | struct task_struct *p; |
2453 | struct siginfo info; | 2453 | struct siginfo info; |
2454 | 2454 | ||
2455 | if (argc != 2) | 2455 | if (argc != 2) |
2456 | return KDB_ARGCOUNT; | 2456 | return KDB_ARGCOUNT; |
2457 | 2457 | ||
2458 | sig = simple_strtol(argv[1], &endp, 0); | 2458 | sig = simple_strtol(argv[1], &endp, 0); |
2459 | if (*endp) | 2459 | if (*endp) |
2460 | return KDB_BADINT; | 2460 | return KDB_BADINT; |
2461 | if (sig >= 0) { | 2461 | if (sig >= 0) { |
2462 | kdb_printf("Invalid signal parameter.<-signal>\n"); | 2462 | kdb_printf("Invalid signal parameter.<-signal>\n"); |
2463 | return 0; | 2463 | return 0; |
2464 | } | 2464 | } |
2465 | sig = -sig; | 2465 | sig = -sig; |
2466 | 2466 | ||
2467 | pid = simple_strtol(argv[2], &endp, 0); | 2467 | pid = simple_strtol(argv[2], &endp, 0); |
2468 | if (*endp) | 2468 | if (*endp) |
2469 | return KDB_BADINT; | 2469 | return KDB_BADINT; |
2470 | if (pid <= 0) { | 2470 | if (pid <= 0) { |
2471 | kdb_printf("Process ID must be large than 0.\n"); | 2471 | kdb_printf("Process ID must be large than 0.\n"); |
2472 | return 0; | 2472 | return 0; |
2473 | } | 2473 | } |
2474 | 2474 | ||
2475 | /* Find the process. */ | 2475 | /* Find the process. */ |
2476 | p = find_task_by_pid_ns(pid, &init_pid_ns); | 2476 | p = find_task_by_pid_ns(pid, &init_pid_ns); |
2477 | if (!p) { | 2477 | if (!p) { |
2478 | kdb_printf("The specified process isn't found.\n"); | 2478 | kdb_printf("The specified process isn't found.\n"); |
2479 | return 0; | 2479 | return 0; |
2480 | } | 2480 | } |
2481 | p = p->group_leader; | 2481 | p = p->group_leader; |
2482 | info.si_signo = sig; | 2482 | info.si_signo = sig; |
2483 | info.si_errno = 0; | 2483 | info.si_errno = 0; |
2484 | info.si_code = SI_USER; | 2484 | info.si_code = SI_USER; |
2485 | info.si_pid = pid; /* same capabilities as process being signalled */ | 2485 | info.si_pid = pid; /* same capabilities as process being signalled */ |
2486 | info.si_uid = 0; /* kdb has root authority */ | 2486 | info.si_uid = 0; /* kdb has root authority */ |
2487 | kdb_send_sig_info(p, &info); | 2487 | kdb_send_sig_info(p, &info); |
2488 | return 0; | 2488 | return 0; |
2489 | } | 2489 | } |
2490 | 2490 | ||
2491 | struct kdb_tm { | 2491 | struct kdb_tm { |
2492 | int tm_sec; /* seconds */ | 2492 | int tm_sec; /* seconds */ |
2493 | int tm_min; /* minutes */ | 2493 | int tm_min; /* minutes */ |
2494 | int tm_hour; /* hours */ | 2494 | int tm_hour; /* hours */ |
2495 | int tm_mday; /* day of the month */ | 2495 | int tm_mday; /* day of the month */ |
2496 | int tm_mon; /* month */ | 2496 | int tm_mon; /* month */ |
2497 | int tm_year; /* year */ | 2497 | int tm_year; /* year */ |
2498 | }; | 2498 | }; |
2499 | 2499 | ||
2500 | static void kdb_gmtime(struct timespec *tv, struct kdb_tm *tm) | 2500 | static void kdb_gmtime(struct timespec *tv, struct kdb_tm *tm) |
2501 | { | 2501 | { |
2502 | /* This will work from 1970-2099, 2100 is not a leap year */ | 2502 | /* This will work from 1970-2099, 2100 is not a leap year */ |
2503 | static int mon_day[] = { 31, 29, 31, 30, 31, 30, 31, | 2503 | static int mon_day[] = { 31, 29, 31, 30, 31, 30, 31, |
2504 | 31, 30, 31, 30, 31 }; | 2504 | 31, 30, 31, 30, 31 }; |
2505 | memset(tm, 0, sizeof(*tm)); | 2505 | memset(tm, 0, sizeof(*tm)); |
2506 | tm->tm_sec = tv->tv_sec % (24 * 60 * 60); | 2506 | tm->tm_sec = tv->tv_sec % (24 * 60 * 60); |
2507 | tm->tm_mday = tv->tv_sec / (24 * 60 * 60) + | 2507 | tm->tm_mday = tv->tv_sec / (24 * 60 * 60) + |
2508 | (2 * 365 + 1); /* shift base from 1970 to 1968 */ | 2508 | (2 * 365 + 1); /* shift base from 1970 to 1968 */ |
2509 | tm->tm_min = tm->tm_sec / 60 % 60; | 2509 | tm->tm_min = tm->tm_sec / 60 % 60; |
2510 | tm->tm_hour = tm->tm_sec / 60 / 60; | 2510 | tm->tm_hour = tm->tm_sec / 60 / 60; |
2511 | tm->tm_sec = tm->tm_sec % 60; | 2511 | tm->tm_sec = tm->tm_sec % 60; |
2512 | tm->tm_year = 68 + 4*(tm->tm_mday / (4*365+1)); | 2512 | tm->tm_year = 68 + 4*(tm->tm_mday / (4*365+1)); |
2513 | tm->tm_mday %= (4*365+1); | 2513 | tm->tm_mday %= (4*365+1); |
2514 | mon_day[1] = 29; | 2514 | mon_day[1] = 29; |
2515 | while (tm->tm_mday >= mon_day[tm->tm_mon]) { | 2515 | while (tm->tm_mday >= mon_day[tm->tm_mon]) { |
2516 | tm->tm_mday -= mon_day[tm->tm_mon]; | 2516 | tm->tm_mday -= mon_day[tm->tm_mon]; |
2517 | if (++tm->tm_mon == 12) { | 2517 | if (++tm->tm_mon == 12) { |
2518 | tm->tm_mon = 0; | 2518 | tm->tm_mon = 0; |
2519 | ++tm->tm_year; | 2519 | ++tm->tm_year; |
2520 | mon_day[1] = 28; | 2520 | mon_day[1] = 28; |
2521 | } | 2521 | } |
2522 | } | 2522 | } |
2523 | ++tm->tm_mday; | 2523 | ++tm->tm_mday; |
2524 | } | 2524 | } |
2525 | 2525 | ||
2526 | /* | 2526 | /* |
2527 | * Most of this code has been lifted from kernel/timer.c::sys_sysinfo(). | 2527 | * Most of this code has been lifted from kernel/timer.c::sys_sysinfo(). |
2528 | * I cannot call that code directly from kdb, it has an unconditional | 2528 | * I cannot call that code directly from kdb, it has an unconditional |
2529 | * cli()/sti() and calls routines that take locks which can stop the debugger. | 2529 | * cli()/sti() and calls routines that take locks which can stop the debugger. |
2530 | */ | 2530 | */ |
2531 | static void kdb_sysinfo(struct sysinfo *val) | 2531 | static void kdb_sysinfo(struct sysinfo *val) |
2532 | { | 2532 | { |
2533 | struct timespec uptime; | 2533 | struct timespec uptime; |
2534 | do_posix_clock_monotonic_gettime(&uptime); | 2534 | do_posix_clock_monotonic_gettime(&uptime); |
2535 | memset(val, 0, sizeof(*val)); | 2535 | memset(val, 0, sizeof(*val)); |
2536 | val->uptime = uptime.tv_sec; | 2536 | val->uptime = uptime.tv_sec; |
2537 | val->loads[0] = avenrun[0]; | 2537 | val->loads[0] = avenrun[0]; |
2538 | val->loads[1] = avenrun[1]; | 2538 | val->loads[1] = avenrun[1]; |
2539 | val->loads[2] = avenrun[2]; | 2539 | val->loads[2] = avenrun[2]; |
2540 | val->procs = nr_threads-1; | 2540 | val->procs = nr_threads-1; |
2541 | si_meminfo(val); | 2541 | si_meminfo(val); |
2542 | 2542 | ||
2543 | return; | 2543 | return; |
2544 | } | 2544 | } |
2545 | 2545 | ||
2546 | /* | 2546 | /* |
2547 | * kdb_summary - This function implements the 'summary' command. | 2547 | * kdb_summary - This function implements the 'summary' command. |
2548 | */ | 2548 | */ |
2549 | static int kdb_summary(int argc, const char **argv) | 2549 | static int kdb_summary(int argc, const char **argv) |
2550 | { | 2550 | { |
2551 | struct timespec now; | 2551 | struct timespec now; |
2552 | struct kdb_tm tm; | 2552 | struct kdb_tm tm; |
2553 | struct sysinfo val; | 2553 | struct sysinfo val; |
2554 | 2554 | ||
2555 | if (argc) | 2555 | if (argc) |
2556 | return KDB_ARGCOUNT; | 2556 | return KDB_ARGCOUNT; |
2557 | 2557 | ||
2558 | kdb_printf("sysname %s\n", init_uts_ns.name.sysname); | 2558 | kdb_printf("sysname %s\n", init_uts_ns.name.sysname); |
2559 | kdb_printf("release %s\n", init_uts_ns.name.release); | 2559 | kdb_printf("release %s\n", init_uts_ns.name.release); |
2560 | kdb_printf("version %s\n", init_uts_ns.name.version); | 2560 | kdb_printf("version %s\n", init_uts_ns.name.version); |
2561 | kdb_printf("machine %s\n", init_uts_ns.name.machine); | 2561 | kdb_printf("machine %s\n", init_uts_ns.name.machine); |
2562 | kdb_printf("nodename %s\n", init_uts_ns.name.nodename); | 2562 | kdb_printf("nodename %s\n", init_uts_ns.name.nodename); |
2563 | kdb_printf("domainname %s\n", init_uts_ns.name.domainname); | 2563 | kdb_printf("domainname %s\n", init_uts_ns.name.domainname); |
2564 | kdb_printf("ccversion %s\n", __stringify(CCVERSION)); | 2564 | kdb_printf("ccversion %s\n", __stringify(CCVERSION)); |
2565 | 2565 | ||
2566 | now = __current_kernel_time(); | 2566 | now = __current_kernel_time(); |
2567 | kdb_gmtime(&now, &tm); | 2567 | kdb_gmtime(&now, &tm); |
2568 | kdb_printf("date %04d-%02d-%02d %02d:%02d:%02d " | 2568 | kdb_printf("date %04d-%02d-%02d %02d:%02d:%02d " |
2569 | "tz_minuteswest %d\n", | 2569 | "tz_minuteswest %d\n", |
2570 | 1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday, | 2570 | 1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday, |
2571 | tm.tm_hour, tm.tm_min, tm.tm_sec, | 2571 | tm.tm_hour, tm.tm_min, tm.tm_sec, |
2572 | sys_tz.tz_minuteswest); | 2572 | sys_tz.tz_minuteswest); |
2573 | 2573 | ||
2574 | kdb_sysinfo(&val); | 2574 | kdb_sysinfo(&val); |
2575 | kdb_printf("uptime "); | 2575 | kdb_printf("uptime "); |
2576 | if (val.uptime > (24*60*60)) { | 2576 | if (val.uptime > (24*60*60)) { |
2577 | int days = val.uptime / (24*60*60); | 2577 | int days = val.uptime / (24*60*60); |
2578 | val.uptime %= (24*60*60); | 2578 | val.uptime %= (24*60*60); |
2579 | kdb_printf("%d day%s ", days, days == 1 ? "" : "s"); | 2579 | kdb_printf("%d day%s ", days, days == 1 ? "" : "s"); |
2580 | } | 2580 | } |
2581 | kdb_printf("%02ld:%02ld\n", val.uptime/(60*60), (val.uptime/60)%60); | 2581 | kdb_printf("%02ld:%02ld\n", val.uptime/(60*60), (val.uptime/60)%60); |
2582 | 2582 | ||
2583 | /* lifted from fs/proc/proc_misc.c::loadavg_read_proc() */ | 2583 | /* lifted from fs/proc/proc_misc.c::loadavg_read_proc() */ |
2584 | 2584 | ||
2585 | #define LOAD_INT(x) ((x) >> FSHIFT) | 2585 | #define LOAD_INT(x) ((x) >> FSHIFT) |
2586 | #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) | 2586 | #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) |
2587 | kdb_printf("load avg %ld.%02ld %ld.%02ld %ld.%02ld\n", | 2587 | kdb_printf("load avg %ld.%02ld %ld.%02ld %ld.%02ld\n", |
2588 | LOAD_INT(val.loads[0]), LOAD_FRAC(val.loads[0]), | 2588 | LOAD_INT(val.loads[0]), LOAD_FRAC(val.loads[0]), |
2589 | LOAD_INT(val.loads[1]), LOAD_FRAC(val.loads[1]), | 2589 | LOAD_INT(val.loads[1]), LOAD_FRAC(val.loads[1]), |
2590 | LOAD_INT(val.loads[2]), LOAD_FRAC(val.loads[2])); | 2590 | LOAD_INT(val.loads[2]), LOAD_FRAC(val.loads[2])); |
2591 | #undef LOAD_INT | 2591 | #undef LOAD_INT |
2592 | #undef LOAD_FRAC | 2592 | #undef LOAD_FRAC |
2593 | /* Display in kilobytes */ | 2593 | /* Display in kilobytes */ |
2594 | #define K(x) ((x) << (PAGE_SHIFT - 10)) | 2594 | #define K(x) ((x) << (PAGE_SHIFT - 10)) |
2595 | kdb_printf("\nMemTotal: %8lu kB\nMemFree: %8lu kB\n" | 2595 | kdb_printf("\nMemTotal: %8lu kB\nMemFree: %8lu kB\n" |
2596 | "Buffers: %8lu kB\n", | 2596 | "Buffers: %8lu kB\n", |
2597 | val.totalram, val.freeram, val.bufferram); | 2597 | val.totalram, val.freeram, val.bufferram); |
2598 | return 0; | 2598 | return 0; |
2599 | } | 2599 | } |
2600 | 2600 | ||
2601 | /* | 2601 | /* |
2602 | * kdb_per_cpu - This function implements the 'per_cpu' command. | 2602 | * kdb_per_cpu - This function implements the 'per_cpu' command. |
2603 | */ | 2603 | */ |
2604 | static int kdb_per_cpu(int argc, const char **argv) | 2604 | static int kdb_per_cpu(int argc, const char **argv) |
2605 | { | 2605 | { |
2606 | char buf[256], fmtstr[64]; | 2606 | char fmtstr[64]; |
2607 | kdb_symtab_t symtab; | 2607 | int cpu, diag, nextarg = 1; |
2608 | cpumask_t suppress = CPU_MASK_NONE; | 2608 | unsigned long addr, symaddr, val, bytesperword = 0, whichcpu = ~0UL; |
2609 | int cpu, diag; | ||
2610 | unsigned long addr, val, bytesperword = 0, whichcpu = ~0UL; | ||
2611 | 2609 | ||
2612 | if (argc < 1 || argc > 3) | 2610 | if (argc < 1 || argc > 3) |
2613 | return KDB_ARGCOUNT; | 2611 | return KDB_ARGCOUNT; |
2614 | 2612 | ||
2615 | snprintf(buf, sizeof(buf), "per_cpu__%s", argv[1]); | 2613 | diag = kdbgetaddrarg(argc, argv, &nextarg, &symaddr, NULL, NULL); |
2616 | if (!kdbgetsymval(buf, &symtab)) { | 2614 | if (diag) |
2617 | kdb_printf("%s is not a per_cpu variable\n", argv[1]); | 2615 | return diag; |
2618 | return KDB_BADADDR; | 2616 | |
2619 | } | ||
2620 | if (argc >= 2) { | 2617 | if (argc >= 2) { |
2621 | diag = kdbgetularg(argv[2], &bytesperword); | 2618 | diag = kdbgetularg(argv[2], &bytesperword); |
2622 | if (diag) | 2619 | if (diag) |
2623 | return diag; | 2620 | return diag; |
2624 | } | 2621 | } |
2625 | if (!bytesperword) | 2622 | if (!bytesperword) |
2626 | bytesperword = KDB_WORD_SIZE; | 2623 | bytesperword = KDB_WORD_SIZE; |
2627 | else if (bytesperword > KDB_WORD_SIZE) | 2624 | else if (bytesperword > KDB_WORD_SIZE) |
2628 | return KDB_BADWIDTH; | 2625 | return KDB_BADWIDTH; |
2629 | sprintf(fmtstr, "%%0%dlx ", (int)(2*bytesperword)); | 2626 | sprintf(fmtstr, "%%0%dlx ", (int)(2*bytesperword)); |
2630 | if (argc >= 3) { | 2627 | if (argc >= 3) { |
2631 | diag = kdbgetularg(argv[3], &whichcpu); | 2628 | diag = kdbgetularg(argv[3], &whichcpu); |
2632 | if (diag) | 2629 | if (diag) |
2633 | return diag; | 2630 | return diag; |
2634 | if (!cpu_online(whichcpu)) { | 2631 | if (!cpu_online(whichcpu)) { |
2635 | kdb_printf("cpu %ld is not online\n", whichcpu); | 2632 | kdb_printf("cpu %ld is not online\n", whichcpu); |
2636 | return KDB_BADCPUNUM; | 2633 | return KDB_BADCPUNUM; |
2637 | } | 2634 | } |
2638 | } | 2635 | } |
2639 | 2636 | ||
2640 | /* Most architectures use __per_cpu_offset[cpu], some use | 2637 | /* Most architectures use __per_cpu_offset[cpu], some use |
2641 | * __per_cpu_offset(cpu), smp has no __per_cpu_offset. | 2638 | * __per_cpu_offset(cpu), smp has no __per_cpu_offset. |
2642 | */ | 2639 | */ |
2643 | #ifdef __per_cpu_offset | 2640 | #ifdef __per_cpu_offset |
2644 | #define KDB_PCU(cpu) __per_cpu_offset(cpu) | 2641 | #define KDB_PCU(cpu) __per_cpu_offset(cpu) |
2645 | #else | 2642 | #else |
2646 | #ifdef CONFIG_SMP | 2643 | #ifdef CONFIG_SMP |
2647 | #define KDB_PCU(cpu) __per_cpu_offset[cpu] | 2644 | #define KDB_PCU(cpu) __per_cpu_offset[cpu] |
2648 | #else | 2645 | #else |
2649 | #define KDB_PCU(cpu) 0 | 2646 | #define KDB_PCU(cpu) 0 |
2650 | #endif | 2647 | #endif |
2651 | #endif | 2648 | #endif |
2652 | |||
2653 | for_each_online_cpu(cpu) { | 2649 | for_each_online_cpu(cpu) { |
2650 | if (KDB_FLAG(CMD_INTERRUPT)) | ||
2651 | return 0; | ||
2652 | |||
2654 | if (whichcpu != ~0UL && whichcpu != cpu) | 2653 | if (whichcpu != ~0UL && whichcpu != cpu) |
2655 | continue; | 2654 | continue; |
2656 | addr = symtab.sym_start + KDB_PCU(cpu); | 2655 | addr = symaddr + KDB_PCU(cpu); |
2657 | diag = kdb_getword(&val, addr, bytesperword); | 2656 | diag = kdb_getword(&val, addr, bytesperword); |
2658 | if (diag) { | 2657 | if (diag) { |
2659 | kdb_printf("%5d " kdb_bfd_vma_fmt0 " - unable to " | 2658 | kdb_printf("%5d " kdb_bfd_vma_fmt0 " - unable to " |
2660 | "read, diag=%d\n", cpu, addr, diag); | 2659 | "read, diag=%d\n", cpu, addr, diag); |
2661 | continue; | 2660 | continue; |
2662 | } | 2661 | } |
2663 | #ifdef CONFIG_SMP | ||
2664 | if (!val) { | ||
2665 | cpu_set(cpu, suppress); | ||
2666 | continue; | ||
2667 | } | ||
2668 | #endif /* CONFIG_SMP */ | ||
2669 | kdb_printf("%5d ", cpu); | 2662 | kdb_printf("%5d ", cpu); |
2670 | kdb_md_line(fmtstr, addr, | 2663 | kdb_md_line(fmtstr, addr, |
2671 | bytesperword == KDB_WORD_SIZE, | 2664 | bytesperword == KDB_WORD_SIZE, |
2672 | 1, bytesperword, 1, 1, 0); | 2665 | 1, bytesperword, 1, 1, 0); |
2673 | } | 2666 | } |
2674 | if (cpus_weight(suppress) == 0) | ||
2675 | return 0; | ||
2676 | kdb_printf("Zero suppressed cpu(s):"); | ||
2677 | for (cpu = first_cpu(suppress); cpu < num_possible_cpus(); | ||
2678 | cpu = next_cpu(cpu, suppress)) { | ||
2679 | kdb_printf(" %d", cpu); | ||
2680 | if (cpu == num_possible_cpus() - 1 || | ||
2681 | next_cpu(cpu, suppress) != cpu + 1) | ||
2682 | continue; | ||
2683 | while (cpu < num_possible_cpus() && | ||
2684 | next_cpu(cpu, suppress) == cpu + 1) | ||
2685 | ++cpu; | ||
2686 | kdb_printf("-%d", cpu); | ||
2687 | } | ||
2688 | kdb_printf("\n"); | ||
2689 | |||
2690 | #undef KDB_PCU | 2667 | #undef KDB_PCU |
2691 | |||
2692 | return 0; | 2668 | return 0; |
2693 | } | 2669 | } |
2694 | 2670 | ||
2695 | /* | 2671 | /* |
2696 | * display help for the use of cmd | grep pattern | 2672 | * display help for the use of cmd | grep pattern |
2697 | */ | 2673 | */ |
2698 | static int kdb_grep_help(int argc, const char **argv) | 2674 | static int kdb_grep_help(int argc, const char **argv) |
2699 | { | 2675 | { |
2700 | kdb_printf("Usage of cmd args | grep pattern:\n"); | 2676 | kdb_printf("Usage of cmd args | grep pattern:\n"); |
2701 | kdb_printf(" Any command's output may be filtered through an "); | 2677 | kdb_printf(" Any command's output may be filtered through an "); |
2702 | kdb_printf("emulated 'pipe'.\n"); | 2678 | kdb_printf("emulated 'pipe'.\n"); |
2703 | kdb_printf(" 'grep' is just a key word.\n"); | 2679 | kdb_printf(" 'grep' is just a key word.\n"); |
2704 | kdb_printf(" The pattern may include a very limited set of " | 2680 | kdb_printf(" The pattern may include a very limited set of " |
2705 | "metacharacters:\n"); | 2681 | "metacharacters:\n"); |
2706 | kdb_printf(" pattern or ^pattern or pattern$ or ^pattern$\n"); | 2682 | kdb_printf(" pattern or ^pattern or pattern$ or ^pattern$\n"); |
2707 | kdb_printf(" And if there are spaces in the pattern, you may " | 2683 | kdb_printf(" And if there are spaces in the pattern, you may " |
2708 | "quote it:\n"); | 2684 | "quote it:\n"); |
2709 | kdb_printf(" \"pat tern\" or \"^pat tern\" or \"pat tern$\"" | 2685 | kdb_printf(" \"pat tern\" or \"^pat tern\" or \"pat tern$\"" |
2710 | " or \"^pat tern$\"\n"); | 2686 | " or \"^pat tern$\"\n"); |
2711 | return 0; | 2687 | return 0; |
2712 | } | 2688 | } |
2713 | 2689 | ||
2714 | /* | 2690 | /* |
2715 | * kdb_register_repeat - This function is used to register a kernel | 2691 | * kdb_register_repeat - This function is used to register a kernel |
2716 | * debugger command. | 2692 | * debugger command. |
2717 | * Inputs: | 2693 | * Inputs: |
2718 | * cmd Command name | 2694 | * cmd Command name |
2719 | * func Function to execute the command | 2695 | * func Function to execute the command |
2720 | * usage A simple usage string showing arguments | 2696 | * usage A simple usage string showing arguments |
2721 | * help A simple help string describing command | 2697 | * help A simple help string describing command |
2722 | * repeat Does the command auto repeat on enter? | 2698 | * repeat Does the command auto repeat on enter? |
2723 | * Returns: | 2699 | * Returns: |
2724 | * zero for success, one if a duplicate command. | 2700 | * zero for success, one if a duplicate command. |
2725 | */ | 2701 | */ |
2726 | #define kdb_command_extend 50 /* arbitrary */ | 2702 | #define kdb_command_extend 50 /* arbitrary */ |
2727 | int kdb_register_repeat(char *cmd, | 2703 | int kdb_register_repeat(char *cmd, |
2728 | kdb_func_t func, | 2704 | kdb_func_t func, |
2729 | char *usage, | 2705 | char *usage, |
2730 | char *help, | 2706 | char *help, |
2731 | short minlen, | 2707 | short minlen, |
2732 | kdb_repeat_t repeat) | 2708 | kdb_repeat_t repeat) |
2733 | { | 2709 | { |
2734 | int i; | 2710 | int i; |
2735 | kdbtab_t *kp; | 2711 | kdbtab_t *kp; |
2736 | 2712 | ||
2737 | /* | 2713 | /* |
2738 | * Brute force method to determine duplicates | 2714 | * Brute force method to determine duplicates |
2739 | */ | 2715 | */ |
2740 | for_each_kdbcmd(kp, i) { | 2716 | for_each_kdbcmd(kp, i) { |
2741 | if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) { | 2717 | if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) { |
2742 | kdb_printf("Duplicate kdb command registered: " | 2718 | kdb_printf("Duplicate kdb command registered: " |
2743 | "%s, func %p help %s\n", cmd, func, help); | 2719 | "%s, func %p help %s\n", cmd, func, help); |
2744 | return 1; | 2720 | return 1; |
2745 | } | 2721 | } |
2746 | } | 2722 | } |
2747 | 2723 | ||
2748 | /* | 2724 | /* |
2749 | * Insert command into first available location in table | 2725 | * Insert command into first available location in table |
2750 | */ | 2726 | */ |
2751 | for_each_kdbcmd(kp, i) { | 2727 | for_each_kdbcmd(kp, i) { |
2752 | if (kp->cmd_name == NULL) | 2728 | if (kp->cmd_name == NULL) |
2753 | break; | 2729 | break; |
2754 | } | 2730 | } |
2755 | 2731 | ||
2756 | if (i >= kdb_max_commands) { | 2732 | if (i >= kdb_max_commands) { |
2757 | kdbtab_t *new = kmalloc((kdb_max_commands - KDB_BASE_CMD_MAX + | 2733 | kdbtab_t *new = kmalloc((kdb_max_commands - KDB_BASE_CMD_MAX + |
2758 | kdb_command_extend) * sizeof(*new), GFP_KDB); | 2734 | kdb_command_extend) * sizeof(*new), GFP_KDB); |
2759 | if (!new) { | 2735 | if (!new) { |
2760 | kdb_printf("Could not allocate new kdb_command " | 2736 | kdb_printf("Could not allocate new kdb_command " |
2761 | "table\n"); | 2737 | "table\n"); |
2762 | return 1; | 2738 | return 1; |
2763 | } | 2739 | } |
2764 | if (kdb_commands) { | 2740 | if (kdb_commands) { |
2765 | memcpy(new, kdb_commands, | 2741 | memcpy(new, kdb_commands, |
2766 | kdb_max_commands * sizeof(*new)); | 2742 | kdb_max_commands * sizeof(*new)); |
2767 | kfree(kdb_commands); | 2743 | kfree(kdb_commands); |
2768 | } | 2744 | } |
2769 | memset(new + kdb_max_commands, 0, | 2745 | memset(new + kdb_max_commands, 0, |
2770 | kdb_command_extend * sizeof(*new)); | 2746 | kdb_command_extend * sizeof(*new)); |
2771 | kdb_commands = new; | 2747 | kdb_commands = new; |
2772 | kp = kdb_commands + kdb_max_commands; | 2748 | kp = kdb_commands + kdb_max_commands; |
2773 | kdb_max_commands += kdb_command_extend; | 2749 | kdb_max_commands += kdb_command_extend; |
2774 | } | 2750 | } |
2775 | 2751 | ||
2776 | kp->cmd_name = cmd; | 2752 | kp->cmd_name = cmd; |
2777 | kp->cmd_func = func; | 2753 | kp->cmd_func = func; |
2778 | kp->cmd_usage = usage; | 2754 | kp->cmd_usage = usage; |
2779 | kp->cmd_help = help; | 2755 | kp->cmd_help = help; |
2780 | kp->cmd_flags = 0; | 2756 | kp->cmd_flags = 0; |
2781 | kp->cmd_minlen = minlen; | 2757 | kp->cmd_minlen = minlen; |
2782 | kp->cmd_repeat = repeat; | 2758 | kp->cmd_repeat = repeat; |
2783 | 2759 | ||
2784 | return 0; | 2760 | return 0; |
2785 | } | 2761 | } |
2786 | EXPORT_SYMBOL_GPL(kdb_register_repeat); | 2762 | EXPORT_SYMBOL_GPL(kdb_register_repeat); |
2787 | 2763 | ||
2788 | 2764 | ||
2789 | /* | 2765 | /* |
2790 | * kdb_register - Compatibility register function for commands that do | 2766 | * kdb_register - Compatibility register function for commands that do |
2791 | * not need to specify a repeat state. Equivalent to | 2767 | * not need to specify a repeat state. Equivalent to |
2792 | * kdb_register_repeat with KDB_REPEAT_NONE. | 2768 | * kdb_register_repeat with KDB_REPEAT_NONE. |
2793 | * Inputs: | 2769 | * Inputs: |
2794 | * cmd Command name | 2770 | * cmd Command name |
2795 | * func Function to execute the command | 2771 | * func Function to execute the command |
2796 | * usage A simple usage string showing arguments | 2772 | * usage A simple usage string showing arguments |
2797 | * help A simple help string describing command | 2773 | * help A simple help string describing command |
2798 | * Returns: | 2774 | * Returns: |
2799 | * zero for success, one if a duplicate command. | 2775 | * zero for success, one if a duplicate command. |
2800 | */ | 2776 | */ |
2801 | int kdb_register(char *cmd, | 2777 | int kdb_register(char *cmd, |
2802 | kdb_func_t func, | 2778 | kdb_func_t func, |
2803 | char *usage, | 2779 | char *usage, |
2804 | char *help, | 2780 | char *help, |
2805 | short minlen) | 2781 | short minlen) |
2806 | { | 2782 | { |
2807 | return kdb_register_repeat(cmd, func, usage, help, minlen, | 2783 | return kdb_register_repeat(cmd, func, usage, help, minlen, |
2808 | KDB_REPEAT_NONE); | 2784 | KDB_REPEAT_NONE); |
2809 | } | 2785 | } |
2810 | EXPORT_SYMBOL_GPL(kdb_register); | 2786 | EXPORT_SYMBOL_GPL(kdb_register); |
2811 | 2787 | ||
2812 | /* | 2788 | /* |
2813 | * kdb_unregister - This function is used to unregister a kernel | 2789 | * kdb_unregister - This function is used to unregister a kernel |
2814 | * debugger command. It is generally called when a module which | 2790 | * debugger command. It is generally called when a module which |
2815 | * implements kdb commands is unloaded. | 2791 | * implements kdb commands is unloaded. |
2816 | * Inputs: | 2792 | * Inputs: |
2817 | * cmd Command name | 2793 | * cmd Command name |
2818 | * Returns: | 2794 | * Returns: |
2819 | * zero for success, one command not registered. | 2795 | * zero for success, one command not registered. |
2820 | */ | 2796 | */ |
2821 | int kdb_unregister(char *cmd) | 2797 | int kdb_unregister(char *cmd) |
2822 | { | 2798 | { |
2823 | int i; | 2799 | int i; |
2824 | kdbtab_t *kp; | 2800 | kdbtab_t *kp; |
2825 | 2801 | ||
2826 | /* | 2802 | /* |
2827 | * find the command. | 2803 | * find the command. |
2828 | */ | 2804 | */ |
2829 | for_each_kdbcmd(kp, i) { | 2805 | for_each_kdbcmd(kp, i) { |
2830 | if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) { | 2806 | if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) { |
2831 | kp->cmd_name = NULL; | 2807 | kp->cmd_name = NULL; |
2832 | return 0; | 2808 | return 0; |
2833 | } | 2809 | } |
2834 | } | 2810 | } |
2835 | 2811 | ||
2836 | /* Couldn't find it. */ | 2812 | /* Couldn't find it. */ |
2837 | return 1; | 2813 | return 1; |
2838 | } | 2814 | } |
2839 | EXPORT_SYMBOL_GPL(kdb_unregister); | 2815 | EXPORT_SYMBOL_GPL(kdb_unregister); |
2840 | 2816 | ||
2841 | /* Initialize the kdb command table. */ | 2817 | /* Initialize the kdb command table. */ |
2842 | static void __init kdb_inittab(void) | 2818 | static void __init kdb_inittab(void) |
2843 | { | 2819 | { |
2844 | int i; | 2820 | int i; |
2845 | kdbtab_t *kp; | 2821 | kdbtab_t *kp; |
2846 | 2822 | ||
2847 | for_each_kdbcmd(kp, i) | 2823 | for_each_kdbcmd(kp, i) |
2848 | kp->cmd_name = NULL; | 2824 | kp->cmd_name = NULL; |
2849 | 2825 | ||
2850 | kdb_register_repeat("md", kdb_md, "<vaddr>", | 2826 | kdb_register_repeat("md", kdb_md, "<vaddr>", |
2851 | "Display Memory Contents, also mdWcN, e.g. md8c1", 1, | 2827 | "Display Memory Contents, also mdWcN, e.g. md8c1", 1, |
2852 | KDB_REPEAT_NO_ARGS); | 2828 | KDB_REPEAT_NO_ARGS); |
2853 | kdb_register_repeat("mdr", kdb_md, "<vaddr> <bytes>", | 2829 | kdb_register_repeat("mdr", kdb_md, "<vaddr> <bytes>", |
2854 | "Display Raw Memory", 0, KDB_REPEAT_NO_ARGS); | 2830 | "Display Raw Memory", 0, KDB_REPEAT_NO_ARGS); |
2855 | kdb_register_repeat("mdp", kdb_md, "<paddr> <bytes>", | 2831 | kdb_register_repeat("mdp", kdb_md, "<paddr> <bytes>", |
2856 | "Display Physical Memory", 0, KDB_REPEAT_NO_ARGS); | 2832 | "Display Physical Memory", 0, KDB_REPEAT_NO_ARGS); |
2857 | kdb_register_repeat("mds", kdb_md, "<vaddr>", | 2833 | kdb_register_repeat("mds", kdb_md, "<vaddr>", |
2858 | "Display Memory Symbolically", 0, KDB_REPEAT_NO_ARGS); | 2834 | "Display Memory Symbolically", 0, KDB_REPEAT_NO_ARGS); |
2859 | kdb_register_repeat("mm", kdb_mm, "<vaddr> <contents>", | 2835 | kdb_register_repeat("mm", kdb_mm, "<vaddr> <contents>", |
2860 | "Modify Memory Contents", 0, KDB_REPEAT_NO_ARGS); | 2836 | "Modify Memory Contents", 0, KDB_REPEAT_NO_ARGS); |
2861 | kdb_register_repeat("go", kdb_go, "[<vaddr>]", | 2837 | kdb_register_repeat("go", kdb_go, "[<vaddr>]", |
2862 | "Continue Execution", 1, KDB_REPEAT_NONE); | 2838 | "Continue Execution", 1, KDB_REPEAT_NONE); |
2863 | kdb_register_repeat("rd", kdb_rd, "", | 2839 | kdb_register_repeat("rd", kdb_rd, "", |
2864 | "Display Registers", 0, KDB_REPEAT_NONE); | 2840 | "Display Registers", 0, KDB_REPEAT_NONE); |
2865 | kdb_register_repeat("rm", kdb_rm, "<reg> <contents>", | 2841 | kdb_register_repeat("rm", kdb_rm, "<reg> <contents>", |
2866 | "Modify Registers", 0, KDB_REPEAT_NONE); | 2842 | "Modify Registers", 0, KDB_REPEAT_NONE); |
2867 | kdb_register_repeat("ef", kdb_ef, "<vaddr>", | 2843 | kdb_register_repeat("ef", kdb_ef, "<vaddr>", |
2868 | "Display exception frame", 0, KDB_REPEAT_NONE); | 2844 | "Display exception frame", 0, KDB_REPEAT_NONE); |
2869 | kdb_register_repeat("bt", kdb_bt, "[<vaddr>]", | 2845 | kdb_register_repeat("bt", kdb_bt, "[<vaddr>]", |
2870 | "Stack traceback", 1, KDB_REPEAT_NONE); | 2846 | "Stack traceback", 1, KDB_REPEAT_NONE); |
2871 | kdb_register_repeat("btp", kdb_bt, "<pid>", | 2847 | kdb_register_repeat("btp", kdb_bt, "<pid>", |
2872 | "Display stack for process <pid>", 0, KDB_REPEAT_NONE); | 2848 | "Display stack for process <pid>", 0, KDB_REPEAT_NONE); |
2873 | kdb_register_repeat("bta", kdb_bt, "[DRSTCZEUIMA]", | 2849 | kdb_register_repeat("bta", kdb_bt, "[DRSTCZEUIMA]", |
2874 | "Display stack all processes", 0, KDB_REPEAT_NONE); | 2850 | "Display stack all processes", 0, KDB_REPEAT_NONE); |
2875 | kdb_register_repeat("btc", kdb_bt, "", | 2851 | kdb_register_repeat("btc", kdb_bt, "", |
2876 | "Backtrace current process on each cpu", 0, KDB_REPEAT_NONE); | 2852 | "Backtrace current process on each cpu", 0, KDB_REPEAT_NONE); |
2877 | kdb_register_repeat("btt", kdb_bt, "<vaddr>", | 2853 | kdb_register_repeat("btt", kdb_bt, "<vaddr>", |
2878 | "Backtrace process given its struct task address", 0, | 2854 | "Backtrace process given its struct task address", 0, |
2879 | KDB_REPEAT_NONE); | 2855 | KDB_REPEAT_NONE); |
2880 | kdb_register_repeat("ll", kdb_ll, "<first-element> <linkoffset> <cmd>", | 2856 | kdb_register_repeat("ll", kdb_ll, "<first-element> <linkoffset> <cmd>", |
2881 | "Execute cmd for each element in linked list", 0, KDB_REPEAT_NONE); | 2857 | "Execute cmd for each element in linked list", 0, KDB_REPEAT_NONE); |
2882 | kdb_register_repeat("env", kdb_env, "", | 2858 | kdb_register_repeat("env", kdb_env, "", |
2883 | "Show environment variables", 0, KDB_REPEAT_NONE); | 2859 | "Show environment variables", 0, KDB_REPEAT_NONE); |
2884 | kdb_register_repeat("set", kdb_set, "", | 2860 | kdb_register_repeat("set", kdb_set, "", |
2885 | "Set environment variables", 0, KDB_REPEAT_NONE); | 2861 | "Set environment variables", 0, KDB_REPEAT_NONE); |
2886 | kdb_register_repeat("help", kdb_help, "", | 2862 | kdb_register_repeat("help", kdb_help, "", |
2887 | "Display Help Message", 1, KDB_REPEAT_NONE); | 2863 | "Display Help Message", 1, KDB_REPEAT_NONE); |
2888 | kdb_register_repeat("?", kdb_help, "", | 2864 | kdb_register_repeat("?", kdb_help, "", |
2889 | "Display Help Message", 0, KDB_REPEAT_NONE); | 2865 | "Display Help Message", 0, KDB_REPEAT_NONE); |
2890 | kdb_register_repeat("cpu", kdb_cpu, "<cpunum>", | 2866 | kdb_register_repeat("cpu", kdb_cpu, "<cpunum>", |
2891 | "Switch to new cpu", 0, KDB_REPEAT_NONE); | 2867 | "Switch to new cpu", 0, KDB_REPEAT_NONE); |
2892 | kdb_register_repeat("kgdb", kdb_kgdb, "", | 2868 | kdb_register_repeat("kgdb", kdb_kgdb, "", |
2893 | "Enter kgdb mode", 0, KDB_REPEAT_NONE); | 2869 | "Enter kgdb mode", 0, KDB_REPEAT_NONE); |
2894 | kdb_register_repeat("ps", kdb_ps, "[<flags>|A]", | 2870 | kdb_register_repeat("ps", kdb_ps, "[<flags>|A]", |
2895 | "Display active task list", 0, KDB_REPEAT_NONE); | 2871 | "Display active task list", 0, KDB_REPEAT_NONE); |
2896 | kdb_register_repeat("pid", kdb_pid, "<pidnum>", | 2872 | kdb_register_repeat("pid", kdb_pid, "<pidnum>", |
2897 | "Switch to another task", 0, KDB_REPEAT_NONE); | 2873 | "Switch to another task", 0, KDB_REPEAT_NONE); |
2898 | kdb_register_repeat("reboot", kdb_reboot, "", | 2874 | kdb_register_repeat("reboot", kdb_reboot, "", |
2899 | "Reboot the machine immediately", 0, KDB_REPEAT_NONE); | 2875 | "Reboot the machine immediately", 0, KDB_REPEAT_NONE); |
2900 | #if defined(CONFIG_MODULES) | 2876 | #if defined(CONFIG_MODULES) |
2901 | kdb_register_repeat("lsmod", kdb_lsmod, "", | 2877 | kdb_register_repeat("lsmod", kdb_lsmod, "", |
2902 | "List loaded kernel modules", 0, KDB_REPEAT_NONE); | 2878 | "List loaded kernel modules", 0, KDB_REPEAT_NONE); |
2903 | #endif | 2879 | #endif |
2904 | #if defined(CONFIG_MAGIC_SYSRQ) | 2880 | #if defined(CONFIG_MAGIC_SYSRQ) |
2905 | kdb_register_repeat("sr", kdb_sr, "<key>", | 2881 | kdb_register_repeat("sr", kdb_sr, "<key>", |
2906 | "Magic SysRq key", 0, KDB_REPEAT_NONE); | 2882 | "Magic SysRq key", 0, KDB_REPEAT_NONE); |
2907 | #endif | 2883 | #endif |
2908 | #if defined(CONFIG_PRINTK) | 2884 | #if defined(CONFIG_PRINTK) |
2909 | kdb_register_repeat("dmesg", kdb_dmesg, "[lines]", | 2885 | kdb_register_repeat("dmesg", kdb_dmesg, "[lines]", |
2910 | "Display syslog buffer", 0, KDB_REPEAT_NONE); | 2886 | "Display syslog buffer", 0, KDB_REPEAT_NONE); |
2911 | #endif | 2887 | #endif |
2912 | kdb_register_repeat("defcmd", kdb_defcmd, "name \"usage\" \"help\"", | 2888 | kdb_register_repeat("defcmd", kdb_defcmd, "name \"usage\" \"help\"", |
2913 | "Define a set of commands, down to endefcmd", 0, KDB_REPEAT_NONE); | 2889 | "Define a set of commands, down to endefcmd", 0, KDB_REPEAT_NONE); |
2914 | kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>", | 2890 | kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>", |
2915 | "Send a signal to a process", 0, KDB_REPEAT_NONE); | 2891 | "Send a signal to a process", 0, KDB_REPEAT_NONE); |
2916 | kdb_register_repeat("summary", kdb_summary, "", | 2892 | kdb_register_repeat("summary", kdb_summary, "", |
2917 | "Summarize the system", 4, KDB_REPEAT_NONE); | 2893 | "Summarize the system", 4, KDB_REPEAT_NONE); |
2918 | kdb_register_repeat("per_cpu", kdb_per_cpu, "", | 2894 | kdb_register_repeat("per_cpu", kdb_per_cpu, "", |
2919 | "Display per_cpu variables", 3, KDB_REPEAT_NONE); | 2895 | "Display per_cpu variables", 3, KDB_REPEAT_NONE); |
2920 | kdb_register_repeat("grephelp", kdb_grep_help, "", | 2896 | kdb_register_repeat("grephelp", kdb_grep_help, "", |
2921 | "Display help on | grep", 0, KDB_REPEAT_NONE); | 2897 | "Display help on | grep", 0, KDB_REPEAT_NONE); |
2922 | } | 2898 | } |
2923 | 2899 | ||
2924 | /* Execute any commands defined in kdb_cmds. */ | 2900 | /* Execute any commands defined in kdb_cmds. */ |
2925 | static void __init kdb_cmd_init(void) | 2901 | static void __init kdb_cmd_init(void) |
2926 | { | 2902 | { |
2927 | int i, diag; | 2903 | int i, diag; |
2928 | for (i = 0; kdb_cmds[i]; ++i) { | 2904 | for (i = 0; kdb_cmds[i]; ++i) { |
2929 | diag = kdb_parse(kdb_cmds[i]); | 2905 | diag = kdb_parse(kdb_cmds[i]); |
2930 | if (diag) | 2906 | if (diag) |
2931 | kdb_printf("kdb command %s failed, kdb diag %d\n", | 2907 | kdb_printf("kdb command %s failed, kdb diag %d\n", |
2932 | kdb_cmds[i], diag); | 2908 | kdb_cmds[i], diag); |
2933 | } | 2909 | } |
2934 | if (defcmd_in_progress) { | 2910 | if (defcmd_in_progress) { |
2935 | kdb_printf("Incomplete 'defcmd' set, forcing endefcmd\n"); | 2911 | kdb_printf("Incomplete 'defcmd' set, forcing endefcmd\n"); |
2936 | kdb_parse("endefcmd"); | 2912 | kdb_parse("endefcmd"); |
2937 | } | 2913 | } |
2938 | } | 2914 | } |
2939 | 2915 | ||
2940 | /* Intialize kdb_printf, breakpoint tables and kdb state */ | 2916 | /* Intialize kdb_printf, breakpoint tables and kdb state */ |
2941 | void __init kdb_init(int lvl) | 2917 | void __init kdb_init(int lvl) |
2942 | { | 2918 | { |
2943 | static int kdb_init_lvl = KDB_NOT_INITIALIZED; | 2919 | static int kdb_init_lvl = KDB_NOT_INITIALIZED; |
2944 | int i; | 2920 | int i; |
2945 | 2921 | ||
2946 | if (kdb_init_lvl == KDB_INIT_FULL || lvl <= kdb_init_lvl) | 2922 | if (kdb_init_lvl == KDB_INIT_FULL || lvl <= kdb_init_lvl) |
2947 | return; | 2923 | return; |
2948 | for (i = kdb_init_lvl; i < lvl; i++) { | 2924 | for (i = kdb_init_lvl; i < lvl; i++) { |
2949 | switch (i) { | 2925 | switch (i) { |
2950 | case KDB_NOT_INITIALIZED: | 2926 | case KDB_NOT_INITIALIZED: |
2951 | kdb_inittab(); /* Initialize Command Table */ | 2927 | kdb_inittab(); /* Initialize Command Table */ |
2952 | kdb_initbptab(); /* Initialize Breakpoints */ | 2928 | kdb_initbptab(); /* Initialize Breakpoints */ |
2953 | break; | 2929 | break; |
2954 | case KDB_INIT_EARLY: | 2930 | case KDB_INIT_EARLY: |
2955 | kdb_cmd_init(); /* Build kdb_cmds tables */ | 2931 | kdb_cmd_init(); /* Build kdb_cmds tables */ |
2956 | break; | 2932 | break; |
2957 | } | 2933 | } |
2958 | } | 2934 | } |