]> Zhao Yanbai Git Server - minix.git/commitdiff
single shot timer interrupts fix
authorTomas Hruby <tom@minix3.org>
Thu, 21 Oct 2010 17:07:01 +0000 (17:07 +0000)
committerTomas Hruby <tom@minix3.org>
Thu, 21 Oct 2010 17:07:01 +0000 (17:07 +0000)
- accidentaly this wasn't part of the SMP merge and the implementation
  remained uncomplete with the timer keeping ticking periodically

- APIC timer is set for a signel shot and restarted everytime it
  expires. This way we can keep the AP's trully idle

- the timer is restarted a little later before leaving to userspace

- LAPIC_TIMER_ICR is written before LAPIC_LVTTR so the newest value is
  used

kernel/arch/i386/apic.c
kernel/arch/i386/arch_clock.c
kernel/proc.c

index b5246f425279ba665015432721a73a6cae0bd523..1655f167214f4af386d9d5458279c4b9924da1f5 100644 (file)
@@ -508,14 +508,14 @@ PUBLIC void lapic_set_timer_one_shot(const u32_t usec)
 
        ticks_per_us = (lapic_bus_freq[cpu] / 1000000) * config_apic_timer_x;
 
+       lapic_write(LAPIC_TIMER_ICR, usec * ticks_per_us);
+
        lvtt = APIC_TDCR_1;
        lapic_write(LAPIC_TIMER_DCR, lvtt);
 
        /* configure timer as one-shot */
        lvtt = APIC_TIMER_INT_VECTOR;
        lapic_write(LAPIC_LVTTR, lvtt);
-
-       lapic_write(LAPIC_TIMER_ICR, usec * ticks_per_us);
 }
 
 PUBLIC void lapic_set_timer_periodic(const unsigned freq)
index 83157401da38d43c0f15d057d2b7607d4cca0ca8..cc6ec35ecb277eb4cc8238c442e746ee36e59f1f 100644 (file)
@@ -124,8 +124,8 @@ PUBLIC int init_local_timer(unsigned freq)
        /* if we know the address, lapic is enabled and we should use it */
        if (lapic_addr) {
                unsigned cpu = cpuid;
-               lapic_set_timer_periodic(freq);
                tsc_per_ms[cpu] = div64u(cpu_get_freq(cpu), 1000);
+               lapic_set_timer_one_shot(1000000/system_hz);
        } else
        {
                BOOT_VERBOSE(printf("Initiating legacy i8253 timer\n"));
index 3e416ae4dd78059b8ba4ad0a270ef229c10df19a..438b43c393a311ca8cc324d83adb826bd4d61853 100644 (file)
@@ -370,8 +370,6 @@ check_misc_flags:
        p = arch_finish_switch_to_user();
        assert(!is_zero64(p->p_cpu_time_left));
 
-       restart_local_timer();
-       
        context_stop(proc_addr(KERNEL));
 
        /* If the process isn't the owner of FPU, enable the FPU exception */
@@ -389,6 +387,9 @@ check_misc_flags:
 #ifdef CONFIG_SMP
        refresh_tlb();
 #endif
+       
+       restart_local_timer();
+       
        /*
         * restore_user_context() carries out the actual mode switch from kernel
         * to userspace. This function does not return