diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2001-03-09 20:33:35 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2001-03-09 20:33:35 +0000 |
commit | 116674acc97ba75a720329996877077d988443a2 (patch) | |
tree | 6a3f2ff0b612ae2ee8a3f3509370c9e6333a53b3 /include/asm-cris/irq.h | |
parent | 71118c319fcae4a138f16e35b4f7e0a6d53ce2ca (diff) |
Merge with Linux 2.4.2.
Diffstat (limited to 'include/asm-cris/irq.h')
-rw-r--r-- | include/asm-cris/irq.h | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/include/asm-cris/irq.h b/include/asm-cris/irq.h new file mode 100644 index 000000000..fe88db74e --- /dev/null +++ b/include/asm-cris/irq.h @@ -0,0 +1,102 @@ +/* + * Interrupt handling assembler for Linux/CRIS + * + * Copyright (c) 2000 Axis Communications AB + * + * Authors: Bjorn Wesen (bjornw@axis.com) + * + */ + +#ifndef _ASM_IRQ_H +#define _ASM_IRQ_H + +/* + * linux/include/asm-cris/irq.h + */ + +#include <linux/linkage.h> +#include <asm/segment.h> + +#include <asm/sv_addr_ag.h> + +#define NR_IRQS 26 /* TODO: what is this for Etrax100/LX ? */ + +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + +#define disable_irq_nosync disable_irq +#define enable_irq_nosync enable_irq + +/* our fine, global, etrax irq vector! the pointer lives in the head.S file. */ + +typedef void (*irqvectptr)(void); + +struct etrax_interrupt_vector { + irqvectptr v[256]; +}; + +extern struct etrax_interrupt_vector *etrax_irv; +void set_int_vector(int n, irqvectptr addr, irqvectptr saddr); +void set_break_vector(int n, irqvectptr addr); + +#define __STR(x) #x +#define STR(x) __STR(x) + +/* SAVE_ALL saves registers so they match pt_regs */ + +#define SAVE_ALL \ + "push irp\n\t" /* push instruction pointer */ \ + "push srp\n\t" /* push subroutine return pointer */ \ + "push dccr\n\t" /* push condition codes */ \ + "push mof\n\t" /* push multiply overflow reg */ \ + "di\n\t" /* need to disable irq's at this point */\ + "subq 14*4,sp\n\t" /* make room for r0-r13 */ \ + "movem r13,[sp]\n\t" /* push the r0-r13 registers */ \ + "push r10\n\t" /* push orig_r10 */ \ + "clear.d [sp=sp-4]\n\t" /* frametype - this is a normal stackframe */ + + /* BLOCK_IRQ and UNBLOCK_IRQ do the same as mask_irq and unmask_irq in irq.c */ + +#define BLOCK_IRQ(mask,nr) \ + "move.d " #mask ",r0\n\t" \ + "move.d r0,[0xb00000d8]\n\t" + +#define UNBLOCK_IRQ(mask) \ + "move.d " #mask ",r0\n\t" \ + "move.d r0,[0xb00000dc]\n\t" + +#define IRQ_NAME2(nr) nr##_interrupt(void) +#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) +#define sIRQ_NAME(nr) IRQ_NAME2(sIRQ##nr) +#define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr) + + /* the asm IRQ handler makes sure the causing IRQ is blocked, then it calls + * do_IRQ (with irq disabled still). after that it unblocks and jumps to + * ret_from_intr (entry.S) + */ + +#define BUILD_IRQ(nr,mask) \ +void IRQ_NAME(nr); \ +void sIRQ_NAME(nr); \ +void BAD_IRQ_NAME(nr); \ +__asm__ ( \ + ".text\n\t" \ + "_IRQ" #nr "_interrupt:\n\t" \ + SAVE_ALL \ + "_sIRQ" #nr "_interrupt:\n\t" /* shortcut for the multiple irq handler */ \ + BLOCK_IRQ(mask,nr) /* this must be done to prevent irq loops when we ei later */ \ + "moveq "#nr",r10\n\t" \ + "move.d sp,r11\n\t" \ + "jsr _do_IRQ\n\t" /* irq.c, r10 and r11 are arguments */ \ + UNBLOCK_IRQ(mask) \ + "moveq 0,r9\n\t" /* make ret_from_intr realise we came from an irq */ \ + "jump _ret_from_intr\n\t" \ + "_bad_IRQ" #nr "_interrupt:\n\t" \ + "push r0\n\t" \ + BLOCK_IRQ(mask,nr) \ + "pop r0\n\t"); + + +#endif /* _ASM_IRQ_H */ + + |