Commit 8daaa5f8261bffd2f6217a960f9182d0503a5c44
Committed by
Ingo Molnar
1 parent
8a1f4653f2
Exists in
master
and in
16 other branches
kdb: Add support for external NMI handler to call KGDB/KDB
This patch adds a kgdb_nmicallin() interface that can be used by external NMI handlers to call the KGDB/KDB handler. The primary need for this is for those types of NMI interrupts where all the CPUs have already received the NMI signal. Therefore no send_IPI(NMI) is required, and in fact it will cause a 2nd unhandled NMI to occur. This generates the "Dazed and Confuzed" messages. Since all the CPUs are getting the NMI at roughly the same time, it's not guaranteed that the first CPU that hits the NMI handler will manage to enter KGDB and set the dbg_master_lock before the slaves start entering. The new argument "send_ready" was added for KGDB to signal the NMI handler to release the slave CPUs for entry into KGDB. Signed-off-by: Mike Travis <travis@sgi.com> Acked-by: Jason Wessel <jason.wessel@windriver.com> Reviewed-by: Dimitri Sivanich <sivanich@sgi.com> Reviewed-by: Hedi Berriche <hedi@sgi.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Link: http://lkml.kernel.org/r/20131002151417.928886849@asylum.americas.sgi.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Showing 6 changed files with 42 additions and 3 deletions Inline Diff
include/linux/kdb.h
1 | #ifndef _KDB_H | 1 | #ifndef _KDB_H |
2 | #define _KDB_H | 2 | #define _KDB_H |
3 | 3 | ||
4 | /* | 4 | /* |
5 | * Kernel Debugger Architecture Independent Global Headers | 5 | * Kernel Debugger Architecture Independent Global Headers |
6 | * | 6 | * |
7 | * This file is subject to the terms and conditions of the GNU General Public | 7 | * This file is subject to the terms and conditions of the GNU General Public |
8 | * License. See the file "COPYING" in the main directory of this archive | 8 | * License. See the file "COPYING" in the main directory of this archive |
9 | * for more details. | 9 | * for more details. |
10 | * | 10 | * |
11 | * Copyright (c) 2000-2007 Silicon Graphics, Inc. All Rights Reserved. | 11 | * Copyright (c) 2000-2007 Silicon Graphics, Inc. All Rights Reserved. |
12 | * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com> | 12 | * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com> |
13 | * Copyright (C) 2009 Jason Wessel <jason.wessel@windriver.com> | 13 | * Copyright (C) 2009 Jason Wessel <jason.wessel@windriver.com> |
14 | */ | 14 | */ |
15 | 15 | ||
16 | typedef enum { | 16 | typedef enum { |
17 | KDB_REPEAT_NONE = 0, /* Do not repeat this command */ | 17 | KDB_REPEAT_NONE = 0, /* Do not repeat this command */ |
18 | KDB_REPEAT_NO_ARGS, /* Repeat the command without arguments */ | 18 | KDB_REPEAT_NO_ARGS, /* Repeat the command without arguments */ |
19 | KDB_REPEAT_WITH_ARGS, /* Repeat the command including its arguments */ | 19 | KDB_REPEAT_WITH_ARGS, /* Repeat the command including its arguments */ |
20 | } kdb_repeat_t; | 20 | } kdb_repeat_t; |
21 | 21 | ||
22 | typedef int (*kdb_func_t)(int, const char **); | 22 | typedef int (*kdb_func_t)(int, const char **); |
23 | 23 | ||
24 | #ifdef CONFIG_KGDB_KDB | 24 | #ifdef CONFIG_KGDB_KDB |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
27 | #include <linux/atomic.h> | 27 | #include <linux/atomic.h> |
28 | 28 | ||
29 | #define KDB_POLL_FUNC_MAX 5 | 29 | #define KDB_POLL_FUNC_MAX 5 |
30 | extern int kdb_poll_idx; | 30 | extern int kdb_poll_idx; |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * kdb_initial_cpu is initialized to -1, and is set to the cpu | 33 | * kdb_initial_cpu is initialized to -1, and is set to the cpu |
34 | * number whenever the kernel debugger is entered. | 34 | * number whenever the kernel debugger is entered. |
35 | */ | 35 | */ |
36 | extern int kdb_initial_cpu; | 36 | extern int kdb_initial_cpu; |
37 | extern atomic_t kdb_event; | 37 | extern atomic_t kdb_event; |
38 | 38 | ||
39 | /* Types and messages used for dynamically added kdb shell commands */ | 39 | /* Types and messages used for dynamically added kdb shell commands */ |
40 | 40 | ||
41 | #define KDB_MAXARGS 16 /* Maximum number of arguments to a function */ | 41 | #define KDB_MAXARGS 16 /* Maximum number of arguments to a function */ |
42 | 42 | ||
43 | /* KDB return codes from a command or internal kdb function */ | 43 | /* KDB return codes from a command or internal kdb function */ |
44 | #define KDB_NOTFOUND (-1) | 44 | #define KDB_NOTFOUND (-1) |
45 | #define KDB_ARGCOUNT (-2) | 45 | #define KDB_ARGCOUNT (-2) |
46 | #define KDB_BADWIDTH (-3) | 46 | #define KDB_BADWIDTH (-3) |
47 | #define KDB_BADRADIX (-4) | 47 | #define KDB_BADRADIX (-4) |
48 | #define KDB_NOTENV (-5) | 48 | #define KDB_NOTENV (-5) |
49 | #define KDB_NOENVVALUE (-6) | 49 | #define KDB_NOENVVALUE (-6) |
50 | #define KDB_NOTIMP (-7) | 50 | #define KDB_NOTIMP (-7) |
51 | #define KDB_ENVFULL (-8) | 51 | #define KDB_ENVFULL (-8) |
52 | #define KDB_ENVBUFFULL (-9) | 52 | #define KDB_ENVBUFFULL (-9) |
53 | #define KDB_TOOMANYBPT (-10) | 53 | #define KDB_TOOMANYBPT (-10) |
54 | #define KDB_TOOMANYDBREGS (-11) | 54 | #define KDB_TOOMANYDBREGS (-11) |
55 | #define KDB_DUPBPT (-12) | 55 | #define KDB_DUPBPT (-12) |
56 | #define KDB_BPTNOTFOUND (-13) | 56 | #define KDB_BPTNOTFOUND (-13) |
57 | #define KDB_BADMODE (-14) | 57 | #define KDB_BADMODE (-14) |
58 | #define KDB_BADINT (-15) | 58 | #define KDB_BADINT (-15) |
59 | #define KDB_INVADDRFMT (-16) | 59 | #define KDB_INVADDRFMT (-16) |
60 | #define KDB_BADREG (-17) | 60 | #define KDB_BADREG (-17) |
61 | #define KDB_BADCPUNUM (-18) | 61 | #define KDB_BADCPUNUM (-18) |
62 | #define KDB_BADLENGTH (-19) | 62 | #define KDB_BADLENGTH (-19) |
63 | #define KDB_NOBP (-20) | 63 | #define KDB_NOBP (-20) |
64 | #define KDB_BADADDR (-21) | 64 | #define KDB_BADADDR (-21) |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * kdb_diemsg | 67 | * kdb_diemsg |
68 | * | 68 | * |
69 | * Contains a pointer to the last string supplied to the | 69 | * Contains a pointer to the last string supplied to the |
70 | * kernel 'die' panic function. | 70 | * kernel 'die' panic function. |
71 | */ | 71 | */ |
72 | extern const char *kdb_diemsg; | 72 | extern const char *kdb_diemsg; |
73 | 73 | ||
74 | #define KDB_FLAG_EARLYKDB (1 << 0) /* set from boot parameter kdb=early */ | 74 | #define KDB_FLAG_EARLYKDB (1 << 0) /* set from boot parameter kdb=early */ |
75 | #define KDB_FLAG_CATASTROPHIC (1 << 1) /* A catastrophic event has occurred */ | 75 | #define KDB_FLAG_CATASTROPHIC (1 << 1) /* A catastrophic event has occurred */ |
76 | #define KDB_FLAG_CMD_INTERRUPT (1 << 2) /* Previous command was interrupted */ | 76 | #define KDB_FLAG_CMD_INTERRUPT (1 << 2) /* Previous command was interrupted */ |
77 | #define KDB_FLAG_NOIPI (1 << 3) /* Do not send IPIs */ | 77 | #define KDB_FLAG_NOIPI (1 << 3) /* Do not send IPIs */ |
78 | #define KDB_FLAG_NO_CONSOLE (1 << 5) /* No console is available, | 78 | #define KDB_FLAG_NO_CONSOLE (1 << 5) /* No console is available, |
79 | * kdb is disabled */ | 79 | * kdb is disabled */ |
80 | #define KDB_FLAG_NO_VT_CONSOLE (1 << 6) /* No VT console is available, do | 80 | #define KDB_FLAG_NO_VT_CONSOLE (1 << 6) /* No VT console is available, do |
81 | * not use keyboard */ | 81 | * not use keyboard */ |
82 | #define KDB_FLAG_NO_I8042 (1 << 7) /* No i8042 chip is available, do | 82 | #define KDB_FLAG_NO_I8042 (1 << 7) /* No i8042 chip is available, do |
83 | * not use keyboard */ | 83 | * not use keyboard */ |
84 | 84 | ||
85 | extern int kdb_flags; /* Global flags, see kdb_state for per cpu state */ | 85 | extern int kdb_flags; /* Global flags, see kdb_state for per cpu state */ |
86 | 86 | ||
87 | extern void kdb_save_flags(void); | 87 | extern void kdb_save_flags(void); |
88 | extern void kdb_restore_flags(void); | 88 | extern void kdb_restore_flags(void); |
89 | 89 | ||
90 | #define KDB_FLAG(flag) (kdb_flags & KDB_FLAG_##flag) | 90 | #define KDB_FLAG(flag) (kdb_flags & KDB_FLAG_##flag) |
91 | #define KDB_FLAG_SET(flag) ((void)(kdb_flags |= KDB_FLAG_##flag)) | 91 | #define KDB_FLAG_SET(flag) ((void)(kdb_flags |= KDB_FLAG_##flag)) |
92 | #define KDB_FLAG_CLEAR(flag) ((void)(kdb_flags &= ~KDB_FLAG_##flag)) | 92 | #define KDB_FLAG_CLEAR(flag) ((void)(kdb_flags &= ~KDB_FLAG_##flag)) |
93 | 93 | ||
94 | /* | 94 | /* |
95 | * External entry point for the kernel debugger. The pt_regs | 95 | * External entry point for the kernel debugger. The pt_regs |
96 | * at the time of entry are supplied along with the reason for | 96 | * at the time of entry are supplied along with the reason for |
97 | * entry to the kernel debugger. | 97 | * entry to the kernel debugger. |
98 | */ | 98 | */ |
99 | 99 | ||
100 | typedef enum { | 100 | typedef enum { |
101 | KDB_REASON_ENTER = 1, /* KDB_ENTER() trap/fault - regs valid */ | 101 | KDB_REASON_ENTER = 1, /* KDB_ENTER() trap/fault - regs valid */ |
102 | KDB_REASON_ENTER_SLAVE, /* KDB_ENTER_SLAVE() trap/fault - regs valid */ | 102 | KDB_REASON_ENTER_SLAVE, /* KDB_ENTER_SLAVE() trap/fault - regs valid */ |
103 | KDB_REASON_BREAK, /* Breakpoint inst. - regs valid */ | 103 | KDB_REASON_BREAK, /* Breakpoint inst. - regs valid */ |
104 | KDB_REASON_DEBUG, /* Debug Fault - regs valid */ | 104 | KDB_REASON_DEBUG, /* Debug Fault - regs valid */ |
105 | KDB_REASON_OOPS, /* Kernel Oops - regs valid */ | 105 | KDB_REASON_OOPS, /* Kernel Oops - regs valid */ |
106 | KDB_REASON_SWITCH, /* CPU switch - regs valid*/ | 106 | KDB_REASON_SWITCH, /* CPU switch - regs valid*/ |
107 | KDB_REASON_KEYBOARD, /* Keyboard entry - regs valid */ | 107 | KDB_REASON_KEYBOARD, /* Keyboard entry - regs valid */ |
108 | KDB_REASON_NMI, /* Non-maskable interrupt; regs valid */ | 108 | KDB_REASON_NMI, /* Non-maskable interrupt; regs valid */ |
109 | KDB_REASON_RECURSE, /* Recursive entry to kdb; | 109 | KDB_REASON_RECURSE, /* Recursive entry to kdb; |
110 | * regs probably valid */ | 110 | * regs probably valid */ |
111 | KDB_REASON_SSTEP, /* Single Step trap. - regs valid */ | 111 | KDB_REASON_SSTEP, /* Single Step trap. - regs valid */ |
112 | KDB_REASON_SYSTEM_NMI, /* In NMI due to SYSTEM cmd; regs valid */ | ||
112 | } kdb_reason_t; | 113 | } kdb_reason_t; |
113 | 114 | ||
114 | extern int kdb_trap_printk; | 115 | extern int kdb_trap_printk; |
115 | extern __printf(1, 0) int vkdb_printf(const char *fmt, va_list args); | 116 | extern __printf(1, 0) int vkdb_printf(const char *fmt, va_list args); |
116 | extern __printf(1, 2) int kdb_printf(const char *, ...); | 117 | extern __printf(1, 2) int kdb_printf(const char *, ...); |
117 | typedef __printf(1, 2) int (*kdb_printf_t)(const char *, ...); | 118 | typedef __printf(1, 2) int (*kdb_printf_t)(const char *, ...); |
118 | 119 | ||
119 | extern void kdb_init(int level); | 120 | extern void kdb_init(int level); |
120 | 121 | ||
121 | /* Access to kdb specific polling devices */ | 122 | /* Access to kdb specific polling devices */ |
122 | typedef int (*get_char_func)(void); | 123 | typedef int (*get_char_func)(void); |
123 | extern get_char_func kdb_poll_funcs[]; | 124 | extern get_char_func kdb_poll_funcs[]; |
124 | extern int kdb_get_kbd_char(void); | 125 | extern int kdb_get_kbd_char(void); |
125 | 126 | ||
126 | static inline | 127 | static inline |
127 | int kdb_process_cpu(const struct task_struct *p) | 128 | int kdb_process_cpu(const struct task_struct *p) |
128 | { | 129 | { |
129 | unsigned int cpu = task_thread_info(p)->cpu; | 130 | unsigned int cpu = task_thread_info(p)->cpu; |
130 | if (cpu > num_possible_cpus()) | 131 | if (cpu > num_possible_cpus()) |
131 | cpu = 0; | 132 | cpu = 0; |
132 | return cpu; | 133 | return cpu; |
133 | } | 134 | } |
134 | 135 | ||
135 | /* kdb access to register set for stack dumping */ | 136 | /* kdb access to register set for stack dumping */ |
136 | extern struct pt_regs *kdb_current_regs; | 137 | extern struct pt_regs *kdb_current_regs; |
137 | #ifdef CONFIG_KALLSYMS | 138 | #ifdef CONFIG_KALLSYMS |
138 | extern const char *kdb_walk_kallsyms(loff_t *pos); | 139 | extern const char *kdb_walk_kallsyms(loff_t *pos); |
139 | #else /* ! CONFIG_KALLSYMS */ | 140 | #else /* ! CONFIG_KALLSYMS */ |
140 | static inline const char *kdb_walk_kallsyms(loff_t *pos) | 141 | static inline const char *kdb_walk_kallsyms(loff_t *pos) |
141 | { | 142 | { |
142 | return NULL; | 143 | return NULL; |
143 | } | 144 | } |
144 | #endif /* ! CONFIG_KALLSYMS */ | 145 | #endif /* ! CONFIG_KALLSYMS */ |
145 | 146 | ||
146 | /* Dynamic kdb shell command registration */ | 147 | /* Dynamic kdb shell command registration */ |
147 | extern int kdb_register(char *, kdb_func_t, char *, char *, short); | 148 | extern int kdb_register(char *, kdb_func_t, char *, char *, short); |
148 | extern int kdb_register_repeat(char *, kdb_func_t, char *, char *, | 149 | extern int kdb_register_repeat(char *, kdb_func_t, char *, char *, |
149 | short, kdb_repeat_t); | 150 | short, kdb_repeat_t); |
150 | extern int kdb_unregister(char *); | 151 | extern int kdb_unregister(char *); |
151 | #else /* ! CONFIG_KGDB_KDB */ | 152 | #else /* ! CONFIG_KGDB_KDB */ |
152 | static inline __printf(1, 2) int kdb_printf(const char *fmt, ...) { return 0; } | 153 | static inline __printf(1, 2) int kdb_printf(const char *fmt, ...) { return 0; } |
153 | static inline void kdb_init(int level) {} | 154 | static inline void kdb_init(int level) {} |
154 | static inline int kdb_register(char *cmd, kdb_func_t func, char *usage, | 155 | static inline int kdb_register(char *cmd, kdb_func_t func, char *usage, |
155 | char *help, short minlen) { return 0; } | 156 | char *help, short minlen) { return 0; } |
156 | static inline int kdb_register_repeat(char *cmd, kdb_func_t func, char *usage, | 157 | static inline int kdb_register_repeat(char *cmd, kdb_func_t func, char *usage, |
157 | char *help, short minlen, | 158 | char *help, short minlen, |
158 | kdb_repeat_t repeat) { return 0; } | 159 | kdb_repeat_t repeat) { return 0; } |
159 | static inline int kdb_unregister(char *cmd) { return 0; } | 160 | static inline int kdb_unregister(char *cmd) { return 0; } |
160 | #endif /* CONFIG_KGDB_KDB */ | 161 | #endif /* CONFIG_KGDB_KDB */ |
161 | enum { | 162 | enum { |
162 | KDB_NOT_INITIALIZED, | 163 | KDB_NOT_INITIALIZED, |
163 | KDB_INIT_EARLY, | 164 | KDB_INIT_EARLY, |
164 | KDB_INIT_FULL, | 165 | KDB_INIT_FULL, |
165 | }; | 166 | }; |
166 | 167 | ||
167 | extern int kdbgetintenv(const char *, int *); | 168 | extern int kdbgetintenv(const char *, int *); |
168 | extern int kdb_set(int, const char **); | 169 | extern int kdb_set(int, const char **); |
169 | 170 | ||
170 | #endif /* !_KDB_H */ | 171 | #endif /* !_KDB_H */ |
171 | 172 |
include/linux/kgdb.h
1 | /* | 1 | /* |
2 | * This provides the callbacks and functions that KGDB needs to share between | 2 | * This provides the callbacks and functions that KGDB needs to share between |
3 | * the core, I/O and arch-specific portions. | 3 | * the core, I/O and arch-specific portions. |
4 | * | 4 | * |
5 | * Author: Amit Kale <amitkale@linsyssoft.com> and | 5 | * Author: Amit Kale <amitkale@linsyssoft.com> and |
6 | * Tom Rini <trini@kernel.crashing.org> | 6 | * Tom Rini <trini@kernel.crashing.org> |
7 | * | 7 | * |
8 | * 2001-2004 (c) Amit S. Kale and 2003-2005 (c) MontaVista Software, Inc. | 8 | * 2001-2004 (c) Amit S. Kale and 2003-2005 (c) MontaVista Software, Inc. |
9 | * This file is licensed under the terms of the GNU General Public License | 9 | * This file is licensed under the terms of the GNU General Public License |
10 | * version 2. This program is licensed "as is" without any warranty of any | 10 | * version 2. This program is licensed "as is" without any warranty of any |
11 | * kind, whether express or implied. | 11 | * kind, whether express or implied. |
12 | */ | 12 | */ |
13 | #ifndef _KGDB_H_ | 13 | #ifndef _KGDB_H_ |
14 | #define _KGDB_H_ | 14 | #define _KGDB_H_ |
15 | 15 | ||
16 | #include <linux/linkage.h> | 16 | #include <linux/linkage.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/atomic.h> | 18 | #include <linux/atomic.h> |
19 | #ifdef CONFIG_HAVE_ARCH_KGDB | 19 | #ifdef CONFIG_HAVE_ARCH_KGDB |
20 | #include <asm/kgdb.h> | 20 | #include <asm/kgdb.h> |
21 | #endif | 21 | #endif |
22 | 22 | ||
23 | #ifdef CONFIG_KGDB | 23 | #ifdef CONFIG_KGDB |
24 | struct pt_regs; | 24 | struct pt_regs; |
25 | 25 | ||
26 | /** | 26 | /** |
27 | * kgdb_skipexception - (optional) exit kgdb_handle_exception early | 27 | * kgdb_skipexception - (optional) exit kgdb_handle_exception early |
28 | * @exception: Exception vector number | 28 | * @exception: Exception vector number |
29 | * @regs: Current &struct pt_regs. | 29 | * @regs: Current &struct pt_regs. |
30 | * | 30 | * |
31 | * On some architectures it is required to skip a breakpoint | 31 | * On some architectures it is required to skip a breakpoint |
32 | * exception when it occurs after a breakpoint has been removed. | 32 | * exception when it occurs after a breakpoint has been removed. |
33 | * This can be implemented in the architecture specific portion of kgdb. | 33 | * This can be implemented in the architecture specific portion of kgdb. |
34 | */ | 34 | */ |
35 | extern int kgdb_skipexception(int exception, struct pt_regs *regs); | 35 | extern int kgdb_skipexception(int exception, struct pt_regs *regs); |
36 | 36 | ||
37 | struct tasklet_struct; | 37 | struct tasklet_struct; |
38 | struct task_struct; | 38 | struct task_struct; |
39 | struct uart_port; | 39 | struct uart_port; |
40 | 40 | ||
41 | /** | 41 | /** |
42 | * kgdb_breakpoint - compiled in breakpoint | 42 | * kgdb_breakpoint - compiled in breakpoint |
43 | * | 43 | * |
44 | * This will be implemented as a static inline per architecture. This | 44 | * This will be implemented as a static inline per architecture. This |
45 | * function is called by the kgdb core to execute an architecture | 45 | * function is called by the kgdb core to execute an architecture |
46 | * specific trap to cause kgdb to enter the exception processing. | 46 | * specific trap to cause kgdb to enter the exception processing. |
47 | * | 47 | * |
48 | */ | 48 | */ |
49 | void kgdb_breakpoint(void); | 49 | void kgdb_breakpoint(void); |
50 | 50 | ||
51 | extern int kgdb_connected; | 51 | extern int kgdb_connected; |
52 | extern int kgdb_io_module_registered; | 52 | extern int kgdb_io_module_registered; |
53 | 53 | ||
54 | extern atomic_t kgdb_setting_breakpoint; | 54 | extern atomic_t kgdb_setting_breakpoint; |
55 | extern atomic_t kgdb_cpu_doing_single_step; | 55 | extern atomic_t kgdb_cpu_doing_single_step; |
56 | 56 | ||
57 | extern struct task_struct *kgdb_usethread; | 57 | extern struct task_struct *kgdb_usethread; |
58 | extern struct task_struct *kgdb_contthread; | 58 | extern struct task_struct *kgdb_contthread; |
59 | 59 | ||
60 | enum kgdb_bptype { | 60 | enum kgdb_bptype { |
61 | BP_BREAKPOINT = 0, | 61 | BP_BREAKPOINT = 0, |
62 | BP_HARDWARE_BREAKPOINT, | 62 | BP_HARDWARE_BREAKPOINT, |
63 | BP_WRITE_WATCHPOINT, | 63 | BP_WRITE_WATCHPOINT, |
64 | BP_READ_WATCHPOINT, | 64 | BP_READ_WATCHPOINT, |
65 | BP_ACCESS_WATCHPOINT, | 65 | BP_ACCESS_WATCHPOINT, |
66 | BP_POKE_BREAKPOINT, | 66 | BP_POKE_BREAKPOINT, |
67 | }; | 67 | }; |
68 | 68 | ||
69 | enum kgdb_bpstate { | 69 | enum kgdb_bpstate { |
70 | BP_UNDEFINED = 0, | 70 | BP_UNDEFINED = 0, |
71 | BP_REMOVED, | 71 | BP_REMOVED, |
72 | BP_SET, | 72 | BP_SET, |
73 | BP_ACTIVE | 73 | BP_ACTIVE |
74 | }; | 74 | }; |
75 | 75 | ||
76 | struct kgdb_bkpt { | 76 | struct kgdb_bkpt { |
77 | unsigned long bpt_addr; | 77 | unsigned long bpt_addr; |
78 | unsigned char saved_instr[BREAK_INSTR_SIZE]; | 78 | unsigned char saved_instr[BREAK_INSTR_SIZE]; |
79 | enum kgdb_bptype type; | 79 | enum kgdb_bptype type; |
80 | enum kgdb_bpstate state; | 80 | enum kgdb_bpstate state; |
81 | }; | 81 | }; |
82 | 82 | ||
83 | struct dbg_reg_def_t { | 83 | struct dbg_reg_def_t { |
84 | char *name; | 84 | char *name; |
85 | int size; | 85 | int size; |
86 | int offset; | 86 | int offset; |
87 | }; | 87 | }; |
88 | 88 | ||
89 | #ifndef DBG_MAX_REG_NUM | 89 | #ifndef DBG_MAX_REG_NUM |
90 | #define DBG_MAX_REG_NUM 0 | 90 | #define DBG_MAX_REG_NUM 0 |
91 | #else | 91 | #else |
92 | extern struct dbg_reg_def_t dbg_reg_def[]; | 92 | extern struct dbg_reg_def_t dbg_reg_def[]; |
93 | extern char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs); | 93 | extern char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs); |
94 | extern int dbg_set_reg(int regno, void *mem, struct pt_regs *regs); | 94 | extern int dbg_set_reg(int regno, void *mem, struct pt_regs *regs); |
95 | #endif | 95 | #endif |
96 | #ifndef KGDB_MAX_BREAKPOINTS | 96 | #ifndef KGDB_MAX_BREAKPOINTS |
97 | # define KGDB_MAX_BREAKPOINTS 1000 | 97 | # define KGDB_MAX_BREAKPOINTS 1000 |
98 | #endif | 98 | #endif |
99 | 99 | ||
100 | #define KGDB_HW_BREAKPOINT 1 | 100 | #define KGDB_HW_BREAKPOINT 1 |
101 | 101 | ||
102 | /* | 102 | /* |
103 | * Functions each KGDB-supporting architecture must provide: | 103 | * Functions each KGDB-supporting architecture must provide: |
104 | */ | 104 | */ |
105 | 105 | ||
106 | /** | 106 | /** |
107 | * kgdb_arch_init - Perform any architecture specific initalization. | 107 | * kgdb_arch_init - Perform any architecture specific initalization. |
108 | * | 108 | * |
109 | * This function will handle the initalization of any architecture | 109 | * This function will handle the initalization of any architecture |
110 | * specific callbacks. | 110 | * specific callbacks. |
111 | */ | 111 | */ |
112 | extern int kgdb_arch_init(void); | 112 | extern int kgdb_arch_init(void); |
113 | 113 | ||
114 | /** | 114 | /** |
115 | * kgdb_arch_exit - Perform any architecture specific uninitalization. | 115 | * kgdb_arch_exit - Perform any architecture specific uninitalization. |
116 | * | 116 | * |
117 | * This function will handle the uninitalization of any architecture | 117 | * This function will handle the uninitalization of any architecture |
118 | * specific callbacks, for dynamic registration and unregistration. | 118 | * specific callbacks, for dynamic registration and unregistration. |
119 | */ | 119 | */ |
120 | extern void kgdb_arch_exit(void); | 120 | extern void kgdb_arch_exit(void); |
121 | 121 | ||
122 | /** | 122 | /** |
123 | * pt_regs_to_gdb_regs - Convert ptrace regs to GDB regs | 123 | * pt_regs_to_gdb_regs - Convert ptrace regs to GDB regs |
124 | * @gdb_regs: A pointer to hold the registers in the order GDB wants. | 124 | * @gdb_regs: A pointer to hold the registers in the order GDB wants. |
125 | * @regs: The &struct pt_regs of the current process. | 125 | * @regs: The &struct pt_regs of the current process. |
126 | * | 126 | * |
127 | * Convert the pt_regs in @regs into the format for registers that | 127 | * Convert the pt_regs in @regs into the format for registers that |
128 | * GDB expects, stored in @gdb_regs. | 128 | * GDB expects, stored in @gdb_regs. |
129 | */ | 129 | */ |
130 | extern void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs); | 130 | extern void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs); |
131 | 131 | ||
132 | /** | 132 | /** |
133 | * sleeping_thread_to_gdb_regs - Convert ptrace regs to GDB regs | 133 | * sleeping_thread_to_gdb_regs - Convert ptrace regs to GDB regs |
134 | * @gdb_regs: A pointer to hold the registers in the order GDB wants. | 134 | * @gdb_regs: A pointer to hold the registers in the order GDB wants. |
135 | * @p: The &struct task_struct of the desired process. | 135 | * @p: The &struct task_struct of the desired process. |
136 | * | 136 | * |
137 | * Convert the register values of the sleeping process in @p to | 137 | * Convert the register values of the sleeping process in @p to |
138 | * the format that GDB expects. | 138 | * the format that GDB expects. |
139 | * This function is called when kgdb does not have access to the | 139 | * This function is called when kgdb does not have access to the |
140 | * &struct pt_regs and therefore it should fill the gdb registers | 140 | * &struct pt_regs and therefore it should fill the gdb registers |
141 | * @gdb_regs with what has been saved in &struct thread_struct | 141 | * @gdb_regs with what has been saved in &struct thread_struct |
142 | * thread field during switch_to. | 142 | * thread field during switch_to. |
143 | */ | 143 | */ |
144 | extern void | 144 | extern void |
145 | sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p); | 145 | sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p); |
146 | 146 | ||
147 | /** | 147 | /** |
148 | * gdb_regs_to_pt_regs - Convert GDB regs to ptrace regs. | 148 | * gdb_regs_to_pt_regs - Convert GDB regs to ptrace regs. |
149 | * @gdb_regs: A pointer to hold the registers we've received from GDB. | 149 | * @gdb_regs: A pointer to hold the registers we've received from GDB. |
150 | * @regs: A pointer to a &struct pt_regs to hold these values in. | 150 | * @regs: A pointer to a &struct pt_regs to hold these values in. |
151 | * | 151 | * |
152 | * Convert the GDB regs in @gdb_regs into the pt_regs, and store them | 152 | * Convert the GDB regs in @gdb_regs into the pt_regs, and store them |
153 | * in @regs. | 153 | * in @regs. |
154 | */ | 154 | */ |
155 | extern void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs); | 155 | extern void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs); |
156 | 156 | ||
157 | /** | 157 | /** |
158 | * kgdb_arch_handle_exception - Handle architecture specific GDB packets. | 158 | * kgdb_arch_handle_exception - Handle architecture specific GDB packets. |
159 | * @vector: The error vector of the exception that happened. | 159 | * @vector: The error vector of the exception that happened. |
160 | * @signo: The signal number of the exception that happened. | 160 | * @signo: The signal number of the exception that happened. |
161 | * @err_code: The error code of the exception that happened. | 161 | * @err_code: The error code of the exception that happened. |
162 | * @remcom_in_buffer: The buffer of the packet we have read. | 162 | * @remcom_in_buffer: The buffer of the packet we have read. |
163 | * @remcom_out_buffer: The buffer of %BUFMAX bytes to write a packet into. | 163 | * @remcom_out_buffer: The buffer of %BUFMAX bytes to write a packet into. |
164 | * @regs: The &struct pt_regs of the current process. | 164 | * @regs: The &struct pt_regs of the current process. |
165 | * | 165 | * |
166 | * This function MUST handle the 'c' and 's' command packets, | 166 | * This function MUST handle the 'c' and 's' command packets, |
167 | * as well packets to set / remove a hardware breakpoint, if used. | 167 | * as well packets to set / remove a hardware breakpoint, if used. |
168 | * If there are additional packets which the hardware needs to handle, | 168 | * If there are additional packets which the hardware needs to handle, |
169 | * they are handled here. The code should return -1 if it wants to | 169 | * they are handled here. The code should return -1 if it wants to |
170 | * process more packets, and a %0 or %1 if it wants to exit from the | 170 | * process more packets, and a %0 or %1 if it wants to exit from the |
171 | * kgdb callback. | 171 | * kgdb callback. |
172 | */ | 172 | */ |
173 | extern int | 173 | extern int |
174 | kgdb_arch_handle_exception(int vector, int signo, int err_code, | 174 | kgdb_arch_handle_exception(int vector, int signo, int err_code, |
175 | char *remcom_in_buffer, | 175 | char *remcom_in_buffer, |
176 | char *remcom_out_buffer, | 176 | char *remcom_out_buffer, |
177 | struct pt_regs *regs); | 177 | struct pt_regs *regs); |
178 | 178 | ||
179 | /** | 179 | /** |
180 | * kgdb_roundup_cpus - Get other CPUs into a holding pattern | 180 | * kgdb_roundup_cpus - Get other CPUs into a holding pattern |
181 | * @flags: Current IRQ state | 181 | * @flags: Current IRQ state |
182 | * | 182 | * |
183 | * On SMP systems, we need to get the attention of the other CPUs | 183 | * On SMP systems, we need to get the attention of the other CPUs |
184 | * and get them into a known state. This should do what is needed | 184 | * and get them into a known state. This should do what is needed |
185 | * to get the other CPUs to call kgdb_wait(). Note that on some arches, | 185 | * to get the other CPUs to call kgdb_wait(). Note that on some arches, |
186 | * the NMI approach is not used for rounding up all the CPUs. For example, | 186 | * the NMI approach is not used for rounding up all the CPUs. For example, |
187 | * in case of MIPS, smp_call_function() is used to roundup CPUs. In | 187 | * in case of MIPS, smp_call_function() is used to roundup CPUs. In |
188 | * this case, we have to make sure that interrupts are enabled before | 188 | * this case, we have to make sure that interrupts are enabled before |
189 | * calling smp_call_function(). The argument to this function is | 189 | * calling smp_call_function(). The argument to this function is |
190 | * the flags that will be used when restoring the interrupts. There is | 190 | * the flags that will be used when restoring the interrupts. There is |
191 | * local_irq_save() call before kgdb_roundup_cpus(). | 191 | * local_irq_save() call before kgdb_roundup_cpus(). |
192 | * | 192 | * |
193 | * On non-SMP systems, this is not called. | 193 | * On non-SMP systems, this is not called. |
194 | */ | 194 | */ |
195 | extern void kgdb_roundup_cpus(unsigned long flags); | 195 | extern void kgdb_roundup_cpus(unsigned long flags); |
196 | 196 | ||
197 | /** | 197 | /** |
198 | * kgdb_arch_set_pc - Generic call back to the program counter | 198 | * kgdb_arch_set_pc - Generic call back to the program counter |
199 | * @regs: Current &struct pt_regs. | 199 | * @regs: Current &struct pt_regs. |
200 | * @pc: The new value for the program counter | 200 | * @pc: The new value for the program counter |
201 | * | 201 | * |
202 | * This function handles updating the program counter and requires an | 202 | * This function handles updating the program counter and requires an |
203 | * architecture specific implementation. | 203 | * architecture specific implementation. |
204 | */ | 204 | */ |
205 | extern void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc); | 205 | extern void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc); |
206 | 206 | ||
207 | 207 | ||
208 | /* Optional functions. */ | 208 | /* Optional functions. */ |
209 | extern int kgdb_validate_break_address(unsigned long addr); | 209 | extern int kgdb_validate_break_address(unsigned long addr); |
210 | extern int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt); | 210 | extern int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt); |
211 | extern int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt); | 211 | extern int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt); |
212 | 212 | ||
213 | /** | 213 | /** |
214 | * kgdb_arch_late - Perform any architecture specific initalization. | 214 | * kgdb_arch_late - Perform any architecture specific initalization. |
215 | * | 215 | * |
216 | * This function will handle the late initalization of any | 216 | * This function will handle the late initalization of any |
217 | * architecture specific callbacks. This is an optional function for | 217 | * architecture specific callbacks. This is an optional function for |
218 | * handling things like late initialization of hw breakpoints. The | 218 | * handling things like late initialization of hw breakpoints. The |
219 | * default implementation does nothing. | 219 | * default implementation does nothing. |
220 | */ | 220 | */ |
221 | extern void kgdb_arch_late(void); | 221 | extern void kgdb_arch_late(void); |
222 | 222 | ||
223 | 223 | ||
224 | /** | 224 | /** |
225 | * struct kgdb_arch - Describe architecture specific values. | 225 | * struct kgdb_arch - Describe architecture specific values. |
226 | * @gdb_bpt_instr: The instruction to trigger a breakpoint. | 226 | * @gdb_bpt_instr: The instruction to trigger a breakpoint. |
227 | * @flags: Flags for the breakpoint, currently just %KGDB_HW_BREAKPOINT. | 227 | * @flags: Flags for the breakpoint, currently just %KGDB_HW_BREAKPOINT. |
228 | * @set_breakpoint: Allow an architecture to specify how to set a software | 228 | * @set_breakpoint: Allow an architecture to specify how to set a software |
229 | * breakpoint. | 229 | * breakpoint. |
230 | * @remove_breakpoint: Allow an architecture to specify how to remove a | 230 | * @remove_breakpoint: Allow an architecture to specify how to remove a |
231 | * software breakpoint. | 231 | * software breakpoint. |
232 | * @set_hw_breakpoint: Allow an architecture to specify how to set a hardware | 232 | * @set_hw_breakpoint: Allow an architecture to specify how to set a hardware |
233 | * breakpoint. | 233 | * breakpoint. |
234 | * @remove_hw_breakpoint: Allow an architecture to specify how to remove a | 234 | * @remove_hw_breakpoint: Allow an architecture to specify how to remove a |
235 | * hardware breakpoint. | 235 | * hardware breakpoint. |
236 | * @disable_hw_break: Allow an architecture to specify how to disable | 236 | * @disable_hw_break: Allow an architecture to specify how to disable |
237 | * hardware breakpoints for a single cpu. | 237 | * hardware breakpoints for a single cpu. |
238 | * @remove_all_hw_break: Allow an architecture to specify how to remove all | 238 | * @remove_all_hw_break: Allow an architecture to specify how to remove all |
239 | * hardware breakpoints. | 239 | * hardware breakpoints. |
240 | * @correct_hw_break: Allow an architecture to specify how to correct the | 240 | * @correct_hw_break: Allow an architecture to specify how to correct the |
241 | * hardware debug registers. | 241 | * hardware debug registers. |
242 | * @enable_nmi: Manage NMI-triggered entry to KGDB | 242 | * @enable_nmi: Manage NMI-triggered entry to KGDB |
243 | */ | 243 | */ |
244 | struct kgdb_arch { | 244 | struct kgdb_arch { |
245 | unsigned char gdb_bpt_instr[BREAK_INSTR_SIZE]; | 245 | unsigned char gdb_bpt_instr[BREAK_INSTR_SIZE]; |
246 | unsigned long flags; | 246 | unsigned long flags; |
247 | 247 | ||
248 | int (*set_breakpoint)(unsigned long, char *); | 248 | int (*set_breakpoint)(unsigned long, char *); |
249 | int (*remove_breakpoint)(unsigned long, char *); | 249 | int (*remove_breakpoint)(unsigned long, char *); |
250 | int (*set_hw_breakpoint)(unsigned long, int, enum kgdb_bptype); | 250 | int (*set_hw_breakpoint)(unsigned long, int, enum kgdb_bptype); |
251 | int (*remove_hw_breakpoint)(unsigned long, int, enum kgdb_bptype); | 251 | int (*remove_hw_breakpoint)(unsigned long, int, enum kgdb_bptype); |
252 | void (*disable_hw_break)(struct pt_regs *regs); | 252 | void (*disable_hw_break)(struct pt_regs *regs); |
253 | void (*remove_all_hw_break)(void); | 253 | void (*remove_all_hw_break)(void); |
254 | void (*correct_hw_break)(void); | 254 | void (*correct_hw_break)(void); |
255 | 255 | ||
256 | void (*enable_nmi)(bool on); | 256 | void (*enable_nmi)(bool on); |
257 | }; | 257 | }; |
258 | 258 | ||
259 | /** | 259 | /** |
260 | * struct kgdb_io - Describe the interface for an I/O driver to talk with KGDB. | 260 | * struct kgdb_io - Describe the interface for an I/O driver to talk with KGDB. |
261 | * @name: Name of the I/O driver. | 261 | * @name: Name of the I/O driver. |
262 | * @read_char: Pointer to a function that will return one char. | 262 | * @read_char: Pointer to a function that will return one char. |
263 | * @write_char: Pointer to a function that will write one char. | 263 | * @write_char: Pointer to a function that will write one char. |
264 | * @flush: Pointer to a function that will flush any pending writes. | 264 | * @flush: Pointer to a function that will flush any pending writes. |
265 | * @init: Pointer to a function that will initialize the device. | 265 | * @init: Pointer to a function that will initialize the device. |
266 | * @pre_exception: Pointer to a function that will do any prep work for | 266 | * @pre_exception: Pointer to a function that will do any prep work for |
267 | * the I/O driver. | 267 | * the I/O driver. |
268 | * @post_exception: Pointer to a function that will do any cleanup work | 268 | * @post_exception: Pointer to a function that will do any cleanup work |
269 | * for the I/O driver. | 269 | * for the I/O driver. |
270 | * @is_console: 1 if the end device is a console 0 if the I/O device is | 270 | * @is_console: 1 if the end device is a console 0 if the I/O device is |
271 | * not a console | 271 | * not a console |
272 | */ | 272 | */ |
273 | struct kgdb_io { | 273 | struct kgdb_io { |
274 | const char *name; | 274 | const char *name; |
275 | int (*read_char) (void); | 275 | int (*read_char) (void); |
276 | void (*write_char) (u8); | 276 | void (*write_char) (u8); |
277 | void (*flush) (void); | 277 | void (*flush) (void); |
278 | int (*init) (void); | 278 | int (*init) (void); |
279 | void (*pre_exception) (void); | 279 | void (*pre_exception) (void); |
280 | void (*post_exception) (void); | 280 | void (*post_exception) (void); |
281 | int is_console; | 281 | int is_console; |
282 | }; | 282 | }; |
283 | 283 | ||
284 | extern struct kgdb_arch arch_kgdb_ops; | 284 | extern struct kgdb_arch arch_kgdb_ops; |
285 | 285 | ||
286 | extern unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs); | 286 | extern unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs); |
287 | 287 | ||
288 | #ifdef CONFIG_SERIAL_KGDB_NMI | 288 | #ifdef CONFIG_SERIAL_KGDB_NMI |
289 | extern int kgdb_register_nmi_console(void); | 289 | extern int kgdb_register_nmi_console(void); |
290 | extern int kgdb_unregister_nmi_console(void); | 290 | extern int kgdb_unregister_nmi_console(void); |
291 | extern bool kgdb_nmi_poll_knock(void); | 291 | extern bool kgdb_nmi_poll_knock(void); |
292 | #else | 292 | #else |
293 | static inline int kgdb_register_nmi_console(void) { return 0; } | 293 | static inline int kgdb_register_nmi_console(void) { return 0; } |
294 | static inline int kgdb_unregister_nmi_console(void) { return 0; } | 294 | static inline int kgdb_unregister_nmi_console(void) { return 0; } |
295 | static inline bool kgdb_nmi_poll_knock(void) { return 1; } | 295 | static inline bool kgdb_nmi_poll_knock(void) { return 1; } |
296 | #endif | 296 | #endif |
297 | 297 | ||
298 | extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops); | 298 | extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops); |
299 | extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops); | 299 | extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops); |
300 | extern struct kgdb_io *dbg_io_ops; | 300 | extern struct kgdb_io *dbg_io_ops; |
301 | 301 | ||
302 | extern int kgdb_hex2long(char **ptr, unsigned long *long_val); | 302 | extern int kgdb_hex2long(char **ptr, unsigned long *long_val); |
303 | extern char *kgdb_mem2hex(char *mem, char *buf, int count); | 303 | extern char *kgdb_mem2hex(char *mem, char *buf, int count); |
304 | extern int kgdb_hex2mem(char *buf, char *mem, int count); | 304 | extern int kgdb_hex2mem(char *buf, char *mem, int count); |
305 | 305 | ||
306 | extern int kgdb_isremovedbreak(unsigned long addr); | 306 | extern int kgdb_isremovedbreak(unsigned long addr); |
307 | extern void kgdb_schedule_breakpoint(void); | 307 | extern void kgdb_schedule_breakpoint(void); |
308 | 308 | ||
309 | extern int | 309 | extern int |
310 | kgdb_handle_exception(int ex_vector, int signo, int err_code, | 310 | kgdb_handle_exception(int ex_vector, int signo, int err_code, |
311 | struct pt_regs *regs); | 311 | struct pt_regs *regs); |
312 | extern int kgdb_nmicallback(int cpu, void *regs); | 312 | extern int kgdb_nmicallback(int cpu, void *regs); |
313 | extern int kgdb_nmicallin(int cpu, int trapnr, void *regs, atomic_t *snd_rdy); | ||
313 | extern void gdbstub_exit(int status); | 314 | extern void gdbstub_exit(int status); |
314 | 315 | ||
315 | extern int kgdb_single_step; | 316 | extern int kgdb_single_step; |
316 | extern atomic_t kgdb_active; | 317 | extern atomic_t kgdb_active; |
317 | #define in_dbg_master() \ | 318 | #define in_dbg_master() \ |
318 | (raw_smp_processor_id() == atomic_read(&kgdb_active)) | 319 | (raw_smp_processor_id() == atomic_read(&kgdb_active)) |
319 | extern bool dbg_is_early; | 320 | extern bool dbg_is_early; |
320 | extern void __init dbg_late_init(void); | 321 | extern void __init dbg_late_init(void); |
321 | #else /* ! CONFIG_KGDB */ | 322 | #else /* ! CONFIG_KGDB */ |
322 | #define in_dbg_master() (0) | 323 | #define in_dbg_master() (0) |
323 | #define dbg_late_init() | 324 | #define dbg_late_init() |
324 | #endif /* ! CONFIG_KGDB */ | 325 | #endif /* ! CONFIG_KGDB */ |
325 | #endif /* _KGDB_H_ */ | 326 | #endif /* _KGDB_H_ */ |
326 | 327 |
kernel/debug/debug_core.c
1 | /* | 1 | /* |
2 | * Kernel Debug Core | 2 | * Kernel Debug Core |
3 | * | 3 | * |
4 | * Maintainer: Jason Wessel <jason.wessel@windriver.com> | 4 | * Maintainer: Jason Wessel <jason.wessel@windriver.com> |
5 | * | 5 | * |
6 | * Copyright (C) 2000-2001 VERITAS Software Corporation. | 6 | * Copyright (C) 2000-2001 VERITAS Software Corporation. |
7 | * Copyright (C) 2002-2004 Timesys Corporation | 7 | * Copyright (C) 2002-2004 Timesys Corporation |
8 | * Copyright (C) 2003-2004 Amit S. Kale <amitkale@linsyssoft.com> | 8 | * Copyright (C) 2003-2004 Amit S. Kale <amitkale@linsyssoft.com> |
9 | * Copyright (C) 2004 Pavel Machek <pavel@ucw.cz> | 9 | * Copyright (C) 2004 Pavel Machek <pavel@ucw.cz> |
10 | * Copyright (C) 2004-2006 Tom Rini <trini@kernel.crashing.org> | 10 | * Copyright (C) 2004-2006 Tom Rini <trini@kernel.crashing.org> |
11 | * Copyright (C) 2004-2006 LinSysSoft Technologies Pvt. Ltd. | 11 | * Copyright (C) 2004-2006 LinSysSoft Technologies Pvt. Ltd. |
12 | * Copyright (C) 2005-2009 Wind River Systems, Inc. | 12 | * Copyright (C) 2005-2009 Wind River Systems, Inc. |
13 | * Copyright (C) 2007 MontaVista Software, Inc. | 13 | * Copyright (C) 2007 MontaVista Software, Inc. |
14 | * Copyright (C) 2008 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> | 14 | * Copyright (C) 2008 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> |
15 | * | 15 | * |
16 | * Contributors at various stages not listed above: | 16 | * Contributors at various stages not listed above: |
17 | * Jason Wessel ( jason.wessel@windriver.com ) | 17 | * Jason Wessel ( jason.wessel@windriver.com ) |
18 | * George Anzinger <george@mvista.com> | 18 | * George Anzinger <george@mvista.com> |
19 | * Anurekh Saxena (anurekh.saxena@timesys.com) | 19 | * Anurekh Saxena (anurekh.saxena@timesys.com) |
20 | * Lake Stevens Instrument Division (Glenn Engel) | 20 | * Lake Stevens Instrument Division (Glenn Engel) |
21 | * Jim Kingdon, Cygnus Support. | 21 | * Jim Kingdon, Cygnus Support. |
22 | * | 22 | * |
23 | * Original KGDB stub: David Grothe <dave@gcom.com>, | 23 | * Original KGDB stub: David Grothe <dave@gcom.com>, |
24 | * Tigran Aivazian <tigran@sco.com> | 24 | * Tigran Aivazian <tigran@sco.com> |
25 | * | 25 | * |
26 | * This file is licensed under the terms of the GNU General Public License | 26 | * This file is licensed under the terms of the GNU General Public License |
27 | * version 2. This program is licensed "as is" without any warranty of any | 27 | * version 2. This program is licensed "as is" without any warranty of any |
28 | * kind, whether express or implied. | 28 | * kind, whether express or implied. |
29 | */ | 29 | */ |
30 | #include <linux/pid_namespace.h> | 30 | #include <linux/pid_namespace.h> |
31 | #include <linux/clocksource.h> | 31 | #include <linux/clocksource.h> |
32 | #include <linux/serial_core.h> | 32 | #include <linux/serial_core.h> |
33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
34 | #include <linux/spinlock.h> | 34 | #include <linux/spinlock.h> |
35 | #include <linux/console.h> | 35 | #include <linux/console.h> |
36 | #include <linux/threads.h> | 36 | #include <linux/threads.h> |
37 | #include <linux/uaccess.h> | 37 | #include <linux/uaccess.h> |
38 | #include <linux/kernel.h> | 38 | #include <linux/kernel.h> |
39 | #include <linux/module.h> | 39 | #include <linux/module.h> |
40 | #include <linux/ptrace.h> | 40 | #include <linux/ptrace.h> |
41 | #include <linux/string.h> | 41 | #include <linux/string.h> |
42 | #include <linux/delay.h> | 42 | #include <linux/delay.h> |
43 | #include <linux/sched.h> | 43 | #include <linux/sched.h> |
44 | #include <linux/sysrq.h> | 44 | #include <linux/sysrq.h> |
45 | #include <linux/reboot.h> | 45 | #include <linux/reboot.h> |
46 | #include <linux/init.h> | 46 | #include <linux/init.h> |
47 | #include <linux/kgdb.h> | 47 | #include <linux/kgdb.h> |
48 | #include <linux/kdb.h> | 48 | #include <linux/kdb.h> |
49 | #include <linux/pid.h> | 49 | #include <linux/pid.h> |
50 | #include <linux/smp.h> | 50 | #include <linux/smp.h> |
51 | #include <linux/mm.h> | 51 | #include <linux/mm.h> |
52 | #include <linux/rcupdate.h> | 52 | #include <linux/rcupdate.h> |
53 | 53 | ||
54 | #include <asm/cacheflush.h> | 54 | #include <asm/cacheflush.h> |
55 | #include <asm/byteorder.h> | 55 | #include <asm/byteorder.h> |
56 | #include <linux/atomic.h> | 56 | #include <linux/atomic.h> |
57 | 57 | ||
58 | #include "debug_core.h" | 58 | #include "debug_core.h" |
59 | 59 | ||
60 | static int kgdb_break_asap; | 60 | static int kgdb_break_asap; |
61 | 61 | ||
62 | struct debuggerinfo_struct kgdb_info[NR_CPUS]; | 62 | struct debuggerinfo_struct kgdb_info[NR_CPUS]; |
63 | 63 | ||
64 | /** | 64 | /** |
65 | * kgdb_connected - Is a host GDB connected to us? | 65 | * kgdb_connected - Is a host GDB connected to us? |
66 | */ | 66 | */ |
67 | int kgdb_connected; | 67 | int kgdb_connected; |
68 | EXPORT_SYMBOL_GPL(kgdb_connected); | 68 | EXPORT_SYMBOL_GPL(kgdb_connected); |
69 | 69 | ||
70 | /* All the KGDB handlers are installed */ | 70 | /* All the KGDB handlers are installed */ |
71 | int kgdb_io_module_registered; | 71 | int kgdb_io_module_registered; |
72 | 72 | ||
73 | /* Guard for recursive entry */ | 73 | /* Guard for recursive entry */ |
74 | static int exception_level; | 74 | static int exception_level; |
75 | 75 | ||
76 | struct kgdb_io *dbg_io_ops; | 76 | struct kgdb_io *dbg_io_ops; |
77 | static DEFINE_SPINLOCK(kgdb_registration_lock); | 77 | static DEFINE_SPINLOCK(kgdb_registration_lock); |
78 | 78 | ||
79 | /* Action for the reboot notifiter, a global allow kdb to change it */ | 79 | /* Action for the reboot notifiter, a global allow kdb to change it */ |
80 | static int kgdbreboot; | 80 | static int kgdbreboot; |
81 | /* kgdb console driver is loaded */ | 81 | /* kgdb console driver is loaded */ |
82 | static int kgdb_con_registered; | 82 | static int kgdb_con_registered; |
83 | /* determine if kgdb console output should be used */ | 83 | /* determine if kgdb console output should be used */ |
84 | static int kgdb_use_con; | 84 | static int kgdb_use_con; |
85 | /* Flag for alternate operations for early debugging */ | 85 | /* Flag for alternate operations for early debugging */ |
86 | bool dbg_is_early = true; | 86 | bool dbg_is_early = true; |
87 | /* Next cpu to become the master debug core */ | 87 | /* Next cpu to become the master debug core */ |
88 | int dbg_switch_cpu; | 88 | int dbg_switch_cpu; |
89 | 89 | ||
90 | /* Use kdb or gdbserver mode */ | 90 | /* Use kdb or gdbserver mode */ |
91 | int dbg_kdb_mode = 1; | 91 | int dbg_kdb_mode = 1; |
92 | 92 | ||
93 | static int __init opt_kgdb_con(char *str) | 93 | static int __init opt_kgdb_con(char *str) |
94 | { | 94 | { |
95 | kgdb_use_con = 1; | 95 | kgdb_use_con = 1; |
96 | return 0; | 96 | return 0; |
97 | } | 97 | } |
98 | 98 | ||
99 | early_param("kgdbcon", opt_kgdb_con); | 99 | early_param("kgdbcon", opt_kgdb_con); |
100 | 100 | ||
101 | module_param(kgdb_use_con, int, 0644); | 101 | module_param(kgdb_use_con, int, 0644); |
102 | module_param(kgdbreboot, int, 0644); | 102 | module_param(kgdbreboot, int, 0644); |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * Holds information about breakpoints in a kernel. These breakpoints are | 105 | * Holds information about breakpoints in a kernel. These breakpoints are |
106 | * added and removed by gdb. | 106 | * added and removed by gdb. |
107 | */ | 107 | */ |
108 | static struct kgdb_bkpt kgdb_break[KGDB_MAX_BREAKPOINTS] = { | 108 | static struct kgdb_bkpt kgdb_break[KGDB_MAX_BREAKPOINTS] = { |
109 | [0 ... KGDB_MAX_BREAKPOINTS-1] = { .state = BP_UNDEFINED } | 109 | [0 ... KGDB_MAX_BREAKPOINTS-1] = { .state = BP_UNDEFINED } |
110 | }; | 110 | }; |
111 | 111 | ||
112 | /* | 112 | /* |
113 | * The CPU# of the active CPU, or -1 if none: | 113 | * The CPU# of the active CPU, or -1 if none: |
114 | */ | 114 | */ |
115 | atomic_t kgdb_active = ATOMIC_INIT(-1); | 115 | atomic_t kgdb_active = ATOMIC_INIT(-1); |
116 | EXPORT_SYMBOL_GPL(kgdb_active); | 116 | EXPORT_SYMBOL_GPL(kgdb_active); |
117 | static DEFINE_RAW_SPINLOCK(dbg_master_lock); | 117 | static DEFINE_RAW_SPINLOCK(dbg_master_lock); |
118 | static DEFINE_RAW_SPINLOCK(dbg_slave_lock); | 118 | static DEFINE_RAW_SPINLOCK(dbg_slave_lock); |
119 | 119 | ||
120 | /* | 120 | /* |
121 | * We use NR_CPUs not PERCPU, in case kgdb is used to debug early | 121 | * We use NR_CPUs not PERCPU, in case kgdb is used to debug early |
122 | * bootup code (which might not have percpu set up yet): | 122 | * bootup code (which might not have percpu set up yet): |
123 | */ | 123 | */ |
124 | static atomic_t masters_in_kgdb; | 124 | static atomic_t masters_in_kgdb; |
125 | static atomic_t slaves_in_kgdb; | 125 | static atomic_t slaves_in_kgdb; |
126 | static atomic_t kgdb_break_tasklet_var; | 126 | static atomic_t kgdb_break_tasklet_var; |
127 | atomic_t kgdb_setting_breakpoint; | 127 | atomic_t kgdb_setting_breakpoint; |
128 | 128 | ||
129 | struct task_struct *kgdb_usethread; | 129 | struct task_struct *kgdb_usethread; |
130 | struct task_struct *kgdb_contthread; | 130 | struct task_struct *kgdb_contthread; |
131 | 131 | ||
132 | int kgdb_single_step; | 132 | int kgdb_single_step; |
133 | static pid_t kgdb_sstep_pid; | 133 | static pid_t kgdb_sstep_pid; |
134 | 134 | ||
135 | /* to keep track of the CPU which is doing the single stepping*/ | 135 | /* to keep track of the CPU which is doing the single stepping*/ |
136 | atomic_t kgdb_cpu_doing_single_step = ATOMIC_INIT(-1); | 136 | atomic_t kgdb_cpu_doing_single_step = ATOMIC_INIT(-1); |
137 | 137 | ||
138 | /* | 138 | /* |
139 | * If you are debugging a problem where roundup (the collection of | 139 | * If you are debugging a problem where roundup (the collection of |
140 | * all other CPUs) is a problem [this should be extremely rare], | 140 | * all other CPUs) is a problem [this should be extremely rare], |
141 | * then use the nokgdbroundup option to avoid roundup. In that case | 141 | * then use the nokgdbroundup option to avoid roundup. In that case |
142 | * the other CPUs might interfere with your debugging context, so | 142 | * the other CPUs might interfere with your debugging context, so |
143 | * use this with care: | 143 | * use this with care: |
144 | */ | 144 | */ |
145 | static int kgdb_do_roundup = 1; | 145 | static int kgdb_do_roundup = 1; |
146 | 146 | ||
147 | static int __init opt_nokgdbroundup(char *str) | 147 | static int __init opt_nokgdbroundup(char *str) |
148 | { | 148 | { |
149 | kgdb_do_roundup = 0; | 149 | kgdb_do_roundup = 0; |
150 | 150 | ||
151 | return 0; | 151 | return 0; |
152 | } | 152 | } |
153 | 153 | ||
154 | early_param("nokgdbroundup", opt_nokgdbroundup); | 154 | early_param("nokgdbroundup", opt_nokgdbroundup); |
155 | 155 | ||
156 | /* | 156 | /* |
157 | * Finally, some KGDB code :-) | 157 | * Finally, some KGDB code :-) |
158 | */ | 158 | */ |
159 | 159 | ||
160 | /* | 160 | /* |
161 | * Weak aliases for breakpoint management, | 161 | * Weak aliases for breakpoint management, |
162 | * can be overriden by architectures when needed: | 162 | * can be overriden by architectures when needed: |
163 | */ | 163 | */ |
164 | int __weak kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) | 164 | int __weak kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) |
165 | { | 165 | { |
166 | int err; | 166 | int err; |
167 | 167 | ||
168 | err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, | 168 | err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, |
169 | BREAK_INSTR_SIZE); | 169 | BREAK_INSTR_SIZE); |
170 | if (err) | 170 | if (err) |
171 | return err; | 171 | return err; |
172 | err = probe_kernel_write((char *)bpt->bpt_addr, | 172 | err = probe_kernel_write((char *)bpt->bpt_addr, |
173 | arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE); | 173 | arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE); |
174 | return err; | 174 | return err; |
175 | } | 175 | } |
176 | 176 | ||
177 | int __weak kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) | 177 | int __weak kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) |
178 | { | 178 | { |
179 | return probe_kernel_write((char *)bpt->bpt_addr, | 179 | return probe_kernel_write((char *)bpt->bpt_addr, |
180 | (char *)bpt->saved_instr, BREAK_INSTR_SIZE); | 180 | (char *)bpt->saved_instr, BREAK_INSTR_SIZE); |
181 | } | 181 | } |
182 | 182 | ||
183 | int __weak kgdb_validate_break_address(unsigned long addr) | 183 | int __weak kgdb_validate_break_address(unsigned long addr) |
184 | { | 184 | { |
185 | struct kgdb_bkpt tmp; | 185 | struct kgdb_bkpt tmp; |
186 | int err; | 186 | int err; |
187 | /* Validate setting the breakpoint and then removing it. If the | 187 | /* Validate setting the breakpoint and then removing it. If the |
188 | * remove fails, the kernel needs to emit a bad message because we | 188 | * remove fails, the kernel needs to emit a bad message because we |
189 | * are deep trouble not being able to put things back the way we | 189 | * are deep trouble not being able to put things back the way we |
190 | * found them. | 190 | * found them. |
191 | */ | 191 | */ |
192 | tmp.bpt_addr = addr; | 192 | tmp.bpt_addr = addr; |
193 | err = kgdb_arch_set_breakpoint(&tmp); | 193 | err = kgdb_arch_set_breakpoint(&tmp); |
194 | if (err) | 194 | if (err) |
195 | return err; | 195 | return err; |
196 | err = kgdb_arch_remove_breakpoint(&tmp); | 196 | err = kgdb_arch_remove_breakpoint(&tmp); |
197 | if (err) | 197 | if (err) |
198 | printk(KERN_ERR "KGDB: Critical breakpoint error, kernel " | 198 | printk(KERN_ERR "KGDB: Critical breakpoint error, kernel " |
199 | "memory destroyed at: %lx", addr); | 199 | "memory destroyed at: %lx", addr); |
200 | return err; | 200 | return err; |
201 | } | 201 | } |
202 | 202 | ||
203 | unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs) | 203 | unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs) |
204 | { | 204 | { |
205 | return instruction_pointer(regs); | 205 | return instruction_pointer(regs); |
206 | } | 206 | } |
207 | 207 | ||
208 | int __weak kgdb_arch_init(void) | 208 | int __weak kgdb_arch_init(void) |
209 | { | 209 | { |
210 | return 0; | 210 | return 0; |
211 | } | 211 | } |
212 | 212 | ||
213 | int __weak kgdb_skipexception(int exception, struct pt_regs *regs) | 213 | int __weak kgdb_skipexception(int exception, struct pt_regs *regs) |
214 | { | 214 | { |
215 | return 0; | 215 | return 0; |
216 | } | 216 | } |
217 | 217 | ||
218 | /* | 218 | /* |
219 | * Some architectures need cache flushes when we set/clear a | 219 | * Some architectures need cache flushes when we set/clear a |
220 | * breakpoint: | 220 | * breakpoint: |
221 | */ | 221 | */ |
222 | static void kgdb_flush_swbreak_addr(unsigned long addr) | 222 | static void kgdb_flush_swbreak_addr(unsigned long addr) |
223 | { | 223 | { |
224 | if (!CACHE_FLUSH_IS_SAFE) | 224 | if (!CACHE_FLUSH_IS_SAFE) |
225 | return; | 225 | return; |
226 | 226 | ||
227 | if (current->mm && current->mm->mmap_cache) { | 227 | if (current->mm && current->mm->mmap_cache) { |
228 | flush_cache_range(current->mm->mmap_cache, | 228 | flush_cache_range(current->mm->mmap_cache, |
229 | addr, addr + BREAK_INSTR_SIZE); | 229 | addr, addr + BREAK_INSTR_SIZE); |
230 | } | 230 | } |
231 | /* Force flush instruction cache if it was outside the mm */ | 231 | /* Force flush instruction cache if it was outside the mm */ |
232 | flush_icache_range(addr, addr + BREAK_INSTR_SIZE); | 232 | flush_icache_range(addr, addr + BREAK_INSTR_SIZE); |
233 | } | 233 | } |
234 | 234 | ||
235 | /* | 235 | /* |
236 | * SW breakpoint management: | 236 | * SW breakpoint management: |
237 | */ | 237 | */ |
238 | int dbg_activate_sw_breakpoints(void) | 238 | int dbg_activate_sw_breakpoints(void) |
239 | { | 239 | { |
240 | int error; | 240 | int error; |
241 | int ret = 0; | 241 | int ret = 0; |
242 | int i; | 242 | int i; |
243 | 243 | ||
244 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { | 244 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { |
245 | if (kgdb_break[i].state != BP_SET) | 245 | if (kgdb_break[i].state != BP_SET) |
246 | continue; | 246 | continue; |
247 | 247 | ||
248 | error = kgdb_arch_set_breakpoint(&kgdb_break[i]); | 248 | error = kgdb_arch_set_breakpoint(&kgdb_break[i]); |
249 | if (error) { | 249 | if (error) { |
250 | ret = error; | 250 | ret = error; |
251 | printk(KERN_INFO "KGDB: BP install failed: %lx", | 251 | printk(KERN_INFO "KGDB: BP install failed: %lx", |
252 | kgdb_break[i].bpt_addr); | 252 | kgdb_break[i].bpt_addr); |
253 | continue; | 253 | continue; |
254 | } | 254 | } |
255 | 255 | ||
256 | kgdb_flush_swbreak_addr(kgdb_break[i].bpt_addr); | 256 | kgdb_flush_swbreak_addr(kgdb_break[i].bpt_addr); |
257 | kgdb_break[i].state = BP_ACTIVE; | 257 | kgdb_break[i].state = BP_ACTIVE; |
258 | } | 258 | } |
259 | return ret; | 259 | return ret; |
260 | } | 260 | } |
261 | 261 | ||
262 | int dbg_set_sw_break(unsigned long addr) | 262 | int dbg_set_sw_break(unsigned long addr) |
263 | { | 263 | { |
264 | int err = kgdb_validate_break_address(addr); | 264 | int err = kgdb_validate_break_address(addr); |
265 | int breakno = -1; | 265 | int breakno = -1; |
266 | int i; | 266 | int i; |
267 | 267 | ||
268 | if (err) | 268 | if (err) |
269 | return err; | 269 | return err; |
270 | 270 | ||
271 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { | 271 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { |
272 | if ((kgdb_break[i].state == BP_SET) && | 272 | if ((kgdb_break[i].state == BP_SET) && |
273 | (kgdb_break[i].bpt_addr == addr)) | 273 | (kgdb_break[i].bpt_addr == addr)) |
274 | return -EEXIST; | 274 | return -EEXIST; |
275 | } | 275 | } |
276 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { | 276 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { |
277 | if (kgdb_break[i].state == BP_REMOVED && | 277 | if (kgdb_break[i].state == BP_REMOVED && |
278 | kgdb_break[i].bpt_addr == addr) { | 278 | kgdb_break[i].bpt_addr == addr) { |
279 | breakno = i; | 279 | breakno = i; |
280 | break; | 280 | break; |
281 | } | 281 | } |
282 | } | 282 | } |
283 | 283 | ||
284 | if (breakno == -1) { | 284 | if (breakno == -1) { |
285 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { | 285 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { |
286 | if (kgdb_break[i].state == BP_UNDEFINED) { | 286 | if (kgdb_break[i].state == BP_UNDEFINED) { |
287 | breakno = i; | 287 | breakno = i; |
288 | break; | 288 | break; |
289 | } | 289 | } |
290 | } | 290 | } |
291 | } | 291 | } |
292 | 292 | ||
293 | if (breakno == -1) | 293 | if (breakno == -1) |
294 | return -E2BIG; | 294 | return -E2BIG; |
295 | 295 | ||
296 | kgdb_break[breakno].state = BP_SET; | 296 | kgdb_break[breakno].state = BP_SET; |
297 | kgdb_break[breakno].type = BP_BREAKPOINT; | 297 | kgdb_break[breakno].type = BP_BREAKPOINT; |
298 | kgdb_break[breakno].bpt_addr = addr; | 298 | kgdb_break[breakno].bpt_addr = addr; |
299 | 299 | ||
300 | return 0; | 300 | return 0; |
301 | } | 301 | } |
302 | 302 | ||
303 | int dbg_deactivate_sw_breakpoints(void) | 303 | int dbg_deactivate_sw_breakpoints(void) |
304 | { | 304 | { |
305 | int error; | 305 | int error; |
306 | int ret = 0; | 306 | int ret = 0; |
307 | int i; | 307 | int i; |
308 | 308 | ||
309 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { | 309 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { |
310 | if (kgdb_break[i].state != BP_ACTIVE) | 310 | if (kgdb_break[i].state != BP_ACTIVE) |
311 | continue; | 311 | continue; |
312 | error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); | 312 | error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); |
313 | if (error) { | 313 | if (error) { |
314 | printk(KERN_INFO "KGDB: BP remove failed: %lx\n", | 314 | printk(KERN_INFO "KGDB: BP remove failed: %lx\n", |
315 | kgdb_break[i].bpt_addr); | 315 | kgdb_break[i].bpt_addr); |
316 | ret = error; | 316 | ret = error; |
317 | } | 317 | } |
318 | 318 | ||
319 | kgdb_flush_swbreak_addr(kgdb_break[i].bpt_addr); | 319 | kgdb_flush_swbreak_addr(kgdb_break[i].bpt_addr); |
320 | kgdb_break[i].state = BP_SET; | 320 | kgdb_break[i].state = BP_SET; |
321 | } | 321 | } |
322 | return ret; | 322 | return ret; |
323 | } | 323 | } |
324 | 324 | ||
325 | int dbg_remove_sw_break(unsigned long addr) | 325 | int dbg_remove_sw_break(unsigned long addr) |
326 | { | 326 | { |
327 | int i; | 327 | int i; |
328 | 328 | ||
329 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { | 329 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { |
330 | if ((kgdb_break[i].state == BP_SET) && | 330 | if ((kgdb_break[i].state == BP_SET) && |
331 | (kgdb_break[i].bpt_addr == addr)) { | 331 | (kgdb_break[i].bpt_addr == addr)) { |
332 | kgdb_break[i].state = BP_REMOVED; | 332 | kgdb_break[i].state = BP_REMOVED; |
333 | return 0; | 333 | return 0; |
334 | } | 334 | } |
335 | } | 335 | } |
336 | return -ENOENT; | 336 | return -ENOENT; |
337 | } | 337 | } |
338 | 338 | ||
339 | int kgdb_isremovedbreak(unsigned long addr) | 339 | int kgdb_isremovedbreak(unsigned long addr) |
340 | { | 340 | { |
341 | int i; | 341 | int i; |
342 | 342 | ||
343 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { | 343 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { |
344 | if ((kgdb_break[i].state == BP_REMOVED) && | 344 | if ((kgdb_break[i].state == BP_REMOVED) && |
345 | (kgdb_break[i].bpt_addr == addr)) | 345 | (kgdb_break[i].bpt_addr == addr)) |
346 | return 1; | 346 | return 1; |
347 | } | 347 | } |
348 | return 0; | 348 | return 0; |
349 | } | 349 | } |
350 | 350 | ||
351 | int dbg_remove_all_break(void) | 351 | int dbg_remove_all_break(void) |
352 | { | 352 | { |
353 | int error; | 353 | int error; |
354 | int i; | 354 | int i; |
355 | 355 | ||
356 | /* Clear memory breakpoints. */ | 356 | /* Clear memory breakpoints. */ |
357 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { | 357 | for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { |
358 | if (kgdb_break[i].state != BP_ACTIVE) | 358 | if (kgdb_break[i].state != BP_ACTIVE) |
359 | goto setundefined; | 359 | goto setundefined; |
360 | error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); | 360 | error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); |
361 | if (error) | 361 | if (error) |
362 | printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n", | 362 | printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n", |
363 | kgdb_break[i].bpt_addr); | 363 | kgdb_break[i].bpt_addr); |
364 | setundefined: | 364 | setundefined: |
365 | kgdb_break[i].state = BP_UNDEFINED; | 365 | kgdb_break[i].state = BP_UNDEFINED; |
366 | } | 366 | } |
367 | 367 | ||
368 | /* Clear hardware breakpoints. */ | 368 | /* Clear hardware breakpoints. */ |
369 | if (arch_kgdb_ops.remove_all_hw_break) | 369 | if (arch_kgdb_ops.remove_all_hw_break) |
370 | arch_kgdb_ops.remove_all_hw_break(); | 370 | arch_kgdb_ops.remove_all_hw_break(); |
371 | 371 | ||
372 | return 0; | 372 | return 0; |
373 | } | 373 | } |
374 | 374 | ||
375 | /* | 375 | /* |
376 | * Return true if there is a valid kgdb I/O module. Also if no | 376 | * Return true if there is a valid kgdb I/O module. Also if no |
377 | * debugger is attached a message can be printed to the console about | 377 | * debugger is attached a message can be printed to the console about |
378 | * waiting for the debugger to attach. | 378 | * waiting for the debugger to attach. |
379 | * | 379 | * |
380 | * The print_wait argument is only to be true when called from inside | 380 | * The print_wait argument is only to be true when called from inside |
381 | * the core kgdb_handle_exception, because it will wait for the | 381 | * the core kgdb_handle_exception, because it will wait for the |
382 | * debugger to attach. | 382 | * debugger to attach. |
383 | */ | 383 | */ |
384 | static int kgdb_io_ready(int print_wait) | 384 | static int kgdb_io_ready(int print_wait) |
385 | { | 385 | { |
386 | if (!dbg_io_ops) | 386 | if (!dbg_io_ops) |
387 | return 0; | 387 | return 0; |
388 | if (kgdb_connected) | 388 | if (kgdb_connected) |
389 | return 1; | 389 | return 1; |
390 | if (atomic_read(&kgdb_setting_breakpoint)) | 390 | if (atomic_read(&kgdb_setting_breakpoint)) |
391 | return 1; | 391 | return 1; |
392 | if (print_wait) { | 392 | if (print_wait) { |
393 | #ifdef CONFIG_KGDB_KDB | 393 | #ifdef CONFIG_KGDB_KDB |
394 | if (!dbg_kdb_mode) | 394 | if (!dbg_kdb_mode) |
395 | printk(KERN_CRIT "KGDB: waiting... or $3#33 for KDB\n"); | 395 | printk(KERN_CRIT "KGDB: waiting... or $3#33 for KDB\n"); |
396 | #else | 396 | #else |
397 | printk(KERN_CRIT "KGDB: Waiting for remote debugger\n"); | 397 | printk(KERN_CRIT "KGDB: Waiting for remote debugger\n"); |
398 | #endif | 398 | #endif |
399 | } | 399 | } |
400 | return 1; | 400 | return 1; |
401 | } | 401 | } |
402 | 402 | ||
403 | static int kgdb_reenter_check(struct kgdb_state *ks) | 403 | static int kgdb_reenter_check(struct kgdb_state *ks) |
404 | { | 404 | { |
405 | unsigned long addr; | 405 | unsigned long addr; |
406 | 406 | ||
407 | if (atomic_read(&kgdb_active) != raw_smp_processor_id()) | 407 | if (atomic_read(&kgdb_active) != raw_smp_processor_id()) |
408 | return 0; | 408 | return 0; |
409 | 409 | ||
410 | /* Panic on recursive debugger calls: */ | 410 | /* Panic on recursive debugger calls: */ |
411 | exception_level++; | 411 | exception_level++; |
412 | addr = kgdb_arch_pc(ks->ex_vector, ks->linux_regs); | 412 | addr = kgdb_arch_pc(ks->ex_vector, ks->linux_regs); |
413 | dbg_deactivate_sw_breakpoints(); | 413 | dbg_deactivate_sw_breakpoints(); |
414 | 414 | ||
415 | /* | 415 | /* |
416 | * If the break point removed ok at the place exception | 416 | * If the break point removed ok at the place exception |
417 | * occurred, try to recover and print a warning to the end | 417 | * occurred, try to recover and print a warning to the end |
418 | * user because the user planted a breakpoint in a place that | 418 | * user because the user planted a breakpoint in a place that |
419 | * KGDB needs in order to function. | 419 | * KGDB needs in order to function. |
420 | */ | 420 | */ |
421 | if (dbg_remove_sw_break(addr) == 0) { | 421 | if (dbg_remove_sw_break(addr) == 0) { |
422 | exception_level = 0; | 422 | exception_level = 0; |
423 | kgdb_skipexception(ks->ex_vector, ks->linux_regs); | 423 | kgdb_skipexception(ks->ex_vector, ks->linux_regs); |
424 | dbg_activate_sw_breakpoints(); | 424 | dbg_activate_sw_breakpoints(); |
425 | printk(KERN_CRIT "KGDB: re-enter error: breakpoint removed %lx\n", | 425 | printk(KERN_CRIT "KGDB: re-enter error: breakpoint removed %lx\n", |
426 | addr); | 426 | addr); |
427 | WARN_ON_ONCE(1); | 427 | WARN_ON_ONCE(1); |
428 | 428 | ||
429 | return 1; | 429 | return 1; |
430 | } | 430 | } |
431 | dbg_remove_all_break(); | 431 | dbg_remove_all_break(); |
432 | kgdb_skipexception(ks->ex_vector, ks->linux_regs); | 432 | kgdb_skipexception(ks->ex_vector, ks->linux_regs); |
433 | 433 | ||
434 | if (exception_level > 1) { | 434 | if (exception_level > 1) { |
435 | dump_stack(); | 435 | dump_stack(); |
436 | panic("Recursive entry to debugger"); | 436 | panic("Recursive entry to debugger"); |
437 | } | 437 | } |
438 | 438 | ||
439 | printk(KERN_CRIT "KGDB: re-enter exception: ALL breakpoints killed\n"); | 439 | printk(KERN_CRIT "KGDB: re-enter exception: ALL breakpoints killed\n"); |
440 | #ifdef CONFIG_KGDB_KDB | 440 | #ifdef CONFIG_KGDB_KDB |
441 | /* Allow kdb to debug itself one level */ | 441 | /* Allow kdb to debug itself one level */ |
442 | return 0; | 442 | return 0; |
443 | #endif | 443 | #endif |
444 | dump_stack(); | 444 | dump_stack(); |
445 | panic("Recursive entry to debugger"); | 445 | panic("Recursive entry to debugger"); |
446 | 446 | ||
447 | return 1; | 447 | return 1; |
448 | } | 448 | } |
449 | 449 | ||
450 | static void dbg_touch_watchdogs(void) | 450 | static void dbg_touch_watchdogs(void) |
451 | { | 451 | { |
452 | touch_softlockup_watchdog_sync(); | 452 | touch_softlockup_watchdog_sync(); |
453 | clocksource_touch_watchdog(); | 453 | clocksource_touch_watchdog(); |
454 | rcu_cpu_stall_reset(); | 454 | rcu_cpu_stall_reset(); |
455 | } | 455 | } |
456 | 456 | ||
457 | static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs, | 457 | static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs, |
458 | int exception_state) | 458 | int exception_state) |
459 | { | 459 | { |
460 | unsigned long flags; | 460 | unsigned long flags; |
461 | int sstep_tries = 100; | 461 | int sstep_tries = 100; |
462 | int error; | 462 | int error; |
463 | int cpu; | 463 | int cpu; |
464 | int trace_on = 0; | 464 | int trace_on = 0; |
465 | int online_cpus = num_online_cpus(); | 465 | int online_cpus = num_online_cpus(); |
466 | 466 | ||
467 | kgdb_info[ks->cpu].enter_kgdb++; | 467 | kgdb_info[ks->cpu].enter_kgdb++; |
468 | kgdb_info[ks->cpu].exception_state |= exception_state; | 468 | kgdb_info[ks->cpu].exception_state |= exception_state; |
469 | 469 | ||
470 | if (exception_state == DCPU_WANT_MASTER) | 470 | if (exception_state == DCPU_WANT_MASTER) |
471 | atomic_inc(&masters_in_kgdb); | 471 | atomic_inc(&masters_in_kgdb); |
472 | else | 472 | else |
473 | atomic_inc(&slaves_in_kgdb); | 473 | atomic_inc(&slaves_in_kgdb); |
474 | 474 | ||
475 | if (arch_kgdb_ops.disable_hw_break) | 475 | if (arch_kgdb_ops.disable_hw_break) |
476 | arch_kgdb_ops.disable_hw_break(regs); | 476 | arch_kgdb_ops.disable_hw_break(regs); |
477 | 477 | ||
478 | acquirelock: | 478 | acquirelock: |
479 | /* | 479 | /* |
480 | * Interrupts will be restored by the 'trap return' code, except when | 480 | * Interrupts will be restored by the 'trap return' code, except when |
481 | * single stepping. | 481 | * single stepping. |
482 | */ | 482 | */ |
483 | local_irq_save(flags); | 483 | local_irq_save(flags); |
484 | 484 | ||
485 | cpu = ks->cpu; | 485 | cpu = ks->cpu; |
486 | kgdb_info[cpu].debuggerinfo = regs; | 486 | kgdb_info[cpu].debuggerinfo = regs; |
487 | kgdb_info[cpu].task = current; | 487 | kgdb_info[cpu].task = current; |
488 | kgdb_info[cpu].ret_state = 0; | 488 | kgdb_info[cpu].ret_state = 0; |
489 | kgdb_info[cpu].irq_depth = hardirq_count() >> HARDIRQ_SHIFT; | 489 | kgdb_info[cpu].irq_depth = hardirq_count() >> HARDIRQ_SHIFT; |
490 | 490 | ||
491 | /* Make sure the above info reaches the primary CPU */ | 491 | /* Make sure the above info reaches the primary CPU */ |
492 | smp_mb(); | 492 | smp_mb(); |
493 | 493 | ||
494 | if (exception_level == 1) { | 494 | if (exception_level == 1) { |
495 | if (raw_spin_trylock(&dbg_master_lock)) | 495 | if (raw_spin_trylock(&dbg_master_lock)) |
496 | atomic_xchg(&kgdb_active, cpu); | 496 | atomic_xchg(&kgdb_active, cpu); |
497 | goto cpu_master_loop; | 497 | goto cpu_master_loop; |
498 | } | 498 | } |
499 | 499 | ||
500 | /* | 500 | /* |
501 | * CPU will loop if it is a slave or request to become a kgdb | 501 | * CPU will loop if it is a slave or request to become a kgdb |
502 | * master cpu and acquire the kgdb_active lock: | 502 | * master cpu and acquire the kgdb_active lock: |
503 | */ | 503 | */ |
504 | while (1) { | 504 | while (1) { |
505 | cpu_loop: | 505 | cpu_loop: |
506 | if (kgdb_info[cpu].exception_state & DCPU_NEXT_MASTER) { | 506 | if (kgdb_info[cpu].exception_state & DCPU_NEXT_MASTER) { |
507 | kgdb_info[cpu].exception_state &= ~DCPU_NEXT_MASTER; | 507 | kgdb_info[cpu].exception_state &= ~DCPU_NEXT_MASTER; |
508 | goto cpu_master_loop; | 508 | goto cpu_master_loop; |
509 | } else if (kgdb_info[cpu].exception_state & DCPU_WANT_MASTER) { | 509 | } else if (kgdb_info[cpu].exception_state & DCPU_WANT_MASTER) { |
510 | if (raw_spin_trylock(&dbg_master_lock)) { | 510 | if (raw_spin_trylock(&dbg_master_lock)) { |
511 | atomic_xchg(&kgdb_active, cpu); | 511 | atomic_xchg(&kgdb_active, cpu); |
512 | break; | 512 | break; |
513 | } | 513 | } |
514 | } else if (kgdb_info[cpu].exception_state & DCPU_IS_SLAVE) { | 514 | } else if (kgdb_info[cpu].exception_state & DCPU_IS_SLAVE) { |
515 | if (!raw_spin_is_locked(&dbg_slave_lock)) | 515 | if (!raw_spin_is_locked(&dbg_slave_lock)) |
516 | goto return_normal; | 516 | goto return_normal; |
517 | } else { | 517 | } else { |
518 | return_normal: | 518 | return_normal: |
519 | /* Return to normal operation by executing any | 519 | /* Return to normal operation by executing any |
520 | * hw breakpoint fixup. | 520 | * hw breakpoint fixup. |
521 | */ | 521 | */ |
522 | if (arch_kgdb_ops.correct_hw_break) | 522 | if (arch_kgdb_ops.correct_hw_break) |
523 | arch_kgdb_ops.correct_hw_break(); | 523 | arch_kgdb_ops.correct_hw_break(); |
524 | if (trace_on) | 524 | if (trace_on) |
525 | tracing_on(); | 525 | tracing_on(); |
526 | kgdb_info[cpu].exception_state &= | 526 | kgdb_info[cpu].exception_state &= |
527 | ~(DCPU_WANT_MASTER | DCPU_IS_SLAVE); | 527 | ~(DCPU_WANT_MASTER | DCPU_IS_SLAVE); |
528 | kgdb_info[cpu].enter_kgdb--; | 528 | kgdb_info[cpu].enter_kgdb--; |
529 | smp_mb__before_atomic_dec(); | 529 | smp_mb__before_atomic_dec(); |
530 | atomic_dec(&slaves_in_kgdb); | 530 | atomic_dec(&slaves_in_kgdb); |
531 | dbg_touch_watchdogs(); | 531 | dbg_touch_watchdogs(); |
532 | local_irq_restore(flags); | 532 | local_irq_restore(flags); |
533 | return 0; | 533 | return 0; |
534 | } | 534 | } |
535 | cpu_relax(); | 535 | cpu_relax(); |
536 | } | 536 | } |
537 | 537 | ||
538 | /* | 538 | /* |
539 | * For single stepping, try to only enter on the processor | 539 | * For single stepping, try to only enter on the processor |
540 | * that was single stepping. To guard against a deadlock, the | 540 | * that was single stepping. To guard against a deadlock, the |
541 | * kernel will only try for the value of sstep_tries before | 541 | * kernel will only try for the value of sstep_tries before |
542 | * giving up and continuing on. | 542 | * giving up and continuing on. |
543 | */ | 543 | */ |
544 | if (atomic_read(&kgdb_cpu_doing_single_step) != -1 && | 544 | if (atomic_read(&kgdb_cpu_doing_single_step) != -1 && |
545 | (kgdb_info[cpu].task && | 545 | (kgdb_info[cpu].task && |
546 | kgdb_info[cpu].task->pid != kgdb_sstep_pid) && --sstep_tries) { | 546 | kgdb_info[cpu].task->pid != kgdb_sstep_pid) && --sstep_tries) { |
547 | atomic_set(&kgdb_active, -1); | 547 | atomic_set(&kgdb_active, -1); |
548 | raw_spin_unlock(&dbg_master_lock); | 548 | raw_spin_unlock(&dbg_master_lock); |
549 | dbg_touch_watchdogs(); | 549 | dbg_touch_watchdogs(); |
550 | local_irq_restore(flags); | 550 | local_irq_restore(flags); |
551 | 551 | ||
552 | goto acquirelock; | 552 | goto acquirelock; |
553 | } | 553 | } |
554 | 554 | ||
555 | if (!kgdb_io_ready(1)) { | 555 | if (!kgdb_io_ready(1)) { |
556 | kgdb_info[cpu].ret_state = 1; | 556 | kgdb_info[cpu].ret_state = 1; |
557 | goto kgdb_restore; /* No I/O connection, resume the system */ | 557 | goto kgdb_restore; /* No I/O connection, resume the system */ |
558 | } | 558 | } |
559 | 559 | ||
560 | /* | 560 | /* |
561 | * Don't enter if we have hit a removed breakpoint. | 561 | * Don't enter if we have hit a removed breakpoint. |
562 | */ | 562 | */ |
563 | if (kgdb_skipexception(ks->ex_vector, ks->linux_regs)) | 563 | if (kgdb_skipexception(ks->ex_vector, ks->linux_regs)) |
564 | goto kgdb_restore; | 564 | goto kgdb_restore; |
565 | 565 | ||
566 | /* Call the I/O driver's pre_exception routine */ | 566 | /* Call the I/O driver's pre_exception routine */ |
567 | if (dbg_io_ops->pre_exception) | 567 | if (dbg_io_ops->pre_exception) |
568 | dbg_io_ops->pre_exception(); | 568 | dbg_io_ops->pre_exception(); |
569 | 569 | ||
570 | /* | 570 | /* |
571 | * Get the passive CPU lock which will hold all the non-primary | 571 | * Get the passive CPU lock which will hold all the non-primary |
572 | * CPU in a spin state while the debugger is active | 572 | * CPU in a spin state while the debugger is active |
573 | */ | 573 | */ |
574 | if (!kgdb_single_step) | 574 | if (!kgdb_single_step) |
575 | raw_spin_lock(&dbg_slave_lock); | 575 | raw_spin_lock(&dbg_slave_lock); |
576 | 576 | ||
577 | #ifdef CONFIG_SMP | 577 | #ifdef CONFIG_SMP |
578 | /* If send_ready set, slaves are already waiting */ | ||
579 | if (ks->send_ready) | ||
580 | atomic_set(ks->send_ready, 1); | ||
581 | |||
578 | /* Signal the other CPUs to enter kgdb_wait() */ | 582 | /* Signal the other CPUs to enter kgdb_wait() */ |
579 | if ((!kgdb_single_step) && kgdb_do_roundup) | 583 | else if ((!kgdb_single_step) && kgdb_do_roundup) |
580 | kgdb_roundup_cpus(flags); | 584 | kgdb_roundup_cpus(flags); |
581 | #endif | 585 | #endif |
582 | 586 | ||
583 | /* | 587 | /* |
584 | * Wait for the other CPUs to be notified and be waiting for us: | 588 | * Wait for the other CPUs to be notified and be waiting for us: |
585 | */ | 589 | */ |
586 | while (kgdb_do_roundup && (atomic_read(&masters_in_kgdb) + | 590 | while (kgdb_do_roundup && (atomic_read(&masters_in_kgdb) + |
587 | atomic_read(&slaves_in_kgdb)) != online_cpus) | 591 | atomic_read(&slaves_in_kgdb)) != online_cpus) |
588 | cpu_relax(); | 592 | cpu_relax(); |
589 | 593 | ||
590 | /* | 594 | /* |
591 | * At this point the primary processor is completely | 595 | * At this point the primary processor is completely |
592 | * in the debugger and all secondary CPUs are quiescent | 596 | * in the debugger and all secondary CPUs are quiescent |
593 | */ | 597 | */ |
594 | dbg_deactivate_sw_breakpoints(); | 598 | dbg_deactivate_sw_breakpoints(); |
595 | kgdb_single_step = 0; | 599 | kgdb_single_step = 0; |
596 | kgdb_contthread = current; | 600 | kgdb_contthread = current; |
597 | exception_level = 0; | 601 | exception_level = 0; |
598 | trace_on = tracing_is_on(); | 602 | trace_on = tracing_is_on(); |
599 | if (trace_on) | 603 | if (trace_on) |
600 | tracing_off(); | 604 | tracing_off(); |
601 | 605 | ||
602 | while (1) { | 606 | while (1) { |
603 | cpu_master_loop: | 607 | cpu_master_loop: |
604 | if (dbg_kdb_mode) { | 608 | if (dbg_kdb_mode) { |
605 | kgdb_connected = 1; | 609 | kgdb_connected = 1; |
606 | error = kdb_stub(ks); | 610 | error = kdb_stub(ks); |
607 | if (error == -1) | 611 | if (error == -1) |
608 | continue; | 612 | continue; |
609 | kgdb_connected = 0; | 613 | kgdb_connected = 0; |
610 | } else { | 614 | } else { |
611 | error = gdb_serial_stub(ks); | 615 | error = gdb_serial_stub(ks); |
612 | } | 616 | } |
613 | 617 | ||
614 | if (error == DBG_PASS_EVENT) { | 618 | if (error == DBG_PASS_EVENT) { |
615 | dbg_kdb_mode = !dbg_kdb_mode; | 619 | dbg_kdb_mode = !dbg_kdb_mode; |
616 | } else if (error == DBG_SWITCH_CPU_EVENT) { | 620 | } else if (error == DBG_SWITCH_CPU_EVENT) { |
617 | kgdb_info[dbg_switch_cpu].exception_state |= | 621 | kgdb_info[dbg_switch_cpu].exception_state |= |
618 | DCPU_NEXT_MASTER; | 622 | DCPU_NEXT_MASTER; |
619 | goto cpu_loop; | 623 | goto cpu_loop; |
620 | } else { | 624 | } else { |
621 | kgdb_info[cpu].ret_state = error; | 625 | kgdb_info[cpu].ret_state = error; |
622 | break; | 626 | break; |
623 | } | 627 | } |
624 | } | 628 | } |
625 | 629 | ||
626 | /* Call the I/O driver's post_exception routine */ | 630 | /* Call the I/O driver's post_exception routine */ |
627 | if (dbg_io_ops->post_exception) | 631 | if (dbg_io_ops->post_exception) |
628 | dbg_io_ops->post_exception(); | 632 | dbg_io_ops->post_exception(); |
629 | 633 | ||
630 | if (!kgdb_single_step) { | 634 | if (!kgdb_single_step) { |
631 | raw_spin_unlock(&dbg_slave_lock); | 635 | raw_spin_unlock(&dbg_slave_lock); |
632 | /* Wait till all the CPUs have quit from the debugger. */ | 636 | /* Wait till all the CPUs have quit from the debugger. */ |
633 | while (kgdb_do_roundup && atomic_read(&slaves_in_kgdb)) | 637 | while (kgdb_do_roundup && atomic_read(&slaves_in_kgdb)) |
634 | cpu_relax(); | 638 | cpu_relax(); |
635 | } | 639 | } |
636 | 640 | ||
637 | kgdb_restore: | 641 | kgdb_restore: |
638 | if (atomic_read(&kgdb_cpu_doing_single_step) != -1) { | 642 | if (atomic_read(&kgdb_cpu_doing_single_step) != -1) { |
639 | int sstep_cpu = atomic_read(&kgdb_cpu_doing_single_step); | 643 | int sstep_cpu = atomic_read(&kgdb_cpu_doing_single_step); |
640 | if (kgdb_info[sstep_cpu].task) | 644 | if (kgdb_info[sstep_cpu].task) |
641 | kgdb_sstep_pid = kgdb_info[sstep_cpu].task->pid; | 645 | kgdb_sstep_pid = kgdb_info[sstep_cpu].task->pid; |
642 | else | 646 | else |
643 | kgdb_sstep_pid = 0; | 647 | kgdb_sstep_pid = 0; |
644 | } | 648 | } |
645 | if (arch_kgdb_ops.correct_hw_break) | 649 | if (arch_kgdb_ops.correct_hw_break) |
646 | arch_kgdb_ops.correct_hw_break(); | 650 | arch_kgdb_ops.correct_hw_break(); |
647 | if (trace_on) | 651 | if (trace_on) |
648 | tracing_on(); | 652 | tracing_on(); |
649 | 653 | ||
650 | kgdb_info[cpu].exception_state &= | 654 | kgdb_info[cpu].exception_state &= |
651 | ~(DCPU_WANT_MASTER | DCPU_IS_SLAVE); | 655 | ~(DCPU_WANT_MASTER | DCPU_IS_SLAVE); |
652 | kgdb_info[cpu].enter_kgdb--; | 656 | kgdb_info[cpu].enter_kgdb--; |
653 | smp_mb__before_atomic_dec(); | 657 | smp_mb__before_atomic_dec(); |
654 | atomic_dec(&masters_in_kgdb); | 658 | atomic_dec(&masters_in_kgdb); |
655 | /* Free kgdb_active */ | 659 | /* Free kgdb_active */ |
656 | atomic_set(&kgdb_active, -1); | 660 | atomic_set(&kgdb_active, -1); |
657 | raw_spin_unlock(&dbg_master_lock); | 661 | raw_spin_unlock(&dbg_master_lock); |
658 | dbg_touch_watchdogs(); | 662 | dbg_touch_watchdogs(); |
659 | local_irq_restore(flags); | 663 | local_irq_restore(flags); |
660 | 664 | ||
661 | return kgdb_info[cpu].ret_state; | 665 | return kgdb_info[cpu].ret_state; |
662 | } | 666 | } |
663 | 667 | ||
664 | /* | 668 | /* |
665 | * kgdb_handle_exception() - main entry point from a kernel exception | 669 | * kgdb_handle_exception() - main entry point from a kernel exception |
666 | * | 670 | * |
667 | * Locking hierarchy: | 671 | * Locking hierarchy: |
668 | * interface locks, if any (begin_session) | 672 | * interface locks, if any (begin_session) |
669 | * kgdb lock (kgdb_active) | 673 | * kgdb lock (kgdb_active) |
670 | */ | 674 | */ |
671 | int | 675 | int |
672 | kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) | 676 | kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) |
673 | { | 677 | { |
674 | struct kgdb_state kgdb_var; | 678 | struct kgdb_state kgdb_var; |
675 | struct kgdb_state *ks = &kgdb_var; | 679 | struct kgdb_state *ks = &kgdb_var; |
676 | int ret = 0; | 680 | int ret = 0; |
677 | 681 | ||
678 | if (arch_kgdb_ops.enable_nmi) | 682 | if (arch_kgdb_ops.enable_nmi) |
679 | arch_kgdb_ops.enable_nmi(0); | 683 | arch_kgdb_ops.enable_nmi(0); |
680 | 684 | ||
685 | memset(ks, 0, sizeof(struct kgdb_state)); | ||
681 | ks->cpu = raw_smp_processor_id(); | 686 | ks->cpu = raw_smp_processor_id(); |
682 | ks->ex_vector = evector; | 687 | ks->ex_vector = evector; |
683 | ks->signo = signo; | 688 | ks->signo = signo; |
684 | ks->err_code = ecode; | 689 | ks->err_code = ecode; |
685 | ks->kgdb_usethreadid = 0; | ||
686 | ks->linux_regs = regs; | 690 | ks->linux_regs = regs; |
687 | 691 | ||
688 | if (kgdb_reenter_check(ks)) | 692 | if (kgdb_reenter_check(ks)) |
689 | goto out; /* Ouch, double exception ! */ | 693 | goto out; /* Ouch, double exception ! */ |
690 | if (kgdb_info[ks->cpu].enter_kgdb != 0) | 694 | if (kgdb_info[ks->cpu].enter_kgdb != 0) |
691 | goto out; | 695 | goto out; |
692 | 696 | ||
693 | ret = kgdb_cpu_enter(ks, regs, DCPU_WANT_MASTER); | 697 | ret = kgdb_cpu_enter(ks, regs, DCPU_WANT_MASTER); |
694 | out: | 698 | out: |
695 | if (arch_kgdb_ops.enable_nmi) | 699 | if (arch_kgdb_ops.enable_nmi) |
696 | arch_kgdb_ops.enable_nmi(1); | 700 | arch_kgdb_ops.enable_nmi(1); |
697 | return ret; | 701 | return ret; |
698 | } | 702 | } |
699 | 703 | ||
700 | /* | 704 | /* |
701 | * GDB places a breakpoint at this function to know dynamically | 705 | * GDB places a breakpoint at this function to know dynamically |
702 | * loaded objects. It's not defined static so that only one instance with this | 706 | * loaded objects. It's not defined static so that only one instance with this |
703 | * name exists in the kernel. | 707 | * name exists in the kernel. |
704 | */ | 708 | */ |
705 | 709 | ||
706 | static int module_event(struct notifier_block *self, unsigned long val, | 710 | static int module_event(struct notifier_block *self, unsigned long val, |
707 | void *data) | 711 | void *data) |
708 | { | 712 | { |
709 | return 0; | 713 | return 0; |
710 | } | 714 | } |
711 | 715 | ||
712 | static struct notifier_block dbg_module_load_nb = { | 716 | static struct notifier_block dbg_module_load_nb = { |
713 | .notifier_call = module_event, | 717 | .notifier_call = module_event, |
714 | }; | 718 | }; |
715 | 719 | ||
716 | int kgdb_nmicallback(int cpu, void *regs) | 720 | int kgdb_nmicallback(int cpu, void *regs) |
717 | { | 721 | { |
718 | #ifdef CONFIG_SMP | 722 | #ifdef CONFIG_SMP |
719 | struct kgdb_state kgdb_var; | 723 | struct kgdb_state kgdb_var; |
720 | struct kgdb_state *ks = &kgdb_var; | 724 | struct kgdb_state *ks = &kgdb_var; |
721 | 725 | ||
722 | memset(ks, 0, sizeof(struct kgdb_state)); | 726 | memset(ks, 0, sizeof(struct kgdb_state)); |
723 | ks->cpu = cpu; | 727 | ks->cpu = cpu; |
724 | ks->linux_regs = regs; | 728 | ks->linux_regs = regs; |
725 | 729 | ||
726 | if (kgdb_info[ks->cpu].enter_kgdb == 0 && | 730 | if (kgdb_info[ks->cpu].enter_kgdb == 0 && |
727 | raw_spin_is_locked(&dbg_master_lock)) { | 731 | raw_spin_is_locked(&dbg_master_lock)) { |
728 | kgdb_cpu_enter(ks, regs, DCPU_IS_SLAVE); | 732 | kgdb_cpu_enter(ks, regs, DCPU_IS_SLAVE); |
733 | return 0; | ||
734 | } | ||
735 | #endif | ||
736 | return 1; | ||
737 | } | ||
738 | |||
739 | int kgdb_nmicallin(int cpu, int trapnr, void *regs, atomic_t *send_ready) | ||
740 | { | ||
741 | #ifdef CONFIG_SMP | ||
742 | if (!kgdb_io_ready(0) || !send_ready) | ||
743 | return 1; | ||
744 | |||
745 | if (kgdb_info[cpu].enter_kgdb == 0) { | ||
746 | struct kgdb_state kgdb_var; | ||
747 | struct kgdb_state *ks = &kgdb_var; | ||
748 | |||
749 | memset(ks, 0, sizeof(struct kgdb_state)); | ||
750 | ks->cpu = cpu; | ||
751 | ks->ex_vector = trapnr; | ||
752 | ks->signo = SIGTRAP; | ||
753 | ks->err_code = KGDB_KDB_REASON_SYSTEM_NMI; | ||
754 | ks->linux_regs = regs; | ||
755 | ks->send_ready = send_ready; | ||
756 | kgdb_cpu_enter(ks, regs, DCPU_WANT_MASTER); | ||
729 | return 0; | 757 | return 0; |
730 | } | 758 | } |
731 | #endif | 759 | #endif |
732 | return 1; | 760 | return 1; |
733 | } | 761 | } |
734 | 762 | ||
735 | static void kgdb_console_write(struct console *co, const char *s, | 763 | static void kgdb_console_write(struct console *co, const char *s, |
736 | unsigned count) | 764 | unsigned count) |
737 | { | 765 | { |
738 | unsigned long flags; | 766 | unsigned long flags; |
739 | 767 | ||
740 | /* If we're debugging, or KGDB has not connected, don't try | 768 | /* If we're debugging, or KGDB has not connected, don't try |
741 | * and print. */ | 769 | * and print. */ |
742 | if (!kgdb_connected || atomic_read(&kgdb_active) != -1 || dbg_kdb_mode) | 770 | if (!kgdb_connected || atomic_read(&kgdb_active) != -1 || dbg_kdb_mode) |
743 | return; | 771 | return; |
744 | 772 | ||
745 | local_irq_save(flags); | 773 | local_irq_save(flags); |
746 | gdbstub_msg_write(s, count); | 774 | gdbstub_msg_write(s, count); |
747 | local_irq_restore(flags); | 775 | local_irq_restore(flags); |
748 | } | 776 | } |
749 | 777 | ||
750 | static struct console kgdbcons = { | 778 | static struct console kgdbcons = { |
751 | .name = "kgdb", | 779 | .name = "kgdb", |
752 | .write = kgdb_console_write, | 780 | .write = kgdb_console_write, |
753 | .flags = CON_PRINTBUFFER | CON_ENABLED, | 781 | .flags = CON_PRINTBUFFER | CON_ENABLED, |
754 | .index = -1, | 782 | .index = -1, |
755 | }; | 783 | }; |
756 | 784 | ||
757 | #ifdef CONFIG_MAGIC_SYSRQ | 785 | #ifdef CONFIG_MAGIC_SYSRQ |
758 | static void sysrq_handle_dbg(int key) | 786 | static void sysrq_handle_dbg(int key) |
759 | { | 787 | { |
760 | if (!dbg_io_ops) { | 788 | if (!dbg_io_ops) { |
761 | printk(KERN_CRIT "ERROR: No KGDB I/O module available\n"); | 789 | printk(KERN_CRIT "ERROR: No KGDB I/O module available\n"); |
762 | return; | 790 | return; |
763 | } | 791 | } |
764 | if (!kgdb_connected) { | 792 | if (!kgdb_connected) { |
765 | #ifdef CONFIG_KGDB_KDB | 793 | #ifdef CONFIG_KGDB_KDB |
766 | if (!dbg_kdb_mode) | 794 | if (!dbg_kdb_mode) |
767 | printk(KERN_CRIT "KGDB or $3#33 for KDB\n"); | 795 | printk(KERN_CRIT "KGDB or $3#33 for KDB\n"); |
768 | #else | 796 | #else |
769 | printk(KERN_CRIT "Entering KGDB\n"); | 797 | printk(KERN_CRIT "Entering KGDB\n"); |
770 | #endif | 798 | #endif |
771 | } | 799 | } |
772 | 800 | ||
773 | kgdb_breakpoint(); | 801 | kgdb_breakpoint(); |
774 | } | 802 | } |
775 | 803 | ||
776 | static struct sysrq_key_op sysrq_dbg_op = { | 804 | static struct sysrq_key_op sysrq_dbg_op = { |
777 | .handler = sysrq_handle_dbg, | 805 | .handler = sysrq_handle_dbg, |
778 | .help_msg = "debug(g)", | 806 | .help_msg = "debug(g)", |
779 | .action_msg = "DEBUG", | 807 | .action_msg = "DEBUG", |
780 | }; | 808 | }; |
781 | #endif | 809 | #endif |
782 | 810 | ||
783 | static int kgdb_panic_event(struct notifier_block *self, | 811 | static int kgdb_panic_event(struct notifier_block *self, |
784 | unsigned long val, | 812 | unsigned long val, |
785 | void *data) | 813 | void *data) |
786 | { | 814 | { |
787 | if (dbg_kdb_mode) | 815 | if (dbg_kdb_mode) |
788 | kdb_printf("PANIC: %s\n", (char *)data); | 816 | kdb_printf("PANIC: %s\n", (char *)data); |
789 | kgdb_breakpoint(); | 817 | kgdb_breakpoint(); |
790 | return NOTIFY_DONE; | 818 | return NOTIFY_DONE; |
791 | } | 819 | } |
792 | 820 | ||
793 | static struct notifier_block kgdb_panic_event_nb = { | 821 | static struct notifier_block kgdb_panic_event_nb = { |
794 | .notifier_call = kgdb_panic_event, | 822 | .notifier_call = kgdb_panic_event, |
795 | .priority = INT_MAX, | 823 | .priority = INT_MAX, |
796 | }; | 824 | }; |
797 | 825 | ||
798 | void __weak kgdb_arch_late(void) | 826 | void __weak kgdb_arch_late(void) |
799 | { | 827 | { |
800 | } | 828 | } |
801 | 829 | ||
802 | void __init dbg_late_init(void) | 830 | void __init dbg_late_init(void) |
803 | { | 831 | { |
804 | dbg_is_early = false; | 832 | dbg_is_early = false; |
805 | if (kgdb_io_module_registered) | 833 | if (kgdb_io_module_registered) |
806 | kgdb_arch_late(); | 834 | kgdb_arch_late(); |
807 | kdb_init(KDB_INIT_FULL); | 835 | kdb_init(KDB_INIT_FULL); |
808 | } | 836 | } |
809 | 837 | ||
810 | static int | 838 | static int |
811 | dbg_notify_reboot(struct notifier_block *this, unsigned long code, void *x) | 839 | dbg_notify_reboot(struct notifier_block *this, unsigned long code, void *x) |
812 | { | 840 | { |
813 | /* | 841 | /* |
814 | * Take the following action on reboot notify depending on value: | 842 | * Take the following action on reboot notify depending on value: |
815 | * 1 == Enter debugger | 843 | * 1 == Enter debugger |
816 | * 0 == [the default] detatch debug client | 844 | * 0 == [the default] detatch debug client |
817 | * -1 == Do nothing... and use this until the board resets | 845 | * -1 == Do nothing... and use this until the board resets |
818 | */ | 846 | */ |
819 | switch (kgdbreboot) { | 847 | switch (kgdbreboot) { |
820 | case 1: | 848 | case 1: |
821 | kgdb_breakpoint(); | 849 | kgdb_breakpoint(); |
822 | case -1: | 850 | case -1: |
823 | goto done; | 851 | goto done; |
824 | } | 852 | } |
825 | if (!dbg_kdb_mode) | 853 | if (!dbg_kdb_mode) |
826 | gdbstub_exit(code); | 854 | gdbstub_exit(code); |
827 | done: | 855 | done: |
828 | return NOTIFY_DONE; | 856 | return NOTIFY_DONE; |
829 | } | 857 | } |
830 | 858 | ||
831 | static struct notifier_block dbg_reboot_notifier = { | 859 | static struct notifier_block dbg_reboot_notifier = { |
832 | .notifier_call = dbg_notify_reboot, | 860 | .notifier_call = dbg_notify_reboot, |
833 | .next = NULL, | 861 | .next = NULL, |
834 | .priority = INT_MAX, | 862 | .priority = INT_MAX, |
835 | }; | 863 | }; |
836 | 864 | ||
837 | static void kgdb_register_callbacks(void) | 865 | static void kgdb_register_callbacks(void) |
838 | { | 866 | { |
839 | if (!kgdb_io_module_registered) { | 867 | if (!kgdb_io_module_registered) { |
840 | kgdb_io_module_registered = 1; | 868 | kgdb_io_module_registered = 1; |
841 | kgdb_arch_init(); | 869 | kgdb_arch_init(); |
842 | if (!dbg_is_early) | 870 | if (!dbg_is_early) |
843 | kgdb_arch_late(); | 871 | kgdb_arch_late(); |
844 | register_module_notifier(&dbg_module_load_nb); | 872 | register_module_notifier(&dbg_module_load_nb); |
845 | register_reboot_notifier(&dbg_reboot_notifier); | 873 | register_reboot_notifier(&dbg_reboot_notifier); |
846 | atomic_notifier_chain_register(&panic_notifier_list, | 874 | atomic_notifier_chain_register(&panic_notifier_list, |
847 | &kgdb_panic_event_nb); | 875 | &kgdb_panic_event_nb); |
848 | #ifdef CONFIG_MAGIC_SYSRQ | 876 | #ifdef CONFIG_MAGIC_SYSRQ |
849 | register_sysrq_key('g', &sysrq_dbg_op); | 877 | register_sysrq_key('g', &sysrq_dbg_op); |
850 | #endif | 878 | #endif |
851 | if (kgdb_use_con && !kgdb_con_registered) { | 879 | if (kgdb_use_con && !kgdb_con_registered) { |
852 | register_console(&kgdbcons); | 880 | register_console(&kgdbcons); |
853 | kgdb_con_registered = 1; | 881 | kgdb_con_registered = 1; |
854 | } | 882 | } |
855 | } | 883 | } |
856 | } | 884 | } |
857 | 885 | ||
858 | static void kgdb_unregister_callbacks(void) | 886 | static void kgdb_unregister_callbacks(void) |
859 | { | 887 | { |
860 | /* | 888 | /* |
861 | * When this routine is called KGDB should unregister from the | 889 | * When this routine is called KGDB should unregister from the |
862 | * panic handler and clean up, making sure it is not handling any | 890 | * panic handler and clean up, making sure it is not handling any |
863 | * break exceptions at the time. | 891 | * break exceptions at the time. |
864 | */ | 892 | */ |
865 | if (kgdb_io_module_registered) { | 893 | if (kgdb_io_module_registered) { |
866 | kgdb_io_module_registered = 0; | 894 | kgdb_io_module_registered = 0; |
867 | unregister_reboot_notifier(&dbg_reboot_notifier); | 895 | unregister_reboot_notifier(&dbg_reboot_notifier); |
868 | unregister_module_notifier(&dbg_module_load_nb); | 896 | unregister_module_notifier(&dbg_module_load_nb); |
869 | atomic_notifier_chain_unregister(&panic_notifier_list, | 897 | atomic_notifier_chain_unregister(&panic_notifier_list, |
870 | &kgdb_panic_event_nb); | 898 | &kgdb_panic_event_nb); |
871 | kgdb_arch_exit(); | 899 | kgdb_arch_exit(); |
872 | #ifdef CONFIG_MAGIC_SYSRQ | 900 | #ifdef CONFIG_MAGIC_SYSRQ |
873 | unregister_sysrq_key('g', &sysrq_dbg_op); | 901 | unregister_sysrq_key('g', &sysrq_dbg_op); |
874 | #endif | 902 | #endif |
875 | if (kgdb_con_registered) { | 903 | if (kgdb_con_registered) { |
876 | unregister_console(&kgdbcons); | 904 | unregister_console(&kgdbcons); |
877 | kgdb_con_registered = 0; | 905 | kgdb_con_registered = 0; |
878 | } | 906 | } |
879 | } | 907 | } |
880 | } | 908 | } |
881 | 909 | ||
882 | /* | 910 | /* |
883 | * There are times a tasklet needs to be used vs a compiled in | 911 | * There are times a tasklet needs to be used vs a compiled in |
884 | * break point so as to cause an exception outside a kgdb I/O module, | 912 | * break point so as to cause an exception outside a kgdb I/O module, |
885 | * such as is the case with kgdboe, where calling a breakpoint in the | 913 | * such as is the case with kgdboe, where calling a breakpoint in the |
886 | * I/O driver itself would be fatal. | 914 | * I/O driver itself would be fatal. |
887 | */ | 915 | */ |
888 | static void kgdb_tasklet_bpt(unsigned long ing) | 916 | static void kgdb_tasklet_bpt(unsigned long ing) |
889 | { | 917 | { |
890 | kgdb_breakpoint(); | 918 | kgdb_breakpoint(); |
891 | atomic_set(&kgdb_break_tasklet_var, 0); | 919 | atomic_set(&kgdb_break_tasklet_var, 0); |
892 | } | 920 | } |
893 | 921 | ||
894 | static DECLARE_TASKLET(kgdb_tasklet_breakpoint, kgdb_tasklet_bpt, 0); | 922 | static DECLARE_TASKLET(kgdb_tasklet_breakpoint, kgdb_tasklet_bpt, 0); |
895 | 923 | ||
896 | void kgdb_schedule_breakpoint(void) | 924 | void kgdb_schedule_breakpoint(void) |
897 | { | 925 | { |
898 | if (atomic_read(&kgdb_break_tasklet_var) || | 926 | if (atomic_read(&kgdb_break_tasklet_var) || |
899 | atomic_read(&kgdb_active) != -1 || | 927 | atomic_read(&kgdb_active) != -1 || |
900 | atomic_read(&kgdb_setting_breakpoint)) | 928 | atomic_read(&kgdb_setting_breakpoint)) |
901 | return; | 929 | return; |
902 | atomic_inc(&kgdb_break_tasklet_var); | 930 | atomic_inc(&kgdb_break_tasklet_var); |
903 | tasklet_schedule(&kgdb_tasklet_breakpoint); | 931 | tasklet_schedule(&kgdb_tasklet_breakpoint); |
904 | } | 932 | } |
905 | EXPORT_SYMBOL_GPL(kgdb_schedule_breakpoint); | 933 | EXPORT_SYMBOL_GPL(kgdb_schedule_breakpoint); |
906 | 934 | ||
907 | static void kgdb_initial_breakpoint(void) | 935 | static void kgdb_initial_breakpoint(void) |
908 | { | 936 | { |
909 | kgdb_break_asap = 0; | 937 | kgdb_break_asap = 0; |
910 | 938 | ||
911 | printk(KERN_CRIT "kgdb: Waiting for connection from remote gdb...\n"); | 939 | printk(KERN_CRIT "kgdb: Waiting for connection from remote gdb...\n"); |
912 | kgdb_breakpoint(); | 940 | kgdb_breakpoint(); |
913 | } | 941 | } |
914 | 942 | ||
915 | /** | 943 | /** |
916 | * kgdb_register_io_module - register KGDB IO module | 944 | * kgdb_register_io_module - register KGDB IO module |
917 | * @new_dbg_io_ops: the io ops vector | 945 | * @new_dbg_io_ops: the io ops vector |
918 | * | 946 | * |
919 | * Register it with the KGDB core. | 947 | * Register it with the KGDB core. |
920 | */ | 948 | */ |
921 | int kgdb_register_io_module(struct kgdb_io *new_dbg_io_ops) | 949 | int kgdb_register_io_module(struct kgdb_io *new_dbg_io_ops) |
922 | { | 950 | { |
923 | int err; | 951 | int err; |
924 | 952 | ||
925 | spin_lock(&kgdb_registration_lock); | 953 | spin_lock(&kgdb_registration_lock); |
926 | 954 | ||
927 | if (dbg_io_ops) { | 955 | if (dbg_io_ops) { |
928 | spin_unlock(&kgdb_registration_lock); | 956 | spin_unlock(&kgdb_registration_lock); |
929 | 957 | ||
930 | printk(KERN_ERR "kgdb: Another I/O driver is already " | 958 | printk(KERN_ERR "kgdb: Another I/O driver is already " |
931 | "registered with KGDB.\n"); | 959 | "registered with KGDB.\n"); |
932 | return -EBUSY; | 960 | return -EBUSY; |
933 | } | 961 | } |
934 | 962 | ||
935 | if (new_dbg_io_ops->init) { | 963 | if (new_dbg_io_ops->init) { |
936 | err = new_dbg_io_ops->init(); | 964 | err = new_dbg_io_ops->init(); |
937 | if (err) { | 965 | if (err) { |
938 | spin_unlock(&kgdb_registration_lock); | 966 | spin_unlock(&kgdb_registration_lock); |
939 | return err; | 967 | return err; |
940 | } | 968 | } |
941 | } | 969 | } |
942 | 970 | ||
943 | dbg_io_ops = new_dbg_io_ops; | 971 | dbg_io_ops = new_dbg_io_ops; |
944 | 972 | ||
945 | spin_unlock(&kgdb_registration_lock); | 973 | spin_unlock(&kgdb_registration_lock); |
946 | 974 | ||
947 | printk(KERN_INFO "kgdb: Registered I/O driver %s.\n", | 975 | printk(KERN_INFO "kgdb: Registered I/O driver %s.\n", |
948 | new_dbg_io_ops->name); | 976 | new_dbg_io_ops->name); |
949 | 977 | ||
950 | /* Arm KGDB now. */ | 978 | /* Arm KGDB now. */ |
951 | kgdb_register_callbacks(); | 979 | kgdb_register_callbacks(); |
952 | 980 | ||
953 | if (kgdb_break_asap) | 981 | if (kgdb_break_asap) |
954 | kgdb_initial_breakpoint(); | 982 | kgdb_initial_breakpoint(); |
955 | 983 | ||
956 | return 0; | 984 | return 0; |
957 | } | 985 | } |
958 | EXPORT_SYMBOL_GPL(kgdb_register_io_module); | 986 | EXPORT_SYMBOL_GPL(kgdb_register_io_module); |
959 | 987 | ||
960 | /** | 988 | /** |
961 | * kkgdb_unregister_io_module - unregister KGDB IO module | 989 | * kkgdb_unregister_io_module - unregister KGDB IO module |
962 | * @old_dbg_io_ops: the io ops vector | 990 | * @old_dbg_io_ops: the io ops vector |
963 | * | 991 | * |
964 | * Unregister it with the KGDB core. | 992 | * Unregister it with the KGDB core. |
965 | */ | 993 | */ |
966 | void kgdb_unregister_io_module(struct kgdb_io *old_dbg_io_ops) | 994 | void kgdb_unregister_io_module(struct kgdb_io *old_dbg_io_ops) |
967 | { | 995 | { |
968 | BUG_ON(kgdb_connected); | 996 | BUG_ON(kgdb_connected); |
969 | 997 | ||
970 | /* | 998 | /* |
971 | * KGDB is no longer able to communicate out, so | 999 | * KGDB is no longer able to communicate out, so |
972 | * unregister our callbacks and reset state. | 1000 | * unregister our callbacks and reset state. |
973 | */ | 1001 | */ |
974 | kgdb_unregister_callbacks(); | 1002 | kgdb_unregister_callbacks(); |
975 | 1003 | ||
976 | spin_lock(&kgdb_registration_lock); | 1004 | spin_lock(&kgdb_registration_lock); |
977 | 1005 | ||
978 | WARN_ON_ONCE(dbg_io_ops != old_dbg_io_ops); | 1006 | WARN_ON_ONCE(dbg_io_ops != old_dbg_io_ops); |
979 | dbg_io_ops = NULL; | 1007 | dbg_io_ops = NULL; |
980 | 1008 | ||
981 | spin_unlock(&kgdb_registration_lock); | 1009 | spin_unlock(&kgdb_registration_lock); |
982 | 1010 | ||
983 | printk(KERN_INFO | 1011 | printk(KERN_INFO |
984 | "kgdb: Unregistered I/O driver %s, debugger disabled.\n", | 1012 | "kgdb: Unregistered I/O driver %s, debugger disabled.\n", |
985 | old_dbg_io_ops->name); | 1013 | old_dbg_io_ops->name); |
986 | } | 1014 | } |
987 | EXPORT_SYMBOL_GPL(kgdb_unregister_io_module); | 1015 | EXPORT_SYMBOL_GPL(kgdb_unregister_io_module); |
988 | 1016 | ||
989 | int dbg_io_get_char(void) | 1017 | int dbg_io_get_char(void) |
990 | { | 1018 | { |
991 | int ret = dbg_io_ops->read_char(); | 1019 | int ret = dbg_io_ops->read_char(); |
992 | if (ret == NO_POLL_CHAR) | 1020 | if (ret == NO_POLL_CHAR) |
993 | return -1; | 1021 | return -1; |
994 | if (!dbg_kdb_mode) | 1022 | if (!dbg_kdb_mode) |
995 | return ret; | 1023 | return ret; |
996 | if (ret == 127) | 1024 | if (ret == 127) |
997 | return 8; | 1025 | return 8; |
998 | return ret; | 1026 | return ret; |
999 | } | 1027 | } |
1000 | 1028 | ||
1001 | /** | 1029 | /** |
1002 | * kgdb_breakpoint - generate breakpoint exception | 1030 | * kgdb_breakpoint - generate breakpoint exception |
1003 | * | 1031 | * |
1004 | * This function will generate a breakpoint exception. It is used at the | 1032 | * This function will generate a breakpoint exception. It is used at the |
1005 | * beginning of a program to sync up with a debugger and can be used | 1033 | * beginning of a program to sync up with a debugger and can be used |
1006 | * otherwise as a quick means to stop program execution and "break" into | 1034 | * otherwise as a quick means to stop program execution and "break" into |
1007 | * the debugger. | 1035 | * the debugger. |
1008 | */ | 1036 | */ |
1009 | void kgdb_breakpoint(void) | 1037 | void kgdb_breakpoint(void) |
1010 | { | 1038 | { |
1011 | atomic_inc(&kgdb_setting_breakpoint); | 1039 | atomic_inc(&kgdb_setting_breakpoint); |
1012 | wmb(); /* Sync point before breakpoint */ | 1040 | wmb(); /* Sync point before breakpoint */ |
1013 | arch_kgdb_breakpoint(); | 1041 | arch_kgdb_breakpoint(); |
1014 | wmb(); /* Sync point after breakpoint */ | 1042 | wmb(); /* Sync point after breakpoint */ |
1015 | atomic_dec(&kgdb_setting_breakpoint); | 1043 | atomic_dec(&kgdb_setting_breakpoint); |
1016 | } | 1044 | } |
1017 | EXPORT_SYMBOL_GPL(kgdb_breakpoint); | 1045 | EXPORT_SYMBOL_GPL(kgdb_breakpoint); |
1018 | 1046 | ||
1019 | static int __init opt_kgdb_wait(char *str) | 1047 | static int __init opt_kgdb_wait(char *str) |
1020 | { | 1048 | { |
1021 | kgdb_break_asap = 1; | 1049 | kgdb_break_asap = 1; |
1022 | 1050 | ||
1023 | kdb_init(KDB_INIT_EARLY); | 1051 | kdb_init(KDB_INIT_EARLY); |
1024 | if (kgdb_io_module_registered) | 1052 | if (kgdb_io_module_registered) |
1025 | kgdb_initial_breakpoint(); | 1053 | kgdb_initial_breakpoint(); |
1026 | 1054 | ||
1027 | return 0; | 1055 | return 0; |
1028 | } | 1056 | } |
1029 | 1057 | ||
1030 | early_param("kgdbwait", opt_kgdb_wait); | 1058 | early_param("kgdbwait", opt_kgdb_wait); |
kernel/debug/debug_core.h
1 | /* | 1 | /* |
2 | * Created by: Jason Wessel <jason.wessel@windriver.com> | 2 | * Created by: Jason Wessel <jason.wessel@windriver.com> |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. | 4 | * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. |
5 | * | 5 | * |
6 | * This file is licensed under the terms of the GNU General Public | 6 | * This file is licensed under the terms of the GNU General Public |
7 | * License version 2. This program is licensed "as is" without any | 7 | * License version 2. This program is licensed "as is" without any |
8 | * warranty of any kind, whether express or implied. | 8 | * warranty of any kind, whether express or implied. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifndef _DEBUG_CORE_H_ | 11 | #ifndef _DEBUG_CORE_H_ |
12 | #define _DEBUG_CORE_H_ | 12 | #define _DEBUG_CORE_H_ |
13 | /* | 13 | /* |
14 | * These are the private implementation headers between the kernel | 14 | * These are the private implementation headers between the kernel |
15 | * debugger core and the debugger front end code. | 15 | * debugger core and the debugger front end code. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | /* kernel debug core data structures */ | 18 | /* kernel debug core data structures */ |
19 | struct kgdb_state { | 19 | struct kgdb_state { |
20 | int ex_vector; | 20 | int ex_vector; |
21 | int signo; | 21 | int signo; |
22 | int err_code; | 22 | int err_code; |
23 | int cpu; | 23 | int cpu; |
24 | int pass_exception; | 24 | int pass_exception; |
25 | unsigned long thr_query; | 25 | unsigned long thr_query; |
26 | unsigned long threadid; | 26 | unsigned long threadid; |
27 | long kgdb_usethreadid; | 27 | long kgdb_usethreadid; |
28 | struct pt_regs *linux_regs; | 28 | struct pt_regs *linux_regs; |
29 | atomic_t *send_ready; | ||
29 | }; | 30 | }; |
30 | 31 | ||
31 | /* Exception state values */ | 32 | /* Exception state values */ |
32 | #define DCPU_WANT_MASTER 0x1 /* Waiting to become a master kgdb cpu */ | 33 | #define DCPU_WANT_MASTER 0x1 /* Waiting to become a master kgdb cpu */ |
33 | #define DCPU_NEXT_MASTER 0x2 /* Transition from one master cpu to another */ | 34 | #define DCPU_NEXT_MASTER 0x2 /* Transition from one master cpu to another */ |
34 | #define DCPU_IS_SLAVE 0x4 /* Slave cpu enter exception */ | 35 | #define DCPU_IS_SLAVE 0x4 /* Slave cpu enter exception */ |
35 | #define DCPU_SSTEP 0x8 /* CPU is single stepping */ | 36 | #define DCPU_SSTEP 0x8 /* CPU is single stepping */ |
36 | 37 | ||
37 | struct debuggerinfo_struct { | 38 | struct debuggerinfo_struct { |
38 | void *debuggerinfo; | 39 | void *debuggerinfo; |
39 | struct task_struct *task; | 40 | struct task_struct *task; |
40 | int exception_state; | 41 | int exception_state; |
41 | int ret_state; | 42 | int ret_state; |
42 | int irq_depth; | 43 | int irq_depth; |
43 | int enter_kgdb; | 44 | int enter_kgdb; |
44 | }; | 45 | }; |
45 | 46 | ||
46 | extern struct debuggerinfo_struct kgdb_info[]; | 47 | extern struct debuggerinfo_struct kgdb_info[]; |
47 | 48 | ||
48 | /* kernel debug core break point routines */ | 49 | /* kernel debug core break point routines */ |
49 | extern int dbg_remove_all_break(void); | 50 | extern int dbg_remove_all_break(void); |
50 | extern int dbg_set_sw_break(unsigned long addr); | 51 | extern int dbg_set_sw_break(unsigned long addr); |
51 | extern int dbg_remove_sw_break(unsigned long addr); | 52 | extern int dbg_remove_sw_break(unsigned long addr); |
52 | extern int dbg_activate_sw_breakpoints(void); | 53 | extern int dbg_activate_sw_breakpoints(void); |
53 | extern int dbg_deactivate_sw_breakpoints(void); | 54 | extern int dbg_deactivate_sw_breakpoints(void); |
54 | 55 | ||
55 | /* polled character access to i/o module */ | 56 | /* polled character access to i/o module */ |
56 | extern int dbg_io_get_char(void); | 57 | extern int dbg_io_get_char(void); |
57 | 58 | ||
58 | /* stub return value for switching between the gdbstub and kdb */ | 59 | /* stub return value for switching between the gdbstub and kdb */ |
59 | #define DBG_PASS_EVENT -12345 | 60 | #define DBG_PASS_EVENT -12345 |
60 | /* Switch from one cpu to another */ | 61 | /* Switch from one cpu to another */ |
61 | #define DBG_SWITCH_CPU_EVENT -123456 | 62 | #define DBG_SWITCH_CPU_EVENT -123456 |
62 | extern int dbg_switch_cpu; | 63 | extern int dbg_switch_cpu; |
63 | 64 | ||
64 | /* gdbstub interface functions */ | 65 | /* gdbstub interface functions */ |
65 | extern int gdb_serial_stub(struct kgdb_state *ks); | 66 | extern int gdb_serial_stub(struct kgdb_state *ks); |
66 | extern void gdbstub_msg_write(const char *s, int len); | 67 | extern void gdbstub_msg_write(const char *s, int len); |
67 | 68 | ||
68 | /* gdbstub functions used for kdb <-> gdbstub transition */ | 69 | /* gdbstub functions used for kdb <-> gdbstub transition */ |
69 | extern int gdbstub_state(struct kgdb_state *ks, char *cmd); | 70 | extern int gdbstub_state(struct kgdb_state *ks, char *cmd); |
70 | extern int dbg_kdb_mode; | 71 | extern int dbg_kdb_mode; |
71 | 72 | ||
72 | #ifdef CONFIG_KGDB_KDB | 73 | #ifdef CONFIG_KGDB_KDB |
73 | extern int kdb_stub(struct kgdb_state *ks); | 74 | extern int kdb_stub(struct kgdb_state *ks); |
74 | extern int kdb_parse(const char *cmdstr); | 75 | extern int kdb_parse(const char *cmdstr); |
75 | extern int kdb_common_init_state(struct kgdb_state *ks); | 76 | extern int kdb_common_init_state(struct kgdb_state *ks); |
76 | extern int kdb_common_deinit_state(void); | 77 | extern int kdb_common_deinit_state(void); |
78 | #define KGDB_KDB_REASON_SYSTEM_NMI KDB_REASON_SYSTEM_NMI | ||
77 | #else /* ! CONFIG_KGDB_KDB */ | 79 | #else /* ! CONFIG_KGDB_KDB */ |
78 | static inline int kdb_stub(struct kgdb_state *ks) | 80 | static inline int kdb_stub(struct kgdb_state *ks) |
79 | { | 81 | { |
80 | return DBG_PASS_EVENT; | 82 | return DBG_PASS_EVENT; |
81 | } | 83 | } |
84 | #define KGDB_KDB_REASON_SYSTEM_NMI 0 | ||
82 | #endif /* CONFIG_KGDB_KDB */ | 85 | #endif /* CONFIG_KGDB_KDB */ |
83 | 86 | ||
84 | #endif /* _DEBUG_CORE_H_ */ | 87 | #endif /* _DEBUG_CORE_H_ */ |
85 | 88 |
kernel/debug/kdb/kdb_debugger.c
1 | /* | 1 | /* |
2 | * Created by: Jason Wessel <jason.wessel@windriver.com> | 2 | * Created by: Jason Wessel <jason.wessel@windriver.com> |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. | 4 | * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. |
5 | * | 5 | * |
6 | * This file is licensed under the terms of the GNU General Public | 6 | * This file is licensed under the terms of the GNU General Public |
7 | * License version 2. This program is licensed "as is" without any | 7 | * License version 2. This program is licensed "as is" without any |
8 | * warranty of any kind, whether express or implied. | 8 | * warranty of any kind, whether express or implied. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/kgdb.h> | 11 | #include <linux/kgdb.h> |
12 | #include <linux/kdb.h> | 12 | #include <linux/kdb.h> |
13 | #include <linux/kdebug.h> | 13 | #include <linux/kdebug.h> |
14 | #include <linux/export.h> | 14 | #include <linux/export.h> |
15 | #include <linux/hardirq.h> | 15 | #include <linux/hardirq.h> |
16 | #include "kdb_private.h" | 16 | #include "kdb_private.h" |
17 | #include "../debug_core.h" | 17 | #include "../debug_core.h" |
18 | 18 | ||
19 | /* | 19 | /* |
20 | * KDB interface to KGDB internals | 20 | * KDB interface to KGDB internals |
21 | */ | 21 | */ |
22 | get_char_func kdb_poll_funcs[] = { | 22 | get_char_func kdb_poll_funcs[] = { |
23 | dbg_io_get_char, | 23 | dbg_io_get_char, |
24 | NULL, | 24 | NULL, |
25 | NULL, | 25 | NULL, |
26 | NULL, | 26 | NULL, |
27 | NULL, | 27 | NULL, |
28 | NULL, | 28 | NULL, |
29 | }; | 29 | }; |
30 | EXPORT_SYMBOL_GPL(kdb_poll_funcs); | 30 | EXPORT_SYMBOL_GPL(kdb_poll_funcs); |
31 | 31 | ||
32 | int kdb_poll_idx = 1; | 32 | int kdb_poll_idx = 1; |
33 | EXPORT_SYMBOL_GPL(kdb_poll_idx); | 33 | EXPORT_SYMBOL_GPL(kdb_poll_idx); |
34 | 34 | ||
35 | static struct kgdb_state *kdb_ks; | 35 | static struct kgdb_state *kdb_ks; |
36 | 36 | ||
37 | int kdb_common_init_state(struct kgdb_state *ks) | 37 | int kdb_common_init_state(struct kgdb_state *ks) |
38 | { | 38 | { |
39 | kdb_initial_cpu = atomic_read(&kgdb_active); | 39 | kdb_initial_cpu = atomic_read(&kgdb_active); |
40 | kdb_current_task = kgdb_info[ks->cpu].task; | 40 | kdb_current_task = kgdb_info[ks->cpu].task; |
41 | kdb_current_regs = kgdb_info[ks->cpu].debuggerinfo; | 41 | kdb_current_regs = kgdb_info[ks->cpu].debuggerinfo; |
42 | return 0; | 42 | return 0; |
43 | } | 43 | } |
44 | 44 | ||
45 | int kdb_common_deinit_state(void) | 45 | int kdb_common_deinit_state(void) |
46 | { | 46 | { |
47 | kdb_initial_cpu = -1; | 47 | kdb_initial_cpu = -1; |
48 | kdb_current_task = NULL; | 48 | kdb_current_task = NULL; |
49 | kdb_current_regs = NULL; | 49 | kdb_current_regs = NULL; |
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
52 | 52 | ||
53 | int kdb_stub(struct kgdb_state *ks) | 53 | int kdb_stub(struct kgdb_state *ks) |
54 | { | 54 | { |
55 | int error = 0; | 55 | int error = 0; |
56 | kdb_bp_t *bp; | 56 | kdb_bp_t *bp; |
57 | unsigned long addr = kgdb_arch_pc(ks->ex_vector, ks->linux_regs); | 57 | unsigned long addr = kgdb_arch_pc(ks->ex_vector, ks->linux_regs); |
58 | kdb_reason_t reason = KDB_REASON_OOPS; | 58 | kdb_reason_t reason = KDB_REASON_OOPS; |
59 | kdb_dbtrap_t db_result = KDB_DB_NOBPT; | 59 | kdb_dbtrap_t db_result = KDB_DB_NOBPT; |
60 | int i; | 60 | int i; |
61 | 61 | ||
62 | kdb_ks = ks; | 62 | kdb_ks = ks; |
63 | if (KDB_STATE(REENTRY)) { | 63 | if (KDB_STATE(REENTRY)) { |
64 | reason = KDB_REASON_SWITCH; | 64 | reason = KDB_REASON_SWITCH; |
65 | KDB_STATE_CLEAR(REENTRY); | 65 | KDB_STATE_CLEAR(REENTRY); |
66 | addr = instruction_pointer(ks->linux_regs); | 66 | addr = instruction_pointer(ks->linux_regs); |
67 | } | 67 | } |
68 | ks->pass_exception = 0; | 68 | ks->pass_exception = 0; |
69 | if (atomic_read(&kgdb_setting_breakpoint)) | 69 | if (atomic_read(&kgdb_setting_breakpoint)) |
70 | reason = KDB_REASON_KEYBOARD; | 70 | reason = KDB_REASON_KEYBOARD; |
71 | 71 | ||
72 | if (in_nmi()) | 72 | if (ks->err_code == KDB_REASON_SYSTEM_NMI && ks->signo == SIGTRAP) |
73 | reason = KDB_REASON_SYSTEM_NMI; | ||
74 | |||
75 | else if (in_nmi()) | ||
73 | reason = KDB_REASON_NMI; | 76 | reason = KDB_REASON_NMI; |
74 | 77 | ||
75 | for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) { | 78 | for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) { |
76 | if ((bp->bp_enabled) && (bp->bp_addr == addr)) { | 79 | if ((bp->bp_enabled) && (bp->bp_addr == addr)) { |
77 | reason = KDB_REASON_BREAK; | 80 | reason = KDB_REASON_BREAK; |
78 | db_result = KDB_DB_BPT; | 81 | db_result = KDB_DB_BPT; |
79 | if (addr != instruction_pointer(ks->linux_regs)) | 82 | if (addr != instruction_pointer(ks->linux_regs)) |
80 | kgdb_arch_set_pc(ks->linux_regs, addr); | 83 | kgdb_arch_set_pc(ks->linux_regs, addr); |
81 | break; | 84 | break; |
82 | } | 85 | } |
83 | } | 86 | } |
84 | if (reason == KDB_REASON_BREAK || reason == KDB_REASON_SWITCH) { | 87 | if (reason == KDB_REASON_BREAK || reason == KDB_REASON_SWITCH) { |
85 | for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) { | 88 | for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) { |
86 | if (bp->bp_free) | 89 | if (bp->bp_free) |
87 | continue; | 90 | continue; |
88 | if (bp->bp_addr == addr) { | 91 | if (bp->bp_addr == addr) { |
89 | bp->bp_delay = 1; | 92 | bp->bp_delay = 1; |
90 | bp->bp_delayed = 1; | 93 | bp->bp_delayed = 1; |
91 | /* | 94 | /* |
92 | * SSBPT is set when the kernel debugger must single step a | 95 | * SSBPT is set when the kernel debugger must single step a |
93 | * task in order to re-establish an instruction breakpoint | 96 | * task in order to re-establish an instruction breakpoint |
94 | * which uses the instruction replacement mechanism. It is | 97 | * which uses the instruction replacement mechanism. It is |
95 | * cleared by any action that removes the need to single-step | 98 | * cleared by any action that removes the need to single-step |
96 | * the breakpoint. | 99 | * the breakpoint. |
97 | */ | 100 | */ |
98 | reason = KDB_REASON_BREAK; | 101 | reason = KDB_REASON_BREAK; |
99 | db_result = KDB_DB_BPT; | 102 | db_result = KDB_DB_BPT; |
100 | KDB_STATE_SET(SSBPT); | 103 | KDB_STATE_SET(SSBPT); |
101 | break; | 104 | break; |
102 | } | 105 | } |
103 | } | 106 | } |
104 | } | 107 | } |
105 | 108 | ||
106 | if (reason != KDB_REASON_BREAK && ks->ex_vector == 0 && | 109 | if (reason != KDB_REASON_BREAK && ks->ex_vector == 0 && |
107 | ks->signo == SIGTRAP) { | 110 | ks->signo == SIGTRAP) { |
108 | reason = KDB_REASON_SSTEP; | 111 | reason = KDB_REASON_SSTEP; |
109 | db_result = KDB_DB_BPT; | 112 | db_result = KDB_DB_BPT; |
110 | } | 113 | } |
111 | /* Set initial kdb state variables */ | 114 | /* Set initial kdb state variables */ |
112 | KDB_STATE_CLEAR(KGDB_TRANS); | 115 | KDB_STATE_CLEAR(KGDB_TRANS); |
113 | kdb_common_init_state(ks); | 116 | kdb_common_init_state(ks); |
114 | /* Remove any breakpoints as needed by kdb and clear single step */ | 117 | /* Remove any breakpoints as needed by kdb and clear single step */ |
115 | kdb_bp_remove(); | 118 | kdb_bp_remove(); |
116 | KDB_STATE_CLEAR(DOING_SS); | 119 | KDB_STATE_CLEAR(DOING_SS); |
117 | KDB_STATE_SET(PAGER); | 120 | KDB_STATE_SET(PAGER); |
118 | /* zero out any offline cpu data */ | 121 | /* zero out any offline cpu data */ |
119 | for_each_present_cpu(i) { | 122 | for_each_present_cpu(i) { |
120 | if (!cpu_online(i)) { | 123 | if (!cpu_online(i)) { |
121 | kgdb_info[i].debuggerinfo = NULL; | 124 | kgdb_info[i].debuggerinfo = NULL; |
122 | kgdb_info[i].task = NULL; | 125 | kgdb_info[i].task = NULL; |
123 | } | 126 | } |
124 | } | 127 | } |
125 | if (ks->err_code == DIE_OOPS || reason == KDB_REASON_OOPS) { | 128 | if (ks->err_code == DIE_OOPS || reason == KDB_REASON_OOPS) { |
126 | ks->pass_exception = 1; | 129 | ks->pass_exception = 1; |
127 | KDB_FLAG_SET(CATASTROPHIC); | 130 | KDB_FLAG_SET(CATASTROPHIC); |
128 | } | 131 | } |
129 | if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) { | 132 | if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) { |
130 | KDB_STATE_CLEAR(SSBPT); | 133 | KDB_STATE_CLEAR(SSBPT); |
131 | KDB_STATE_CLEAR(DOING_SS); | 134 | KDB_STATE_CLEAR(DOING_SS); |
132 | } else { | 135 | } else { |
133 | /* Start kdb main loop */ | 136 | /* Start kdb main loop */ |
134 | error = kdb_main_loop(KDB_REASON_ENTER, reason, | 137 | error = kdb_main_loop(KDB_REASON_ENTER, reason, |
135 | ks->err_code, db_result, ks->linux_regs); | 138 | ks->err_code, db_result, ks->linux_regs); |
136 | } | 139 | } |
137 | /* | 140 | /* |
138 | * Upon exit from the kdb main loop setup break points and restart | 141 | * Upon exit from the kdb main loop setup break points and restart |
139 | * the system based on the requested continue state | 142 | * the system based on the requested continue state |
140 | */ | 143 | */ |
141 | kdb_common_deinit_state(); | 144 | kdb_common_deinit_state(); |
142 | KDB_STATE_CLEAR(PAGER); | 145 | KDB_STATE_CLEAR(PAGER); |
143 | kdbnearsym_cleanup(); | 146 | kdbnearsym_cleanup(); |
144 | if (error == KDB_CMD_KGDB) { | 147 | if (error == KDB_CMD_KGDB) { |
145 | if (KDB_STATE(DOING_KGDB)) | 148 | if (KDB_STATE(DOING_KGDB)) |
146 | KDB_STATE_CLEAR(DOING_KGDB); | 149 | KDB_STATE_CLEAR(DOING_KGDB); |
147 | return DBG_PASS_EVENT; | 150 | return DBG_PASS_EVENT; |
148 | } | 151 | } |
149 | kdb_bp_install(ks->linux_regs); | 152 | kdb_bp_install(ks->linux_regs); |
150 | dbg_activate_sw_breakpoints(); | 153 | dbg_activate_sw_breakpoints(); |
151 | /* Set the exit state to a single step or a continue */ | 154 | /* Set the exit state to a single step or a continue */ |
152 | if (KDB_STATE(DOING_SS)) | 155 | if (KDB_STATE(DOING_SS)) |
153 | gdbstub_state(ks, "s"); | 156 | gdbstub_state(ks, "s"); |
154 | else | 157 | else |
155 | gdbstub_state(ks, "c"); | 158 | gdbstub_state(ks, "c"); |
156 | 159 | ||
157 | KDB_FLAG_CLEAR(CATASTROPHIC); | 160 | KDB_FLAG_CLEAR(CATASTROPHIC); |
158 | 161 | ||
159 | /* Invoke arch specific exception handling prior to system resume */ | 162 | /* Invoke arch specific exception handling prior to system resume */ |
160 | kgdb_info[ks->cpu].ret_state = gdbstub_state(ks, "e"); | 163 | kgdb_info[ks->cpu].ret_state = gdbstub_state(ks, "e"); |
161 | if (ks->pass_exception) | 164 | if (ks->pass_exception) |
162 | kgdb_info[ks->cpu].ret_state = 1; | 165 | kgdb_info[ks->cpu].ret_state = 1; |
163 | if (error == KDB_CMD_CPU) { | 166 | if (error == KDB_CMD_CPU) { |
164 | KDB_STATE_SET(REENTRY); | 167 | KDB_STATE_SET(REENTRY); |
165 | /* | 168 | /* |
166 | * Force clear the single step bit because kdb emulates this | 169 | * Force clear the single step bit because kdb emulates this |
167 | * differently vs the gdbstub | 170 | * differently vs the gdbstub |
168 | */ | 171 | */ |
169 | kgdb_single_step = 0; | 172 | kgdb_single_step = 0; |
170 | dbg_deactivate_sw_breakpoints(); | 173 | dbg_deactivate_sw_breakpoints(); |
171 | return DBG_SWITCH_CPU_EVENT; | 174 | return DBG_SWITCH_CPU_EVENT; |
172 | } | 175 | } |
173 | return kgdb_info[ks->cpu].ret_state; | 176 | return kgdb_info[ks->cpu].ret_state; |
174 | } | 177 | } |
175 | 178 | ||
176 | void kdb_gdb_state_pass(char *buf) | 179 | void kdb_gdb_state_pass(char *buf) |
177 | { | 180 | { |
178 | gdbstub_state(kdb_ks, buf); | 181 | gdbstub_state(kdb_ks, buf); |
179 | } | 182 | } |
180 | 183 |
kernel/debug/kdb/kdb_main.c
1 | /* | 1 | /* |
2 | * Kernel Debugger Architecture Independent Main Code | 2 | * Kernel Debugger Architecture Independent Main Code |
3 | * | 3 | * |
4 | * This file is subject to the terms and conditions of the GNU General Public | 4 | * This file is subject to the terms and conditions of the GNU General Public |
5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 1999-2004 Silicon Graphics, Inc. All Rights Reserved. | 8 | * Copyright (C) 1999-2004 Silicon Graphics, Inc. All Rights Reserved. |
9 | * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com> | 9 | * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com> |
10 | * Xscale (R) modifications copyright (C) 2003 Intel Corporation. | 10 | * Xscale (R) modifications copyright (C) 2003 Intel Corporation. |
11 | * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. | 11 | * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/ctype.h> | 14 | #include <linux/ctype.h> |
15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/kmsg_dump.h> | 17 | #include <linux/kmsg_dump.h> |
18 | #include <linux/reboot.h> | 18 | #include <linux/reboot.h> |
19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
20 | #include <linux/sysrq.h> | 20 | #include <linux/sysrq.h> |
21 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
22 | #include <linux/utsname.h> | 22 | #include <linux/utsname.h> |
23 | #include <linux/vmalloc.h> | 23 | #include <linux/vmalloc.h> |
24 | #include <linux/atomic.h> | 24 | #include <linux/atomic.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/kallsyms.h> | 28 | #include <linux/kallsyms.h> |
29 | #include <linux/kgdb.h> | 29 | #include <linux/kgdb.h> |
30 | #include <linux/kdb.h> | 30 | #include <linux/kdb.h> |
31 | #include <linux/notifier.h> | 31 | #include <linux/notifier.h> |
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
34 | #include <linux/nmi.h> | 34 | #include <linux/nmi.h> |
35 | #include <linux/time.h> | 35 | #include <linux/time.h> |
36 | #include <linux/ptrace.h> | 36 | #include <linux/ptrace.h> |
37 | #include <linux/sysctl.h> | 37 | #include <linux/sysctl.h> |
38 | #include <linux/cpu.h> | 38 | #include <linux/cpu.h> |
39 | #include <linux/kdebug.h> | 39 | #include <linux/kdebug.h> |
40 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
41 | #include <linux/uaccess.h> | 41 | #include <linux/uaccess.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include "kdb_private.h" | 43 | #include "kdb_private.h" |
44 | 44 | ||
45 | #define GREP_LEN 256 | 45 | #define GREP_LEN 256 |
46 | char kdb_grep_string[GREP_LEN]; | 46 | char kdb_grep_string[GREP_LEN]; |
47 | int kdb_grepping_flag; | 47 | int kdb_grepping_flag; |
48 | EXPORT_SYMBOL(kdb_grepping_flag); | 48 | EXPORT_SYMBOL(kdb_grepping_flag); |
49 | int kdb_grep_leading; | 49 | int kdb_grep_leading; |
50 | int kdb_grep_trailing; | 50 | int kdb_grep_trailing; |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * Kernel debugger state flags | 53 | * Kernel debugger state flags |
54 | */ | 54 | */ |
55 | int kdb_flags; | 55 | int kdb_flags; |
56 | atomic_t kdb_event; | 56 | atomic_t kdb_event; |
57 | 57 | ||
58 | /* | 58 | /* |
59 | * kdb_lock protects updates to kdb_initial_cpu. Used to | 59 | * kdb_lock protects updates to kdb_initial_cpu. Used to |
60 | * single thread processors through the kernel debugger. | 60 | * single thread processors through the kernel debugger. |
61 | */ | 61 | */ |
62 | int kdb_initial_cpu = -1; /* cpu number that owns kdb */ | 62 | int kdb_initial_cpu = -1; /* cpu number that owns kdb */ |
63 | int kdb_nextline = 1; | 63 | int kdb_nextline = 1; |
64 | int kdb_state; /* General KDB state */ | 64 | int kdb_state; /* General KDB state */ |
65 | 65 | ||
66 | struct task_struct *kdb_current_task; | 66 | struct task_struct *kdb_current_task; |
67 | EXPORT_SYMBOL(kdb_current_task); | 67 | EXPORT_SYMBOL(kdb_current_task); |
68 | struct pt_regs *kdb_current_regs; | 68 | struct pt_regs *kdb_current_regs; |
69 | 69 | ||
70 | const char *kdb_diemsg; | 70 | const char *kdb_diemsg; |
71 | static int kdb_go_count; | 71 | static int kdb_go_count; |
72 | #ifdef CONFIG_KDB_CONTINUE_CATASTROPHIC | 72 | #ifdef CONFIG_KDB_CONTINUE_CATASTROPHIC |
73 | static unsigned int kdb_continue_catastrophic = | 73 | static unsigned int kdb_continue_catastrophic = |
74 | CONFIG_KDB_CONTINUE_CATASTROPHIC; | 74 | CONFIG_KDB_CONTINUE_CATASTROPHIC; |
75 | #else | 75 | #else |
76 | static unsigned int kdb_continue_catastrophic; | 76 | static unsigned int kdb_continue_catastrophic; |
77 | #endif | 77 | #endif |
78 | 78 | ||
79 | /* kdb_commands describes the available commands. */ | 79 | /* kdb_commands describes the available commands. */ |
80 | static kdbtab_t *kdb_commands; | 80 | static kdbtab_t *kdb_commands; |
81 | #define KDB_BASE_CMD_MAX 50 | 81 | #define KDB_BASE_CMD_MAX 50 |
82 | static int kdb_max_commands = KDB_BASE_CMD_MAX; | 82 | static int kdb_max_commands = KDB_BASE_CMD_MAX; |
83 | static kdbtab_t kdb_base_commands[KDB_BASE_CMD_MAX]; | 83 | static kdbtab_t kdb_base_commands[KDB_BASE_CMD_MAX]; |
84 | #define for_each_kdbcmd(cmd, num) \ | 84 | #define for_each_kdbcmd(cmd, num) \ |
85 | for ((cmd) = kdb_base_commands, (num) = 0; \ | 85 | for ((cmd) = kdb_base_commands, (num) = 0; \ |
86 | num < kdb_max_commands; \ | 86 | num < kdb_max_commands; \ |
87 | num++, num == KDB_BASE_CMD_MAX ? cmd = kdb_commands : cmd++) | 87 | num++, num == KDB_BASE_CMD_MAX ? cmd = kdb_commands : cmd++) |
88 | 88 | ||
89 | typedef struct _kdbmsg { | 89 | typedef struct _kdbmsg { |
90 | int km_diag; /* kdb diagnostic */ | 90 | int km_diag; /* kdb diagnostic */ |
91 | char *km_msg; /* Corresponding message text */ | 91 | char *km_msg; /* Corresponding message text */ |
92 | } kdbmsg_t; | 92 | } kdbmsg_t; |
93 | 93 | ||
94 | #define KDBMSG(msgnum, text) \ | 94 | #define KDBMSG(msgnum, text) \ |
95 | { KDB_##msgnum, text } | 95 | { KDB_##msgnum, text } |
96 | 96 | ||
97 | static kdbmsg_t kdbmsgs[] = { | 97 | static kdbmsg_t kdbmsgs[] = { |
98 | KDBMSG(NOTFOUND, "Command Not Found"), | 98 | KDBMSG(NOTFOUND, "Command Not Found"), |
99 | KDBMSG(ARGCOUNT, "Improper argument count, see usage."), | 99 | KDBMSG(ARGCOUNT, "Improper argument count, see usage."), |
100 | KDBMSG(BADWIDTH, "Illegal value for BYTESPERWORD use 1, 2, 4 or 8, " | 100 | KDBMSG(BADWIDTH, "Illegal value for BYTESPERWORD use 1, 2, 4 or 8, " |
101 | "8 is only allowed on 64 bit systems"), | 101 | "8 is only allowed on 64 bit systems"), |
102 | KDBMSG(BADRADIX, "Illegal value for RADIX use 8, 10 or 16"), | 102 | KDBMSG(BADRADIX, "Illegal value for RADIX use 8, 10 or 16"), |
103 | KDBMSG(NOTENV, "Cannot find environment variable"), | 103 | KDBMSG(NOTENV, "Cannot find environment variable"), |
104 | KDBMSG(NOENVVALUE, "Environment variable should have value"), | 104 | KDBMSG(NOENVVALUE, "Environment variable should have value"), |
105 | KDBMSG(NOTIMP, "Command not implemented"), | 105 | KDBMSG(NOTIMP, "Command not implemented"), |
106 | KDBMSG(ENVFULL, "Environment full"), | 106 | KDBMSG(ENVFULL, "Environment full"), |
107 | KDBMSG(ENVBUFFULL, "Environment buffer full"), | 107 | KDBMSG(ENVBUFFULL, "Environment buffer full"), |
108 | KDBMSG(TOOMANYBPT, "Too many breakpoints defined"), | 108 | KDBMSG(TOOMANYBPT, "Too many breakpoints defined"), |
109 | #ifdef CONFIG_CPU_XSCALE | 109 | #ifdef CONFIG_CPU_XSCALE |
110 | KDBMSG(TOOMANYDBREGS, "More breakpoints than ibcr registers defined"), | 110 | KDBMSG(TOOMANYDBREGS, "More breakpoints than ibcr registers defined"), |
111 | #else | 111 | #else |
112 | KDBMSG(TOOMANYDBREGS, "More breakpoints than db registers defined"), | 112 | KDBMSG(TOOMANYDBREGS, "More breakpoints than db registers defined"), |
113 | #endif | 113 | #endif |
114 | KDBMSG(DUPBPT, "Duplicate breakpoint address"), | 114 | KDBMSG(DUPBPT, "Duplicate breakpoint address"), |
115 | KDBMSG(BPTNOTFOUND, "Breakpoint not found"), | 115 | KDBMSG(BPTNOTFOUND, "Breakpoint not found"), |
116 | KDBMSG(BADMODE, "Invalid IDMODE"), | 116 | KDBMSG(BADMODE, "Invalid IDMODE"), |
117 | KDBMSG(BADINT, "Illegal numeric value"), | 117 | KDBMSG(BADINT, "Illegal numeric value"), |
118 | KDBMSG(INVADDRFMT, "Invalid symbolic address format"), | 118 | KDBMSG(INVADDRFMT, "Invalid symbolic address format"), |
119 | KDBMSG(BADREG, "Invalid register name"), | 119 | KDBMSG(BADREG, "Invalid register name"), |
120 | KDBMSG(BADCPUNUM, "Invalid cpu number"), | 120 | KDBMSG(BADCPUNUM, "Invalid cpu number"), |
121 | KDBMSG(BADLENGTH, "Invalid length field"), | 121 | KDBMSG(BADLENGTH, "Invalid length field"), |
122 | KDBMSG(NOBP, "No Breakpoint exists"), | 122 | KDBMSG(NOBP, "No Breakpoint exists"), |
123 | KDBMSG(BADADDR, "Invalid address"), | 123 | KDBMSG(BADADDR, "Invalid address"), |
124 | }; | 124 | }; |
125 | #undef KDBMSG | 125 | #undef KDBMSG |
126 | 126 | ||
127 | static const int __nkdb_err = ARRAY_SIZE(kdbmsgs); | 127 | static const int __nkdb_err = ARRAY_SIZE(kdbmsgs); |
128 | 128 | ||
129 | 129 | ||
130 | /* | 130 | /* |
131 | * Initial environment. This is all kept static and local to | 131 | * Initial environment. This is all kept static and local to |
132 | * this file. We don't want to rely on the memory allocation | 132 | * this file. We don't want to rely on the memory allocation |
133 | * mechanisms in the kernel, so we use a very limited allocate-only | 133 | * mechanisms in the kernel, so we use a very limited allocate-only |
134 | * heap for new and altered environment variables. The entire | 134 | * heap for new and altered environment variables. The entire |
135 | * environment is limited to a fixed number of entries (add more | 135 | * environment is limited to a fixed number of entries (add more |
136 | * to __env[] if required) and a fixed amount of heap (add more to | 136 | * to __env[] if required) and a fixed amount of heap (add more to |
137 | * KDB_ENVBUFSIZE if required). | 137 | * KDB_ENVBUFSIZE if required). |
138 | */ | 138 | */ |
139 | 139 | ||
140 | static char *__env[] = { | 140 | static char *__env[] = { |
141 | #if defined(CONFIG_SMP) | 141 | #if defined(CONFIG_SMP) |
142 | "PROMPT=[%d]kdb> ", | 142 | "PROMPT=[%d]kdb> ", |
143 | #else | 143 | #else |
144 | "PROMPT=kdb> ", | 144 | "PROMPT=kdb> ", |
145 | #endif | 145 | #endif |
146 | "MOREPROMPT=more> ", | 146 | "MOREPROMPT=more> ", |
147 | "RADIX=16", | 147 | "RADIX=16", |
148 | "MDCOUNT=8", /* lines of md output */ | 148 | "MDCOUNT=8", /* lines of md output */ |
149 | KDB_PLATFORM_ENV, | 149 | KDB_PLATFORM_ENV, |
150 | "DTABCOUNT=30", | 150 | "DTABCOUNT=30", |
151 | "NOSECT=1", | 151 | "NOSECT=1", |
152 | (char *)0, | 152 | (char *)0, |
153 | (char *)0, | 153 | (char *)0, |
154 | (char *)0, | 154 | (char *)0, |
155 | (char *)0, | 155 | (char *)0, |
156 | (char *)0, | 156 | (char *)0, |
157 | (char *)0, | 157 | (char *)0, |
158 | (char *)0, | 158 | (char *)0, |
159 | (char *)0, | 159 | (char *)0, |
160 | (char *)0, | 160 | (char *)0, |
161 | (char *)0, | 161 | (char *)0, |
162 | (char *)0, | 162 | (char *)0, |
163 | (char *)0, | 163 | (char *)0, |
164 | (char *)0, | 164 | (char *)0, |
165 | (char *)0, | 165 | (char *)0, |
166 | (char *)0, | 166 | (char *)0, |
167 | (char *)0, | 167 | (char *)0, |
168 | (char *)0, | 168 | (char *)0, |
169 | (char *)0, | 169 | (char *)0, |
170 | (char *)0, | 170 | (char *)0, |
171 | (char *)0, | 171 | (char *)0, |
172 | (char *)0, | 172 | (char *)0, |
173 | (char *)0, | 173 | (char *)0, |
174 | (char *)0, | 174 | (char *)0, |
175 | (char *)0, | 175 | (char *)0, |
176 | }; | 176 | }; |
177 | 177 | ||
178 | static const int __nenv = ARRAY_SIZE(__env); | 178 | static const int __nenv = ARRAY_SIZE(__env); |
179 | 179 | ||
180 | struct task_struct *kdb_curr_task(int cpu) | 180 | struct task_struct *kdb_curr_task(int cpu) |
181 | { | 181 | { |
182 | struct task_struct *p = curr_task(cpu); | 182 | struct task_struct *p = curr_task(cpu); |
183 | #ifdef _TIF_MCA_INIT | 183 | #ifdef _TIF_MCA_INIT |
184 | if ((task_thread_info(p)->flags & _TIF_MCA_INIT) && KDB_TSK(cpu)) | 184 | if ((task_thread_info(p)->flags & _TIF_MCA_INIT) && KDB_TSK(cpu)) |
185 | p = krp->p; | 185 | p = krp->p; |
186 | #endif | 186 | #endif |
187 | return p; | 187 | return p; |
188 | } | 188 | } |
189 | 189 | ||
190 | /* | 190 | /* |
191 | * kdbgetenv - This function will return the character string value of | 191 | * kdbgetenv - This function will return the character string value of |
192 | * an environment variable. | 192 | * an environment variable. |
193 | * Parameters: | 193 | * Parameters: |
194 | * match A character string representing an environment variable. | 194 | * match A character string representing an environment variable. |
195 | * Returns: | 195 | * Returns: |
196 | * NULL No environment variable matches 'match' | 196 | * NULL No environment variable matches 'match' |
197 | * char* Pointer to string value of environment variable. | 197 | * char* Pointer to string value of environment variable. |
198 | */ | 198 | */ |
199 | char *kdbgetenv(const char *match) | 199 | char *kdbgetenv(const char *match) |
200 | { | 200 | { |
201 | char **ep = __env; | 201 | char **ep = __env; |
202 | int matchlen = strlen(match); | 202 | int matchlen = strlen(match); |
203 | int i; | 203 | int i; |
204 | 204 | ||
205 | for (i = 0; i < __nenv; i++) { | 205 | for (i = 0; i < __nenv; i++) { |
206 | char *e = *ep++; | 206 | char *e = *ep++; |
207 | 207 | ||
208 | if (!e) | 208 | if (!e) |
209 | continue; | 209 | continue; |
210 | 210 | ||
211 | if ((strncmp(match, e, matchlen) == 0) | 211 | if ((strncmp(match, e, matchlen) == 0) |
212 | && ((e[matchlen] == '\0') | 212 | && ((e[matchlen] == '\0') |
213 | || (e[matchlen] == '='))) { | 213 | || (e[matchlen] == '='))) { |
214 | char *cp = strchr(e, '='); | 214 | char *cp = strchr(e, '='); |
215 | return cp ? ++cp : ""; | 215 | return cp ? ++cp : ""; |
216 | } | 216 | } |
217 | } | 217 | } |
218 | return NULL; | 218 | return NULL; |
219 | } | 219 | } |
220 | 220 | ||
221 | /* | 221 | /* |
222 | * kdballocenv - This function is used to allocate bytes for | 222 | * kdballocenv - This function is used to allocate bytes for |
223 | * environment entries. | 223 | * environment entries. |
224 | * Parameters: | 224 | * Parameters: |
225 | * match A character string representing a numeric value | 225 | * match A character string representing a numeric value |
226 | * Outputs: | 226 | * Outputs: |
227 | * *value the unsigned long representation of the env variable 'match' | 227 | * *value the unsigned long representation of the env variable 'match' |
228 | * Returns: | 228 | * Returns: |
229 | * Zero on success, a kdb diagnostic on failure. | 229 | * Zero on success, a kdb diagnostic on failure. |
230 | * Remarks: | 230 | * Remarks: |
231 | * We use a static environment buffer (envbuffer) to hold the values | 231 | * We use a static environment buffer (envbuffer) to hold the values |
232 | * of dynamically generated environment variables (see kdb_set). Buffer | 232 | * of dynamically generated environment variables (see kdb_set). Buffer |
233 | * space once allocated is never free'd, so over time, the amount of space | 233 | * space once allocated is never free'd, so over time, the amount of space |
234 | * (currently 512 bytes) will be exhausted if env variables are changed | 234 | * (currently 512 bytes) will be exhausted if env variables are changed |
235 | * frequently. | 235 | * frequently. |
236 | */ | 236 | */ |
237 | static char *kdballocenv(size_t bytes) | 237 | static char *kdballocenv(size_t bytes) |
238 | { | 238 | { |
239 | #define KDB_ENVBUFSIZE 512 | 239 | #define KDB_ENVBUFSIZE 512 |
240 | static char envbuffer[KDB_ENVBUFSIZE]; | 240 | static char envbuffer[KDB_ENVBUFSIZE]; |
241 | static int envbufsize; | 241 | static int envbufsize; |
242 | char *ep = NULL; | 242 | char *ep = NULL; |
243 | 243 | ||
244 | if ((KDB_ENVBUFSIZE - envbufsize) >= bytes) { | 244 | if ((KDB_ENVBUFSIZE - envbufsize) >= bytes) { |
245 | ep = &envbuffer[envbufsize]; | 245 | ep = &envbuffer[envbufsize]; |
246 | envbufsize += bytes; | 246 | envbufsize += bytes; |
247 | } | 247 | } |
248 | return ep; | 248 | return ep; |
249 | } | 249 | } |
250 | 250 | ||
251 | /* | 251 | /* |
252 | * kdbgetulenv - This function will return the value of an unsigned | 252 | * kdbgetulenv - This function will return the value of an unsigned |
253 | * long-valued environment variable. | 253 | * long-valued environment variable. |
254 | * Parameters: | 254 | * Parameters: |
255 | * match A character string representing a numeric value | 255 | * match A character string representing a numeric value |
256 | * Outputs: | 256 | * Outputs: |
257 | * *value the unsigned long represntation of the env variable 'match' | 257 | * *value the unsigned long represntation of the env variable 'match' |
258 | * Returns: | 258 | * Returns: |
259 | * Zero on success, a kdb diagnostic on failure. | 259 | * Zero on success, a kdb diagnostic on failure. |
260 | */ | 260 | */ |
261 | static int kdbgetulenv(const char *match, unsigned long *value) | 261 | static int kdbgetulenv(const char *match, unsigned long *value) |
262 | { | 262 | { |
263 | char *ep; | 263 | char *ep; |
264 | 264 | ||
265 | ep = kdbgetenv(match); | 265 | ep = kdbgetenv(match); |
266 | if (!ep) | 266 | if (!ep) |
267 | return KDB_NOTENV; | 267 | return KDB_NOTENV; |
268 | if (strlen(ep) == 0) | 268 | if (strlen(ep) == 0) |
269 | return KDB_NOENVVALUE; | 269 | return KDB_NOENVVALUE; |
270 | 270 | ||
271 | *value = simple_strtoul(ep, NULL, 0); | 271 | *value = simple_strtoul(ep, NULL, 0); |
272 | 272 | ||
273 | return 0; | 273 | return 0; |
274 | } | 274 | } |
275 | 275 | ||
276 | /* | 276 | /* |
277 | * kdbgetintenv - This function will return the value of an | 277 | * kdbgetintenv - This function will return the value of an |
278 | * integer-valued environment variable. | 278 | * integer-valued environment variable. |
279 | * Parameters: | 279 | * Parameters: |
280 | * match A character string representing an integer-valued env variable | 280 | * match A character string representing an integer-valued env variable |
281 | * Outputs: | 281 | * Outputs: |
282 | * *value the integer representation of the environment variable 'match' | 282 | * *value the integer representation of the environment variable 'match' |
283 | * Returns: | 283 | * Returns: |
284 | * Zero on success, a kdb diagnostic on failure. | 284 | * Zero on success, a kdb diagnostic on failure. |
285 | */ | 285 | */ |
286 | int kdbgetintenv(const char *match, int *value) | 286 | int kdbgetintenv(const char *match, int *value) |
287 | { | 287 | { |
288 | unsigned long val; | 288 | unsigned long val; |
289 | int diag; | 289 | int diag; |
290 | 290 | ||
291 | diag = kdbgetulenv(match, &val); | 291 | diag = kdbgetulenv(match, &val); |
292 | if (!diag) | 292 | if (!diag) |
293 | *value = (int) val; | 293 | *value = (int) val; |
294 | return diag; | 294 | return diag; |
295 | } | 295 | } |
296 | 296 | ||
297 | /* | 297 | /* |
298 | * kdbgetularg - This function will convert a numeric string into an | 298 | * kdbgetularg - This function will convert a numeric string into an |
299 | * unsigned long value. | 299 | * unsigned long value. |
300 | * Parameters: | 300 | * Parameters: |
301 | * arg A character string representing a numeric value | 301 | * arg A character string representing a numeric value |
302 | * Outputs: | 302 | * Outputs: |
303 | * *value the unsigned long represntation of arg. | 303 | * *value the unsigned long represntation of arg. |
304 | * Returns: | 304 | * Returns: |
305 | * Zero on success, a kdb diagnostic on failure. | 305 | * Zero on success, a kdb diagnostic on failure. |
306 | */ | 306 | */ |
307 | int kdbgetularg(const char *arg, unsigned long *value) | 307 | int kdbgetularg(const char *arg, unsigned long *value) |
308 | { | 308 | { |
309 | char *endp; | 309 | char *endp; |
310 | unsigned long val; | 310 | unsigned long val; |
311 | 311 | ||
312 | val = simple_strtoul(arg, &endp, 0); | 312 | val = simple_strtoul(arg, &endp, 0); |
313 | 313 | ||
314 | if (endp == arg) { | 314 | if (endp == arg) { |
315 | /* | 315 | /* |
316 | * Also try base 16, for us folks too lazy to type the | 316 | * Also try base 16, for us folks too lazy to type the |
317 | * leading 0x... | 317 | * leading 0x... |
318 | */ | 318 | */ |
319 | val = simple_strtoul(arg, &endp, 16); | 319 | val = simple_strtoul(arg, &endp, 16); |
320 | if (endp == arg) | 320 | if (endp == arg) |
321 | return KDB_BADINT; | 321 | return KDB_BADINT; |
322 | } | 322 | } |
323 | 323 | ||
324 | *value = val; | 324 | *value = val; |
325 | 325 | ||
326 | return 0; | 326 | return 0; |
327 | } | 327 | } |
328 | 328 | ||
329 | int kdbgetu64arg(const char *arg, u64 *value) | 329 | int kdbgetu64arg(const char *arg, u64 *value) |
330 | { | 330 | { |
331 | char *endp; | 331 | char *endp; |
332 | u64 val; | 332 | u64 val; |
333 | 333 | ||
334 | val = simple_strtoull(arg, &endp, 0); | 334 | val = simple_strtoull(arg, &endp, 0); |
335 | 335 | ||
336 | if (endp == arg) { | 336 | if (endp == arg) { |
337 | 337 | ||
338 | val = simple_strtoull(arg, &endp, 16); | 338 | val = simple_strtoull(arg, &endp, 16); |
339 | if (endp == arg) | 339 | if (endp == arg) |
340 | return KDB_BADINT; | 340 | return KDB_BADINT; |
341 | } | 341 | } |
342 | 342 | ||
343 | *value = val; | 343 | *value = val; |
344 | 344 | ||
345 | return 0; | 345 | return 0; |
346 | } | 346 | } |
347 | 347 | ||
348 | /* | 348 | /* |
349 | * kdb_set - This function implements the 'set' command. Alter an | 349 | * kdb_set - This function implements the 'set' command. Alter an |
350 | * existing environment variable or create a new one. | 350 | * existing environment variable or create a new one. |
351 | */ | 351 | */ |
352 | int kdb_set(int argc, const char **argv) | 352 | int kdb_set(int argc, const char **argv) |
353 | { | 353 | { |
354 | int i; | 354 | int i; |
355 | char *ep; | 355 | char *ep; |
356 | size_t varlen, vallen; | 356 | size_t varlen, vallen; |
357 | 357 | ||
358 | /* | 358 | /* |
359 | * we can be invoked two ways: | 359 | * we can be invoked two ways: |
360 | * set var=value argv[1]="var", argv[2]="value" | 360 | * set var=value argv[1]="var", argv[2]="value" |
361 | * set var = value argv[1]="var", argv[2]="=", argv[3]="value" | 361 | * set var = value argv[1]="var", argv[2]="=", argv[3]="value" |
362 | * - if the latter, shift 'em down. | 362 | * - if the latter, shift 'em down. |
363 | */ | 363 | */ |
364 | if (argc == 3) { | 364 | if (argc == 3) { |
365 | argv[2] = argv[3]; | 365 | argv[2] = argv[3]; |
366 | argc--; | 366 | argc--; |
367 | } | 367 | } |
368 | 368 | ||
369 | if (argc != 2) | 369 | if (argc != 2) |
370 | return KDB_ARGCOUNT; | 370 | return KDB_ARGCOUNT; |
371 | 371 | ||
372 | /* | 372 | /* |
373 | * Check for internal variables | 373 | * Check for internal variables |
374 | */ | 374 | */ |
375 | if (strcmp(argv[1], "KDBDEBUG") == 0) { | 375 | if (strcmp(argv[1], "KDBDEBUG") == 0) { |
376 | unsigned int debugflags; | 376 | unsigned int debugflags; |
377 | char *cp; | 377 | char *cp; |
378 | 378 | ||
379 | debugflags = simple_strtoul(argv[2], &cp, 0); | 379 | debugflags = simple_strtoul(argv[2], &cp, 0); |
380 | if (cp == argv[2] || debugflags & ~KDB_DEBUG_FLAG_MASK) { | 380 | if (cp == argv[2] || debugflags & ~KDB_DEBUG_FLAG_MASK) { |
381 | kdb_printf("kdb: illegal debug flags '%s'\n", | 381 | kdb_printf("kdb: illegal debug flags '%s'\n", |
382 | argv[2]); | 382 | argv[2]); |
383 | return 0; | 383 | return 0; |
384 | } | 384 | } |
385 | kdb_flags = (kdb_flags & | 385 | kdb_flags = (kdb_flags & |
386 | ~(KDB_DEBUG_FLAG_MASK << KDB_DEBUG_FLAG_SHIFT)) | 386 | ~(KDB_DEBUG_FLAG_MASK << KDB_DEBUG_FLAG_SHIFT)) |
387 | | (debugflags << KDB_DEBUG_FLAG_SHIFT); | 387 | | (debugflags << KDB_DEBUG_FLAG_SHIFT); |
388 | 388 | ||
389 | return 0; | 389 | return 0; |
390 | } | 390 | } |
391 | 391 | ||
392 | /* | 392 | /* |
393 | * Tokenizer squashed the '=' sign. argv[1] is variable | 393 | * Tokenizer squashed the '=' sign. argv[1] is variable |
394 | * name, argv[2] = value. | 394 | * name, argv[2] = value. |
395 | */ | 395 | */ |
396 | varlen = strlen(argv[1]); | 396 | varlen = strlen(argv[1]); |
397 | vallen = strlen(argv[2]); | 397 | vallen = strlen(argv[2]); |
398 | ep = kdballocenv(varlen + vallen + 2); | 398 | ep = kdballocenv(varlen + vallen + 2); |
399 | if (ep == (char *)0) | 399 | if (ep == (char *)0) |
400 | return KDB_ENVBUFFULL; | 400 | return KDB_ENVBUFFULL; |
401 | 401 | ||
402 | sprintf(ep, "%s=%s", argv[1], argv[2]); | 402 | sprintf(ep, "%s=%s", argv[1], argv[2]); |
403 | 403 | ||
404 | ep[varlen+vallen+1] = '\0'; | 404 | ep[varlen+vallen+1] = '\0'; |
405 | 405 | ||
406 | for (i = 0; i < __nenv; i++) { | 406 | for (i = 0; i < __nenv; i++) { |
407 | if (__env[i] | 407 | if (__env[i] |
408 | && ((strncmp(__env[i], argv[1], varlen) == 0) | 408 | && ((strncmp(__env[i], argv[1], varlen) == 0) |
409 | && ((__env[i][varlen] == '\0') | 409 | && ((__env[i][varlen] == '\0') |
410 | || (__env[i][varlen] == '=')))) { | 410 | || (__env[i][varlen] == '=')))) { |
411 | __env[i] = ep; | 411 | __env[i] = ep; |
412 | return 0; | 412 | return 0; |
413 | } | 413 | } |
414 | } | 414 | } |
415 | 415 | ||
416 | /* | 416 | /* |
417 | * Wasn't existing variable. Fit into slot. | 417 | * Wasn't existing variable. Fit into slot. |
418 | */ | 418 | */ |
419 | for (i = 0; i < __nenv-1; i++) { | 419 | for (i = 0; i < __nenv-1; i++) { |
420 | if (__env[i] == (char *)0) { | 420 | if (__env[i] == (char *)0) { |
421 | __env[i] = ep; | 421 | __env[i] = ep; |
422 | return 0; | 422 | return 0; |
423 | } | 423 | } |
424 | } | 424 | } |
425 | 425 | ||
426 | return KDB_ENVFULL; | 426 | return KDB_ENVFULL; |
427 | } | 427 | } |
428 | 428 | ||
429 | static int kdb_check_regs(void) | 429 | static int kdb_check_regs(void) |
430 | { | 430 | { |
431 | if (!kdb_current_regs) { | 431 | if (!kdb_current_regs) { |
432 | kdb_printf("No current kdb registers." | 432 | kdb_printf("No current kdb registers." |
433 | " You may need to select another task\n"); | 433 | " You may need to select another task\n"); |
434 | return KDB_BADREG; | 434 | return KDB_BADREG; |
435 | } | 435 | } |
436 | return 0; | 436 | return 0; |
437 | } | 437 | } |
438 | 438 | ||
439 | /* | 439 | /* |
440 | * kdbgetaddrarg - This function is responsible for parsing an | 440 | * kdbgetaddrarg - This function is responsible for parsing an |
441 | * address-expression and returning the value of the expression, | 441 | * address-expression and returning the value of the expression, |
442 | * symbol name, and offset to the caller. | 442 | * symbol name, and offset to the caller. |
443 | * | 443 | * |
444 | * The argument may consist of a numeric value (decimal or | 444 | * The argument may consist of a numeric value (decimal or |
445 | * hexidecimal), a symbol name, a register name (preceded by the | 445 | * hexidecimal), a symbol name, a register name (preceded by the |
446 | * percent sign), an environment variable with a numeric value | 446 | * percent sign), an environment variable with a numeric value |
447 | * (preceded by a dollar sign) or a simple arithmetic expression | 447 | * (preceded by a dollar sign) or a simple arithmetic expression |
448 | * consisting of a symbol name, +/-, and a numeric constant value | 448 | * consisting of a symbol name, +/-, and a numeric constant value |
449 | * (offset). | 449 | * (offset). |
450 | * Parameters: | 450 | * Parameters: |
451 | * argc - count of arguments in argv | 451 | * argc - count of arguments in argv |
452 | * argv - argument vector | 452 | * argv - argument vector |
453 | * *nextarg - index to next unparsed argument in argv[] | 453 | * *nextarg - index to next unparsed argument in argv[] |
454 | * regs - Register state at time of KDB entry | 454 | * regs - Register state at time of KDB entry |
455 | * Outputs: | 455 | * Outputs: |
456 | * *value - receives the value of the address-expression | 456 | * *value - receives the value of the address-expression |
457 | * *offset - receives the offset specified, if any | 457 | * *offset - receives the offset specified, if any |
458 | * *name - receives the symbol name, if any | 458 | * *name - receives the symbol name, if any |
459 | * *nextarg - index to next unparsed argument in argv[] | 459 | * *nextarg - index to next unparsed argument in argv[] |
460 | * Returns: | 460 | * Returns: |
461 | * zero is returned on success, a kdb diagnostic code is | 461 | * zero is returned on success, a kdb diagnostic code is |
462 | * returned on error. | 462 | * returned on error. |
463 | */ | 463 | */ |
464 | int kdbgetaddrarg(int argc, const char **argv, int *nextarg, | 464 | int kdbgetaddrarg(int argc, const char **argv, int *nextarg, |
465 | unsigned long *value, long *offset, | 465 | unsigned long *value, long *offset, |
466 | char **name) | 466 | char **name) |
467 | { | 467 | { |
468 | unsigned long addr; | 468 | unsigned long addr; |
469 | unsigned long off = 0; | 469 | unsigned long off = 0; |
470 | int positive; | 470 | int positive; |
471 | int diag; | 471 | int diag; |
472 | int found = 0; | 472 | int found = 0; |
473 | char *symname; | 473 | char *symname; |
474 | char symbol = '\0'; | 474 | char symbol = '\0'; |
475 | char *cp; | 475 | char *cp; |
476 | kdb_symtab_t symtab; | 476 | kdb_symtab_t symtab; |
477 | 477 | ||
478 | /* | 478 | /* |
479 | * Process arguments which follow the following syntax: | 479 | * Process arguments which follow the following syntax: |
480 | * | 480 | * |
481 | * symbol | numeric-address [+/- numeric-offset] | 481 | * symbol | numeric-address [+/- numeric-offset] |
482 | * %register | 482 | * %register |
483 | * $environment-variable | 483 | * $environment-variable |
484 | */ | 484 | */ |
485 | 485 | ||
486 | if (*nextarg > argc) | 486 | if (*nextarg > argc) |
487 | return KDB_ARGCOUNT; | 487 | return KDB_ARGCOUNT; |
488 | 488 | ||
489 | symname = (char *)argv[*nextarg]; | 489 | symname = (char *)argv[*nextarg]; |
490 | 490 | ||
491 | /* | 491 | /* |
492 | * If there is no whitespace between the symbol | 492 | * If there is no whitespace between the symbol |
493 | * or address and the '+' or '-' symbols, we | 493 | * or address and the '+' or '-' symbols, we |
494 | * remember the character and replace it with a | 494 | * remember the character and replace it with a |
495 | * null so the symbol/value can be properly parsed | 495 | * null so the symbol/value can be properly parsed |
496 | */ | 496 | */ |
497 | cp = strpbrk(symname, "+-"); | 497 | cp = strpbrk(symname, "+-"); |
498 | if (cp != NULL) { | 498 | if (cp != NULL) { |
499 | symbol = *cp; | 499 | symbol = *cp; |
500 | *cp++ = '\0'; | 500 | *cp++ = '\0'; |
501 | } | 501 | } |
502 | 502 | ||
503 | if (symname[0] == '$') { | 503 | if (symname[0] == '$') { |
504 | diag = kdbgetulenv(&symname[1], &addr); | 504 | diag = kdbgetulenv(&symname[1], &addr); |
505 | if (diag) | 505 | if (diag) |
506 | return diag; | 506 | return diag; |
507 | } else if (symname[0] == '%') { | 507 | } else if (symname[0] == '%') { |
508 | diag = kdb_check_regs(); | 508 | diag = kdb_check_regs(); |
509 | if (diag) | 509 | if (diag) |
510 | return diag; | 510 | return diag; |
511 | /* Implement register values with % at a later time as it is | 511 | /* Implement register values with % at a later time as it is |
512 | * arch optional. | 512 | * arch optional. |
513 | */ | 513 | */ |
514 | return KDB_NOTIMP; | 514 | return KDB_NOTIMP; |
515 | } else { | 515 | } else { |
516 | found = kdbgetsymval(symname, &symtab); | 516 | found = kdbgetsymval(symname, &symtab); |
517 | if (found) { | 517 | if (found) { |
518 | addr = symtab.sym_start; | 518 | addr = symtab.sym_start; |
519 | } else { | 519 | } else { |
520 | diag = kdbgetularg(argv[*nextarg], &addr); | 520 | diag = kdbgetularg(argv[*nextarg], &addr); |
521 | if (diag) | 521 | if (diag) |
522 | return diag; | 522 | return diag; |
523 | } | 523 | } |
524 | } | 524 | } |
525 | 525 | ||
526 | if (!found) | 526 | if (!found) |
527 | found = kdbnearsym(addr, &symtab); | 527 | found = kdbnearsym(addr, &symtab); |
528 | 528 | ||
529 | (*nextarg)++; | 529 | (*nextarg)++; |
530 | 530 | ||
531 | if (name) | 531 | if (name) |
532 | *name = symname; | 532 | *name = symname; |
533 | if (value) | 533 | if (value) |
534 | *value = addr; | 534 | *value = addr; |
535 | if (offset && name && *name) | 535 | if (offset && name && *name) |
536 | *offset = addr - symtab.sym_start; | 536 | *offset = addr - symtab.sym_start; |
537 | 537 | ||
538 | if ((*nextarg > argc) | 538 | if ((*nextarg > argc) |
539 | && (symbol == '\0')) | 539 | && (symbol == '\0')) |
540 | return 0; | 540 | return 0; |
541 | 541 | ||
542 | /* | 542 | /* |
543 | * check for +/- and offset | 543 | * check for +/- and offset |
544 | */ | 544 | */ |
545 | 545 | ||
546 | if (symbol == '\0') { | 546 | if (symbol == '\0') { |
547 | if ((argv[*nextarg][0] != '+') | 547 | if ((argv[*nextarg][0] != '+') |
548 | && (argv[*nextarg][0] != '-')) { | 548 | && (argv[*nextarg][0] != '-')) { |
549 | /* | 549 | /* |
550 | * Not our argument. Return. | 550 | * Not our argument. Return. |
551 | */ | 551 | */ |
552 | return 0; | 552 | return 0; |
553 | } else { | 553 | } else { |
554 | positive = (argv[*nextarg][0] == '+'); | 554 | positive = (argv[*nextarg][0] == '+'); |
555 | (*nextarg)++; | 555 | (*nextarg)++; |
556 | } | 556 | } |
557 | } else | 557 | } else |
558 | positive = (symbol == '+'); | 558 | positive = (symbol == '+'); |
559 | 559 | ||
560 | /* | 560 | /* |
561 | * Now there must be an offset! | 561 | * Now there must be an offset! |
562 | */ | 562 | */ |
563 | if ((*nextarg > argc) | 563 | if ((*nextarg > argc) |
564 | && (symbol == '\0')) { | 564 | && (symbol == '\0')) { |
565 | return KDB_INVADDRFMT; | 565 | return KDB_INVADDRFMT; |
566 | } | 566 | } |
567 | 567 | ||
568 | if (!symbol) { | 568 | if (!symbol) { |
569 | cp = (char *)argv[*nextarg]; | 569 | cp = (char *)argv[*nextarg]; |
570 | (*nextarg)++; | 570 | (*nextarg)++; |
571 | } | 571 | } |
572 | 572 | ||
573 | diag = kdbgetularg(cp, &off); | 573 | diag = kdbgetularg(cp, &off); |
574 | if (diag) | 574 | if (diag) |
575 | return diag; | 575 | return diag; |
576 | 576 | ||
577 | if (!positive) | 577 | if (!positive) |
578 | off = -off; | 578 | off = -off; |
579 | 579 | ||
580 | if (offset) | 580 | if (offset) |
581 | *offset += off; | 581 | *offset += off; |
582 | 582 | ||
583 | if (value) | 583 | if (value) |
584 | *value += off; | 584 | *value += off; |
585 | 585 | ||
586 | return 0; | 586 | return 0; |
587 | } | 587 | } |
588 | 588 | ||
589 | static void kdb_cmderror(int diag) | 589 | static void kdb_cmderror(int diag) |
590 | { | 590 | { |
591 | int i; | 591 | int i; |
592 | 592 | ||
593 | if (diag >= 0) { | 593 | if (diag >= 0) { |
594 | kdb_printf("no error detected (diagnostic is %d)\n", diag); | 594 | kdb_printf("no error detected (diagnostic is %d)\n", diag); |
595 | return; | 595 | return; |
596 | } | 596 | } |
597 | 597 | ||
598 | for (i = 0; i < __nkdb_err; i++) { | 598 | for (i = 0; i < __nkdb_err; i++) { |
599 | if (kdbmsgs[i].km_diag == diag) { | 599 | if (kdbmsgs[i].km_diag == diag) { |
600 | kdb_printf("diag: %d: %s\n", diag, kdbmsgs[i].km_msg); | 600 | kdb_printf("diag: %d: %s\n", diag, kdbmsgs[i].km_msg); |
601 | return; | 601 | return; |
602 | } | 602 | } |
603 | } | 603 | } |
604 | 604 | ||
605 | kdb_printf("Unknown diag %d\n", -diag); | 605 | kdb_printf("Unknown diag %d\n", -diag); |
606 | } | 606 | } |
607 | 607 | ||
608 | /* | 608 | /* |
609 | * kdb_defcmd, kdb_defcmd2 - This function implements the 'defcmd' | 609 | * kdb_defcmd, kdb_defcmd2 - This function implements the 'defcmd' |
610 | * command which defines one command as a set of other commands, | 610 | * command which defines one command as a set of other commands, |
611 | * terminated by endefcmd. kdb_defcmd processes the initial | 611 | * terminated by endefcmd. kdb_defcmd processes the initial |
612 | * 'defcmd' command, kdb_defcmd2 is invoked from kdb_parse for | 612 | * 'defcmd' command, kdb_defcmd2 is invoked from kdb_parse for |
613 | * the following commands until 'endefcmd'. | 613 | * the following commands until 'endefcmd'. |
614 | * Inputs: | 614 | * Inputs: |
615 | * argc argument count | 615 | * argc argument count |
616 | * argv argument vector | 616 | * argv argument vector |
617 | * Returns: | 617 | * Returns: |
618 | * zero for success, a kdb diagnostic if error | 618 | * zero for success, a kdb diagnostic if error |
619 | */ | 619 | */ |
620 | struct defcmd_set { | 620 | struct defcmd_set { |
621 | int count; | 621 | int count; |
622 | int usable; | 622 | int usable; |
623 | char *name; | 623 | char *name; |
624 | char *usage; | 624 | char *usage; |
625 | char *help; | 625 | char *help; |
626 | char **command; | 626 | char **command; |
627 | }; | 627 | }; |
628 | static struct defcmd_set *defcmd_set; | 628 | static struct defcmd_set *defcmd_set; |
629 | static int defcmd_set_count; | 629 | static int defcmd_set_count; |
630 | static int defcmd_in_progress; | 630 | static int defcmd_in_progress; |
631 | 631 | ||
632 | /* Forward references */ | 632 | /* Forward references */ |
633 | static int kdb_exec_defcmd(int argc, const char **argv); | 633 | static int kdb_exec_defcmd(int argc, const char **argv); |
634 | 634 | ||
635 | static int kdb_defcmd2(const char *cmdstr, const char *argv0) | 635 | static int kdb_defcmd2(const char *cmdstr, const char *argv0) |
636 | { | 636 | { |
637 | struct defcmd_set *s = defcmd_set + defcmd_set_count - 1; | 637 | struct defcmd_set *s = defcmd_set + defcmd_set_count - 1; |
638 | char **save_command = s->command; | 638 | char **save_command = s->command; |
639 | if (strcmp(argv0, "endefcmd") == 0) { | 639 | if (strcmp(argv0, "endefcmd") == 0) { |
640 | defcmd_in_progress = 0; | 640 | defcmd_in_progress = 0; |
641 | if (!s->count) | 641 | if (!s->count) |
642 | s->usable = 0; | 642 | s->usable = 0; |
643 | if (s->usable) | 643 | if (s->usable) |
644 | kdb_register(s->name, kdb_exec_defcmd, | 644 | kdb_register(s->name, kdb_exec_defcmd, |
645 | s->usage, s->help, 0); | 645 | s->usage, s->help, 0); |
646 | return 0; | 646 | return 0; |
647 | } | 647 | } |
648 | if (!s->usable) | 648 | if (!s->usable) |
649 | return KDB_NOTIMP; | 649 | return KDB_NOTIMP; |
650 | s->command = kzalloc((s->count + 1) * sizeof(*(s->command)), GFP_KDB); | 650 | s->command = kzalloc((s->count + 1) * sizeof(*(s->command)), GFP_KDB); |
651 | if (!s->command) { | 651 | if (!s->command) { |
652 | kdb_printf("Could not allocate new kdb_defcmd table for %s\n", | 652 | kdb_printf("Could not allocate new kdb_defcmd table for %s\n", |
653 | cmdstr); | 653 | cmdstr); |
654 | s->usable = 0; | 654 | s->usable = 0; |
655 | return KDB_NOTIMP; | 655 | return KDB_NOTIMP; |
656 | } | 656 | } |
657 | memcpy(s->command, save_command, s->count * sizeof(*(s->command))); | 657 | memcpy(s->command, save_command, s->count * sizeof(*(s->command))); |
658 | s->command[s->count++] = kdb_strdup(cmdstr, GFP_KDB); | 658 | s->command[s->count++] = kdb_strdup(cmdstr, GFP_KDB); |
659 | kfree(save_command); | 659 | kfree(save_command); |
660 | return 0; | 660 | return 0; |
661 | } | 661 | } |
662 | 662 | ||
663 | static int kdb_defcmd(int argc, const char **argv) | 663 | static int kdb_defcmd(int argc, const char **argv) |
664 | { | 664 | { |
665 | struct defcmd_set *save_defcmd_set = defcmd_set, *s; | 665 | struct defcmd_set *save_defcmd_set = defcmd_set, *s; |
666 | if (defcmd_in_progress) { | 666 | if (defcmd_in_progress) { |
667 | kdb_printf("kdb: nested defcmd detected, assuming missing " | 667 | kdb_printf("kdb: nested defcmd detected, assuming missing " |
668 | "endefcmd\n"); | 668 | "endefcmd\n"); |
669 | kdb_defcmd2("endefcmd", "endefcmd"); | 669 | kdb_defcmd2("endefcmd", "endefcmd"); |
670 | } | 670 | } |
671 | if (argc == 0) { | 671 | if (argc == 0) { |
672 | int i; | 672 | int i; |
673 | for (s = defcmd_set; s < defcmd_set + defcmd_set_count; ++s) { | 673 | for (s = defcmd_set; s < defcmd_set + defcmd_set_count; ++s) { |
674 | kdb_printf("defcmd %s \"%s\" \"%s\"\n", s->name, | 674 | kdb_printf("defcmd %s \"%s\" \"%s\"\n", s->name, |
675 | s->usage, s->help); | 675 | s->usage, s->help); |
676 | for (i = 0; i < s->count; ++i) | 676 | for (i = 0; i < s->count; ++i) |
677 | kdb_printf("%s", s->command[i]); | 677 | kdb_printf("%s", s->command[i]); |
678 | kdb_printf("endefcmd\n"); | 678 | kdb_printf("endefcmd\n"); |
679 | } | 679 | } |
680 | return 0; | 680 | return 0; |
681 | } | 681 | } |
682 | if (argc != 3) | 682 | if (argc != 3) |
683 | return KDB_ARGCOUNT; | 683 | return KDB_ARGCOUNT; |
684 | if (in_dbg_master()) { | 684 | if (in_dbg_master()) { |
685 | kdb_printf("Command only available during kdb_init()\n"); | 685 | kdb_printf("Command only available during kdb_init()\n"); |
686 | return KDB_NOTIMP; | 686 | return KDB_NOTIMP; |
687 | } | 687 | } |
688 | defcmd_set = kmalloc((defcmd_set_count + 1) * sizeof(*defcmd_set), | 688 | defcmd_set = kmalloc((defcmd_set_count + 1) * sizeof(*defcmd_set), |
689 | GFP_KDB); | 689 | GFP_KDB); |
690 | if (!defcmd_set) | 690 | if (!defcmd_set) |
691 | goto fail_defcmd; | 691 | goto fail_defcmd; |
692 | memcpy(defcmd_set, save_defcmd_set, | 692 | memcpy(defcmd_set, save_defcmd_set, |
693 | defcmd_set_count * sizeof(*defcmd_set)); | 693 | defcmd_set_count * sizeof(*defcmd_set)); |
694 | s = defcmd_set + defcmd_set_count; | 694 | s = defcmd_set + defcmd_set_count; |
695 | memset(s, 0, sizeof(*s)); | 695 | memset(s, 0, sizeof(*s)); |
696 | s->usable = 1; | 696 | s->usable = 1; |
697 | s->name = kdb_strdup(argv[1], GFP_KDB); | 697 | s->name = kdb_strdup(argv[1], GFP_KDB); |
698 | if (!s->name) | 698 | if (!s->name) |
699 | goto fail_name; | 699 | goto fail_name; |
700 | s->usage = kdb_strdup(argv[2], GFP_KDB); | 700 | s->usage = kdb_strdup(argv[2], GFP_KDB); |
701 | if (!s->usage) | 701 | if (!s->usage) |
702 | goto fail_usage; | 702 | goto fail_usage; |
703 | s->help = kdb_strdup(argv[3], GFP_KDB); | 703 | s->help = kdb_strdup(argv[3], GFP_KDB); |
704 | if (!s->help) | 704 | if (!s->help) |
705 | goto fail_help; | 705 | goto fail_help; |
706 | if (s->usage[0] == '"') { | 706 | if (s->usage[0] == '"') { |
707 | strcpy(s->usage, argv[2]+1); | 707 | strcpy(s->usage, argv[2]+1); |
708 | s->usage[strlen(s->usage)-1] = '\0'; | 708 | s->usage[strlen(s->usage)-1] = '\0'; |
709 | } | 709 | } |
710 | if (s->help[0] == '"') { | 710 | if (s->help[0] == '"') { |
711 | strcpy(s->help, argv[3]+1); | 711 | strcpy(s->help, argv[3]+1); |
712 | s->help[strlen(s->help)-1] = '\0'; | 712 | s->help[strlen(s->help)-1] = '\0'; |
713 | } | 713 | } |
714 | ++defcmd_set_count; | 714 | ++defcmd_set_count; |
715 | defcmd_in_progress = 1; | 715 | defcmd_in_progress = 1; |
716 | kfree(save_defcmd_set); | 716 | kfree(save_defcmd_set); |
717 | return 0; | 717 | return 0; |
718 | fail_help: | 718 | fail_help: |
719 | kfree(s->usage); | 719 | kfree(s->usage); |
720 | fail_usage: | 720 | fail_usage: |
721 | kfree(s->name); | 721 | kfree(s->name); |
722 | fail_name: | 722 | fail_name: |
723 | kfree(defcmd_set); | 723 | kfree(defcmd_set); |
724 | fail_defcmd: | 724 | fail_defcmd: |
725 | kdb_printf("Could not allocate new defcmd_set entry for %s\n", argv[1]); | 725 | kdb_printf("Could not allocate new defcmd_set entry for %s\n", argv[1]); |
726 | defcmd_set = save_defcmd_set; | 726 | defcmd_set = save_defcmd_set; |
727 | return KDB_NOTIMP; | 727 | return KDB_NOTIMP; |
728 | } | 728 | } |
729 | 729 | ||
730 | /* | 730 | /* |
731 | * kdb_exec_defcmd - Execute the set of commands associated with this | 731 | * kdb_exec_defcmd - Execute the set of commands associated with this |
732 | * defcmd name. | 732 | * defcmd name. |
733 | * Inputs: | 733 | * Inputs: |
734 | * argc argument count | 734 | * argc argument count |
735 | * argv argument vector | 735 | * argv argument vector |
736 | * Returns: | 736 | * Returns: |
737 | * zero for success, a kdb diagnostic if error | 737 | * zero for success, a kdb diagnostic if error |
738 | */ | 738 | */ |
739 | static int kdb_exec_defcmd(int argc, const char **argv) | 739 | static int kdb_exec_defcmd(int argc, const char **argv) |
740 | { | 740 | { |
741 | int i, ret; | 741 | int i, ret; |
742 | struct defcmd_set *s; | 742 | struct defcmd_set *s; |
743 | if (argc != 0) | 743 | if (argc != 0) |
744 | return KDB_ARGCOUNT; | 744 | return KDB_ARGCOUNT; |
745 | for (s = defcmd_set, i = 0; i < defcmd_set_count; ++i, ++s) { | 745 | for (s = defcmd_set, i = 0; i < defcmd_set_count; ++i, ++s) { |
746 | if (strcmp(s->name, argv[0]) == 0) | 746 | if (strcmp(s->name, argv[0]) == 0) |
747 | break; | 747 | break; |
748 | } | 748 | } |
749 | if (i == defcmd_set_count) { | 749 | if (i == defcmd_set_count) { |
750 | kdb_printf("kdb_exec_defcmd: could not find commands for %s\n", | 750 | kdb_printf("kdb_exec_defcmd: could not find commands for %s\n", |
751 | argv[0]); | 751 | argv[0]); |
752 | return KDB_NOTIMP; | 752 | return KDB_NOTIMP; |
753 | } | 753 | } |
754 | for (i = 0; i < s->count; ++i) { | 754 | for (i = 0; i < s->count; ++i) { |
755 | /* Recursive use of kdb_parse, do not use argv after | 755 | /* Recursive use of kdb_parse, do not use argv after |
756 | * this point */ | 756 | * this point */ |
757 | argv = NULL; | 757 | argv = NULL; |
758 | kdb_printf("[%s]kdb> %s\n", s->name, s->command[i]); | 758 | kdb_printf("[%s]kdb> %s\n", s->name, s->command[i]); |
759 | ret = kdb_parse(s->command[i]); | 759 | ret = kdb_parse(s->command[i]); |
760 | if (ret) | 760 | if (ret) |
761 | return ret; | 761 | return ret; |
762 | } | 762 | } |
763 | return 0; | 763 | return 0; |
764 | } | 764 | } |
765 | 765 | ||
766 | /* Command history */ | 766 | /* Command history */ |
767 | #define KDB_CMD_HISTORY_COUNT 32 | 767 | #define KDB_CMD_HISTORY_COUNT 32 |
768 | #define CMD_BUFLEN 200 /* kdb_printf: max printline | 768 | #define CMD_BUFLEN 200 /* kdb_printf: max printline |
769 | * size == 256 */ | 769 | * size == 256 */ |
770 | static unsigned int cmd_head, cmd_tail; | 770 | static unsigned int cmd_head, cmd_tail; |
771 | static unsigned int cmdptr; | 771 | static unsigned int cmdptr; |
772 | static char cmd_hist[KDB_CMD_HISTORY_COUNT][CMD_BUFLEN]; | 772 | static char cmd_hist[KDB_CMD_HISTORY_COUNT][CMD_BUFLEN]; |
773 | static char cmd_cur[CMD_BUFLEN]; | 773 | static char cmd_cur[CMD_BUFLEN]; |
774 | 774 | ||
775 | /* | 775 | /* |
776 | * The "str" argument may point to something like | grep xyz | 776 | * The "str" argument may point to something like | grep xyz |
777 | */ | 777 | */ |
778 | static void parse_grep(const char *str) | 778 | static void parse_grep(const char *str) |
779 | { | 779 | { |
780 | int len; | 780 | int len; |
781 | char *cp = (char *)str, *cp2; | 781 | char *cp = (char *)str, *cp2; |
782 | 782 | ||
783 | /* sanity check: we should have been called with the \ first */ | 783 | /* sanity check: we should have been called with the \ first */ |
784 | if (*cp != '|') | 784 | if (*cp != '|') |
785 | return; | 785 | return; |
786 | cp++; | 786 | cp++; |
787 | while (isspace(*cp)) | 787 | while (isspace(*cp)) |
788 | cp++; | 788 | cp++; |
789 | if (strncmp(cp, "grep ", 5)) { | 789 | if (strncmp(cp, "grep ", 5)) { |
790 | kdb_printf("invalid 'pipe', see grephelp\n"); | 790 | kdb_printf("invalid 'pipe', see grephelp\n"); |
791 | return; | 791 | return; |
792 | } | 792 | } |
793 | cp += 5; | 793 | cp += 5; |
794 | while (isspace(*cp)) | 794 | while (isspace(*cp)) |
795 | cp++; | 795 | cp++; |
796 | cp2 = strchr(cp, '\n'); | 796 | cp2 = strchr(cp, '\n'); |
797 | if (cp2) | 797 | if (cp2) |
798 | *cp2 = '\0'; /* remove the trailing newline */ | 798 | *cp2 = '\0'; /* remove the trailing newline */ |
799 | len = strlen(cp); | 799 | len = strlen(cp); |
800 | if (len == 0) { | 800 | if (len == 0) { |
801 | kdb_printf("invalid 'pipe', see grephelp\n"); | 801 | kdb_printf("invalid 'pipe', see grephelp\n"); |
802 | return; | 802 | return; |
803 | } | 803 | } |
804 | /* now cp points to a nonzero length search string */ | 804 | /* now cp points to a nonzero length search string */ |
805 | if (*cp == '"') { | 805 | if (*cp == '"') { |
806 | /* allow it be "x y z" by removing the "'s - there must | 806 | /* allow it be "x y z" by removing the "'s - there must |
807 | be two of them */ | 807 | be two of them */ |
808 | cp++; | 808 | cp++; |
809 | cp2 = strchr(cp, '"'); | 809 | cp2 = strchr(cp, '"'); |
810 | if (!cp2) { | 810 | if (!cp2) { |
811 | kdb_printf("invalid quoted string, see grephelp\n"); | 811 | kdb_printf("invalid quoted string, see grephelp\n"); |
812 | return; | 812 | return; |
813 | } | 813 | } |
814 | *cp2 = '\0'; /* end the string where the 2nd " was */ | 814 | *cp2 = '\0'; /* end the string where the 2nd " was */ |
815 | } | 815 | } |
816 | kdb_grep_leading = 0; | 816 | kdb_grep_leading = 0; |
817 | if (*cp == '^') { | 817 | if (*cp == '^') { |
818 | kdb_grep_leading = 1; | 818 | kdb_grep_leading = 1; |
819 | cp++; | 819 | cp++; |
820 | } | 820 | } |
821 | len = strlen(cp); | 821 | len = strlen(cp); |
822 | kdb_grep_trailing = 0; | 822 | kdb_grep_trailing = 0; |
823 | if (*(cp+len-1) == '$') { | 823 | if (*(cp+len-1) == '$') { |
824 | kdb_grep_trailing = 1; | 824 | kdb_grep_trailing = 1; |
825 | *(cp+len-1) = '\0'; | 825 | *(cp+len-1) = '\0'; |
826 | } | 826 | } |
827 | len = strlen(cp); | 827 | len = strlen(cp); |
828 | if (!len) | 828 | if (!len) |
829 | return; | 829 | return; |
830 | if (len >= GREP_LEN) { | 830 | if (len >= GREP_LEN) { |
831 | kdb_printf("search string too long\n"); | 831 | kdb_printf("search string too long\n"); |
832 | return; | 832 | return; |
833 | } | 833 | } |
834 | strcpy(kdb_grep_string, cp); | 834 | strcpy(kdb_grep_string, cp); |
835 | kdb_grepping_flag++; | 835 | kdb_grepping_flag++; |
836 | return; | 836 | return; |
837 | } | 837 | } |
838 | 838 | ||
839 | /* | 839 | /* |
840 | * kdb_parse - Parse the command line, search the command table for a | 840 | * kdb_parse - Parse the command line, search the command table for a |
841 | * matching command and invoke the command function. This | 841 | * matching command and invoke the command function. This |
842 | * function may be called recursively, if it is, the second call | 842 | * function may be called recursively, if it is, the second call |
843 | * will overwrite argv and cbuf. It is the caller's | 843 | * will overwrite argv and cbuf. It is the caller's |
844 | * responsibility to save their argv if they recursively call | 844 | * responsibility to save their argv if they recursively call |
845 | * kdb_parse(). | 845 | * kdb_parse(). |
846 | * Parameters: | 846 | * Parameters: |
847 | * cmdstr The input command line to be parsed. | 847 | * cmdstr The input command line to be parsed. |
848 | * regs The registers at the time kdb was entered. | 848 | * regs The registers at the time kdb was entered. |
849 | * Returns: | 849 | * Returns: |
850 | * Zero for success, a kdb diagnostic if failure. | 850 | * Zero for success, a kdb diagnostic if failure. |
851 | * Remarks: | 851 | * Remarks: |
852 | * Limited to 20 tokens. | 852 | * Limited to 20 tokens. |
853 | * | 853 | * |
854 | * Real rudimentary tokenization. Basically only whitespace | 854 | * Real rudimentary tokenization. Basically only whitespace |
855 | * is considered a token delimeter (but special consideration | 855 | * is considered a token delimeter (but special consideration |
856 | * is taken of the '=' sign as used by the 'set' command). | 856 | * is taken of the '=' sign as used by the 'set' command). |
857 | * | 857 | * |
858 | * The algorithm used to tokenize the input string relies on | 858 | * The algorithm used to tokenize the input string relies on |
859 | * there being at least one whitespace (or otherwise useless) | 859 | * there being at least one whitespace (or otherwise useless) |
860 | * character between tokens as the character immediately following | 860 | * character between tokens as the character immediately following |
861 | * the token is altered in-place to a null-byte to terminate the | 861 | * the token is altered in-place to a null-byte to terminate the |
862 | * token string. | 862 | * token string. |
863 | */ | 863 | */ |
864 | 864 | ||
865 | #define MAXARGC 20 | 865 | #define MAXARGC 20 |
866 | 866 | ||
867 | int kdb_parse(const char *cmdstr) | 867 | int kdb_parse(const char *cmdstr) |
868 | { | 868 | { |
869 | static char *argv[MAXARGC]; | 869 | static char *argv[MAXARGC]; |
870 | static int argc; | 870 | static int argc; |
871 | static char cbuf[CMD_BUFLEN+2]; | 871 | static char cbuf[CMD_BUFLEN+2]; |
872 | char *cp; | 872 | char *cp; |
873 | char *cpp, quoted; | 873 | char *cpp, quoted; |
874 | kdbtab_t *tp; | 874 | kdbtab_t *tp; |
875 | int i, escaped, ignore_errors = 0, check_grep; | 875 | int i, escaped, ignore_errors = 0, check_grep; |
876 | 876 | ||
877 | /* | 877 | /* |
878 | * First tokenize the command string. | 878 | * First tokenize the command string. |
879 | */ | 879 | */ |
880 | cp = (char *)cmdstr; | 880 | cp = (char *)cmdstr; |
881 | kdb_grepping_flag = check_grep = 0; | 881 | kdb_grepping_flag = check_grep = 0; |
882 | 882 | ||
883 | if (KDB_FLAG(CMD_INTERRUPT)) { | 883 | if (KDB_FLAG(CMD_INTERRUPT)) { |
884 | /* Previous command was interrupted, newline must not | 884 | /* Previous command was interrupted, newline must not |
885 | * repeat the command */ | 885 | * repeat the command */ |
886 | KDB_FLAG_CLEAR(CMD_INTERRUPT); | 886 | KDB_FLAG_CLEAR(CMD_INTERRUPT); |
887 | KDB_STATE_SET(PAGER); | 887 | KDB_STATE_SET(PAGER); |
888 | argc = 0; /* no repeat */ | 888 | argc = 0; /* no repeat */ |
889 | } | 889 | } |
890 | 890 | ||
891 | if (*cp != '\n' && *cp != '\0') { | 891 | if (*cp != '\n' && *cp != '\0') { |
892 | argc = 0; | 892 | argc = 0; |
893 | cpp = cbuf; | 893 | cpp = cbuf; |
894 | while (*cp) { | 894 | while (*cp) { |
895 | /* skip whitespace */ | 895 | /* skip whitespace */ |
896 | while (isspace(*cp)) | 896 | while (isspace(*cp)) |
897 | cp++; | 897 | cp++; |
898 | if ((*cp == '\0') || (*cp == '\n') || | 898 | if ((*cp == '\0') || (*cp == '\n') || |
899 | (*cp == '#' && !defcmd_in_progress)) | 899 | (*cp == '#' && !defcmd_in_progress)) |
900 | break; | 900 | break; |
901 | /* special case: check for | grep pattern */ | 901 | /* special case: check for | grep pattern */ |
902 | if (*cp == '|') { | 902 | if (*cp == '|') { |
903 | check_grep++; | 903 | check_grep++; |
904 | break; | 904 | break; |
905 | } | 905 | } |
906 | if (cpp >= cbuf + CMD_BUFLEN) { | 906 | if (cpp >= cbuf + CMD_BUFLEN) { |
907 | kdb_printf("kdb_parse: command buffer " | 907 | kdb_printf("kdb_parse: command buffer " |
908 | "overflow, command ignored\n%s\n", | 908 | "overflow, command ignored\n%s\n", |
909 | cmdstr); | 909 | cmdstr); |
910 | return KDB_NOTFOUND; | 910 | return KDB_NOTFOUND; |
911 | } | 911 | } |
912 | if (argc >= MAXARGC - 1) { | 912 | if (argc >= MAXARGC - 1) { |
913 | kdb_printf("kdb_parse: too many arguments, " | 913 | kdb_printf("kdb_parse: too many arguments, " |
914 | "command ignored\n%s\n", cmdstr); | 914 | "command ignored\n%s\n", cmdstr); |
915 | return KDB_NOTFOUND; | 915 | return KDB_NOTFOUND; |
916 | } | 916 | } |
917 | argv[argc++] = cpp; | 917 | argv[argc++] = cpp; |
918 | escaped = 0; | 918 | escaped = 0; |
919 | quoted = '\0'; | 919 | quoted = '\0'; |
920 | /* Copy to next unquoted and unescaped | 920 | /* Copy to next unquoted and unescaped |
921 | * whitespace or '=' */ | 921 | * whitespace or '=' */ |
922 | while (*cp && *cp != '\n' && | 922 | while (*cp && *cp != '\n' && |
923 | (escaped || quoted || !isspace(*cp))) { | 923 | (escaped || quoted || !isspace(*cp))) { |
924 | if (cpp >= cbuf + CMD_BUFLEN) | 924 | if (cpp >= cbuf + CMD_BUFLEN) |
925 | break; | 925 | break; |
926 | if (escaped) { | 926 | if (escaped) { |
927 | escaped = 0; | 927 | escaped = 0; |
928 | *cpp++ = *cp++; | 928 | *cpp++ = *cp++; |
929 | continue; | 929 | continue; |
930 | } | 930 | } |
931 | if (*cp == '\\') { | 931 | if (*cp == '\\') { |
932 | escaped = 1; | 932 | escaped = 1; |
933 | ++cp; | 933 | ++cp; |
934 | continue; | 934 | continue; |
935 | } | 935 | } |
936 | if (*cp == quoted) | 936 | if (*cp == quoted) |
937 | quoted = '\0'; | 937 | quoted = '\0'; |
938 | else if (*cp == '\'' || *cp == '"') | 938 | else if (*cp == '\'' || *cp == '"') |
939 | quoted = *cp; | 939 | quoted = *cp; |
940 | *cpp = *cp++; | 940 | *cpp = *cp++; |
941 | if (*cpp == '=' && !quoted) | 941 | if (*cpp == '=' && !quoted) |
942 | break; | 942 | break; |
943 | ++cpp; | 943 | ++cpp; |
944 | } | 944 | } |
945 | *cpp++ = '\0'; /* Squash a ws or '=' character */ | 945 | *cpp++ = '\0'; /* Squash a ws or '=' character */ |
946 | } | 946 | } |
947 | } | 947 | } |
948 | if (!argc) | 948 | if (!argc) |
949 | return 0; | 949 | return 0; |
950 | if (check_grep) | 950 | if (check_grep) |
951 | parse_grep(cp); | 951 | parse_grep(cp); |
952 | if (defcmd_in_progress) { | 952 | if (defcmd_in_progress) { |
953 | int result = kdb_defcmd2(cmdstr, argv[0]); | 953 | int result = kdb_defcmd2(cmdstr, argv[0]); |
954 | if (!defcmd_in_progress) { | 954 | if (!defcmd_in_progress) { |
955 | argc = 0; /* avoid repeat on endefcmd */ | 955 | argc = 0; /* avoid repeat on endefcmd */ |
956 | *(argv[0]) = '\0'; | 956 | *(argv[0]) = '\0'; |
957 | } | 957 | } |
958 | return result; | 958 | return result; |
959 | } | 959 | } |
960 | if (argv[0][0] == '-' && argv[0][1] && | 960 | if (argv[0][0] == '-' && argv[0][1] && |
961 | (argv[0][1] < '0' || argv[0][1] > '9')) { | 961 | (argv[0][1] < '0' || argv[0][1] > '9')) { |
962 | ignore_errors = 1; | 962 | ignore_errors = 1; |
963 | ++argv[0]; | 963 | ++argv[0]; |
964 | } | 964 | } |
965 | 965 | ||
966 | for_each_kdbcmd(tp, i) { | 966 | for_each_kdbcmd(tp, i) { |
967 | if (tp->cmd_name) { | 967 | if (tp->cmd_name) { |
968 | /* | 968 | /* |
969 | * If this command is allowed to be abbreviated, | 969 | * If this command is allowed to be abbreviated, |
970 | * check to see if this is it. | 970 | * check to see if this is it. |
971 | */ | 971 | */ |
972 | 972 | ||
973 | if (tp->cmd_minlen | 973 | if (tp->cmd_minlen |
974 | && (strlen(argv[0]) <= tp->cmd_minlen)) { | 974 | && (strlen(argv[0]) <= tp->cmd_minlen)) { |
975 | if (strncmp(argv[0], | 975 | if (strncmp(argv[0], |
976 | tp->cmd_name, | 976 | tp->cmd_name, |
977 | tp->cmd_minlen) == 0) { | 977 | tp->cmd_minlen) == 0) { |
978 | break; | 978 | break; |
979 | } | 979 | } |
980 | } | 980 | } |
981 | 981 | ||
982 | if (strcmp(argv[0], tp->cmd_name) == 0) | 982 | if (strcmp(argv[0], tp->cmd_name) == 0) |
983 | break; | 983 | break; |
984 | } | 984 | } |
985 | } | 985 | } |
986 | 986 | ||
987 | /* | 987 | /* |
988 | * If we don't find a command by this name, see if the first | 988 | * If we don't find a command by this name, see if the first |
989 | * few characters of this match any of the known commands. | 989 | * few characters of this match any of the known commands. |
990 | * e.g., md1c20 should match md. | 990 | * e.g., md1c20 should match md. |
991 | */ | 991 | */ |
992 | if (i == kdb_max_commands) { | 992 | if (i == kdb_max_commands) { |
993 | for_each_kdbcmd(tp, i) { | 993 | for_each_kdbcmd(tp, i) { |
994 | if (tp->cmd_name) { | 994 | if (tp->cmd_name) { |
995 | if (strncmp(argv[0], | 995 | if (strncmp(argv[0], |
996 | tp->cmd_name, | 996 | tp->cmd_name, |
997 | strlen(tp->cmd_name)) == 0) { | 997 | strlen(tp->cmd_name)) == 0) { |
998 | break; | 998 | break; |
999 | } | 999 | } |
1000 | } | 1000 | } |
1001 | } | 1001 | } |
1002 | } | 1002 | } |
1003 | 1003 | ||
1004 | if (i < kdb_max_commands) { | 1004 | if (i < kdb_max_commands) { |
1005 | int result; | 1005 | int result; |
1006 | KDB_STATE_SET(CMD); | 1006 | KDB_STATE_SET(CMD); |
1007 | result = (*tp->cmd_func)(argc-1, (const char **)argv); | 1007 | result = (*tp->cmd_func)(argc-1, (const char **)argv); |
1008 | if (result && ignore_errors && result > KDB_CMD_GO) | 1008 | if (result && ignore_errors && result > KDB_CMD_GO) |
1009 | result = 0; | 1009 | result = 0; |
1010 | KDB_STATE_CLEAR(CMD); | 1010 | KDB_STATE_CLEAR(CMD); |
1011 | switch (tp->cmd_repeat) { | 1011 | switch (tp->cmd_repeat) { |
1012 | case KDB_REPEAT_NONE: | 1012 | case KDB_REPEAT_NONE: |
1013 | argc = 0; | 1013 | argc = 0; |
1014 | if (argv[0]) | 1014 | if (argv[0]) |
1015 | *(argv[0]) = '\0'; | 1015 | *(argv[0]) = '\0'; |
1016 | break; | 1016 | break; |
1017 | case KDB_REPEAT_NO_ARGS: | 1017 | case KDB_REPEAT_NO_ARGS: |
1018 | argc = 1; | 1018 | argc = 1; |
1019 | if (argv[1]) | 1019 | if (argv[1]) |
1020 | *(argv[1]) = '\0'; | 1020 | *(argv[1]) = '\0'; |
1021 | break; | 1021 | break; |
1022 | case KDB_REPEAT_WITH_ARGS: | 1022 | case KDB_REPEAT_WITH_ARGS: |
1023 | break; | 1023 | break; |
1024 | } | 1024 | } |
1025 | return result; | 1025 | return result; |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | /* | 1028 | /* |
1029 | * If the input with which we were presented does not | 1029 | * If the input with which we were presented does not |
1030 | * map to an existing command, attempt to parse it as an | 1030 | * map to an existing command, attempt to parse it as an |
1031 | * address argument and display the result. Useful for | 1031 | * address argument and display the result. Useful for |
1032 | * obtaining the address of a variable, or the nearest symbol | 1032 | * obtaining the address of a variable, or the nearest symbol |
1033 | * to an address contained in a register. | 1033 | * to an address contained in a register. |
1034 | */ | 1034 | */ |
1035 | { | 1035 | { |
1036 | unsigned long value; | 1036 | unsigned long value; |
1037 | char *name = NULL; | 1037 | char *name = NULL; |
1038 | long offset; | 1038 | long offset; |
1039 | int nextarg = 0; | 1039 | int nextarg = 0; |
1040 | 1040 | ||
1041 | if (kdbgetaddrarg(0, (const char **)argv, &nextarg, | 1041 | if (kdbgetaddrarg(0, (const char **)argv, &nextarg, |
1042 | &value, &offset, &name)) { | 1042 | &value, &offset, &name)) { |
1043 | return KDB_NOTFOUND; | 1043 | return KDB_NOTFOUND; |
1044 | } | 1044 | } |
1045 | 1045 | ||
1046 | kdb_printf("%s = ", argv[0]); | 1046 | kdb_printf("%s = ", argv[0]); |
1047 | kdb_symbol_print(value, NULL, KDB_SP_DEFAULT); | 1047 | kdb_symbol_print(value, NULL, KDB_SP_DEFAULT); |
1048 | kdb_printf("\n"); | 1048 | kdb_printf("\n"); |
1049 | return 0; | 1049 | return 0; |
1050 | } | 1050 | } |
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | 1053 | ||
1054 | static int handle_ctrl_cmd(char *cmd) | 1054 | static int handle_ctrl_cmd(char *cmd) |
1055 | { | 1055 | { |
1056 | #define CTRL_P 16 | 1056 | #define CTRL_P 16 |
1057 | #define CTRL_N 14 | 1057 | #define CTRL_N 14 |
1058 | 1058 | ||
1059 | /* initial situation */ | 1059 | /* initial situation */ |
1060 | if (cmd_head == cmd_tail) | 1060 | if (cmd_head == cmd_tail) |
1061 | return 0; | 1061 | return 0; |
1062 | switch (*cmd) { | 1062 | switch (*cmd) { |
1063 | case CTRL_P: | 1063 | case CTRL_P: |
1064 | if (cmdptr != cmd_tail) | 1064 | if (cmdptr != cmd_tail) |
1065 | cmdptr = (cmdptr-1) % KDB_CMD_HISTORY_COUNT; | 1065 | cmdptr = (cmdptr-1) % KDB_CMD_HISTORY_COUNT; |
1066 | strncpy(cmd_cur, cmd_hist[cmdptr], CMD_BUFLEN); | 1066 | strncpy(cmd_cur, cmd_hist[cmdptr], CMD_BUFLEN); |
1067 | return 1; | 1067 | return 1; |
1068 | case CTRL_N: | 1068 | case CTRL_N: |
1069 | if (cmdptr != cmd_head) | 1069 | if (cmdptr != cmd_head) |
1070 | cmdptr = (cmdptr+1) % KDB_CMD_HISTORY_COUNT; | 1070 | cmdptr = (cmdptr+1) % KDB_CMD_HISTORY_COUNT; |
1071 | strncpy(cmd_cur, cmd_hist[cmdptr], CMD_BUFLEN); | 1071 | strncpy(cmd_cur, cmd_hist[cmdptr], CMD_BUFLEN); |
1072 | return 1; | 1072 | return 1; |
1073 | } | 1073 | } |
1074 | return 0; | 1074 | return 0; |
1075 | } | 1075 | } |
1076 | 1076 | ||
1077 | /* | 1077 | /* |
1078 | * kdb_reboot - This function implements the 'reboot' command. Reboot | 1078 | * kdb_reboot - This function implements the 'reboot' command. Reboot |
1079 | * the system immediately, or loop for ever on failure. | 1079 | * the system immediately, or loop for ever on failure. |
1080 | */ | 1080 | */ |
1081 | static int kdb_reboot(int argc, const char **argv) | 1081 | static int kdb_reboot(int argc, const char **argv) |
1082 | { | 1082 | { |
1083 | emergency_restart(); | 1083 | emergency_restart(); |
1084 | kdb_printf("Hmm, kdb_reboot did not reboot, spinning here\n"); | 1084 | kdb_printf("Hmm, kdb_reboot did not reboot, spinning here\n"); |
1085 | while (1) | 1085 | while (1) |
1086 | cpu_relax(); | 1086 | cpu_relax(); |
1087 | /* NOTREACHED */ | 1087 | /* NOTREACHED */ |
1088 | return 0; | 1088 | return 0; |
1089 | } | 1089 | } |
1090 | 1090 | ||
1091 | static void kdb_dumpregs(struct pt_regs *regs) | 1091 | static void kdb_dumpregs(struct pt_regs *regs) |
1092 | { | 1092 | { |
1093 | int old_lvl = console_loglevel; | 1093 | int old_lvl = console_loglevel; |
1094 | console_loglevel = 15; | 1094 | console_loglevel = 15; |
1095 | kdb_trap_printk++; | 1095 | kdb_trap_printk++; |
1096 | show_regs(regs); | 1096 | show_regs(regs); |
1097 | kdb_trap_printk--; | 1097 | kdb_trap_printk--; |
1098 | kdb_printf("\n"); | 1098 | kdb_printf("\n"); |
1099 | console_loglevel = old_lvl; | 1099 | console_loglevel = old_lvl; |
1100 | } | 1100 | } |
1101 | 1101 | ||
1102 | void kdb_set_current_task(struct task_struct *p) | 1102 | void kdb_set_current_task(struct task_struct *p) |
1103 | { | 1103 | { |
1104 | kdb_current_task = p; | 1104 | kdb_current_task = p; |
1105 | 1105 | ||
1106 | if (kdb_task_has_cpu(p)) { | 1106 | if (kdb_task_has_cpu(p)) { |
1107 | kdb_current_regs = KDB_TSKREGS(kdb_process_cpu(p)); | 1107 | kdb_current_regs = KDB_TSKREGS(kdb_process_cpu(p)); |
1108 | return; | 1108 | return; |
1109 | } | 1109 | } |
1110 | kdb_current_regs = NULL; | 1110 | kdb_current_regs = NULL; |
1111 | } | 1111 | } |
1112 | 1112 | ||
1113 | /* | 1113 | /* |
1114 | * kdb_local - The main code for kdb. This routine is invoked on a | 1114 | * kdb_local - The main code for kdb. This routine is invoked on a |
1115 | * specific processor, it is not global. The main kdb() routine | 1115 | * specific processor, it is not global. The main kdb() routine |
1116 | * ensures that only one processor at a time is in this routine. | 1116 | * ensures that only one processor at a time is in this routine. |
1117 | * This code is called with the real reason code on the first | 1117 | * This code is called with the real reason code on the first |
1118 | * entry to a kdb session, thereafter it is called with reason | 1118 | * entry to a kdb session, thereafter it is called with reason |
1119 | * SWITCH, even if the user goes back to the original cpu. | 1119 | * SWITCH, even if the user goes back to the original cpu. |
1120 | * Inputs: | 1120 | * Inputs: |
1121 | * reason The reason KDB was invoked | 1121 | * reason The reason KDB was invoked |
1122 | * error The hardware-defined error code | 1122 | * error The hardware-defined error code |
1123 | * regs The exception frame at time of fault/breakpoint. | 1123 | * regs The exception frame at time of fault/breakpoint. |
1124 | * db_result Result code from the break or debug point. | 1124 | * db_result Result code from the break or debug point. |
1125 | * Returns: | 1125 | * Returns: |
1126 | * 0 KDB was invoked for an event which it wasn't responsible | 1126 | * 0 KDB was invoked for an event which it wasn't responsible |
1127 | * 1 KDB handled the event for which it was invoked. | 1127 | * 1 KDB handled the event for which it was invoked. |
1128 | * KDB_CMD_GO User typed 'go'. | 1128 | * KDB_CMD_GO User typed 'go'. |
1129 | * KDB_CMD_CPU User switched to another cpu. | 1129 | * KDB_CMD_CPU User switched to another cpu. |
1130 | * KDB_CMD_SS Single step. | 1130 | * KDB_CMD_SS Single step. |
1131 | */ | 1131 | */ |
1132 | static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, | 1132 | static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, |
1133 | kdb_dbtrap_t db_result) | 1133 | kdb_dbtrap_t db_result) |
1134 | { | 1134 | { |
1135 | char *cmdbuf; | 1135 | char *cmdbuf; |
1136 | int diag; | 1136 | int diag; |
1137 | struct task_struct *kdb_current = | 1137 | struct task_struct *kdb_current = |
1138 | kdb_curr_task(raw_smp_processor_id()); | 1138 | kdb_curr_task(raw_smp_processor_id()); |
1139 | 1139 | ||
1140 | KDB_DEBUG_STATE("kdb_local 1", reason); | 1140 | KDB_DEBUG_STATE("kdb_local 1", reason); |
1141 | kdb_go_count = 0; | 1141 | kdb_go_count = 0; |
1142 | if (reason == KDB_REASON_DEBUG) { | 1142 | if (reason == KDB_REASON_DEBUG) { |
1143 | /* special case below */ | 1143 | /* special case below */ |
1144 | } else { | 1144 | } else { |
1145 | kdb_printf("\nEntering kdb (current=0x%p, pid %d) ", | 1145 | kdb_printf("\nEntering kdb (current=0x%p, pid %d) ", |
1146 | kdb_current, kdb_current ? kdb_current->pid : 0); | 1146 | kdb_current, kdb_current ? kdb_current->pid : 0); |
1147 | #if defined(CONFIG_SMP) | 1147 | #if defined(CONFIG_SMP) |
1148 | kdb_printf("on processor %d ", raw_smp_processor_id()); | 1148 | kdb_printf("on processor %d ", raw_smp_processor_id()); |
1149 | #endif | 1149 | #endif |
1150 | } | 1150 | } |
1151 | 1151 | ||
1152 | switch (reason) { | 1152 | switch (reason) { |
1153 | case KDB_REASON_DEBUG: | 1153 | case KDB_REASON_DEBUG: |
1154 | { | 1154 | { |
1155 | /* | 1155 | /* |
1156 | * If re-entering kdb after a single step | 1156 | * If re-entering kdb after a single step |
1157 | * command, don't print the message. | 1157 | * command, don't print the message. |
1158 | */ | 1158 | */ |
1159 | switch (db_result) { | 1159 | switch (db_result) { |
1160 | case KDB_DB_BPT: | 1160 | case KDB_DB_BPT: |
1161 | kdb_printf("\nEntering kdb (0x%p, pid %d) ", | 1161 | kdb_printf("\nEntering kdb (0x%p, pid %d) ", |
1162 | kdb_current, kdb_current->pid); | 1162 | kdb_current, kdb_current->pid); |
1163 | #if defined(CONFIG_SMP) | 1163 | #if defined(CONFIG_SMP) |
1164 | kdb_printf("on processor %d ", raw_smp_processor_id()); | 1164 | kdb_printf("on processor %d ", raw_smp_processor_id()); |
1165 | #endif | 1165 | #endif |
1166 | kdb_printf("due to Debug @ " kdb_machreg_fmt "\n", | 1166 | kdb_printf("due to Debug @ " kdb_machreg_fmt "\n", |
1167 | instruction_pointer(regs)); | 1167 | instruction_pointer(regs)); |
1168 | break; | 1168 | break; |
1169 | case KDB_DB_SS: | 1169 | case KDB_DB_SS: |
1170 | break; | 1170 | break; |
1171 | case KDB_DB_SSBPT: | 1171 | case KDB_DB_SSBPT: |
1172 | KDB_DEBUG_STATE("kdb_local 4", reason); | 1172 | KDB_DEBUG_STATE("kdb_local 4", reason); |
1173 | return 1; /* kdba_db_trap did the work */ | 1173 | return 1; /* kdba_db_trap did the work */ |
1174 | default: | 1174 | default: |
1175 | kdb_printf("kdb: Bad result from kdba_db_trap: %d\n", | 1175 | kdb_printf("kdb: Bad result from kdba_db_trap: %d\n", |
1176 | db_result); | 1176 | db_result); |
1177 | break; | 1177 | break; |
1178 | } | 1178 | } |
1179 | 1179 | ||
1180 | } | 1180 | } |
1181 | break; | 1181 | break; |
1182 | case KDB_REASON_ENTER: | 1182 | case KDB_REASON_ENTER: |
1183 | if (KDB_STATE(KEYBOARD)) | 1183 | if (KDB_STATE(KEYBOARD)) |
1184 | kdb_printf("due to Keyboard Entry\n"); | 1184 | kdb_printf("due to Keyboard Entry\n"); |
1185 | else | 1185 | else |
1186 | kdb_printf("due to KDB_ENTER()\n"); | 1186 | kdb_printf("due to KDB_ENTER()\n"); |
1187 | break; | 1187 | break; |
1188 | case KDB_REASON_KEYBOARD: | 1188 | case KDB_REASON_KEYBOARD: |
1189 | KDB_STATE_SET(KEYBOARD); | 1189 | KDB_STATE_SET(KEYBOARD); |
1190 | kdb_printf("due to Keyboard Entry\n"); | 1190 | kdb_printf("due to Keyboard Entry\n"); |
1191 | break; | 1191 | break; |
1192 | case KDB_REASON_ENTER_SLAVE: | 1192 | case KDB_REASON_ENTER_SLAVE: |
1193 | /* drop through, slaves only get released via cpu switch */ | 1193 | /* drop through, slaves only get released via cpu switch */ |
1194 | case KDB_REASON_SWITCH: | 1194 | case KDB_REASON_SWITCH: |
1195 | kdb_printf("due to cpu switch\n"); | 1195 | kdb_printf("due to cpu switch\n"); |
1196 | break; | 1196 | break; |
1197 | case KDB_REASON_OOPS: | 1197 | case KDB_REASON_OOPS: |
1198 | kdb_printf("Oops: %s\n", kdb_diemsg); | 1198 | kdb_printf("Oops: %s\n", kdb_diemsg); |
1199 | kdb_printf("due to oops @ " kdb_machreg_fmt "\n", | 1199 | kdb_printf("due to oops @ " kdb_machreg_fmt "\n", |
1200 | instruction_pointer(regs)); | 1200 | instruction_pointer(regs)); |
1201 | kdb_dumpregs(regs); | 1201 | kdb_dumpregs(regs); |
1202 | break; | 1202 | break; |
1203 | case KDB_REASON_SYSTEM_NMI: | ||
1204 | kdb_printf("due to System NonMaskable Interrupt\n"); | ||
1205 | break; | ||
1203 | case KDB_REASON_NMI: | 1206 | case KDB_REASON_NMI: |
1204 | kdb_printf("due to NonMaskable Interrupt @ " | 1207 | kdb_printf("due to NonMaskable Interrupt @ " |
1205 | kdb_machreg_fmt "\n", | 1208 | kdb_machreg_fmt "\n", |
1206 | instruction_pointer(regs)); | 1209 | instruction_pointer(regs)); |
1207 | kdb_dumpregs(regs); | 1210 | kdb_dumpregs(regs); |
1208 | break; | 1211 | break; |
1209 | case KDB_REASON_SSTEP: | 1212 | case KDB_REASON_SSTEP: |
1210 | case KDB_REASON_BREAK: | 1213 | case KDB_REASON_BREAK: |
1211 | kdb_printf("due to %s @ " kdb_machreg_fmt "\n", | 1214 | kdb_printf("due to %s @ " kdb_machreg_fmt "\n", |
1212 | reason == KDB_REASON_BREAK ? | 1215 | reason == KDB_REASON_BREAK ? |
1213 | "Breakpoint" : "SS trap", instruction_pointer(regs)); | 1216 | "Breakpoint" : "SS trap", instruction_pointer(regs)); |
1214 | /* | 1217 | /* |
1215 | * Determine if this breakpoint is one that we | 1218 | * Determine if this breakpoint is one that we |
1216 | * are interested in. | 1219 | * are interested in. |
1217 | */ | 1220 | */ |
1218 | if (db_result != KDB_DB_BPT) { | 1221 | if (db_result != KDB_DB_BPT) { |
1219 | kdb_printf("kdb: error return from kdba_bp_trap: %d\n", | 1222 | kdb_printf("kdb: error return from kdba_bp_trap: %d\n", |
1220 | db_result); | 1223 | db_result); |
1221 | KDB_DEBUG_STATE("kdb_local 6", reason); | 1224 | KDB_DEBUG_STATE("kdb_local 6", reason); |
1222 | return 0; /* Not for us, dismiss it */ | 1225 | return 0; /* Not for us, dismiss it */ |
1223 | } | 1226 | } |
1224 | break; | 1227 | break; |
1225 | case KDB_REASON_RECURSE: | 1228 | case KDB_REASON_RECURSE: |
1226 | kdb_printf("due to Recursion @ " kdb_machreg_fmt "\n", | 1229 | kdb_printf("due to Recursion @ " kdb_machreg_fmt "\n", |
1227 | instruction_pointer(regs)); | 1230 | instruction_pointer(regs)); |
1228 | break; | 1231 | break; |
1229 | default: | 1232 | default: |
1230 | kdb_printf("kdb: unexpected reason code: %d\n", reason); | 1233 | kdb_printf("kdb: unexpected reason code: %d\n", reason); |
1231 | KDB_DEBUG_STATE("kdb_local 8", reason); | 1234 | KDB_DEBUG_STATE("kdb_local 8", reason); |
1232 | return 0; /* Not for us, dismiss it */ | 1235 | return 0; /* Not for us, dismiss it */ |
1233 | } | 1236 | } |
1234 | 1237 | ||
1235 | while (1) { | 1238 | while (1) { |
1236 | /* | 1239 | /* |
1237 | * Initialize pager context. | 1240 | * Initialize pager context. |
1238 | */ | 1241 | */ |
1239 | kdb_nextline = 1; | 1242 | kdb_nextline = 1; |
1240 | KDB_STATE_CLEAR(SUPPRESS); | 1243 | KDB_STATE_CLEAR(SUPPRESS); |
1241 | 1244 | ||
1242 | cmdbuf = cmd_cur; | 1245 | cmdbuf = cmd_cur; |
1243 | *cmdbuf = '\0'; | 1246 | *cmdbuf = '\0'; |
1244 | *(cmd_hist[cmd_head]) = '\0'; | 1247 | *(cmd_hist[cmd_head]) = '\0'; |
1245 | 1248 | ||
1246 | do_full_getstr: | 1249 | do_full_getstr: |
1247 | #if defined(CONFIG_SMP) | 1250 | #if defined(CONFIG_SMP) |
1248 | snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT"), | 1251 | snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT"), |
1249 | raw_smp_processor_id()); | 1252 | raw_smp_processor_id()); |
1250 | #else | 1253 | #else |
1251 | snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT")); | 1254 | snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT")); |
1252 | #endif | 1255 | #endif |
1253 | if (defcmd_in_progress) | 1256 | if (defcmd_in_progress) |
1254 | strncat(kdb_prompt_str, "[defcmd]", CMD_BUFLEN); | 1257 | strncat(kdb_prompt_str, "[defcmd]", CMD_BUFLEN); |
1255 | 1258 | ||
1256 | /* | 1259 | /* |
1257 | * Fetch command from keyboard | 1260 | * Fetch command from keyboard |
1258 | */ | 1261 | */ |
1259 | cmdbuf = kdb_getstr(cmdbuf, CMD_BUFLEN, kdb_prompt_str); | 1262 | cmdbuf = kdb_getstr(cmdbuf, CMD_BUFLEN, kdb_prompt_str); |
1260 | if (*cmdbuf != '\n') { | 1263 | if (*cmdbuf != '\n') { |
1261 | if (*cmdbuf < 32) { | 1264 | if (*cmdbuf < 32) { |
1262 | if (cmdptr == cmd_head) { | 1265 | if (cmdptr == cmd_head) { |
1263 | strncpy(cmd_hist[cmd_head], cmd_cur, | 1266 | strncpy(cmd_hist[cmd_head], cmd_cur, |
1264 | CMD_BUFLEN); | 1267 | CMD_BUFLEN); |
1265 | *(cmd_hist[cmd_head] + | 1268 | *(cmd_hist[cmd_head] + |
1266 | strlen(cmd_hist[cmd_head])-1) = '\0'; | 1269 | strlen(cmd_hist[cmd_head])-1) = '\0'; |
1267 | } | 1270 | } |
1268 | if (!handle_ctrl_cmd(cmdbuf)) | 1271 | if (!handle_ctrl_cmd(cmdbuf)) |
1269 | *(cmd_cur+strlen(cmd_cur)-1) = '\0'; | 1272 | *(cmd_cur+strlen(cmd_cur)-1) = '\0'; |
1270 | cmdbuf = cmd_cur; | 1273 | cmdbuf = cmd_cur; |
1271 | goto do_full_getstr; | 1274 | goto do_full_getstr; |
1272 | } else { | 1275 | } else { |
1273 | strncpy(cmd_hist[cmd_head], cmd_cur, | 1276 | strncpy(cmd_hist[cmd_head], cmd_cur, |
1274 | CMD_BUFLEN); | 1277 | CMD_BUFLEN); |
1275 | } | 1278 | } |
1276 | 1279 | ||
1277 | cmd_head = (cmd_head+1) % KDB_CMD_HISTORY_COUNT; | 1280 | cmd_head = (cmd_head+1) % KDB_CMD_HISTORY_COUNT; |
1278 | if (cmd_head == cmd_tail) | 1281 | if (cmd_head == cmd_tail) |
1279 | cmd_tail = (cmd_tail+1) % KDB_CMD_HISTORY_COUNT; | 1282 | cmd_tail = (cmd_tail+1) % KDB_CMD_HISTORY_COUNT; |
1280 | } | 1283 | } |
1281 | 1284 | ||
1282 | cmdptr = cmd_head; | 1285 | cmdptr = cmd_head; |
1283 | diag = kdb_parse(cmdbuf); | 1286 | diag = kdb_parse(cmdbuf); |
1284 | if (diag == KDB_NOTFOUND) { | 1287 | if (diag == KDB_NOTFOUND) { |
1285 | kdb_printf("Unknown kdb command: '%s'\n", cmdbuf); | 1288 | kdb_printf("Unknown kdb command: '%s'\n", cmdbuf); |
1286 | diag = 0; | 1289 | diag = 0; |
1287 | } | 1290 | } |
1288 | if (diag == KDB_CMD_GO | 1291 | if (diag == KDB_CMD_GO |
1289 | || diag == KDB_CMD_CPU | 1292 | || diag == KDB_CMD_CPU |
1290 | || diag == KDB_CMD_SS | 1293 | || diag == KDB_CMD_SS |
1291 | || diag == KDB_CMD_KGDB) | 1294 | || diag == KDB_CMD_KGDB) |
1292 | break; | 1295 | break; |
1293 | 1296 | ||
1294 | if (diag) | 1297 | if (diag) |
1295 | kdb_cmderror(diag); | 1298 | kdb_cmderror(diag); |
1296 | } | 1299 | } |
1297 | KDB_DEBUG_STATE("kdb_local 9", diag); | 1300 | KDB_DEBUG_STATE("kdb_local 9", diag); |
1298 | return diag; | 1301 | return diag; |
1299 | } | 1302 | } |
1300 | 1303 | ||
1301 | 1304 | ||
1302 | /* | 1305 | /* |
1303 | * kdb_print_state - Print the state data for the current processor | 1306 | * kdb_print_state - Print the state data for the current processor |
1304 | * for debugging. | 1307 | * for debugging. |
1305 | * Inputs: | 1308 | * Inputs: |
1306 | * text Identifies the debug point | 1309 | * text Identifies the debug point |
1307 | * value Any integer value to be printed, e.g. reason code. | 1310 | * value Any integer value to be printed, e.g. reason code. |
1308 | */ | 1311 | */ |
1309 | void kdb_print_state(const char *text, int value) | 1312 | void kdb_print_state(const char *text, int value) |
1310 | { | 1313 | { |
1311 | kdb_printf("state: %s cpu %d value %d initial %d state %x\n", | 1314 | kdb_printf("state: %s cpu %d value %d initial %d state %x\n", |
1312 | text, raw_smp_processor_id(), value, kdb_initial_cpu, | 1315 | text, raw_smp_processor_id(), value, kdb_initial_cpu, |
1313 | kdb_state); | 1316 | kdb_state); |
1314 | } | 1317 | } |
1315 | 1318 | ||
1316 | /* | 1319 | /* |
1317 | * kdb_main_loop - After initial setup and assignment of the | 1320 | * kdb_main_loop - After initial setup and assignment of the |
1318 | * controlling cpu, all cpus are in this loop. One cpu is in | 1321 | * controlling cpu, all cpus are in this loop. One cpu is in |
1319 | * control and will issue the kdb prompt, the others will spin | 1322 | * control and will issue the kdb prompt, the others will spin |
1320 | * until 'go' or cpu switch. | 1323 | * until 'go' or cpu switch. |
1321 | * | 1324 | * |
1322 | * To get a consistent view of the kernel stacks for all | 1325 | * To get a consistent view of the kernel stacks for all |
1323 | * processes, this routine is invoked from the main kdb code via | 1326 | * processes, this routine is invoked from the main kdb code via |
1324 | * an architecture specific routine. kdba_main_loop is | 1327 | * an architecture specific routine. kdba_main_loop is |
1325 | * responsible for making the kernel stacks consistent for all | 1328 | * responsible for making the kernel stacks consistent for all |
1326 | * processes, there should be no difference between a blocked | 1329 | * processes, there should be no difference between a blocked |
1327 | * process and a running process as far as kdb is concerned. | 1330 | * process and a running process as far as kdb is concerned. |
1328 | * Inputs: | 1331 | * Inputs: |
1329 | * reason The reason KDB was invoked | 1332 | * reason The reason KDB was invoked |
1330 | * error The hardware-defined error code | 1333 | * error The hardware-defined error code |
1331 | * reason2 kdb's current reason code. | 1334 | * reason2 kdb's current reason code. |
1332 | * Initially error but can change | 1335 | * Initially error but can change |
1333 | * according to kdb state. | 1336 | * according to kdb state. |
1334 | * db_result Result code from break or debug point. | 1337 | * db_result Result code from break or debug point. |
1335 | * regs The exception frame at time of fault/breakpoint. | 1338 | * regs The exception frame at time of fault/breakpoint. |
1336 | * should always be valid. | 1339 | * should always be valid. |
1337 | * Returns: | 1340 | * Returns: |
1338 | * 0 KDB was invoked for an event which it wasn't responsible | 1341 | * 0 KDB was invoked for an event which it wasn't responsible |
1339 | * 1 KDB handled the event for which it was invoked. | 1342 | * 1 KDB handled the event for which it was invoked. |
1340 | */ | 1343 | */ |
1341 | int kdb_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error, | 1344 | int kdb_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error, |
1342 | kdb_dbtrap_t db_result, struct pt_regs *regs) | 1345 | kdb_dbtrap_t db_result, struct pt_regs *regs) |
1343 | { | 1346 | { |
1344 | int result = 1; | 1347 | int result = 1; |
1345 | /* Stay in kdb() until 'go', 'ss[b]' or an error */ | 1348 | /* Stay in kdb() until 'go', 'ss[b]' or an error */ |
1346 | while (1) { | 1349 | while (1) { |
1347 | /* | 1350 | /* |
1348 | * All processors except the one that is in control | 1351 | * All processors except the one that is in control |
1349 | * will spin here. | 1352 | * will spin here. |
1350 | */ | 1353 | */ |
1351 | KDB_DEBUG_STATE("kdb_main_loop 1", reason); | 1354 | KDB_DEBUG_STATE("kdb_main_loop 1", reason); |
1352 | while (KDB_STATE(HOLD_CPU)) { | 1355 | while (KDB_STATE(HOLD_CPU)) { |
1353 | /* state KDB is turned off by kdb_cpu to see if the | 1356 | /* state KDB is turned off by kdb_cpu to see if the |
1354 | * other cpus are still live, each cpu in this loop | 1357 | * other cpus are still live, each cpu in this loop |
1355 | * turns it back on. | 1358 | * turns it back on. |
1356 | */ | 1359 | */ |
1357 | if (!KDB_STATE(KDB)) | 1360 | if (!KDB_STATE(KDB)) |
1358 | KDB_STATE_SET(KDB); | 1361 | KDB_STATE_SET(KDB); |
1359 | } | 1362 | } |
1360 | 1363 | ||
1361 | KDB_STATE_CLEAR(SUPPRESS); | 1364 | KDB_STATE_CLEAR(SUPPRESS); |
1362 | KDB_DEBUG_STATE("kdb_main_loop 2", reason); | 1365 | KDB_DEBUG_STATE("kdb_main_loop 2", reason); |
1363 | if (KDB_STATE(LEAVING)) | 1366 | if (KDB_STATE(LEAVING)) |
1364 | break; /* Another cpu said 'go' */ | 1367 | break; /* Another cpu said 'go' */ |
1365 | /* Still using kdb, this processor is in control */ | 1368 | /* Still using kdb, this processor is in control */ |
1366 | result = kdb_local(reason2, error, regs, db_result); | 1369 | result = kdb_local(reason2, error, regs, db_result); |
1367 | KDB_DEBUG_STATE("kdb_main_loop 3", result); | 1370 | KDB_DEBUG_STATE("kdb_main_loop 3", result); |
1368 | 1371 | ||
1369 | if (result == KDB_CMD_CPU) | 1372 | if (result == KDB_CMD_CPU) |
1370 | break; | 1373 | break; |
1371 | 1374 | ||
1372 | if (result == KDB_CMD_SS) { | 1375 | if (result == KDB_CMD_SS) { |
1373 | KDB_STATE_SET(DOING_SS); | 1376 | KDB_STATE_SET(DOING_SS); |
1374 | break; | 1377 | break; |
1375 | } | 1378 | } |
1376 | 1379 | ||
1377 | if (result == KDB_CMD_KGDB) { | 1380 | if (result == KDB_CMD_KGDB) { |
1378 | if (!KDB_STATE(DOING_KGDB)) | 1381 | if (!KDB_STATE(DOING_KGDB)) |
1379 | kdb_printf("Entering please attach debugger " | 1382 | kdb_printf("Entering please attach debugger " |
1380 | "or use $D#44+ or $3#33\n"); | 1383 | "or use $D#44+ or $3#33\n"); |
1381 | break; | 1384 | break; |
1382 | } | 1385 | } |
1383 | if (result && result != 1 && result != KDB_CMD_GO) | 1386 | if (result && result != 1 && result != KDB_CMD_GO) |
1384 | kdb_printf("\nUnexpected kdb_local return code %d\n", | 1387 | kdb_printf("\nUnexpected kdb_local return code %d\n", |
1385 | result); | 1388 | result); |
1386 | KDB_DEBUG_STATE("kdb_main_loop 4", reason); | 1389 | KDB_DEBUG_STATE("kdb_main_loop 4", reason); |
1387 | break; | 1390 | break; |
1388 | } | 1391 | } |
1389 | if (KDB_STATE(DOING_SS)) | 1392 | if (KDB_STATE(DOING_SS)) |
1390 | KDB_STATE_CLEAR(SSBPT); | 1393 | KDB_STATE_CLEAR(SSBPT); |
1391 | 1394 | ||
1392 | /* Clean up any keyboard devices before leaving */ | 1395 | /* Clean up any keyboard devices before leaving */ |
1393 | kdb_kbd_cleanup_state(); | 1396 | kdb_kbd_cleanup_state(); |
1394 | 1397 | ||
1395 | return result; | 1398 | return result; |
1396 | } | 1399 | } |
1397 | 1400 | ||
1398 | /* | 1401 | /* |
1399 | * kdb_mdr - This function implements the guts of the 'mdr', memory | 1402 | * kdb_mdr - This function implements the guts of the 'mdr', memory |
1400 | * read command. | 1403 | * read command. |
1401 | * mdr <addr arg>,<byte count> | 1404 | * mdr <addr arg>,<byte count> |
1402 | * Inputs: | 1405 | * Inputs: |
1403 | * addr Start address | 1406 | * addr Start address |
1404 | * count Number of bytes | 1407 | * count Number of bytes |
1405 | * Returns: | 1408 | * Returns: |
1406 | * Always 0. Any errors are detected and printed by kdb_getarea. | 1409 | * Always 0. Any errors are detected and printed by kdb_getarea. |
1407 | */ | 1410 | */ |
1408 | static int kdb_mdr(unsigned long addr, unsigned int count) | 1411 | static int kdb_mdr(unsigned long addr, unsigned int count) |
1409 | { | 1412 | { |
1410 | unsigned char c; | 1413 | unsigned char c; |
1411 | while (count--) { | 1414 | while (count--) { |
1412 | if (kdb_getarea(c, addr)) | 1415 | if (kdb_getarea(c, addr)) |
1413 | return 0; | 1416 | return 0; |
1414 | kdb_printf("%02x", c); | 1417 | kdb_printf("%02x", c); |
1415 | addr++; | 1418 | addr++; |
1416 | } | 1419 | } |
1417 | kdb_printf("\n"); | 1420 | kdb_printf("\n"); |
1418 | return 0; | 1421 | return 0; |
1419 | } | 1422 | } |
1420 | 1423 | ||
1421 | /* | 1424 | /* |
1422 | * kdb_md - This function implements the 'md', 'md1', 'md2', 'md4', | 1425 | * kdb_md - This function implements the 'md', 'md1', 'md2', 'md4', |
1423 | * 'md8' 'mdr' and 'mds' commands. | 1426 | * 'md8' 'mdr' and 'mds' commands. |
1424 | * | 1427 | * |
1425 | * md|mds [<addr arg> [<line count> [<radix>]]] | 1428 | * md|mds [<addr arg> [<line count> [<radix>]]] |
1426 | * mdWcN [<addr arg> [<line count> [<radix>]]] | 1429 | * mdWcN [<addr arg> [<line count> [<radix>]]] |
1427 | * where W = is the width (1, 2, 4 or 8) and N is the count. | 1430 | * where W = is the width (1, 2, 4 or 8) and N is the count. |
1428 | * for eg., md1c20 reads 20 bytes, 1 at a time. | 1431 | * for eg., md1c20 reads 20 bytes, 1 at a time. |
1429 | * mdr <addr arg>,<byte count> | 1432 | * mdr <addr arg>,<byte count> |
1430 | */ | 1433 | */ |
1431 | static void kdb_md_line(const char *fmtstr, unsigned long addr, | 1434 | static void kdb_md_line(const char *fmtstr, unsigned long addr, |
1432 | int symbolic, int nosect, int bytesperword, | 1435 | int symbolic, int nosect, int bytesperword, |
1433 | int num, int repeat, int phys) | 1436 | int num, int repeat, int phys) |
1434 | { | 1437 | { |
1435 | /* print just one line of data */ | 1438 | /* print just one line of data */ |
1436 | kdb_symtab_t symtab; | 1439 | kdb_symtab_t symtab; |
1437 | char cbuf[32]; | 1440 | char cbuf[32]; |
1438 | char *c = cbuf; | 1441 | char *c = cbuf; |
1439 | int i; | 1442 | int i; |
1440 | unsigned long word; | 1443 | unsigned long word; |
1441 | 1444 | ||
1442 | memset(cbuf, '\0', sizeof(cbuf)); | 1445 | memset(cbuf, '\0', sizeof(cbuf)); |
1443 | if (phys) | 1446 | if (phys) |
1444 | kdb_printf("phys " kdb_machreg_fmt0 " ", addr); | 1447 | kdb_printf("phys " kdb_machreg_fmt0 " ", addr); |
1445 | else | 1448 | else |
1446 | kdb_printf(kdb_machreg_fmt0 " ", addr); | 1449 | kdb_printf(kdb_machreg_fmt0 " ", addr); |
1447 | 1450 | ||
1448 | for (i = 0; i < num && repeat--; i++) { | 1451 | for (i = 0; i < num && repeat--; i++) { |
1449 | if (phys) { | 1452 | if (phys) { |
1450 | if (kdb_getphysword(&word, addr, bytesperword)) | 1453 | if (kdb_getphysword(&word, addr, bytesperword)) |
1451 | break; | 1454 | break; |
1452 | } else if (kdb_getword(&word, addr, bytesperword)) | 1455 | } else if (kdb_getword(&word, addr, bytesperword)) |
1453 | break; | 1456 | break; |
1454 | kdb_printf(fmtstr, word); | 1457 | kdb_printf(fmtstr, word); |
1455 | if (symbolic) | 1458 | if (symbolic) |
1456 | kdbnearsym(word, &symtab); | 1459 | kdbnearsym(word, &symtab); |
1457 | else | 1460 | else |
1458 | memset(&symtab, 0, sizeof(symtab)); | 1461 | memset(&symtab, 0, sizeof(symtab)); |
1459 | if (symtab.sym_name) { | 1462 | if (symtab.sym_name) { |
1460 | kdb_symbol_print(word, &symtab, 0); | 1463 | kdb_symbol_print(word, &symtab, 0); |
1461 | if (!nosect) { | 1464 | if (!nosect) { |
1462 | kdb_printf("\n"); | 1465 | kdb_printf("\n"); |
1463 | kdb_printf(" %s %s " | 1466 | kdb_printf(" %s %s " |
1464 | kdb_machreg_fmt " " | 1467 | kdb_machreg_fmt " " |
1465 | kdb_machreg_fmt " " | 1468 | kdb_machreg_fmt " " |
1466 | kdb_machreg_fmt, symtab.mod_name, | 1469 | kdb_machreg_fmt, symtab.mod_name, |
1467 | symtab.sec_name, symtab.sec_start, | 1470 | symtab.sec_name, symtab.sec_start, |
1468 | symtab.sym_start, symtab.sym_end); | 1471 | symtab.sym_start, symtab.sym_end); |
1469 | } | 1472 | } |
1470 | addr += bytesperword; | 1473 | addr += bytesperword; |
1471 | } else { | 1474 | } else { |
1472 | union { | 1475 | union { |
1473 | u64 word; | 1476 | u64 word; |
1474 | unsigned char c[8]; | 1477 | unsigned char c[8]; |
1475 | } wc; | 1478 | } wc; |
1476 | unsigned char *cp; | 1479 | unsigned char *cp; |
1477 | #ifdef __BIG_ENDIAN | 1480 | #ifdef __BIG_ENDIAN |
1478 | cp = wc.c + 8 - bytesperword; | 1481 | cp = wc.c + 8 - bytesperword; |
1479 | #else | 1482 | #else |
1480 | cp = wc.c; | 1483 | cp = wc.c; |
1481 | #endif | 1484 | #endif |
1482 | wc.word = word; | 1485 | wc.word = word; |
1483 | #define printable_char(c) \ | 1486 | #define printable_char(c) \ |
1484 | ({unsigned char __c = c; isascii(__c) && isprint(__c) ? __c : '.'; }) | 1487 | ({unsigned char __c = c; isascii(__c) && isprint(__c) ? __c : '.'; }) |
1485 | switch (bytesperword) { | 1488 | switch (bytesperword) { |
1486 | case 8: | 1489 | case 8: |
1487 | *c++ = printable_char(*cp++); | 1490 | *c++ = printable_char(*cp++); |
1488 | *c++ = printable_char(*cp++); | 1491 | *c++ = printable_char(*cp++); |
1489 | *c++ = printable_char(*cp++); | 1492 | *c++ = printable_char(*cp++); |
1490 | *c++ = printable_char(*cp++); | 1493 | *c++ = printable_char(*cp++); |
1491 | addr += 4; | 1494 | addr += 4; |
1492 | case 4: | 1495 | case 4: |
1493 | *c++ = printable_char(*cp++); | 1496 | *c++ = printable_char(*cp++); |
1494 | *c++ = printable_char(*cp++); | 1497 | *c++ = printable_char(*cp++); |
1495 | addr += 2; | 1498 | addr += 2; |
1496 | case 2: | 1499 | case 2: |
1497 | *c++ = printable_char(*cp++); | 1500 | *c++ = printable_char(*cp++); |
1498 | addr++; | 1501 | addr++; |
1499 | case 1: | 1502 | case 1: |
1500 | *c++ = printable_char(*cp++); | 1503 | *c++ = printable_char(*cp++); |
1501 | addr++; | 1504 | addr++; |
1502 | break; | 1505 | break; |
1503 | } | 1506 | } |
1504 | #undef printable_char | 1507 | #undef printable_char |
1505 | } | 1508 | } |
1506 | } | 1509 | } |
1507 | kdb_printf("%*s %s\n", (int)((num-i)*(2*bytesperword + 1)+1), | 1510 | kdb_printf("%*s %s\n", (int)((num-i)*(2*bytesperword + 1)+1), |
1508 | " ", cbuf); | 1511 | " ", cbuf); |
1509 | } | 1512 | } |
1510 | 1513 | ||
1511 | static int kdb_md(int argc, const char **argv) | 1514 | static int kdb_md(int argc, const char **argv) |
1512 | { | 1515 | { |
1513 | static unsigned long last_addr; | 1516 | static unsigned long last_addr; |
1514 | static int last_radix, last_bytesperword, last_repeat; | 1517 | static int last_radix, last_bytesperword, last_repeat; |
1515 | int radix = 16, mdcount = 8, bytesperword = KDB_WORD_SIZE, repeat; | 1518 | int radix = 16, mdcount = 8, bytesperword = KDB_WORD_SIZE, repeat; |
1516 | int nosect = 0; | 1519 | int nosect = 0; |
1517 | char fmtchar, fmtstr[64]; | 1520 | char fmtchar, fmtstr[64]; |
1518 | unsigned long addr; | 1521 | unsigned long addr; |
1519 | unsigned long word; | 1522 | unsigned long word; |
1520 | long offset = 0; | 1523 | long offset = 0; |
1521 | int symbolic = 0; | 1524 | int symbolic = 0; |
1522 | int valid = 0; | 1525 | int valid = 0; |
1523 | int phys = 0; | 1526 | int phys = 0; |
1524 | 1527 | ||
1525 | kdbgetintenv("MDCOUNT", &mdcount); | 1528 | kdbgetintenv("MDCOUNT", &mdcount); |
1526 | kdbgetintenv("RADIX", &radix); | 1529 | kdbgetintenv("RADIX", &radix); |
1527 | kdbgetintenv("BYTESPERWORD", &bytesperword); | 1530 | kdbgetintenv("BYTESPERWORD", &bytesperword); |
1528 | 1531 | ||
1529 | /* Assume 'md <addr>' and start with environment values */ | 1532 | /* Assume 'md <addr>' and start with environment values */ |
1530 | repeat = mdcount * 16 / bytesperword; | 1533 | repeat = mdcount * 16 / bytesperword; |
1531 | 1534 | ||
1532 | if (strcmp(argv[0], "mdr") == 0) { | 1535 | if (strcmp(argv[0], "mdr") == 0) { |
1533 | if (argc != 2) | 1536 | if (argc != 2) |
1534 | return KDB_ARGCOUNT; | 1537 | return KDB_ARGCOUNT; |
1535 | valid = 1; | 1538 | valid = 1; |
1536 | } else if (isdigit(argv[0][2])) { | 1539 | } else if (isdigit(argv[0][2])) { |
1537 | bytesperword = (int)(argv[0][2] - '0'); | 1540 | bytesperword = (int)(argv[0][2] - '0'); |
1538 | if (bytesperword == 0) { | 1541 | if (bytesperword == 0) { |
1539 | bytesperword = last_bytesperword; | 1542 | bytesperword = last_bytesperword; |
1540 | if (bytesperword == 0) | 1543 | if (bytesperword == 0) |
1541 | bytesperword = 4; | 1544 | bytesperword = 4; |
1542 | } | 1545 | } |
1543 | last_bytesperword = bytesperword; | 1546 | last_bytesperword = bytesperword; |
1544 | repeat = mdcount * 16 / bytesperword; | 1547 | repeat = mdcount * 16 / bytesperword; |
1545 | if (!argv[0][3]) | 1548 | if (!argv[0][3]) |
1546 | valid = 1; | 1549 | valid = 1; |
1547 | else if (argv[0][3] == 'c' && argv[0][4]) { | 1550 | else if (argv[0][3] == 'c' && argv[0][4]) { |
1548 | char *p; | 1551 | char *p; |
1549 | repeat = simple_strtoul(argv[0] + 4, &p, 10); | 1552 | repeat = simple_strtoul(argv[0] + 4, &p, 10); |
1550 | mdcount = ((repeat * bytesperword) + 15) / 16; | 1553 | mdcount = ((repeat * bytesperword) + 15) / 16; |
1551 | valid = !*p; | 1554 | valid = !*p; |
1552 | } | 1555 | } |
1553 | last_repeat = repeat; | 1556 | last_repeat = repeat; |
1554 | } else if (strcmp(argv[0], "md") == 0) | 1557 | } else if (strcmp(argv[0], "md") == 0) |
1555 | valid = 1; | 1558 | valid = 1; |
1556 | else if (strcmp(argv[0], "mds") == 0) | 1559 | else if (strcmp(argv[0], "mds") == 0) |
1557 | valid = 1; | 1560 | valid = 1; |
1558 | else if (strcmp(argv[0], "mdp") == 0) { | 1561 | else if (strcmp(argv[0], "mdp") == 0) { |
1559 | phys = valid = 1; | 1562 | phys = valid = 1; |
1560 | } | 1563 | } |
1561 | if (!valid) | 1564 | if (!valid) |
1562 | return KDB_NOTFOUND; | 1565 | return KDB_NOTFOUND; |
1563 | 1566 | ||
1564 | if (argc == 0) { | 1567 | if (argc == 0) { |
1565 | if (last_addr == 0) | 1568 | if (last_addr == 0) |
1566 | return KDB_ARGCOUNT; | 1569 | return KDB_ARGCOUNT; |
1567 | addr = last_addr; | 1570 | addr = last_addr; |
1568 | radix = last_radix; | 1571 | radix = last_radix; |
1569 | bytesperword = last_bytesperword; | 1572 | bytesperword = last_bytesperword; |
1570 | repeat = last_repeat; | 1573 | repeat = last_repeat; |
1571 | mdcount = ((repeat * bytesperword) + 15) / 16; | 1574 | mdcount = ((repeat * bytesperword) + 15) / 16; |
1572 | } | 1575 | } |
1573 | 1576 | ||
1574 | if (argc) { | 1577 | if (argc) { |
1575 | unsigned long val; | 1578 | unsigned long val; |
1576 | int diag, nextarg = 1; | 1579 | int diag, nextarg = 1; |
1577 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, | 1580 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, |
1578 | &offset, NULL); | 1581 | &offset, NULL); |
1579 | if (diag) | 1582 | if (diag) |
1580 | return diag; | 1583 | return diag; |
1581 | if (argc > nextarg+2) | 1584 | if (argc > nextarg+2) |
1582 | return KDB_ARGCOUNT; | 1585 | return KDB_ARGCOUNT; |
1583 | 1586 | ||
1584 | if (argc >= nextarg) { | 1587 | if (argc >= nextarg) { |
1585 | diag = kdbgetularg(argv[nextarg], &val); | 1588 | diag = kdbgetularg(argv[nextarg], &val); |
1586 | if (!diag) { | 1589 | if (!diag) { |
1587 | mdcount = (int) val; | 1590 | mdcount = (int) val; |
1588 | repeat = mdcount * 16 / bytesperword; | 1591 | repeat = mdcount * 16 / bytesperword; |
1589 | } | 1592 | } |
1590 | } | 1593 | } |
1591 | if (argc >= nextarg+1) { | 1594 | if (argc >= nextarg+1) { |
1592 | diag = kdbgetularg(argv[nextarg+1], &val); | 1595 | diag = kdbgetularg(argv[nextarg+1], &val); |
1593 | if (!diag) | 1596 | if (!diag) |
1594 | radix = (int) val; | 1597 | radix = (int) val; |
1595 | } | 1598 | } |
1596 | } | 1599 | } |
1597 | 1600 | ||
1598 | if (strcmp(argv[0], "mdr") == 0) | 1601 | if (strcmp(argv[0], "mdr") == 0) |
1599 | return kdb_mdr(addr, mdcount); | 1602 | return kdb_mdr(addr, mdcount); |
1600 | 1603 | ||
1601 | switch (radix) { | 1604 | switch (radix) { |
1602 | case 10: | 1605 | case 10: |
1603 | fmtchar = 'd'; | 1606 | fmtchar = 'd'; |
1604 | break; | 1607 | break; |
1605 | case 16: | 1608 | case 16: |
1606 | fmtchar = 'x'; | 1609 | fmtchar = 'x'; |
1607 | break; | 1610 | break; |
1608 | case 8: | 1611 | case 8: |
1609 | fmtchar = 'o'; | 1612 | fmtchar = 'o'; |
1610 | break; | 1613 | break; |
1611 | default: | 1614 | default: |
1612 | return KDB_BADRADIX; | 1615 | return KDB_BADRADIX; |
1613 | } | 1616 | } |
1614 | 1617 | ||
1615 | last_radix = radix; | 1618 | last_radix = radix; |
1616 | 1619 | ||
1617 | if (bytesperword > KDB_WORD_SIZE) | 1620 | if (bytesperword > KDB_WORD_SIZE) |
1618 | return KDB_BADWIDTH; | 1621 | return KDB_BADWIDTH; |
1619 | 1622 | ||
1620 | switch (bytesperword) { | 1623 | switch (bytesperword) { |
1621 | case 8: | 1624 | case 8: |
1622 | sprintf(fmtstr, "%%16.16l%c ", fmtchar); | 1625 | sprintf(fmtstr, "%%16.16l%c ", fmtchar); |
1623 | break; | 1626 | break; |
1624 | case 4: | 1627 | case 4: |
1625 | sprintf(fmtstr, "%%8.8l%c ", fmtchar); | 1628 | sprintf(fmtstr, "%%8.8l%c ", fmtchar); |
1626 | break; | 1629 | break; |
1627 | case 2: | 1630 | case 2: |
1628 | sprintf(fmtstr, "%%4.4l%c ", fmtchar); | 1631 | sprintf(fmtstr, "%%4.4l%c ", fmtchar); |
1629 | break; | 1632 | break; |
1630 | case 1: | 1633 | case 1: |
1631 | sprintf(fmtstr, "%%2.2l%c ", fmtchar); | 1634 | sprintf(fmtstr, "%%2.2l%c ", fmtchar); |
1632 | break; | 1635 | break; |
1633 | default: | 1636 | default: |
1634 | return KDB_BADWIDTH; | 1637 | return KDB_BADWIDTH; |
1635 | } | 1638 | } |
1636 | 1639 | ||
1637 | last_repeat = repeat; | 1640 | last_repeat = repeat; |
1638 | last_bytesperword = bytesperword; | 1641 | last_bytesperword = bytesperword; |
1639 | 1642 | ||
1640 | if (strcmp(argv[0], "mds") == 0) { | 1643 | if (strcmp(argv[0], "mds") == 0) { |
1641 | symbolic = 1; | 1644 | symbolic = 1; |
1642 | /* Do not save these changes as last_*, they are temporary mds | 1645 | /* Do not save these changes as last_*, they are temporary mds |
1643 | * overrides. | 1646 | * overrides. |
1644 | */ | 1647 | */ |
1645 | bytesperword = KDB_WORD_SIZE; | 1648 | bytesperword = KDB_WORD_SIZE; |
1646 | repeat = mdcount; | 1649 | repeat = mdcount; |
1647 | kdbgetintenv("NOSECT", &nosect); | 1650 | kdbgetintenv("NOSECT", &nosect); |
1648 | } | 1651 | } |
1649 | 1652 | ||
1650 | /* Round address down modulo BYTESPERWORD */ | 1653 | /* Round address down modulo BYTESPERWORD */ |
1651 | 1654 | ||
1652 | addr &= ~(bytesperword-1); | 1655 | addr &= ~(bytesperword-1); |
1653 | 1656 | ||
1654 | while (repeat > 0) { | 1657 | while (repeat > 0) { |
1655 | unsigned long a; | 1658 | unsigned long a; |
1656 | int n, z, num = (symbolic ? 1 : (16 / bytesperword)); | 1659 | int n, z, num = (symbolic ? 1 : (16 / bytesperword)); |
1657 | 1660 | ||
1658 | if (KDB_FLAG(CMD_INTERRUPT)) | 1661 | if (KDB_FLAG(CMD_INTERRUPT)) |
1659 | return 0; | 1662 | return 0; |
1660 | for (a = addr, z = 0; z < repeat; a += bytesperword, ++z) { | 1663 | for (a = addr, z = 0; z < repeat; a += bytesperword, ++z) { |
1661 | if (phys) { | 1664 | if (phys) { |
1662 | if (kdb_getphysword(&word, a, bytesperword) | 1665 | if (kdb_getphysword(&word, a, bytesperword) |
1663 | || word) | 1666 | || word) |
1664 | break; | 1667 | break; |
1665 | } else if (kdb_getword(&word, a, bytesperword) || word) | 1668 | } else if (kdb_getword(&word, a, bytesperword) || word) |
1666 | break; | 1669 | break; |
1667 | } | 1670 | } |
1668 | n = min(num, repeat); | 1671 | n = min(num, repeat); |
1669 | kdb_md_line(fmtstr, addr, symbolic, nosect, bytesperword, | 1672 | kdb_md_line(fmtstr, addr, symbolic, nosect, bytesperword, |
1670 | num, repeat, phys); | 1673 | num, repeat, phys); |
1671 | addr += bytesperword * n; | 1674 | addr += bytesperword * n; |
1672 | repeat -= n; | 1675 | repeat -= n; |
1673 | z = (z + num - 1) / num; | 1676 | z = (z + num - 1) / num; |
1674 | if (z > 2) { | 1677 | if (z > 2) { |
1675 | int s = num * (z-2); | 1678 | int s = num * (z-2); |
1676 | kdb_printf(kdb_machreg_fmt0 "-" kdb_machreg_fmt0 | 1679 | kdb_printf(kdb_machreg_fmt0 "-" kdb_machreg_fmt0 |
1677 | " zero suppressed\n", | 1680 | " zero suppressed\n", |
1678 | addr, addr + bytesperword * s - 1); | 1681 | addr, addr + bytesperword * s - 1); |
1679 | addr += bytesperword * s; | 1682 | addr += bytesperword * s; |
1680 | repeat -= s; | 1683 | repeat -= s; |
1681 | } | 1684 | } |
1682 | } | 1685 | } |
1683 | last_addr = addr; | 1686 | last_addr = addr; |
1684 | 1687 | ||
1685 | return 0; | 1688 | return 0; |
1686 | } | 1689 | } |
1687 | 1690 | ||
1688 | /* | 1691 | /* |
1689 | * kdb_mm - This function implements the 'mm' command. | 1692 | * kdb_mm - This function implements the 'mm' command. |
1690 | * mm address-expression new-value | 1693 | * mm address-expression new-value |
1691 | * Remarks: | 1694 | * Remarks: |
1692 | * mm works on machine words, mmW works on bytes. | 1695 | * mm works on machine words, mmW works on bytes. |
1693 | */ | 1696 | */ |
1694 | static int kdb_mm(int argc, const char **argv) | 1697 | static int kdb_mm(int argc, const char **argv) |
1695 | { | 1698 | { |
1696 | int diag; | 1699 | int diag; |
1697 | unsigned long addr; | 1700 | unsigned long addr; |
1698 | long offset = 0; | 1701 | long offset = 0; |
1699 | unsigned long contents; | 1702 | unsigned long contents; |
1700 | int nextarg; | 1703 | int nextarg; |
1701 | int width; | 1704 | int width; |
1702 | 1705 | ||
1703 | if (argv[0][2] && !isdigit(argv[0][2])) | 1706 | if (argv[0][2] && !isdigit(argv[0][2])) |
1704 | return KDB_NOTFOUND; | 1707 | return KDB_NOTFOUND; |
1705 | 1708 | ||
1706 | if (argc < 2) | 1709 | if (argc < 2) |
1707 | return KDB_ARGCOUNT; | 1710 | return KDB_ARGCOUNT; |
1708 | 1711 | ||
1709 | nextarg = 1; | 1712 | nextarg = 1; |
1710 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL); | 1713 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL); |
1711 | if (diag) | 1714 | if (diag) |
1712 | return diag; | 1715 | return diag; |
1713 | 1716 | ||
1714 | if (nextarg > argc) | 1717 | if (nextarg > argc) |
1715 | return KDB_ARGCOUNT; | 1718 | return KDB_ARGCOUNT; |
1716 | diag = kdbgetaddrarg(argc, argv, &nextarg, &contents, NULL, NULL); | 1719 | diag = kdbgetaddrarg(argc, argv, &nextarg, &contents, NULL, NULL); |
1717 | if (diag) | 1720 | if (diag) |
1718 | return diag; | 1721 | return diag; |
1719 | 1722 | ||
1720 | if (nextarg != argc + 1) | 1723 | if (nextarg != argc + 1) |
1721 | return KDB_ARGCOUNT; | 1724 | return KDB_ARGCOUNT; |
1722 | 1725 | ||
1723 | width = argv[0][2] ? (argv[0][2] - '0') : (KDB_WORD_SIZE); | 1726 | width = argv[0][2] ? (argv[0][2] - '0') : (KDB_WORD_SIZE); |
1724 | diag = kdb_putword(addr, contents, width); | 1727 | diag = kdb_putword(addr, contents, width); |
1725 | if (diag) | 1728 | if (diag) |
1726 | return diag; | 1729 | return diag; |
1727 | 1730 | ||
1728 | kdb_printf(kdb_machreg_fmt " = " kdb_machreg_fmt "\n", addr, contents); | 1731 | kdb_printf(kdb_machreg_fmt " = " kdb_machreg_fmt "\n", addr, contents); |
1729 | 1732 | ||
1730 | return 0; | 1733 | return 0; |
1731 | } | 1734 | } |
1732 | 1735 | ||
1733 | /* | 1736 | /* |
1734 | * kdb_go - This function implements the 'go' command. | 1737 | * kdb_go - This function implements the 'go' command. |
1735 | * go [address-expression] | 1738 | * go [address-expression] |
1736 | */ | 1739 | */ |
1737 | static int kdb_go(int argc, const char **argv) | 1740 | static int kdb_go(int argc, const char **argv) |
1738 | { | 1741 | { |
1739 | unsigned long addr; | 1742 | unsigned long addr; |
1740 | int diag; | 1743 | int diag; |
1741 | int nextarg; | 1744 | int nextarg; |
1742 | long offset; | 1745 | long offset; |
1743 | 1746 | ||
1744 | if (raw_smp_processor_id() != kdb_initial_cpu) { | 1747 | if (raw_smp_processor_id() != kdb_initial_cpu) { |
1745 | kdb_printf("go must execute on the entry cpu, " | 1748 | kdb_printf("go must execute on the entry cpu, " |
1746 | "please use \"cpu %d\" and then execute go\n", | 1749 | "please use \"cpu %d\" and then execute go\n", |
1747 | kdb_initial_cpu); | 1750 | kdb_initial_cpu); |
1748 | return KDB_BADCPUNUM; | 1751 | return KDB_BADCPUNUM; |
1749 | } | 1752 | } |
1750 | if (argc == 1) { | 1753 | if (argc == 1) { |
1751 | nextarg = 1; | 1754 | nextarg = 1; |
1752 | diag = kdbgetaddrarg(argc, argv, &nextarg, | 1755 | diag = kdbgetaddrarg(argc, argv, &nextarg, |
1753 | &addr, &offset, NULL); | 1756 | &addr, &offset, NULL); |
1754 | if (diag) | 1757 | if (diag) |
1755 | return diag; | 1758 | return diag; |
1756 | } else if (argc) { | 1759 | } else if (argc) { |
1757 | return KDB_ARGCOUNT; | 1760 | return KDB_ARGCOUNT; |
1758 | } | 1761 | } |
1759 | 1762 | ||
1760 | diag = KDB_CMD_GO; | 1763 | diag = KDB_CMD_GO; |
1761 | if (KDB_FLAG(CATASTROPHIC)) { | 1764 | if (KDB_FLAG(CATASTROPHIC)) { |
1762 | kdb_printf("Catastrophic error detected\n"); | 1765 | kdb_printf("Catastrophic error detected\n"); |
1763 | kdb_printf("kdb_continue_catastrophic=%d, ", | 1766 | kdb_printf("kdb_continue_catastrophic=%d, ", |
1764 | kdb_continue_catastrophic); | 1767 | kdb_continue_catastrophic); |
1765 | if (kdb_continue_catastrophic == 0 && kdb_go_count++ == 0) { | 1768 | if (kdb_continue_catastrophic == 0 && kdb_go_count++ == 0) { |
1766 | kdb_printf("type go a second time if you really want " | 1769 | kdb_printf("type go a second time if you really want " |
1767 | "to continue\n"); | 1770 | "to continue\n"); |
1768 | return 0; | 1771 | return 0; |
1769 | } | 1772 | } |
1770 | if (kdb_continue_catastrophic == 2) { | 1773 | if (kdb_continue_catastrophic == 2) { |
1771 | kdb_printf("forcing reboot\n"); | 1774 | kdb_printf("forcing reboot\n"); |
1772 | kdb_reboot(0, NULL); | 1775 | kdb_reboot(0, NULL); |
1773 | } | 1776 | } |
1774 | kdb_printf("attempting to continue\n"); | 1777 | kdb_printf("attempting to continue\n"); |
1775 | } | 1778 | } |
1776 | return diag; | 1779 | return diag; |
1777 | } | 1780 | } |
1778 | 1781 | ||
1779 | /* | 1782 | /* |
1780 | * kdb_rd - This function implements the 'rd' command. | 1783 | * kdb_rd - This function implements the 'rd' command. |
1781 | */ | 1784 | */ |
1782 | static int kdb_rd(int argc, const char **argv) | 1785 | static int kdb_rd(int argc, const char **argv) |
1783 | { | 1786 | { |
1784 | int len = kdb_check_regs(); | 1787 | int len = kdb_check_regs(); |
1785 | #if DBG_MAX_REG_NUM > 0 | 1788 | #if DBG_MAX_REG_NUM > 0 |
1786 | int i; | 1789 | int i; |
1787 | char *rname; | 1790 | char *rname; |
1788 | int rsize; | 1791 | int rsize; |
1789 | u64 reg64; | 1792 | u64 reg64; |
1790 | u32 reg32; | 1793 | u32 reg32; |
1791 | u16 reg16; | 1794 | u16 reg16; |
1792 | u8 reg8; | 1795 | u8 reg8; |
1793 | 1796 | ||
1794 | if (len) | 1797 | if (len) |
1795 | return len; | 1798 | return len; |
1796 | 1799 | ||
1797 | for (i = 0; i < DBG_MAX_REG_NUM; i++) { | 1800 | for (i = 0; i < DBG_MAX_REG_NUM; i++) { |
1798 | rsize = dbg_reg_def[i].size * 2; | 1801 | rsize = dbg_reg_def[i].size * 2; |
1799 | if (rsize > 16) | 1802 | if (rsize > 16) |
1800 | rsize = 2; | 1803 | rsize = 2; |
1801 | if (len + strlen(dbg_reg_def[i].name) + 4 + rsize > 80) { | 1804 | if (len + strlen(dbg_reg_def[i].name) + 4 + rsize > 80) { |
1802 | len = 0; | 1805 | len = 0; |
1803 | kdb_printf("\n"); | 1806 | kdb_printf("\n"); |
1804 | } | 1807 | } |
1805 | if (len) | 1808 | if (len) |
1806 | len += kdb_printf(" "); | 1809 | len += kdb_printf(" "); |
1807 | switch(dbg_reg_def[i].size * 8) { | 1810 | switch(dbg_reg_def[i].size * 8) { |
1808 | case 8: | 1811 | case 8: |
1809 | rname = dbg_get_reg(i, ®8, kdb_current_regs); | 1812 | rname = dbg_get_reg(i, ®8, kdb_current_regs); |
1810 | if (!rname) | 1813 | if (!rname) |
1811 | break; | 1814 | break; |
1812 | len += kdb_printf("%s: %02x", rname, reg8); | 1815 | len += kdb_printf("%s: %02x", rname, reg8); |
1813 | break; | 1816 | break; |
1814 | case 16: | 1817 | case 16: |
1815 | rname = dbg_get_reg(i, ®16, kdb_current_regs); | 1818 | rname = dbg_get_reg(i, ®16, kdb_current_regs); |
1816 | if (!rname) | 1819 | if (!rname) |
1817 | break; | 1820 | break; |
1818 | len += kdb_printf("%s: %04x", rname, reg16); | 1821 | len += kdb_printf("%s: %04x", rname, reg16); |
1819 | break; | 1822 | break; |
1820 | case 32: | 1823 | case 32: |
1821 | rname = dbg_get_reg(i, ®32, kdb_current_regs); | 1824 | rname = dbg_get_reg(i, ®32, kdb_current_regs); |
1822 | if (!rname) | 1825 | if (!rname) |
1823 | break; | 1826 | break; |
1824 | len += kdb_printf("%s: %08x", rname, reg32); | 1827 | len += kdb_printf("%s: %08x", rname, reg32); |
1825 | break; | 1828 | break; |
1826 | case 64: | 1829 | case 64: |
1827 | rname = dbg_get_reg(i, ®64, kdb_current_regs); | 1830 | rname = dbg_get_reg(i, ®64, kdb_current_regs); |
1828 | if (!rname) | 1831 | if (!rname) |
1829 | break; | 1832 | break; |
1830 | len += kdb_printf("%s: %016llx", rname, reg64); | 1833 | len += kdb_printf("%s: %016llx", rname, reg64); |
1831 | break; | 1834 | break; |
1832 | default: | 1835 | default: |
1833 | len += kdb_printf("%s: ??", dbg_reg_def[i].name); | 1836 | len += kdb_printf("%s: ??", dbg_reg_def[i].name); |
1834 | } | 1837 | } |
1835 | } | 1838 | } |
1836 | kdb_printf("\n"); | 1839 | kdb_printf("\n"); |
1837 | #else | 1840 | #else |
1838 | if (len) | 1841 | if (len) |
1839 | return len; | 1842 | return len; |
1840 | 1843 | ||
1841 | kdb_dumpregs(kdb_current_regs); | 1844 | kdb_dumpregs(kdb_current_regs); |
1842 | #endif | 1845 | #endif |
1843 | return 0; | 1846 | return 0; |
1844 | } | 1847 | } |
1845 | 1848 | ||
1846 | /* | 1849 | /* |
1847 | * kdb_rm - This function implements the 'rm' (register modify) command. | 1850 | * kdb_rm - This function implements the 'rm' (register modify) command. |
1848 | * rm register-name new-contents | 1851 | * rm register-name new-contents |
1849 | * Remarks: | 1852 | * Remarks: |
1850 | * Allows register modification with the same restrictions as gdb | 1853 | * Allows register modification with the same restrictions as gdb |
1851 | */ | 1854 | */ |
1852 | static int kdb_rm(int argc, const char **argv) | 1855 | static int kdb_rm(int argc, const char **argv) |
1853 | { | 1856 | { |
1854 | #if DBG_MAX_REG_NUM > 0 | 1857 | #if DBG_MAX_REG_NUM > 0 |
1855 | int diag; | 1858 | int diag; |
1856 | const char *rname; | 1859 | const char *rname; |
1857 | int i; | 1860 | int i; |
1858 | u64 reg64; | 1861 | u64 reg64; |
1859 | u32 reg32; | 1862 | u32 reg32; |
1860 | u16 reg16; | 1863 | u16 reg16; |
1861 | u8 reg8; | 1864 | u8 reg8; |
1862 | 1865 | ||
1863 | if (argc != 2) | 1866 | if (argc != 2) |
1864 | return KDB_ARGCOUNT; | 1867 | return KDB_ARGCOUNT; |
1865 | /* | 1868 | /* |
1866 | * Allow presence or absence of leading '%' symbol. | 1869 | * Allow presence or absence of leading '%' symbol. |
1867 | */ | 1870 | */ |
1868 | rname = argv[1]; | 1871 | rname = argv[1]; |
1869 | if (*rname == '%') | 1872 | if (*rname == '%') |
1870 | rname++; | 1873 | rname++; |
1871 | 1874 | ||
1872 | diag = kdbgetu64arg(argv[2], ®64); | 1875 | diag = kdbgetu64arg(argv[2], ®64); |
1873 | if (diag) | 1876 | if (diag) |
1874 | return diag; | 1877 | return diag; |
1875 | 1878 | ||
1876 | diag = kdb_check_regs(); | 1879 | diag = kdb_check_regs(); |
1877 | if (diag) | 1880 | if (diag) |
1878 | return diag; | 1881 | return diag; |
1879 | 1882 | ||
1880 | diag = KDB_BADREG; | 1883 | diag = KDB_BADREG; |
1881 | for (i = 0; i < DBG_MAX_REG_NUM; i++) { | 1884 | for (i = 0; i < DBG_MAX_REG_NUM; i++) { |
1882 | if (strcmp(rname, dbg_reg_def[i].name) == 0) { | 1885 | if (strcmp(rname, dbg_reg_def[i].name) == 0) { |
1883 | diag = 0; | 1886 | diag = 0; |
1884 | break; | 1887 | break; |
1885 | } | 1888 | } |
1886 | } | 1889 | } |
1887 | if (!diag) { | 1890 | if (!diag) { |
1888 | switch(dbg_reg_def[i].size * 8) { | 1891 | switch(dbg_reg_def[i].size * 8) { |
1889 | case 8: | 1892 | case 8: |
1890 | reg8 = reg64; | 1893 | reg8 = reg64; |
1891 | dbg_set_reg(i, ®8, kdb_current_regs); | 1894 | dbg_set_reg(i, ®8, kdb_current_regs); |
1892 | break; | 1895 | break; |
1893 | case 16: | 1896 | case 16: |
1894 | reg16 = reg64; | 1897 | reg16 = reg64; |
1895 | dbg_set_reg(i, ®16, kdb_current_regs); | 1898 | dbg_set_reg(i, ®16, kdb_current_regs); |
1896 | break; | 1899 | break; |
1897 | case 32: | 1900 | case 32: |
1898 | reg32 = reg64; | 1901 | reg32 = reg64; |
1899 | dbg_set_reg(i, ®32, kdb_current_regs); | 1902 | dbg_set_reg(i, ®32, kdb_current_regs); |
1900 | break; | 1903 | break; |
1901 | case 64: | 1904 | case 64: |
1902 | dbg_set_reg(i, ®64, kdb_current_regs); | 1905 | dbg_set_reg(i, ®64, kdb_current_regs); |
1903 | break; | 1906 | break; |
1904 | } | 1907 | } |
1905 | } | 1908 | } |
1906 | return diag; | 1909 | return diag; |
1907 | #else | 1910 | #else |
1908 | kdb_printf("ERROR: Register set currently not implemented\n"); | 1911 | kdb_printf("ERROR: Register set currently not implemented\n"); |
1909 | return 0; | 1912 | return 0; |
1910 | #endif | 1913 | #endif |
1911 | } | 1914 | } |
1912 | 1915 | ||
1913 | #if defined(CONFIG_MAGIC_SYSRQ) | 1916 | #if defined(CONFIG_MAGIC_SYSRQ) |
1914 | /* | 1917 | /* |
1915 | * kdb_sr - This function implements the 'sr' (SYSRQ key) command | 1918 | * kdb_sr - This function implements the 'sr' (SYSRQ key) command |
1916 | * which interfaces to the soi-disant MAGIC SYSRQ functionality. | 1919 | * which interfaces to the soi-disant MAGIC SYSRQ functionality. |
1917 | * sr <magic-sysrq-code> | 1920 | * sr <magic-sysrq-code> |
1918 | */ | 1921 | */ |
1919 | static int kdb_sr(int argc, const char **argv) | 1922 | static int kdb_sr(int argc, const char **argv) |
1920 | { | 1923 | { |
1921 | if (argc != 1) | 1924 | if (argc != 1) |
1922 | return KDB_ARGCOUNT; | 1925 | return KDB_ARGCOUNT; |
1923 | kdb_trap_printk++; | 1926 | kdb_trap_printk++; |
1924 | __handle_sysrq(*argv[1], false); | 1927 | __handle_sysrq(*argv[1], false); |
1925 | kdb_trap_printk--; | 1928 | kdb_trap_printk--; |
1926 | 1929 | ||
1927 | return 0; | 1930 | return 0; |
1928 | } | 1931 | } |
1929 | #endif /* CONFIG_MAGIC_SYSRQ */ | 1932 | #endif /* CONFIG_MAGIC_SYSRQ */ |
1930 | 1933 | ||
1931 | /* | 1934 | /* |
1932 | * kdb_ef - This function implements the 'regs' (display exception | 1935 | * kdb_ef - This function implements the 'regs' (display exception |
1933 | * frame) command. This command takes an address and expects to | 1936 | * frame) command. This command takes an address and expects to |
1934 | * find an exception frame at that address, formats and prints | 1937 | * find an exception frame at that address, formats and prints |
1935 | * it. | 1938 | * it. |
1936 | * regs address-expression | 1939 | * regs address-expression |
1937 | * Remarks: | 1940 | * Remarks: |
1938 | * Not done yet. | 1941 | * Not done yet. |
1939 | */ | 1942 | */ |
1940 | static int kdb_ef(int argc, const char **argv) | 1943 | static int kdb_ef(int argc, const char **argv) |
1941 | { | 1944 | { |
1942 | int diag; | 1945 | int diag; |
1943 | unsigned long addr; | 1946 | unsigned long addr; |
1944 | long offset; | 1947 | long offset; |
1945 | int nextarg; | 1948 | int nextarg; |
1946 | 1949 | ||
1947 | if (argc != 1) | 1950 | if (argc != 1) |
1948 | return KDB_ARGCOUNT; | 1951 | return KDB_ARGCOUNT; |
1949 | 1952 | ||
1950 | nextarg = 1; | 1953 | nextarg = 1; |
1951 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL); | 1954 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL); |
1952 | if (diag) | 1955 | if (diag) |
1953 | return diag; | 1956 | return diag; |
1954 | show_regs((struct pt_regs *)addr); | 1957 | show_regs((struct pt_regs *)addr); |
1955 | return 0; | 1958 | return 0; |
1956 | } | 1959 | } |
1957 | 1960 | ||
1958 | #if defined(CONFIG_MODULES) | 1961 | #if defined(CONFIG_MODULES) |
1959 | /* | 1962 | /* |
1960 | * kdb_lsmod - This function implements the 'lsmod' command. Lists | 1963 | * kdb_lsmod - This function implements the 'lsmod' command. Lists |
1961 | * currently loaded kernel modules. | 1964 | * currently loaded kernel modules. |
1962 | * Mostly taken from userland lsmod. | 1965 | * Mostly taken from userland lsmod. |
1963 | */ | 1966 | */ |
1964 | static int kdb_lsmod(int argc, const char **argv) | 1967 | static int kdb_lsmod(int argc, const char **argv) |
1965 | { | 1968 | { |
1966 | struct module *mod; | 1969 | struct module *mod; |
1967 | 1970 | ||
1968 | if (argc != 0) | 1971 | if (argc != 0) |
1969 | return KDB_ARGCOUNT; | 1972 | return KDB_ARGCOUNT; |
1970 | 1973 | ||
1971 | kdb_printf("Module Size modstruct Used by\n"); | 1974 | kdb_printf("Module Size modstruct Used by\n"); |
1972 | list_for_each_entry(mod, kdb_modules, list) { | 1975 | list_for_each_entry(mod, kdb_modules, list) { |
1973 | if (mod->state == MODULE_STATE_UNFORMED) | 1976 | if (mod->state == MODULE_STATE_UNFORMED) |
1974 | continue; | 1977 | continue; |
1975 | 1978 | ||
1976 | kdb_printf("%-20s%8u 0x%p ", mod->name, | 1979 | kdb_printf("%-20s%8u 0x%p ", mod->name, |
1977 | mod->core_size, (void *)mod); | 1980 | mod->core_size, (void *)mod); |
1978 | #ifdef CONFIG_MODULE_UNLOAD | 1981 | #ifdef CONFIG_MODULE_UNLOAD |
1979 | kdb_printf("%4ld ", module_refcount(mod)); | 1982 | kdb_printf("%4ld ", module_refcount(mod)); |
1980 | #endif | 1983 | #endif |
1981 | if (mod->state == MODULE_STATE_GOING) | 1984 | if (mod->state == MODULE_STATE_GOING) |
1982 | kdb_printf(" (Unloading)"); | 1985 | kdb_printf(" (Unloading)"); |
1983 | else if (mod->state == MODULE_STATE_COMING) | 1986 | else if (mod->state == MODULE_STATE_COMING) |
1984 | kdb_printf(" (Loading)"); | 1987 | kdb_printf(" (Loading)"); |
1985 | else | 1988 | else |
1986 | kdb_printf(" (Live)"); | 1989 | kdb_printf(" (Live)"); |
1987 | kdb_printf(" 0x%p", mod->module_core); | 1990 | kdb_printf(" 0x%p", mod->module_core); |
1988 | 1991 | ||
1989 | #ifdef CONFIG_MODULE_UNLOAD | 1992 | #ifdef CONFIG_MODULE_UNLOAD |
1990 | { | 1993 | { |
1991 | struct module_use *use; | 1994 | struct module_use *use; |
1992 | kdb_printf(" [ "); | 1995 | kdb_printf(" [ "); |
1993 | list_for_each_entry(use, &mod->source_list, | 1996 | list_for_each_entry(use, &mod->source_list, |
1994 | source_list) | 1997 | source_list) |
1995 | kdb_printf("%s ", use->target->name); | 1998 | kdb_printf("%s ", use->target->name); |
1996 | kdb_printf("]\n"); | 1999 | kdb_printf("]\n"); |
1997 | } | 2000 | } |
1998 | #endif | 2001 | #endif |
1999 | } | 2002 | } |
2000 | 2003 | ||
2001 | return 0; | 2004 | return 0; |
2002 | } | 2005 | } |
2003 | 2006 | ||
2004 | #endif /* CONFIG_MODULES */ | 2007 | #endif /* CONFIG_MODULES */ |
2005 | 2008 | ||
2006 | /* | 2009 | /* |
2007 | * kdb_env - This function implements the 'env' command. Display the | 2010 | * kdb_env - This function implements the 'env' command. Display the |
2008 | * current environment variables. | 2011 | * current environment variables. |
2009 | */ | 2012 | */ |
2010 | 2013 | ||
2011 | static int kdb_env(int argc, const char **argv) | 2014 | static int kdb_env(int argc, const char **argv) |
2012 | { | 2015 | { |
2013 | int i; | 2016 | int i; |
2014 | 2017 | ||
2015 | for (i = 0; i < __nenv; i++) { | 2018 | for (i = 0; i < __nenv; i++) { |
2016 | if (__env[i]) | 2019 | if (__env[i]) |
2017 | kdb_printf("%s\n", __env[i]); | 2020 | kdb_printf("%s\n", __env[i]); |
2018 | } | 2021 | } |
2019 | 2022 | ||
2020 | if (KDB_DEBUG(MASK)) | 2023 | if (KDB_DEBUG(MASK)) |
2021 | kdb_printf("KDBFLAGS=0x%x\n", kdb_flags); | 2024 | kdb_printf("KDBFLAGS=0x%x\n", kdb_flags); |
2022 | 2025 | ||
2023 | return 0; | 2026 | return 0; |
2024 | } | 2027 | } |
2025 | 2028 | ||
2026 | #ifdef CONFIG_PRINTK | 2029 | #ifdef CONFIG_PRINTK |
2027 | /* | 2030 | /* |
2028 | * kdb_dmesg - This function implements the 'dmesg' command to display | 2031 | * kdb_dmesg - This function implements the 'dmesg' command to display |
2029 | * the contents of the syslog buffer. | 2032 | * the contents of the syslog buffer. |
2030 | * dmesg [lines] [adjust] | 2033 | * dmesg [lines] [adjust] |
2031 | */ | 2034 | */ |
2032 | static int kdb_dmesg(int argc, const char **argv) | 2035 | static int kdb_dmesg(int argc, const char **argv) |
2033 | { | 2036 | { |
2034 | int diag; | 2037 | int diag; |
2035 | int logging; | 2038 | int logging; |
2036 | int lines = 0; | 2039 | int lines = 0; |
2037 | int adjust = 0; | 2040 | int adjust = 0; |
2038 | int n = 0; | 2041 | int n = 0; |
2039 | int skip = 0; | 2042 | int skip = 0; |
2040 | struct kmsg_dumper dumper = { .active = 1 }; | 2043 | struct kmsg_dumper dumper = { .active = 1 }; |
2041 | size_t len; | 2044 | size_t len; |
2042 | char buf[201]; | 2045 | char buf[201]; |
2043 | 2046 | ||
2044 | if (argc > 2) | 2047 | if (argc > 2) |
2045 | return KDB_ARGCOUNT; | 2048 | return KDB_ARGCOUNT; |
2046 | if (argc) { | 2049 | if (argc) { |
2047 | char *cp; | 2050 | char *cp; |
2048 | lines = simple_strtol(argv[1], &cp, 0); | 2051 | lines = simple_strtol(argv[1], &cp, 0); |
2049 | if (*cp) | 2052 | if (*cp) |
2050 | lines = 0; | 2053 | lines = 0; |
2051 | if (argc > 1) { | 2054 | if (argc > 1) { |
2052 | adjust = simple_strtoul(argv[2], &cp, 0); | 2055 | adjust = simple_strtoul(argv[2], &cp, 0); |
2053 | if (*cp || adjust < 0) | 2056 | if (*cp || adjust < 0) |
2054 | adjust = 0; | 2057 | adjust = 0; |
2055 | } | 2058 | } |
2056 | } | 2059 | } |
2057 | 2060 | ||
2058 | /* disable LOGGING if set */ | 2061 | /* disable LOGGING if set */ |
2059 | diag = kdbgetintenv("LOGGING", &logging); | 2062 | diag = kdbgetintenv("LOGGING", &logging); |
2060 | if (!diag && logging) { | 2063 | if (!diag && logging) { |
2061 | const char *setargs[] = { "set", "LOGGING", "0" }; | 2064 | const char *setargs[] = { "set", "LOGGING", "0" }; |
2062 | kdb_set(2, setargs); | 2065 | kdb_set(2, setargs); |
2063 | } | 2066 | } |
2064 | 2067 | ||
2065 | kmsg_dump_rewind_nolock(&dumper); | 2068 | kmsg_dump_rewind_nolock(&dumper); |
2066 | while (kmsg_dump_get_line_nolock(&dumper, 1, NULL, 0, NULL)) | 2069 | while (kmsg_dump_get_line_nolock(&dumper, 1, NULL, 0, NULL)) |
2067 | n++; | 2070 | n++; |
2068 | 2071 | ||
2069 | if (lines < 0) { | 2072 | if (lines < 0) { |
2070 | if (adjust >= n) | 2073 | if (adjust >= n) |
2071 | kdb_printf("buffer only contains %d lines, nothing " | 2074 | kdb_printf("buffer only contains %d lines, nothing " |
2072 | "printed\n", n); | 2075 | "printed\n", n); |
2073 | else if (adjust - lines >= n) | 2076 | else if (adjust - lines >= n) |
2074 | kdb_printf("buffer only contains %d lines, last %d " | 2077 | kdb_printf("buffer only contains %d lines, last %d " |
2075 | "lines printed\n", n, n - adjust); | 2078 | "lines printed\n", n, n - adjust); |
2076 | skip = adjust; | 2079 | skip = adjust; |
2077 | lines = abs(lines); | 2080 | lines = abs(lines); |
2078 | } else if (lines > 0) { | 2081 | } else if (lines > 0) { |
2079 | skip = n - lines - adjust; | 2082 | skip = n - lines - adjust; |
2080 | lines = abs(lines); | 2083 | lines = abs(lines); |
2081 | if (adjust >= n) { | 2084 | if (adjust >= n) { |
2082 | kdb_printf("buffer only contains %d lines, " | 2085 | kdb_printf("buffer only contains %d lines, " |
2083 | "nothing printed\n", n); | 2086 | "nothing printed\n", n); |
2084 | skip = n; | 2087 | skip = n; |
2085 | } else if (skip < 0) { | 2088 | } else if (skip < 0) { |
2086 | lines += skip; | 2089 | lines += skip; |
2087 | skip = 0; | 2090 | skip = 0; |
2088 | kdb_printf("buffer only contains %d lines, first " | 2091 | kdb_printf("buffer only contains %d lines, first " |
2089 | "%d lines printed\n", n, lines); | 2092 | "%d lines printed\n", n, lines); |
2090 | } | 2093 | } |
2091 | } else { | 2094 | } else { |
2092 | lines = n; | 2095 | lines = n; |
2093 | } | 2096 | } |
2094 | 2097 | ||
2095 | if (skip >= n || skip < 0) | 2098 | if (skip >= n || skip < 0) |
2096 | return 0; | 2099 | return 0; |
2097 | 2100 | ||
2098 | kmsg_dump_rewind_nolock(&dumper); | 2101 | kmsg_dump_rewind_nolock(&dumper); |
2099 | while (kmsg_dump_get_line_nolock(&dumper, 1, buf, sizeof(buf), &len)) { | 2102 | while (kmsg_dump_get_line_nolock(&dumper, 1, buf, sizeof(buf), &len)) { |
2100 | if (skip) { | 2103 | if (skip) { |
2101 | skip--; | 2104 | skip--; |
2102 | continue; | 2105 | continue; |
2103 | } | 2106 | } |
2104 | if (!lines--) | 2107 | if (!lines--) |
2105 | break; | 2108 | break; |
2106 | if (KDB_FLAG(CMD_INTERRUPT)) | 2109 | if (KDB_FLAG(CMD_INTERRUPT)) |
2107 | return 0; | 2110 | return 0; |
2108 | 2111 | ||
2109 | kdb_printf("%.*s\n", (int)len - 1, buf); | 2112 | kdb_printf("%.*s\n", (int)len - 1, buf); |
2110 | } | 2113 | } |
2111 | 2114 | ||
2112 | return 0; | 2115 | return 0; |
2113 | } | 2116 | } |
2114 | #endif /* CONFIG_PRINTK */ | 2117 | #endif /* CONFIG_PRINTK */ |
2115 | 2118 | ||
2116 | /* Make sure we balance enable/disable calls, must disable first. */ | 2119 | /* Make sure we balance enable/disable calls, must disable first. */ |
2117 | static atomic_t kdb_nmi_disabled; | 2120 | static atomic_t kdb_nmi_disabled; |
2118 | 2121 | ||
2119 | static int kdb_disable_nmi(int argc, const char *argv[]) | 2122 | static int kdb_disable_nmi(int argc, const char *argv[]) |
2120 | { | 2123 | { |
2121 | if (atomic_read(&kdb_nmi_disabled)) | 2124 | if (atomic_read(&kdb_nmi_disabled)) |
2122 | return 0; | 2125 | return 0; |
2123 | atomic_set(&kdb_nmi_disabled, 1); | 2126 | atomic_set(&kdb_nmi_disabled, 1); |
2124 | arch_kgdb_ops.enable_nmi(0); | 2127 | arch_kgdb_ops.enable_nmi(0); |
2125 | return 0; | 2128 | return 0; |
2126 | } | 2129 | } |
2127 | 2130 | ||
2128 | static int kdb_param_enable_nmi(const char *val, const struct kernel_param *kp) | 2131 | static int kdb_param_enable_nmi(const char *val, const struct kernel_param *kp) |
2129 | { | 2132 | { |
2130 | if (!atomic_add_unless(&kdb_nmi_disabled, -1, 0)) | 2133 | if (!atomic_add_unless(&kdb_nmi_disabled, -1, 0)) |
2131 | return -EINVAL; | 2134 | return -EINVAL; |
2132 | arch_kgdb_ops.enable_nmi(1); | 2135 | arch_kgdb_ops.enable_nmi(1); |
2133 | return 0; | 2136 | return 0; |
2134 | } | 2137 | } |
2135 | 2138 | ||
2136 | static const struct kernel_param_ops kdb_param_ops_enable_nmi = { | 2139 | static const struct kernel_param_ops kdb_param_ops_enable_nmi = { |
2137 | .set = kdb_param_enable_nmi, | 2140 | .set = kdb_param_enable_nmi, |
2138 | }; | 2141 | }; |
2139 | module_param_cb(enable_nmi, &kdb_param_ops_enable_nmi, NULL, 0600); | 2142 | module_param_cb(enable_nmi, &kdb_param_ops_enable_nmi, NULL, 0600); |
2140 | 2143 | ||
2141 | /* | 2144 | /* |
2142 | * kdb_cpu - This function implements the 'cpu' command. | 2145 | * kdb_cpu - This function implements the 'cpu' command. |
2143 | * cpu [<cpunum>] | 2146 | * cpu [<cpunum>] |
2144 | * Returns: | 2147 | * Returns: |
2145 | * KDB_CMD_CPU for success, a kdb diagnostic if error | 2148 | * KDB_CMD_CPU for success, a kdb diagnostic if error |
2146 | */ | 2149 | */ |
2147 | static void kdb_cpu_status(void) | 2150 | static void kdb_cpu_status(void) |
2148 | { | 2151 | { |
2149 | int i, start_cpu, first_print = 1; | 2152 | int i, start_cpu, first_print = 1; |
2150 | char state, prev_state = '?'; | 2153 | char state, prev_state = '?'; |
2151 | 2154 | ||
2152 | kdb_printf("Currently on cpu %d\n", raw_smp_processor_id()); | 2155 | kdb_printf("Currently on cpu %d\n", raw_smp_processor_id()); |
2153 | kdb_printf("Available cpus: "); | 2156 | kdb_printf("Available cpus: "); |
2154 | for (start_cpu = -1, i = 0; i < NR_CPUS; i++) { | 2157 | for (start_cpu = -1, i = 0; i < NR_CPUS; i++) { |
2155 | if (!cpu_online(i)) { | 2158 | if (!cpu_online(i)) { |
2156 | state = 'F'; /* cpu is offline */ | 2159 | state = 'F'; /* cpu is offline */ |
2157 | } else { | 2160 | } else { |
2158 | state = ' '; /* cpu is responding to kdb */ | 2161 | state = ' '; /* cpu is responding to kdb */ |
2159 | if (kdb_task_state_char(KDB_TSK(i)) == 'I') | 2162 | if (kdb_task_state_char(KDB_TSK(i)) == 'I') |
2160 | state = 'I'; /* idle task */ | 2163 | state = 'I'; /* idle task */ |
2161 | } | 2164 | } |
2162 | if (state != prev_state) { | 2165 | if (state != prev_state) { |
2163 | if (prev_state != '?') { | 2166 | if (prev_state != '?') { |
2164 | if (!first_print) | 2167 | if (!first_print) |
2165 | kdb_printf(", "); | 2168 | kdb_printf(", "); |
2166 | first_print = 0; | 2169 | first_print = 0; |
2167 | kdb_printf("%d", start_cpu); | 2170 | kdb_printf("%d", start_cpu); |
2168 | if (start_cpu < i-1) | 2171 | if (start_cpu < i-1) |
2169 | kdb_printf("-%d", i-1); | 2172 | kdb_printf("-%d", i-1); |
2170 | if (prev_state != ' ') | 2173 | if (prev_state != ' ') |
2171 | kdb_printf("(%c)", prev_state); | 2174 | kdb_printf("(%c)", prev_state); |
2172 | } | 2175 | } |
2173 | prev_state = state; | 2176 | prev_state = state; |
2174 | start_cpu = i; | 2177 | start_cpu = i; |
2175 | } | 2178 | } |
2176 | } | 2179 | } |
2177 | /* print the trailing cpus, ignoring them if they are all offline */ | 2180 | /* print the trailing cpus, ignoring them if they are all offline */ |
2178 | if (prev_state != 'F') { | 2181 | if (prev_state != 'F') { |
2179 | if (!first_print) | 2182 | if (!first_print) |
2180 | kdb_printf(", "); | 2183 | kdb_printf(", "); |
2181 | kdb_printf("%d", start_cpu); | 2184 | kdb_printf("%d", start_cpu); |
2182 | if (start_cpu < i-1) | 2185 | if (start_cpu < i-1) |
2183 | kdb_printf("-%d", i-1); | 2186 | kdb_printf("-%d", i-1); |
2184 | if (prev_state != ' ') | 2187 | if (prev_state != ' ') |
2185 | kdb_printf("(%c)", prev_state); | 2188 | kdb_printf("(%c)", prev_state); |
2186 | } | 2189 | } |
2187 | kdb_printf("\n"); | 2190 | kdb_printf("\n"); |
2188 | } | 2191 | } |
2189 | 2192 | ||
2190 | static int kdb_cpu(int argc, const char **argv) | 2193 | static int kdb_cpu(int argc, const char **argv) |
2191 | { | 2194 | { |
2192 | unsigned long cpunum; | 2195 | unsigned long cpunum; |
2193 | int diag; | 2196 | int diag; |
2194 | 2197 | ||
2195 | if (argc == 0) { | 2198 | if (argc == 0) { |
2196 | kdb_cpu_status(); | 2199 | kdb_cpu_status(); |
2197 | return 0; | 2200 | return 0; |
2198 | } | 2201 | } |
2199 | 2202 | ||
2200 | if (argc != 1) | 2203 | if (argc != 1) |
2201 | return KDB_ARGCOUNT; | 2204 | return KDB_ARGCOUNT; |
2202 | 2205 | ||
2203 | diag = kdbgetularg(argv[1], &cpunum); | 2206 | diag = kdbgetularg(argv[1], &cpunum); |
2204 | if (diag) | 2207 | if (diag) |
2205 | return diag; | 2208 | return diag; |
2206 | 2209 | ||
2207 | /* | 2210 | /* |
2208 | * Validate cpunum | 2211 | * Validate cpunum |
2209 | */ | 2212 | */ |
2210 | if ((cpunum > NR_CPUS) || !cpu_online(cpunum)) | 2213 | if ((cpunum > NR_CPUS) || !cpu_online(cpunum)) |
2211 | return KDB_BADCPUNUM; | 2214 | return KDB_BADCPUNUM; |
2212 | 2215 | ||
2213 | dbg_switch_cpu = cpunum; | 2216 | dbg_switch_cpu = cpunum; |
2214 | 2217 | ||
2215 | /* | 2218 | /* |
2216 | * Switch to other cpu | 2219 | * Switch to other cpu |
2217 | */ | 2220 | */ |
2218 | return KDB_CMD_CPU; | 2221 | return KDB_CMD_CPU; |
2219 | } | 2222 | } |
2220 | 2223 | ||
2221 | /* The user may not realize that ps/bta with no parameters does not print idle | 2224 | /* The user may not realize that ps/bta with no parameters does not print idle |
2222 | * or sleeping system daemon processes, so tell them how many were suppressed. | 2225 | * or sleeping system daemon processes, so tell them how many were suppressed. |
2223 | */ | 2226 | */ |
2224 | void kdb_ps_suppressed(void) | 2227 | void kdb_ps_suppressed(void) |
2225 | { | 2228 | { |
2226 | int idle = 0, daemon = 0; | 2229 | int idle = 0, daemon = 0; |
2227 | unsigned long mask_I = kdb_task_state_string("I"), | 2230 | unsigned long mask_I = kdb_task_state_string("I"), |
2228 | mask_M = kdb_task_state_string("M"); | 2231 | mask_M = kdb_task_state_string("M"); |
2229 | unsigned long cpu; | 2232 | unsigned long cpu; |
2230 | const struct task_struct *p, *g; | 2233 | const struct task_struct *p, *g; |
2231 | for_each_online_cpu(cpu) { | 2234 | for_each_online_cpu(cpu) { |
2232 | p = kdb_curr_task(cpu); | 2235 | p = kdb_curr_task(cpu); |
2233 | if (kdb_task_state(p, mask_I)) | 2236 | if (kdb_task_state(p, mask_I)) |
2234 | ++idle; | 2237 | ++idle; |
2235 | } | 2238 | } |
2236 | kdb_do_each_thread(g, p) { | 2239 | kdb_do_each_thread(g, p) { |
2237 | if (kdb_task_state(p, mask_M)) | 2240 | if (kdb_task_state(p, mask_M)) |
2238 | ++daemon; | 2241 | ++daemon; |
2239 | } kdb_while_each_thread(g, p); | 2242 | } kdb_while_each_thread(g, p); |
2240 | if (idle || daemon) { | 2243 | if (idle || daemon) { |
2241 | if (idle) | 2244 | if (idle) |
2242 | kdb_printf("%d idle process%s (state I)%s\n", | 2245 | kdb_printf("%d idle process%s (state I)%s\n", |
2243 | idle, idle == 1 ? "" : "es", | 2246 | idle, idle == 1 ? "" : "es", |
2244 | daemon ? " and " : ""); | 2247 | daemon ? " and " : ""); |
2245 | if (daemon) | 2248 | if (daemon) |
2246 | kdb_printf("%d sleeping system daemon (state M) " | 2249 | kdb_printf("%d sleeping system daemon (state M) " |
2247 | "process%s", daemon, | 2250 | "process%s", daemon, |
2248 | daemon == 1 ? "" : "es"); | 2251 | daemon == 1 ? "" : "es"); |
2249 | kdb_printf(" suppressed,\nuse 'ps A' to see all.\n"); | 2252 | kdb_printf(" suppressed,\nuse 'ps A' to see all.\n"); |
2250 | } | 2253 | } |
2251 | } | 2254 | } |
2252 | 2255 | ||
2253 | /* | 2256 | /* |
2254 | * kdb_ps - This function implements the 'ps' command which shows a | 2257 | * kdb_ps - This function implements the 'ps' command which shows a |
2255 | * list of the active processes. | 2258 | * list of the active processes. |
2256 | * ps [DRSTCZEUIMA] All processes, optionally filtered by state | 2259 | * ps [DRSTCZEUIMA] All processes, optionally filtered by state |
2257 | */ | 2260 | */ |
2258 | void kdb_ps1(const struct task_struct *p) | 2261 | void kdb_ps1(const struct task_struct *p) |
2259 | { | 2262 | { |
2260 | int cpu; | 2263 | int cpu; |
2261 | unsigned long tmp; | 2264 | unsigned long tmp; |
2262 | 2265 | ||
2263 | if (!p || probe_kernel_read(&tmp, (char *)p, sizeof(unsigned long))) | 2266 | if (!p || probe_kernel_read(&tmp, (char *)p, sizeof(unsigned long))) |
2264 | return; | 2267 | return; |
2265 | 2268 | ||
2266 | cpu = kdb_process_cpu(p); | 2269 | cpu = kdb_process_cpu(p); |
2267 | kdb_printf("0x%p %8d %8d %d %4d %c 0x%p %c%s\n", | 2270 | kdb_printf("0x%p %8d %8d %d %4d %c 0x%p %c%s\n", |
2268 | (void *)p, p->pid, p->parent->pid, | 2271 | (void *)p, p->pid, p->parent->pid, |
2269 | kdb_task_has_cpu(p), kdb_process_cpu(p), | 2272 | kdb_task_has_cpu(p), kdb_process_cpu(p), |
2270 | kdb_task_state_char(p), | 2273 | kdb_task_state_char(p), |
2271 | (void *)(&p->thread), | 2274 | (void *)(&p->thread), |
2272 | p == kdb_curr_task(raw_smp_processor_id()) ? '*' : ' ', | 2275 | p == kdb_curr_task(raw_smp_processor_id()) ? '*' : ' ', |
2273 | p->comm); | 2276 | p->comm); |
2274 | if (kdb_task_has_cpu(p)) { | 2277 | if (kdb_task_has_cpu(p)) { |
2275 | if (!KDB_TSK(cpu)) { | 2278 | if (!KDB_TSK(cpu)) { |
2276 | kdb_printf(" Error: no saved data for this cpu\n"); | 2279 | kdb_printf(" Error: no saved data for this cpu\n"); |
2277 | } else { | 2280 | } else { |
2278 | if (KDB_TSK(cpu) != p) | 2281 | if (KDB_TSK(cpu) != p) |
2279 | kdb_printf(" Error: does not match running " | 2282 | kdb_printf(" Error: does not match running " |
2280 | "process table (0x%p)\n", KDB_TSK(cpu)); | 2283 | "process table (0x%p)\n", KDB_TSK(cpu)); |
2281 | } | 2284 | } |
2282 | } | 2285 | } |
2283 | } | 2286 | } |
2284 | 2287 | ||
2285 | static int kdb_ps(int argc, const char **argv) | 2288 | static int kdb_ps(int argc, const char **argv) |
2286 | { | 2289 | { |
2287 | struct task_struct *g, *p; | 2290 | struct task_struct *g, *p; |
2288 | unsigned long mask, cpu; | 2291 | unsigned long mask, cpu; |
2289 | 2292 | ||
2290 | if (argc == 0) | 2293 | if (argc == 0) |
2291 | kdb_ps_suppressed(); | 2294 | kdb_ps_suppressed(); |
2292 | kdb_printf("%-*s Pid Parent [*] cpu State %-*s Command\n", | 2295 | kdb_printf("%-*s Pid Parent [*] cpu State %-*s Command\n", |
2293 | (int)(2*sizeof(void *))+2, "Task Addr", | 2296 | (int)(2*sizeof(void *))+2, "Task Addr", |
2294 | (int)(2*sizeof(void *))+2, "Thread"); | 2297 | (int)(2*sizeof(void *))+2, "Thread"); |
2295 | mask = kdb_task_state_string(argc ? argv[1] : NULL); | 2298 | mask = kdb_task_state_string(argc ? argv[1] : NULL); |
2296 | /* Run the active tasks first */ | 2299 | /* Run the active tasks first */ |
2297 | for_each_online_cpu(cpu) { | 2300 | for_each_online_cpu(cpu) { |
2298 | if (KDB_FLAG(CMD_INTERRUPT)) | 2301 | if (KDB_FLAG(CMD_INTERRUPT)) |
2299 | return 0; | 2302 | return 0; |
2300 | p = kdb_curr_task(cpu); | 2303 | p = kdb_curr_task(cpu); |
2301 | if (kdb_task_state(p, mask)) | 2304 | if (kdb_task_state(p, mask)) |
2302 | kdb_ps1(p); | 2305 | kdb_ps1(p); |
2303 | } | 2306 | } |
2304 | kdb_printf("\n"); | 2307 | kdb_printf("\n"); |
2305 | /* Now the real tasks */ | 2308 | /* Now the real tasks */ |
2306 | kdb_do_each_thread(g, p) { | 2309 | kdb_do_each_thread(g, p) { |
2307 | if (KDB_FLAG(CMD_INTERRUPT)) | 2310 | if (KDB_FLAG(CMD_INTERRUPT)) |
2308 | return 0; | 2311 | return 0; |
2309 | if (kdb_task_state(p, mask)) | 2312 | if (kdb_task_state(p, mask)) |
2310 | kdb_ps1(p); | 2313 | kdb_ps1(p); |
2311 | } kdb_while_each_thread(g, p); | 2314 | } kdb_while_each_thread(g, p); |
2312 | 2315 | ||
2313 | return 0; | 2316 | return 0; |
2314 | } | 2317 | } |
2315 | 2318 | ||
2316 | /* | 2319 | /* |
2317 | * kdb_pid - This function implements the 'pid' command which switches | 2320 | * kdb_pid - This function implements the 'pid' command which switches |
2318 | * the currently active process. | 2321 | * the currently active process. |
2319 | * pid [<pid> | R] | 2322 | * pid [<pid> | R] |
2320 | */ | 2323 | */ |
2321 | static int kdb_pid(int argc, const char **argv) | 2324 | static int kdb_pid(int argc, const char **argv) |
2322 | { | 2325 | { |
2323 | struct task_struct *p; | 2326 | struct task_struct *p; |
2324 | unsigned long val; | 2327 | unsigned long val; |
2325 | int diag; | 2328 | int diag; |
2326 | 2329 | ||
2327 | if (argc > 1) | 2330 | if (argc > 1) |
2328 | return KDB_ARGCOUNT; | 2331 | return KDB_ARGCOUNT; |
2329 | 2332 | ||
2330 | if (argc) { | 2333 | if (argc) { |
2331 | if (strcmp(argv[1], "R") == 0) { | 2334 | if (strcmp(argv[1], "R") == 0) { |
2332 | p = KDB_TSK(kdb_initial_cpu); | 2335 | p = KDB_TSK(kdb_initial_cpu); |
2333 | } else { | 2336 | } else { |
2334 | diag = kdbgetularg(argv[1], &val); | 2337 | diag = kdbgetularg(argv[1], &val); |
2335 | if (diag) | 2338 | if (diag) |
2336 | return KDB_BADINT; | 2339 | return KDB_BADINT; |
2337 | 2340 | ||
2338 | p = find_task_by_pid_ns((pid_t)val, &init_pid_ns); | 2341 | p = find_task_by_pid_ns((pid_t)val, &init_pid_ns); |
2339 | if (!p) { | 2342 | if (!p) { |
2340 | kdb_printf("No task with pid=%d\n", (pid_t)val); | 2343 | kdb_printf("No task with pid=%d\n", (pid_t)val); |
2341 | return 0; | 2344 | return 0; |
2342 | } | 2345 | } |
2343 | } | 2346 | } |
2344 | kdb_set_current_task(p); | 2347 | kdb_set_current_task(p); |
2345 | } | 2348 | } |
2346 | kdb_printf("KDB current process is %s(pid=%d)\n", | 2349 | kdb_printf("KDB current process is %s(pid=%d)\n", |
2347 | kdb_current_task->comm, | 2350 | kdb_current_task->comm, |
2348 | kdb_current_task->pid); | 2351 | kdb_current_task->pid); |
2349 | 2352 | ||
2350 | return 0; | 2353 | return 0; |
2351 | } | 2354 | } |
2352 | 2355 | ||
2353 | static int kdb_kgdb(int argc, const char **argv) | 2356 | static int kdb_kgdb(int argc, const char **argv) |
2354 | { | 2357 | { |
2355 | return KDB_CMD_KGDB; | 2358 | return KDB_CMD_KGDB; |
2356 | } | 2359 | } |
2357 | 2360 | ||
2358 | /* | 2361 | /* |
2359 | * kdb_help - This function implements the 'help' and '?' commands. | 2362 | * kdb_help - This function implements the 'help' and '?' commands. |
2360 | */ | 2363 | */ |
2361 | static int kdb_help(int argc, const char **argv) | 2364 | static int kdb_help(int argc, const char **argv) |
2362 | { | 2365 | { |
2363 | kdbtab_t *kt; | 2366 | kdbtab_t *kt; |
2364 | int i; | 2367 | int i; |
2365 | 2368 | ||
2366 | kdb_printf("%-15.15s %-20.20s %s\n", "Command", "Usage", "Description"); | 2369 | kdb_printf("%-15.15s %-20.20s %s\n", "Command", "Usage", "Description"); |
2367 | kdb_printf("-----------------------------" | 2370 | kdb_printf("-----------------------------" |
2368 | "-----------------------------\n"); | 2371 | "-----------------------------\n"); |
2369 | for_each_kdbcmd(kt, i) { | 2372 | for_each_kdbcmd(kt, i) { |
2370 | char *space = ""; | 2373 | char *space = ""; |
2371 | if (KDB_FLAG(CMD_INTERRUPT)) | 2374 | if (KDB_FLAG(CMD_INTERRUPT)) |
2372 | return 0; | 2375 | return 0; |
2373 | if (!kt->cmd_name) | 2376 | if (!kt->cmd_name) |
2374 | continue; | 2377 | continue; |
2375 | if (strlen(kt->cmd_usage) > 20) | 2378 | if (strlen(kt->cmd_usage) > 20) |
2376 | space = "\n "; | 2379 | space = "\n "; |
2377 | kdb_printf("%-15.15s %-20s%s%s\n", kt->cmd_name, | 2380 | kdb_printf("%-15.15s %-20s%s%s\n", kt->cmd_name, |
2378 | kt->cmd_usage, space, kt->cmd_help); | 2381 | kt->cmd_usage, space, kt->cmd_help); |
2379 | } | 2382 | } |
2380 | return 0; | 2383 | return 0; |
2381 | } | 2384 | } |
2382 | 2385 | ||
2383 | /* | 2386 | /* |
2384 | * kdb_kill - This function implements the 'kill' commands. | 2387 | * kdb_kill - This function implements the 'kill' commands. |
2385 | */ | 2388 | */ |
2386 | static int kdb_kill(int argc, const char **argv) | 2389 | static int kdb_kill(int argc, const char **argv) |
2387 | { | 2390 | { |
2388 | long sig, pid; | 2391 | long sig, pid; |
2389 | char *endp; | 2392 | char *endp; |
2390 | struct task_struct *p; | 2393 | struct task_struct *p; |
2391 | struct siginfo info; | 2394 | struct siginfo info; |
2392 | 2395 | ||
2393 | if (argc != 2) | 2396 | if (argc != 2) |
2394 | return KDB_ARGCOUNT; | 2397 | return KDB_ARGCOUNT; |
2395 | 2398 | ||
2396 | sig = simple_strtol(argv[1], &endp, 0); | 2399 | sig = simple_strtol(argv[1], &endp, 0); |
2397 | if (*endp) | 2400 | if (*endp) |
2398 | return KDB_BADINT; | 2401 | return KDB_BADINT; |
2399 | if (sig >= 0) { | 2402 | if (sig >= 0) { |
2400 | kdb_printf("Invalid signal parameter.<-signal>\n"); | 2403 | kdb_printf("Invalid signal parameter.<-signal>\n"); |
2401 | return 0; | 2404 | return 0; |
2402 | } | 2405 | } |
2403 | sig = -sig; | 2406 | sig = -sig; |
2404 | 2407 | ||
2405 | pid = simple_strtol(argv[2], &endp, 0); | 2408 | pid = simple_strtol(argv[2], &endp, 0); |
2406 | if (*endp) | 2409 | if (*endp) |
2407 | return KDB_BADINT; | 2410 | return KDB_BADINT; |
2408 | if (pid <= 0) { | 2411 | if (pid <= 0) { |
2409 | kdb_printf("Process ID must be large than 0.\n"); | 2412 | kdb_printf("Process ID must be large than 0.\n"); |
2410 | return 0; | 2413 | return 0; |
2411 | } | 2414 | } |
2412 | 2415 | ||
2413 | /* Find the process. */ | 2416 | /* Find the process. */ |
2414 | p = find_task_by_pid_ns(pid, &init_pid_ns); | 2417 | p = find_task_by_pid_ns(pid, &init_pid_ns); |
2415 | if (!p) { | 2418 | if (!p) { |
2416 | kdb_printf("The specified process isn't found.\n"); | 2419 | kdb_printf("The specified process isn't found.\n"); |
2417 | return 0; | 2420 | return 0; |
2418 | } | 2421 | } |
2419 | p = p->group_leader; | 2422 | p = p->group_leader; |
2420 | info.si_signo = sig; | 2423 | info.si_signo = sig; |
2421 | info.si_errno = 0; | 2424 | info.si_errno = 0; |
2422 | info.si_code = SI_USER; | 2425 | info.si_code = SI_USER; |
2423 | info.si_pid = pid; /* same capabilities as process being signalled */ | 2426 | info.si_pid = pid; /* same capabilities as process being signalled */ |
2424 | info.si_uid = 0; /* kdb has root authority */ | 2427 | info.si_uid = 0; /* kdb has root authority */ |
2425 | kdb_send_sig_info(p, &info); | 2428 | kdb_send_sig_info(p, &info); |
2426 | return 0; | 2429 | return 0; |
2427 | } | 2430 | } |
2428 | 2431 | ||
2429 | struct kdb_tm { | 2432 | struct kdb_tm { |
2430 | int tm_sec; /* seconds */ | 2433 | int tm_sec; /* seconds */ |
2431 | int tm_min; /* minutes */ | 2434 | int tm_min; /* minutes */ |
2432 | int tm_hour; /* hours */ | 2435 | int tm_hour; /* hours */ |
2433 | int tm_mday; /* day of the month */ | 2436 | int tm_mday; /* day of the month */ |
2434 | int tm_mon; /* month */ | 2437 | int tm_mon; /* month */ |
2435 | int tm_year; /* year */ | 2438 | int tm_year; /* year */ |
2436 | }; | 2439 | }; |
2437 | 2440 | ||
2438 | static void kdb_gmtime(struct timespec *tv, struct kdb_tm *tm) | 2441 | static void kdb_gmtime(struct timespec *tv, struct kdb_tm *tm) |
2439 | { | 2442 | { |
2440 | /* This will work from 1970-2099, 2100 is not a leap year */ | 2443 | /* This will work from 1970-2099, 2100 is not a leap year */ |
2441 | static int mon_day[] = { 31, 29, 31, 30, 31, 30, 31, | 2444 | static int mon_day[] = { 31, 29, 31, 30, 31, 30, 31, |
2442 | 31, 30, 31, 30, 31 }; | 2445 | 31, 30, 31, 30, 31 }; |
2443 | memset(tm, 0, sizeof(*tm)); | 2446 | memset(tm, 0, sizeof(*tm)); |
2444 | tm->tm_sec = tv->tv_sec % (24 * 60 * 60); | 2447 | tm->tm_sec = tv->tv_sec % (24 * 60 * 60); |
2445 | tm->tm_mday = tv->tv_sec / (24 * 60 * 60) + | 2448 | tm->tm_mday = tv->tv_sec / (24 * 60 * 60) + |
2446 | (2 * 365 + 1); /* shift base from 1970 to 1968 */ | 2449 | (2 * 365 + 1); /* shift base from 1970 to 1968 */ |
2447 | tm->tm_min = tm->tm_sec / 60 % 60; | 2450 | tm->tm_min = tm->tm_sec / 60 % 60; |
2448 | tm->tm_hour = tm->tm_sec / 60 / 60; | 2451 | tm->tm_hour = tm->tm_sec / 60 / 60; |
2449 | tm->tm_sec = tm->tm_sec % 60; | 2452 | tm->tm_sec = tm->tm_sec % 60; |
2450 | tm->tm_year = 68 + 4*(tm->tm_mday / (4*365+1)); | 2453 | tm->tm_year = 68 + 4*(tm->tm_mday / (4*365+1)); |
2451 | tm->tm_mday %= (4*365+1); | 2454 | tm->tm_mday %= (4*365+1); |
2452 | mon_day[1] = 29; | 2455 | mon_day[1] = 29; |
2453 | while (tm->tm_mday >= mon_day[tm->tm_mon]) { | 2456 | while (tm->tm_mday >= mon_day[tm->tm_mon]) { |
2454 | tm->tm_mday -= mon_day[tm->tm_mon]; | 2457 | tm->tm_mday -= mon_day[tm->tm_mon]; |
2455 | if (++tm->tm_mon == 12) { | 2458 | if (++tm->tm_mon == 12) { |
2456 | tm->tm_mon = 0; | 2459 | tm->tm_mon = 0; |
2457 | ++tm->tm_year; | 2460 | ++tm->tm_year; |
2458 | mon_day[1] = 28; | 2461 | mon_day[1] = 28; |
2459 | } | 2462 | } |
2460 | } | 2463 | } |
2461 | ++tm->tm_mday; | 2464 | ++tm->tm_mday; |
2462 | } | 2465 | } |
2463 | 2466 | ||
2464 | /* | 2467 | /* |
2465 | * Most of this code has been lifted from kernel/timer.c::sys_sysinfo(). | 2468 | * Most of this code has been lifted from kernel/timer.c::sys_sysinfo(). |
2466 | * I cannot call that code directly from kdb, it has an unconditional | 2469 | * I cannot call that code directly from kdb, it has an unconditional |
2467 | * cli()/sti() and calls routines that take locks which can stop the debugger. | 2470 | * cli()/sti() and calls routines that take locks which can stop the debugger. |
2468 | */ | 2471 | */ |
2469 | static void kdb_sysinfo(struct sysinfo *val) | 2472 | static void kdb_sysinfo(struct sysinfo *val) |
2470 | { | 2473 | { |
2471 | struct timespec uptime; | 2474 | struct timespec uptime; |
2472 | do_posix_clock_monotonic_gettime(&uptime); | 2475 | do_posix_clock_monotonic_gettime(&uptime); |
2473 | memset(val, 0, sizeof(*val)); | 2476 | memset(val, 0, sizeof(*val)); |
2474 | val->uptime = uptime.tv_sec; | 2477 | val->uptime = uptime.tv_sec; |
2475 | val->loads[0] = avenrun[0]; | 2478 | val->loads[0] = avenrun[0]; |
2476 | val->loads[1] = avenrun[1]; | 2479 | val->loads[1] = avenrun[1]; |
2477 | val->loads[2] = avenrun[2]; | 2480 | val->loads[2] = avenrun[2]; |
2478 | val->procs = nr_threads-1; | 2481 | val->procs = nr_threads-1; |
2479 | si_meminfo(val); | 2482 | si_meminfo(val); |
2480 | 2483 | ||
2481 | return; | 2484 | return; |
2482 | } | 2485 | } |
2483 | 2486 | ||
2484 | /* | 2487 | /* |
2485 | * kdb_summary - This function implements the 'summary' command. | 2488 | * kdb_summary - This function implements the 'summary' command. |
2486 | */ | 2489 | */ |
2487 | static int kdb_summary(int argc, const char **argv) | 2490 | static int kdb_summary(int argc, const char **argv) |
2488 | { | 2491 | { |
2489 | struct timespec now; | 2492 | struct timespec now; |
2490 | struct kdb_tm tm; | 2493 | struct kdb_tm tm; |
2491 | struct sysinfo val; | 2494 | struct sysinfo val; |
2492 | 2495 | ||
2493 | if (argc) | 2496 | if (argc) |
2494 | return KDB_ARGCOUNT; | 2497 | return KDB_ARGCOUNT; |
2495 | 2498 | ||
2496 | kdb_printf("sysname %s\n", init_uts_ns.name.sysname); | 2499 | kdb_printf("sysname %s\n", init_uts_ns.name.sysname); |
2497 | kdb_printf("release %s\n", init_uts_ns.name.release); | 2500 | kdb_printf("release %s\n", init_uts_ns.name.release); |
2498 | kdb_printf("version %s\n", init_uts_ns.name.version); | 2501 | kdb_printf("version %s\n", init_uts_ns.name.version); |
2499 | kdb_printf("machine %s\n", init_uts_ns.name.machine); | 2502 | kdb_printf("machine %s\n", init_uts_ns.name.machine); |
2500 | kdb_printf("nodename %s\n", init_uts_ns.name.nodename); | 2503 | kdb_printf("nodename %s\n", init_uts_ns.name.nodename); |
2501 | kdb_printf("domainname %s\n", init_uts_ns.name.domainname); | 2504 | kdb_printf("domainname %s\n", init_uts_ns.name.domainname); |
2502 | kdb_printf("ccversion %s\n", __stringify(CCVERSION)); | 2505 | kdb_printf("ccversion %s\n", __stringify(CCVERSION)); |
2503 | 2506 | ||
2504 | now = __current_kernel_time(); | 2507 | now = __current_kernel_time(); |
2505 | kdb_gmtime(&now, &tm); | 2508 | kdb_gmtime(&now, &tm); |
2506 | kdb_printf("date %04d-%02d-%02d %02d:%02d:%02d " | 2509 | kdb_printf("date %04d-%02d-%02d %02d:%02d:%02d " |
2507 | "tz_minuteswest %d\n", | 2510 | "tz_minuteswest %d\n", |
2508 | 1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday, | 2511 | 1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday, |
2509 | tm.tm_hour, tm.tm_min, tm.tm_sec, | 2512 | tm.tm_hour, tm.tm_min, tm.tm_sec, |
2510 | sys_tz.tz_minuteswest); | 2513 | sys_tz.tz_minuteswest); |
2511 | 2514 | ||
2512 | kdb_sysinfo(&val); | 2515 | kdb_sysinfo(&val); |
2513 | kdb_printf("uptime "); | 2516 | kdb_printf("uptime "); |
2514 | if (val.uptime > (24*60*60)) { | 2517 | if (val.uptime > (24*60*60)) { |
2515 | int days = val.uptime / (24*60*60); | 2518 | int days = val.uptime / (24*60*60); |
2516 | val.uptime %= (24*60*60); | 2519 | val.uptime %= (24*60*60); |
2517 | kdb_printf("%d day%s ", days, days == 1 ? "" : "s"); | 2520 | kdb_printf("%d day%s ", days, days == 1 ? "" : "s"); |
2518 | } | 2521 | } |
2519 | kdb_printf("%02ld:%02ld\n", val.uptime/(60*60), (val.uptime/60)%60); | 2522 | kdb_printf("%02ld:%02ld\n", val.uptime/(60*60), (val.uptime/60)%60); |
2520 | 2523 | ||
2521 | /* lifted from fs/proc/proc_misc.c::loadavg_read_proc() */ | 2524 | /* lifted from fs/proc/proc_misc.c::loadavg_read_proc() */ |
2522 | 2525 | ||
2523 | #define LOAD_INT(x) ((x) >> FSHIFT) | 2526 | #define LOAD_INT(x) ((x) >> FSHIFT) |
2524 | #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) | 2527 | #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) |
2525 | kdb_printf("load avg %ld.%02ld %ld.%02ld %ld.%02ld\n", | 2528 | kdb_printf("load avg %ld.%02ld %ld.%02ld %ld.%02ld\n", |
2526 | LOAD_INT(val.loads[0]), LOAD_FRAC(val.loads[0]), | 2529 | LOAD_INT(val.loads[0]), LOAD_FRAC(val.loads[0]), |
2527 | LOAD_INT(val.loads[1]), LOAD_FRAC(val.loads[1]), | 2530 | LOAD_INT(val.loads[1]), LOAD_FRAC(val.loads[1]), |
2528 | LOAD_INT(val.loads[2]), LOAD_FRAC(val.loads[2])); | 2531 | LOAD_INT(val.loads[2]), LOAD_FRAC(val.loads[2])); |
2529 | #undef LOAD_INT | 2532 | #undef LOAD_INT |
2530 | #undef LOAD_FRAC | 2533 | #undef LOAD_FRAC |
2531 | /* Display in kilobytes */ | 2534 | /* Display in kilobytes */ |
2532 | #define K(x) ((x) << (PAGE_SHIFT - 10)) | 2535 | #define K(x) ((x) << (PAGE_SHIFT - 10)) |
2533 | kdb_printf("\nMemTotal: %8lu kB\nMemFree: %8lu kB\n" | 2536 | kdb_printf("\nMemTotal: %8lu kB\nMemFree: %8lu kB\n" |
2534 | "Buffers: %8lu kB\n", | 2537 | "Buffers: %8lu kB\n", |
2535 | val.totalram, val.freeram, val.bufferram); | 2538 | val.totalram, val.freeram, val.bufferram); |
2536 | return 0; | 2539 | return 0; |
2537 | } | 2540 | } |
2538 | 2541 | ||
2539 | /* | 2542 | /* |
2540 | * kdb_per_cpu - This function implements the 'per_cpu' command. | 2543 | * kdb_per_cpu - This function implements the 'per_cpu' command. |
2541 | */ | 2544 | */ |
2542 | static int kdb_per_cpu(int argc, const char **argv) | 2545 | static int kdb_per_cpu(int argc, const char **argv) |
2543 | { | 2546 | { |
2544 | char fmtstr[64]; | 2547 | char fmtstr[64]; |
2545 | int cpu, diag, nextarg = 1; | 2548 | int cpu, diag, nextarg = 1; |
2546 | unsigned long addr, symaddr, val, bytesperword = 0, whichcpu = ~0UL; | 2549 | unsigned long addr, symaddr, val, bytesperword = 0, whichcpu = ~0UL; |
2547 | 2550 | ||
2548 | if (argc < 1 || argc > 3) | 2551 | if (argc < 1 || argc > 3) |
2549 | return KDB_ARGCOUNT; | 2552 | return KDB_ARGCOUNT; |
2550 | 2553 | ||
2551 | diag = kdbgetaddrarg(argc, argv, &nextarg, &symaddr, NULL, NULL); | 2554 | diag = kdbgetaddrarg(argc, argv, &nextarg, &symaddr, NULL, NULL); |
2552 | if (diag) | 2555 | if (diag) |
2553 | return diag; | 2556 | return diag; |
2554 | 2557 | ||
2555 | if (argc >= 2) { | 2558 | if (argc >= 2) { |
2556 | diag = kdbgetularg(argv[2], &bytesperword); | 2559 | diag = kdbgetularg(argv[2], &bytesperword); |
2557 | if (diag) | 2560 | if (diag) |
2558 | return diag; | 2561 | return diag; |
2559 | } | 2562 | } |
2560 | if (!bytesperword) | 2563 | if (!bytesperword) |
2561 | bytesperword = KDB_WORD_SIZE; | 2564 | bytesperword = KDB_WORD_SIZE; |
2562 | else if (bytesperword > KDB_WORD_SIZE) | 2565 | else if (bytesperword > KDB_WORD_SIZE) |
2563 | return KDB_BADWIDTH; | 2566 | return KDB_BADWIDTH; |
2564 | sprintf(fmtstr, "%%0%dlx ", (int)(2*bytesperword)); | 2567 | sprintf(fmtstr, "%%0%dlx ", (int)(2*bytesperword)); |
2565 | if (argc >= 3) { | 2568 | if (argc >= 3) { |
2566 | diag = kdbgetularg(argv[3], &whichcpu); | 2569 | diag = kdbgetularg(argv[3], &whichcpu); |
2567 | if (diag) | 2570 | if (diag) |
2568 | return diag; | 2571 | return diag; |
2569 | if (!cpu_online(whichcpu)) { | 2572 | if (!cpu_online(whichcpu)) { |
2570 | kdb_printf("cpu %ld is not online\n", whichcpu); | 2573 | kdb_printf("cpu %ld is not online\n", whichcpu); |
2571 | return KDB_BADCPUNUM; | 2574 | return KDB_BADCPUNUM; |
2572 | } | 2575 | } |
2573 | } | 2576 | } |
2574 | 2577 | ||
2575 | /* Most architectures use __per_cpu_offset[cpu], some use | 2578 | /* Most architectures use __per_cpu_offset[cpu], some use |
2576 | * __per_cpu_offset(cpu), smp has no __per_cpu_offset. | 2579 | * __per_cpu_offset(cpu), smp has no __per_cpu_offset. |
2577 | */ | 2580 | */ |
2578 | #ifdef __per_cpu_offset | 2581 | #ifdef __per_cpu_offset |
2579 | #define KDB_PCU(cpu) __per_cpu_offset(cpu) | 2582 | #define KDB_PCU(cpu) __per_cpu_offset(cpu) |
2580 | #else | 2583 | #else |
2581 | #ifdef CONFIG_SMP | 2584 | #ifdef CONFIG_SMP |
2582 | #define KDB_PCU(cpu) __per_cpu_offset[cpu] | 2585 | #define KDB_PCU(cpu) __per_cpu_offset[cpu] |
2583 | #else | 2586 | #else |
2584 | #define KDB_PCU(cpu) 0 | 2587 | #define KDB_PCU(cpu) 0 |
2585 | #endif | 2588 | #endif |
2586 | #endif | 2589 | #endif |
2587 | for_each_online_cpu(cpu) { | 2590 | for_each_online_cpu(cpu) { |
2588 | if (KDB_FLAG(CMD_INTERRUPT)) | 2591 | if (KDB_FLAG(CMD_INTERRUPT)) |
2589 | return 0; | 2592 | return 0; |
2590 | 2593 | ||
2591 | if (whichcpu != ~0UL && whichcpu != cpu) | 2594 | if (whichcpu != ~0UL && whichcpu != cpu) |
2592 | continue; | 2595 | continue; |
2593 | addr = symaddr + KDB_PCU(cpu); | 2596 | addr = symaddr + KDB_PCU(cpu); |
2594 | diag = kdb_getword(&val, addr, bytesperword); | 2597 | diag = kdb_getword(&val, addr, bytesperword); |
2595 | if (diag) { | 2598 | if (diag) { |
2596 | kdb_printf("%5d " kdb_bfd_vma_fmt0 " - unable to " | 2599 | kdb_printf("%5d " kdb_bfd_vma_fmt0 " - unable to " |
2597 | "read, diag=%d\n", cpu, addr, diag); | 2600 | "read, diag=%d\n", cpu, addr, diag); |
2598 | continue; | 2601 | continue; |
2599 | } | 2602 | } |
2600 | kdb_printf("%5d ", cpu); | 2603 | kdb_printf("%5d ", cpu); |
2601 | kdb_md_line(fmtstr, addr, | 2604 | kdb_md_line(fmtstr, addr, |
2602 | bytesperword == KDB_WORD_SIZE, | 2605 | bytesperword == KDB_WORD_SIZE, |
2603 | 1, bytesperword, 1, 1, 0); | 2606 | 1, bytesperword, 1, 1, 0); |
2604 | } | 2607 | } |
2605 | #undef KDB_PCU | 2608 | #undef KDB_PCU |
2606 | return 0; | 2609 | return 0; |
2607 | } | 2610 | } |
2608 | 2611 | ||
2609 | /* | 2612 | /* |
2610 | * display help for the use of cmd | grep pattern | 2613 | * display help for the use of cmd | grep pattern |
2611 | */ | 2614 | */ |
2612 | static int kdb_grep_help(int argc, const char **argv) | 2615 | static int kdb_grep_help(int argc, const char **argv) |
2613 | { | 2616 | { |
2614 | kdb_printf("Usage of cmd args | grep pattern:\n"); | 2617 | kdb_printf("Usage of cmd args | grep pattern:\n"); |
2615 | kdb_printf(" Any command's output may be filtered through an "); | 2618 | kdb_printf(" Any command's output may be filtered through an "); |
2616 | kdb_printf("emulated 'pipe'.\n"); | 2619 | kdb_printf("emulated 'pipe'.\n"); |
2617 | kdb_printf(" 'grep' is just a key word.\n"); | 2620 | kdb_printf(" 'grep' is just a key word.\n"); |
2618 | kdb_printf(" The pattern may include a very limited set of " | 2621 | kdb_printf(" The pattern may include a very limited set of " |
2619 | "metacharacters:\n"); | 2622 | "metacharacters:\n"); |
2620 | kdb_printf(" pattern or ^pattern or pattern$ or ^pattern$\n"); | 2623 | kdb_printf(" pattern or ^pattern or pattern$ or ^pattern$\n"); |
2621 | kdb_printf(" And if there are spaces in the pattern, you may " | 2624 | kdb_printf(" And if there are spaces in the pattern, you may " |
2622 | "quote it:\n"); | 2625 | "quote it:\n"); |
2623 | kdb_printf(" \"pat tern\" or \"^pat tern\" or \"pat tern$\"" | 2626 | kdb_printf(" \"pat tern\" or \"^pat tern\" or \"pat tern$\"" |
2624 | " or \"^pat tern$\"\n"); | 2627 | " or \"^pat tern$\"\n"); |
2625 | return 0; | 2628 | return 0; |
2626 | } | 2629 | } |
2627 | 2630 | ||
2628 | /* | 2631 | /* |
2629 | * kdb_register_repeat - This function is used to register a kernel | 2632 | * kdb_register_repeat - This function is used to register a kernel |
2630 | * debugger command. | 2633 | * debugger command. |
2631 | * Inputs: | 2634 | * Inputs: |
2632 | * cmd Command name | 2635 | * cmd Command name |
2633 | * func Function to execute the command | 2636 | * func Function to execute the command |
2634 | * usage A simple usage string showing arguments | 2637 | * usage A simple usage string showing arguments |
2635 | * help A simple help string describing command | 2638 | * help A simple help string describing command |
2636 | * repeat Does the command auto repeat on enter? | 2639 | * repeat Does the command auto repeat on enter? |
2637 | * Returns: | 2640 | * Returns: |
2638 | * zero for success, one if a duplicate command. | 2641 | * zero for success, one if a duplicate command. |
2639 | */ | 2642 | */ |
2640 | #define kdb_command_extend 50 /* arbitrary */ | 2643 | #define kdb_command_extend 50 /* arbitrary */ |
2641 | int kdb_register_repeat(char *cmd, | 2644 | int kdb_register_repeat(char *cmd, |
2642 | kdb_func_t func, | 2645 | kdb_func_t func, |
2643 | char *usage, | 2646 | char *usage, |
2644 | char *help, | 2647 | char *help, |
2645 | short minlen, | 2648 | short minlen, |
2646 | kdb_repeat_t repeat) | 2649 | kdb_repeat_t repeat) |
2647 | { | 2650 | { |
2648 | int i; | 2651 | int i; |
2649 | kdbtab_t *kp; | 2652 | kdbtab_t *kp; |
2650 | 2653 | ||
2651 | /* | 2654 | /* |
2652 | * Brute force method to determine duplicates | 2655 | * Brute force method to determine duplicates |
2653 | */ | 2656 | */ |
2654 | for_each_kdbcmd(kp, i) { | 2657 | for_each_kdbcmd(kp, i) { |
2655 | if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) { | 2658 | if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) { |
2656 | kdb_printf("Duplicate kdb command registered: " | 2659 | kdb_printf("Duplicate kdb command registered: " |
2657 | "%s, func %p help %s\n", cmd, func, help); | 2660 | "%s, func %p help %s\n", cmd, func, help); |
2658 | return 1; | 2661 | return 1; |
2659 | } | 2662 | } |
2660 | } | 2663 | } |
2661 | 2664 | ||
2662 | /* | 2665 | /* |
2663 | * Insert command into first available location in table | 2666 | * Insert command into first available location in table |
2664 | */ | 2667 | */ |
2665 | for_each_kdbcmd(kp, i) { | 2668 | for_each_kdbcmd(kp, i) { |
2666 | if (kp->cmd_name == NULL) | 2669 | if (kp->cmd_name == NULL) |
2667 | break; | 2670 | break; |
2668 | } | 2671 | } |
2669 | 2672 | ||
2670 | if (i >= kdb_max_commands) { | 2673 | if (i >= kdb_max_commands) { |
2671 | kdbtab_t *new = kmalloc((kdb_max_commands - KDB_BASE_CMD_MAX + | 2674 | kdbtab_t *new = kmalloc((kdb_max_commands - KDB_BASE_CMD_MAX + |
2672 | kdb_command_extend) * sizeof(*new), GFP_KDB); | 2675 | kdb_command_extend) * sizeof(*new), GFP_KDB); |
2673 | if (!new) { | 2676 | if (!new) { |
2674 | kdb_printf("Could not allocate new kdb_command " | 2677 | kdb_printf("Could not allocate new kdb_command " |
2675 | "table\n"); | 2678 | "table\n"); |
2676 | return 1; | 2679 | return 1; |
2677 | } | 2680 | } |
2678 | if (kdb_commands) { | 2681 | if (kdb_commands) { |
2679 | memcpy(new, kdb_commands, | 2682 | memcpy(new, kdb_commands, |
2680 | (kdb_max_commands - KDB_BASE_CMD_MAX) * sizeof(*new)); | 2683 | (kdb_max_commands - KDB_BASE_CMD_MAX) * sizeof(*new)); |
2681 | kfree(kdb_commands); | 2684 | kfree(kdb_commands); |
2682 | } | 2685 | } |
2683 | memset(new + kdb_max_commands - KDB_BASE_CMD_MAX, 0, | 2686 | memset(new + kdb_max_commands - KDB_BASE_CMD_MAX, 0, |
2684 | kdb_command_extend * sizeof(*new)); | 2687 | kdb_command_extend * sizeof(*new)); |
2685 | kdb_commands = new; | 2688 | kdb_commands = new; |
2686 | kp = kdb_commands + kdb_max_commands - KDB_BASE_CMD_MAX; | 2689 | kp = kdb_commands + kdb_max_commands - KDB_BASE_CMD_MAX; |
2687 | kdb_max_commands += kdb_command_extend; | 2690 | kdb_max_commands += kdb_command_extend; |
2688 | } | 2691 | } |
2689 | 2692 | ||
2690 | kp->cmd_name = cmd; | 2693 | kp->cmd_name = cmd; |
2691 | kp->cmd_func = func; | 2694 | kp->cmd_func = func; |
2692 | kp->cmd_usage = usage; | 2695 | kp->cmd_usage = usage; |
2693 | kp->cmd_help = help; | 2696 | kp->cmd_help = help; |
2694 | kp->cmd_flags = 0; | 2697 | kp->cmd_flags = 0; |
2695 | kp->cmd_minlen = minlen; | 2698 | kp->cmd_minlen = minlen; |
2696 | kp->cmd_repeat = repeat; | 2699 | kp->cmd_repeat = repeat; |
2697 | 2700 | ||
2698 | return 0; | 2701 | return 0; |
2699 | } | 2702 | } |
2700 | EXPORT_SYMBOL_GPL(kdb_register_repeat); | 2703 | EXPORT_SYMBOL_GPL(kdb_register_repeat); |
2701 | 2704 | ||
2702 | 2705 | ||
2703 | /* | 2706 | /* |
2704 | * kdb_register - Compatibility register function for commands that do | 2707 | * kdb_register - Compatibility register function for commands that do |
2705 | * not need to specify a repeat state. Equivalent to | 2708 | * not need to specify a repeat state. Equivalent to |
2706 | * kdb_register_repeat with KDB_REPEAT_NONE. | 2709 | * kdb_register_repeat with KDB_REPEAT_NONE. |
2707 | * Inputs: | 2710 | * Inputs: |
2708 | * cmd Command name | 2711 | * cmd Command name |
2709 | * func Function to execute the command | 2712 | * func Function to execute the command |
2710 | * usage A simple usage string showing arguments | 2713 | * usage A simple usage string showing arguments |
2711 | * help A simple help string describing command | 2714 | * help A simple help string describing command |
2712 | * Returns: | 2715 | * Returns: |
2713 | * zero for success, one if a duplicate command. | 2716 | * zero for success, one if a duplicate command. |
2714 | */ | 2717 | */ |
2715 | int kdb_register(char *cmd, | 2718 | int kdb_register(char *cmd, |
2716 | kdb_func_t func, | 2719 | kdb_func_t func, |
2717 | char *usage, | 2720 | char *usage, |
2718 | char *help, | 2721 | char *help, |
2719 | short minlen) | 2722 | short minlen) |
2720 | { | 2723 | { |
2721 | return kdb_register_repeat(cmd, func, usage, help, minlen, | 2724 | return kdb_register_repeat(cmd, func, usage, help, minlen, |
2722 | KDB_REPEAT_NONE); | 2725 | KDB_REPEAT_NONE); |
2723 | } | 2726 | } |
2724 | EXPORT_SYMBOL_GPL(kdb_register); | 2727 | EXPORT_SYMBOL_GPL(kdb_register); |
2725 | 2728 | ||
2726 | /* | 2729 | /* |
2727 | * kdb_unregister - This function is used to unregister a kernel | 2730 | * kdb_unregister - This function is used to unregister a kernel |
2728 | * debugger command. It is generally called when a module which | 2731 | * debugger command. It is generally called when a module which |
2729 | * implements kdb commands is unloaded. | 2732 | * implements kdb commands is unloaded. |
2730 | * Inputs: | 2733 | * Inputs: |
2731 | * cmd Command name | 2734 | * cmd Command name |
2732 | * Returns: | 2735 | * Returns: |
2733 | * zero for success, one command not registered. | 2736 | * zero for success, one command not registered. |
2734 | */ | 2737 | */ |
2735 | int kdb_unregister(char *cmd) | 2738 | int kdb_unregister(char *cmd) |
2736 | { | 2739 | { |
2737 | int i; | 2740 | int i; |
2738 | kdbtab_t *kp; | 2741 | kdbtab_t *kp; |
2739 | 2742 | ||
2740 | /* | 2743 | /* |
2741 | * find the command. | 2744 | * find the command. |
2742 | */ | 2745 | */ |
2743 | for_each_kdbcmd(kp, i) { | 2746 | for_each_kdbcmd(kp, i) { |
2744 | if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) { | 2747 | if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) { |
2745 | kp->cmd_name = NULL; | 2748 | kp->cmd_name = NULL; |
2746 | return 0; | 2749 | return 0; |
2747 | } | 2750 | } |
2748 | } | 2751 | } |
2749 | 2752 | ||
2750 | /* Couldn't find it. */ | 2753 | /* Couldn't find it. */ |
2751 | return 1; | 2754 | return 1; |
2752 | } | 2755 | } |
2753 | EXPORT_SYMBOL_GPL(kdb_unregister); | 2756 | EXPORT_SYMBOL_GPL(kdb_unregister); |
2754 | 2757 | ||
2755 | /* Initialize the kdb command table. */ | 2758 | /* Initialize the kdb command table. */ |
2756 | static void __init kdb_inittab(void) | 2759 | static void __init kdb_inittab(void) |
2757 | { | 2760 | { |
2758 | int i; | 2761 | int i; |
2759 | kdbtab_t *kp; | 2762 | kdbtab_t *kp; |
2760 | 2763 | ||
2761 | for_each_kdbcmd(kp, i) | 2764 | for_each_kdbcmd(kp, i) |
2762 | kp->cmd_name = NULL; | 2765 | kp->cmd_name = NULL; |
2763 | 2766 | ||
2764 | kdb_register_repeat("md", kdb_md, "<vaddr>", | 2767 | kdb_register_repeat("md", kdb_md, "<vaddr>", |
2765 | "Display Memory Contents, also mdWcN, e.g. md8c1", 1, | 2768 | "Display Memory Contents, also mdWcN, e.g. md8c1", 1, |
2766 | KDB_REPEAT_NO_ARGS); | 2769 | KDB_REPEAT_NO_ARGS); |
2767 | kdb_register_repeat("mdr", kdb_md, "<vaddr> <bytes>", | 2770 | kdb_register_repeat("mdr", kdb_md, "<vaddr> <bytes>", |
2768 | "Display Raw Memory", 0, KDB_REPEAT_NO_ARGS); | 2771 | "Display Raw Memory", 0, KDB_REPEAT_NO_ARGS); |
2769 | kdb_register_repeat("mdp", kdb_md, "<paddr> <bytes>", | 2772 | kdb_register_repeat("mdp", kdb_md, "<paddr> <bytes>", |
2770 | "Display Physical Memory", 0, KDB_REPEAT_NO_ARGS); | 2773 | "Display Physical Memory", 0, KDB_REPEAT_NO_ARGS); |
2771 | kdb_register_repeat("mds", kdb_md, "<vaddr>", | 2774 | kdb_register_repeat("mds", kdb_md, "<vaddr>", |
2772 | "Display Memory Symbolically", 0, KDB_REPEAT_NO_ARGS); | 2775 | "Display Memory Symbolically", 0, KDB_REPEAT_NO_ARGS); |
2773 | kdb_register_repeat("mm", kdb_mm, "<vaddr> <contents>", | 2776 | kdb_register_repeat("mm", kdb_mm, "<vaddr> <contents>", |
2774 | "Modify Memory Contents", 0, KDB_REPEAT_NO_ARGS); | 2777 | "Modify Memory Contents", 0, KDB_REPEAT_NO_ARGS); |
2775 | kdb_register_repeat("go", kdb_go, "[<vaddr>]", | 2778 | kdb_register_repeat("go", kdb_go, "[<vaddr>]", |
2776 | "Continue Execution", 1, KDB_REPEAT_NONE); | 2779 | "Continue Execution", 1, KDB_REPEAT_NONE); |
2777 | kdb_register_repeat("rd", kdb_rd, "", | 2780 | kdb_register_repeat("rd", kdb_rd, "", |
2778 | "Display Registers", 0, KDB_REPEAT_NONE); | 2781 | "Display Registers", 0, KDB_REPEAT_NONE); |
2779 | kdb_register_repeat("rm", kdb_rm, "<reg> <contents>", | 2782 | kdb_register_repeat("rm", kdb_rm, "<reg> <contents>", |
2780 | "Modify Registers", 0, KDB_REPEAT_NONE); | 2783 | "Modify Registers", 0, KDB_REPEAT_NONE); |
2781 | kdb_register_repeat("ef", kdb_ef, "<vaddr>", | 2784 | kdb_register_repeat("ef", kdb_ef, "<vaddr>", |
2782 | "Display exception frame", 0, KDB_REPEAT_NONE); | 2785 | "Display exception frame", 0, KDB_REPEAT_NONE); |
2783 | kdb_register_repeat("bt", kdb_bt, "[<vaddr>]", | 2786 | kdb_register_repeat("bt", kdb_bt, "[<vaddr>]", |
2784 | "Stack traceback", 1, KDB_REPEAT_NONE); | 2787 | "Stack traceback", 1, KDB_REPEAT_NONE); |
2785 | kdb_register_repeat("btp", kdb_bt, "<pid>", | 2788 | kdb_register_repeat("btp", kdb_bt, "<pid>", |
2786 | "Display stack for process <pid>", 0, KDB_REPEAT_NONE); | 2789 | "Display stack for process <pid>", 0, KDB_REPEAT_NONE); |
2787 | kdb_register_repeat("bta", kdb_bt, "[D|R|S|T|C|Z|E|U|I|M|A]", | 2790 | kdb_register_repeat("bta", kdb_bt, "[D|R|S|T|C|Z|E|U|I|M|A]", |
2788 | "Backtrace all processes matching state flag", 0, KDB_REPEAT_NONE); | 2791 | "Backtrace all processes matching state flag", 0, KDB_REPEAT_NONE); |
2789 | kdb_register_repeat("btc", kdb_bt, "", | 2792 | kdb_register_repeat("btc", kdb_bt, "", |
2790 | "Backtrace current process on each cpu", 0, KDB_REPEAT_NONE); | 2793 | "Backtrace current process on each cpu", 0, KDB_REPEAT_NONE); |
2791 | kdb_register_repeat("btt", kdb_bt, "<vaddr>", | 2794 | kdb_register_repeat("btt", kdb_bt, "<vaddr>", |
2792 | "Backtrace process given its struct task address", 0, | 2795 | "Backtrace process given its struct task address", 0, |
2793 | KDB_REPEAT_NONE); | 2796 | KDB_REPEAT_NONE); |
2794 | kdb_register_repeat("env", kdb_env, "", | 2797 | kdb_register_repeat("env", kdb_env, "", |
2795 | "Show environment variables", 0, KDB_REPEAT_NONE); | 2798 | "Show environment variables", 0, KDB_REPEAT_NONE); |
2796 | kdb_register_repeat("set", kdb_set, "", | 2799 | kdb_register_repeat("set", kdb_set, "", |
2797 | "Set environment variables", 0, KDB_REPEAT_NONE); | 2800 | "Set environment variables", 0, KDB_REPEAT_NONE); |
2798 | kdb_register_repeat("help", kdb_help, "", | 2801 | kdb_register_repeat("help", kdb_help, "", |
2799 | "Display Help Message", 1, KDB_REPEAT_NONE); | 2802 | "Display Help Message", 1, KDB_REPEAT_NONE); |
2800 | kdb_register_repeat("?", kdb_help, "", | 2803 | kdb_register_repeat("?", kdb_help, "", |
2801 | "Display Help Message", 0, KDB_REPEAT_NONE); | 2804 | "Display Help Message", 0, KDB_REPEAT_NONE); |
2802 | kdb_register_repeat("cpu", kdb_cpu, "<cpunum>", | 2805 | kdb_register_repeat("cpu", kdb_cpu, "<cpunum>", |
2803 | "Switch to new cpu", 0, KDB_REPEAT_NONE); | 2806 | "Switch to new cpu", 0, KDB_REPEAT_NONE); |
2804 | kdb_register_repeat("kgdb", kdb_kgdb, "", | 2807 | kdb_register_repeat("kgdb", kdb_kgdb, "", |
2805 | "Enter kgdb mode", 0, KDB_REPEAT_NONE); | 2808 | "Enter kgdb mode", 0, KDB_REPEAT_NONE); |
2806 | kdb_register_repeat("ps", kdb_ps, "[<flags>|A]", | 2809 | kdb_register_repeat("ps", kdb_ps, "[<flags>|A]", |
2807 | "Display active task list", 0, KDB_REPEAT_NONE); | 2810 | "Display active task list", 0, KDB_REPEAT_NONE); |
2808 | kdb_register_repeat("pid", kdb_pid, "<pidnum>", | 2811 | kdb_register_repeat("pid", kdb_pid, "<pidnum>", |
2809 | "Switch to another task", 0, KDB_REPEAT_NONE); | 2812 | "Switch to another task", 0, KDB_REPEAT_NONE); |
2810 | kdb_register_repeat("reboot", kdb_reboot, "", | 2813 | kdb_register_repeat("reboot", kdb_reboot, "", |
2811 | "Reboot the machine immediately", 0, KDB_REPEAT_NONE); | 2814 | "Reboot the machine immediately", 0, KDB_REPEAT_NONE); |
2812 | #if defined(CONFIG_MODULES) | 2815 | #if defined(CONFIG_MODULES) |
2813 | kdb_register_repeat("lsmod", kdb_lsmod, "", | 2816 | kdb_register_repeat("lsmod", kdb_lsmod, "", |
2814 | "List loaded kernel modules", 0, KDB_REPEAT_NONE); | 2817 | "List loaded kernel modules", 0, KDB_REPEAT_NONE); |
2815 | #endif | 2818 | #endif |
2816 | #if defined(CONFIG_MAGIC_SYSRQ) | 2819 | #if defined(CONFIG_MAGIC_SYSRQ) |
2817 | kdb_register_repeat("sr", kdb_sr, "<key>", | 2820 | kdb_register_repeat("sr", kdb_sr, "<key>", |
2818 | "Magic SysRq key", 0, KDB_REPEAT_NONE); | 2821 | "Magic SysRq key", 0, KDB_REPEAT_NONE); |
2819 | #endif | 2822 | #endif |
2820 | #if defined(CONFIG_PRINTK) | 2823 | #if defined(CONFIG_PRINTK) |
2821 | kdb_register_repeat("dmesg", kdb_dmesg, "[lines]", | 2824 | kdb_register_repeat("dmesg", kdb_dmesg, "[lines]", |
2822 | "Display syslog buffer", 0, KDB_REPEAT_NONE); | 2825 | "Display syslog buffer", 0, KDB_REPEAT_NONE); |
2823 | #endif | 2826 | #endif |
2824 | if (arch_kgdb_ops.enable_nmi) { | 2827 | if (arch_kgdb_ops.enable_nmi) { |
2825 | kdb_register_repeat("disable_nmi", kdb_disable_nmi, "", | 2828 | kdb_register_repeat("disable_nmi", kdb_disable_nmi, "", |
2826 | "Disable NMI entry to KDB", 0, KDB_REPEAT_NONE); | 2829 | "Disable NMI entry to KDB", 0, KDB_REPEAT_NONE); |
2827 | } | 2830 | } |
2828 | kdb_register_repeat("defcmd", kdb_defcmd, "name \"usage\" \"help\"", | 2831 | kdb_register_repeat("defcmd", kdb_defcmd, "name \"usage\" \"help\"", |
2829 | "Define a set of commands, down to endefcmd", 0, KDB_REPEAT_NONE); | 2832 | "Define a set of commands, down to endefcmd", 0, KDB_REPEAT_NONE); |
2830 | kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>", | 2833 | kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>", |
2831 | "Send a signal to a process", 0, KDB_REPEAT_NONE); | 2834 | "Send a signal to a process", 0, KDB_REPEAT_NONE); |
2832 | kdb_register_repeat("summary", kdb_summary, "", | 2835 | kdb_register_repeat("summary", kdb_summary, "", |
2833 | "Summarize the system", 4, KDB_REPEAT_NONE); | 2836 | "Summarize the system", 4, KDB_REPEAT_NONE); |
2834 | kdb_register_repeat("per_cpu", kdb_per_cpu, "<sym> [<bytes>] [<cpu>]", | 2837 | kdb_register_repeat("per_cpu", kdb_per_cpu, "<sym> [<bytes>] [<cpu>]", |
2835 | "Display per_cpu variables", 3, KDB_REPEAT_NONE); | 2838 | "Display per_cpu variables", 3, KDB_REPEAT_NONE); |
2836 | kdb_register_repeat("grephelp", kdb_grep_help, "", | 2839 | kdb_register_repeat("grephelp", kdb_grep_help, "", |
2837 | "Display help on | grep", 0, KDB_REPEAT_NONE); | 2840 | "Display help on | grep", 0, KDB_REPEAT_NONE); |
2838 | } | 2841 | } |
2839 | 2842 | ||
2840 | /* Execute any commands defined in kdb_cmds. */ | 2843 | /* Execute any commands defined in kdb_cmds. */ |
2841 | static void __init kdb_cmd_init(void) | 2844 | static void __init kdb_cmd_init(void) |
2842 | { | 2845 | { |
2843 | int i, diag; | 2846 | int i, diag; |
2844 | for (i = 0; kdb_cmds[i]; ++i) { | 2847 | for (i = 0; kdb_cmds[i]; ++i) { |
2845 | diag = kdb_parse(kdb_cmds[i]); | 2848 | diag = kdb_parse(kdb_cmds[i]); |
2846 | if (diag) | 2849 | if (diag) |
2847 | kdb_printf("kdb command %s failed, kdb diag %d\n", | 2850 | kdb_printf("kdb command %s failed, kdb diag %d\n", |
2848 | kdb_cmds[i], diag); | 2851 | kdb_cmds[i], diag); |
2849 | } | 2852 | } |
2850 | if (defcmd_in_progress) { | 2853 | if (defcmd_in_progress) { |
2851 | kdb_printf("Incomplete 'defcmd' set, forcing endefcmd\n"); | 2854 | kdb_printf("Incomplete 'defcmd' set, forcing endefcmd\n"); |
2852 | kdb_parse("endefcmd"); | 2855 | kdb_parse("endefcmd"); |
2853 | } | 2856 | } |
2854 | } | 2857 | } |
2855 | 2858 | ||
2856 | /* Initialize kdb_printf, breakpoint tables and kdb state */ | 2859 | /* Initialize kdb_printf, breakpoint tables and kdb state */ |
2857 | void __init kdb_init(int lvl) | 2860 | void __init kdb_init(int lvl) |
2858 | { | 2861 | { |
2859 | static int kdb_init_lvl = KDB_NOT_INITIALIZED; | 2862 | static int kdb_init_lvl = KDB_NOT_INITIALIZED; |
2860 | int i; | 2863 | int i; |
2861 | 2864 | ||
2862 | if (kdb_init_lvl == KDB_INIT_FULL || lvl <= kdb_init_lvl) | 2865 | if (kdb_init_lvl == KDB_INIT_FULL || lvl <= kdb_init_lvl) |
2863 | return; | 2866 | return; |
2864 | for (i = kdb_init_lvl; i < lvl; i++) { | 2867 | for (i = kdb_init_lvl; i < lvl; i++) { |
2865 | switch (i) { | 2868 | switch (i) { |
2866 | case KDB_NOT_INITIALIZED: | 2869 | case KDB_NOT_INITIALIZED: |
2867 | kdb_inittab(); /* Initialize Command Table */ | 2870 | kdb_inittab(); /* Initialize Command Table */ |
2868 | kdb_initbptab(); /* Initialize Breakpoints */ | 2871 | kdb_initbptab(); /* Initialize Breakpoints */ |
2869 | break; | 2872 | break; |
2870 | case KDB_INIT_EARLY: | 2873 | case KDB_INIT_EARLY: |
2871 | kdb_cmd_init(); /* Build kdb_cmds tables */ | 2874 | kdb_cmd_init(); /* Build kdb_cmds tables */ |
2872 | break; | 2875 | break; |
2873 | } | 2876 | } |
2874 | } | 2877 | } |
2875 | kdb_init_lvl = lvl; | 2878 | kdb_init_lvl = lvl; |
2876 | } | 2879 | } |
2877 | 2880 |