X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fintr_asm.S;fp=src%2Fintr_asm.S;h=ea0be36d1561b53a3f6a32bce77371b065d782b1;hb=a2f94f569a4c99204de02814a20098a71527e913;hp=0000000000000000000000000000000000000000;hpb=d1e8a437c1fab4535f82c4c214ec3330ac32e48d;p=bootcensus diff --git a/src/intr_asm.S b/src/intr_asm.S new file mode 100644 index 0000000..ea0be36 --- /dev/null +++ b/src/intr_asm.S @@ -0,0 +1,114 @@ + .data + .align 4 + .short 0 +idtr_desc: +lim: .short 0 +addr: .long 0 + + .text +/* void set_idt(uint32_t addr, uint16_t limit) */ + .global set_idt +set_idt: + mov 4(%esp), %eax + mov %eax, addr + mov 8(%esp), %ax + mov %ax, lim + lidt (idtr_desc) + ret + +/* int get_intr_flag() */ + .global get_intr_flag +get_intr_flag: + pushf + popl %eax + # bit 9 of eflags is IF + shr $9, %eax + and $1, %eax + ret + +/* void set_intr_flag(int onoff) */ + .global set_intr_flag +set_intr_flag: + cmpl $0, 4(%esp) + jz 0f + sti + ret +0: cli + ret + +/* interrupt entry with error code macro + * this macro generates an interrupt entry point for the + * exceptions which include error codes in the stack frame + */ + .macro ientry_err n name + .globl intr_entry_\name +intr_entry_\name: + pushl $\n + jmp intr_entry_common + .endm + +/* interrupt entry without error code macro + * this macro generates an interrupt entry point for the interrupts + * and exceptions which do not include error codes in the stack frame + * it pushes a dummy error code (0), to make the stack frame identical + */ + .macro ientry_noerr n name + .globl intr_entry_\name +intr_entry_\name: + pushl $0 + pushl $\n + jmp intr_entry_common + .endm + +/* common code used by all entry points. calls dispatch_intr() + * defined in intr.c + */ + .extern dispatch_intr +intr_entry_common: + /* save general purpose registers */ + pusha + call dispatch_intr +intr_ret_local: + /* restore general purpose registers */ + popa + /* remove error code and intr num from stack */ + add $8, %esp + iret + +/* special case for the timer interrupt, to avoid all the overhead of + * going through the C interrupt dispatcher 250 times each second + */ + .extern nticks + .global intr_entry_fast_timer +intr_entry_fast_timer: + incl nticks + # signal end of interrupt + push %eax + mov $0x20, %al + out %al, $0x20 + pop %eax + iret + + +/* XXX not necessary for now, just leaving it in in case it's useful + * down the road. + * + * intr_ret is called by context_switch to return from the kernel + * to userspace. The argument is a properly formed intr_frame + * structure with the saved context of the new task. + * + * First thing to do is remove the return address pointing back + * to context_switch, which then leaves us with a proper interrupt + * stack frame, so we can jump right in the middle of the regular + * interrupt return code above. + */ + .global intr_ret +intr_ret: + add $4, %esp + jmp intr_ret_local + +/* by including interrupts.h with ASM defined, the macros above + * are expanded to generate all required interrupt entry points + */ +#define ASM +#include