diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2006-04-21 12:52:36 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-04-21 12:52:36 -0400 |
commit | a748422ee45725e04e1d3792fa19dfa90ddfd116 (patch) | |
tree | 978e12895468baaa9f7ab2747b9f7d50beaf1717 /arch/mips/mips-boards/sim/sim_int.c | |
parent | c63e31c2cc1ec67372920b5e1aff8204d04dd172 (diff) | |
parent | f4ffaa452e71495a06376f12f772342bc57051fc (diff) | |
download | blackbird-op-linux-a748422ee45725e04e1d3792fa19dfa90ddfd116.tar.gz blackbird-op-linux-a748422ee45725e04e1d3792fa19dfa90ddfd116.zip |
Merge branch 'master'
Diffstat (limited to 'arch/mips/mips-boards/sim/sim_int.c')
-rw-r--r-- | arch/mips/mips-boards/sim/sim_int.c | 64 |
1 files changed, 59 insertions, 5 deletions
diff --git a/arch/mips/mips-boards/sim/sim_int.c b/arch/mips/mips-boards/sim/sim_int.c index a4d0a2c05031..2c15c8efec4e 100644 --- a/arch/mips/mips-boards/sim/sim_int.c +++ b/arch/mips/mips-boards/sim/sim_int.c @@ -25,17 +25,71 @@ extern void mips_cpu_irq_init(int); -extern asmlinkage void simIRQ(void); +static inline int clz(unsigned long x) +{ + __asm__ ( + " .set push \n" + " .set mips32 \n" + " clz %0, %1 \n" + " .set pop \n" + : "=r" (x) + : "r" (x)); + + return x; +} + +/* + * Version of ffs that only looks at bits 12..15. + */ +static inline unsigned int irq_ffs(unsigned int pending) +{ +#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) + return -clz(pending) + 31 - CAUSEB_IP; +#else + unsigned int a0 = 7; + unsigned int t0; + + t0 = s0 & 0xf000; + t0 = t0 < 1; + t0 = t0 << 2; + a0 = a0 - t0; + s0 = s0 << t0; + + t0 = s0 & 0xc000; + t0 = t0 < 1; + t0 = t0 << 1; + a0 = a0 - t0; + s0 = s0 << t0; -asmlinkage void sim_hw0_irqdispatch(struct pt_regs *regs) + t0 = s0 & 0x8000; + t0 = t0 < 1; + //t0 = t0 << 2; + a0 = a0 - t0; + //s0 = s0 << t0; + + return a0; +#endif +} + +static inline void sim_hw0_irqdispatch(struct pt_regs *regs) { do_IRQ(2, regs); } -void __init arch_init_irq(void) +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) { - /* Now safe to set the exception vector. */ - set_except_vector(0, simIRQ); + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; + int irq; + + irq = irq_ffs(pending); + if (irq > 0) + do_IRQ(MIPSCPU_INT_BASE + irq, regs); + else + spurious_interrupt(regs); +} + +void __init arch_init_irq(void) +{ mips_cpu_irq_init(MIPSCPU_INT_BASE); } |