move gic to new devtree interface
[lunaix-os.git] / lunaix-os / arch / aarch64 / soc / gic / gic_dt.c
1 #include <lunaix/types.h>
2 #include <lunaix/mm/mmio.h>
3 #include <asm/soc/gic.h>
4
5 #include <klibc/string.h>
6
7 static bool
8 __its_predicate(struct dt_node_iter* iter, struct dtn_base* pos)
9 {
10     return strneq(pos->compat.str_val, "arm,gic-v3-its", 14);
11 }
12
13 static inline void*
14 __do_remap_mmio(struct dtpropx* dtpx, int row)
15 {
16     struct dtprop_xval base, size;
17
18     dtpx_extract_loc(&dtpx, &base, row, 0);
19     dtpx_extract_loc(&dtpx, &size, row, 1);
20
21     return ioremap(base.u64, size.u64);
22 }
23
24 static inline void*
25 __remap_mmio_dtn(struct dtn* node)
26 {
27     struct dtprop_xval base, size;
28     struct dtpropx dtpx;
29     dt_proplet gic_mmio =  dtprop_reglike(&node->base);
30
31     dtpx_compile_proplet(gic_mmio);
32     dtpx_prepare_with(&dtpx, &node->reg, &gic_mmio);
33
34     return __do_remap_mmio(&dtpx, 0);
35 }
36
37 static void
38 __create_its(struct arm_gic* gic, struct dtn* gic_node)
39 {
40     struct dt_node* its_node;
41     struct dtn_iter iter;
42
43     dt_begin_find(&iter, gic_node, __its_predicate, NULL);
44
45     while (dt_find_next(&iter, (struct dt_node_base**)&its_node))
46     {
47         gic_its_create(gic, __remap_mmio_dtn(its_node));
48     }
49     
50     dt_end_find(&iter);
51 }
52
53 void
54 gic_create_from_dt(struct arm_gic* gic, struct dtn* node)
55 {
56     struct dtpropx dtpx;
57     struct gic_rd* rd;
58     dt_proplet gic_mmio =  dtprop_reglike(&node->base);
59
60     dtpx_compile_proplet(gic_mmio);
61     dtpx_prepare_with(&dtpx, &node->reg, &gic_mmio);
62
63     gic->mmrs.dist_base = (gicreg_t*)__do_remap_mmio(&dtpx, 0);
64
65     for (int i = 0; i < NR_CPU; i++) {
66         rd = (struct gic_rd*)__do_remap_mmio(&dtpx, i + 1);
67         gic->pes[i]._rd = rd;
68     }
69     
70     // ignore cpu_if, as we use sysreg to access them    
71     // ignore vcpu_if, as we dont do any EL2 stuff
72
73     __create_its(gic, node);
74 }
75
76 unsigned int;
77 gic_decode_specifier(struct gic_int_param* param, 
78                      struct dtp_val* val, int nr_cells)
79 {
80     struct dtpropi dtpi;
81     unsigned int v;
82
83     assert(nr_cells >= 3);
84     dtpi_init(&dtpi, val);
85
86     v = dtpi_next_u32(&dtpi);
87     switch (v)
88     {
89     case 0:
90         param->class = GIC_SPI;
91         break;
92     case 1:
93         param->class = GIC_PPI;
94         break;
95     case 2:
96         param->class = GIC_SPI;
97         param->ext_range = true;
98     
99     default:
100         fail("invalid interrupt type");
101         break;
102     }
103
104     param->group = GIC_G1NS;
105     param->rel_intid = dtpi_next_u32(&dtpi);
106     
107     v = dtpi_next_u32(&dtpi);
108     param->trigger = v == 1 ? GIC_TRIG_EDGE : GIC_TRIG_LEVEL;
109
110     // 4th cell only applicable to PPI, ignore for now
111
112     return param->rel_intid;
113 }