aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorJason Wessel <jason.wessel@windriver.com>2008-03-07 17:34:17 -0500
committerIngo Molnar <mingo@elte.hu>2008-04-17 14:05:42 -0400
commite8d31c204e36e019b9134f2a11926cac0fcf9b19 (patch)
tree2720c1deadb6e57981254ec4120624b8a24dfdcf /drivers/misc
parent737a460f21febe551ff1d2299b63bae9b154078f (diff)
kgdb: add kgdb internal test suite
This patch adds regression tests for testing the kgdb core and arch specific implementation. The kgdb test suite is designed to be built into the kernel and not as a module because it uses a number of low level kernel and kgdb primitives which should not be exported externally. The kgdb test suite is designed as a KGDB I/O module which simulates the communications that a debugger would have with kgdb. The tests are broken up in to a line by line and referenced here as a "get" which is kgdb requesting input and "put" which is kgdb sending a response. The kgdb suite can be invoked from the kernel command line arguments system or executed dynamically at run time. The test suite uses the variable "kgdbts" to obtain the information about which tests to run and to configure the verbosity level. The following are the various characters you can use with the kgdbts= line: When using the "kgdbts=" you only choose one of the following core test types: A = Run all the core tests silently V1 = Run all the core tests with minimal output V2 = Run all the core tests in debug mode You can also specify optional tests: N## = Go to sleep with interrupts of for ## seconds to test the HW NMI watchdog F## = Break at do_fork for ## iterations S## = Break at sys_open for ## iterations NOTE: that the do_fork and sys_open tests are mutually exclusive. To invoke the kgdb test suite from boot you use a kernel start argument as follows: kgdbts=V1 kgdbwait Or if you wanted to perform the NMI test for 6 seconds and do_fork test for 100 forks, you could use: kgdbts=V1N6F100 kgdbwait The test suite can also be invoked at run time with: echo kgdbts=V1N6F100 > /sys/module/kgdbts/parameters/kgdbts Or as another example: echo kgdbts=V2 > /sys/module/kgdbts/parameters/kgdbts When developing a new kgdb arch specific implementation or using these tests for the purpose of regression testing, several invocations are required. 1) Boot with the test suite enabled by using the kernel arguments "kgdbts=V1F100 kgdbwait" ## If kgdb arch specific implementation has NMI use "kgdbts=V1N6F100 2) After the system boot run the basic test. echo kgdbts=V1 > /sys/module/kgdbts/parameters/kgdbts 3) Run the concurrency tests. It is best to use n+1 while loops where n is the number of cpus you have in your system. The example below uses only two loops. ## This tests break points on sys_open while [ 1 ] ; do find / > /dev/null 2>&1 ; done & while [ 1 ] ; do find / > /dev/null 2>&1 ; done & echo kgdbts=V1S10000 > /sys/module/kgdbts/parameters/kgdbts fg # and hit control-c fg # and hit control-c ## This tests break points on do_fork while [ 1 ] ; do date > /dev/null ; done & while [ 1 ] ; do date > /dev/null ; done & echo kgdbts=V1F1000 > /sys/module/kgdbts/parameters/kgdbts fg # and hit control-c Signed-off-by: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/kgdbts.c1083
2 files changed, 1084 insertions, 0 deletions
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 3b12f5da8562..bbc69fdd1b9d 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o
22obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o 22obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
23obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o 23obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o
24obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o 24obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o
25obj-$(CONFIG_KGDB_TESTS) += kgdbts.o
diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c
new file mode 100644
index 000000000000..cbc4822b5847
--- /dev/null
+++ b/drivers/misc/kgdbts.c
@@ -0,0 +1,1083 @@
1/*
2 * kgdbts is a test suite for kgdb for the sole purpose of validating
3 * that key pieces of the kgdb internals are working properly such as
4 * HW/SW breakpoints, single stepping, and NMI.
5 *
6 * Created by: Jason Wessel <jason.wessel@windriver.com>
7 *
8 * Copyright (c) 2008 Wind River Systems, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 * See the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23/* Information about the kgdb test suite.
24 * -------------------------------------
25 *
26 * The kgdb test suite is designed as a KGDB I/O module which
27 * simulates the communications that a debugger would have with kgdb.
28 * The tests are broken up in to a line by line and referenced here as
29 * a "get" which is kgdb requesting input and "put" which is kgdb
30 * sending a response.
31 *
32 * The kgdb suite can be invoked from the kernel command line
33 * arguments system or executed dynamically at run time. The test
34 * suite uses the variable "kgdbts" to obtain the information about
35 * which tests to run and to configure the verbosity level. The
36 * following are the various characters you can use with the kgdbts=
37 * line:
38 *
39 * When using the "kgdbts=" you only choose one of the following core
40 * test types:
41 * A = Run all the core tests silently
42 * V1 = Run all the core tests with minimal output
43 * V2 = Run all the core tests in debug mode
44 *
45 * You can also specify optional tests:
46 * N## = Go to sleep with interrupts of for ## seconds
47 * to test the HW NMI watchdog
48 * F## = Break at do_fork for ## iterations
49 * S## = Break at sys_open for ## iterations
50 *
51 * NOTE: that the do_fork and sys_open tests are mutually exclusive.
52 *
53 * To invoke the kgdb test suite from boot you use a kernel start
54 * argument as follows:
55 * kgdbts=V1 kgdbwait
56 * Or if you wanted to perform the NMI test for 6 seconds and do_fork
57 * test for 100 forks, you could use:
58 * kgdbts=V1N6F100 kgdbwait
59 *
60 * The test suite can also be invoked at run time with:
61 * echo kgdbts=V1N6F100 > /sys/module/kgdbts/parameters/kgdbts
62 * Or as another example:
63 * echo kgdbts=V2 > /sys/module/kgdbts/parameters/kgdbts
64 *
65 * When developing a new kgdb arch specific implementation or
66 * using these tests for the purpose of regression testing,
67 * several invocations are required.
68 *
69 * 1) Boot with the test suite enabled by using the kernel arguments
70 * "kgdbts=V1F100 kgdbwait"
71 * ## If kgdb arch specific implementation has NMI use
72 * "kgdbts=V1N6F100
73 *
74 * 2) After the system boot run the basic test.
75 * echo kgdbts=V1 > /sys/module/kgdbts/parameters/kgdbts
76 *
77 * 3) Run the concurrency tests. It is best to use n+1
78 * while loops where n is the number of cpus you have
79 * in your system. The example below uses only two
80 * loops.
81 *
82 * ## This tests break points on sys_open
83 * while [ 1 ] ; do find / > /dev/null 2>&1 ; done &
84 * while [ 1 ] ; do find / > /dev/null 2>&1 ; done &
85 * echo kgdbts=V1S10000 > /sys/module/kgdbts/parameters/kgdbts
86 * fg # and hit control-c
87 * fg # and hit control-c
88 * ## This tests break points on do_fork
89 * while [ 1 ] ; do date > /dev/null ; done &
90 * while [ 1 ] ; do date > /dev/null ; done &
91 * echo kgdbts=V1F1000 > /sys/module/kgdbts/parameters/kgdbts
92 * fg # and hit control-c
93 *
94 */
95
96#include <linux/kernel.h>
97#include <linux/kgdb.h>
98#include <linux/ctype.h>
99#include <linux/uaccess.h>
100#include <linux/syscalls.h>
101#include <linux/nmi.h>
102#include <linux/delay.h>
103#include <linux/kthread.h>
104#include <linux/delay.h>
105
106#define v1printk(a...) do { \
107 if (verbose) \
108 printk(KERN_INFO a); \
109 } while (0)
110#define v2printk(a...) do { \
111 if (verbose > 1) \
112 printk(KERN_INFO a); \
113 touch_nmi_watchdog(); \
114 } while (0)
115#define MAX_CONFIG_LEN 40
116
117static const char hexchars[] = "0123456789abcdef";
118static struct kgdb_io kgdbts_io_ops;
119static char get_buf[BUFMAX];
120static int get_buf_cnt;
121static char put_buf[BUFMAX];
122static int put_buf_cnt;
123static char scratch_buf[BUFMAX];
124static int verbose;
125static int repeat_test;
126static int test_complete;
127static int send_ack;
128static int final_ack;
129static int hw_break_val;
130static int hw_break_val2;
131#if defined(CONFIG_ARM) || defined(CONFIG_MIPS)
132static int arch_needs_sstep_emulation = 1;
133#else
134static int arch_needs_sstep_emulation;
135#endif
136static unsigned long sstep_addr;
137static int sstep_state;
138
139/* Storage for the registers, in GDB format. */
140static unsigned long kgdbts_gdb_regs[(NUMREGBYTES +
141 sizeof(unsigned long) - 1) /
142 sizeof(unsigned long)];
143static struct pt_regs kgdbts_regs;
144
145/* -1 = init not run yet, 0 = unconfigured, 1 = configured. */
146static int configured = -1;
147
148static char config[MAX_CONFIG_LEN];
149static struct kparam_string kps = {
150 .string = config,
151 .maxlen = MAX_CONFIG_LEN,
152};
153
154static void fill_get_buf(char *buf);
155
156struct test_struct {
157 char *get;
158 char *put;
159 void (*get_handler)(char *);
160 int (*put_handler)(char *, char *);
161};
162
163struct test_state {
164 char *name;
165 struct test_struct *tst;
166 int idx;
167 int (*run_test) (int, int);
168 int (*validate_put) (char *);
169};
170
171static struct test_state ts;
172
173static int kgdbts_unreg_thread(void *ptr)
174{
175 /* Wait until the tests are complete and then ungresiter the I/O
176 * driver.
177 */
178 while (!final_ack)
179 msleep_interruptible(1500);
180
181 if (configured)
182 kgdb_unregister_io_module(&kgdbts_io_ops);
183 configured = 0;
184
185 return 0;
186}
187
188/* This is noinline such that it can be used for a single location to
189 * place a breakpoint
190 */
191static noinline void kgdbts_break_test(void)
192{
193 v2printk("kgdbts: breakpoint complete\n");
194}
195
196/* Lookup symbol info in the kernel */
197static unsigned long lookup_addr(char *arg)
198{
199 unsigned long addr = 0;
200
201 if (!strcmp(arg, "kgdbts_break_test"))
202 addr = (unsigned long)kgdbts_break_test;
203 else if (!strcmp(arg, "sys_open"))
204 addr = (unsigned long)sys_open;
205 else if (!strcmp(arg, "do_fork"))
206 addr = (unsigned long)do_fork;
207 else if (!strcmp(arg, "hw_break_val"))
208 addr = (unsigned long)&hw_break_val;
209 return addr;
210}
211
212static void break_helper(char *bp_type, char *arg, unsigned long vaddr)
213{
214 unsigned long addr;
215
216 if (arg)
217 addr = lookup_addr(arg);
218 else
219 addr = vaddr;
220
221 sprintf(scratch_buf, "%s,%lx,%i", bp_type, addr,
222 BREAK_INSTR_SIZE);
223 fill_get_buf(scratch_buf);
224}
225
226static void sw_break(char *arg)
227{
228 break_helper("Z0", arg, 0);
229}
230
231static void sw_rem_break(char *arg)
232{
233 break_helper("z0", arg, 0);
234}
235
236static void hw_break(char *arg)
237{
238 break_helper("Z1", arg, 0);
239}
240
241static void hw_rem_break(char *arg)
242{
243 break_helper("z1", arg, 0);
244}
245
246static void hw_write_break(char *arg)
247{
248 break_helper("Z2", arg, 0);
249}
250
251static void hw_rem_write_break(char *arg)
252{
253 break_helper("z2", arg, 0);
254}
255
256static void hw_access_break(char *arg)
257{
258 break_helper("Z4", arg, 0);
259}
260
261static void hw_rem_access_break(char *arg)
262{
263 break_helper("z4", arg, 0);
264}
265
266static void hw_break_val_access(void)
267{
268 hw_break_val2 = hw_break_val;
269}
270
271static void hw_break_val_write(void)
272{
273 hw_break_val++;
274}
275
276static int check_and_rewind_pc(char *put_str, char *arg)
277{
278 unsigned long addr = lookup_addr(arg);
279 int offset = 0;
280
281 kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs,
282 NUMREGBYTES);
283 gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs);
284 v2printk("Stopped at IP: %lx\n", instruction_pointer(&kgdbts_regs));
285#ifdef CONFIG_X86
286 /* On x86 a breakpoint stop requires it to be decremented */
287 if (addr + 1 == kgdbts_regs.ip)
288 offset = -1;
289#endif
290 if (strcmp(arg, "silent") &&
291 instruction_pointer(&kgdbts_regs) + offset != addr) {
292 printk(KERN_ERR "kgdbts: BP mismatch %lx expected %lx\n",
293 instruction_pointer(&kgdbts_regs) + offset, addr);
294 return 1;
295 }
296#ifdef CONFIG_X86
297 /* On x86 adjust the instruction pointer if needed */
298 kgdbts_regs.ip += offset;
299#endif
300 return 0;
301}
302
303static int check_single_step(char *put_str, char *arg)
304{
305 unsigned long addr = lookup_addr(arg);
306 /*
307 * From an arch indepent point of view the instruction pointer
308 * should be on a different instruction
309 */
310 kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs,
311 NUMREGBYTES);
312 gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs);
313 v2printk("Singlestep stopped at IP: %lx\n",
314 instruction_pointer(&kgdbts_regs));
315 if (instruction_pointer(&kgdbts_regs) == addr) {
316 printk(KERN_ERR "kgdbts: SingleStep failed at %lx\n",
317 instruction_pointer(&kgdbts_regs));
318 return 1;
319 }
320
321 return 0;
322}
323
324static void write_regs(char *arg)
325{
326 memset(scratch_buf, 0, sizeof(scratch_buf));
327 scratch_buf[0] = 'G';
328 pt_regs_to_gdb_regs(kgdbts_gdb_regs, &kgdbts_regs);
329 kgdb_mem2hex((char *)kgdbts_gdb_regs, &scratch_buf[1], NUMREGBYTES);
330 fill_get_buf(scratch_buf);
331}
332
333static void skip_back_repeat_test(char *arg)
334{
335 int go_back = simple_strtol(arg, NULL, 10);
336
337 repeat_test--;
338 if (repeat_test <= 0)
339 ts.idx++;
340 else
341 ts.idx -= go_back;
342 fill_get_buf(ts.tst[ts.idx].get);
343}
344
345static int got_break(char *put_str, char *arg)
346{
347 test_complete = 1;
348 if (!strncmp(put_str+1, arg, 2)) {
349 if (!strncmp(arg, "T0", 2))
350 test_complete = 2;
351 return 0;
352 }
353 return 1;
354}
355
356static void emul_sstep_get(char *arg)
357{
358 if (!arch_needs_sstep_emulation) {
359 fill_get_buf(arg);
360 return;
361 }
362 switch (sstep_state) {
363 case 0:
364 v2printk("Emulate single step\n");
365 /* Start by looking at the current PC */
366 fill_get_buf("g");
367 break;
368 case 1:
369 /* set breakpoint */
370 break_helper("Z0", 0, sstep_addr);
371 break;
372 case 2:
373 /* Continue */
374 fill_get_buf("c");
375 break;
376 case 3:
377 /* Clear breakpoint */
378 break_helper("z0", 0, sstep_addr);
379 break;
380 default:
381 printk(KERN_ERR "kgdbts: ERROR failed sstep get emulation\n");
382 }
383 sstep_state++;
384}
385
386static int emul_sstep_put(char *put_str, char *arg)
387{
388 if (!arch_needs_sstep_emulation) {
389 if (!strncmp(put_str+1, arg, 2))
390 return 0;
391 return 1;
392 }
393 switch (sstep_state) {
394 case 1:
395 /* validate the "g" packet to get the IP */
396 kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs,
397 NUMREGBYTES);
398 gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs);
399 v2printk("Stopped at IP: %lx\n",
400 instruction_pointer(&kgdbts_regs));
401 /* Want to stop at IP + break instruction size by default */
402 sstep_addr = instruction_pointer(&kgdbts_regs) +
403 BREAK_INSTR_SIZE;
404 break;
405 case 2:
406 if (strncmp(put_str, "$OK", 3)) {
407 printk(KERN_ERR "kgdbts: failed sstep break set\n");
408 return 1;
409 }
410 break;
411 case 3:
412 if (strncmp(put_str, "$T0", 3)) {
413 printk(KERN_ERR "kgdbts: failed continue sstep\n");
414 return 1;
415 }
416 break;
417 case 4:
418 if (strncmp(put_str, "$OK", 3)) {
419 printk(KERN_ERR "kgdbts: failed sstep break unset\n");
420 return 1;
421 }
422 /* Single step is complete so continue on! */
423 sstep_state = 0;
424 return 0;
425 default:
426 printk(KERN_ERR "kgdbts: ERROR failed sstep put emulation\n");
427 }
428
429 /* Continue on the same test line until emulation is complete */
430 ts.idx--;
431 return 0;
432}
433
434static int final_ack_set(char *put_str, char *arg)
435{
436 if (strncmp(put_str+1, arg, 2))
437 return 1;
438 final_ack = 1;
439 return 0;
440}
441/*
442 * Test to plant a breakpoint and detach, which should clear out the
443 * breakpoint and restore the original instruction.
444 */
445static struct test_struct plant_and_detach_test[] = {
446 { "?", "S0*" }, /* Clear break points */
447 { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
448 { "D", "OK" }, /* Detach */
449 { "", "" },
450};
451
452/*
453 * Simple test to write in a software breakpoint, check for the
454 * correct stop location and detach.
455 */
456static struct test_struct sw_breakpoint_test[] = {
457 { "?", "S0*" }, /* Clear break points */
458 { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
459 { "c", "T0*", }, /* Continue */
460 { "g", "kgdbts_break_test", 0, check_and_rewind_pc },
461 { "write", "OK", write_regs },
462 { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */
463 { "D", "OK" }, /* Detach */
464 { "D", "OK", 0, got_break }, /* If the test worked we made it here */
465 { "", "" },
466};
467
468/*
469 * Test a known bad memory read location to test the fault handler and
470 * read bytes 1-8 at the bad address
471 */
472static struct test_struct bad_read_test[] = {
473 { "?", "S0*" }, /* Clear break points */
474 { "m0,1", "E*" }, /* read 1 byte at address 1 */
475 { "m0,2", "E*" }, /* read 1 byte at address 2 */
476 { "m0,3", "E*" }, /* read 1 byte at address 3 */
477 { "m0,4", "E*" }, /* read 1 byte at address 4 */
478 { "m0,5", "E*" }, /* read 1 byte at address 5 */
479 { "m0,6", "E*" }, /* read 1 byte at address 6 */
480 { "m0,7", "E*" }, /* read 1 byte at address 7 */
481 { "m0,8", "E*" }, /* read 1 byte at address 8 */
482 { "D", "OK" }, /* Detach which removes all breakpoints and continues */
483 { "", "" },
484};
485
486/*
487 * Test for hitting a breakpoint, remove it, single step, plant it
488 * again and detach.
489 */
490static struct test_struct singlestep_break_test[] = {
491 { "?", "S0*" }, /* Clear break points */
492 { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
493 { "c", "T0*", }, /* Continue */
494 { "g", "kgdbts_break_test", 0, check_and_rewind_pc },
495 { "write", "OK", write_regs }, /* Write registers */
496 { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */
497 { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
498 { "g", "kgdbts_break_test", 0, check_single_step },
499 { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
500 { "c", "T0*", }, /* Continue */
501 { "g", "kgdbts_break_test", 0, check_and_rewind_pc },
502 { "write", "OK", write_regs }, /* Write registers */
503 { "D", "OK" }, /* Remove all breakpoints and continues */
504 { "", "" },
505};
506
507/*
508 * Test for hitting a breakpoint at do_fork for what ever the number
509 * of iterations required by the variable repeat_test.
510 */
511static struct test_struct do_fork_test[] = {
512 { "?", "S0*" }, /* Clear break points */
513 { "do_fork", "OK", sw_break, }, /* set sw breakpoint */
514 { "c", "T0*", }, /* Continue */
515 { "g", "do_fork", 0, check_and_rewind_pc }, /* check location */
516 { "write", "OK", write_regs }, /* Write registers */
517 { "do_fork", "OK", sw_rem_break }, /*remove breakpoint */
518 { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
519 { "g", "do_fork", 0, check_single_step },
520 { "do_fork", "OK", sw_break, }, /* set sw breakpoint */
521 { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */
522 { "D", "OK", 0, final_ack_set }, /* detach and unregister I/O */
523 { "", "" },
524};
525
526/* Test for hitting a breakpoint at sys_open for what ever the number
527 * of iterations required by the variable repeat_test.
528 */
529static struct test_struct sys_open_test[] = {
530 { "?", "S0*" }, /* Clear break points */
531 { "sys_open", "OK", sw_break, }, /* set sw breakpoint */
532 { "c", "T0*", }, /* Continue */
533 { "g", "sys_open", 0, check_and_rewind_pc }, /* check location */
534 { "write", "OK", write_regs }, /* Write registers */
535 { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */
536 { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
537 { "g", "sys_open", 0, check_single_step },
538 { "sys_open", "OK", sw_break, }, /* set sw breakpoint */
539 { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */
540 { "D", "OK", 0, final_ack_set }, /* detach and unregister I/O */
541 { "", "" },
542};
543
544/*
545 * Test for hitting a simple hw breakpoint
546 */
547static struct test_struct hw_breakpoint_test[] = {
548 { "?", "S0*" }, /* Clear break points */
549 { "kgdbts_break_test", "OK", hw_break, }, /* set hw breakpoint */
550 { "c", "T0*", }, /* Continue */
551 { "g", "kgdbts_break_test", 0, check_and_rewind_pc },
552 { "write", "OK", write_regs },
553 { "kgdbts_break_test", "OK", hw_rem_break }, /*remove breakpoint */
554 { "D", "OK" }, /* Detach */
555 { "D", "OK", 0, got_break }, /* If the test worked we made it here */
556 { "", "" },
557};
558
559/*
560 * Test for hitting a hw write breakpoint
561 */
562static struct test_struct hw_write_break_test[] = {
563 { "?", "S0*" }, /* Clear break points */
564 { "hw_break_val", "OK", hw_write_break, }, /* set hw breakpoint */
565 { "c", "T0*", 0, got_break }, /* Continue */
566 { "g", "silent", 0, check_and_rewind_pc },
567 { "write", "OK", write_regs },
568 { "hw_break_val", "OK", hw_rem_write_break }, /*remove breakpoint */
569 { "D", "OK" }, /* Detach */
570 { "D", "OK", 0, got_break }, /* If the test worked we made it here */
571 { "", "" },
572};
573
574/*
575 * Test for hitting a hw access breakpoint
576 */
577static struct test_struct hw_access_break_test[] = {
578 { "?", "S0*" }, /* Clear break points */
579 { "hw_break_val", "OK", hw_access_break, }, /* set hw breakpoint */
580 { "c", "T0*", 0, got_break }, /* Continue */
581 { "g", "silent", 0, check_and_rewind_pc },
582 { "write", "OK", write_regs },
583 { "hw_break_val", "OK", hw_rem_access_break }, /*remove breakpoint */
584 { "D", "OK" }, /* Detach */
585 { "D", "OK", 0, got_break }, /* If the test worked we made it here */
586 { "", "" },
587};
588
589/*
590 * Test for hitting a hw access breakpoint
591 */
592static struct test_struct nmi_sleep_test[] = {
593 { "?", "S0*" }, /* Clear break points */
594 { "c", "T0*", 0, got_break }, /* Continue */
595 { "D", "OK" }, /* Detach */
596 { "D", "OK", 0, got_break }, /* If the test worked we made it here */
597 { "", "" },
598};
599
600static void fill_get_buf(char *buf)
601{
602 unsigned char checksum = 0;
603 int count = 0;
604 char ch;
605
606 strcpy(get_buf, "$");
607 strcat(get_buf, buf);
608 while ((ch = buf[count])) {
609 checksum += ch;
610 count++;
611 }
612 strcat(get_buf, "#");
613 get_buf[count + 2] = hexchars[checksum >> 4];
614 get_buf[count + 3] = hexchars[checksum & 0xf];
615 get_buf[count + 4] = '\0';
616 v2printk("get%i: %s\n", ts.idx, get_buf);
617}
618
619static int validate_simple_test(char *put_str)
620{
621 char *chk_str;
622
623 if (ts.tst[ts.idx].put_handler)
624 return ts.tst[ts.idx].put_handler(put_str,
625 ts.tst[ts.idx].put);
626
627 chk_str = ts.tst[ts.idx].put;
628 if (*put_str == '$')
629 put_str++;
630
631 while (*chk_str != '\0' && *put_str != '\0') {
632 /* If someone does a * to match the rest of the string, allow
633 * it, or stop if the recieved string is complete.
634 */
635 if (*put_str == '#' || *chk_str == '*')
636 return 0;
637 if (*put_str != *chk_str)
638 return 1;
639
640 chk_str++;
641 put_str++;
642 }
643 if (*chk_str == '\0' && (*put_str == '\0' || *put_str == '#'))
644 return 0;
645
646 return 1;
647}
648
649static int run_simple_test(int is_get_char, int chr)
650{
651 int ret = 0;
652 if (is_get_char) {
653 /* Send an ACK on the get if a prior put completed and set the
654 * send ack variable
655 */
656 if (send_ack) {
657 send_ack = 0;
658 return '+';
659 }
660 /* On the first get char, fill the transmit buffer and then
661 * take from the get_string.
662 */
663 if (get_buf_cnt == 0) {
664 if (ts.tst[ts.idx].get_handler)
665 ts.tst[ts.idx].get_handler(ts.tst[ts.idx].get);
666 else
667 fill_get_buf(ts.tst[ts.idx].get);
668 }
669
670 if (get_buf[get_buf_cnt] == '\0') {
671 printk(KERN_ERR
672 "kgdbts: ERROR GET: end of buffer on '%s' at %i\n",
673 ts.name, ts.idx);
674 get_buf_cnt = 0;
675 fill_get_buf("D");
676 }
677 ret = get_buf[get_buf_cnt];
678 get_buf_cnt++;
679 return ret;
680 }
681
682 /* This callback is a put char which is when kgdb sends data to
683 * this I/O module.
684 */
685 if (ts.tst[ts.idx].get[0] == '\0' &&
686 ts.tst[ts.idx].put[0] == '\0') {
687 printk(KERN_ERR "kgdbts: ERROR: beyond end of test on"
688 " '%s' line %i\n", ts.name, ts.idx);
689 return 0;
690 }
691
692 if (put_buf_cnt >= BUFMAX) {
693 printk(KERN_ERR "kgdbts: ERROR: put buffer overflow on"
694 " '%s' line %i\n", ts.name, ts.idx);
695 put_buf_cnt = 0;
696 return 0;
697 }
698 /* Ignore everything until the first valid packet start '$' */
699 if (put_buf_cnt == 0 && chr != '$')
700 return 0;
701
702 put_buf[put_buf_cnt] = chr;
703 put_buf_cnt++;
704
705 /* End of packet == #XX so look for the '#' */
706 if (put_buf_cnt > 3 && put_buf[put_buf_cnt - 3] == '#') {
707 put_buf[put_buf_cnt] = '\0';
708 v2printk("put%i: %s\n", ts.idx, put_buf);
709 /* Trigger check here */
710 if (ts.validate_put && ts.validate_put(put_buf)) {
711 printk(KERN_ERR "kgdbts: ERROR PUT: end of test "
712 "buffer on '%s' line %i expected %s got %s\n",
713 ts.name, ts.idx, ts.tst[ts.idx].put, put_buf);
714 }
715 ts.idx++;
716 put_buf_cnt = 0;
717 get_buf_cnt = 0;
718 send_ack = 1;
719 }
720 return 0;
721}
722
723static void init_simple_test(void)
724{
725 memset(&ts, 0, sizeof(ts));
726 ts.run_test = run_simple_test;
727 ts.validate_put = validate_simple_test;
728}
729
730static void run_plant_and_detach_test(int is_early)
731{
732 char before[BREAK_INSTR_SIZE];
733 char after[BREAK_INSTR_SIZE];
734
735 probe_kernel_read(before, (char *)kgdbts_break_test,
736 BREAK_INSTR_SIZE);
737 init_simple_test();
738 ts.tst = plant_and_detach_test;
739 ts.name = "plant_and_detach_test";
740 /* Activate test with initial breakpoint */
741 if (!is_early)
742 kgdb_breakpoint();
743 probe_kernel_read(after, (char *)kgdbts_break_test,
744 BREAK_INSTR_SIZE);
745 if (memcmp(before, after, BREAK_INSTR_SIZE)) {
746 printk(KERN_CRIT "kgdbts: ERROR kgdb corrupted memory\n");
747 panic("kgdb memory corruption");
748 }
749
750 /* complete the detach test */
751 if (!is_early)
752 kgdbts_break_test();
753}
754
755static void run_breakpoint_test(int is_hw_breakpoint)
756{
757 test_complete = 0;
758 init_simple_test();
759 if (is_hw_breakpoint) {
760 ts.tst = hw_breakpoint_test;
761 ts.name = "hw_breakpoint_test";
762 } else {
763 ts.tst = sw_breakpoint_test;
764 ts.name = "sw_breakpoint_test";
765 }
766 /* Activate test with initial breakpoint */
767 kgdb_breakpoint();
768 /* run code with the break point in it */
769 kgdbts_break_test();
770 kgdb_breakpoint();
771
772 if (test_complete)
773 return;
774
775 printk(KERN_ERR "kgdbts: ERROR %s test failed\n", ts.name);
776}
777
778static void run_hw_break_test(int is_write_test)
779{
780 test_complete = 0;
781 init_simple_test();
782 if (is_write_test) {
783 ts.tst = hw_write_break_test;
784 ts.name = "hw_write_break_test";
785 } else {
786 ts.tst = hw_access_break_test;
787 ts.name = "hw_access_break_test";
788 }
789 /* Activate test with initial breakpoint */
790 kgdb_breakpoint();
791 hw_break_val_access();
792 if (is_write_test) {
793 if (test_complete == 2)
794 printk(KERN_ERR "kgdbts: ERROR %s broke on access\n",
795 ts.name);
796 hw_break_val_write();
797 }
798 kgdb_breakpoint();
799
800 if (test_complete == 1)
801 return;
802
803 printk(KERN_ERR "kgdbts: ERROR %s test failed\n", ts.name);
804}
805
806static void run_nmi_sleep_test(int nmi_sleep)
807{
808 unsigned long flags;
809
810 init_simple_test();
811 ts.tst = nmi_sleep_test;
812 ts.name = "nmi_sleep_test";
813 /* Activate test with initial breakpoint */
814 kgdb_breakpoint();
815 local_irq_save(flags);
816 mdelay(nmi_sleep*1000);
817 touch_nmi_watchdog();
818 local_irq_restore(flags);
819 if (test_complete != 2)
820 printk(KERN_ERR "kgdbts: ERROR nmi_test did not hit nmi\n");
821 kgdb_breakpoint();
822 if (test_complete == 1)
823 return;
824
825 printk(KERN_ERR "kgdbts: ERROR %s test failed\n", ts.name);
826}
827
828static void run_bad_read_test(void)
829{
830 init_simple_test();
831 ts.tst = bad_read_test;
832 ts.name = "bad_read_test";
833 /* Activate test with initial breakpoint */
834 kgdb_breakpoint();
835}
836
837static void run_do_fork_test(void)
838{
839 init_simple_test();
840 ts.tst = do_fork_test;
841 ts.name = "do_fork_test";
842 /* Activate test with initial breakpoint */
843 kgdb_breakpoint();
844}
845
846static void run_sys_open_test(void)
847{
848 init_simple_test();
849 ts.tst = sys_open_test;
850 ts.name = "sys_open_test";
851 /* Activate test with initial breakpoint */
852 kgdb_breakpoint();
853}
854
855static void run_singlestep_break_test(void)
856{
857 init_simple_test();
858 ts.tst = singlestep_break_test;
859 ts.name = "singlestep_breakpoint_test";
860 /* Activate test with initial breakpoint */
861 kgdb_breakpoint();
862 kgdbts_break_test();
863 kgdbts_break_test();
864}
865
866static void kgdbts_run_tests(void)
867{
868 char *ptr;
869 int fork_test = 0;
870 int sys_open_test = 0;
871 int nmi_sleep = 0;
872
873 ptr = strstr(config, "F");
874 if (ptr)
875 fork_test = simple_strtol(ptr+1, NULL, 10);
876 ptr = strstr(config, "S");
877 if (ptr)
878 sys_open_test = simple_strtol(ptr+1, NULL, 10);
879 ptr = strstr(config, "N");
880 if (ptr)
881 nmi_sleep = simple_strtol(ptr+1, NULL, 10);
882
883 /* required internal KGDB tests */
884 v1printk("kgdbts:RUN plant and detach test\n");
885 run_plant_and_detach_test(0);
886 v1printk("kgdbts:RUN sw breakpoint test\n");
887 run_breakpoint_test(0);
888 v1printk("kgdbts:RUN bad memory access test\n");
889 run_bad_read_test();
890 v1printk("kgdbts:RUN singlestep breakpoint test\n");
891 run_singlestep_break_test();
892
893 /* ===Optional tests=== */
894
895 /* All HW break point tests */
896 if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) {
897 v1printk("kgdbts:RUN hw breakpoint test\n");
898 run_breakpoint_test(1);
899 v1printk("kgdbts:RUN hw write breakpoint test\n");
900 run_hw_break_test(1);
901 v1printk("kgdbts:RUN access write breakpoint test\n");
902 run_hw_break_test(0);
903 }
904
905 if (nmi_sleep) {
906 v1printk("kgdbts:RUN NMI sleep %i seconds test\n", nmi_sleep);
907 run_nmi_sleep_test(nmi_sleep);
908 }
909
910 /* If the do_fork test is run it will be the last test that is
911 * executed because a kernel thread will be spawned at the very
912 * end to unregister the debug hooks.
913 */
914 if (fork_test) {
915 repeat_test = fork_test;
916 printk(KERN_INFO "kgdbts:RUN do_fork for %i breakpoints\n",
917 repeat_test);
918 kthread_run(kgdbts_unreg_thread, 0, "kgdbts_unreg");
919 run_do_fork_test();
920 return;
921 }
922
923 /* If the sys_open test is run it will be the last test that is
924 * executed because a kernel thread will be spawned at the very
925 * end to unregister the debug hooks.
926 */
927 if (sys_open_test) {
928 repeat_test = sys_open_test;
929 printk(KERN_INFO "kgdbts:RUN sys_open for %i breakpoints\n",
930 repeat_test);
931 kthread_run(kgdbts_unreg_thread, 0, "kgdbts_unreg");
932 run_sys_open_test();
933 return;
934 }
935 /* Shutdown and unregister */
936 kgdb_unregister_io_module(&kgdbts_io_ops);
937 configured = 0;
938}
939
940static int kgdbts_option_setup(char *opt)
941{
942 if (strlen(opt) > MAX_CONFIG_LEN) {
943 printk(KERN_ERR "kgdbts: config string too long\n");
944 return -ENOSPC;
945 }
946 strcpy(config, opt);
947
948 verbose = 0;
949 if (strstr(config, "V1"))
950 verbose = 1;
951 if (strstr(config, "V2"))
952 verbose = 2;
953
954 return 0;
955}
956
957__setup("kgdbts=", kgdbts_option_setup);
958
959static int configure_kgdbts(void)
960{
961 int err = 0;
962
963 if (!strlen(config) || isspace(config[0]))
964 goto noconfig;
965 err = kgdbts_option_setup(config);
966 if (err)
967 goto noconfig;
968
969 final_ack = 0;
970 run_plant_and_detach_test(1);
971
972 err = kgdb_register_io_module(&kgdbts_io_ops);
973 if (err) {
974 configured = 0;
975 return err;
976 }
977 configured = 1;
978 kgdbts_run_tests();
979
980 return err;
981
982noconfig:
983 config[0] = 0;
984 configured = 0;
985
986 return err;
987}
988
989static int __init init_kgdbts(void)
990{
991 /* Already configured? */
992 if (configured == 1)
993 return 0;
994
995 return configure_kgdbts();
996}
997
998static void cleanup_kgdbts(void)
999{
1000 if (configured == 1)
1001 kgdb_unregister_io_module(&kgdbts_io_ops);
1002}
1003
1004static int kgdbts_get_char(void)
1005{
1006 int val = 0;
1007
1008 if (ts.run_test)
1009 val = ts.run_test(1, 0);
1010
1011 return val;
1012}
1013
1014static void kgdbts_put_char(u8 chr)
1015{
1016 if (ts.run_test)
1017 ts.run_test(0, chr);
1018}
1019
1020static int param_set_kgdbts_var(const char *kmessage, struct kernel_param *kp)
1021{
1022 int len = strlen(kmessage);
1023
1024 if (len >= MAX_CONFIG_LEN) {
1025 printk(KERN_ERR "kgdbts: config string too long\n");
1026 return -ENOSPC;
1027 }
1028
1029 /* Only copy in the string if the init function has not run yet */
1030 if (configured < 0) {
1031 strcpy(config, kmessage);
1032 return 0;
1033 }
1034
1035 if (kgdb_connected) {
1036 printk(KERN_ERR
1037 "kgdbts: Cannot reconfigure while KGDB is connected.\n");
1038
1039 return -EBUSY;
1040 }
1041
1042 strcpy(config, kmessage);
1043 /* Chop out \n char as a result of echo */
1044 if (config[len - 1] == '\n')
1045 config[len - 1] = '\0';
1046
1047 if (configured == 1)
1048 cleanup_kgdbts();
1049
1050 /* Go and configure with the new params. */
1051 return configure_kgdbts();
1052}
1053
1054static void kgdbts_pre_exp_handler(void)
1055{
1056 /* Increment the module count when the debugger is active */
1057 if (!kgdb_connected)
1058 try_module_get(THIS_MODULE);
1059}
1060
1061static void kgdbts_post_exp_handler(void)
1062{
1063 /* decrement the module count when the debugger detaches */
1064 if (!kgdb_connected)
1065 module_put(THIS_MODULE);
1066}
1067
1068static struct kgdb_io kgdbts_io_ops = {
1069 .name = "kgdbts",
1070 .read_char = kgdbts_get_char,
1071 .write_char = kgdbts_put_char,
1072 .pre_exception = kgdbts_pre_exp_handler,
1073 .post_exception = kgdbts_post_exp_handler,
1074};
1075
1076module_init(init_kgdbts);
1077module_exit(cleanup_kgdbts);
1078module_param_call(kgdbts, param_set_kgdbts_var, param_get_string, &kps, 0644);
1079MODULE_PARM_DESC(kgdbts, "<A|V1|V2>[F#|S#][N#]");
1080MODULE_DESCRIPTION("KGDB Test Suite");
1081MODULE_LICENSE("GPL");
1082MODULE_AUTHOR("Wind River Systems, Inc.");
1083