1 #include <lunaix/types.h>
2 #include <lunaix/mm/mmio.h>
3 #include <asm/soc/gic.h>
5 #include <klibc/string.h>
8 __its_predicate(struct dt_node_iter* iter, struct dtn_base* pos)
10 return strneq(pos->compat.str_val, "arm,gic-v3-its", 14);
14 __do_remap_mmio(struct dtpropx* dtpx, int row)
16 struct dtprop_xval base, size;
18 dtpx_extract_loc(&dtpx, &base, row, 0);
19 dtpx_extract_loc(&dtpx, &size, row, 1);
21 return ioremap(base.u64, size.u64);
25 __remap_mmio_dtn(struct dtn* node)
27 struct dtprop_xval base, size;
29 dt_proplet gic_mmio = dtprop_reglike(&node->base);
31 dtpx_compile_proplet(gic_mmio);
32 dtpx_prepare_with(&dtpx, &node->reg, &gic_mmio);
34 return __do_remap_mmio(&dtpx, 0);
38 __create_its(struct arm_gic* gic, struct dtn* gic_node)
40 struct dt_node* its_node;
43 dt_begin_find(&iter, gic_node, __its_predicate, NULL);
45 while (dt_find_next(&iter, (struct dt_node_base**)&its_node))
47 gic_its_create(gic, __remap_mmio_dtn(its_node));
54 gic_create_from_dt(struct arm_gic* gic, struct dtn* node)
58 dt_proplet gic_mmio = dtprop_reglike(&node->base);
60 dtpx_compile_proplet(gic_mmio);
61 dtpx_prepare_with(&dtpx, &node->reg, &gic_mmio);
63 gic->mmrs.dist_base = (gicreg_t*)__do_remap_mmio(&dtpx, 0);
65 for (int i = 0; i < NR_CPU; i++) {
66 rd = (struct gic_rd*)__do_remap_mmio(&dtpx, i + 1);
70 // ignore cpu_if, as we use sysreg to access them
71 // ignore vcpu_if, as we dont do any EL2 stuff
73 __create_its(gic, node);
77 gic_decode_specifier(struct gic_int_param* param,
78 struct dtp_val* val, int nr_cells)
83 assert(nr_cells >= 3);
84 dtpi_init(&dtpi, val);
86 v = dtpi_next_u32(&dtpi);
90 param->class = GIC_SPI;
93 param->class = GIC_PPI;
96 param->class = GIC_SPI;
97 param->ext_range = true;
100 fail("invalid interrupt type");
104 param->group = GIC_G1NS;
105 param->rel_intid = dtpi_next_u32(&dtpi);
107 v = dtpi_next_u32(&dtpi);
108 param->trigger = v == 1 ? GIC_TRIG_EDGE : GIC_TRIG_LEVEL;
110 // 4th cell only applicable to PPI, ignore for now
112 return param->rel_intid;