irq.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:7k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Interrupt handling assembler and defines for Linux/CRIS
  3.  *
  4.  * Copyright (c) 2000, 2001 Axis Communications AB
  5.  *
  6.  */
  7. #ifndef _ASM_IRQ_H
  8. #define _ASM_IRQ_H
  9. /*
  10.  * linux/include/asm-cris/irq.h
  11.  */
  12. #include <linux/linkage.h>
  13. #include <asm/segment.h>
  14. #include <asm/sv_addr_ag.h>
  15. #define NR_IRQS 32
  16. #define SOME_IRQ_NBR        IO_BITNR(R_VECT_MASK_RD, some)   /* 0 ? */
  17. #define NMI_IRQ_NBR         IO_BITNR(R_VECT_MASK_RD, nmi)    /* 1 */
  18. #define TIMER0_IRQ_NBR      IO_BITNR(R_VECT_MASK_RD, timer0) /* 2 */
  19. #define TIMER1_IRQ_NBR      IO_BITNR(R_VECT_MASK_RD, timer1) /* 3 */
  20. /* mio, ata, par0, scsi0 on 4 */
  21. /* par1, scsi1 on 5 */
  22. #define NETWORK_STATUS_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, network) /* 6 */
  23. #define SERIAL_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, serial) /* 8 */
  24. #define PA_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, pa) /* 11 */
  25. /* extdma0 and extdma1 is at irq 12 and 13 and/or same as dma5 and dma6 ? */
  26. #define EXTDMA0_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, ext_dma0)
  27. #define EXTDMA1_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, ext_dma1)
  28. /* dma0-9 is irq 16..25 */
  29. /* 16,17: network */
  30. #define DMA0_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma0)
  31. #define DMA1_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma1)
  32. #define NETWORK_DMA_TX_IRQ_NBR DMA0_TX_IRQ_NBR
  33. #define NETWORK_DMA_RX_IRQ_NBR DMA1_RX_IRQ_NBR
  34. /* 18,19: dma2 and dma3 shared by par0, scsi0, ser2 and ata */
  35. #define DMA2_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma2)
  36. #define DMA3_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma3)
  37. #define SER2_DMA_TX_IRQ_NBR DMA2_TX_IRQ_NBR
  38. #define SER2_DMA_RX_IRQ_NBR DMA3_RX_IRQ_NBR
  39. /* 20,21: dma4 and dma5 shared by par1, scsi1, ser3 and extdma0 */
  40. #define DMA4_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma4)
  41. #define DMA5_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma5)
  42. #define SER3_DMA_TX_IRQ_NBR DMA4_TX_IRQ_NBR
  43. #define SER3_DMA_RX_IRQ_NBR DMA5_RX_IRQ_NBR
  44. /* 22,23: dma6 and dma7 shared by ser0, extdma1 and mem2mem */
  45. #define DMA6_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma6)
  46. #define DMA7_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma7)
  47. #define SER0_DMA_TX_IRQ_NBR DMA6_TX_IRQ_NBR
  48. #define SER0_DMA_RX_IRQ_NBR DMA7_RX_IRQ_NBR
  49. #define MEM2MEM_DMA_TX_IRQ_NBR DMA6_TX_IRQ_NBR
  50. #define MEM2MEM_DMA_RX_IRQ_NBR DMA7_RX_IRQ_NBR
  51. /* 24,25: dma8 and dma9 shared by ser1 and usb */
  52. #define DMA8_TX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma8)
  53. #define DMA9_RX_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, dma9)
  54. #define SER1_DMA_TX_IRQ_NBR DMA8_TX_IRQ_NBR
  55. #define SER1_DMA_RX_IRQ_NBR DMA9_RX_IRQ_NBR
  56. #define USB_DMA_TX_IRQ_NBR DMA8_TX_IRQ_NBR
  57. #define USB_DMA_RX_IRQ_NBR DMA9_RX_IRQ_NBR
  58. /* usb: controller at irq 31 + uses DMA8 and DMA9 */
  59. #define USB_HC_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, usb)
  60. extern void disable_irq(unsigned int);
  61. extern void enable_irq(unsigned int);
  62. #define disable_irq_nosync      disable_irq
  63. #define enable_irq_nosync       enable_irq
  64. /* our fine, global, etrax irq vector! the pointer lives in the head.S file. */
  65. typedef void (*irqvectptr)(void);
  66. struct etrax_interrupt_vector {
  67. irqvectptr v[256];
  68. };
  69. extern struct etrax_interrupt_vector *etrax_irv;
  70. void set_int_vector(int n, irqvectptr addr, irqvectptr saddr);
  71. void set_break_vector(int n, irqvectptr addr);
  72. #define __STR(x) #x
  73. #define STR(x) __STR(x)
  74.  
  75. /* SAVE_ALL saves registers so they match pt_regs */
  76. #define SAVE_ALL 
  77.   "move $irp,[$sp=$sp-16]nt" /* push instruction pointer and fake SBFS struct */ 
  78.   "push $srpnt"       /* push subroutine return pointer */ 
  79.   "push $dccrnt"      /* push condition codes */ 
  80.   "push $mofnt"       /* push multiply overflow reg */ 
  81.   "dint"             /* need to disable irq's at this point */
  82.   "subq 14*4,$spnt"   /* make room for r0-r13 */ 
  83.   "movem $r13,[$sp]nt" /* push the r0-r13 registers */ 
  84.   "push $r10nt"       /* push orig_r10 */ 
  85.   "clear.d [$sp=$sp-4]nt"  /* frametype - this is a normal stackframe */
  86.   /* BLOCK_IRQ and UNBLOCK_IRQ do the same as mask_irq and unmask_irq in irq.c */
  87. #define BLOCK_IRQ(mask,nr) 
  88.   "move.d " #mask ",$r0nt" 
  89.   "move.d $r0,[0xb00000d8]nt" 
  90.   
  91. #define UNBLOCK_IRQ(mask) 
  92.   "move.d " #mask ",$r0nt" 
  93.   "move.d $r0,[0xb00000dc]nt" 
  94. #define IRQ_NAME2(nr) nr##_interrupt(void)
  95. #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
  96. #define sIRQ_NAME(nr) IRQ_NAME2(sIRQ##nr)
  97. #define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
  98.   /* the asm IRQ handler makes sure the causing IRQ is blocked, then it calls
  99.    * do_IRQ (with irq disabled still). after that it unblocks and jumps to
  100.    * ret_from_intr (entry.S)
  101.    *
  102.    * The reason the IRQ is blocked is to allow an sti() before the handler which
  103.    * will acknowledge the interrupt is run.
  104.    */
  105. #define BUILD_IRQ(nr,mask) 
  106. void IRQ_NAME(nr); 
  107. void sIRQ_NAME(nr); 
  108. void BAD_IRQ_NAME(nr); 
  109. __asm__ ( 
  110.           ".textnt" 
  111.           "IRQ" #nr "_interrupt:nt" 
  112.   SAVE_ALL 
  113.   "sIRQ" #nr "_interrupt:nt" /* shortcut for the multiple irq handler */ 
  114.   BLOCK_IRQ(mask,nr) /* this must be done to prevent irq loops when we ei later */ 
  115.   "moveq "#nr",$r10nt" 
  116.   "move.d $sp,$r11nt" 
  117.   "jsr do_IRQnt" /* irq.c, r10 and r11 are arguments */ 
  118.   UNBLOCK_IRQ(mask) 
  119.   "moveq 0,$r9nt" /* make ret_from_intr realise we came from an irq */ 
  120.   "jump ret_from_intrnt" 
  121.           "bad_IRQ" #nr "_interrupt:nt" 
  122.   "push $r0nt" 
  123.   BLOCK_IRQ(mask,nr) 
  124.   "pop $r0nt" 
  125.           "retint" 
  126.           "nopn");
  127. /* This is subtle. The timer interrupt is crucial and it should not be disabled for 
  128.  * too long. However, if it had been a normal interrupt as per BUILD_IRQ, it would
  129.  * have been BLOCK'ed, and then softirq's are run before we return here to UNBLOCK.
  130.  * If the softirq's take too much time to run, the timer irq won't run and the 
  131.  * watchdog will kill us.
  132.  *
  133.  * Furthermore, if a lot of other irq's occur before we return here, the multiple_irq
  134.  * handler is run and it prioritizes the timer interrupt. However if we had BLOCK'ed
  135.  * it here, we would not get the multiple_irq at all.
  136.  *
  137.  * The non-blocking here is based on the knowledge that the timer interrupt is 
  138.  * registred as a fast interrupt (SA_INTERRUPT) so that we _know_ there will not
  139.  * be an sti() before the timer irq handler is run to acknowledge the interrupt.
  140.  */
  141. #define BUILD_TIMER_IRQ(nr,mask) 
  142. void IRQ_NAME(nr); 
  143. void sIRQ_NAME(nr); 
  144. void BAD_IRQ_NAME(nr); 
  145. __asm__ ( 
  146.           ".textnt" 
  147.           "IRQ" #nr "_interrupt:nt" 
  148.   SAVE_ALL 
  149.   "sIRQ" #nr "_interrupt:nt" /* shortcut for the multiple irq handler */ 
  150.   "moveq "#nr",$r10nt" 
  151.   "move.d $sp,$r11nt" 
  152.   "jsr do_IRQnt" /* irq.c, r10 and r11 are arguments */ 
  153.   "moveq 0,$r9nt" /* make ret_from_intr realise we came from an irq */ 
  154.   "jump ret_from_intrnt" 
  155.           "bad_IRQ" #nr "_interrupt:nt" 
  156.   "push $r0nt" 
  157.   BLOCK_IRQ(mask,nr) 
  158.   "pop $r0nt" 
  159.           "retint" 
  160.           "nopn");
  161. #endif  /* _ASM_IRQ_H */