X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/9461d582084ab8c0d85e8dca1df276945366a84b..2804ceee4ce65d49e9d52d0ed817317c0ac9efdc:/lunaix-os/kernel/time/timer.c diff --git a/lunaix-os/kernel/time/timer.c b/lunaix-os/kernel/time/timer.c index 51c2c7f..989256f 100644 --- a/lunaix-os/kernel/time/timer.c +++ b/lunaix-os/kernel/time/timer.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -20,6 +21,8 @@ #include #include +#include + #define LVT_ENTRY_TIMER(vector, mode) (LVT_DELIVERY_FIXED | mode | vector) LOG_MODULE("TIMER"); @@ -57,7 +60,7 @@ timer_init_context() assert_msg(timer_ctx, "Fail to initialize timer contex"); timer_ctx->active_timers = (struct lx_timer*)cake_grab(timer_pile); - llist_init_head(timer_ctx->active_timers); + llist_init_head(&timer_ctx->active_timers->link); } void @@ -69,10 +72,20 @@ timer_init(uint32_t frequency) // Setup APIC timer + // Remap the IRQ 8 (rtc timer's vector) to RTC_TIMER_IV in ioapic + // (Remarks IRQ 8 is pin INTIN8) + // See IBM PC/AT Technical Reference 1-10 for old RTC IRQ + // See Intel's Multiprocessor Specification for IRQ - IOAPIC INTIN + // mapping config. + + // grab ourselves these irq numbers + uint32_t iv_rtc = isrm_bindirq(PC_AT_IRQ_RTC, temp_intr_routine_rtc_tick); + uint32_t iv_timer = isrm_ivexalloc(temp_intr_routine_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 apic_write_reg(APIC_TIMER_LVT, - LVT_ENTRY_TIMER(APIC_TIMER_IV, LVT_TIMER_ONESHOT)); + LVT_ENTRY_TIMER(iv_timer, LVT_TIMER_ONESHOT)); // Set divider to 64 apic_write_reg(APIC_TIMER_DCR, APIC_TIMER_DIV64); @@ -110,9 +123,6 @@ timer_init(uint32_t frequency) rtc_counter = 0; apic_timer_done = 0; - intr_subscribe(APIC_TIMER_IV, temp_intr_routine_apic_timer); - intr_subscribe(RTC_TIMER_IV, temp_intr_routine_rtc_tick); - rtc_enable_timer(); // start RTC timer apic_write_reg(APIC_TIMER_ICR, APIC_CALIBRATION_CONST); // start APIC timer @@ -123,18 +133,19 @@ timer_init(uint32_t frequency) assert_msg(timer_ctx->base_frequency, "Fail to initialize timer (NOFREQ)"); - kprintf(KINFO "Base frequency: %u Hz\n", timer_ctx->base_frequency); + kprintf( + KINFO "hw: %u Hz; os: %u Hz\n", timer_ctx->base_frequency, frequency); timer_ctx->running_frequency = frequency; timer_ctx->tphz = timer_ctx->base_frequency / frequency; // cleanup - intr_unsubscribe(APIC_TIMER_IV, temp_intr_routine_apic_timer); - intr_unsubscribe(RTC_TIMER_IV, temp_intr_routine_rtc_tick); + isrm_ivfree(iv_timer); + isrm_ivfree(iv_rtc); - apic_write_reg(APIC_TIMER_LVT, - LVT_ENTRY_TIMER(APIC_TIMER_IV, LVT_TIMER_PERIODIC)); - intr_subscribe(APIC_TIMER_IV, timer_update); + apic_write_reg( + APIC_TIMER_LVT, + LVT_ENTRY_TIMER(isrm_ivexalloc(timer_update), LVT_TIMER_PERIODIC)); apic_write_reg(APIC_TIMER_ICR, timer_ctx->tphz); @@ -178,7 +189,7 @@ timer_run(ticks_t ticks, void (*callback)(void*), void* payload, uint8_t flags) timer->payload = payload; timer->flags = flags; - llist_append(timer_ctx->active_timers, &timer->link); + llist_append(&timer_ctx->active_timers->link, &timer->link); return timer; }