From baf4326e49801526e4516e4de7f37b5e51468c49 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 12 Oct 2006 12:03:04 +0900 Subject: [PATCH] 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 --- arch/sh/kernel/cpu/sh3/ex.S | 195 -------------- arch/sh/kernel/cpu/sh4/ex.S | 500 ------------------------------------ arch/sh/kernel/entry.S | 43 +++- arch/sh/kernel/irq.c | 23 +- 4 files changed, 40 insertions(+), 721 deletions(-) diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S index 44daf44833..6be46f0686 100644 --- a/arch/sh/kernel/cpu/sh3/ex.S +++ b/arch/sh/kernel/cpu/sh3/ex.S @@ -49,198 +49,3 @@ ENTRY(nmi_slot) #endif ENTRY(user_break_point_trap) .long break_point_trap /* 1E0 */ -ENTRY(interrupt_table) - ! external hardware - .long do_IRQ ! 0000 /* 200 */ - .long do_IRQ ! 0001 - .long do_IRQ ! 0010 - .long do_IRQ ! 0011 - .long do_IRQ ! 0100 - .long do_IRQ ! 0101 - .long do_IRQ ! 0110 - .long do_IRQ ! 0111 - .long do_IRQ ! 1000 /* 300 */ - .long do_IRQ ! 1001 - .long do_IRQ ! 1010 - .long do_IRQ ! 1011 - .long do_IRQ ! 1100 - .long do_IRQ ! 1101 - .long do_IRQ ! 1110 - .long exception_error - ! Internal hardware - .long do_IRQ ! TMU0 tuni0 /* 400 */ - .long do_IRQ ! TMU1 tuni1 - .long do_IRQ ! TMU2 tuni2 - .long do_IRQ ! ticpi2 - .long do_IRQ ! RTC ati - .long do_IRQ ! pri - .long do_IRQ ! cui - .long do_IRQ ! SCI eri - .long do_IRQ ! rxi /* 500 */ - .long do_IRQ ! txi - .long do_IRQ ! tei - .long do_IRQ ! WDT iti /* 560 */ - .long do_IRQ ! REF rcmi - .long do_IRQ ! rovi - .long do_IRQ - .long do_IRQ /* 5E0 */ -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \ - defined(CONFIG_CPU_SUBTYPE_SH7709) || \ - defined(CONFIG_CPU_SUBTYPE_SH7706) || \ - defined(CONFIG_CPU_SUBTYPE_SH7300) || \ - defined(CONFIG_CPU_SUBTYPE_SH7705) || \ - defined(CONFIG_CPU_SUBTYPE_SH7710) - .long do_IRQ ! 32 IRQ irq0 /* 600 */ - .long do_IRQ ! 33 irq1 - .long do_IRQ ! 34 irq2 - .long do_IRQ ! 35 irq3 - .long do_IRQ ! 36 irq4 - .long do_IRQ ! 37 irq5 - .long do_IRQ ! 38 - .long do_IRQ ! 39 - .long do_IRQ ! 40 PINT pint0-7 /* 700 */ - .long do_IRQ ! 41 pint8-15 - .long do_IRQ ! 42 - .long do_IRQ ! 43 - .long do_IRQ ! 44 - .long do_IRQ ! 45 - .long do_IRQ ! 46 - .long do_IRQ ! 47 - .long do_IRQ ! 48 DMAC dei0 /* 800 */ - .long do_IRQ ! 49 dei1 - .long do_IRQ ! 50 dei2 - .long do_IRQ ! 51 dei3 - .long do_IRQ ! 52 IrDA eri1 - .long do_IRQ ! 53 rxi1 - .long do_IRQ ! 54 bri1 - .long do_IRQ ! 55 txi1 - .long do_IRQ ! 56 SCIF eri2 - .long do_IRQ ! 57 rxi2 - .long do_IRQ ! 58 bri2 - .long do_IRQ ! 59 txi2 - .long do_IRQ ! 60 ADC adi /* 980 */ -#if defined(CONFIG_CPU_SUBTYPE_SH7705) - .long exception_none ! 61 /* 9A0 */ - .long exception_none ! 62 - .long exception_none ! 63 - .long exception_none ! 64 /* A00 */ - .long do_IRQ ! 65 USB usi0 - .long do_IRQ ! 66 usi1 - .long exception_none ! 67 - .long exception_none ! 68 - .long exception_none ! 69 - .long exception_none ! 70 - .long exception_none ! 71 - .long exception_none ! 72 /* B00 */ - .long exception_none ! 73 - .long exception_none ! 74 - .long exception_none ! 75 - .long exception_none ! 76 - .long exception_none ! 77 - .long exception_none ! 78 - .long exception_none ! 79 - .long do_IRQ ! 80 TPU0 tpi0 /* C00 */ - .long do_IRQ ! 81 TPU1 tpi1 - .long exception_none ! 82 - .long exception_none ! 83 - .long do_IRQ ! 84 TPU2 tpi2 - .long do_IRQ ! 85 TPU3 tpi3 /* CA0 */ -#endif -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7300) - .long do_IRQ ! 61 LCDC lcdi /* 9A0 */ - .long do_IRQ ! 62 PCC pcc0i - .long do_IRQ ! 63 pcc1i /* 9E0 */ -#endif -#if defined(CONFIG_CPU_SUBTYPE_SH7710) - .long exception_none ! 61 /* 9A0 */ - .long exception_none ! 62 - .long exception_none ! 63 - .long exception_none ! 64 /* A00 */ - .long exception_none ! 65 - .long exception_none ! 66 - .long exception_none ! 67 - .long exception_none ! 68 - .long exception_none ! 69 - .long exception_none ! 70 - .long exception_none ! 71 - .long exception_none ! 72 /* B00 */ - .long exception_none ! 73 - .long exception_none ! 74 - .long exception_none ! 75 - .long do_IRQ ! 76 DMAC2 dei4 /* B80 */ - .long do_IRQ ! 77 DMAC2 dei5 - .long exception_none ! 78 - .long do_IRQ ! 79 IPSEC ipseci /* BE0 */ - .long do_IRQ ! 80 EDMAC eint0 /* C00 */ - .long do_IRQ ! 81 EDMAC eint1 - .long do_IRQ ! 82 EDMAC eint2 - .long exception_none ! 83 /* C60 */ - .long exception_none ! 84 - .long exception_none ! 85 - .long exception_none ! 86 - .long exception_none ! 87 - .long exception_none ! 88 /* D00 */ - .long exception_none ! 89 - .long exception_none ! 90 - .long exception_none ! 91 - .long exception_none ! 92 - .long exception_none ! 93 - .long exception_none ! 94 - .long exception_none ! 95 - .long do_IRQ ! 96 SIOF eri0 /* E00 */ - .long do_IRQ ! 97 txi0 - .long do_IRQ ! 98 rxi0 - .long do_IRQ ! 99 cci0 - .long do_IRQ ! 100 eri1 /* E80 */ - .long do_IRQ ! 101 txi1 - .long do_IRQ ! 102 rxi2 - .long do_IRQ ! 103 cci3 -#endif -#if defined(CONFIG_CPU_SUBTYPE_SH7300) - .long do_IRQ ! 64 - .long do_IRQ ! 65 - .long do_IRQ ! 66 - .long do_IRQ ! 67 - .long do_IRQ ! 68 - .long do_IRQ ! 69 - .long do_IRQ ! 70 - .long do_IRQ ! 71 - .long do_IRQ ! 72 - .long do_IRQ ! 73 - .long do_IRQ ! 74 - .long do_IRQ ! 75 - .long do_IRQ ! 76 - .long do_IRQ ! 77 - .long do_IRQ ! 78 - .long do_IRQ ! 79 - .long do_IRQ ! 80 SCIF0(SH7300) - .long do_IRQ ! 81 - .long do_IRQ ! 82 - .long do_IRQ ! 83 - .long do_IRQ ! 84 - .long do_IRQ ! 85 - .long do_IRQ ! 86 - .long do_IRQ ! 87 - .long do_IRQ ! 88 - .long do_IRQ ! 89 - .long do_IRQ ! 90 - .long do_IRQ ! 91 - .long do_IRQ ! 92 - .long do_IRQ ! 93 - .long do_IRQ ! 94 - .long do_IRQ ! 95 - .long do_IRQ ! 96 - .long do_IRQ ! 97 - .long do_IRQ ! 98 - .long do_IRQ ! 99 - .long do_IRQ ! 100 - .long do_IRQ ! 101 - .long do_IRQ ! 102 - .long do_IRQ ! 103 - .long do_IRQ ! 104 - .long do_IRQ ! 105 - .long do_IRQ ! 106 - .long do_IRQ ! 107 - .long do_IRQ ! 108 -#endif -#endif diff --git a/arch/sh/kernel/cpu/sh4/ex.S b/arch/sh/kernel/cpu/sh4/ex.S index 7146893a6c..3f4cd043e9 100644 --- a/arch/sh/kernel/cpu/sh4/ex.S +++ b/arch/sh/kernel/cpu/sh4/ex.S @@ -53,503 +53,3 @@ ENTRY(nmi_slot) #endif ENTRY(user_break_point_trap) .long break_point_trap /* 1E0 */ -ENTRY(interrupt_table) - ! external hardware - .long do_IRQ ! 0000 /* 200 */ - .long do_IRQ ! 0001 - .long do_IRQ ! 0010 - .long do_IRQ ! 0011 - .long do_IRQ ! 0100 - .long do_IRQ ! 0101 - .long do_IRQ ! 0110 - .long do_IRQ ! 0111 - .long do_IRQ ! 1000 /* 300 */ - .long do_IRQ ! 1001 - .long do_IRQ ! 1010 - .long do_IRQ ! 1011 - .long do_IRQ ! 1100 - .long do_IRQ ! 1101 - .long do_IRQ ! 1110 - .long exception_error - ! Internal hardware -#ifndef CONFIG_CPU_SUBTYPE_SH7780 - .long do_IRQ ! TMU0 tuni0 /* 400 */ - .long do_IRQ ! TMU1 tuni1 - .long do_IRQ ! TMU2 tuni2 - .long do_IRQ ! ticpi2 -#if defined(CONFIG_CPU_SUBTYPE_SH7760) - .long exception_error - .long exception_error - .long exception_error - .long exception_error - .long exception_error /* 500 */ - .long exception_error - .long exception_error -#else - .long do_IRQ ! RTC ati - .long do_IRQ ! pri - .long do_IRQ ! cui - .long do_IRQ ! SCI eri - .long do_IRQ ! rxi /* 500 */ - .long do_IRQ ! txi - .long do_IRQ ! tei -#endif - .long do_IRQ ! WDT iti /* 560 */ - .long do_IRQ ! REF rcmi - .long do_IRQ ! rovi - .long do_IRQ - .long do_IRQ /* 5E0 */ - .long do_IRQ ! 32 Hitachi UDI /* 600 */ - .long do_IRQ ! 33 GPIO - .long do_IRQ ! 34 DMAC dmte0 - .long do_IRQ ! 35 dmte1 - .long do_IRQ ! 36 dmte2 - .long do_IRQ ! 37 dmte3 - .long do_IRQ ! 38 dmae - .long exception_error ! 39 /* 6E0 */ -#if defined(CONFIG_CPU_SUBTYPE_SH7760) - .long exception_error /* 700 */ - .long exception_error - .long exception_error - .long exception_error /* 760 */ -#else - .long do_IRQ ! 40 SCIF eri /* 700 */ - .long do_IRQ ! 41 rxi - .long do_IRQ ! 42 bri - .long do_IRQ ! 43 txi -#endif -#if CONFIG_NR_ONCHIP_DMA_CHANNELS == 8 - .long do_IRQ ! 44 DMAC dmte4 /* 780 */ - .long do_IRQ ! 45 dmte5 - .long do_IRQ ! 46 dmte6 - .long do_IRQ ! 47 dmte7 /* 7E0 */ -#elif defined(CONFIG_CPU_SUBTYPE_SH7343) - .long do_IRQ ! 44 IIC1 ali /* 780 */ - .long do_IRQ ! 45 tacki - .long do_IRQ ! 46 waiti - .long do_IRQ ! 47 dtei /* 7E0 */ - .long do_IRQ ! 48 DMAC dei0 /* 800 */ - .long do_IRQ ! 49 dei1 /* 820 */ -#else - .long exception_error ! 44 /* 780 */ - .long exception_error ! 45 - .long exception_error ! 46 - .long exception_error ! 47 -#endif -#if defined(CONFIG_SH_FPU) - .long do_fpu_state_restore ! 48 /* 800 */ - .long do_fpu_state_restore ! 49 /* 820 */ -#elif !defined(CONFIG_CPU_SUBTYPE_SH7343) && \ - !defined(CONFIG_CPU_SUBTYPE_SH73180) - .long exception_error - .long exception_error -#endif -#if defined(CONFIG_CPU_SUBTYPE_SH7751) - .long exception_error /* 840 */ - .long exception_error - .long exception_error - .long exception_error - .long exception_error - .long exception_error - .long exception_error /* 900 */ - .long exception_error - .long exception_error - .long exception_error - .long exception_error - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! PCI serr /* A00 */ - .long do_IRQ ! dma3 - .long do_IRQ ! dma2 - .long do_IRQ ! dma1 - .long do_IRQ ! dma0 - .long do_IRQ ! pwon - .long do_IRQ ! pwdwn - .long do_IRQ ! err - .long do_IRQ ! TMU3 tuni3 /* B00 */ - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! TMU4 tuni4 /* B80 */ -#elif defined(CONFIG_CPU_SUBTYPE_SH7760) - .long do_IRQ ! IRQ irq6 /* 840 */ - .long do_IRQ ! irq7 - .long do_IRQ ! SCIF eri0 - .long do_IRQ ! rxi0 - .long do_IRQ ! bri0 - .long do_IRQ ! txi0 - .long do_IRQ ! HCAN2 cani0 /* 900 */ - .long do_IRQ ! cani1 - .long do_IRQ ! SSI ssii0 - .long do_IRQ ! ssii1 - .long do_IRQ ! HAC haci0 - .long do_IRQ ! haci1 - .long do_IRQ ! IIC iici0 - .long do_IRQ ! iici1 - .long do_IRQ ! USB usbi /* A00 */ - .long do_IRQ ! LCDC vint - .long exception_error - .long exception_error - .long do_IRQ ! DMABRG dmabrgi0 - .long do_IRQ ! dmabrgi1 - .long do_IRQ ! dmabrgi2 - .long exception_error - .long do_IRQ ! SCIF eri1 /* B00 */ - .long do_IRQ ! rxi1 - .long do_IRQ ! bri1 - .long do_IRQ ! txi1 - .long do_IRQ ! eri2 - .long do_IRQ ! rxi2 - .long do_IRQ ! bri2 - .long do_IRQ ! txi2 - .long do_IRQ ! SIM simeri /* C00 */ - .long do_IRQ ! simrxi - .long do_IRQ ! simtxi - .long do_IRQ ! simtei - .long do_IRQ ! HSPI spii - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! MMCIF mmci0 /* D00 */ - .long do_IRQ ! mmci1 - .long do_IRQ ! mmci2 - .long do_IRQ ! mmci3 - .long exception_error - .long exception_error - .long exception_error - .long exception_error - .long exception_error /* E00 */ - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! MFI mfii - .long exception_error - .long exception_error - .long exception_error - .long exception_error /* F00 */ - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! ADC adi - .long do_IRQ ! CMT cmti /* FA0 */ -#elif defined(CONFIG_CPU_SUBTYPE_SH73180) || defined(CONFIG_CPU_SUBTYPE_SH7343) - .long do_IRQ ! 50 0x840 - .long do_IRQ ! 51 0x860 - .long do_IRQ ! 52 0x880 - .long do_IRQ ! 53 0x8a0 - .long do_IRQ ! 54 0x8c0 - .long do_IRQ ! 55 0x8e0 - .long do_IRQ ! 56 0x900 - .long do_IRQ ! 57 0x920 - .long do_IRQ ! 58 0x940 - .long do_IRQ ! 59 0x960 - .long do_IRQ ! 60 0x980 - .long do_IRQ ! 61 0x9a0 - .long do_IRQ ! 62 0x9c0 - .long do_IRQ ! 63 0x9e0 - .long do_IRQ ! 64 0xa00 - .long do_IRQ ! 65 0xa20 - .long do_IRQ ! 66 0xa40 - .long do_IRQ ! 67 0xa60 - .long do_IRQ ! 68 0xa80 - .long do_IRQ ! 69 0xaa0 - .long do_IRQ ! 70 0xac0 - .long do_IRQ ! 71 0xae0 - .long do_IRQ ! 72 0xb00 - .long do_IRQ ! 73 0xb20 - .long do_IRQ ! 74 0xb40 - .long do_IRQ ! 75 0xb60 - .long do_IRQ ! 76 0xb80 - .long do_IRQ ! 77 0xba0 - .long do_IRQ ! 78 0xbc0 - .long do_IRQ ! 79 0xbe0 - .long do_IRQ ! 80 0xc00 - .long do_IRQ ! 81 0xc20 - .long do_IRQ ! 82 0xc40 - .long do_IRQ ! 83 0xc60 - .long do_IRQ ! 84 0xc80 - .long do_IRQ ! 85 0xca0 - .long do_IRQ ! 86 0xcc0 - .long do_IRQ ! 87 0xce0 - .long do_IRQ ! 88 0xd00 - .long do_IRQ ! 89 0xd20 - .long do_IRQ ! 90 0xd40 - .long do_IRQ ! 91 0xd60 - .long do_IRQ ! 92 0xd80 - .long do_IRQ ! 93 0xda0 - .long do_IRQ ! 94 0xdc0 - .long do_IRQ ! 95 0xde0 - .long do_IRQ ! 96 0xe00 - .long do_IRQ ! 97 0xe20 - .long do_IRQ ! 98 0xe40 - .long do_IRQ ! 99 0xe60 - .long do_IRQ ! 100 0xe80 - .long do_IRQ ! 101 0xea0 - .long do_IRQ ! 102 0xec0 - .long do_IRQ ! 103 0xee0 - .long do_IRQ ! 104 0xf00 - .long do_IRQ ! 105 0xf20 - .long do_IRQ ! 106 0xf40 - .long do_IRQ ! 107 0xf60 - .long do_IRQ ! 108 0xf80 -#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1) - .long exception_error ! 50 0x840 - .long exception_error ! 51 0x860 - .long exception_error ! 52 0x880 - .long exception_error ! 53 0x8a0 - .long exception_error ! 54 0x8c0 - .long exception_error ! 55 0x8e0 - .long exception_error ! 56 0x900 - .long exception_error ! 57 0x920 - .long exception_error ! 58 0x940 - .long exception_error ! 59 0x960 - .long exception_error ! 60 0x980 - .long exception_error ! 61 0x9a0 - .long exception_error ! 62 0x9c0 - .long exception_error ! 63 0x9e0 - .long do_IRQ ! 64 0xa00 PCI serr - .long do_IRQ ! 65 0xa20 err - .long do_IRQ ! 66 0xa40 ad - .long do_IRQ ! 67 0xa60 pwr_dwn - .long exception_error ! 68 0xa80 - .long exception_error ! 69 0xaa0 - .long exception_error ! 70 0xac0 - .long exception_error ! 71 0xae0 - .long do_IRQ ! 72 0xb00 DMA INT0 - .long do_IRQ ! 73 0xb20 INT1 - .long do_IRQ ! 74 0xb40 INT2 - .long do_IRQ ! 75 0xb60 INT3 - .long do_IRQ ! 76 0xb80 INT4 - .long exception_error ! 77 0xba0 - .long do_IRQ ! 78 0xbc0 DMA ERR - .long exception_error ! 79 0xbe0 - .long do_IRQ ! 80 0xc00 PIO0 - .long do_IRQ ! 81 0xc20 PIO1 - .long do_IRQ ! 82 0xc40 PIO2 - .long exception_error ! 83 0xc60 - .long exception_error ! 84 0xc80 - .long exception_error ! 85 0xca0 - .long exception_error ! 86 0xcc0 - .long exception_error ! 87 0xce0 - .long exception_error ! 88 0xd00 - .long exception_error ! 89 0xd20 - .long exception_error ! 90 0xd40 - .long exception_error ! 91 0xd60 - .long exception_error ! 92 0xd80 - .long exception_error ! 93 0xda0 - .long exception_error ! 94 0xdc0 - .long exception_error ! 95 0xde0 - .long exception_error ! 96 0xe00 - .long exception_error ! 97 0xe20 - .long exception_error ! 98 0xe40 - .long exception_error ! 99 0xe60 - .long exception_error ! 100 0xe80 - .long exception_error ! 101 0xea0 - .long exception_error ! 102 0xec0 - .long exception_error ! 103 0xee0 - .long exception_error ! 104 0xf00 - .long exception_error ! 105 0xf20 - .long exception_error ! 106 0xf40 - .long exception_error ! 107 0xf60 - .long exception_error ! 108 0xf80 - .long exception_error ! 109 0xfa0 - .long exception_error ! 110 0xfc0 - .long exception_error ! 111 0xfe0 - .long do_IRQ ! 112 0x1000 Mailbox - .long exception_error ! 113 0x1020 - .long exception_error ! 114 0x1040 - .long exception_error ! 115 0x1060 - .long exception_error ! 116 0x1080 - .long exception_error ! 117 0x10a0 - .long exception_error ! 118 0x10c0 - .long exception_error ! 119 0x10e0 - .long exception_error ! 120 0x1100 - .long exception_error ! 121 0x1120 - .long exception_error ! 122 0x1140 - .long exception_error ! 123 0x1160 - .long exception_error ! 124 0x1180 - .long exception_error ! 125 0x11a0 - .long exception_error ! 126 0x11c0 - .long exception_error ! 127 0x11e0 - .long exception_error ! 128 0x1200 - .long exception_error ! 129 0x1220 - .long exception_error ! 130 0x1240 - .long exception_error ! 131 0x1260 - .long exception_error ! 132 0x1280 - .long exception_error ! 133 0x12a0 - .long exception_error ! 134 0x12c0 - .long exception_error ! 135 0x12e0 - .long exception_error ! 136 0x1300 - .long exception_error ! 137 0x1320 - .long exception_error ! 138 0x1340 - .long exception_error ! 139 0x1360 - .long do_IRQ ! 140 0x1380 EMPI INV_ADDR - .long exception_error ! 141 0x13a0 - .long exception_error ! 142 0x13c0 - .long exception_error ! 143 0x13e0 -#elif defined(CONFIG_CPU_SUBTYPE_SH7770) - .long do_IRQ ! 50 0x840 - .long do_IRQ ! 51 0x860 - .long do_IRQ ! 52 0x880 - .long do_IRQ ! 53 0x8a0 - .long do_IRQ ! 54 0x8c0 - .long do_IRQ ! 55 0x8e0 - .long do_IRQ ! 56 0x900 - .long do_IRQ ! 57 0x920 - .long do_IRQ ! 58 0x940 - .long do_IRQ ! 59 0x960 - .long do_IRQ ! 60 0x980 - .long do_IRQ ! 61 0x9a0 - .long do_IRQ ! 62 0x9c0 - .long do_IRQ ! 63 0x9e0 - .long do_IRQ ! 64 0xa00 - .long do_IRQ ! 65 0xa20 - .long do_IRQ ! 66 0xa4d - .long do_IRQ ! 67 0xa60 - .long do_IRQ ! 68 0xa80 - .long do_IRQ ! 69 0xaa0 - .long do_IRQ ! 70 0xac0 - .long do_IRQ ! 71 0xae0 - .long do_IRQ ! 72 0xb00 - .long do_IRQ ! 73 0xb20 - .long do_IRQ ! 74 0xb40 - .long do_IRQ ! 75 0xb60 - .long do_IRQ ! 76 0xb80 - .long do_IRQ ! 77 0xba0 - .long do_IRQ ! 78 0xbc0 - .long do_IRQ ! 79 0xbe0 - .long do_IRQ ! 80 0xc00 - .long do_IRQ ! 81 0xc20 - .long do_IRQ ! 82 0xc40 - .long do_IRQ ! 83 0xc60 - .long do_IRQ ! 84 0xc80 - .long do_IRQ ! 85 0xca0 - .long do_IRQ ! 86 0xcc0 - .long do_IRQ ! 87 0xce0 - .long do_IRQ ! 88 0xd00 - .long do_IRQ ! 89 0xd20 - .long do_IRQ ! 90 0xd40 - .long do_IRQ ! 91 0xd60 - .long do_IRQ ! 92 0xd80 - .long do_IRQ ! 93 0xda0 - .long do_IRQ ! 94 0xdc0 - .long do_IRQ ! 95 0xde0 - .long do_IRQ ! 96 0xe00 - .long do_IRQ ! 97 0xe20 - .long do_IRQ ! 98 0xe40 - .long do_IRQ ! 99 0xe60 - .long do_IRQ ! 100 0xe80 - .long do_IRQ ! 101 0xea0 - .long do_IRQ ! 102 0xec0 - .long do_IRQ ! 103 0xee0 - .long do_IRQ ! 104 0xf00 - .long do_IRQ ! 105 0xf20 - .long do_IRQ ! 106 0xf40 - .long do_IRQ ! 107 0xf60 - .long do_IRQ ! 108 0xf80 -#endif -#else - .long exception_error /* 400 */ - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! RTC ati - .long do_IRQ ! pri - .long do_IRQ ! cui - .long exception_error - .long exception_error /* 500 */ - .long exception_error - .long exception_error - .long do_IRQ ! WDT iti /* 560 */ - .long do_IRQ ! TMU-ch0 - .long do_IRQ ! TMU-ch1 - .long do_IRQ ! TMU-ch2 - .long do_IRQ ! ticpi2 /* 5E0 */ - .long do_IRQ ! 32 Hitachi UDI /* 600 */ - .long exception_error - .long do_IRQ ! 34 DMAC dmte0 - .long do_IRQ ! 35 dmte1 - .long do_IRQ ! 36 dmte2 - .long do_IRQ ! 37 dmte3 - .long do_IRQ ! 38 dmae - .long exception_error ! 39 /* 6E0 */ - .long do_IRQ ! 40 SCIF-ch0 eri /* 700 */ - .long do_IRQ ! 41 rxi - .long do_IRQ ! 42 bri - .long do_IRQ ! 43 txi - .long do_IRQ ! 44 DMAC dmte4 /* 780 */ - .long do_IRQ ! 45 dmte5 - .long do_IRQ ! 46 dmte6 - .long do_IRQ ! 47 dmte7 /* 7E0 */ -#if defined(CONFIG_SH_FPU) - .long do_fpu_state_restore ! 48 /* 800 */ - .long do_fpu_state_restore ! 49 /* 820 */ -#else - .long exception_error - .long exception_error -#endif - .long exception_error /* 840 */ - .long exception_error - .long exception_error - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! 56 CMT /* 900 */ - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! 60 HAC - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! PCI serr /* A00 */ - .long do_IRQ ! INTA - .long do_IRQ ! INTB - .long do_IRQ ! INTC - .long do_IRQ ! INTD - .long do_IRQ ! err - .long do_IRQ ! pwd3 - .long do_IRQ ! pwd2 - .long do_IRQ ! pwd1 /* B00 */ - .long do_IRQ ! pwd0 - .long exception_error - .long exception_error - .long do_IRQ ! SCIF-ch1 eri /* B80 */ - .long do_IRQ ! rxi - .long do_IRQ ! bri - .long do_IRQ ! txi - .long do_IRQ ! SIOF /* C00 */ - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! HSPI /* C80 */ - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! MMCIF fatat /* D00 */ - .long do_IRQ ! tran - .long do_IRQ ! err - .long do_IRQ ! frdy - .long do_IRQ ! DMAC dmint8 /* D80 */ - .long do_IRQ ! dmint9 - .long do_IRQ ! dmint10 - .long do_IRQ ! dmint11 - .long do_IRQ ! TMU-ch3 /* E00 */ - .long do_IRQ ! TMU-ch4 - .long do_IRQ ! TMU-ch5 - .long exception_error - .long do_IRQ ! SSI - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! FLCTL flste /* F00 */ - .long do_IRQ ! fltend - .long do_IRQ ! fltrq0 - .long do_IRQ ! fltrq1 - .long do_IRQ ! GPIO gpioi0 /* F80 */ - .long do_IRQ ! gpioi1 - .long do_IRQ ! gpioi2 - .long do_IRQ ! gpioi3 -#endif - diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S index 97c571fbcd..39aaefb2d8 100644 --- a/arch/sh/kernel/entry.S +++ b/arch/sh/kernel/entry.S @@ -1,9 +1,8 @@ -/* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $ - * +/* * linux/arch/sh/entry.S * * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2003 - 2006 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -78,7 +77,6 @@ OFF_TRA = (16*4+6*4) #define k3 r3 #define k4 r4 -#define k_ex_code r2_bank /* r2_bank1 */ #define g_imask r6 /* r6_bank1 */ #define k_g_imask r6_bank /* r6_bank1 */ #define current r7 /* r7_bank1 */ @@ -691,7 +689,7 @@ interrupt: 0: #endif /* defined(CONFIG_KGDB_NMI) */ bra handle_exception - mov.l @k2, k2 + mov #-1, k2 ! interrupt exception marker .align 2 1: .long EXPEVT @@ -717,8 +715,7 @@ ENTRY(handle_exception) add current, k1 mov k1, r15 ! change to kernel stack ! -1: mov #-1, k4 - mov.l 2f, k1 +1: mov.l 2f, k1 ! #ifdef CONFIG_SH_DSP mov.l r2, @-r15 ! Save r2, we need another reg @@ -763,6 +760,8 @@ skip_save: #endif ! Save the user registers on the stack. mov.l k2, @-r15 ! EXPEVT + + mov #-1, k4 mov.l k4, @-r15 ! set TRA (default: -1) ! sts.l macl, @-r15 @@ -797,8 +796,21 @@ skip_save: mov.l r2, @-r15 mov.l r1, @-r15 mov.l r0, @-r15 - ! Then, dispatch to the handler, according to the exception code. - stc k_ex_code, r8 + + /* + * This gets a bit tricky.. in the INTEVT case we don't want to use + * the VBR offset as a destination in the jump call table, since all + * of the destinations are the same. In this case, (interrupt) sets + * a marker in r2 (now r2_bank since SR.RB changed), which we check + * to determine the exception type. For all other exceptions, we + * forcibly read EXPEVT from memory and fix up the jump address, in + * the interrupt exception case we jump to do_IRQ() and defer the + * INTEVT read until there. As a bonus, we can also clean up the SR.RB + * checks that do_IRQ() was doing.. + */ + stc r2_bank, r8 + cmp/pz r8 + bf interrupt_exception shlr2 r8 shlr r8 mov.l 4f, r9 @@ -806,6 +818,8 @@ skip_save: mov.l @r9, r9 jmp @r9 nop + rts + nop .align 2 1: .long 0x00001000 ! DSP=1 @@ -813,8 +827,17 @@ skip_save: 3: .long 0xcfffffff ! RB=0, BL=0 4: .long exception_handling_table +interrupt_exception: + mov.l 1f, r9 + jmp @r9 + nop + rts + nop + + .align 2 +1: .long do_IRQ + .align 2 ENTRY(exception_none) rts nop - diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 3b93682bf1..acf2602569 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,7 @@ atomic_t irq_err_count; */ void ack_bad_irq(unsigned int irq) { + atomic_inc(&irq_err_count); printk("unexpected IRQ trap at vector %02x\n", irq); } @@ -85,7 +87,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, struct pt_regs regs) { struct pt_regs *old_regs = set_irq_regs(®s); - int irq = r4; + int irq; #ifdef CONFIG_4KSTACKS union irq_ctx *curctx, *irqctx; #endif @@ -109,20 +111,9 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, #endif #ifdef CONFIG_CPU_HAS_INTEVT - __asm__ __volatile__ ( -#ifdef CONFIG_CPU_HAS_SR_RB - "stc r2_bank, %0\n\t" + irq = (ctrl_inl(INTEVT) >> 5) - 16; #else - "mov.l @%1, %0\n\t" -#endif - "shlr2 %0\n\t" - "shlr2 %0\n\t" - "shlr %0\n\t" - "add #-16, %0\n\t" - : "=z" (irq), "=r" (r4) - : "1" (INTEVT) - : "memory" - ); + irq = r4; #endif irq = irq_demux(irq); @@ -147,9 +138,9 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, __asm__ __volatile__ ( "mov %0, r4 \n" "mov r15, r9 \n" - "jsr @%2 \n" + "jsr @%1 \n" /* swith to the irq stack */ - " mov %3, r15 \n" + " mov %2, r15 \n" /* restore the stack (ring zero) */ "mov r9, r15 \n" : /* no outputs */ -- 2.39.5