move gic to new devtree interface
[lunaix-os.git] / lunaix-os / arch / aarch64 / soc / gic / gic.c
index 59905e83053ee9496c56b0c45920955dd9da95ac..d374a8e4de92913093b04563c8e6fc34a6b22240 100644 (file)
@@ -7,8 +7,8 @@
 #include <lunaix/syslog.h>
 
 #include <hal/devtree.h>
+#include <hal/devtreem.h>
 
-#include <asm/aa64_isrm.h>
 #include <asm/soc/gic.h>
 
 static struct arm_gic gic;
@@ -529,178 +529,38 @@ gic_signal_eoi()
     set_sysreg(ICC_EOIR1_EL1, pe->iar_val);
 }
 
-/* ****** Lunaix ISRM Interfacing ****** */
-
-void
-isrm_init()
-{
-    // nothing to do
-}
-
-void
-isrm_ivfree(int iv)
-{
-    struct gic_interrupt* ent;
-    struct gic_distributor* dist;
-    
-    ent  = __find_interrupt_record(iv);
-    if (!ent) {
-        return;
-    }
-
-    dist = __attached_distributor(0, ent);
-    __undone_interrupt(&gic, dist, ent);
-
-    hlist_delete(&ent->node);
-    vfree(ent);
-}
-
-int
-isrm_ivosalloc(isr_cb handler)
+struct arm_gic*
+gic_instance()
 {
-    return isrm_ivexalloc(handler);
+    return &gic;
 }
 
-int
-isrm_ivexalloc(isr_cb handler)
-{
-    struct gic_int_param param;
-    struct gic_interrupt* intr;
-
-    param = (struct gic_int_param) {
-        .class = GIC_SPI,
-        .group = GIC_G1NS,
-        .trigger = GIC_TRIG_EDGE,
-    };
-
-    intr = gic_install_int(&param, handler, true);
-    
-    return intr->intid;
-}
-
-isr_cb
-isrm_get(int iv)
-{
-    struct gic_interrupt* intr;
-
-    intr = __find_interrupt_record(iv);
-    if (!intr) {
-        return NULL;
-    }
-
-    return intr->handler;
-}
-
-ptr_t
-isrm_get_payload(const struct hart_state* state)
-{
-    struct gic_interrupt* active;
-
-    active = gic.pes[0].active;
-    assert(active);
-
-    return active->handler;
-}
-
-void
-isrm_set_payload(int iv, ptr_t payload)
-{
-    struct gic_interrupt* intr;
-
-    intr = __find_interrupt_record(iv);
-    if (!intr) {
-        return NULL;
-    }
-
-    intr->payload = payload;
-}
-
-void
-isrm_notify_eoi(cpu_t id, int iv)
-{
-    gic_signal_eoi();
-}
-
-void
-isrm_notify_eos(cpu_t id)
-{
-    isrm_notify_eoi(id, 0);
-}
+/* ****** Device Definition & Export ****** */
 
-msi_vector_t
-isrm_msialloc(isr_cb handler)
+static void
+gic_register(struct device_def* def)
 {
-    int intid;
-    msi_vector_t msiv;
-    struct gic_int_param param;
-
-    param = (struct gic_int_param) {
-        .group = GIC_G1NS,
-        .trigger = GIC_TRIG_EDGE
-    };
-
-    if (gic.msi_via_spi) {
-        param.class = GIC_SPI;
-
-        intid = gic_install_int(&param, handler, true);
-        msiv.msi_addr  = gic_regptr(gic.mmrs.dist_base, GICD_SETSPI_NSR);
-        goto done;
-    }
-    
-    if (unlikely(!gic.lpi_ready)) {
-        return invalid_msi_vector;
-    }
-
-    if (unlikely(llist_empty(&gic.its))) {
-        // FIXME The MSI interface need rework
-        WARN("ITS-base MSI is yet unsupported.");
-        return invalid_msi_vector;
-    }
-
-    param.class = GIC_LPI;
-    intid = gic_install_int(&param, handler, true);
-    msiv.msi_addr = gic_regptr(gic.pes[0]._rd->base, GICR_SETLPIR);
+    dtm_register_entry(def, "arm,gic-v3");
 
-done:
-    msiv.mapped_iv = intid;
-    msiv.msi_data  = intid;
+    // TODO need to re-exam the programming model for gic v1,v2
+    // dtm_register_entry(def, "arm,cortex-a*-gic");
+    // dtm_register_entry(def, "arm,gic-400");
 
-    return msiv;
+    memset(&gic, 0, sizeof(gic));
 }
 
-int
-isrm_bind_dtnode(struct dt_intr_node* node, isr_cb handler)
+static void
+gic_init(struct device_def* def, morph_t* mobj)
 {
-    struct dt_prop_val* val;
-    struct gic_int_param param;
-    struct gic_interrupt* installed;
-
-    val = dt_resolve_interrupt(INTR_TO_DTNODE(node));
-    if (!val) {
-        return EINVAL;
-    }
+    struct dtn* node;
+    struct device* gic_dev;
 
-    if (node->intr.extended) {
-        WARN("binding of multi interrupt is yet to supported");
-        return EINVAL;
+    node = changeling_try_reveal(mobj, dt_morpher);
+    if (!node) {
+        return;
     }
 
-    gic_dtprop_interpret(&param, val, 3);
-    param.cpu_id = 0;
-
-    installed = gic_install_int(&param, handler, false);
-
-    return installed->intid;
-}
-
-/* ****** Device Definition & Export ****** */
-
-static void
-gic_init()
-{
-    memset(&gic, 0, sizeof(gic));
-
-    gic_create_from_dt(&gic);
+    gic_create_from_dt(&gic, node);
 
     // configure the system interfaces
     gic_configure_icc();
@@ -714,12 +574,17 @@ gic_init()
         gic_configure_pe(&gic, &gic.pes[i]);
     }
 
+    gic_dev = device_allocsys(NULL, &gic);
+    register_device_var(gic_dev, &def->class, "gic");
+    
     gic_configure_its(&gic);
 }
 
 static struct device_def dev_arm_gic = {
-    .name = "ARM Generic Interrupt Controller",
-    .class = DEVCLASS(DEVIF_SOC, DEVFN_CFG, DEV_INTC),
-    .init = gic_init
+    def_device_name("ARM Generic Interrupt Controller"),
+    def_device_class(ARM, CFG, INTC),
+
+    def_on_register(gic_register),
+    def_on_create(gic_init)
 };
 EXPORT_DEVICE(arm_gic, &dev_arm_gic, load_sysconf);
\ No newline at end of file