From d35d473c25d43d7db3e5e18b66d558d2a631cca8 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 3 Apr 2006 13:17:41 +0100 Subject: [PATCH] [MIPS] Fix the crime against humanity that mipsIRQ.S is. Signed-off-by: Ralf Baechle --- arch/mips/mips-boards/atlas/Makefile | 2 +- .../{generic/mipsIRQ.S => atlas/atlas-irq.S} | 47 +------ arch/mips/mips-boards/generic/Makefile | 4 +- arch/mips/mips-boards/malta/Makefile | 2 +- arch/mips/mips-boards/malta/malta-irq.S | 122 ++++++++++++++++++ arch/mips/mips-boards/sead/Makefile | 2 +- arch/mips/mips-boards/sead/sead-irq.S | 111 ++++++++++++++++ include/asm-mips/mips-boards/atlas.h | 18 ++- include/asm-mips/mips-boards/atlasint.h | 19 --- 9 files changed, 260 insertions(+), 67 deletions(-) rename arch/mips/mips-boards/{generic/mipsIRQ.S => atlas/atlas-irq.S} (70%) create mode 100644 arch/mips/mips-boards/malta/malta-irq.S create mode 100644 arch/mips/mips-boards/sead/sead-irq.S diff --git a/arch/mips/mips-boards/atlas/Makefile b/arch/mips/mips-boards/atlas/Makefile index d8dab75906bf..50fec2a5aee6 100644 --- a/arch/mips/mips-boards/atlas/Makefile +++ b/arch/mips/mips-boards/atlas/Makefile @@ -16,5 +16,5 @@ # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. # -obj-y := atlas_int.o atlas_setup.o +obj-y := atlas_int.o atlas-irq.o atlas_setup.o obj-$(CONFIG_KGDB) += atlas_gdb.o diff --git a/arch/mips/mips-boards/generic/mipsIRQ.S b/arch/mips/mips-boards/atlas/atlas-irq.S similarity index 70% rename from arch/mips/mips-boards/generic/mipsIRQ.S rename to arch/mips/mips-boards/atlas/atlas-irq.S index 973e10aaacd5..31bc99a52383 100644 --- a/arch/mips/mips-boards/generic/mipsIRQ.S +++ b/arch/mips/mips-boards/atlas/atlas-irq.S @@ -2,8 +2,6 @@ * Carsten Langgaard, carstenl@mips.com * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. * - * ######################################################################## - * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -17,10 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - * ######################################################################## - * * Interrupt exception dispatch code. - * */ #include @@ -28,33 +23,9 @@ #include #include #include - -#ifdef CONFIG_MIPS_ATLAS #include -#define CASCADE_IRQ MIPSCPU_INT_ATLAS -#define CASCADE_DISPATCH atlas_hw0_irqdispatch -#endif -#ifdef CONFIG_MIPS_MALTA -#include -#define CASCADE_IRQ MIPSCPU_INT_I8259A -#define CASCADE_DISPATCH malta_hw0_irqdispatch -#endif -#ifdef CONFIG_MIPS_SEAD -#include -#endif -/* A lot of complication here is taken away because: - * - * 1) We handle one interrupt and return, sitting in a loop and moving across - * all the pending IRQ bits in the cause register is _NOT_ the answer, the - * common case is one pending IRQ so optimize in that direction. - * - * 2) We need not check against bits in the status register IRQ mask, that - * would make this routine slow as hell. - * - * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in - * between like BSD spl() brain-damage. - * +/* * Furthermore, the IRQs on the MIPS board look basically (barring software * IRQs which we don't use at all and all external interrupt sources are * combined together on hardware interrupt 0 (MIPS IRQ 2)) like: @@ -127,31 +98,23 @@ # sll s0, t0 #endif -#ifdef CASCADE_IRQ - li a1, CASCADE_IRQ + li a1, MIPSCPU_INT_ATLAS bne a0, a1, 1f addu a0, MIPSCPU_INT_BASE - jal CASCADE_DISPATCH + jal atlas_hw0_irqdispatch move a0, sp j ret_from_irq nop -1: -#else - addu a0, MIPSCPU_INT_BASE -#endif - jal do_IRQ +1: jal do_IRQ move a1, sp j ret_from_irq nop - spurious: - jal spurious_interrupt - nop - j ret_from_irq + j spurious_interrupt nop END(mipsIRQ) diff --git a/arch/mips/mips-boards/generic/Makefile b/arch/mips/mips-boards/generic/Makefile index b21bc6887fa8..be47c1c2bc80 100644 --- a/arch/mips/mips-boards/generic/Makefile +++ b/arch/mips/mips-boards/generic/Makefile @@ -18,8 +18,8 @@ # Makefile for the MIPS boards generic routines under Linux. # -obj-y := mipsIRQ.o reset.o display.o init.o memory.o \ - printf.o cmdline.o time.o +obj-y := reset.o display.o init.o memory.o printf.o \ + cmdline.o time.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_KGDB) += gdb_hook.o diff --git a/arch/mips/mips-boards/malta/Makefile b/arch/mips/mips-boards/malta/Makefile index fd4c143c0e2f..3ae8fe6c0070 100644 --- a/arch/mips/mips-boards/malta/Makefile +++ b/arch/mips/mips-boards/malta/Makefile @@ -19,4 +19,4 @@ # under Linux. # -obj-y := malta_int.o malta_setup.o +obj-y := malta_int.o malta-irq.o malta_setup.o diff --git a/arch/mips/mips-boards/malta/malta-irq.S b/arch/mips/mips-boards/malta/malta-irq.S new file mode 100644 index 000000000000..6217aff3be03 --- /dev/null +++ b/arch/mips/mips-boards/malta/malta-irq.S @@ -0,0 +1,122 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Interrupt exception dispatch code. + * + */ +#include + +#include +#include +#include +#include +#include + +/* + * IRQs on the Malta board look basically (barring software IRQs which we + * don't use at all and all external interrupt sources are combined together + * on hardware interrupt 0 (MIPS IRQ 2)) like: + * + * MIPS IRQ Source + * -------- ------ + * 0 Software (ignored) + * 1 Software (ignored) + * 2 Combined hardware interrupt (hw0) + * 3 Hardware (ignored) + * 4 Hardware (ignored) + * 5 Hardware (ignored) + * 6 Hardware (ignored) + * 7 R4k timer (what we use) + * + * We handle the IRQ according to _our_ priority which is: + * + * Highest ---- R4k Timer + * Lowest ---- Combined hardware interrupt + * + * then we just return, if multiple IRQs are pending then we will just take + * another exception, big deal. + */ + + .text + .set noreorder + .set noat + .align 5 + NESTED(mipsIRQ, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + + mfc0 s0, CP0_CAUSE # get irq bits + mfc0 s1, CP0_STATUS # get irq mask + andi s0, ST0_IM # CAUSE.CE may be non-zero! + and s0, s1 + +#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) + .set mips32 + clz a0, s0 + .set mips0 + negu a0 + addu a0, 31-CAUSEB_IP + bltz a0, spurious +#else + beqz s0, spurious + li a0, 7 + + and t0, s0, 0xf000 + sltiu t0, t0, 1 + sll t0, 2 + subu a0, t0 + sll s0, t0 + + and t0, s0, 0xc000 + sltiu t0, t0, 1 + sll t0, 1 + subu a0, t0 + sll s0, t0 + + and t0, s0, 0x8000 + sltiu t0, t0, 1 + # sll t0, 0 + subu a0, t0 + # sll s0, t0 +#endif + + li a1, MIPSCPU_INT_I8259A + bne a0, a1, 1f + addu a0, MIPSCPU_INT_BASE + + jal malta_hw0_irqdispatch + move a0, sp + + j ret_from_irq + nop +1: + + jal do_IRQ + move a1, sp + + j ret_from_irq + nop + +spurious: + j spurious_interrupt + nop + END(mipsIRQ) diff --git a/arch/mips/mips-boards/sead/Makefile b/arch/mips/mips-boards/sead/Makefile index 224bb848f16b..01780b605346 100644 --- a/arch/mips/mips-boards/sead/Makefile +++ b/arch/mips/mips-boards/sead/Makefile @@ -23,4 +23,4 @@ # under Linux. # -obj-y := sead_int.o sead_setup.o +obj-y := sead_int.o sead-irq.o sead_setup.o diff --git a/arch/mips/mips-boards/sead/sead-irq.S b/arch/mips/mips-boards/sead/sead-irq.S new file mode 100644 index 000000000000..d5dea1d2e220 --- /dev/null +++ b/arch/mips/mips-boards/sead/sead-irq.S @@ -0,0 +1,111 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Interrupt exception dispatch code. + * + */ +#include + +#include +#include +#include +#include +#include + +/* + * IRQs on the SEAD board look basically are combined together on hardware + * interrupt 0 (MIPS IRQ 2)) like: + * + * MIPS IRQ Source + * -------- ------ + * 0 Software (ignored) + * 1 Software (ignored) + * 2 UART0 (hw0) + * 3 UART1 (hw1) + * 4 Hardware (ignored) + * 5 Hardware (ignored) + * 6 Hardware (ignored) + * 7 R4k timer (what we use) + * + * We handle the IRQ according to _our_ priority which is: + * + * Highest ---- R4k Timer + * Lowest ---- Combined hardware interrupt + * + * then we just return, if multiple IRQs are pending then we will just take + * another exception, big deal. + */ + + .text + .set noreorder + .set noat + .align 5 + NESTED(mipsIRQ, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + + mfc0 s0, CP0_CAUSE # get irq bits + mfc0 s1, CP0_STATUS # get irq mask + andi s0, ST0_IM # CAUSE.CE may be non-zero! + and s0, s1 + +#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) + .set mips32 + clz a0, s0 + .set mips0 + negu a0 + addu a0, 31-CAUSEB_IP + bltz a0, spurious +#else + beqz s0, spurious + li a0, 7 + + and t0, s0, 0xf000 + sltiu t0, t0, 1 + sll t0, 2 + subu a0, t0 + sll s0, t0 + + and t0, s0, 0xc000 + sltiu t0, t0, 1 + sll t0, 1 + subu a0, t0 + sll s0, t0 + + and t0, s0, 0x8000 + sltiu t0, t0, 1 + # sll t0, 0 + subu a0, t0 + # sll s0, t0 +#endif + + addu a0, MIPSCPU_INT_BASE + jal do_IRQ + move a1, sp + + j ret_from_irq + nop + +spurious: + j spurious_interrupt + nop + END(mipsIRQ) diff --git a/include/asm-mips/mips-boards/atlas.h b/include/asm-mips/mips-boards/atlas.h index 0998151fb3a1..a8ae12d120ee 100644 --- a/include/asm-mips/mips-boards/atlas.h +++ b/include/asm-mips/mips-boards/atlas.h @@ -33,12 +33,28 @@ #define ATLAS_RTC_ADR_REG 0x1f000800 #define ATLAS_RTC_DAT_REG 0x1f000808 - /* * Atlas interrupt controller register base. */ #define ATLAS_ICTRL_REGS_BASE 0x1f000000 +/* + * Atlas registers are memory mapped on 64-bit aligned boundaries and + * only word access are allowed. + */ +struct atlas_ictrl_regs { + volatile unsigned int intraw; + int dummy1; + volatile unsigned int intseten; + int dummy2; + volatile unsigned int intrsten; + int dummy3; + volatile unsigned int intenable; + int dummy4; + volatile unsigned int intstatus; + int dummy5; +}; + /* * Atlas UART register base. */ diff --git a/include/asm-mips/mips-boards/atlasint.h b/include/asm-mips/mips-boards/atlasint.h index bba35c183d08..fd7ebc54fa90 100644 --- a/include/asm-mips/mips-boards/atlasint.h +++ b/include/asm-mips/mips-boards/atlasint.h @@ -62,23 +62,4 @@ #define ATLASINT_RES31 (ATLASINT_BASE+31) #define ATLASINT_END (ATLASINT_BASE+31) -/* - * Atlas registers are memory mapped on 64-bit aligned boundaries and - * only word access are allowed. - */ -struct atlas_ictrl_regs { - volatile unsigned int intraw; - int dummy1; - volatile unsigned int intseten; - int dummy2; - volatile unsigned int intrsten; - int dummy3; - volatile unsigned int intenable; - int dummy4; - volatile unsigned int intstatus; - int dummy5; -}; - -extern void atlasint_init(void); - #endif /* !(_MIPS_ATLASINT_H) */ -- 2.34.1