add support to GIC ITS, and the MSI service base on it
[lunaix-os.git] / lunaix-os / arch / aarch64 / soc / gic / gic_dt.c
index 863aa039650b7e1d1b41278500f0fbb3ac2cc9e6..cce0411ac435864e330de35a66d51fce946f581b 100644 (file)
@@ -1,4 +1,5 @@
 #include <lunaix/types.h>
+#include <lunaix/mm/mmio.h>
 #include <asm/soc/gic.h>
 
 #include <klibc/string.h>
@@ -20,25 +21,15 @@ __its_predicate(struct dt_node_iter* iter, struct dt_node_base* pos)
 }
 
 static void
-__setup_pe_rdist(struct arm_gic* gic, struct dt_prop_iter* prop)
+__setup_pe_rdist(struct arm_gic* gic, struct dt_prop_iter* prop, int cpu)
 {
     ptr_t base;
-    size_t len, off;
-    int i;
+    size_t len;
 
     base = dtprop_reg_nextaddr(prop);
     len  = dtprop_reg_nextlen(prop);
 
-    assert(len >= NR_CPU * FRAME_SIZE * 2);
-
-    i = 0;
-    base = ioremap(base, len);
-    off = base;
-
-    for (; i < NR_CPU; i++) {
-        gic->pes[i]._rd = (struct gic_rd*) (base + off);
-        off += sizeof(struct gic_rd);
-    }
+    gic->pes[cpu]._rd = (struct gic_rd*)ioremap(base, len);
 }
 
 static void
@@ -47,25 +38,24 @@ __create_its(struct arm_gic* gic, struct dt_node* gic_node)
     struct dt_node* its_node;
     struct dt_node_iter iter;
     struct dt_prop_iter prop;
+    struct gic_its* its;
     ptr_t its_base;
     size_t its_size;
 
     dt_begin_find(&iter, gic_node, __its_predicate, NULL);
 
-    if (!dt_find_next(&iter, (struct dt_node_base**)&its_node)) {
-        return;
-    }
-
-    dt_end_find(&iter);
-
-    dt_decode_reg(&prop, its_node, reg);
-
-    its_base = dtprop_reg_nextaddr(&prop);
-    its_size = dtprop_reg_nextlen(&prop);
+    while (dt_find_next(&iter, (struct dt_node_base**)&its_node))
+    {
+        dt_decode_reg(&prop, its_node, reg);
 
-    assert(its_size >= sizeof(struct gic_its));
+        its_base = dtprop_reg_nextaddr(&prop);
+        its_size = dtprop_reg_nextlen(&prop);
 
-    gic->mmrs.its = (struct gic_its*)ioremap(its_base, its_size);
+        its = gic_its_create(gic, ioremap(its_base, its_size));
+        dt_bind_object(&its_node->base, its);    
+    }
+    
+    dt_end_find(&iter);
 }
 
 void
@@ -91,11 +81,11 @@ gic_create_from_dt(struct arm_gic* gic)
     sz  = dtprop_reg_nextlen(&prop);
     gic->mmrs.dist_base = (gicreg_t*)ioremap(ptr, sz);
 
-    __setup_pe_rdist(gic, &prop);
-    
-    // ignore cpu_if, as we use sysreg to access them
-    dtprop_next_n(&prop, 2);
+    for (int i = 0; i < NR_CPU; i++) {
+        __setup_pe_rdist(gic, &prop, i);
+    }
     
+    // ignore cpu_if, as we use sysreg to access them    
     // ignore vcpu_if, as we dont do any EL2 stuff
 
     __create_its(gic, gic_node);
@@ -107,10 +97,10 @@ unsigned int;
 gic_dtprop_interpret(struct gic_int_param* param, 
                      struct dt_prop_val* val, int width)
 {
-    struct dt_prop_iter* iter;
+    struct dt_prop_iter iter;
     unsigned int v;
 
-    dt_decode(&iter, NULL, val, 1);
+    dt_decode_simple(&iter, val);
 
     v = dtprop_u32_at(&iter, 0);
     switch (v)