From 6198c499368711fa914adb5f6bec46d171ad203c Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Sat, 2 May 2009 16:26:22 +0800 Subject: [PATCH] lapic timer: Improve lapic timer testing - Add lapic_timer_oneshot_intr_enable(), which set lapic timer into one shot mode and enable lapic timer interrupt. It is called during per-cpu systimers initialization. - Add lapic_timer_oneshot_quick(), which only set lapic timer's ICR --- sys/platform/pc32/apic/mpapic.c | 47 ++++++++++++++++++--------------- sys/platform/pc32/isa/clock.c | 11 ++++++-- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/sys/platform/pc32/apic/mpapic.c b/sys/platform/pc32/apic/mpapic.c index 3bc525a41b..773b14c61d 100644 --- a/sys/platform/pc32/apic/mpapic.c +++ b/sys/platform/pc32/apic/mpapic.c @@ -46,7 +46,8 @@ static void lapic_timer_calibrate(void); static void lapic_timer_set_divisor(int); void lapic_timer_process(void); void lapic_timer_process_frame(struct intrframe *); -void lapic_timer_intr_reload(sysclock_t); +void lapic_timer_intr_test(void); +void lapic_timer_oneshot_intr_enable(void); int lapic_timer_test; TUNABLE_INT("hw.lapic_timer_test", &lapic_timer_test); @@ -214,6 +215,12 @@ lapic_timer_oneshot(u_int count) lapic.icr_timer = count; } +static void +lapic_timer_oneshot_quick(u_int count) +{ + lapic.icr_timer = count; +} + static void lapic_timer_calibrate(void) { @@ -243,7 +250,7 @@ lapic_timer_process(void) { struct globaldata *gd = mycpu; - gd->gd_timer_running = 1; + gd->gd_timer_running = 0; if (lapic_timer_test) kprintf("%d proc\n", gd->gd_cpuid); @@ -254,38 +261,34 @@ lapic_timer_process_frame(struct intrframe *frame) { struct globaldata *gd = mycpu; - gd->gd_timer_running = 1; + gd->gd_timer_running = 0; if (lapic_timer_test) kprintf("%d proc frame\n", gd->gd_cpuid); } void -lapic_timer_intr_reload(sysclock_t reload) +lapic_timer_intr_test(void) { struct globaldata *gd = mycpu; - if (lapic_timer_test) { - if (gd->gd_timer_running == 2) { - return; - } else if (gd->gd_timer_running == 1) { - gd->gd_timer_running = 2; - KKASSERT(lapic_timer_freq != 0); - lapic_timer_oneshot(lapic_timer_freq); - } else if (gd->gd_timer_running == 0) { - uint32_t timer; - - timer = lapic.lvt_timer; - timer &= ~APIC_LVTT_MASKED; - lapic.lvt_timer = timer; - - gd->gd_timer_running = 2; - KKASSERT(lapic_timer_freq != 0); - lapic_timer_oneshot(lapic_timer_freq); - } + if (!gd->gd_timer_running) { + gd->gd_timer_running = 1; + KKASSERT(lapic_timer_freq != 0); + lapic_timer_oneshot_quick(lapic_timer_freq); } } +void +lapic_timer_oneshot_intr_enable(void) +{ + uint32_t timer; + + timer = lapic.lvt_timer; + timer &= ~(APIC_LVTT_MASKED | APIC_LVTT_PERIODIC); + lapic.lvt_timer = timer; +} + /* * dump contents of local APIC registers diff --git a/sys/platform/pc32/isa/clock.c b/sys/platform/pc32/isa/clock.c index 65c3a2ef89..4c95906a11 100644 --- a/sys/platform/pc32/isa/clock.c +++ b/sys/platform/pc32/isa/clock.c @@ -362,7 +362,9 @@ i8254_intr_reload(sysclock_t reload) } #ifdef SMP -extern void lapic_timer_intr_reload(sysclock_t); +extern int lapic_timer_test; +extern void lapic_timer_oneshot_intr_enable(void); +extern void lapic_timer_intr_test(void); #endif void @@ -370,13 +372,18 @@ cputimer_intr_reload(sysclock_t reload) { i8254_intr_reload(reload); #ifdef SMP - lapic_timer_intr_reload(reload); + if (__predict_false(lapic_timer_test)) + lapic_timer_intr_test(); #endif } void cputimer_intr_enable(void) { +#ifdef SMP + if (lapic_timer_test) + lapic_timer_oneshot_intr_enable(); +#endif } /* -- 2.41.0