00001 #ifndef _ASM_IRQ_H
00002 #define _ASM_IRQ_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <linux/segment.h>
00015 #include <linux/linkage.h>
00016
00017 extern void disable_irq(unsigned int);
00018 extern void enable_irq(unsigned int);
00019
00020 #define __STR(x) #x
00021 #define STR(x) __STR(x)
00022
00023 #define SAVE_ALL \
00024 "cld\n\t" \
00025 "push %gs\n\t" \
00026 "push %fs\n\t" \
00027 "push %es\n\t" \
00028 "push %ds\n\t" \
00029 "pushl %eax\n\t" \
00030 "pushl %ebp\n\t" \
00031 "pushl %edi\n\t" \
00032 "pushl %esi\n\t" \
00033 "pushl %edx\n\t" \
00034 "pushl %ecx\n\t" \
00035 "pushl %ebx\n\t" \
00036 "movl $" STR(KERNEL_DS) ",%edx\n\t" \
00037 "mov %dx,%ds\n\t" \
00038 "mov %dx,%es\n\t" \
00039 "movl $" STR(USER_DS) ",%edx\n\t" \
00040 "mov %dx,%fs\n\t" \
00041 "movl $0,%edx\n\t" \
00042 "movl %edx,%db7\n\t"
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #define SAVE_MOST \
00063 "cld\n\t" \
00064 "push %es\n\t" \
00065 "push %ds\n\t" \
00066 "pushl %eax\n\t" \
00067 "pushl %edx\n\t" \
00068 "pushl %ecx\n\t" \
00069 "movl $" STR(KERNEL_DS) ",%edx\n\t" \
00070 "mov %dx,%ds\n\t" \
00071 "mov %dx,%es\n\t"
00072
00073 #define RESTORE_MOST \
00074 "popl %ecx\n\t" \
00075 "popl %edx\n\t" \
00076 "popl %eax\n\t" \
00077 "pop %ds\n\t" \
00078 "pop %es\n\t" \
00079 "iret"
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 #define ACK_FIRST(mask) \
00091 "inb $0x21,%al\n\t" \
00092 "jmp 1f\n" \
00093 "1:\tjmp 1f\n" \
00094 "1:\torb $" #mask ",_cache_21\n\t" \
00095 "movb _cache_21,%al\n\t" \
00096 "outb %al,$0x21\n\t" \
00097 "jmp 1f\n" \
00098 "1:\tjmp 1f\n" \
00099 "1:\tmovb $0x20,%al\n\t" \
00100 "outb %al,$0x20\n\t"
00101
00102 #define ACK_SECOND(mask) \
00103 "inb $0xA1,%al\n\t" \
00104 "jmp 1f\n" \
00105 "1:\tjmp 1f\n" \
00106 "1:\torb $" #mask ",_cache_A1\n\t" \
00107 "movb _cache_A1,%al\n\t" \
00108 "outb %al,$0xA1\n\t" \
00109 "jmp 1f\n" \
00110 "1:\tjmp 1f\n" \
00111 "1:\tmovb $0x20,%al\n\t" \
00112 "outb %al,$0xA0\n\t" \
00113 "jmp 1f\n" \
00114 "1:\tjmp 1f\n" \
00115 "1:\toutb %al,$0x20\n\t"
00116
00117 #define UNBLK_FIRST(mask) \
00118 "inb $0x21,%al\n\t" \
00119 "jmp 1f\n" \
00120 "1:\tjmp 1f\n" \
00121 "1:\tandb $~(" #mask "),_cache_21\n\t" \
00122 "movb _cache_21,%al\n\t" \
00123 "outb %al,$0x21\n\t"
00124
00125 #define UNBLK_SECOND(mask) \
00126 "inb $0xA1,%al\n\t" \
00127 "jmp 1f\n" \
00128 "1:\tjmp 1f\n" \
00129 "1:\tandb $~(" #mask "),_cache_A1\n\t" \
00130 "movb _cache_A1,%al\n\t" \
00131 "outb %al,$0xA1\n\t"
00132
00133 #define IRQ_NAME2(nr) nr##_interrupt(void)
00134 #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
00135 #define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr)
00136 #define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
00137
00138 #define BUILD_IRQ(chip,nr,mask) \
00139 asmlinkage void IRQ_NAME(nr); \
00140 asmlinkage void FAST_IRQ_NAME(nr); \
00141 asmlinkage void BAD_IRQ_NAME(nr); \
00142 __asm__( \
00143 "\n.align 4\n" \
00144 "_IRQ" #nr "_interrupt:\n\t" \
00145 "pushl $-"#nr"-2\n\t" \
00146 SAVE_ALL \
00147 ACK_##chip(mask) \
00148 "incl _intr_count\n\t"\
00149 "sti\n\t" \
00150 "movl %esp,%ebx\n\t" \
00151 "pushl %ebx\n\t" \
00152 "pushl $" #nr "\n\t" \
00153 "call _do_IRQ\n\t" \
00154 "addl $8,%esp\n\t" \
00155 "cli\n\t" \
00156 UNBLK_##chip(mask) \
00157 "decl _intr_count\n\t" \
00158 "jmp ret_from_sys_call\n" \
00159 "\n.align 4\n" \
00160 "_fast_IRQ" #nr "_interrupt:\n\t" \
00161 SAVE_MOST \
00162 ACK_##chip(mask) \
00163 "incl _intr_count\n\t" \
00164 "pushl $" #nr "\n\t" \
00165 "call _do_fast_IRQ\n\t" \
00166 "addl $4,%esp\n\t" \
00167 "cli\n\t" \
00168 UNBLK_##chip(mask) \
00169 "decl _intr_count\n\t" \
00170 RESTORE_MOST \
00171 "\n\n.align 4\n" \
00172 "_bad_IRQ" #nr "_interrupt:\n\t" \
00173 SAVE_MOST \
00174 ACK_##chip(mask) \
00175 RESTORE_MOST);
00176
00177 #endif