Annotation of Gnu-Mach/linux/src/include/asm-i386/irq.h, revision 1.1.1.1

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, 1993 Linus Torvalds
                      8:  *
                      9:  *     IRQ/IPI changes taken from work by Thomas Radke <[email protected]>
                     10:  */
                     11: 
                     12: #include <linux/linkage.h>
                     13: #include <asm/segment.h>
                     14: 
                     15: #define NR_IRQS 16
                     16: 
                     17: #define TIMER_IRQ 0
                     18: 
                     19: extern void disable_irq(unsigned int);
                     20: extern void enable_irq(unsigned int);
                     21: 
                     22: #define __STR(x) #x
                     23: #define STR(x) __STR(x)
                     24:  
                     25: #define SAVE_ALL \
                     26:        "cld\n\t" \
                     27:        "push %gs\n\t" \
                     28:        "push %fs\n\t" \
                     29:        "push %es\n\t" \
                     30:        "push %ds\n\t" \
                     31:        "pushl %eax\n\t" \
                     32:        "pushl %ebp\n\t" \
                     33:        "pushl %edi\n\t" \
                     34:        "pushl %esi\n\t" \
                     35:        "pushl %edx\n\t" \
                     36:        "pushl %ecx\n\t" \
                     37:        "pushl %ebx\n\t" \
                     38:        "movl $" STR(KERNEL_DS) ",%edx\n\t" \
                     39:        "mov %dx,%ds\n\t" \
                     40:        "mov %dx,%es\n\t" \
                     41:        "movl $" STR(USER_DS) ",%edx\n\t" \
                     42:        "mov %dx,%fs\n\t"   \
                     43:        "movl $0,%edx\n\t"  \
                     44:        "movl %edx,%db7\n\t"
                     45: 
                     46: /*
                     47:  * SAVE_MOST/RESTORE_MOST is used for the faster version of IRQ handlers,
                     48:  * installed by using the SA_INTERRUPT flag. These kinds of IRQ's don't
                     49:  * call the routines that do signal handling etc on return, and can have
                     50:  * more relaxed register-saving etc. They are also atomic, and are thus
                     51:  * suited for small, fast interrupts like the serial lines or the harddisk
                     52:  * drivers, which don't actually need signal handling etc.
                     53:  *
                     54:  * Also note that we actually save only those registers that are used in
                     55:  * C subroutines (%eax, %edx and %ecx), so if you do something weird,
                     56:  * you're on your own. The only segments that are saved (not counting the
                     57:  * automatic stack and code segment handling) are %ds and %es, and they
                     58:  * point to kernel space. No messing around with %fs here.
                     59:  */
                     60: #define SAVE_MOST \
                     61:        "cld\n\t" \
                     62:        "push %es\n\t" \
                     63:        "push %ds\n\t" \
                     64:        "pushl %eax\n\t" \
                     65:        "pushl %edx\n\t" \
                     66:        "pushl %ecx\n\t" \
                     67:        "movl $" STR(KERNEL_DS) ",%edx\n\t" \
                     68:        "mov %dx,%ds\n\t" \
                     69:        "mov %dx,%es\n\t"
                     70: 
                     71: #define RESTORE_MOST \
                     72:        "popl %ecx\n\t" \
                     73:        "popl %edx\n\t" \
                     74:        "popl %eax\n\t" \
                     75:        "pop %ds\n\t" \
                     76:        "pop %es\n\t" \
                     77:        "iret"
                     78: 
                     79: /*
                     80:  * The "inb" instructions are not needed, but seem to change the timings
                     81:  * a bit - without them it seems that the harddisk driver won't work on
                     82:  * all hardware. Arghh.
                     83:  */
                     84: #define ACK_FIRST(mask,nr) \
                     85:        "inb $0x21,%al\n\t" \
                     86:        "jmp 1f\n" \
                     87:        "1:\tjmp 1f\n" \
                     88:        "1:\torb $" #mask ","SYMBOL_NAME_STR(cache_21)"\n\t" \
                     89:        "movb "SYMBOL_NAME_STR(cache_21)",%al\n\t" \
                     90:        "outb %al,$0x21\n\t" \
                     91:        "jmp 1f\n" \
                     92:        "1:\tjmp 1f\n" \
                     93:        "1:\tmovb $0x20,%al\n\t" \
                     94:        "outb %al,$0x20\n\t"
                     95: 
                     96: #define ACK_SECOND(mask,nr) \
                     97:        "inb $0xA1,%al\n\t" \
                     98:        "jmp 1f\n" \
                     99:        "1:\tjmp 1f\n" \
                    100:        "1:\torb $" #mask ","SYMBOL_NAME_STR(cache_A1)"\n\t" \
                    101:        "movb "SYMBOL_NAME_STR(cache_A1)",%al\n\t" \
                    102:        "outb %al,$0xA1\n\t" \
                    103:        "jmp 1f\n" \
                    104:        "1:\tjmp 1f\n" \
                    105:        "1:\tmovb $0x20,%al\n\t" \
                    106:        "outb %al,$0xA0\n\t" \
                    107:        "jmp 1f\n" \
                    108:        "1:\tjmp 1f\n" \
                    109:        "1:\toutb %al,$0x20\n\t"
                    110: 
                    111: /* do not modify the ISR nor the cache_A1 variable */
                    112: #define MSGACK_SECOND(mask,nr) \
                    113:        "inb $0xA1,%al\n\t" \
                    114:        "jmp 1f\n" \
                    115:        "1:\tjmp 1f\n" \
                    116:        "1:\tmovb $0x20,%al\n\t" \
                    117:        "outb %al,$0xA0\n\t" \
                    118:        "jmp 1f\n" \
                    119:        "1:\tjmp 1f\n" \
                    120:        "1:\toutb %al,$0x20\n\t"
                    121: 
                    122: #define UNBLK_FIRST(mask) \
                    123:        "inb $0x21,%al\n\t" \
                    124:        "jmp 1f\n" \
                    125:        "1:\tjmp 1f\n" \
                    126:        "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_21)"\n\t" \
                    127:        "movb "SYMBOL_NAME_STR(cache_21)",%al\n\t" \
                    128:        "outb %al,$0x21\n\t"
                    129: 
                    130: #define UNBLK_SECOND(mask) \
                    131:        "inb $0xA1,%al\n\t" \
                    132:        "jmp 1f\n" \
                    133:        "1:\tjmp 1f\n" \
                    134:        "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_A1)"\n\t" \
                    135:        "movb "SYMBOL_NAME_STR(cache_A1)",%al\n\t" \
                    136:        "outb %al,$0xA1\n\t"
                    137: 
                    138: #define IRQ_NAME2(nr) nr##_interrupt(void)
                    139: #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
                    140: #define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr)
                    141: #define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
                    142: 
                    143: #ifdef __SMP__
                    144: 
                    145: #ifndef __SMP_PROF__
                    146: #define SMP_PROF_INT_SPINS 
                    147: #define SMP_PROF_IPI_CNT 
                    148: #else
                    149: #define SMP_PROF_INT_SPINS "incl "SYMBOL_NAME_STR(smp_spins)"(,%eax,4)\n\t"
                    150: #define SMP_PROF_IPI_CNT "incl "SYMBOL_NAME_STR(ipi_count)"\n\t" 
                    151: #endif
                    152: 
                    153: #define GET_PROCESSOR_ID \
                    154:        "movl "SYMBOL_NAME_STR(apic_reg)", %edx\n\t" \
                    155:        "movl 32(%edx), %eax\n\t" \
                    156:        "shrl $24,%eax\n\t" \
                    157:        "andl $0x0F,%eax\n"
                    158: 
                    159: #define        ENTER_KERNEL \
                    160:        "pushl %eax\n\t" \
                    161:        "pushl %ebx\n\t" \
                    162:        "pushl %ecx\n\t" \
                    163:        "pushl %edx\n\t" \
                    164:        "pushfl\n\t" \
                    165:        "cli\n\t" \
                    166:        "movl $6000, %ebx\n\t" \
                    167:        "movl "SYMBOL_NAME_STR(smp_loops_per_tick)", %ecx\n\t" \
                    168:        GET_PROCESSOR_ID \
                    169:        "btsl $" STR(SMP_FROM_INT) ","SYMBOL_NAME_STR(smp_proc_in_lock)"(,%eax,4)\n\t" \
                    170:        "1: " \
                    171:        "lock\n\t" \
                    172:        "btsl $0, "SYMBOL_NAME_STR(kernel_flag)"\n\t" \
                    173:        "jnc 3f\n\t" \
                    174:        "cmpb "SYMBOL_NAME_STR(active_kernel_processor)", %al\n\t" \
                    175:        "je 4f\n\t" \
                    176:        "cmpb "SYMBOL_NAME_STR(boot_cpu_id)", %al\n\t" \
                    177:        "jne 2f\n\t" \
                    178:        "movb $1, "SYMBOL_NAME_STR(smp_blocked_interrupt_pending)"\n\t" \
                    179:        "2: " \
                    180:         SMP_PROF_INT_SPINS \
                    181:        "btl %eax, "SYMBOL_NAME_STR(smp_invalidate_needed)"\n\t" \
                    182:        "jnc 5f\n\t" \
                    183:        "lock\n\t" \
                    184:        "btrl %eax, "SYMBOL_NAME_STR(smp_invalidate_needed)"\n\t" \
                    185:        "jnc 5f\n\t" \
                    186:        "movl %cr3,%edx\n\t" \
                    187:        "movl %edx,%cr3\n" \
                    188:        "5: btl $0, "SYMBOL_NAME_STR(kernel_flag)"\n\t" \
                    189:        "jnc 1b\n\t" \
                    190:        "cmpb "SYMBOL_NAME_STR(active_kernel_processor)", %al\n\t" \
                    191:        "je 4f\n\t" \
                    192:        "decl %ecx\n\t" \
                    193:        "jne 2b\n\t" \
                    194:        "decl %ebx\n\t" \
                    195:        "jne 6f\n\t" \
                    196:        "call "SYMBOL_NAME_STR(irq_deadlock_detected)"\n\t" \
                    197:        "6: movl "SYMBOL_NAME_STR(smp_loops_per_tick)", %ecx\n\t" \
                    198:        "cmpb "SYMBOL_NAME_STR(boot_cpu_id)", %al\n\t" \
                    199:        "jne 2b\n\t" \
                    200:        "incl "SYMBOL_NAME_STR(jiffies)"\n\t" \
                    201:        "jmp 2b\n\t" \
                    202:        "3: " \
                    203:        "movb %al, "SYMBOL_NAME_STR(active_kernel_processor)"\n\t" \
                    204:        "4: " \
                    205:        "incl "SYMBOL_NAME_STR(kernel_counter)"\n\t" \
                    206:        "cmpb "SYMBOL_NAME_STR(boot_cpu_id)", %al\n\t" \
                    207:        "jne 7f\n\t" \
                    208:        "movb $0, "SYMBOL_NAME_STR(smp_blocked_interrupt_pending)"\n\t" \
                    209:        "7: " \
                    210:        "popfl\n\t" \
                    211:        "popl %edx\n\t" \
                    212:        "popl %ecx\n\t" \
                    213:        "popl %ebx\n\t" \
                    214:        "popl %eax\n\t"
                    215: 
                    216: #define        LEAVE_KERNEL \
                    217:        GET_PROCESSOR_ID \
                    218:        "btrl $" STR(SMP_FROM_INT) ","SYMBOL_NAME_STR(smp_proc_in_lock)"(,%eax,4)\n\t" \
                    219:        "pushfl\n\t" \
                    220:        "cli\n\t" \
                    221:        "decl "SYMBOL_NAME_STR(kernel_counter)"\n\t" \
                    222:        "jnz 1f\n\t" \
                    223:        "movb "SYMBOL_NAME_STR(saved_active_kernel_processor)",%al\n\t" \
                    224:        "movb %al,"SYMBOL_NAME_STR(active_kernel_processor)"\n\t" \
                    225:        "cmpb $" STR (NO_PROC_ID) ",%al\n\t" \
                    226:        "jne 1f\n\t" \
                    227:        "lock\n\t" \
                    228:        "btrl $0, "SYMBOL_NAME_STR(kernel_flag)"\n\t" \
                    229:        "1: " \
                    230:        "popfl\n\t"
                    231:        
                    232:        
                    233: /*
                    234:  *     the syscall count inc is a gross hack because ret_from_syscall is used by both irq and
                    235:  *     syscall return paths (urghh).
                    236:  */
                    237:  
                    238: #define BUILD_IRQ(chip,nr,mask) \
                    239: asmlinkage void IRQ_NAME(nr); \
                    240: asmlinkage void FAST_IRQ_NAME(nr); \
                    241: asmlinkage void BAD_IRQ_NAME(nr); \
                    242: __asm__( \
                    243: "\n"__ALIGN_STR"\n" \
                    244: SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
                    245:        "pushl $-"#nr"-2\n\t" \
                    246:        SAVE_ALL \
                    247:        ENTER_KERNEL \
                    248:        ACK_##chip(mask,(nr&7)) \
                    249:        "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
                    250:        "sti\n\t" \
                    251:        "movl %esp,%ebx\n\t" \
                    252:        "pushl %ebx\n\t" \
                    253:        "pushl $" #nr "\n\t" \
                    254:        "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
                    255:        "addl $8,%esp\n\t" \
                    256:        "cli\n\t" \
                    257:        UNBLK_##chip(mask) \
                    258:        "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
                    259:        "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \
                    260:        "jmp ret_from_sys_call\n" \
                    261: "\n"__ALIGN_STR"\n" \
                    262: SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
                    263:        SAVE_MOST \
                    264:        ENTER_KERNEL \
                    265:        ACK_##chip(mask,(nr&7)) \
                    266:        "incl "SYMBOL_NAME_STR(intr_count)"\n\t" \
                    267:        "pushl $" #nr "\n\t" \
                    268:        "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
                    269:        "addl $4,%esp\n\t" \
                    270:        "cli\n\t" \
                    271:        UNBLK_##chip(mask) \
                    272:        "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
                    273:        LEAVE_KERNEL \
                    274:        RESTORE_MOST \
                    275: "\n"__ALIGN_STR"\n" \
                    276: SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
                    277:        SAVE_MOST \
                    278:        ENTER_KERNEL \
                    279:        ACK_##chip(mask,(nr&7)) \
                    280:        LEAVE_KERNEL \
                    281:        RESTORE_MOST);
                    282:        
                    283:  
                    284: #define BUILD_TIMER_IRQ(chip,nr,mask) \
                    285: asmlinkage void IRQ_NAME(nr); \
                    286: asmlinkage void FAST_IRQ_NAME(nr); \
                    287: asmlinkage void BAD_IRQ_NAME(nr); \
                    288: __asm__( \
                    289: "\n"__ALIGN_STR"\n" \
                    290: SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
                    291: SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
                    292: SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
                    293:        "pushl $-"#nr"-2\n\t" \
                    294:        SAVE_ALL \
                    295:        ENTER_KERNEL \
                    296:        ACK_##chip(mask,(nr&7)) \
                    297:        "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
                    298:        "movl %esp,%ebx\n\t" \
                    299:        "pushl %ebx\n\t" \
                    300:        "pushl $" #nr "\n\t" \
                    301:        "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
                    302:        "addl $8,%esp\n\t" \
                    303:        "cli\n\t" \
                    304:        UNBLK_##chip(mask) \
                    305:        "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
                    306:        "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \
                    307:        "jmp ret_from_sys_call\n");
                    308: 
                    309:        
                    310: /*
                    311:  *     Message pass must be a fast IRQ..
                    312:  */
                    313: 
                    314: #define BUILD_MSGIRQ(chip,nr,mask) \
                    315: asmlinkage void IRQ_NAME(nr); \
                    316: asmlinkage void FAST_IRQ_NAME(nr); \
                    317: asmlinkage void BAD_IRQ_NAME(nr); \
                    318: __asm__( \
                    319: "\n"__ALIGN_STR"\n" \
                    320: SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
                    321: SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
                    322:        SAVE_MOST \
                    323:        MSGACK_##chip(mask,(nr&7)) \
                    324:        SMP_PROF_IPI_CNT \
                    325:        "pushl $" #nr "\n\t" \
                    326:        "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
                    327:        "addl $4,%esp\n\t" \
                    328:        "cli\n\t" \
                    329:        RESTORE_MOST \
                    330: "\n"__ALIGN_STR"\n" \
                    331: SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
                    332:        SAVE_MOST \
                    333:        ACK_##chip(mask,(nr&7)) \
                    334:        RESTORE_MOST);
                    335: 
                    336: #define BUILD_RESCHEDIRQ(nr) \
                    337: asmlinkage void IRQ_NAME(nr); \
                    338: __asm__( \
                    339: "\n"__ALIGN_STR"\n" \
                    340: SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
                    341:        "pushl $-"#nr"-2\n\t" \
                    342:        SAVE_ALL \
                    343:        ENTER_KERNEL \
                    344:        "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
                    345:        "sti\n\t" \
                    346:        "movl %esp,%ebx\n\t" \
                    347:        "pushl %ebx\n\t" \
                    348:        "pushl $" #nr "\n\t" \
                    349:        "call "SYMBOL_NAME_STR(smp_reschedule_irq)"\n\t" \
                    350:        "addl $8,%esp\n\t" \
                    351:        "cli\n\t" \
                    352:        "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
                    353:        "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \
                    354:        "jmp ret_from_sys_call\n");
                    355: #else
                    356:        
                    357: #define BUILD_IRQ(chip,nr,mask) \
                    358: asmlinkage void IRQ_NAME(nr); \
                    359: asmlinkage void FAST_IRQ_NAME(nr); \
                    360: asmlinkage void BAD_IRQ_NAME(nr); \
                    361: __asm__( \
                    362: "\n"__ALIGN_STR"\n" \
                    363: SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
                    364:        "pushl $-"#nr"-2\n\t" \
                    365:        SAVE_ALL \
                    366:        ACK_##chip(mask,(nr&7)) \
                    367:        "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
                    368:        "sti\n\t" \
                    369:        "movl %esp,%ebx\n\t" \
                    370:        "pushl %ebx\n\t" \
                    371:        "pushl $" #nr "\n\t" \
                    372:        "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
                    373:        "addl $8,%esp\n\t" \
                    374:        "cli\n\t" \
                    375:        UNBLK_##chip(mask) \
                    376:        "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
                    377:        "jmp ret_from_sys_call\n" \
                    378: "\n"__ALIGN_STR"\n" \
                    379: SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
                    380:        SAVE_MOST \
                    381:        ACK_##chip(mask,(nr&7)) \
                    382:        "incl "SYMBOL_NAME_STR(intr_count)"\n\t" \
                    383:        "pushl $" #nr "\n\t" \
                    384:        "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
                    385:        "addl $4,%esp\n\t" \
                    386:        "cli\n\t" \
                    387:        UNBLK_##chip(mask) \
                    388:        "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
                    389:        RESTORE_MOST \
                    390: "\n"__ALIGN_STR"\n" \
                    391: SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
                    392:        SAVE_MOST \
                    393:        ACK_##chip(mask,(nr&7)) \
                    394:        RESTORE_MOST);
                    395:        
                    396: #define BUILD_TIMER_IRQ(chip,nr,mask) \
                    397: asmlinkage void IRQ_NAME(nr); \
                    398: asmlinkage void FAST_IRQ_NAME(nr); \
                    399: asmlinkage void BAD_IRQ_NAME(nr); \
                    400: __asm__( \
                    401: "\n"__ALIGN_STR"\n" \
                    402: SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
                    403: SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
                    404: SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
                    405:        "pushl $-"#nr"-2\n\t" \
                    406:        SAVE_ALL \
                    407:        ACK_##chip(mask,(nr&7)) \
                    408:        "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
                    409:        "movl %esp,%ebx\n\t" \
                    410:        "pushl %ebx\n\t" \
                    411:        "pushl $" #nr "\n\t" \
                    412:        "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
                    413:        "addl $8,%esp\n\t" \
                    414:        "cli\n\t" \
                    415:        UNBLK_##chip(mask) \
                    416:        "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
                    417:        "jmp ret_from_sys_call\n");
                    418: 
                    419: #endif
                    420: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.