Decoupling Architectural-specific Code (#35)
[lunaix-os.git] / lunaix-os / hal / timer / apic_timer.c
diff --git a/lunaix-os/hal/timer/apic_timer.c b/lunaix-os/hal/timer/apic_timer.c
deleted file mode 100644 (file)
index e195f34..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-#include <hal/apic_timer.h>
-#include <hal/hwrtc.h>
-#include <hal/hwtimer.h>
-
-#include <lunaix/compiler.h>
-#include <lunaix/isrm.h>
-#include <lunaix/spike.h>
-#include <lunaix/syslog.h>
-
-#include <sys/apic.h>
-
-LOG_MODULE("APIC_TIMER")
-
-#define LVT_ENTRY_TIMER(vector, mode) (LVT_DELIVERY_FIXED | mode | vector)
-#define APIC_BASETICKS 0x100000
-
-// Don't optimize them! Took me an half hour to figure that out...
-
-static volatile u8_t apic_timer_done = 0;
-static volatile ticks_t base_freq = 0;
-static volatile ticks_t systicks = 0;
-
-static timer_tick_cb tick_cb = NULL;
-
-static void
-temp_intr_routine_apic_timer(const isr_param* param)
-{
-    apic_timer_done = 1;
-}
-
-static void
-apic_timer_tick_isr(const isr_param* param)
-{
-    systicks++;
-
-    if (likely((ptr_t)tick_cb)) {
-        tick_cb();
-    }
-}
-
-static int
-apic_timer_check(struct hwtimer* hwt)
-{
-    // TODO check whether apic timer is supported
-    return 1;
-}
-
-static ticks_t
-apic_get_systicks()
-{
-    return systicks;
-}
-
-static ticks_t
-apic_get_base_freq()
-{
-    return base_freq;
-}
-
-void
-apic_timer_init(struct hwtimer* timer, u32_t hertz, timer_tick_cb timer_cb)
-{
-    ticks_t frequency = hertz;
-    tick_cb = timer_cb;
-
-    cpu_disable_interrupt();
-
-    // 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
-    u32_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(iv_timer, LVT_TIMER_ONESHOT));
-
-    // Set divider to 64
-    apic_write_reg(APIC_TIMER_DCR, APIC_TIMER_DIV64);
-
-    /*
-        Timer calibration process - measure the APIC timer base frequency
-
-         step 1: setup a temporary isr for RTC timer which trigger at each tick
-                 (1024Hz)
-         step 2: setup a temporary isr for #APIC_TIMER_IV
-         step 3: setup the divider, APIC_TIMER_DCR
-         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.
-
-        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
-       RTC interrupts should be blocked by local APIC as we are currently busy
-       on handling #APIC_TIMER_IV)
-
-        So the apic timer frequency F_apic in Hz can be calculate as
-            v / F_apic = k / 1024
-            =>  F_apic = v / k * 1024
-
-    */
-
-#ifdef __LUNAIXOS_DEBUG__
-    if (frequency < 1000) {
-        kprintf(KWARN "Frequency too low. Millisecond timer might be dodgy.");
-    }
-#endif
-
-    apic_timer_done = 0;
-
-    primary_rtc->cls_mask(primary_rtc);
-    apic_write_reg(APIC_TIMER_ICR, APIC_BASETICKS); // start APIC timer
-
-    // enable interrupt, just for our RTC start ticking!
-    cpu_enable_interrupt();
-
-    wait_until(apic_timer_done);
-
-    cpu_disable_interrupt();
-
-    primary_rtc->set_mask(primary_rtc);
-
-    base_freq = primary_rtc->get_counts(primary_rtc);
-    base_freq = APIC_BASETICKS / base_freq * primary_rtc->base_freq;
-
-    assert_msg(base_freq, "Fail to initialize timer (NOFREQ)");
-
-    kprintf(KINFO "hw: %u Hz; os: %u Hz\n", base_freq, frequency);
-
-    // cleanup
-    isrm_ivfree(iv_timer);
-
-    apic_write_reg(
-      APIC_TIMER_LVT,
-      LVT_ENTRY_TIMER(isrm_ivexalloc(apic_timer_tick_isr), LVT_TIMER_PERIODIC));
-
-    timer->base_freq = base_freq;
-
-    ticks_t tphz = base_freq / frequency;
-    apic_write_reg(APIC_TIMER_ICR, tphz);
-}
-
-struct hwtimer*
-apic_hwtimer_context()
-{
-    static struct hwtimer apic_hwt = {
-        .name = "apic_timer",
-        .class = DEVCLASSV(DEVIF_SOC, DEVFN_TIME, DEV_TIMER, DEV_TIMER_APIC),
-        .init = apic_timer_init,
-        .supported = apic_timer_check,
-        .systicks = apic_get_systicks
-    };
-
-    return &apic_hwt;
-}