aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mn10300/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-24 13:07:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-24 13:07:50 -0400
commit3dab04e6978e358ad2307bca563fabd6c5d2c58b (patch)
tree893e9bc5041e7f722722fe13a3b145396f2554d8 /arch/mn10300/kernel
parent6d1e9a42e7176bbce9348274784b2e5f69223936 (diff)
parent5a4b65ab506398ba5a35c37e06edddd387cc0add (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-2.6-mn10300
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-2.6-mn10300: MN10300: gcc 4.6 vs am33 inline assembly MN10300: Deprecate gdbstub MN10300: Allow KGDB to use the MN10300 serial ports MN10300: Emulate single stepping in KGDB on MN10300 MN10300: Generalise kernel debugger kernel halt, reboot or power off hook KGDB: Notify GDB of machine halt, reboot or power off MN10300: Use KGDB MN10300: Create generic kernel debugger hooks MN10300: Create general kernel debugger cache flushing MN10300: Introduce a general config option for kernel debugger hooks MN10300: The icache invalidate functions should disable the icache first MN10300: gdbstub: Restrict single-stepping to non-preemptable non-SMP configs
Diffstat (limited to 'arch/mn10300/kernel')
-rw-r--r--arch/mn10300/kernel/Makefile5
-rw-r--r--arch/mn10300/kernel/entry.S67
-rw-r--r--arch/mn10300/kernel/fpu.c18
-rw-r--r--arch/mn10300/kernel/gdb-cache.S105
-rw-r--r--arch/mn10300/kernel/gdb-io-ttysm.c8
-rw-r--r--arch/mn10300/kernel/gdb-stub.c41
-rw-r--r--arch/mn10300/kernel/internal.h7
-rw-r--r--arch/mn10300/kernel/irq.c2
-rw-r--r--arch/mn10300/kernel/kgdb.c502
-rw-r--r--arch/mn10300/kernel/mn10300-serial.c75
-rw-r--r--arch/mn10300/kernel/process.c6
-rw-r--r--arch/mn10300/kernel/smp.c26
-rw-r--r--arch/mn10300/kernel/switch_to.S111
-rw-r--r--arch/mn10300/kernel/traps.c406
14 files changed, 996 insertions, 383 deletions
diff --git a/arch/mn10300/kernel/Makefile b/arch/mn10300/kernel/Makefile
index a06a2e10051d..47ed30fe8178 100644
--- a/arch/mn10300/kernel/Makefile
+++ b/arch/mn10300/kernel/Makefile
@@ -21,11 +21,8 @@ obj-$(CONFIG_GDBSTUB) += gdb-stub.o gdb-low.o
21obj-$(CONFIG_GDBSTUB_ON_TTYSx) += gdb-io-serial.o gdb-io-serial-low.o 21obj-$(CONFIG_GDBSTUB_ON_TTYSx) += gdb-io-serial.o gdb-io-serial-low.o
22obj-$(CONFIG_GDBSTUB_ON_TTYSMx) += gdb-io-ttysm.o gdb-io-ttysm-low.o 22obj-$(CONFIG_GDBSTUB_ON_TTYSMx) += gdb-io-ttysm.o gdb-io-ttysm-low.o
23 23
24ifeq ($(CONFIG_MN10300_CACHE_ENABLED),y)
25obj-$(CONFIG_GDBSTUB) += gdb-cache.o
26endif
27
28obj-$(CONFIG_MN10300_RTC) += rtc.o 24obj-$(CONFIG_MN10300_RTC) += rtc.o
29obj-$(CONFIG_PROFILE) += profile.o profile-low.o 25obj-$(CONFIG_PROFILE) += profile.o profile-low.o
30obj-$(CONFIG_MODULES) += module.o 26obj-$(CONFIG_MODULES) += module.o
31obj-$(CONFIG_KPROBES) += kprobes.o 27obj-$(CONFIG_KPROBES) += kprobes.o
28obj-$(CONFIG_KGDB) += kgdb.o
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S
index f00b9bafcd3e..fb93ad720b82 100644
--- a/arch/mn10300/kernel/entry.S
+++ b/arch/mn10300/kernel/entry.S
@@ -266,7 +266,11 @@ ENTRY(raw_bus_error)
266 266
267############################################################################### 267###############################################################################
268# 268#
269# Miscellaneous exception entry points 269# NMI exception entry points
270#
271# This is used by ordinary interrupt channels that have the GxICR_NMI bit set
272# in addition to the main NMI and Watchdog channels. SMP NMI IPIs use this
273# facility.
270# 274#
271############################################################################### 275###############################################################################
272ENTRY(nmi_handler) 276ENTRY(nmi_handler)
@@ -281,7 +285,7 @@ ENTRY(nmi_handler)
281 and NMIAGR_GN,d0 285 and NMIAGR_GN,d0
282 lsr 0x2,d0 286 lsr 0x2,d0
283 cmp CALL_FUNCTION_NMI_IPI,d0 287 cmp CALL_FUNCTION_NMI_IPI,d0
284 bne 5f # if not call function, jump 288 bne nmi_not_smp_callfunc # if not call function, jump
285 289
286 # function call nmi ipi 290 # function call nmi ipi
287 add 4,sp # no need to store TBR 291 add 4,sp # no need to store TBR
@@ -295,59 +299,38 @@ ENTRY(nmi_handler)
295 call smp_nmi_call_function_interrupt[],0 299 call smp_nmi_call_function_interrupt[],0
296 RESTORE_ALL 300 RESTORE_ALL
297 301
2985: 302nmi_not_smp_callfunc:
299#ifdef CONFIG_GDBSTUB 303#ifdef CONFIG_KERNEL_DEBUGGER
300 cmp GDB_NMI_IPI,d0 304 cmp DEBUGGER_NMI_IPI,d0
301 bne 3f # if not gdb nmi ipi, jump 305 bne nmi_not_debugger # if not kernel debugger NMI IPI, jump
302 306
303 # gdb nmi ipi 307 # kernel debugger NMI IPI
304 add 4,sp # no need to store TBR 308 add 4,sp # no need to store TBR
305 mov GxICR_DETECT,d0 # clear NMI 309 mov GxICR_DETECT,d0 # clear NMI
306 movbu d0,(GxICR(GDB_NMI_IPI)) 310 movbu d0,(GxICR(DEBUGGER_NMI_IPI))
307 movhu (GxICR(GDB_NMI_IPI)),d0 311 movhu (GxICR(DEBUGGER_NMI_IPI)),d0
308 and ~EPSW_NMID,epsw # enable NMI 312 and ~EPSW_NMID,epsw # enable NMI
309#ifdef CONFIG_MN10300_CACHE_ENABLED 313
310 mov (gdbstub_nmi_opr_type),d0
311 cmp GDBSTUB_NMI_CACHE_PURGE,d0
312 bne 4f # if not gdb cache purge, jump
313
314 # gdb cache purge nmi ipi
315 add -20,sp
316 mov d1,(4,sp)
317 mov a0,(8,sp)
318 mov a1,(12,sp)
319 mov mdr,d0
320 mov d0,(16,sp)
321 call gdbstub_local_purge_cache[],0
322 mov 0x1,d0
323 mov (CPUID),d1
324 asl d1,d0
325 mov gdbstub_nmi_cpumask,a0
326 bclr d0,(a0)
327 mov (4,sp),d1
328 mov (8,sp),a0
329 mov (12,sp),a1
330 mov (16,sp),d0
331 mov d0,mdr
332 add 20,sp
333 mov (sp),d0
334 add 4,sp
335 rti
3364:
337#endif /* CONFIG_MN10300_CACHE_ENABLED */
338 # gdb wait nmi ipi
339 mov (sp),d0 314 mov (sp),d0
340 SAVE_ALL 315 SAVE_ALL
341 call gdbstub_nmi_wait[],0 316 mov fp,d0 # arg 0: stacked register file
317 mov a2,d1 # arg 1: exception number
318 call debugger_nmi_interrupt[],0
342 RESTORE_ALL 319 RESTORE_ALL
3433: 320
344#endif /* CONFIG_GDBSTUB */ 321nmi_not_debugger:
322#endif /* CONFIG_KERNEL_DEBUGGER */
345 mov (sp),d0 # restore TBR to d0 323 mov (sp),d0 # restore TBR to d0
346 add 4,sp 324 add 4,sp
347#endif /* CONFIG_SMP */ 325#endif /* CONFIG_SMP */
348 326
349 bra __common_exception_nonmi 327 bra __common_exception_nonmi
350 328
329###############################################################################
330#
331# General exception entry point
332#
333###############################################################################
351ENTRY(__common_exception) 334ENTRY(__common_exception)
352 add -4,sp 335 add -4,sp
353 mov d0,(sp) 336 mov d0,(sp)
diff --git a/arch/mn10300/kernel/fpu.c b/arch/mn10300/kernel/fpu.c
index 5f9c3fa19a85..bb5fa7df6c44 100644
--- a/arch/mn10300/kernel/fpu.c
+++ b/arch/mn10300/kernel/fpu.c
@@ -70,24 +70,6 @@ asmlinkage void fpu_exception(struct pt_regs *regs, enum exception_code code)
70} 70}
71 71
72/* 72/*
73 * handle an FPU invalid_op exception
74 * - Derived from DO_EINFO() macro in arch/mn10300/kernel/traps.c
75 */
76asmlinkage void fpu_invalid_op(struct pt_regs *regs, enum exception_code code)
77{
78 siginfo_t info;
79
80 if (!user_mode(regs))
81 die_if_no_fixup("FPU invalid opcode", regs, code);
82
83 info.si_signo = SIGILL;
84 info.si_errno = 0;
85 info.si_code = ILL_COPROC;
86 info.si_addr = (void *) regs->pc;
87 force_sig_info(info.si_signo, &info, current);
88}
89
90/*
91 * save the FPU state to a signal context 73 * save the FPU state to a signal context
92 */ 74 */
93int fpu_setup_sigcontext(struct fpucontext *fpucontext) 75int fpu_setup_sigcontext(struct fpucontext *fpucontext)
diff --git a/arch/mn10300/kernel/gdb-cache.S b/arch/mn10300/kernel/gdb-cache.S
deleted file mode 100644
index 1108badc3d32..000000000000
--- a/arch/mn10300/kernel/gdb-cache.S
+++ /dev/null
@@ -1,105 +0,0 @@
1###############################################################################
2#
3# MN10300 Low-level cache purging routines for gdbstub
4#
5# Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
6# Written by David Howells (dhowells@redhat.com)
7#
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public Licence
10# as published by the Free Software Foundation; either version
11# 2 of the Licence, or (at your option) any later version.
12#
13###############################################################################
14#include <linux/sys.h>
15#include <linux/linkage.h>
16#include <asm/smp.h>
17#include <asm/cache.h>
18#include <asm/cpu-regs.h>
19#include <asm/exceptions.h>
20#include <asm/frame.inc>
21#include <asm/serial-regs.h>
22
23 .text
24
25###############################################################################
26#
27# GDB stub cache purge
28#
29###############################################################################
30 .type gdbstub_purge_cache,@function
31ENTRY(gdbstub_purge_cache)
32 #######################################################################
33 # read the addresses tagged in the cache's tag RAM and attempt to flush
34 # those addresses specifically
35 # - we rely on the hardware to filter out invalid tag entry addresses
36 mov DCACHE_TAG(0,0),a0 # dcache tag RAM access address
37 mov DCACHE_PURGE(0,0),a1 # dcache purge request address
38 mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of entries
39
40mn10300_dcache_flush_loop:
41 mov (a0),d0
42 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0
43 or L1_CACHE_TAG_VALID,d0 # retain valid entries in the
44 # cache
45 mov d0,(a1) # conditional purge
46
47mn10300_dcache_flush_skip:
48 add L1_CACHE_BYTES,a0
49 add L1_CACHE_BYTES,a1
50 add -1,d1
51 bne mn10300_dcache_flush_loop
52
53;; # unconditionally flush and invalidate the dcache
54;; mov DCACHE_PURGE(0,0),a1 # dcache purge request address
55;; mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of
56;; # entries
57;;
58;; gdbstub_purge_cache__dcache_loop:
59;; mov (a1),d0 # unconditional purge
60;;
61;; add L1_CACHE_BYTES,a1
62;; add -1,d1
63;; bne gdbstub_purge_cache__dcache_loop
64
65 #######################################################################
66 # now invalidate the icache
67 mov CHCTR,a0
68 movhu (a0),a1
69
70 mov epsw,d1
71 and ~EPSW_IE,epsw
72 nop
73 nop
74
75 # disable the icache
76 and ~CHCTR_ICEN,d0
77 movhu d0,(a0)
78
79 # and wait for it to calm down
80 setlb
81 movhu (a0),d0
82 btst CHCTR_ICBUSY,d0
83 lne
84
85 # invalidate
86 or CHCTR_ICINV,d0
87 movhu d0,(a0)
88
89 # wait for the cache to finish
90 mov CHCTR,a0
91 setlb
92 movhu (a0),d0
93 btst CHCTR_ICBUSY,d0
94 lne
95
96 # and reenable it
97 movhu a1,(a0)
98 movhu (a0),d0 # read back to flush
99 # (SIGILLs all over without this)
100
101 mov d1,epsw
102
103 ret [],0
104
105 .size gdbstub_purge_cache,.-gdbstub_purge_cache
diff --git a/arch/mn10300/kernel/gdb-io-ttysm.c b/arch/mn10300/kernel/gdb-io-ttysm.c
index abdeea153c89..c859cacbb9c3 100644
--- a/arch/mn10300/kernel/gdb-io-ttysm.c
+++ b/arch/mn10300/kernel/gdb-io-ttysm.c
@@ -59,10 +59,10 @@ void __init gdbstub_io_init(void)
59 59
60 /* we want to get serial receive interrupts */ 60 /* we want to get serial receive interrupts */
61 set_intr_level(gdbstub_port->rx_irq, 61 set_intr_level(gdbstub_port->rx_irq,
62 NUM2GxICR_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL)); 62 NUM2GxICR_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL));
63 set_intr_level(gdbstub_port->tx_irq, 63 set_intr_level(gdbstub_port->tx_irq,
64 NUM2GxICR_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL)); 64 NUM2GxICR_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL));
65 set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL), 65 set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL),
66 gdbstub_io_rx_handler); 66 gdbstub_io_rx_handler);
67 67
68 *gdbstub_port->rx_icr |= GxICR_ENABLE; 68 *gdbstub_port->rx_icr |= GxICR_ENABLE;
@@ -88,7 +88,7 @@ void __init gdbstub_io_init(void)
88 88
89 /* permit level 0 IRQs only */ 89 /* permit level 0 IRQs only */
90 arch_local_change_intr_mask_level( 90 arch_local_change_intr_mask_level(
91 NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); 91 NUM2EPSW_IM(CONFIG_DEBUGGER_IRQ_LEVEL + 1));
92} 92}
93 93
94/* 94/*
diff --git a/arch/mn10300/kernel/gdb-stub.c b/arch/mn10300/kernel/gdb-stub.c
index b169d99d9f20..538266b2c9bc 100644
--- a/arch/mn10300/kernel/gdb-stub.c
+++ b/arch/mn10300/kernel/gdb-stub.c
@@ -133,7 +133,7 @@
133#include <asm/system.h> 133#include <asm/system.h>
134#include <asm/gdb-stub.h> 134#include <asm/gdb-stub.h>
135#include <asm/exceptions.h> 135#include <asm/exceptions.h>
136#include <asm/cacheflush.h> 136#include <asm/debugger.h>
137#include <asm/serial-regs.h> 137#include <asm/serial-regs.h>
138#include <asm/busctl-regs.h> 138#include <asm/busctl-regs.h>
139#include <unit/leds.h> 139#include <unit/leds.h>
@@ -405,6 +405,7 @@ static int hexToInt(char **ptr, int *intValue)
405 return (numChars); 405 return (numChars);
406} 406}
407 407
408#ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP
408/* 409/*
409 * We single-step by setting breakpoints. When an exception 410 * We single-step by setting breakpoints. When an exception
410 * is handled, we need to restore the instructions hoisted 411 * is handled, we need to restore the instructions hoisted
@@ -729,6 +730,7 @@ static int gdbstub_single_step(struct pt_regs *regs)
729 __gdbstub_restore_bp(); 730 __gdbstub_restore_bp();
730 return -EFAULT; 731 return -EFAULT;
731} 732}
733#endif /* CONFIG_GDBSTUB_ALLOW_SINGLE_STEP */
732 734
733#ifdef CONFIG_GDBSTUB_CONSOLE 735#ifdef CONFIG_GDBSTUB_CONSOLE
734 736
@@ -1171,7 +1173,7 @@ int gdbstub_clear_breakpoint(u8 *addr, int len)
1171 1173
1172/* 1174/*
1173 * This function does all command processing for interfacing to gdb 1175 * This function does all command processing for interfacing to gdb
1174 * - returns 1 if the exception should be skipped, 0 otherwise. 1176 * - returns 0 if the exception should be skipped, -ERROR otherwise.
1175 */ 1177 */
1176static int gdbstub(struct pt_regs *regs, enum exception_code excep) 1178static int gdbstub(struct pt_regs *regs, enum exception_code excep)
1177{ 1179{
@@ -1186,7 +1188,7 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
1186 int loop; 1188 int loop;
1187 1189
1188 if (excep == EXCEP_FPU_DISABLED) 1190 if (excep == EXCEP_FPU_DISABLED)
1189 return 0; 1191 return -ENOTSUPP;
1190 1192
1191 gdbstub_flush_caches = 0; 1193 gdbstub_flush_caches = 0;
1192 1194
@@ -1195,7 +1197,7 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
1195 asm volatile("mov mdr,%0" : "=d"(mdr)); 1197 asm volatile("mov mdr,%0" : "=d"(mdr));
1196 local_save_flags(epsw); 1198 local_save_flags(epsw);
1197 arch_local_change_intr_mask_level( 1199 arch_local_change_intr_mask_level(
1198 NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); 1200 NUM2EPSW_IM(CONFIG_DEBUGGER_IRQ_LEVEL + 1));
1199 1201
1200 gdbstub_store_fpu(); 1202 gdbstub_store_fpu();
1201 1203
@@ -1208,11 +1210,13 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
1208 /* if we were single stepping, restore the opcodes hoisted for the 1210 /* if we were single stepping, restore the opcodes hoisted for the
1209 * breakpoint[s] */ 1211 * breakpoint[s] */
1210 broke = 0; 1212 broke = 0;
1213#ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP
1211 if ((step_bp[0].addr && step_bp[0].addr == (u8 *) regs->pc) || 1214 if ((step_bp[0].addr && step_bp[0].addr == (u8 *) regs->pc) ||
1212 (step_bp[1].addr && step_bp[1].addr == (u8 *) regs->pc)) 1215 (step_bp[1].addr && step_bp[1].addr == (u8 *) regs->pc))
1213 broke = 1; 1216 broke = 1;
1214 1217
1215 __gdbstub_restore_bp(); 1218 __gdbstub_restore_bp();
1219#endif
1216 1220
1217 if (gdbstub_rx_unget) { 1221 if (gdbstub_rx_unget) {
1218 sigval = SIGINT; 1222 sigval = SIGINT;
@@ -1548,17 +1552,21 @@ packet_waiting:
1548 * Step to next instruction 1552 * Step to next instruction
1549 */ 1553 */
1550 case 's': 1554 case 's':
1551 /* 1555 /* Using the T flag doesn't seem to perform single
1552 * using the T flag doesn't seem to perform single
1553 * stepping (it seems to wind up being caught by the 1556 * stepping (it seems to wind up being caught by the
1554 * JTAG unit), so we have to use breakpoints and 1557 * JTAG unit), so we have to use breakpoints and
1555 * continue instead. 1558 * continue instead.
1556 */ 1559 */
1560#ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP
1557 if (gdbstub_single_step(regs) < 0) 1561 if (gdbstub_single_step(regs) < 0)
1558 /* ignore any fault error for now */ 1562 /* ignore any fault error for now */
1559 gdbstub_printk("unable to set single-step" 1563 gdbstub_printk("unable to set single-step"
1560 " bp\n"); 1564 " bp\n");
1561 goto done; 1565 goto done;
1566#else
1567 gdbstub_strcpy(output_buffer, "E01");
1568 break;
1569#endif
1562 1570
1563 /* 1571 /*
1564 * Set baud rate (bBB) 1572 * Set baud rate (bBB)
@@ -1657,7 +1665,7 @@ done:
1657 * NB: We flush both caches, just to be sure... 1665 * NB: We flush both caches, just to be sure...
1658 */ 1666 */
1659 if (gdbstub_flush_caches) 1667 if (gdbstub_flush_caches)
1660 gdbstub_purge_cache(); 1668 debugger_local_cache_flushinv();
1661 1669
1662 gdbstub_load_fpu(); 1670 gdbstub_load_fpu();
1663 mn10300_set_gdbleds(0); 1671 mn10300_set_gdbleds(0);
@@ -1667,14 +1675,23 @@ done:
1667 touch_softlockup_watchdog(); 1675 touch_softlockup_watchdog();
1668 1676
1669 local_irq_restore(epsw); 1677 local_irq_restore(epsw);
1670 return 1; 1678 return 0;
1679}
1680
1681/*
1682 * Determine if we hit a debugger special breakpoint that needs skipping over
1683 * automatically.
1684 */
1685int at_debugger_breakpoint(struct pt_regs *regs)
1686{
1687 return 0;
1671} 1688}
1672 1689
1673/* 1690/*
1674 * handle event interception 1691 * handle event interception
1675 */ 1692 */
1676asmlinkage int gdbstub_intercept(struct pt_regs *regs, 1693asmlinkage int debugger_intercept(enum exception_code excep,
1677 enum exception_code excep) 1694 int signo, int si_code, struct pt_regs *regs)
1678{ 1695{
1679 static u8 notfirst = 1; 1696 static u8 notfirst = 1;
1680 int ret; 1697 int ret;
@@ -1688,7 +1705,7 @@ asmlinkage int gdbstub_intercept(struct pt_regs *regs,
1688 asm("mov mdr,%0" : "=d"(mdr)); 1705 asm("mov mdr,%0" : "=d"(mdr));
1689 1706
1690 gdbstub_entry( 1707 gdbstub_entry(
1691 "--> gdbstub_intercept(%p,%04x) [MDR=%lx PC=%lx]\n", 1708 "--> debugger_intercept(%p,%04x) [MDR=%lx PC=%lx]\n",
1692 regs, excep, mdr, regs->pc); 1709 regs, excep, mdr, regs->pc);
1693 1710
1694 gdbstub_entry( 1711 gdbstub_entry(
@@ -1722,7 +1739,7 @@ asmlinkage int gdbstub_intercept(struct pt_regs *regs,
1722 1739
1723 ret = gdbstub(regs, excep); 1740 ret = gdbstub(regs, excep);
1724 1741
1725 gdbstub_entry("<-- gdbstub_intercept()\n"); 1742 gdbstub_entry("<-- debugger_intercept()\n");
1726 gdbstub_busy = 0; 1743 gdbstub_busy = 0;
1727 return ret; 1744 return ret;
1728} 1745}
diff --git a/arch/mn10300/kernel/internal.h b/arch/mn10300/kernel/internal.h
index ea946613f46d..a5ac755dd69f 100644
--- a/arch/mn10300/kernel/internal.h
+++ b/arch/mn10300/kernel/internal.h
@@ -30,6 +30,13 @@ extern void mn10300_low_ipi_handler(void);
30#endif 30#endif
31 31
32/* 32/*
33 * smp.c
34 */
35#ifdef CONFIG_SMP
36extern void smp_jump_to_debugger(void);
37#endif
38
39/*
33 * time.c 40 * time.c
34 */ 41 */
35extern irqreturn_t local_timer_interrupt(void); 42extern irqreturn_t local_timer_interrupt(void);
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index f09fed5e6afc..5f7fc3eb45e6 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -153,7 +153,7 @@ mn10300_cpupic_setaffinity(struct irq_data *d, const struct cpumask *mask,
153 case LOCAL_TIMER_IPI: 153 case LOCAL_TIMER_IPI:
154 case FLUSH_CACHE_IPI: 154 case FLUSH_CACHE_IPI:
155 case CALL_FUNCTION_NMI_IPI: 155 case CALL_FUNCTION_NMI_IPI:
156 case GDB_NMI_IPI: 156 case DEBUGGER_NMI_IPI:
157#ifdef CONFIG_MN10300_TTYSM0 157#ifdef CONFIG_MN10300_TTYSM0
158 case SC0RXIRQ: 158 case SC0RXIRQ:
159 case SC0TXIRQ: 159 case SC0TXIRQ:
diff --git a/arch/mn10300/kernel/kgdb.c b/arch/mn10300/kernel/kgdb.c
new file mode 100644
index 000000000000..f6c981db2a36
--- /dev/null
+++ b/arch/mn10300/kernel/kgdb.c
@@ -0,0 +1,502 @@
1/* kgdb support for MN10300
2 *
3 * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#include <linux/slab.h>
13#include <linux/ptrace.h>
14#include <linux/kgdb.h>
15#include <linux/uaccess.h>
16#include <unit/leds.h>
17#include <unit/serial.h>
18#include <asm/debugger.h>
19#include <asm/serial-regs.h>
20#include "internal.h"
21
22/*
23 * Software single-stepping breakpoint save (used by __switch_to())
24 */
25static struct thread_info *kgdb_sstep_thread;
26u8 *kgdb_sstep_bp_addr[2];
27u8 kgdb_sstep_bp[2];
28
29/*
30 * Copy kernel exception frame registers to the GDB register file
31 */
32void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
33{
34 unsigned long ssp = (unsigned long) (regs + 1);
35
36 gdb_regs[GDB_FR_D0] = regs->d0;
37 gdb_regs[GDB_FR_D1] = regs->d1;
38 gdb_regs[GDB_FR_D2] = regs->d2;
39 gdb_regs[GDB_FR_D3] = regs->d3;
40 gdb_regs[GDB_FR_A0] = regs->a0;
41 gdb_regs[GDB_FR_A1] = regs->a1;
42 gdb_regs[GDB_FR_A2] = regs->a2;
43 gdb_regs[GDB_FR_A3] = regs->a3;
44 gdb_regs[GDB_FR_SP] = (regs->epsw & EPSW_nSL) ? regs->sp : ssp;
45 gdb_regs[GDB_FR_PC] = regs->pc;
46 gdb_regs[GDB_FR_MDR] = regs->mdr;
47 gdb_regs[GDB_FR_EPSW] = regs->epsw;
48 gdb_regs[GDB_FR_LIR] = regs->lir;
49 gdb_regs[GDB_FR_LAR] = regs->lar;
50 gdb_regs[GDB_FR_MDRQ] = regs->mdrq;
51 gdb_regs[GDB_FR_E0] = regs->e0;
52 gdb_regs[GDB_FR_E1] = regs->e1;
53 gdb_regs[GDB_FR_E2] = regs->e2;
54 gdb_regs[GDB_FR_E3] = regs->e3;
55 gdb_regs[GDB_FR_E4] = regs->e4;
56 gdb_regs[GDB_FR_E5] = regs->e5;
57 gdb_regs[GDB_FR_E6] = regs->e6;
58 gdb_regs[GDB_FR_E7] = regs->e7;
59 gdb_regs[GDB_FR_SSP] = ssp;
60 gdb_regs[GDB_FR_MSP] = 0;
61 gdb_regs[GDB_FR_USP] = regs->sp;
62 gdb_regs[GDB_FR_MCRH] = regs->mcrh;
63 gdb_regs[GDB_FR_MCRL] = regs->mcrl;
64 gdb_regs[GDB_FR_MCVF] = regs->mcvf;
65 gdb_regs[GDB_FR_DUMMY0] = 0;
66 gdb_regs[GDB_FR_DUMMY1] = 0;
67 gdb_regs[GDB_FR_FS0] = 0;
68}
69
70/*
71 * Extracts kernel SP/PC values understandable by gdb from the values
72 * saved by switch_to().
73 */
74void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
75{
76 gdb_regs[GDB_FR_SSP] = p->thread.sp;
77 gdb_regs[GDB_FR_PC] = p->thread.pc;
78 gdb_regs[GDB_FR_A3] = p->thread.a3;
79 gdb_regs[GDB_FR_USP] = p->thread.usp;
80 gdb_regs[GDB_FR_FPCR] = p->thread.fpu_state.fpcr;
81}
82
83/*
84 * Fill kernel exception frame registers from the GDB register file
85 */
86void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
87{
88 regs->d0 = gdb_regs[GDB_FR_D0];
89 regs->d1 = gdb_regs[GDB_FR_D1];
90 regs->d2 = gdb_regs[GDB_FR_D2];
91 regs->d3 = gdb_regs[GDB_FR_D3];
92 regs->a0 = gdb_regs[GDB_FR_A0];
93 regs->a1 = gdb_regs[GDB_FR_A1];
94 regs->a2 = gdb_regs[GDB_FR_A2];
95 regs->a3 = gdb_regs[GDB_FR_A3];
96 regs->sp = gdb_regs[GDB_FR_SP];
97 regs->pc = gdb_regs[GDB_FR_PC];
98 regs->mdr = gdb_regs[GDB_FR_MDR];
99 regs->epsw = gdb_regs[GDB_FR_EPSW];
100 regs->lir = gdb_regs[GDB_FR_LIR];
101 regs->lar = gdb_regs[GDB_FR_LAR];
102 regs->mdrq = gdb_regs[GDB_FR_MDRQ];
103 regs->e0 = gdb_regs[GDB_FR_E0];
104 regs->e1 = gdb_regs[GDB_FR_E1];
105 regs->e2 = gdb_regs[GDB_FR_E2];
106 regs->e3 = gdb_regs[GDB_FR_E3];
107 regs->e4 = gdb_regs[GDB_FR_E4];
108 regs->e5 = gdb_regs[GDB_FR_E5];
109 regs->e6 = gdb_regs[GDB_FR_E6];
110 regs->e7 = gdb_regs[GDB_FR_E7];
111 regs->sp = gdb_regs[GDB_FR_SSP];
112 /* gdb_regs[GDB_FR_MSP]; */
113 // regs->usp = gdb_regs[GDB_FR_USP];
114 regs->mcrh = gdb_regs[GDB_FR_MCRH];
115 regs->mcrl = gdb_regs[GDB_FR_MCRL];
116 regs->mcvf = gdb_regs[GDB_FR_MCVF];
117 /* gdb_regs[GDB_FR_DUMMY0]; */
118 /* gdb_regs[GDB_FR_DUMMY1]; */
119
120 // regs->fpcr = gdb_regs[GDB_FR_FPCR];
121 // regs->fs0 = gdb_regs[GDB_FR_FS0];
122}
123
124struct kgdb_arch arch_kgdb_ops = {
125 .gdb_bpt_instr = { 0xff },
126 .flags = KGDB_HW_BREAKPOINT,
127};
128
129static const unsigned char mn10300_kgdb_insn_sizes[256] =
130{
131 /* 1 2 3 4 5 6 7 8 9 a b c d e f */
132 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, /* 0 */
133 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */
134 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, /* 2 */
135 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, /* 3 */
136 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, /* 4 */
137 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, /* 5 */
138 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */
139 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7 */
140 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 8 */
141 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 9 */
142 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* a */
143 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* b */
144 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 2, /* c */
145 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */
146 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */
147 0, 2, 2, 2, 2, 2, 2, 4, 0, 3, 0, 4, 0, 6, 7, 1 /* f */
148};
149
150/*
151 * Attempt to emulate single stepping by means of breakpoint instructions.
152 * Although there is a single-step trace flag in EPSW, its use is not
153 * sufficiently documented and is only intended for use with the JTAG debugger.
154 */
155static int kgdb_arch_do_singlestep(struct pt_regs *regs)
156{
157 unsigned long arg;
158 unsigned size;
159 u8 *pc = (u8 *)regs->pc, *sp = (u8 *)(regs + 1), cur;
160 u8 *x = NULL, *y = NULL;
161 int ret;
162
163 ret = probe_kernel_read(&cur, pc, 1);
164 if (ret < 0)
165 return ret;
166
167 size = mn10300_kgdb_insn_sizes[cur];
168 if (size > 0) {
169 x = pc + size;
170 goto set_x;
171 }
172
173 switch (cur) {
174 /* Bxx (d8,PC) */
175 case 0xc0 ... 0xca:
176 ret = probe_kernel_read(&arg, pc + 1, 1);
177 if (ret < 0)
178 return ret;
179 x = pc + 2;
180 if (arg >= 0 && arg <= 2)
181 goto set_x;
182 y = pc + (s8)arg;
183 goto set_x_and_y;
184
185 /* LXX (d8,PC) */
186 case 0xd0 ... 0xda:
187 x = pc + 1;
188 if (regs->pc == regs->lar)
189 goto set_x;
190 y = (u8 *)regs->lar;
191 goto set_x_and_y;
192
193 /* SETLB - loads the next four bytes into the LIR register
194 * (which mustn't include a breakpoint instruction) */
195 case 0xdb:
196 x = pc + 5;
197 goto set_x;
198
199 /* JMP (d16,PC) or CALL (d16,PC) */
200 case 0xcc:
201 case 0xcd:
202 ret = probe_kernel_read(&arg, pc + 1, 2);
203 if (ret < 0)
204 return ret;
205 x = pc + (s16)arg;
206 goto set_x;
207
208 /* JMP (d32,PC) or CALL (d32,PC) */
209 case 0xdc:
210 case 0xdd:
211 ret = probe_kernel_read(&arg, pc + 1, 4);
212 if (ret < 0)
213 return ret;
214 x = pc + (s32)arg;
215 goto set_x;
216
217 /* RETF */
218 case 0xde:
219 x = (u8 *)regs->mdr;
220 goto set_x;
221
222 /* RET */
223 case 0xdf:
224 ret = probe_kernel_read(&arg, pc + 2, 1);
225 if (ret < 0)
226 return ret;
227 ret = probe_kernel_read(&x, sp + (s8)arg, 4);
228 if (ret < 0)
229 return ret;
230 goto set_x;
231
232 case 0xf0:
233 ret = probe_kernel_read(&cur, pc + 1, 1);
234 if (ret < 0)
235 return ret;
236
237 if (cur >= 0xf0 && cur <= 0xf7) {
238 /* JMP (An) / CALLS (An) */
239 switch (cur & 3) {
240 case 0: x = (u8 *)regs->a0; break;
241 case 1: x = (u8 *)regs->a1; break;
242 case 2: x = (u8 *)regs->a2; break;
243 case 3: x = (u8 *)regs->a3; break;
244 }
245 goto set_x;
246 } else if (cur == 0xfc) {
247 /* RETS */
248 ret = probe_kernel_read(&x, sp, 4);
249 if (ret < 0)
250 return ret;
251 goto set_x;
252 } else if (cur == 0xfd) {
253 /* RTI */
254 ret = probe_kernel_read(&x, sp + 4, 4);
255 if (ret < 0)
256 return ret;
257 goto set_x;
258 } else {
259 x = pc + 2;
260 goto set_x;
261 }
262 break;
263
264 /* potential 3-byte conditional branches */
265 case 0xf8:
266 ret = probe_kernel_read(&cur, pc + 1, 1);
267 if (ret < 0)
268 return ret;
269 x = pc + 3;
270
271 if (cur >= 0xe8 && cur <= 0xeb) {
272 ret = probe_kernel_read(&arg, pc + 2, 1);
273 if (ret < 0)
274 return ret;
275 if (arg >= 0 && arg <= 3)
276 goto set_x;
277 y = pc + (s8)arg;
278 goto set_x_and_y;
279 }
280 goto set_x;
281
282 case 0xfa:
283 ret = probe_kernel_read(&cur, pc + 1, 1);
284 if (ret < 0)
285 return ret;
286
287 if (cur == 0xff) {
288 /* CALLS (d16,PC) */
289 ret = probe_kernel_read(&arg, pc + 2, 2);
290 if (ret < 0)
291 return ret;
292 x = pc + (s16)arg;
293 goto set_x;
294 }
295
296 x = pc + 4;
297 goto set_x;
298
299 case 0xfc:
300 ret = probe_kernel_read(&cur, pc + 1, 1);
301 if (ret < 0)
302 return ret;
303
304 if (cur == 0xff) {
305 /* CALLS (d32,PC) */
306 ret = probe_kernel_read(&arg, pc + 2, 4);
307 if (ret < 0)
308 return ret;
309 x = pc + (s32)arg;
310 goto set_x;
311 }
312
313 x = pc + 6;
314 goto set_x;
315 }
316
317 return 0;
318
319set_x:
320 kgdb_sstep_bp_addr[0] = x;
321 kgdb_sstep_bp_addr[1] = NULL;
322 ret = probe_kernel_read(&kgdb_sstep_bp[0], x, 1);
323 if (ret < 0)
324 return ret;
325 ret = probe_kernel_write(x, &arch_kgdb_ops.gdb_bpt_instr, 1);
326 if (ret < 0)
327 return ret;
328 kgdb_sstep_thread = current_thread_info();
329 debugger_local_cache_flushinv_one(x);
330 return ret;
331
332set_x_and_y:
333 kgdb_sstep_bp_addr[0] = x;
334 kgdb_sstep_bp_addr[1] = y;
335 ret = probe_kernel_read(&kgdb_sstep_bp[0], x, 1);
336 if (ret < 0)
337 return ret;
338 ret = probe_kernel_read(&kgdb_sstep_bp[1], y, 1);
339 if (ret < 0)
340 return ret;
341 ret = probe_kernel_write(x, &arch_kgdb_ops.gdb_bpt_instr, 1);
342 if (ret < 0)
343 return ret;
344 ret = probe_kernel_write(y, &arch_kgdb_ops.gdb_bpt_instr, 1);
345 if (ret < 0) {
346 probe_kernel_write(kgdb_sstep_bp_addr[0],
347 &kgdb_sstep_bp[0], 1);
348 } else {
349 kgdb_sstep_thread = current_thread_info();
350 }
351 debugger_local_cache_flushinv_one(x);
352 debugger_local_cache_flushinv_one(y);
353 return ret;
354}
355
356/*
357 * Remove emplaced single-step breakpoints, returning true if we hit one of
358 * them.
359 */
360static bool kgdb_arch_undo_singlestep(struct pt_regs *regs)
361{
362 bool hit = false;
363 u8 *x = kgdb_sstep_bp_addr[0], *y = kgdb_sstep_bp_addr[1];
364 u8 opcode;
365
366 if (kgdb_sstep_thread == current_thread_info()) {
367 if (x) {
368 if (x == (u8 *)regs->pc)
369 hit = true;
370 if (probe_kernel_read(&opcode, x,
371 1) < 0 ||
372 opcode != 0xff)
373 BUG();
374 probe_kernel_write(x, &kgdb_sstep_bp[0], 1);
375 debugger_local_cache_flushinv_one(x);
376 }
377 if (y) {
378 if (y == (u8 *)regs->pc)
379 hit = true;
380 if (probe_kernel_read(&opcode, y,
381 1) < 0 ||
382 opcode != 0xff)
383 BUG();
384 probe_kernel_write(y, &kgdb_sstep_bp[1], 1);
385 debugger_local_cache_flushinv_one(y);
386 }
387 }
388
389 kgdb_sstep_bp_addr[0] = NULL;
390 kgdb_sstep_bp_addr[1] = NULL;
391 kgdb_sstep_thread = NULL;
392 return hit;
393}
394
395/*
396 * Catch a single-step-pending thread being deleted and make sure the global
397 * single-step state is cleared. At this point the breakpoints should have
398 * been removed by __switch_to().
399 */
400void free_thread_info(struct thread_info *ti)
401{
402 if (kgdb_sstep_thread == ti) {
403 kgdb_sstep_thread = NULL;
404
405 /* However, we may now be running in degraded mode, with most
406 * of the CPUs disabled until such a time as KGDB is reentered,
407 * so force immediate reentry */
408 kgdb_breakpoint();
409 }
410 kfree(ti);
411}
412
413/*
414 * Handle unknown packets and [CcsDk] packets
415 * - at this point breakpoints have been installed
416 */
417int kgdb_arch_handle_exception(int vector, int signo, int err_code,
418 char *remcom_in_buffer, char *remcom_out_buffer,
419 struct pt_regs *regs)
420{
421 long addr;
422 char *ptr;
423
424 switch (remcom_in_buffer[0]) {
425 case 'c':
426 case 's':
427 /* try to read optional parameter, pc unchanged if no parm */
428 ptr = &remcom_in_buffer[1];
429 if (kgdb_hex2long(&ptr, &addr))
430 regs->pc = addr;
431 case 'D':
432 case 'k':
433 atomic_set(&kgdb_cpu_doing_single_step, -1);
434
435 if (remcom_in_buffer[0] == 's') {
436 kgdb_arch_do_singlestep(regs);
437 kgdb_single_step = 1;
438 atomic_set(&kgdb_cpu_doing_single_step,
439 raw_smp_processor_id());
440 }
441 return 0;
442 }
443 return -1; /* this means that we do not want to exit from the handler */
444}
445
446/*
447 * Handle event interception
448 * - returns 0 if the exception should be skipped, -ERROR otherwise.
449 */
450int debugger_intercept(enum exception_code excep, int signo, int si_code,
451 struct pt_regs *regs)
452{
453 int ret;
454
455 if (kgdb_arch_undo_singlestep(regs)) {
456 excep = EXCEP_TRAP;
457 signo = SIGTRAP;
458 si_code = TRAP_TRACE;
459 }
460
461 ret = kgdb_handle_exception(excep, signo, si_code, regs);
462
463 debugger_local_cache_flushinv();
464
465 return ret;
466}
467
468/*
469 * Determine if we've hit a debugger special breakpoint
470 */
471int at_debugger_breakpoint(struct pt_regs *regs)
472{
473 return regs->pc == (unsigned long)&__arch_kgdb_breakpoint;
474}
475
476/*
477 * Initialise kgdb
478 */
479int kgdb_arch_init(void)
480{
481 return 0;
482}
483
484/*
485 * Do something, perhaps, but don't know what.
486 */
487void kgdb_arch_exit(void)
488{
489}
490
491#ifdef CONFIG_SMP
492void debugger_nmi_interrupt(struct pt_regs *regs, enum exception_code code)
493{
494 kgdb_nmicallback(arch_smp_processor_id(), regs);
495 debugger_local_cache_flushinv();
496}
497
498void kgdb_roundup_cpus(unsigned long flags)
499{
500 smp_jump_to_debugger();
501}
502#endif
diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c
index 93c53739cfc9..efca426a2ed4 100644
--- a/arch/mn10300/kernel/mn10300-serial.c
+++ b/arch/mn10300/kernel/mn10300-serial.c
@@ -119,6 +119,10 @@ static int mn10300_serial_request_port(struct uart_port *);
119static void mn10300_serial_config_port(struct uart_port *, int); 119static void mn10300_serial_config_port(struct uart_port *, int);
120static int mn10300_serial_verify_port(struct uart_port *, 120static int mn10300_serial_verify_port(struct uart_port *,
121 struct serial_struct *); 121 struct serial_struct *);
122#ifdef CONFIG_CONSOLE_POLL
123static void mn10300_serial_poll_put_char(struct uart_port *, unsigned char);
124static int mn10300_serial_poll_get_char(struct uart_port *);
125#endif
122 126
123static const struct uart_ops mn10300_serial_ops = { 127static const struct uart_ops mn10300_serial_ops = {
124 .tx_empty = mn10300_serial_tx_empty, 128 .tx_empty = mn10300_serial_tx_empty,
@@ -138,6 +142,10 @@ static const struct uart_ops mn10300_serial_ops = {
138 .request_port = mn10300_serial_request_port, 142 .request_port = mn10300_serial_request_port,
139 .config_port = mn10300_serial_config_port, 143 .config_port = mn10300_serial_config_port,
140 .verify_port = mn10300_serial_verify_port, 144 .verify_port = mn10300_serial_verify_port,
145#ifdef CONFIG_CONSOLE_POLL
146 .poll_put_char = mn10300_serial_poll_put_char,
147 .poll_get_char = mn10300_serial_poll_get_char,
148#endif
141}; 149};
142 150
143static irqreturn_t mn10300_serial_interrupt(int irq, void *dev_id); 151static irqreturn_t mn10300_serial_interrupt(int irq, void *dev_id);
@@ -1634,3 +1642,70 @@ static int __init mn10300_serial_console_init(void)
1634 1642
1635console_initcall(mn10300_serial_console_init); 1643console_initcall(mn10300_serial_console_init);
1636#endif 1644#endif
1645
1646#ifdef CONFIG_CONSOLE_POLL
1647/*
1648 * Polled character reception for the kernel debugger
1649 */
1650static int mn10300_serial_poll_get_char(struct uart_port *_port)
1651{
1652 struct mn10300_serial_port *port =
1653 container_of(_port, struct mn10300_serial_port, uart);
1654 unsigned ix;
1655 u8 st, ch;
1656
1657 _enter("%s", port->name);
1658
1659 do {
1660 /* pull chars out of the hat */
1661 ix = port->rx_outp;
1662 if (ix == port->rx_inp)
1663 return NO_POLL_CHAR;
1664
1665 ch = port->rx_buffer[ix++];
1666 st = port->rx_buffer[ix++];
1667 smp_rmb();
1668 port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1);
1669
1670 } while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF));
1671
1672 return ch;
1673}
1674
1675
1676/*
1677 * Polled character transmission for the kernel debugger
1678 */
1679static void mn10300_serial_poll_put_char(struct uart_port *_port,
1680 unsigned char ch)
1681{
1682 struct mn10300_serial_port *port =
1683 container_of(_port, struct mn10300_serial_port, uart);
1684 u8 intr, tmp;
1685
1686 /* wait for the transmitter to finish anything it might be doing (and
1687 * this includes the virtual DMA handler, so it might take a while) */
1688 while (*port->_status & (SC01STR_TBF | SC01STR_TXF))
1689 continue;
1690
1691 /* disable the Tx ready interrupt */
1692 intr = *port->_intr;
1693 *port->_intr = intr & ~SC01ICR_TI;
1694 tmp = *port->_intr;
1695
1696 if (ch == 0x0a) {
1697 *(u8 *) port->_txb = 0x0d;
1698 while (*port->_status & SC01STR_TBF)
1699 continue;
1700 }
1701
1702 *(u8 *) port->_txb = ch;
1703 while (*port->_status & SC01STR_TBF)
1704 continue;
1705
1706 /* restore the Tx interrupt flag */
1707 *port->_intr = intr;
1708 tmp = *port->_intr;
1709}
1710
1711#endif /* CONFIG_CONSOLE_POLL */
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c
index e1b14a6ed544..28eec3102535 100644
--- a/arch/mn10300/kernel/process.c
+++ b/arch/mn10300/kernel/process.c
@@ -135,7 +135,7 @@ void release_segments(struct mm_struct *mm)
135 135
136void machine_restart(char *cmd) 136void machine_restart(char *cmd)
137{ 137{
138#ifdef CONFIG_GDBSTUB 138#ifdef CONFIG_KERNEL_DEBUGGER
139 gdbstub_exit(0); 139 gdbstub_exit(0);
140#endif 140#endif
141 141
@@ -148,14 +148,14 @@ void machine_restart(char *cmd)
148 148
149void machine_halt(void) 149void machine_halt(void)
150{ 150{
151#ifdef CONFIG_GDBSTUB 151#ifdef CONFIG_KERNEL_DEBUGGER
152 gdbstub_exit(0); 152 gdbstub_exit(0);
153#endif 153#endif
154} 154}
155 155
156void machine_power_off(void) 156void machine_power_off(void)
157{ 157{
158#ifdef CONFIG_GDBSTUB 158#ifdef CONFIG_KERNEL_DEBUGGER
159 gdbstub_exit(0); 159 gdbstub_exit(0);
160#endif 160#endif
161} 161}
diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c
index 1ebb79f1650d..51c02f97dcea 100644
--- a/arch/mn10300/kernel/smp.c
+++ b/arch/mn10300/kernel/smp.c
@@ -440,6 +440,22 @@ int smp_nmi_call_function(smp_call_func_t func, void *info, int wait)
440} 440}
441 441
442/** 442/**
443 * smp_jump_to_debugger - Make other CPUs enter the debugger by sending an IPI
444 *
445 * Send a non-maskable request to all other CPUs in the system, instructing
446 * them to jump into the debugger. The caller is responsible for checking that
447 * the other CPUs responded to the instruction.
448 *
449 * The caller should make sure that this CPU's debugger IPI is disabled.
450 */
451void smp_jump_to_debugger(void)
452{
453 if (num_online_cpus() > 1)
454 /* Send a message to all other CPUs */
455 send_IPI_allbutself(DEBUGGER_NMI_IPI);
456}
457
458/**
443 * stop_this_cpu - Callback to stop a CPU. 459 * stop_this_cpu - Callback to stop a CPU.
444 * @unused: Callback context (ignored). 460 * @unused: Callback context (ignored).
445 */ 461 */
@@ -603,7 +619,7 @@ static void __init smp_cpu_init(void)
603/** 619/**
604 * smp_prepare_cpu_init - Initialise CPU in startup_secondary 620 * smp_prepare_cpu_init - Initialise CPU in startup_secondary
605 * 621 *
606 * Set interrupt level 0-6 setting and init ICR of gdbstub. 622 * Set interrupt level 0-6 setting and init ICR of the kernel debugger.
607 */ 623 */
608void smp_prepare_cpu_init(void) 624void smp_prepare_cpu_init(void)
609{ 625{
@@ -622,15 +638,15 @@ void smp_prepare_cpu_init(void)
622 for (loop = 0; loop < GxICR_NUM_IRQS; loop++) 638 for (loop = 0; loop < GxICR_NUM_IRQS; loop++)
623 GxICR(loop) = GxICR_LEVEL_6 | GxICR_DETECT; 639 GxICR(loop) = GxICR_LEVEL_6 | GxICR_DETECT;
624 640
625#ifdef CONFIG_GDBSTUB 641#ifdef CONFIG_KERNEL_DEBUGGER
626 /* initialise GDB-stub */ 642 /* initialise the kernel debugger interrupt */
627 do { 643 do {
628 unsigned long flags; 644 unsigned long flags;
629 u16 tmp16; 645 u16 tmp16;
630 646
631 flags = arch_local_cli_save(); 647 flags = arch_local_cli_save();
632 GxICR(GDB_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT; 648 GxICR(DEBUGGER_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT;
633 tmp16 = GxICR(GDB_NMI_IPI); 649 tmp16 = GxICR(DEBUGGER_NMI_IPI);
634 arch_local_irq_restore(flags); 650 arch_local_irq_restore(flags);
635 } while (0); 651 } while (0);
636#endif 652#endif
diff --git a/arch/mn10300/kernel/switch_to.S b/arch/mn10300/kernel/switch_to.S
index 9074d0fb8788..de3e74fc9ea0 100644
--- a/arch/mn10300/kernel/switch_to.S
+++ b/arch/mn10300/kernel/switch_to.S
@@ -39,11 +39,17 @@ ENTRY(__switch_to)
39 39
40 # save prev context 40 # save prev context
41 mov __switch_back,d0 41 mov __switch_back,d0
42 mov d0,(THREAD_PC,a0)
43 mov sp,a2 42 mov sp,a2
44 mov a2,(THREAD_SP,a0) 43 mov a2,(THREAD_SP,a0)
45 mov a3,(THREAD_A3,a0) 44 mov a3,(THREAD_A3,a0)
46 45
46#ifdef CONFIG_KGDB
47 btst 0xff,(kgdb_single_step)
48 bne __switch_to__lift_sstep_bp
49__switch_to__continue:
50#endif
51 mov d0,(THREAD_PC,a0)
52
47 mov (THREAD_A3,a1),a3 53 mov (THREAD_A3,a1),a3
48 mov (THREAD_SP,a1),a2 54 mov (THREAD_SP,a1),a2
49 55
@@ -68,3 +74,106 @@ ENTRY(__switch_to)
68__switch_back: 74__switch_back:
69 and ~EPSW_NMID,epsw 75 and ~EPSW_NMID,epsw
70 ret [d2,d3,a2,a3,exreg1],32 76 ret [d2,d3,a2,a3,exreg1],32
77
78#ifdef CONFIG_KGDB
79###############################################################################
80#
81# Lift the single-step breakpoints when the task being traced is switched out
82# A0 = prev
83# A1 = next
84#
85###############################################################################
86__switch_to__lift_sstep_bp:
87 add -12,sp
88 mov a0,e4
89 mov a1,e5
90
91 # Clear the single-step flag to prevent us coming this way until we get
92 # switched back in
93 bclr 0xff,(kgdb_single_step)
94
95 # Remove first breakpoint
96 mov (kgdb_sstep_bp_addr),a2
97 cmp 0,a2
98 beq 1f
99 movbu (kgdb_sstep_bp),d0
100 movbu d0,(a2)
101#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
102 mov a2,d0
103 mov a2,d1
104 add 1,d1
105 calls flush_icache_range
106#endif
1071:
108
109 # Remove second breakpoint
110 mov (kgdb_sstep_bp_addr+4),a2
111 cmp 0,a2
112 beq 2f
113 movbu (kgdb_sstep_bp+1),d0
114 movbu d0,(a2)
115#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
116 mov a2,d0
117 mov a2,d1
118 add 1,d1
119 calls flush_icache_range
120#endif
1212:
122
123 # Change the resumption address and return
124 mov __switch_back__reinstall_sstep_bp,d0
125 mov e4,a0
126 mov e5,a1
127 add 12,sp
128 bra __switch_to__continue
129
130###############################################################################
131#
132# Reinstall the single-step breakpoints when the task being traced is switched
133# back in (A1 points to the new thread_struct).
134#
135###############################################################################
136__switch_back__reinstall_sstep_bp:
137 add -12,sp
138 mov a0,e4 # save the return value
139 mov 0xff,d3
140
141 # Reinstall first breakpoint
142 mov (kgdb_sstep_bp_addr),a2
143 cmp 0,a2
144 beq 1f
145 movbu (a2),d0
146 movbu d0,(kgdb_sstep_bp)
147 movbu d3,(a2)
148#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
149 mov a2,d0
150 mov a2,d1
151 add 1,d1
152 calls flush_icache_range
153#endif
1541:
155
156 # Reinstall second breakpoint
157 mov (kgdb_sstep_bp_addr+4),a2
158 cmp 0,a2
159 beq 2f
160 movbu (a2),d0
161 movbu d0,(kgdb_sstep_bp+1)
162 movbu d3,(a2)
163#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
164 mov a2,d0
165 mov a2,d1
166 add 1,d1
167 calls flush_icache_range
168#endif
1692:
170
171 mov d3,(kgdb_single_step)
172
173 # Restore the return value (the previous thread_struct pointer)
174 mov e4,a0
175 mov a0,d0
176 add 12,sp
177 bra __switch_back
178
179#endif /* CONFIG_KGDB */
diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c
index b90c3f160c77..f03cb278828f 100644
--- a/arch/mn10300/kernel/traps.c
+++ b/arch/mn10300/kernel/traps.c
@@ -38,8 +38,9 @@
38#include <asm/busctl-regs.h> 38#include <asm/busctl-regs.h>
39#include <unit/leds.h> 39#include <unit/leds.h>
40#include <asm/fpu.h> 40#include <asm/fpu.h>
41#include <asm/gdb-stub.h>
42#include <asm/sections.h> 41#include <asm/sections.h>
42#include <asm/debugger.h>
43#include "internal.h"
43 44
44#if (CONFIG_INTERRUPT_VECTOR_BASE & 0xffffff) 45#if (CONFIG_INTERRUPT_VECTOR_BASE & 0xffffff)
45#error "INTERRUPT_VECTOR_BASE not aligned to 16MiB boundary!" 46#error "INTERRUPT_VECTOR_BASE not aligned to 16MiB boundary!"
@@ -49,63 +50,169 @@ int kstack_depth_to_print = 24;
49 50
50spinlock_t die_lock = __SPIN_LOCK_UNLOCKED(die_lock); 51spinlock_t die_lock = __SPIN_LOCK_UNLOCKED(die_lock);
51 52
52ATOMIC_NOTIFIER_HEAD(mn10300_die_chain); 53struct exception_to_signal_map {
54 u8 signo;
55 u32 si_code;
56};
57
58static const struct exception_to_signal_map exception_to_signal_map[256] = {
59 /* MMU exceptions */
60 [EXCEP_ITLBMISS >> 3] = { 0, 0 },
61 [EXCEP_DTLBMISS >> 3] = { 0, 0 },
62 [EXCEP_IAERROR >> 3] = { 0, 0 },
63 [EXCEP_DAERROR >> 3] = { 0, 0 },
64
65 /* system exceptions */
66 [EXCEP_TRAP >> 3] = { SIGTRAP, TRAP_BRKPT },
67 [EXCEP_ISTEP >> 3] = { SIGTRAP, TRAP_TRACE }, /* Monitor */
68 [EXCEP_IBREAK >> 3] = { SIGTRAP, TRAP_HWBKPT }, /* Monitor */
69 [EXCEP_OBREAK >> 3] = { SIGTRAP, TRAP_HWBKPT }, /* Monitor */
70 [EXCEP_PRIVINS >> 3] = { SIGILL, ILL_PRVOPC },
71 [EXCEP_UNIMPINS >> 3] = { SIGILL, ILL_ILLOPC },
72 [EXCEP_UNIMPEXINS >> 3] = { SIGILL, ILL_ILLOPC },
73 [EXCEP_MEMERR >> 3] = { SIGSEGV, SEGV_ACCERR },
74 [EXCEP_MISALIGN >> 3] = { SIGBUS, BUS_ADRALN },
75 [EXCEP_BUSERROR >> 3] = { SIGBUS, BUS_ADRERR },
76 [EXCEP_ILLINSACC >> 3] = { SIGSEGV, SEGV_ACCERR },
77 [EXCEP_ILLDATACC >> 3] = { SIGSEGV, SEGV_ACCERR },
78 [EXCEP_IOINSACC >> 3] = { SIGSEGV, SEGV_ACCERR },
79 [EXCEP_PRIVINSACC >> 3] = { SIGSEGV, SEGV_ACCERR }, /* userspace */
80 [EXCEP_PRIVDATACC >> 3] = { SIGSEGV, SEGV_ACCERR }, /* userspace */
81 [EXCEP_DATINSACC >> 3] = { SIGSEGV, SEGV_ACCERR },
82 [EXCEP_DOUBLE_FAULT >> 3] = { SIGILL, ILL_BADSTK },
83
84 /* FPU exceptions */
85 [EXCEP_FPU_DISABLED >> 3] = { SIGILL, ILL_COPROC },
86 [EXCEP_FPU_UNIMPINS >> 3] = { SIGILL, ILL_COPROC },
87 [EXCEP_FPU_OPERATION >> 3] = { SIGFPE, FPE_INTDIV },
88
89 /* interrupts */
90 [EXCEP_WDT >> 3] = { SIGALRM, 0 },
91 [EXCEP_NMI >> 3] = { SIGQUIT, 0 },
92 [EXCEP_IRQ_LEVEL0 >> 3] = { SIGINT, 0 },
93 [EXCEP_IRQ_LEVEL1 >> 3] = { 0, 0 },
94 [EXCEP_IRQ_LEVEL2 >> 3] = { 0, 0 },
95 [EXCEP_IRQ_LEVEL3 >> 3] = { 0, 0 },
96 [EXCEP_IRQ_LEVEL4 >> 3] = { 0, 0 },
97 [EXCEP_IRQ_LEVEL5 >> 3] = { 0, 0 },
98 [EXCEP_IRQ_LEVEL6 >> 3] = { 0, 0 },
99
100 /* system calls */
101 [EXCEP_SYSCALL0 >> 3] = { 0, 0 },
102 [EXCEP_SYSCALL1 >> 3] = { SIGILL, ILL_ILLTRP },
103 [EXCEP_SYSCALL2 >> 3] = { SIGILL, ILL_ILLTRP },
104 [EXCEP_SYSCALL3 >> 3] = { SIGILL, ILL_ILLTRP },
105 [EXCEP_SYSCALL4 >> 3] = { SIGILL, ILL_ILLTRP },
106 [EXCEP_SYSCALL5 >> 3] = { SIGILL, ILL_ILLTRP },
107 [EXCEP_SYSCALL6 >> 3] = { SIGILL, ILL_ILLTRP },
108 [EXCEP_SYSCALL7 >> 3] = { SIGILL, ILL_ILLTRP },
109 [EXCEP_SYSCALL8 >> 3] = { SIGILL, ILL_ILLTRP },
110 [EXCEP_SYSCALL9 >> 3] = { SIGILL, ILL_ILLTRP },
111 [EXCEP_SYSCALL10 >> 3] = { SIGILL, ILL_ILLTRP },
112 [EXCEP_SYSCALL11 >> 3] = { SIGILL, ILL_ILLTRP },
113 [EXCEP_SYSCALL12 >> 3] = { SIGILL, ILL_ILLTRP },
114 [EXCEP_SYSCALL13 >> 3] = { SIGILL, ILL_ILLTRP },
115 [EXCEP_SYSCALL14 >> 3] = { SIGILL, ILL_ILLTRP },
116 [EXCEP_SYSCALL15 >> 3] = { SIGABRT, 0 },
117};
53 118
54/* 119/*
55 * These constants are for searching for possible module text 120 * Handle kernel exceptions.
56 * segments. MODULE_RANGE is a guess of how much space is likely 121 *
57 * to be vmalloced. 122 * See if there's a fixup handler we can force a jump to when an exception
123 * happens due to something kernel code did
58 */ 124 */
59#define MODULE_RANGE (8 * 1024 * 1024) 125int die_if_no_fixup(const char *str, struct pt_regs *regs,
60 126 enum exception_code code)
61#define DO_ERROR(signr, prologue, str, name) \ 127{
62asmlinkage void name(struct pt_regs *regs, u32 intcode) \ 128 u8 opcode;
63{ \ 129 int signo, si_code;
64 prologue; \ 130
65 if (die_if_no_fixup(str, regs, intcode)) \ 131 if (user_mode(regs))
66 return; \ 132 return 0;
67 force_sig(signr, current); \ 133
68} 134 peripheral_leds_display_exception(code);
135
136 signo = exception_to_signal_map[code >> 3].signo;
137 si_code = exception_to_signal_map[code >> 3].si_code;
138
139 switch (code) {
140 /* see if we can fixup the kernel accessing memory */
141 case EXCEP_ITLBMISS:
142 case EXCEP_DTLBMISS:
143 case EXCEP_IAERROR:
144 case EXCEP_DAERROR:
145 case EXCEP_MEMERR:
146 case EXCEP_MISALIGN:
147 case EXCEP_BUSERROR:
148 case EXCEP_ILLDATACC:
149 case EXCEP_IOINSACC:
150 case EXCEP_PRIVINSACC:
151 case EXCEP_PRIVDATACC:
152 case EXCEP_DATINSACC:
153 if (fixup_exception(regs))
154 return 1;
155 break;
69 156
70#define DO_EINFO(signr, prologue, str, name, sicode) \ 157 case EXCEP_TRAP:
71asmlinkage void name(struct pt_regs *regs, u32 intcode) \ 158 case EXCEP_UNIMPINS:
72{ \ 159 if (get_user(opcode, (uint8_t __user *)regs->pc) != 0)
73 siginfo_t info; \ 160 break;
74 prologue; \ 161 if (opcode == 0xff) {
75 if (die_if_no_fixup(str, regs, intcode)) \ 162 if (notify_die(DIE_BREAKPOINT, str, regs, code, 0, 0))
76 return; \ 163 return 1;
77 info.si_signo = signr; \ 164 if (at_debugger_breakpoint(regs))
78 if (signr == SIGILL && sicode == ILL_ILLOPC) { \ 165 regs->pc++;
79 uint8_t opcode; \ 166 signo = SIGTRAP;
80 if (get_user(opcode, (uint8_t __user *)regs->pc) == 0) \ 167 si_code = TRAP_BRKPT;
81 if (opcode == 0xff) \ 168 }
82 info.si_signo = SIGTRAP; \ 169 break;
83 } \ 170
84 info.si_errno = 0; \ 171 case EXCEP_SYSCALL1 ... EXCEP_SYSCALL14:
85 info.si_code = sicode; \ 172 /* syscall return addr is _after_ the instruction */
86 info.si_addr = (void *) regs->pc; \ 173 regs->pc -= 2;
87 force_sig_info(info.si_signo, &info, current); \ 174 break;
175
176 case EXCEP_SYSCALL15:
177 if (report_bug(regs->pc, regs) == BUG_TRAP_TYPE_WARN)
178 return 1;
179
180 /* syscall return addr is _after_ the instruction */
181 regs->pc -= 2;
182 break;
183
184 default:
185 break;
186 }
187
188 if (debugger_intercept(code, signo, si_code, regs) == 0)
189 return 1;
190
191 if (notify_die(DIE_GPF, str, regs, code, 0, 0))
192 return 1;
193
194 /* make the process die as the last resort */
195 die(str, regs, code);
88} 196}
89 197
90DO_ERROR(SIGTRAP, {}, "trap", trap); 198/*
91DO_ERROR(SIGSEGV, {}, "ibreak", ibreak); 199 * General exception handler
92DO_ERROR(SIGSEGV, {}, "obreak", obreak); 200 */
93DO_EINFO(SIGSEGV, {}, "access error", access_error, SEGV_ACCERR); 201asmlinkage void handle_exception(struct pt_regs *regs, u32 intcode)
94DO_EINFO(SIGSEGV, {}, "insn access error", insn_acc_error, SEGV_ACCERR); 202{
95DO_EINFO(SIGSEGV, {}, "data access error", data_acc_error, SEGV_ACCERR); 203 siginfo_t info;
96DO_EINFO(SIGILL, {}, "privileged opcode", priv_op, ILL_PRVOPC); 204
97DO_EINFO(SIGILL, {}, "invalid opcode", invalid_op, ILL_ILLOPC); 205 /* deal with kernel exceptions here */
98DO_EINFO(SIGILL, {}, "invalid ex opcode", invalid_exop, ILL_ILLOPC); 206 if (die_if_no_fixup(NULL, regs, intcode))
99DO_EINFO(SIGBUS, {}, "invalid address", mem_error, BUS_ADRERR); 207 return;
100DO_EINFO(SIGBUS, {}, "bus error", bus_error, BUS_ADRERR); 208
101 209 /* otherwise it's a userspace exception */
102DO_ERROR(SIGTRAP, 210 info.si_signo = exception_to_signal_map[intcode >> 3].signo;
103#ifndef CONFIG_MN10300_USING_JTAG 211 info.si_code = exception_to_signal_map[intcode >> 3].si_code;
104 DCR &= ~0x0001, 212 info.si_errno = 0;
105#else 213 info.si_addr = (void *) regs->pc;
106 {}, 214 force_sig_info(info.si_signo, &info, current);
107#endif 215}
108 "single step", istep);
109 216
110/* 217/*
111 * handle NMI 218 * handle NMI
@@ -113,10 +220,8 @@ DO_ERROR(SIGTRAP,
113asmlinkage void nmi(struct pt_regs *regs, enum exception_code code) 220asmlinkage void nmi(struct pt_regs *regs, enum exception_code code)
114{ 221{
115 /* see if gdbstub wants to deal with it */ 222 /* see if gdbstub wants to deal with it */
116#ifdef CONFIG_GDBSTUB 223 if (debugger_intercept(code, SIGQUIT, 0, regs))
117 if (gdbstub_intercept(regs, code))
118 return; 224 return;
119#endif
120 225
121 printk(KERN_WARNING "--- Register Dump ---\n"); 226 printk(KERN_WARNING "--- Register Dump ---\n");
122 show_registers(regs); 227 show_registers(regs);
@@ -128,29 +233,36 @@ asmlinkage void nmi(struct pt_regs *regs, enum exception_code code)
128 */ 233 */
129void show_trace(unsigned long *sp) 234void show_trace(unsigned long *sp)
130{ 235{
131 unsigned long *stack, addr, module_start, module_end; 236 unsigned long bottom, stack, addr, fp, raslot;
132 int i; 237
133 238 printk(KERN_EMERG "\nCall Trace:\n");
134 printk(KERN_EMERG "\nCall Trace:"); 239
135 240 //stack = (unsigned long)sp;
136 stack = sp; 241 asm("mov sp,%0" : "=a"(stack));
137 i = 0; 242 asm("mov a3,%0" : "=r"(fp));
138 module_start = VMALLOC_START; 243
139 module_end = VMALLOC_END; 244 raslot = ULONG_MAX;
245 bottom = (stack + THREAD_SIZE) & ~(THREAD_SIZE - 1);
246 for (; stack < bottom; stack += sizeof(addr)) {
247 addr = *(unsigned long *)stack;
248 if (stack == fp) {
249 if (addr > stack && addr < bottom) {
250 fp = addr;
251 raslot = stack + sizeof(addr);
252 continue;
253 }
254 fp = 0;
255 raslot = ULONG_MAX;
256 }
140 257
141 while (((long) stack & (THREAD_SIZE - 1)) != 0) {
142 addr = *stack++;
143 if (__kernel_text_address(addr)) { 258 if (__kernel_text_address(addr)) {
144#if 1
145 printk(" [<%08lx>]", addr); 259 printk(" [<%08lx>]", addr);
260 if (stack >= raslot)
261 raslot = ULONG_MAX;
262 else
263 printk(" ?");
146 print_symbol(" %s", addr); 264 print_symbol(" %s", addr);
147 printk("\n"); 265 printk("\n");
148#else
149 if ((i % 6) == 0)
150 printk(KERN_EMERG " ");
151 printk("[<%08lx>] ", addr);
152 i++;
153#endif
154 } 266 }
155 } 267 }
156 268
@@ -323,86 +435,6 @@ void die(const char *str, struct pt_regs *regs, enum exception_code code)
323} 435}
324 436
325/* 437/*
326 * see if there's a fixup handler we can force a jump to when an exception
327 * happens due to something kernel code did
328 */
329int die_if_no_fixup(const char *str, struct pt_regs *regs,
330 enum exception_code code)
331{
332 if (user_mode(regs))
333 return 0;
334
335 peripheral_leds_display_exception(code);
336
337 switch (code) {
338 /* see if we can fixup the kernel accessing memory */
339 case EXCEP_ITLBMISS:
340 case EXCEP_DTLBMISS:
341 case EXCEP_IAERROR:
342 case EXCEP_DAERROR:
343 case EXCEP_MEMERR:
344 case EXCEP_MISALIGN:
345 case EXCEP_BUSERROR:
346 case EXCEP_ILLDATACC:
347 case EXCEP_IOINSACC:
348 case EXCEP_PRIVINSACC:
349 case EXCEP_PRIVDATACC:
350 case EXCEP_DATINSACC:
351 if (fixup_exception(regs))
352 return 1;
353 case EXCEP_UNIMPINS:
354 if (regs->pc && *(uint8_t *)regs->pc == 0xff)
355 if (notify_die(DIE_BREAKPOINT, str, regs, code, 0, 0))
356 return 1;
357 break;
358 default:
359 break;
360 }
361
362 /* see if gdbstub wants to deal with it */
363#ifdef CONFIG_GDBSTUB
364 if (gdbstub_intercept(regs, code))
365 return 1;
366#endif
367
368 if (notify_die(DIE_GPF, str, regs, code, 0, 0))
369 return 1;
370
371 /* make the process die as the last resort */
372 die(str, regs, code);
373}
374
375/*
376 * handle unsupported syscall instructions (syscall 1-15)
377 */
378static asmlinkage void unsupported_syscall(struct pt_regs *regs,
379 enum exception_code code)
380{
381 struct task_struct *tsk = current;
382 siginfo_t info;
383
384 /* catch a kernel BUG() */
385 if (code == EXCEP_SYSCALL15 && !user_mode(regs)) {
386 if (report_bug(regs->pc, regs) == BUG_TRAP_TYPE_BUG) {
387#ifdef CONFIG_GDBSTUB
388 gdbstub_intercept(regs, code);
389#endif
390 }
391 }
392
393 regs->pc -= 2; /* syscall return addr is _after_ the instruction */
394
395 die_if_no_fixup("An unsupported syscall insn was used by the kernel\n",
396 regs, code);
397
398 info.si_signo = SIGILL;
399 info.si_errno = ENOSYS;
400 info.si_code = ILL_ILLTRP;
401 info.si_addr = (void *) regs->pc;
402 force_sig_info(SIGILL, &info, tsk);
403}
404
405/*
406 * display the register file when the stack pointer gets clobbered 438 * display the register file when the stack pointer gets clobbered
407 */ 439 */
408asmlinkage void do_double_fault(struct pt_regs *regs) 440asmlinkage void do_double_fault(struct pt_regs *regs)
@@ -481,10 +513,8 @@ asmlinkage void uninitialised_exception(struct pt_regs *regs,
481{ 513{
482 514
483 /* see if gdbstub wants to deal with it */ 515 /* see if gdbstub wants to deal with it */
484#ifdef CONFIG_GDBSTUB 516 if (debugger_intercept(code, SIGSYS, 0, regs) == 0)
485 if (gdbstub_intercept(regs, code))
486 return; 517 return;
487#endif
488 518
489 peripheral_leds_display_exception(code); 519 peripheral_leds_display_exception(code);
490 printk(KERN_EMERG "Uninitialised Exception 0x%04x\n", code & 0xFFFF); 520 printk(KERN_EMERG "Uninitialised Exception 0x%04x\n", code & 0xFFFF);
@@ -549,43 +579,43 @@ void __init set_intr_stub(enum exception_code code, void *handler)
549 */ 579 */
550void __init trap_init(void) 580void __init trap_init(void)
551{ 581{
552 set_excp_vector(EXCEP_TRAP, trap); 582 set_excp_vector(EXCEP_TRAP, handle_exception);
553 set_excp_vector(EXCEP_ISTEP, istep); 583 set_excp_vector(EXCEP_ISTEP, handle_exception);
554 set_excp_vector(EXCEP_IBREAK, ibreak); 584 set_excp_vector(EXCEP_IBREAK, handle_exception);
555 set_excp_vector(EXCEP_OBREAK, obreak); 585 set_excp_vector(EXCEP_OBREAK, handle_exception);
556 586
557 set_excp_vector(EXCEP_PRIVINS, priv_op); 587 set_excp_vector(EXCEP_PRIVINS, handle_exception);
558 set_excp_vector(EXCEP_UNIMPINS, invalid_op); 588 set_excp_vector(EXCEP_UNIMPINS, handle_exception);
559 set_excp_vector(EXCEP_UNIMPEXINS, invalid_exop); 589 set_excp_vector(EXCEP_UNIMPEXINS, handle_exception);
560 set_excp_vector(EXCEP_MEMERR, mem_error); 590 set_excp_vector(EXCEP_MEMERR, handle_exception);
561 set_excp_vector(EXCEP_MISALIGN, misalignment); 591 set_excp_vector(EXCEP_MISALIGN, misalignment);
562 set_excp_vector(EXCEP_BUSERROR, bus_error); 592 set_excp_vector(EXCEP_BUSERROR, handle_exception);
563 set_excp_vector(EXCEP_ILLINSACC, insn_acc_error); 593 set_excp_vector(EXCEP_ILLINSACC, handle_exception);
564 set_excp_vector(EXCEP_ILLDATACC, data_acc_error); 594 set_excp_vector(EXCEP_ILLDATACC, handle_exception);
565 set_excp_vector(EXCEP_IOINSACC, insn_acc_error); 595 set_excp_vector(EXCEP_IOINSACC, handle_exception);
566 set_excp_vector(EXCEP_PRIVINSACC, insn_acc_error); 596 set_excp_vector(EXCEP_PRIVINSACC, handle_exception);
567 set_excp_vector(EXCEP_PRIVDATACC, data_acc_error); 597 set_excp_vector(EXCEP_PRIVDATACC, handle_exception);
568 set_excp_vector(EXCEP_DATINSACC, insn_acc_error); 598 set_excp_vector(EXCEP_DATINSACC, handle_exception);
569 set_excp_vector(EXCEP_FPU_UNIMPINS, fpu_invalid_op); 599 set_excp_vector(EXCEP_FPU_UNIMPINS, handle_exception);
570 set_excp_vector(EXCEP_FPU_OPERATION, fpu_exception); 600 set_excp_vector(EXCEP_FPU_OPERATION, fpu_exception);
571 601
572 set_excp_vector(EXCEP_NMI, nmi); 602 set_excp_vector(EXCEP_NMI, nmi);
573 603
574 set_excp_vector(EXCEP_SYSCALL1, unsupported_syscall); 604 set_excp_vector(EXCEP_SYSCALL1, handle_exception);
575 set_excp_vector(EXCEP_SYSCALL2, unsupported_syscall); 605 set_excp_vector(EXCEP_SYSCALL2, handle_exception);
576 set_excp_vector(EXCEP_SYSCALL3, unsupported_syscall); 606 set_excp_vector(EXCEP_SYSCALL3, handle_exception);
577 set_excp_vector(EXCEP_SYSCALL4, unsupported_syscall); 607 set_excp_vector(EXCEP_SYSCALL4, handle_exception);
578 set_excp_vector(EXCEP_SYSCALL5, unsupported_syscall); 608 set_excp_vector(EXCEP_SYSCALL5, handle_exception);
579 set_excp_vector(EXCEP_SYSCALL6, unsupported_syscall); 609 set_excp_vector(EXCEP_SYSCALL6, handle_exception);
580 set_excp_vector(EXCEP_SYSCALL7, unsupported_syscall); 610 set_excp_vector(EXCEP_SYSCALL7, handle_exception);
581 set_excp_vector(EXCEP_SYSCALL8, unsupported_syscall); 611 set_excp_vector(EXCEP_SYSCALL8, handle_exception);
582 set_excp_vector(EXCEP_SYSCALL9, unsupported_syscall); 612 set_excp_vector(EXCEP_SYSCALL9, handle_exception);
583 set_excp_vector(EXCEP_SYSCALL10, unsupported_syscall); 613 set_excp_vector(EXCEP_SYSCALL10, handle_exception);
584 set_excp_vector(EXCEP_SYSCALL11, unsupported_syscall); 614 set_excp_vector(EXCEP_SYSCALL11, handle_exception);
585 set_excp_vector(EXCEP_SYSCALL12, unsupported_syscall); 615 set_excp_vector(EXCEP_SYSCALL12, handle_exception);
586 set_excp_vector(EXCEP_SYSCALL13, unsupported_syscall); 616 set_excp_vector(EXCEP_SYSCALL13, handle_exception);
587 set_excp_vector(EXCEP_SYSCALL14, unsupported_syscall); 617 set_excp_vector(EXCEP_SYSCALL14, handle_exception);
588 set_excp_vector(EXCEP_SYSCALL15, unsupported_syscall); 618 set_excp_vector(EXCEP_SYSCALL15, handle_exception);
589} 619}
590 620
591/* 621/*