diff --git a/kernel/arch/i386/apic.c b/kernel/arch/i386/apic.c index 32b6d8bb7..b5fa1a26f 100644 --- a/kernel/arch/i386/apic.c +++ b/kernel/arch/i386/apic.c @@ -144,7 +144,9 @@ PUBLIC void apic_calibrate_clocks(void) init_8253A_timer(system_hz); /* loop for some time to get a sample */ - while(probe_ticks < PROBE_TICKS); + while(probe_ticks < PROBE_TICKS) { + intr_enable(); + } intr_disable(); stop_8253A_timer(); diff --git a/kernel/arch/i386/apic_asm.S b/kernel/arch/i386/apic_asm.S index 815ce2825..d014928e9 100644 --- a/kernel/arch/i386/apic_asm.S +++ b/kernel/arch/i386/apic_asm.S @@ -48,6 +48,7 @@ pusha ;\ call cycles_accounting_stop_idle ;\ APIC_IRQ_HANDLER(irq) ;\ + CLEAR_IF(10*4(%esp)) ;\ popa ;\ iret ; @@ -158,6 +159,7 @@ apic_hwint15: pusha ;\ call cycles_accounting_stop_idle ;\ LAPIC_INTR_HANDLER(func) ;\ + CLEAR_IF(10*4(%esp)) ;\ popa ;\ iret ; diff --git a/kernel/arch/i386/klib386.S b/kernel/arch/i386/klib386.S index d1bb9c1aa..a4b09c005 100644 --- a/kernel/arch/i386/klib386.S +++ b/kernel/arch/i386/klib386.S @@ -608,8 +608,11 @@ idt_zero: */ halt_cpu: sti - hlt - cli + hlt /* interrupts enabled only after this instruction is executed! */ + /* + * interrupt handlers make sure that the interrupts are disabled when we + * get here so we take only _one_ interrupt after halting the CPU + */ ret /*===========================================================================*/ diff --git a/kernel/arch/i386/mpx386.S b/kernel/arch/i386/mpx386.S index 293f1df02..a768db586 100644 --- a/kernel/arch/i386/mpx386.S +++ b/kernel/arch/i386/mpx386.S @@ -267,6 +267,7 @@ csinit: PIC_IRQ_HANDLER(irq) ;\ movb $END_OF_INT, %al ;\ outb $INT_CTL /* reenable interrupts in master pic */ ;\ + CLEAR_IF(10*4(%esp)) ;\ popa ;\ iret ; @@ -336,6 +337,7 @@ hwint07: movb $END_OF_INT, %al ;\ outb $INT_CTL /* reenable interrupts in master pic */ ;\ outb $INT2_CTL /* reenable slave 8259 */ ;\ + CLEAR_IF(10*4(%esp)) ;\ popa ;\ iret ; diff --git a/kernel/arch/i386/sconst.h b/kernel/arch/i386/sconst.h index efda211d0..0bad53dd6 100644 --- a/kernel/arch/i386/sconst.h +++ b/kernel/arch/i386/sconst.h @@ -141,4 +141,13 @@ call lazy_fpu ;\ add $4, %esp ; +/* + * clear the IF flag in eflags which are stored somewhere in memory, e.g. on + * stack. iret or popf will load the new value later + */ +#define CLEAR_IF(where) \ + mov where, %eax ;\ + andl $0xfffffdff, %eax ;\ + mov %eax, where ; + #endif /* __SCONST_H__ */