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