aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mips-boards/sim
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2006-04-03 12:56:36 -0400
committerRalf Baechle <ralf@linux-mips.org>2006-04-18 22:14:21 -0400
commite4ac58afdfac792c0583af30dbd9eae53e24c78b (patch)
tree7517bef2c515fc630e4d3d238867b91cde96f558 /arch/mips/mips-boards/sim
parentd35d473c25d43d7db3e5e18b66d558d2a631cca8 (diff)
[MIPS] Rewrite all the assembler interrupt handlers to C.
Saves like 1,600 lines of code, is way easier to debug, compilers frequently do a better job than the cut and paste type of handlers many boards had. And finally having all the stuff done in a single place also means alot of bug potencial for the MT ASE is gone. The only surviving handler in assembler is the DECstation one; I hope Maciej will rewrite it. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mips-boards/sim')
-rw-r--r--arch/mips/mips-boards/sim/sim_int.c64
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 @@
25 25
26extern void mips_cpu_irq_init(int); 26extern void mips_cpu_irq_init(int);
27 27
28extern asmlinkage void simIRQ(void); 28static inline int clz(unsigned long x)
29{
30 __asm__ (
31 " .set push \n"
32 " .set mips32 \n"
33 " clz %0, %1 \n"
34 " .set pop \n"
35 : "=r" (x)
36 : "r" (x));
37
38 return x;
39}
40
41/*
42 * Version of ffs that only looks at bits 12..15.
43 */
44static inline unsigned int irq_ffs(unsigned int pending)
45{
46#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
47 return -clz(pending) + 31 - CAUSEB_IP;
48#else
49 unsigned int a0 = 7;
50 unsigned int t0;
51
52 t0 = s0 & 0xf000;
53 t0 = t0 < 1;
54 t0 = t0 << 2;
55 a0 = a0 - t0;
56 s0 = s0 << t0;
57
58 t0 = s0 & 0xc000;
59 t0 = t0 < 1;
60 t0 = t0 << 1;
61 a0 = a0 - t0;
62 s0 = s0 << t0;
29 63
30asmlinkage void sim_hw0_irqdispatch(struct pt_regs *regs) 64 t0 = s0 & 0x8000;
65 t0 = t0 < 1;
66 //t0 = t0 << 2;
67 a0 = a0 - t0;
68 //s0 = s0 << t0;
69
70 return a0;
71#endif
72}
73
74static inline void sim_hw0_irqdispatch(struct pt_regs *regs)
31{ 75{
32 do_IRQ(2, regs); 76 do_IRQ(2, regs);
33} 77}
34 78
35void __init arch_init_irq(void) 79asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
36{ 80{
37 /* Now safe to set the exception vector. */ 81 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
38 set_except_vector(0, simIRQ); 82 int irq;
83
84 irq = irq_ffs(pending);
39 85
86 if (irq > 0)
87 do_IRQ(MIPSCPU_INT_BASE + irq, regs);
88 else
89 spurious_interrupt(regs);
90}
91
92void __init arch_init_irq(void)
93{
40 mips_cpu_irq_init(MIPSCPU_INT_BASE); 94 mips_cpu_irq_init(MIPSCPU_INT_BASE);
41} 95}