diff options
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/Kconfig.debug | 8 | ||||
-rw-r--r-- | arch/sh/Makefile | 34 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh5/entry.S | 57 | ||||
-rw-r--r-- | arch/sh/lib64/.gitignore | 1 | ||||
-rw-r--r-- | arch/sh/lib64/dbg.c | 134 |
5 files changed, 2 insertions, 232 deletions
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index fafa907e14a..44627ef5254 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug | |||
@@ -137,12 +137,4 @@ config SH64_SR_WATCH | |||
137 | bool "Debug: set SR.WATCH to enable hardware watchpoints and trace" | 137 | bool "Debug: set SR.WATCH to enable hardware watchpoints and trace" |
138 | depends on SUPERH64 | 138 | depends on SUPERH64 |
139 | 139 | ||
140 | config POOR_MANS_STRACE | ||
141 | bool "Debug: enable rudimentary strace facility" | ||
142 | depends on SUPERH64 | ||
143 | help | ||
144 | This option allows system calls to be traced to the console. It also | ||
145 | aids in detecting kernel stack underflow. It is useful for debugging | ||
146 | early-userland problems (e.g. init incurring fatal exceptions.) | ||
147 | |||
148 | endmenu | 140 | endmenu |
diff --git a/arch/sh/Makefile b/arch/sh/Makefile index bece1f7535f..493da979eff 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile | |||
@@ -193,7 +193,7 @@ zImage uImage uImage.srec vmlinux.srec: vmlinux | |||
193 | 193 | ||
194 | compressed: zImage | 194 | compressed: zImage |
195 | 195 | ||
196 | archprepare: maketools arch/sh/lib64/syscalltab.h | 196 | archprepare: maketools |
197 | 197 | ||
198 | archclean: | 198 | archclean: |
199 | $(Q)$(MAKE) $(clean)=$(boot) | 199 | $(Q)$(MAKE) $(clean)=$(boot) |
@@ -205,34 +205,4 @@ define archhelp | |||
205 | @echo ' uImage.srec - Create an S-record for U-Boot' | 205 | @echo ' uImage.srec - Create an S-record for U-Boot' |
206 | endef | 206 | endef |
207 | 207 | ||
208 | define filechk_gen-syscalltab | 208 | CLEAN_FILES += include/asm-sh/machtypes.h |
209 | (set -e; \ | ||
210 | echo "/*"; \ | ||
211 | echo " * DO NOT MODIFY."; \ | ||
212 | echo " *"; \ | ||
213 | echo " * This file was generated by arch/sh/Makefile"; \ | ||
214 | echo " * Any changes will be reverted at build time."; \ | ||
215 | echo " */"; \ | ||
216 | echo ""; \ | ||
217 | echo "#ifndef __SYSCALLTAB_H"; \ | ||
218 | echo "#define __SYSCALLTAB_H"; \ | ||
219 | echo ""; \ | ||
220 | echo "#include <linux/kernel.h>"; \ | ||
221 | echo ""; \ | ||
222 | echo "struct syscall_info {"; \ | ||
223 | echo " const char *name;"; \ | ||
224 | echo "} syscall_info_table[] = {"; \ | ||
225 | sed -e '/^.*\.long /!d;s// { "/;s/\(\([^/]*\)\/\)\{1\}.*/\2/; \ | ||
226 | s/[ \t]*$$//g;s/$$/" },/;s/\("\)sys_/\1/g'; \ | ||
227 | echo "};"; \ | ||
228 | echo ""; \ | ||
229 | echo "#define NUM_SYSCALL_INFO_ENTRIES ARRAY_SIZE(syscall_info_table)";\ | ||
230 | echo ""; \ | ||
231 | echo "#endif /* __SYSCALLTAB_H */" ) | ||
232 | endef | ||
233 | |||
234 | arch/sh/lib64/syscalltab.h: arch/sh/kernel/syscalls_64.S | ||
235 | $(call filechk,gen-syscalltab) | ||
236 | |||
237 | CLEAN_FILES += arch/sh/lib64/syscalltab.h \ | ||
238 | include/asm-sh/machtypes.h | ||
diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S index 516297515b2..b0aacf67525 100644 --- a/arch/sh/kernel/cpu/sh5/entry.S +++ b/arch/sh/kernel/cpu/sh5/entry.S | |||
@@ -812,27 +812,6 @@ no_underflow: | |||
812 | ! exceptions | 812 | ! exceptions |
813 | add SP, ZERO, r14 | 813 | add SP, ZERO, r14 |
814 | 814 | ||
815 | #ifdef CONFIG_POOR_MANS_STRACE | ||
816 | /* We've pushed all the registers now, so only r2-r4 hold anything | ||
817 | * useful. Move them into callee save registers */ | ||
818 | or r2, ZERO, r28 | ||
819 | or r3, ZERO, r29 | ||
820 | or r4, ZERO, r30 | ||
821 | |||
822 | /* Preserve r2 as the event code */ | ||
823 | movi evt_debug, r3 | ||
824 | ori r3, 1, r3 | ||
825 | ptabs r3, tr0 | ||
826 | |||
827 | or SP, ZERO, r6 | ||
828 | getcon TRA, r5 | ||
829 | blink tr0, LINK | ||
830 | |||
831 | or r28, ZERO, r2 | ||
832 | or r29, ZERO, r3 | ||
833 | or r30, ZERO, r4 | ||
834 | #endif | ||
835 | |||
836 | /* For syscall and debug race condition, get TRA now */ | 815 | /* For syscall and debug race condition, get TRA now */ |
837 | getcon TRA, r5 | 816 | getcon TRA, r5 |
838 | 817 | ||
@@ -887,11 +866,6 @@ no_underflow: | |||
887 | */ | 866 | */ |
888 | .global ret_from_irq | 867 | .global ret_from_irq |
889 | ret_from_irq: | 868 | ret_from_irq: |
890 | #ifdef CONFIG_POOR_MANS_STRACE | ||
891 | pta evt_debug_ret_from_irq, tr0 | ||
892 | ori SP, 0, r2 | ||
893 | blink tr0, LINK | ||
894 | #endif | ||
895 | ld.q SP, FRAME_S(FSSR), r6 | 869 | ld.q SP, FRAME_S(FSSR), r6 |
896 | shlri r6, 30, r6 | 870 | shlri r6, 30, r6 |
897 | andi r6, 1, r6 | 871 | andi r6, 1, r6 |
@@ -905,12 +879,6 @@ ret_from_irq: | |||
905 | ret_from_exception: | 879 | ret_from_exception: |
906 | preempt_stop() | 880 | preempt_stop() |
907 | 881 | ||
908 | #ifdef CONFIG_POOR_MANS_STRACE | ||
909 | pta evt_debug_ret_from_exc, tr0 | ||
910 | ori SP, 0, r2 | ||
911 | blink tr0, LINK | ||
912 | #endif | ||
913 | |||
914 | ld.q SP, FRAME_S(FSSR), r6 | 882 | ld.q SP, FRAME_S(FSSR), r6 |
915 | shlri r6, 30, r6 | 883 | shlri r6, 30, r6 |
916 | andi r6, 1, r6 | 884 | andi r6, 1, r6 |
@@ -1236,18 +1204,6 @@ syscall_bad: | |||
1236 | .global syscall_ret | 1204 | .global syscall_ret |
1237 | syscall_ret: | 1205 | syscall_ret: |
1238 | st.q SP, FRAME_R(9), r2 /* Expecting SP back to BASIC frame */ | 1206 | st.q SP, FRAME_R(9), r2 /* Expecting SP back to BASIC frame */ |
1239 | |||
1240 | #ifdef CONFIG_POOR_MANS_STRACE | ||
1241 | /* nothing useful in registers at this point */ | ||
1242 | |||
1243 | movi evt_debug2, r5 | ||
1244 | ori r5, 1, r5 | ||
1245 | ptabs r5, tr0 | ||
1246 | ld.q SP, FRAME_R(9), r2 | ||
1247 | or SP, ZERO, r3 | ||
1248 | blink tr0, LINK | ||
1249 | #endif | ||
1250 | |||
1251 | ld.q SP, FRAME_S(FSPC), r2 | 1207 | ld.q SP, FRAME_S(FSPC), r2 |
1252 | addi r2, 4, r2 /* Move PC, being pre-execution event */ | 1208 | addi r2, 4, r2 /* Move PC, being pre-execution event */ |
1253 | st.q SP, FRAME_S(FSPC), r2 | 1209 | st.q SP, FRAME_S(FSPC), r2 |
@@ -1268,25 +1224,12 @@ ret_from_fork: | |||
1268 | ptabs r5, tr0 | 1224 | ptabs r5, tr0 |
1269 | blink tr0, LINK | 1225 | blink tr0, LINK |
1270 | 1226 | ||
1271 | #ifdef CONFIG_POOR_MANS_STRACE | ||
1272 | /* nothing useful in registers at this point */ | ||
1273 | |||
1274 | movi evt_debug2, r5 | ||
1275 | ori r5, 1, r5 | ||
1276 | ptabs r5, tr0 | ||
1277 | ld.q SP, FRAME_R(9), r2 | ||
1278 | or SP, ZERO, r3 | ||
1279 | blink tr0, LINK | ||
1280 | #endif | ||
1281 | |||
1282 | ld.q SP, FRAME_S(FSPC), r2 | 1227 | ld.q SP, FRAME_S(FSPC), r2 |
1283 | addi r2, 4, r2 /* Move PC, being pre-execution event */ | 1228 | addi r2, 4, r2 /* Move PC, being pre-execution event */ |
1284 | st.q SP, FRAME_S(FSPC), r2 | 1229 | st.q SP, FRAME_S(FSPC), r2 |
1285 | pta ret_from_syscall, tr0 | 1230 | pta ret_from_syscall, tr0 |
1286 | blink tr0, ZERO | 1231 | blink tr0, ZERO |
1287 | 1232 | ||
1288 | |||
1289 | |||
1290 | syscall_allowed: | 1233 | syscall_allowed: |
1291 | /* Use LINK to deflect the exit point, default is syscall_ret */ | 1234 | /* Use LINK to deflect the exit point, default is syscall_ret */ |
1292 | pta syscall_ret, tr0 | 1235 | pta syscall_ret, tr0 |
diff --git a/arch/sh/lib64/.gitignore b/arch/sh/lib64/.gitignore deleted file mode 100644 index 3508c2cb23c..00000000000 --- a/arch/sh/lib64/.gitignore +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | syscalltab.h | ||
diff --git a/arch/sh/lib64/dbg.c b/arch/sh/lib64/dbg.c index 2fb8eaf6de6..25f2481bd89 100644 --- a/arch/sh/lib64/dbg.c +++ b/arch/sh/lib64/dbg.c | |||
@@ -135,140 +135,6 @@ void print_itlb(void) | |||
135 | (" =============================================================\n"); | 135 | (" =============================================================\n"); |
136 | } | 136 | } |
137 | 137 | ||
138 | /* ======================================================================= */ | ||
139 | |||
140 | #ifdef CONFIG_POOR_MANS_STRACE | ||
141 | |||
142 | #include "syscalltab.h" | ||
143 | |||
144 | struct ring_node { | ||
145 | int evt; | ||
146 | int ret_addr; | ||
147 | int event; | ||
148 | int tra; | ||
149 | int pid; | ||
150 | unsigned long sp; | ||
151 | unsigned long pc; | ||
152 | }; | ||
153 | |||
154 | static struct ring_node event_ring[16]; | ||
155 | static int event_ptr = 0; | ||
156 | |||
157 | struct stored_syscall_data { | ||
158 | int pid; | ||
159 | int syscall_number; | ||
160 | }; | ||
161 | |||
162 | #define N_STORED_SYSCALLS 16 | ||
163 | |||
164 | static struct stored_syscall_data stored_syscalls[N_STORED_SYSCALLS]; | ||
165 | static int syscall_next=0; | ||
166 | static int syscall_next_print=0; | ||
167 | |||
168 | void evt_debug(int evt, int ret_addr, int event, int tra, struct pt_regs *regs) | ||
169 | { | ||
170 | int syscallno = tra & 0xff; | ||
171 | unsigned long sp; | ||
172 | unsigned long stack_bottom; | ||
173 | int pid; | ||
174 | struct ring_node *rr; | ||
175 | |||
176 | pid = current->pid; | ||
177 | stack_bottom = (unsigned long) task_stack_page(current); | ||
178 | asm volatile("ori r15, 0, %0" : "=r" (sp)); | ||
179 | rr = event_ring + event_ptr; | ||
180 | rr->evt = evt; | ||
181 | rr->ret_addr = ret_addr; | ||
182 | rr->event = event; | ||
183 | rr->tra = tra; | ||
184 | rr->pid = pid; | ||
185 | rr->sp = sp; | ||
186 | rr->pc = regs->pc; | ||
187 | |||
188 | if (sp < stack_bottom + 3092) { | ||
189 | int i, j; | ||
190 | printk("evt_debug : stack underflow report\n"); | ||
191 | for (j=0, i = event_ptr; j<16; j++) { | ||
192 | rr = event_ring + i; | ||
193 | printk("evt=%08x event=%08x tra=%08x pid=%5d sp=%08lx pc=%08lx\n", | ||
194 | rr->evt, rr->event, rr->tra, rr->pid, rr->sp, rr->pc); | ||
195 | i--; | ||
196 | i &= 15; | ||
197 | } | ||
198 | panic("STACK UNDERFLOW\n"); | ||
199 | } | ||
200 | |||
201 | event_ptr = (event_ptr + 1) & 15; | ||
202 | |||
203 | if ((event == 2) && (evt == 0x160)) { | ||
204 | if (syscallno < NUM_SYSCALL_INFO_ENTRIES) { | ||
205 | /* Store the syscall information to print later. We | ||
206 | * can't print this now - currently we're running with | ||
207 | * SR.BL=1, so we can't take a tlbmiss (which could occur | ||
208 | * in the console drivers under printk). | ||
209 | * | ||
210 | * Just overwrite old entries on ring overflow - this | ||
211 | * is only for last-hope debugging. */ | ||
212 | stored_syscalls[syscall_next].pid = current->pid; | ||
213 | stored_syscalls[syscall_next].syscall_number = syscallno; | ||
214 | syscall_next++; | ||
215 | syscall_next &= (N_STORED_SYSCALLS - 1); | ||
216 | } | ||
217 | } | ||
218 | } | ||
219 | |||
220 | static void drain_syscalls(void) { | ||
221 | while (syscall_next_print != syscall_next) { | ||
222 | printk("Task %d: %s()\n", | ||
223 | stored_syscalls[syscall_next_print].pid, | ||
224 | syscall_info_table[stored_syscalls[syscall_next_print].syscall_number].name); | ||
225 | syscall_next_print++; | ||
226 | syscall_next_print &= (N_STORED_SYSCALLS - 1); | ||
227 | } | ||
228 | } | ||
229 | |||
230 | void evt_debug2(unsigned int ret) | ||
231 | { | ||
232 | drain_syscalls(); | ||
233 | printk("Task %d: syscall returns %08x\n", current->pid, ret); | ||
234 | } | ||
235 | |||
236 | void evt_debug_ret_from_irq(struct pt_regs *regs) | ||
237 | { | ||
238 | int pid; | ||
239 | struct ring_node *rr; | ||
240 | |||
241 | pid = current->pid; | ||
242 | rr = event_ring + event_ptr; | ||
243 | rr->evt = 0xffff; | ||
244 | rr->ret_addr = 0; | ||
245 | rr->event = 0; | ||
246 | rr->tra = 0; | ||
247 | rr->pid = pid; | ||
248 | rr->pc = regs->pc; | ||
249 | event_ptr = (event_ptr + 1) & 15; | ||
250 | } | ||
251 | |||
252 | void evt_debug_ret_from_exc(struct pt_regs *regs) | ||
253 | { | ||
254 | int pid; | ||
255 | struct ring_node *rr; | ||
256 | |||
257 | pid = current->pid; | ||
258 | rr = event_ring + event_ptr; | ||
259 | rr->evt = 0xfffe; | ||
260 | rr->ret_addr = 0; | ||
261 | rr->event = 0; | ||
262 | rr->tra = 0; | ||
263 | rr->pid = pid; | ||
264 | rr->pc = regs->pc; | ||
265 | event_ptr = (event_ptr + 1) & 15; | ||
266 | } | ||
267 | |||
268 | #endif /* CONFIG_POOR_MANS_STRACE */ | ||
269 | |||
270 | /* ======================================================================= */ | ||
271 | |||
272 | void show_excp_regs(char *from, int trapnr, int signr, struct pt_regs *regs) | 138 | void show_excp_regs(char *from, int trapnr, int signr, struct pt_regs *regs) |
273 | { | 139 | { |
274 | 140 | ||