aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2011-03-18 12:54:30 -0400
committerDavid Howells <dhowells@redhat.com>2011-03-18 12:54:30 -0400
commit67ddb4052daac9d449caf2643ac365d42a04219a (patch)
tree7c610973a19b7e70b47294c540b182f203680fde
parent7f386ac3272e057fbf51e5b5712fad1a80e77125 (diff)
MN10300: Create generic kernel debugger hooks
Create generic kernel debugger hooks in the MN10300 arch and make gdbstub use them. This is a preparation for KGDB support. Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--arch/mn10300/Kconfig6
-rw-r--r--arch/mn10300/include/asm/debugger.h15
-rw-r--r--arch/mn10300/include/asm/fpu.h2
-rw-r--r--arch/mn10300/include/asm/irqflags.h2
-rw-r--r--arch/mn10300/include/asm/smp.h3
-rw-r--r--arch/mn10300/kernel/entry.S36
-rw-r--r--arch/mn10300/kernel/fpu.c18
-rw-r--r--arch/mn10300/kernel/gdb-io-ttysm.c8
-rw-r--r--arch/mn10300/kernel/gdb-stub.c25
-rw-r--r--arch/mn10300/kernel/internal.h7
-rw-r--r--arch/mn10300/kernel/irq.c2
-rw-r--r--arch/mn10300/kernel/smp.c26
-rw-r--r--arch/mn10300/kernel/traps.c406
-rw-r--r--arch/mn10300/mm/fault.c9
14 files changed, 317 insertions, 248 deletions
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index 25e6a0bc62ab..6e9cac970024 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -401,8 +401,8 @@ comment "[!] NOTE: A lower number/level indicates a higher priority (0 is highes
401comment "____Non-maskable interrupt levels____" 401comment "____Non-maskable interrupt levels____"
402comment "The following must be set to a higher priority than local_irq_disable() and on-chip serial" 402comment "The following must be set to a higher priority than local_irq_disable() and on-chip serial"
403 403
404config GDBSTUB_IRQ_LEVEL 404config DEBUGGER_IRQ_LEVEL
405 int "GDBSTUB interrupt priority" 405 int "DEBUGGER interrupt priority"
406 depends on KERNEL_DEBUGGER 406 depends on KERNEL_DEBUGGER
407 range 0 1 if LINUX_CLI_LEVEL = 2 407 range 0 1 if LINUX_CLI_LEVEL = 2
408 range 0 2 if LINUX_CLI_LEVEL = 3 408 range 0 2 if LINUX_CLI_LEVEL = 3
@@ -437,7 +437,7 @@ config LINUX_CLI_LEVEL
437 EPSW.IM from 7. Any interrupt is permitted for which the level is 437 EPSW.IM from 7. Any interrupt is permitted for which the level is
438 lower than EPSW.IM. 438 lower than EPSW.IM.
439 439
440 Certain interrupts, such as GDBSTUB and virtual MN10300 on-chip 440 Certain interrupts, such as DEBUGGER and virtual MN10300 on-chip
441 serial DMA interrupts are allowed to interrupt normal disabled 441 serial DMA interrupts are allowed to interrupt normal disabled
442 sections. 442 sections.
443 443
diff --git a/arch/mn10300/include/asm/debugger.h b/arch/mn10300/include/asm/debugger.h
index 4517f839a999..e1d3b083696c 100644
--- a/arch/mn10300/include/asm/debugger.h
+++ b/arch/mn10300/include/asm/debugger.h
@@ -14,6 +14,9 @@
14 14
15#if defined(CONFIG_KERNEL_DEBUGGER) 15#if defined(CONFIG_KERNEL_DEBUGGER)
16 16
17extern int debugger_intercept(enum exception_code, int, int, struct pt_regs *);
18extern int at_debugger_breakpoint(struct pt_regs *);
19
17#ifndef CONFIG_MN10300_DEBUGGER_CACHE_NO_FLUSH 20#ifndef CONFIG_MN10300_DEBUGGER_CACHE_NO_FLUSH
18extern void debugger_local_cache_flushinv(void); 21extern void debugger_local_cache_flushinv(void);
19extern void debugger_local_cache_flushinv_one(u8 *); 22extern void debugger_local_cache_flushinv_one(u8 *);
@@ -24,5 +27,17 @@ static inline void debugger_local_cache_flushinv_one(u8 *addr) {}
24 27
25#else /* CONFIG_KERNEL_DEBUGGER */ 28#else /* CONFIG_KERNEL_DEBUGGER */
26 29
30static inline int debugger_intercept(enum exception_code excep,
31 int signo, int si_code,
32 struct pt_regs *regs)
33{
34 return 0;
35}
36
37static inline int at_debugger_breakpoint(struct pt_regs *regs)
38{
39 return 0;
40}
41
27#endif /* CONFIG_KERNEL_DEBUGGER */ 42#endif /* CONFIG_KERNEL_DEBUGGER */
28#endif /* _ASM_DEBUGGER_H */ 43#endif /* _ASM_DEBUGGER_H */
diff --git a/arch/mn10300/include/asm/fpu.h b/arch/mn10300/include/asm/fpu.h
index b7625de8eade..738ff72659d5 100644
--- a/arch/mn10300/include/asm/fpu.h
+++ b/arch/mn10300/include/asm/fpu.h
@@ -55,7 +55,6 @@ static inline void clear_using_fpu(struct task_struct *tsk)
55 55
56extern asmlinkage void fpu_kill_state(struct task_struct *); 56extern asmlinkage void fpu_kill_state(struct task_struct *);
57extern asmlinkage void fpu_exception(struct pt_regs *, enum exception_code); 57extern asmlinkage void fpu_exception(struct pt_regs *, enum exception_code);
58extern asmlinkage void fpu_invalid_op(struct pt_regs *, enum exception_code);
59extern asmlinkage void fpu_init_state(void); 58extern asmlinkage void fpu_init_state(void);
60extern asmlinkage void fpu_save(struct fpu_state_struct *); 59extern asmlinkage void fpu_save(struct fpu_state_struct *);
61extern int fpu_setup_sigcontext(struct fpucontext *buf); 60extern int fpu_setup_sigcontext(struct fpucontext *buf);
@@ -113,7 +112,6 @@ static inline void flush_fpu(void)
113 112
114extern asmlinkage 113extern asmlinkage
115void unexpected_fpu_exception(struct pt_regs *, enum exception_code); 114void unexpected_fpu_exception(struct pt_regs *, enum exception_code);
116#define fpu_invalid_op unexpected_fpu_exception
117#define fpu_exception unexpected_fpu_exception 115#define fpu_exception unexpected_fpu_exception
118 116
119struct task_struct; 117struct task_struct;
diff --git a/arch/mn10300/include/asm/irqflags.h b/arch/mn10300/include/asm/irqflags.h
index 7a7ae12c7119..678f68d5f37b 100644
--- a/arch/mn10300/include/asm/irqflags.h
+++ b/arch/mn10300/include/asm/irqflags.h
@@ -20,7 +20,7 @@
20/* 20/*
21 * interrupt control 21 * interrupt control
22 * - "disabled": run in IM1/2 22 * - "disabled": run in IM1/2
23 * - level 0 - GDB stub 23 * - level 0 - kernel debugger
24 * - level 1 - virtual serial DMA (if present) 24 * - level 1 - virtual serial DMA (if present)
25 * - level 5 - normal interrupt priority 25 * - level 5 - normal interrupt priority
26 * - level 6 - timer interrupt 26 * - level 6 - timer interrupt
diff --git a/arch/mn10300/include/asm/smp.h b/arch/mn10300/include/asm/smp.h
index a3930e43a958..e3d13a899855 100644
--- a/arch/mn10300/include/asm/smp.h
+++ b/arch/mn10300/include/asm/smp.h
@@ -34,7 +34,7 @@
34#define LOCAL_TIMER_IPI 193 34#define LOCAL_TIMER_IPI 193
35#define FLUSH_CACHE_IPI 194 35#define FLUSH_CACHE_IPI 194
36#define CALL_FUNCTION_NMI_IPI 195 36#define CALL_FUNCTION_NMI_IPI 195
37#define GDB_NMI_IPI 196 37#define DEBUGGER_NMI_IPI 196
38 38
39#define SMP_BOOT_IRQ 195 39#define SMP_BOOT_IRQ 195
40 40
@@ -43,6 +43,7 @@
43#define LOCAL_TIMER_GxICR_LV GxICR_LEVEL_4 43#define LOCAL_TIMER_GxICR_LV GxICR_LEVEL_4
44#define FLUSH_CACHE_GxICR_LV GxICR_LEVEL_0 44#define FLUSH_CACHE_GxICR_LV GxICR_LEVEL_0
45#define SMP_BOOT_GxICR_LV GxICR_LEVEL_0 45#define SMP_BOOT_GxICR_LV GxICR_LEVEL_0
46#define DEBUGGER_GxICR_LV CONFIG_DEBUGGER_IRQ_LEVEL
46 47
47#define TIME_OUT_COUNT_BOOT_IPI 100 48#define TIME_OUT_COUNT_BOOT_IPI 100
48#define DELAY_TIME_BOOT_IPI 75000 49#define DELAY_TIME_BOOT_IPI 75000
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S
index 8e79a04f1cb0..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,30 +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 313
310 mov (sp),d0 314 mov (sp),d0
311 SAVE_ALL 315 SAVE_ALL
312 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
313 RESTORE_ALL 319 RESTORE_ALL
3143: 320
315#endif /* CONFIG_GDBSTUB */ 321nmi_not_debugger:
322#endif /* CONFIG_KERNEL_DEBUGGER */
316 mov (sp),d0 # restore TBR to d0 323 mov (sp),d0 # restore TBR to d0
317 add 4,sp 324 add 4,sp
318#endif /* CONFIG_SMP */ 325#endif /* CONFIG_SMP */
319 326
320 bra __common_exception_nonmi 327 bra __common_exception_nonmi
321 328
329###############################################################################
330#
331# General exception entry point
332#
333###############################################################################
322ENTRY(__common_exception) 334ENTRY(__common_exception)
323 add -4,sp 335 add -4,sp
324 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-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 1e8f24f00637..538266b2c9bc 100644
--- a/arch/mn10300/kernel/gdb-stub.c
+++ b/arch/mn10300/kernel/gdb-stub.c
@@ -1173,7 +1173,7 @@ int gdbstub_clear_breakpoint(u8 *addr, int len)
1173 1173
1174/* 1174/*
1175 * This function does all command processing for interfacing to gdb 1175 * This function does all command processing for interfacing to gdb
1176 * - returns 1 if the exception should be skipped, 0 otherwise. 1176 * - returns 0 if the exception should be skipped, -ERROR otherwise.
1177 */ 1177 */
1178static int gdbstub(struct pt_regs *regs, enum exception_code excep) 1178static int gdbstub(struct pt_regs *regs, enum exception_code excep)
1179{ 1179{
@@ -1188,7 +1188,7 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
1188 int loop; 1188 int loop;
1189 1189
1190 if (excep == EXCEP_FPU_DISABLED) 1190 if (excep == EXCEP_FPU_DISABLED)
1191 return 0; 1191 return -ENOTSUPP;
1192 1192
1193 gdbstub_flush_caches = 0; 1193 gdbstub_flush_caches = 0;
1194 1194
@@ -1197,7 +1197,7 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep)
1197 asm volatile("mov mdr,%0" : "=d"(mdr)); 1197 asm volatile("mov mdr,%0" : "=d"(mdr));
1198 local_save_flags(epsw); 1198 local_save_flags(epsw);
1199 arch_local_change_intr_mask_level( 1199 arch_local_change_intr_mask_level(
1200 NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); 1200 NUM2EPSW_IM(CONFIG_DEBUGGER_IRQ_LEVEL + 1));
1201 1201
1202 gdbstub_store_fpu(); 1202 gdbstub_store_fpu();
1203 1203
@@ -1675,14 +1675,23 @@ done:
1675 touch_softlockup_watchdog(); 1675 touch_softlockup_watchdog();
1676 1676
1677 local_irq_restore(epsw); 1677 local_irq_restore(epsw);
1678 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;
1679} 1688}
1680 1689
1681/* 1690/*
1682 * handle event interception 1691 * handle event interception
1683 */ 1692 */
1684asmlinkage int gdbstub_intercept(struct pt_regs *regs, 1693asmlinkage int debugger_intercept(enum exception_code excep,
1685 enum exception_code excep) 1694 int signo, int si_code, struct pt_regs *regs)
1686{ 1695{
1687 static u8 notfirst = 1; 1696 static u8 notfirst = 1;
1688 int ret; 1697 int ret;
@@ -1696,7 +1705,7 @@ asmlinkage int gdbstub_intercept(struct pt_regs *regs,
1696 asm("mov mdr,%0" : "=d"(mdr)); 1705 asm("mov mdr,%0" : "=d"(mdr));
1697 1706
1698 gdbstub_entry( 1707 gdbstub_entry(
1699 "--> gdbstub_intercept(%p,%04x) [MDR=%lx PC=%lx]\n", 1708 "--> debugger_intercept(%p,%04x) [MDR=%lx PC=%lx]\n",
1700 regs, excep, mdr, regs->pc); 1709 regs, excep, mdr, regs->pc);
1701 1710
1702 gdbstub_entry( 1711 gdbstub_entry(
@@ -1730,7 +1739,7 @@ asmlinkage int gdbstub_intercept(struct pt_regs *regs,
1730 1739
1731 ret = gdbstub(regs, excep); 1740 ret = gdbstub(regs, excep);
1732 1741
1733 gdbstub_entry("<-- gdbstub_intercept()\n"); 1742 gdbstub_entry("<-- debugger_intercept()\n");
1734 gdbstub_busy = 0; 1743 gdbstub_busy = 0;
1735 return ret; 1744 return ret;
1736} 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/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/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/*
diff --git a/arch/mn10300/mm/fault.c b/arch/mn10300/mm/fault.c
index 59c3da49d9d9..0945409a8022 100644
--- a/arch/mn10300/mm/fault.c
+++ b/arch/mn10300/mm/fault.c
@@ -28,8 +28,9 @@
28#include <asm/uaccess.h> 28#include <asm/uaccess.h>
29#include <asm/pgalloc.h> 29#include <asm/pgalloc.h>
30#include <asm/hardirq.h> 30#include <asm/hardirq.h>
31#include <asm/gdb-stub.h>
32#include <asm/cpu-regs.h> 31#include <asm/cpu-regs.h>
32#include <asm/debugger.h>
33#include <asm/gdb-stub.h>
33 34
34/* 35/*
35 * Unlock any spinlocks which will prevent us from getting the 36 * Unlock any spinlocks which will prevent us from getting the
@@ -306,10 +307,8 @@ no_context:
306 printk(" printing pc:\n"); 307 printk(" printing pc:\n");
307 printk(KERN_ALERT "%08lx\n", regs->pc); 308 printk(KERN_ALERT "%08lx\n", regs->pc);
308 309
309#ifdef CONFIG_GDBSTUB 310 debugger_intercept(fault_code & 0x00010000 ? EXCEP_IAERROR : EXCEP_DAERROR,
310 gdbstub_intercept( 311 SIGSEGV, SEGV_ACCERR, regs);
311 regs, fault_code & 0x00010000 ? EXCEP_IAERROR : EXCEP_DAERROR);
312#endif
313 312
314 page = PTBR; 313 page = PTBR;
315 page = ((unsigned long *) __va(page))[address >> 22]; 314 page = ((unsigned long *) __va(page))[address >> 22];