home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / include / asm / irq.h < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-31  |  3.9 KB  |  166 lines

  1. #ifndef _ASM_IRQ_H
  2. #define _ASM_IRQ_H
  3.  
  4. /*
  5.  *    linux/include/asm/irq.h
  6.  *
  7.  *    (C) 1992, 1993 Linus Torvalds
  8.  */
  9.  
  10. #include <linux/segment.h>
  11. #include <linux/linkage.h>
  12.  
  13. extern void disable_irq(unsigned int);
  14. extern void enable_irq(unsigned int);
  15.  
  16. #define __STR(x) #x
  17. #define STR(x) __STR(x)
  18.  
  19. #define SAVE_ALL \
  20.     "cld\n\t" \
  21.     "push %gs\n\t" \
  22.     "push %fs\n\t" \
  23.     "push %es\n\t" \
  24.     "push %ds\n\t" \
  25.     "pushl %eax\n\t" \
  26.     "pushl %ebp\n\t" \
  27.     "pushl %edi\n\t" \
  28.     "pushl %esi\n\t" \
  29.     "pushl %edx\n\t" \
  30.     "pushl %ecx\n\t" \
  31.     "pushl %ebx\n\t" \
  32.     "movl $" STR(KERNEL_DS) ",%edx\n\t" \
  33.     "mov %dx,%ds\n\t" \
  34.     "mov %dx,%es\n\t" \
  35.     "movl $" STR(USER_DS) ",%edx\n\t" \
  36.     "mov %dx,%fs\n\t"   \
  37.     "movl $0,%edx\n\t"  \
  38.     "movl %edx,%db7\n\t"
  39.  
  40. /*
  41.  * SAVE_MOST/RESTORE_MOST is used for the faster version of IRQ handlers,
  42.  * installed by using the SA_INTERRUPT flag. These kinds of IRQ's don't
  43.  * call the routines that do signal handling etc on return, and can have
  44.  * more relaxed register-saving etc. They are also atomic, and are thus
  45.  * suited for small, fast interrupts like the serial lines or the harddisk
  46.  * drivers, which don't actually need signal handling etc.
  47.  *
  48.  * Also note that we actually save only those registers that are used in
  49.  * C subroutines (%eax, %edx and %ecx), so if you do something weird,
  50.  * you're on your own. The only segments that are saved (not counting the
  51.  * automatic stack and code segment handling) are %ds and %es, and they
  52.  * point to kernel space. No messing around with %fs here.
  53.  */
  54. #define SAVE_MOST \
  55.     "cld\n\t" \
  56.     "push %es\n\t" \
  57.     "push %ds\n\t" \
  58.     "pushl %eax\n\t" \
  59.     "pushl %edx\n\t" \
  60.     "pushl %ecx\n\t" \
  61.     "movl $" STR(KERNEL_DS) ",%edx\n\t" \
  62.     "mov %dx,%ds\n\t" \
  63.     "mov %dx,%es\n\t"
  64.  
  65. #define RESTORE_MOST \
  66.     "popl %ecx\n\t" \
  67.     "popl %edx\n\t" \
  68.     "popl %eax\n\t" \
  69.     "pop %ds\n\t" \
  70.     "pop %es\n\t" \
  71.     "iret"
  72.  
  73. /*
  74.  * The "inb" instructions are not needed, but seem to change the timings
  75.  * a bit - without them it seems that the harddisk driver won't work on
  76.  * all hardware. Arghh.
  77.  */
  78. #define ACK_FIRST(mask) \
  79.     "inb $0x21,%al\n\t" \
  80.     "jmp 1f\n" \
  81.     "1:\tjmp 1f\n" \
  82.     "1:\torb $" #mask ",_cache_21\n\t" \
  83.     "movb _cache_21,%al\n\t" \
  84.     "outb %al,$0x21\n\t" \
  85.     "jmp 1f\n" \
  86.     "1:\tjmp 1f\n" \
  87.     "1:\tmovb $0x20,%al\n\t" \
  88.     "outb %al,$0x20\n\t"
  89.  
  90. #define ACK_SECOND(mask) \
  91.     "inb $0xA1,%al\n\t" \
  92.     "jmp 1f\n" \
  93.     "1:\tjmp 1f\n" \
  94.     "1:\torb $" #mask ",_cache_A1\n\t" \
  95.     "movb _cache_A1,%al\n\t" \
  96.     "outb %al,$0xA1\n\t" \
  97.     "jmp 1f\n" \
  98.     "1:\tjmp 1f\n" \
  99.     "1:\tmovb $0x20,%al\n\t" \
  100.     "outb %al,$0xA0\n\t" \
  101.     "jmp 1f\n" \
  102.     "1:\tjmp 1f\n" \
  103.     "1:\toutb %al,$0x20\n\t"
  104.  
  105. #define UNBLK_FIRST(mask) \
  106.     "inb $0x21,%al\n\t" \
  107.     "jmp 1f\n" \
  108.     "1:\tjmp 1f\n" \
  109.     "1:\tandb $~(" #mask "),_cache_21\n\t" \
  110.     "movb _cache_21,%al\n\t" \
  111.     "outb %al,$0x21\n\t"
  112.  
  113. #define UNBLK_SECOND(mask) \
  114.     "inb $0xA1,%al\n\t" \
  115.     "jmp 1f\n" \
  116.     "1:\tjmp 1f\n" \
  117.     "1:\tandb $~(" #mask "),_cache_A1\n\t" \
  118.     "movb _cache_A1,%al\n\t" \
  119.     "outb %al,$0xA1\n\t"
  120.  
  121. #define IRQ_NAME2(nr) nr##_interrupt(void)
  122. #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
  123. #define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr)
  124. #define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
  125.     
  126. #define BUILD_IRQ(chip,nr,mask) \
  127. asmlinkage void IRQ_NAME(nr); \
  128. asmlinkage void FAST_IRQ_NAME(nr); \
  129. asmlinkage void BAD_IRQ_NAME(nr); \
  130. __asm__( \
  131. "\n.align 4\n" \
  132. "_IRQ" #nr "_interrupt:\n\t" \
  133.     "pushl $-"#nr"-2\n\t" \
  134.     SAVE_ALL \
  135.     ACK_##chip(mask) \
  136.     "incl _intr_count\n\t"\
  137.     "sti\n\t" \
  138.     "movl %esp,%ebx\n\t" \
  139.     "pushl %ebx\n\t" \
  140.     "pushl $" #nr "\n\t" \
  141.     "call _do_IRQ\n\t" \
  142.     "addl $8,%esp\n\t" \
  143.     "cli\n\t" \
  144.     UNBLK_##chip(mask) \
  145.     "decl _intr_count\n\t" \
  146.     "jmp ret_from_sys_call\n" \
  147. "\n.align 4\n" \
  148. "_fast_IRQ" #nr "_interrupt:\n\t" \
  149.     SAVE_MOST \
  150.     ACK_##chip(mask) \
  151.     "incl _intr_count\n\t" \
  152.     "pushl $" #nr "\n\t" \
  153.     "call _do_fast_IRQ\n\t" \
  154.     "addl $4,%esp\n\t" \
  155.     "cli\n\t" \
  156.     UNBLK_##chip(mask) \
  157.     "decl _intr_count\n\t" \
  158.     RESTORE_MOST \
  159. "\n\n.align 4\n" \
  160. "_bad_IRQ" #nr "_interrupt:\n\t" \
  161.     SAVE_MOST \
  162.     ACK_##chip(mask) \
  163.     RESTORE_MOST);
  164.  
  165. #endif
  166.