hw_irq.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. #ifndef _ASM_HW_IRQ_H
  2. #define _ASM_HW_IRQ_H
  3. /*
  4.  * linux/include/asm/hw_irq.h
  5.  *
  6.  * (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
  7.  *
  8.  * moved some of the old arch/i386/kernel/irq.h to here. VY
  9.  *
  10.  * IRQ/IPI changes taken from work by Thomas Radke
  11.  * <tomsoft@informatik.tu-chemnitz.de>
  12.  *
  13.  * hacked by Andi Kleen for x86-64.
  14.  * 
  15.  *  $Id: hw_irq.h,v 1.29 2002/04/15 23:43:12 ak Exp $
  16.  */
  17. #include <linux/config.h>
  18. #include <asm/atomic.h>
  19. #include <asm/irq.h>
  20. /*
  21.  * IDT vectors usable for external interrupt sources start
  22.  * at 0x20:
  23.  */
  24. #define FIRST_EXTERNAL_VECTOR 0x20
  25. #define IA32_SYSCALL_VECTOR 0x80
  26. #define KDBENTER_VECTOR 0x81
  27. /*
  28.  * Vectors 0x20-0x2f are used for ISA interrupts.
  29.  */
  30. /*
  31.  * Special IRQ vectors used by the SMP architecture, 0xf0-0xff
  32.  *
  33.  *  some of the following vectors are 'rare', they are merged
  34.  *  into a single vector (CALL_FUNCTION_VECTOR) to save vector space.
  35.  *  TLB, reschedule and local APIC vectors are performance-critical.
  36.  *
  37.  *  Vectors 0xf0-0xf9 are free (reserved for future Linux use).
  38.  */
  39. #define SPURIOUS_APIC_VECTOR 0xff
  40. #define ERROR_APIC_VECTOR 0xfe
  41. #define INVALIDATE_TLB_VECTOR 0xfd
  42. #define RESCHEDULE_VECTOR 0xfc
  43. #define KDB_VECTOR 0xfa
  44. #define CALL_FUNCTION_VECTOR 0xfb
  45. #define KDB_VECTOR              0xfa
  46. /*
  47.  * Local APIC timer IRQ vector is on a different priority level,
  48.  * to work around the 'lost local interrupt if more than 2 IRQ
  49.  * sources per level' errata.
  50.  */
  51. #define LOCAL_TIMER_VECTOR 0xef
  52. /*
  53.  * First APIC vector available to drivers: (vectors 0x30-0xee)
  54.  * we start at 0x31 to spread out vectors evenly between priority
  55.  * levels. (0x80 is the syscall vector)
  56.  */
  57. #define FIRST_DEVICE_VECTOR 0x31
  58. #define FIRST_SYSTEM_VECTOR 0xef
  59. extern int irq_vector[NR_IRQS];
  60. #define IO_APIC_VECTOR(irq) irq_vector[irq]
  61. /*
  62.  * Various low-level irq details needed by irq.c, process.c,
  63.  * time.c, io_apic.c and smp.c
  64.  *
  65.  * Interrupt entry/exit code at both C and assembly level
  66.  */
  67. extern void mask_irq(unsigned int irq);
  68. extern void unmask_irq(unsigned int irq);
  69. extern void disable_8259A_irq(unsigned int irq);
  70. extern void enable_8259A_irq(unsigned int irq);
  71. extern int i8259A_irq_pending(unsigned int irq);
  72. extern void make_8259A_irq(unsigned int irq);
  73. extern void init_8259A(int aeoi);
  74. extern void FASTCALL(send_IPI_self(int vector));
  75. extern void init_VISWS_APIC_irqs(void);
  76. extern void setup_IO_APIC(void);
  77. extern void disable_IO_APIC(void);
  78. extern void print_IO_APIC(void);
  79. extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
  80. extern void send_IPI(int dest, int vector);
  81. extern unsigned long io_apic_irqs;
  82. extern atomic_t irq_err_count;
  83. extern atomic_t irq_mis_count;
  84. extern char _stext, _etext;
  85. #define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
  86. #define __STR(x) #x
  87. #define STR(x) __STR(x)
  88. #include <asm/ptrace.h>
  89. #ifndef ASM_OFFSET_H
  90. #include <asm/offset.h>
  91. #endif
  92. /* IF:off, stack contains irq number on origrax */ 
  93. #define IRQ_ENTER
  94. " cld ;"
  95. " pushq %rdi ;"
  96. " pushq %rsi ;"
  97. " pushq %rdx ;"
  98. " pushq %rcx ;"
  99. " pushq %rax ;"
  100. " pushq %r8 ;"
  101. " pushq %r9 ;"
  102. " pushq %r10 ;"
  103. " pushq %r11 ;"
  104. " leaq -48(%rsp),%rdi ;"
  105. " testl $3,136(%rdi) ;"
  106. " je 1f ;"
  107. " swapgs ;"
  108. "1: addl $1,%gs: " STR(pda_irqcount) ";"
  109. " movq %gs: " STR(pda_irqstackptr) ",%rax ;"
  110. " cmoveq %rax,%rsp ;"
  111. " pushq %rdi ;" 
  112. #define IRQ_NAME2(nr) nr##_interrupt(void)
  113. #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
  114. /*
  115.  * SMP has a few special interrupts for IPI messages
  116.  */
  117. /* there is a second layer of macro just to get the symbolic
  118.    name for the vector evaluated. This change is for RTLinux */
  119. #define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v)
  120. #define XBUILD_SMP_INTERRUPT(x,v)
  121. asmlinkage void x(void); 
  122. asmlinkage void call_##x(void); 
  123. __asm__( 
  124. "n"__ALIGN_STR"n" 
  125. SYMBOL_NAME_STR(x) ":nt" 
  126. "push $" #v "-256;" 
  127. IRQ_ENTER 
  128. "call " SYMBOL_NAME_STR(smp_##x) " ; " 
  129. "jmp ret_from_intr")
  130. #define BUILD_COMMON_IRQ()
  131. #define BUILD_IRQ(nr) 
  132. asmlinkage void IRQ_NAME(nr); 
  133. __asm__( 
  134. "n"__ALIGN_STR "n" 
  135. SYMBOL_NAME_STR(IRQ) #nr "_interrupt:nt" 
  136. "push $" #nr "-256 ; " 
  137. "jmp common_interrupt");
  138. extern unsigned long prof_cpu_mask;
  139. extern unsigned int * prof_buffer;
  140. extern unsigned long prof_len;
  141. extern unsigned long prof_shift;
  142. /*
  143.  * x86 profiling function, SMP safe. We might want to do this in
  144.  * assembly totally?
  145.  */
  146. static inline void x86_do_profile (unsigned long eip)
  147. {
  148. if (!prof_buffer)
  149. return;
  150. /*
  151.  * Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
  152.  * (default is all CPUs.)
  153.  */
  154. if (!((1<<smp_processor_id()) & prof_cpu_mask))
  155. return;
  156. eip -= (unsigned long) &_stext;
  157. eip >>= prof_shift;
  158. /*
  159.  * Don't ignore out-of-bounds EIP values silently,
  160.  * put them into the last histogram slot, so if
  161.  * present, they will show up as a sharp peak.
  162.  */
  163. if (eip > prof_len-1)
  164. eip = prof_len-1;
  165. atomic_inc((atomic_t *)&prof_buffer[eip]);
  166. }
  167. #ifdef CONFIG_SMP /*more of this file should probably be ifdefed SMP */
  168. static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
  169. if (IO_APIC_IRQ(i))
  170. send_IPI_self(IO_APIC_VECTOR(i));
  171. }
  172. #else
  173. static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
  174. #endif
  175. #endif /* _ASM_HW_IRQ_H */