|
|
1.1 ! root 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 $-1\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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.