aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/entry.S
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2006-10-11 23:03:04 -0400
committerPaul Mundt <lethal@linux-sh.org>2006-10-11 23:03:04 -0400
commitbaf4326e49801526e4516e4de7f37b5e51468c49 (patch)
tree44fc3dd7c68827613cf0bcfcf2f4edacc63b1ea1 /arch/sh/kernel/entry.S
parent8884c4cb8b621963b5eb4a9ae45070bd0cb7085f (diff)
sh: interrupt exception handling rework
Kill off interrupt_table for all of the CPU subtypes, we now default in to stepping in to do_IRQ() for _all_ IRQ exceptions and counting the spurious ones, rather than simply flipping on the ones we cared about. This and enabling the IRQ by default automatically has already uncovered a couple of bugs and IRQs that weren't being caught, as well as some that are being generated far too often (SCI Tx Data Empty, for example). The general rationale is to use a marker for interrupt exceptions, test for it in the handle_exception() path, and skip out to do_IRQ() if it's found. Everything else follows the same behaviour of finding the cached EXPEVT value in r2/r2_bank, we just rip out the INTEVT read from entry.S entirely (except for in the kGDB NMI case, which is another matter). Note that while this changes the do_IRQ() semantics regarding r4 handling, they were fundamentally broken anyways (relying entirely on r2_bank for the cached code). With this, we do the INTEVT read from do_IRQ() itself (in the CONFIG_CPU_HAS_INTEVT case), or fall back on r4 for the muxed IRQ number, which should also be closer to what SH-2 and SH-2A want anyways. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/entry.S')
-rw-r--r--arch/sh/kernel/entry.S43
1 files changed, 33 insertions, 10 deletions
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index 97c571fbcdf1..39aaefb2d83f 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -1,9 +1,8 @@
1/* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $ 1/*
2 *
3 * linux/arch/sh/entry.S 2 * linux/arch/sh/entry.S
4 * 3 *
5 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka 4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
6 * Copyright (C) 2003 Paul Mundt 5 * Copyright (C) 2003 - 2006 Paul Mundt
7 * 6 *
8 * This file is subject to the terms and conditions of the GNU General Public 7 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive 8 * License. See the file "COPYING" in the main directory of this archive
@@ -78,7 +77,6 @@ OFF_TRA = (16*4+6*4)
78#define k3 r3 77#define k3 r3
79#define k4 r4 78#define k4 r4
80 79
81#define k_ex_code r2_bank /* r2_bank1 */
82#define g_imask r6 /* r6_bank1 */ 80#define g_imask r6 /* r6_bank1 */
83#define k_g_imask r6_bank /* r6_bank1 */ 81#define k_g_imask r6_bank /* r6_bank1 */
84#define current r7 /* r7_bank1 */ 82#define current r7 /* r7_bank1 */
@@ -691,7 +689,7 @@ interrupt:
6910: 6890:
692#endif /* defined(CONFIG_KGDB_NMI) */ 690#endif /* defined(CONFIG_KGDB_NMI) */
693 bra handle_exception 691 bra handle_exception
694 mov.l @k2, k2 692 mov #-1, k2 ! interrupt exception marker
695 693
696 .align 2 694 .align 2
6971: .long EXPEVT 6951: .long EXPEVT
@@ -717,8 +715,7 @@ ENTRY(handle_exception)
717 add current, k1 715 add current, k1
718 mov k1, r15 ! change to kernel stack 716 mov k1, r15 ! change to kernel stack
719 ! 717 !
7201: mov #-1, k4 7181: mov.l 2f, k1
721 mov.l 2f, k1
722 ! 719 !
723#ifdef CONFIG_SH_DSP 720#ifdef CONFIG_SH_DSP
724 mov.l r2, @-r15 ! Save r2, we need another reg 721 mov.l r2, @-r15 ! Save r2, we need another reg
@@ -763,6 +760,8 @@ skip_save:
763#endif 760#endif
764 ! Save the user registers on the stack. 761 ! Save the user registers on the stack.
765 mov.l k2, @-r15 ! EXPEVT 762 mov.l k2, @-r15 ! EXPEVT
763
764 mov #-1, k4
766 mov.l k4, @-r15 ! set TRA (default: -1) 765 mov.l k4, @-r15 ! set TRA (default: -1)
767 ! 766 !
768 sts.l macl, @-r15 767 sts.l macl, @-r15
@@ -797,8 +796,21 @@ skip_save:
797 mov.l r2, @-r15 796 mov.l r2, @-r15
798 mov.l r1, @-r15 797 mov.l r1, @-r15
799 mov.l r0, @-r15 798 mov.l r0, @-r15
800 ! Then, dispatch to the handler, according to the exception code. 799
801 stc k_ex_code, r8 800 /*
801 * This gets a bit tricky.. in the INTEVT case we don't want to use
802 * the VBR offset as a destination in the jump call table, since all
803 * of the destinations are the same. In this case, (interrupt) sets
804 * a marker in r2 (now r2_bank since SR.RB changed), which we check
805 * to determine the exception type. For all other exceptions, we
806 * forcibly read EXPEVT from memory and fix up the jump address, in
807 * the interrupt exception case we jump to do_IRQ() and defer the
808 * INTEVT read until there. As a bonus, we can also clean up the SR.RB
809 * checks that do_IRQ() was doing..
810 */
811 stc r2_bank, r8
812 cmp/pz r8
813 bf interrupt_exception
802 shlr2 r8 814 shlr2 r8
803 shlr r8 815 shlr r8
804 mov.l 4f, r9 816 mov.l 4f, r9
@@ -806,6 +818,8 @@ skip_save:
806 mov.l @r9, r9 818 mov.l @r9, r9
807 jmp @r9 819 jmp @r9
808 nop 820 nop
821 rts
822 nop
809 823
810 .align 2 824 .align 2
8111: .long 0x00001000 ! DSP=1 8251: .long 0x00001000 ! DSP=1
@@ -813,8 +827,17 @@ skip_save:
8133: .long 0xcfffffff ! RB=0, BL=0 8273: .long 0xcfffffff ! RB=0, BL=0
8144: .long exception_handling_table 8284: .long exception_handling_table
815 829
830interrupt_exception:
831 mov.l 1f, r9
832 jmp @r9
833 nop
834 rts
835 nop
836
837 .align 2
8381: .long do_IRQ
839
816 .align 2 840 .align 2
817ENTRY(exception_none) 841ENTRY(exception_none)
818 rts 842 rts
819 nop 843 nop
820