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

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

unix.superglobalmegacorp.com

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