1 #include <lunaix/types.h>
2 #include <asm/soc/gic.h>
4 #include <klibc/string.h>
7 __gic_predicate(struct dt_node_iter* iter, struct dt_node_base* pos)
9 if (likely(!pos->intr_controll)) {
13 return strneq(pos->compat.str_val, "arm,gic-", 8);
17 __its_predicate(struct dt_node_iter* iter, struct dt_node_base* pos)
19 return strneq(pos->compat.str_val, "arm,gic-v3-its", 14);
23 __setup_pe_rdist(struct arm_gic* gic, struct dt_prop_iter* prop)
29 base = dtprop_reg_nextaddr(prop);
30 len = dtprop_reg_nextlen(prop);
32 assert(len >= NR_CPU * FRAME_SIZE * 2);
35 base = ioremap(base, len);
38 for (; i < NR_CPU; i++) {
39 gic->pes[i]._rd = (struct gic_rd*) (base + off);
40 off += sizeof(struct gic_rd);
45 __create_its(struct arm_gic* gic, struct dt_node* gic_node)
47 struct dt_node* its_node;
48 struct dt_node_iter iter;
49 struct dt_prop_iter prop;
53 dt_begin_find(&iter, gic_node, __its_predicate, NULL);
55 if (!dt_find_next(&iter, (struct dt_node_base**)&its_node)) {
61 dt_decode_reg(&prop, its_node, reg);
63 its_base = dtprop_reg_nextaddr(&prop);
64 its_size = dtprop_reg_nextlen(&prop);
66 assert(its_size >= sizeof(struct gic_its));
68 gic->mmrs.its = (struct gic_its*)ioremap(its_base, its_size);
72 gic_create_from_dt(struct arm_gic* gic)
74 struct dt_node* gic_node;
75 struct dt_node_iter iter;
76 struct dt_prop_iter prop;
80 dt_begin_find(&iter, NULL, __gic_predicate, NULL);
82 if (!dt_find_next(&iter, (struct dt_node_base**)&gic_node)) {
83 fail("expected 'arm,gic-*' compatible node, but found none");
88 dt_decode_reg(&prop, gic_node, reg);
90 ptr = dtprop_reg_nextaddr(&prop);
91 sz = dtprop_reg_nextlen(&prop);
92 gic->mmrs.dist_base = (gicreg_t*)ioremap(ptr, sz);
94 __setup_pe_rdist(gic, &prop);
96 // ignore cpu_if, as we use sysreg to access them
97 dtprop_next_n(&prop, 2);
99 // ignore vcpu_if, as we dont do any EL2 stuff
101 __create_its(gic, gic_node);
103 dt_bind_object(&gic_node->base, gic);
107 gic_dtprop_interpret(struct gic_int_param* param,
108 struct dt_prop_val* val, int width)
110 struct dt_prop_iter* iter;
113 dt_decode(&iter, NULL, val, 1);
115 v = dtprop_u32_at(&iter, 0);
119 param->class = GIC_SPI;
122 param->class = GIC_PPI;
125 param->class = GIC_SPI;
126 param->ext_range = true;
129 fail("invalid interrupt type");
133 v = dtprop_u32_at(&iter, 2);
134 param->trigger = v == 1 ? GIC_TRIG_EDGE : GIC_TRIG_LEVEL;
136 param->group = GIC_G1NS;
137 param->rel_intid = dtprop_u32_at(&iter, 1);
139 return param->rel_intid;