add btrie_map() for allocating free slot, remove isrm
[lunaix-os.git] / lunaix-os / arch / x86 / hal / mc146818a.c
index 96b95e175afc19855c12a349560a196d786d6367..d6d931d78081a3ec60348748af80a9e7acac19c1 100644 (file)
  *
  */
 
-#include <lunaix/generic/isrm.h>
 #include <lunaix/mm/valloc.h>
 #include <lunaix/status.h>
 #include <lunaix/hart_state.h>
 
 #include <hal/hwrtc.h>
+#include <hal/irq.h>
 
 #include <klibc/string.h>
 
-#include <sys/port_io.h>
+#include <asm/x86_pmio.h>
 
 #define RTC_INDEX_PORT 0x70
 #define RTC_TARGET_PORT 0x71
 
-#define WITH_NMI_DISABLED 0x80
-
 #define RTC_CURRENT_CENTRY 20
 
 #define RTC_REG_YRS 0x9
 
 struct mc146818
 {
-    struct hwrtc* rtc_context;
-    u32_t rtc_iv;
-    u32_t tick_counts;
+    struct hwrtc_potens* rtc_context;
+    irq_t irq;
 };
 
 #define rtc_state(data) ((struct mc146818*)(data))
 
-static u8_t
+static inline u8_t
 rtc_read_reg(u8_t reg_selector)
 {
     port_wrbyte(RTC_INDEX_PORT, reg_selector);
     return port_rdbyte(RTC_TARGET_PORT);
 }
 
-static void
+static inline void
 rtc_write_reg(u8_t reg_selector, u8_t val)
 {
     port_wrbyte(RTC_INDEX_PORT, reg_selector);
     port_wrbyte(RTC_TARGET_PORT, val);
 }
 
-static void
+static inline void
 rtc_enable_timer()
 {
     u8_t regB = rtc_read_reg(RTC_REG_B);
     rtc_write_reg(RTC_REG_B, regB | RTC_TIMER_ON);
 }
 
-static void
+static inline void
 rtc_disable_timer()
 {
     u8_t regB = rtc_read_reg(RTC_REG_B);
@@ -94,7 +91,7 @@ rtc_disable_timer()
 }
 
 static void
-rtc_getwalltime(struct hwrtc* rtc, datetime_t* datetime)
+rtc_getwalltime(struct hwrtc_potens* rtc, datetime_t* datetime)
 {
     datetime_t current;
 
@@ -116,7 +113,7 @@ rtc_getwalltime(struct hwrtc* rtc, datetime_t* datetime)
 }
 
 static void
-rtc_setwalltime(struct hwrtc* rtc, datetime_t* datetime)
+rtc_setwalltime(struct hwrtc_potens* rtc, datetime_t* datetime)
 {
     u8_t reg = rtc_read_reg(RTC_REG_B);
     reg = reg & ~RTC_SET;
@@ -134,60 +131,46 @@ rtc_setwalltime(struct hwrtc* rtc, datetime_t* datetime)
     rtc_write_reg(RTC_REG_B, reg & ~RTC_SET);
 }
 
-static int
-mc146818_check_support(struct hwrtc* rtc)
-{
-#if __ARCH__ == i386
-    return 1;
-#else
-    return 0;
-#endif
-}
-
 static void
-__rtc_tick(const struct hart_state* hstate)
+__rtc_tick(irq_t irq, const struct hart_state* hstate)
 {
-    struct mc146818* state = (struct mc146818*)isrm_get_payload(hstate);
+    struct mc146818* state;
 
-    state->tick_counts++;
+    state = irq_payload(irq, struct mc146818);
+    state->rtc_context->live++;
 
     (void)rtc_read_reg(RTC_REG_C);
 }
 
 static void
-rtc_set_mask(struct hwrtc* rtc)
+rtc_set_proactive(struct hwrtc_potens* pot, bool proactive)
 {
-    rtc->state = RTC_STATE_MASKED;
-    rtc_disable_timer();
-}
-
-static void
-rtc_cls_mask(struct hwrtc* rtc)
-{
-    struct mc146818* state = rtc_state(rtc->data);
-
-    rtc->state = 0;
-    state->tick_counts = 0;
-    rtc_enable_timer();
+    if (proactive) {
+        pot->state = 0;
+        rtc_enable_timer();
+    }
+    else {
+        pot->state = RTC_STATE_MASKED;
+        rtc_disable_timer();
+    }
 }
 
 static int
-rtc_chfreq(struct hwrtc* rtc, int freq)
+rtc_chfreq(struct hwrtc_potens* rtc, int freq)
 {
     return ENOTSUP;
 }
 
 static int
-rtc_getcnt(struct hwrtc* rtc)
+__rtc_calibrate(struct hwrtc_potens* pot)
 {
-    struct mc146818* state = rtc_state(rtc->data);
-    return state->tick_counts;
-}
+    struct mc146818* state;
+    struct device* rtc_dev;
+    u8_t reg;
 
-static int
-rtc_init(struct device_def* devdef)
-{
-    u8_t reg = rtc_read_reg(RTC_REG_A);
+    rtc_dev = potens_dev(pot);
+
+    reg = rtc_read_reg(RTC_REG_A);
     reg = (reg & ~0x7f) | RTC_FREQUENCY_1024HZ | RTC_DIVIDER_33KHZ;
     rtc_write_reg(RTC_REG_A, reg);
 
@@ -197,31 +180,52 @@ rtc_init(struct device_def* devdef)
     // Make sure the rtc timer is disabled by default
     rtc_disable_timer();
 
-    struct hwrtc* rtc = hwrtc_alloc_new("mc146818");
-    struct mc146818* state = valloc(sizeof(struct mc146818));
+    pot->base_freq = RTC_TIMER_BASE_FREQUENCY;
+
+    state = (struct mc146818*)rtc_dev->underlay;
+
+    state->irq = irq_declare_line(__rtc_tick, PC_AT_IRQ_RTC, NULL);
+    irq_set_payload(state->irq, state);
+
+    irq_assign(irq_owning_domain(rtc_dev), state->irq);
+
+    return 0;
+}
+
+static struct hwrtc_potens_ops ops = {
+    .get_walltime  = rtc_getwalltime,
+    .set_walltime  = rtc_setwalltime,
+    .set_proactive = rtc_set_proactive,
+    .chfreq = rtc_chfreq,
+    .calibrate = __rtc_calibrate
+};
+
+static int
+rtc_load(struct device_def* devdef)
+{
+    struct device* dev;
+    struct mc146818* state;
+    struct hwrtc_potens* pot;
+    state = valloc(sizeof(struct mc146818));
+    dev = device_allocsys(NULL, state);
 
-    state->rtc_context = rtc;
-    state->rtc_iv = isrm_bindirq(PC_AT_IRQ_RTC, __rtc_tick);
-    isrm_set_payload(state->rtc_iv, (ptr_t)state);
+    pot = hwrtc_attach_potens(dev, &ops);
+    if (!pot) {
+        return 1;
+    }
 
-    rtc->state = RTC_STATE_MASKED;
-    rtc->data = state;
-    rtc->base_freq = RTC_TIMER_BASE_FREQUENCY;
-    rtc->get_walltime = rtc_getwalltime;
-    rtc->set_walltime = rtc_setwalltime;
-    rtc->set_mask = rtc_set_mask;
-    rtc->cls_mask = rtc_cls_mask;
-    rtc->get_counts = rtc_getcnt;
-    rtc->chfreq = rtc_chfreq;
+    pot->state = RTC_STATE_MASKED;    
+    state->rtc_context = pot;
 
-    hwrtc_register(&devdef->class, rtc);
+    register_device(dev, &devdef->class, "mc146818");
 
     return 0;
 }
 
 static struct device_def devrtc_mc146818 = {
-    .name = "MC146818 RTC",
-    .class = DEVCLASS(DEVIF_SOC, DEVFN_TIME, DEV_RTC),
-    .init = rtc_init
+    def_device_class(INTEL, TIME, RTC),
+    def_device_name("x86 legacy RTC"),
+    def_on_load(rtc_load)
 };
-EXPORT_DEVICE(mc146818, &devrtc_mc146818, load_timedev);
\ No newline at end of file
+EXPORT_DEVICE(mc146818, &devrtc_mc146818, load_sysconf);
\ No newline at end of file