X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/80890b99fec2630ef0a1a0805d894c3d86c16506..2e21eb2f39dd80aa166216381d5d402be943686e:/lunaix-os/kernel/time/timer.c?ds=sidebyside diff --git a/lunaix-os/kernel/time/timer.c b/lunaix-os/kernel/time/timer.c index 73bc0d5..42a9ac2 100644 --- a/lunaix-os/kernel/time/timer.c +++ b/lunaix-os/kernel/time/timer.c @@ -16,6 +16,7 @@ #include #include #include +#include #define LVT_ENTRY_TIMER(vector, mode) (LVT_DELIVERY_FIXED | mode | vector) @@ -38,6 +39,9 @@ static volatile struct lx_timer_context* timer_ctx = NULL; static volatile uint32_t rtc_counter = 0; static volatile uint8_t apic_timer_done = 0; +static volatile uint32_t sched_ticks = 0; +static volatile uint32_t sched_ticks_counter = 0; + #define APIC_CALIBRATION_CONST 0x100000 void @@ -51,6 +55,7 @@ timer_init_context() timer_ctx->active_timers = (struct lx_timer*)lxmalloc(sizeof(struct lx_timer)); llist_init_head(timer_ctx->active_timers); + } void @@ -63,8 +68,7 @@ timer_init(uint32_t frequency) // Setup APIC timer // Setup a one-shot timer, we will use this to measure the bus speed. So we - // can - // then calibrate apic timer to work at *nearly* accurate hz + // can then calibrate apic timer to work at *nearly* accurate hz apic_write_reg(APIC_TIMER_LVT, LVT_ENTRY_TIMER(APIC_TIMER_IV, LVT_TIMER_ONESHOT)); @@ -81,7 +85,7 @@ timer_init(uint32_t frequency) step 4: Startup RTC timer step 5: Write a large value, v, to APIC_TIMER_ICR to start APIC timer (this must be followed immediately after step 4) - step 6: issue a write to EOI and clean up. + step 6: issue a write to EOI and clean up. When the APIC ICR counting down to 0 #APIC_TIMER_IV triggered, save the rtc timer's counter, k, and disable RTC timer immediately (although the @@ -94,6 +98,12 @@ timer_init(uint32_t frequency) */ + #ifdef __LUNAIXOS_DEBUG__ + if (frequency < 1000) { + kprintf(KWARN "Frequency too low. Millisecond timer might be dodgy."); + } + #endif + timer_ctx->base_frequency = 0; rtc_counter = 0; apic_timer_done = 0; @@ -109,14 +119,13 @@ timer_init(uint32_t frequency) wait_until(apic_timer_done); - // cpu_disable_interrupt(); assert_msg(timer_ctx->base_frequency, "Fail to initialize timer (NOFREQ)"); kprintf(KINFO "Base frequency: %u Hz\n", timer_ctx->base_frequency); timer_ctx->running_frequency = frequency; - timer_ctx->tps = timer_ctx->base_frequency / frequency; + timer_ctx->tphz = timer_ctx->base_frequency / frequency; // cleanup intr_unsubscribe(APIC_TIMER_IV, temp_intr_routine_apic_timer); @@ -126,7 +135,10 @@ timer_init(uint32_t frequency) LVT_ENTRY_TIMER(APIC_TIMER_IV, LVT_TIMER_PERIODIC)); intr_subscribe(APIC_TIMER_IV, timer_update); - apic_write_reg(APIC_TIMER_ICR, timer_ctx->tps); + apic_write_reg(APIC_TIMER_ICR, timer_ctx->tphz); + + sched_ticks = timer_ctx->running_frequency / 1000 * SCHED_TIME_SLICE; + sched_ticks_counter = 0; } int @@ -180,6 +192,13 @@ timer_update(const isr_param* param) lxfree(pos); } } + + sched_ticks_counter++; + + if (sched_ticks_counter >= sched_ticks) { + sched_ticks_counter = 0; + schedule(); + } } static void