Annotation of Gnu-Mach/linux/src/include/asm-i386/irq.h, revision 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.