feat: lunadbg GDB plugin to ease kernel debugging process.
[lunaix-os.git] / lunaix-os / kernel / time / timer.c
index f479f581a34f6849593824bdb5dc1d37f4bcb59e..e48c40cd5c4a42a1028ba3748260eaee03e5e4c8 100644 (file)
@@ -9,9 +9,7 @@
  * @copyright Copyright (c) 2022
  *
  */
  * @copyright Copyright (c) 2022
  *
  */
-#include <arch/x86/interrupts.h>
-#include <hal/apic.h>
-#include <hal/rtc.h>
+#include <sys/interrupts.h>
 
 #include <lunaix/mm/cake.h>
 #include <lunaix/mm/valloc.h>
 
 #include <lunaix/mm/cake.h>
 #include <lunaix/mm/valloc.h>
 #include <lunaix/syslog.h>
 #include <lunaix/timer.h>
 
 #include <lunaix/syslog.h>
 #include <lunaix/timer.h>
 
-#define LVT_ENTRY_TIMER(vector, mode) (LVT_DELIVERY_FIXED | mode | vector)
+#include <hal/hwtimer.h>
 
 LOG_MODULE("TIMER");
 
 static void
 
 LOG_MODULE("TIMER");
 
 static void
-temp_intr_routine_rtc_tick(const isr_param* param);
-
-static void
-temp_intr_routine_apic_timer(const isr_param* param);
-
-static void
-timer_update(const isr_param* param);
+timer_update();
 
 static volatile struct lx_timer_context* timer_ctx = NULL;
 
 
 static volatile struct lx_timer_context* timer_ctx = NULL;
 
-// Don't optimize them! Took me an half hour to figure that out...
-
-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;
+static volatile u32_t sched_ticks = 0;
+static volatile u32_t sched_ticks_counter = 0;
 
 static struct cake_pile* timer_pile;
 
 
 static struct cake_pile* timer_pile;
 
-#define APIC_CALIBRATION_CONST 0x100000
-
 void
 timer_init_context()
 {
 void
 timer_init_context()
 {
@@ -57,115 +42,44 @@ timer_init_context()
     assert_msg(timer_ctx, "Fail to initialize timer contex");
 
     timer_ctx->active_timers = (struct lx_timer*)cake_grab(timer_pile);
     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
 }
 
 void
-timer_init(uint32_t frequency)
+timer_init()
 {
     timer_init_context();
 
 {
     timer_init_context();
 
-    cpu_disable_interrupt();
-
-    // 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
-    apic_write_reg(APIC_TIMER_LVT,
-                   LVT_ENTRY_TIMER(APIC_TIMER_IV, 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
-
-    timer_ctx->base_frequency = 0;
-    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
-
-    // enable interrupt, just for our RTC start ticking!
-    cpu_enable_interrupt();
+    hwtimer_init(SYS_TIMER_FREQUENCY_HZ, timer_update);
 
 
-    wait_until(apic_timer_done);
+    timer_ctx->base_frequency = hwtimer_base_frequency();
 
 
-    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->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);
-
-    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_ICR, timer_ctx->tphz);
-
-    sched_ticks = timer_ctx->running_frequency / 1000 * SCHED_TIME_SLICE;
+    sched_ticks = (SYS_TIMER_FREQUENCY_HZ * SCHED_TIME_SLICE) / 1000;
     sched_ticks_counter = 0;
 }
 
 struct lx_timer*
     sched_ticks_counter = 0;
 }
 
 struct lx_timer*
-timer_run_second(uint32_t second,
+timer_run_second(u32_t second,
                  void (*callback)(void*),
                  void* payload,
                  void (*callback)(void*),
                  void* payload,
-                 uint8_t flags)
+                 u8_t flags)
 {
 {
-    return timer_run(
-      second * timer_ctx->running_frequency, callback, payload, flags);
+    ticks_t t = hwtimer_to_ticks(second, TIME_SEC);
+    return timer_run(t, callback, payload, flags);
 }
 
 struct lx_timer*
 }
 
 struct lx_timer*
-timer_run_ms(uint32_t millisecond,
+timer_run_ms(u32_t millisecond,
              void (*callback)(void*),
              void* payload,
              void (*callback)(void*),
              void* payload,
-             uint8_t flags)
+             u8_t flags)
 {
 {
-    return timer_run(timer_ctx->running_frequency / 1000 * millisecond,
-                     callback,
-                     payload,
-                     flags);
+    ticks_t t = hwtimer_to_ticks(millisecond, TIME_MS);
+    return timer_run(t, callback, payload, flags);
 }
 
 struct lx_timer*
 }
 
 struct lx_timer*
-timer_run(ticks_t ticks, void (*callback)(void*), void* payload, uint8_t flags)
+timer_run(ticks_t ticks, void (*callback)(void*), void* payload, u8_t flags)
 {
     struct lx_timer* timer = (struct lx_timer*)cake_grab(timer_pile);
 
 {
     struct lx_timer* timer = (struct lx_timer*)cake_grab(timer_pile);
 
@@ -178,13 +92,13 @@ timer_run(ticks_t ticks, void (*callback)(void*), void* payload, uint8_t flags)
     timer->payload = payload;
     timer->flags = 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;
 }
 
 static void
 
     return timer;
 }
 
 static void
-timer_update(const isr_param* param)
+timer_update()
 {
     struct lx_timer *pos, *n;
     struct lx_timer* timer_list_head = timer_ctx->active_timers;
 {
     struct lx_timer *pos, *n;
     struct lx_timer* timer_list_head = timer_ctx->active_timers;
@@ -213,34 +127,8 @@ timer_update(const isr_param* param)
     }
 }
 
     }
 }
 
-void
-sched_yield()
-{
-    sched_ticks_counter = sched_ticks;
-}
-
-static void
-temp_intr_routine_rtc_tick(const isr_param* param)
-{
-    rtc_counter++;
-
-    // dummy read on register C so RTC can send anther interrupt
-    //  This strange behaviour observed in virtual box & bochs
-    (void)rtc_read_reg(RTC_REG_C);
-}
-
-static void
-temp_intr_routine_apic_timer(const isr_param* param)
-{
-    timer_ctx->base_frequency =
-      APIC_CALIBRATION_CONST / rtc_counter * RTC_TIMER_BASE_FREQUENCY;
-    apic_timer_done = 1;
-
-    rtc_disable_timer();
-}
-
 struct lx_timer_context*
 timer_context()
 {
 struct lx_timer_context*
 timer_context()
 {
-    return timer_ctx;
+    return (struct lx_timer_context*)timer_ctx;
 }
\ No newline at end of file
 }
\ No newline at end of file