root/include/asm/irq.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


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

/* [previous][next][first][last][top][bottom][index][help] */