home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / lxapi32.zip / Include / asm / hw_irq.h < prev    next >
C/C++ Source or Header  |  2002-04-26  |  6KB  |  243 lines

  1. /* $Id: hw_irq.h,v 1.2 2002/04/26 23:09:19 smilcke Exp $ */
  2.  
  3. #ifndef _ASM_HW_IRQ_H
  4. #define _ASM_HW_IRQ_H
  5.  
  6. /*
  7.  *    linux/include/asm/hw_irq.h
  8.  *
  9.  *    (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
  10.  *
  11.  *    moved some of the old arch/i386/kernel/irq.h to here. VY
  12.  *
  13.  *    IRQ/IPI changes taken from work by Thomas Radke
  14.  *    <tomsoft@informatik.tu-chemnitz.de>
  15.  */
  16.  
  17. #include <linux/config.h>
  18. #include <asm/atomic.h>
  19. #include <asm/irq.h>
  20.  
  21. /*
  22.  * IDT vectors usable for external interrupt sources start
  23.  * at 0x20:
  24.  */
  25. #define FIRST_EXTERNAL_VECTOR    0x20
  26.  
  27. #define SYSCALL_VECTOR        0x80
  28.  
  29. /*
  30.  * Vectors 0x20-0x2f are used for ISA interrupts.
  31.  */
  32.  
  33. /*
  34.  * Special IRQ vectors used by the SMP architecture, 0xf0-0xff
  35.  *
  36.  *  some of the following vectors are 'rare', they are merged
  37.  *  into a single vector (CALL_FUNCTION_VECTOR) to save vector space.
  38.  *  TLB, reschedule and local APIC vectors are performance-critical.
  39.  *
  40.  *  Vectors 0xf0-0xfa are free (reserved for future Linux use).
  41.  */
  42. #define SPURIOUS_APIC_VECTOR    0xff
  43. #define ERROR_APIC_VECTOR    0xfe
  44. #define INVALIDATE_TLB_VECTOR    0xfd
  45. #define RESCHEDULE_VECTOR    0xfc
  46. #define CALL_FUNCTION_VECTOR    0xfb
  47.  
  48. /*
  49.  * Local APIC timer IRQ vector is on a different priority level,
  50.  * to work around the 'lost local interrupt if more than 2 IRQ
  51.  * sources per level' errata.
  52.  */
  53. #define LOCAL_TIMER_VECTOR    0xef
  54.  
  55. /*
  56.  * First APIC vector available to drivers: (vectors 0x30-0xee)
  57.  * we start at 0x31 to spread out vectors evenly between priority
  58.  * levels. (0x80 is the syscall vector)
  59.  */
  60. #define FIRST_DEVICE_VECTOR    0x31
  61. #define FIRST_SYSTEM_VECTOR    0xef
  62.  
  63. extern int irq_vector[NR_IRQS];
  64. #define IO_APIC_VECTOR(irq)    irq_vector[irq]
  65.  
  66. /*
  67.  * Various low-level irq details needed by irq.c, process.c,
  68.  * time.c, io_apic.c and smp.c
  69.  *
  70.  * Interrupt entry/exit code at both C and assembly level
  71.  */
  72.  
  73. extern void mask_irq(unsigned int irq);
  74. extern void unmask_irq(unsigned int irq);
  75. extern void disable_8259A_irq(unsigned int irq);
  76. extern void enable_8259A_irq(unsigned int irq);
  77. extern int i8259A_irq_pending(unsigned int irq);
  78. extern void make_8259A_irq(unsigned int irq);
  79. extern void init_8259A(int aeoi);
  80. extern void FASTCALL(send_IPI_self(int vector));
  81. extern void init_VISWS_APIC_irqs(void);
  82. extern void setup_IO_APIC(void);
  83. extern void disable_IO_APIC(void);
  84. extern void print_IO_APIC(void);
  85. extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
  86. extern void send_IPI(int dest, int vector);
  87.  
  88. extern unsigned long io_apic_irqs;
  89.  
  90. extern atomic_t irq_err_count;
  91. extern atomic_t irq_mis_count;
  92.  
  93. extern char _stext, _etext;
  94.  
  95. #define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
  96.  
  97. #define __STR(x) #x
  98. #define STR(x) __STR(x)
  99.  
  100. #define SAVE_ALL \
  101.     "cld\n\t" \
  102.     "pushl %es\n\t" \
  103.     "pushl %ds\n\t" \
  104.     "pushl %eax\n\t" \
  105.     "pushl %ebp\n\t" \
  106.     "pushl %edi\n\t" \
  107.     "pushl %esi\n\t" \
  108.     "pushl %edx\n\t" \
  109.     "pushl %ecx\n\t" \
  110.     "pushl %ebx\n\t" \
  111.     "movl $" STR(__KERNEL_DS) ",%edx\n\t" \
  112.     "movl %edx,%ds\n\t" \
  113.     "movl %edx,%es\n\t"
  114.  
  115. #define IRQ_NAME2(nr) nr##_interrupt(void)
  116. #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
  117.  
  118. #define GET_CURRENT \
  119.     "movl %esp, %ebx\n\t" \
  120.     "andl $-8192, %ebx\n\t"
  121.  
  122. /*
  123.  *    SMP has a few special interrupts for IPI messages
  124.  */
  125.  
  126.     /* there is a second layer of macro just to get the symbolic
  127.        name for the vector evaluated. This change is for RTLinux */
  128. #define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v)
  129. #define XBUILD_SMP_INTERRUPT(x,v)\
  130. asmlinkage void x(void); \
  131. asmlinkage void call_##x(void); \
  132. __asm__( \
  133. "\n"__ALIGN_STR"\n" \
  134. SYMBOL_NAME_STR(x) ":\n\t" \
  135.     "pushl $"#v"-256\n\t" \
  136.     SAVE_ALL \
  137.     SYMBOL_NAME_STR(call_##x)":\n\t" \
  138.     "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
  139.     "jmp ret_from_intr\n");
  140.  
  141. #define BUILD_SMP_TIMER_INTERRUPT(x,v) XBUILD_SMP_TIMER_INTERRUPT(x,v)
  142. #define XBUILD_SMP_TIMER_INTERRUPT(x,v) \
  143. asmlinkage void x(struct pt_regs * regs); \
  144. asmlinkage void call_##x(void); \
  145. __asm__( \
  146. "\n"__ALIGN_STR"\n" \
  147. SYMBOL_NAME_STR(x) ":\n\t" \
  148.     "pushl $"#v"-256\n\t" \
  149.     SAVE_ALL \
  150.     "movl %esp,%eax\n\t" \
  151.     "pushl %eax\n\t" \
  152.     SYMBOL_NAME_STR(call_##x)":\n\t" \
  153.     "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
  154.     "addl $4,%esp\n\t" \
  155.     "jmp ret_from_intr\n");
  156.  
  157. #define BUILD_COMMON_IRQ() \
  158. asmlinkage void call_do_IRQ(void); \
  159. __asm__( \
  160.     "\n" __ALIGN_STR"\n" \
  161.     "common_interrupt:\n\t" \
  162.     SAVE_ALL \
  163.     SYMBOL_NAME_STR(call_do_IRQ)":\n\t" \
  164.     "call " SYMBOL_NAME_STR(do_IRQ) "\n\t" \
  165.     "jmp ret_from_intr\n");
  166.  
  167. /*
  168.  * subtle. orig_eax is used by the signal code to distinct between
  169.  * system calls and interrupted 'random user-space'. Thus we have
  170.  * to put a negative value into orig_eax here. (the problem is that
  171.  * both system calls and IRQs want to have small integer numbers in
  172.  * orig_eax, and the syscall code has won the optimization conflict ;)
  173.  *
  174.  * Subtle as a pigs ear.  VY
  175.  */
  176.  
  177. #define BUILD_IRQ(nr) \
  178. asmlinkage void IRQ_NAME(nr); \
  179. __asm__( \
  180. "\n"__ALIGN_STR"\n" \
  181. SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
  182.     "pushl $"#nr"-256\n\t" \
  183.     "jmp common_interrupt");
  184.  
  185. extern unsigned long prof_cpu_mask;
  186. extern unsigned int * prof_buffer;
  187. extern unsigned long prof_len;
  188. extern unsigned long prof_shift;
  189.  
  190. /*
  191.  * x86 profiling function, SMP safe. We might want to do this in
  192.  * assembly totally?
  193.  */
  194. #ifdef TARGET_OS2
  195. static __inline__
  196. #else
  197. static inline
  198. #endif
  199. void x86_do_profile (unsigned long eip)
  200. {
  201.     if (!prof_buffer)
  202.         return;
  203.  
  204.     /*
  205.      * Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
  206.      * (default is all CPUs.)
  207.      */
  208.     if (!((1<<smp_processor_id()) & prof_cpu_mask))
  209.         return;
  210.  
  211.     eip -= (unsigned long) &_stext;
  212.     eip >>= prof_shift;
  213.     /*
  214.      * Don't ignore out-of-bounds EIP values silently,
  215.      * put them into the last histogram slot, so if
  216.      * present, they will show up as a sharp peak.
  217.      */
  218.     if (eip > prof_len-1)
  219.         eip = prof_len-1;
  220.     atomic_inc((atomic_t *)&prof_buffer[eip]);
  221. }
  222.  
  223. #ifdef CONFIG_SMP /*more of this file should probably be ifdefed SMP */
  224. #ifdef TARGET_OS2
  225. static __inline__
  226. #else
  227. static inline
  228. #endif
  229. void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
  230.     if (IO_APIC_IRQ(i))
  231.         send_IPI_self(IO_APIC_VECTOR(i));
  232. }
  233. #else
  234. #ifdef TARGET_OS2
  235. static __inline__
  236. #else
  237. static inline
  238. #endif
  239. void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
  240. #endif
  241.  
  242. #endif /* _ASM_HW_IRQ_H */
  243.