From: Lunaixsky Date: Sat, 14 Dec 2024 14:12:01 +0000 (+0000) Subject: move gic to new devtree interface X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/commitdiff_plain/refs/heads/arm64-irq-premerge?ds=sidebyside move gic to new devtree interface --- diff --git a/lunaix-os/arch/aarch64/includes/asm/aa64_isrm.h b/lunaix-os/arch/aarch64/includes/asm/aa64_isrm.h deleted file mode 100644 index 2ab1367..0000000 --- a/lunaix-os/arch/aarch64/includes/asm/aa64_isrm.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __LUNAIX_AA64_ISRM_H -#define __LUNAIX_AA64_ISRM_H - -#include -#include "soc/gic.h" - -unsigned int -aa64_isrm_ivalloc(struct gic_int_param* ivcfg, isr_cb handler); - -#endif /* __LUNAIX_AA64_ISRM_H */ diff --git a/lunaix-os/arch/aarch64/includes/asm/soc/gic.h b/lunaix-os/arch/aarch64/includes/asm/soc/gic.h index 840700d..ee86965 100644 --- a/lunaix-os/arch/aarch64/includes/asm/soc/gic.h +++ b/lunaix-os/arch/aarch64/includes/asm/soc/gic.h @@ -266,11 +266,11 @@ struct arm_gic }; void -gic_create_from_dt(struct arm_gic* gic); +gic_create_from_dt(struct arm_gic* gic, struct dtn* node); unsigned int; -gic_dtprop_interpret(struct gic_int_param* param, - struct dt_prop_val* val, int width); +gic_decode_specifier(struct gic_int_param* param, + struct dtp_val* val, int nr_cells); struct gic_its* gic_its_create(struct arm_gic* gic, ptr_t regs); diff --git a/lunaix-os/arch/aarch64/soc/gic/gic.c b/lunaix-os/arch/aarch64/soc/gic/gic.c index 59905e8..d374a8e 100644 --- a/lunaix-os/arch/aarch64/soc/gic/gic.c +++ b/lunaix-os/arch/aarch64/soc/gic/gic.c @@ -7,8 +7,8 @@ #include #include +#include -#include #include 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(¶m, 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(¶m, 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(¶m, 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(¶m, val, 3); - param.cpu_id = 0; - - installed = gic_install_int(¶m, 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 diff --git a/lunaix-os/arch/aarch64/soc/gic/gic_dt.c b/lunaix-os/arch/aarch64/soc/gic/gic_dt.c index cce0411..802f097 100644 --- a/lunaix-os/arch/aarch64/soc/gic/gic_dt.c +++ b/lunaix-os/arch/aarch64/soc/gic/gic_dt.c @@ -5,104 +5,85 @@ #include static bool -__gic_predicate(struct dt_node_iter* iter, struct dt_node_base* pos) +__its_predicate(struct dt_node_iter* iter, struct dtn_base* pos) { - if (likely(!pos->intr_controll)) { - return false; - } - - return strneq(pos->compat.str_val, "arm,gic-", 8); + return strneq(pos->compat.str_val, "arm,gic-v3-its", 14); } -static bool -__its_predicate(struct dt_node_iter* iter, struct dt_node_base* pos) +static inline void* +__do_remap_mmio(struct dtpropx* dtpx, int row) { - return strneq(pos->compat.str_val, "arm,gic-v3-its", 14); + struct dtprop_xval base, size; + + dtpx_extract_loc(&dtpx, &base, row, 0); + dtpx_extract_loc(&dtpx, &size, row, 1); + + return ioremap(base.u64, size.u64); } -static void -__setup_pe_rdist(struct arm_gic* gic, struct dt_prop_iter* prop, int cpu) +static inline void* +__remap_mmio_dtn(struct dtn* node) { - ptr_t base; - size_t len; + struct dtprop_xval base, size; + struct dtpropx dtpx; + dt_proplet gic_mmio = dtprop_reglike(&node->base); - base = dtprop_reg_nextaddr(prop); - len = dtprop_reg_nextlen(prop); + dtpx_compile_proplet(gic_mmio); + dtpx_prepare_with(&dtpx, &node->reg, &gic_mmio); - gic->pes[cpu]._rd = (struct gic_rd*)ioremap(base, len); + return __do_remap_mmio(&dtpx, 0); } static void -__create_its(struct arm_gic* gic, struct dt_node* gic_node) +__create_its(struct arm_gic* gic, struct dtn* 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; + struct dtn_iter iter; dt_begin_find(&iter, gic_node, __its_predicate, NULL); while (dt_find_next(&iter, (struct dt_node_base**)&its_node)) { - dt_decode_reg(&prop, its_node, reg); - - its_base = dtprop_reg_nextaddr(&prop); - its_size = dtprop_reg_nextlen(&prop); - - its = gic_its_create(gic, ioremap(its_base, its_size)); - dt_bind_object(&its_node->base, its); + gic_its_create(gic, __remap_mmio_dtn(its_node)); } dt_end_find(&iter); } void -gic_create_from_dt(struct arm_gic* gic) +gic_create_from_dt(struct arm_gic* gic, struct dtn* node) { - struct dt_node* gic_node; - struct dt_node_iter iter; - struct dt_prop_iter prop; - ptr_t ptr; - size_t sz; + struct dtpropx dtpx; + struct gic_rd* rd; + dt_proplet gic_mmio = dtprop_reglike(&node->base); - dt_begin_find(&iter, NULL, __gic_predicate, NULL); + dtpx_compile_proplet(gic_mmio); + dtpx_prepare_with(&dtpx, &node->reg, &gic_mmio); - if (!dt_find_next(&iter, (struct dt_node_base**)&gic_node)) { - fail("expected 'arm,gic-*' compatible node, but found none"); - } - - dt_end_find(&iter); - - dt_decode_reg(&prop, gic_node, reg); - - ptr = dtprop_reg_nextaddr(&prop); - sz = dtprop_reg_nextlen(&prop); - gic->mmrs.dist_base = (gicreg_t*)ioremap(ptr, sz); + gic->mmrs.dist_base = (gicreg_t*)__do_remap_mmio(&dtpx, 0); for (int i = 0; i < NR_CPU; i++) { - __setup_pe_rdist(gic, &prop, i); + rd = (struct gic_rd*)__do_remap_mmio(&dtpx, i + 1); + gic->pes[i]._rd = rd; } // 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); - - dt_bind_object(&gic_node->base, gic); + __create_its(gic, node); } unsigned int; -gic_dtprop_interpret(struct gic_int_param* param, - struct dt_prop_val* val, int width) +gic_decode_specifier(struct gic_int_param* param, + struct dtp_val* val, int nr_cells) { - struct dt_prop_iter iter; + struct dtpropi dtpi; unsigned int v; - dt_decode_simple(&iter, val); + assert(nr_cells >= 3); + dtpi_init(&dtpi, val); - v = dtprop_u32_at(&iter, 0); + v = dtpi_next_u32(&dtpi); switch (v) { case 0: @@ -120,11 +101,13 @@ gic_dtprop_interpret(struct gic_int_param* param, break; } - v = dtprop_u32_at(&iter, 2); + param->group = GIC_G1NS; + param->rel_intid = dtpi_next_u32(&dtpi); + + v = dtpi_next_u32(&dtpi); param->trigger = v == 1 ? GIC_TRIG_EDGE : GIC_TRIG_LEVEL; - param->group = GIC_G1NS; - param->rel_intid = dtprop_u32_at(&iter, 1); + // 4th cell only applicable to PPI, ignore for now return param->rel_intid; } \ No newline at end of file diff --git a/lunaix-os/hal/bus/pci.c b/lunaix-os/hal/bus/pci.c index 3052a90..9bb8416 100644 --- a/lunaix-os/hal/bus/pci.c +++ b/lunaix-os/hal/bus/pci.c @@ -545,7 +545,7 @@ pci_create(struct device_def* def, morph_t* obj) { devtree_link_t devtree_node; - devtree_node = changeling_try_reveal(obj, dt_node_morpher); + devtree_node = changeling_try_reveal(obj, dt_morpher); pci_bridge = device_allocsys(NULL, NULL); device_set_devtree_node(pci_bridge, devtree_node); diff --git a/lunaix-os/hal/devtree/dt.c b/lunaix-os/hal/devtree/dt.c index a426551..ee68cf6 100644 --- a/lunaix-os/hal/devtree/dt.c +++ b/lunaix-os/hal/devtree/dt.c @@ -759,11 +759,21 @@ dtpx_compile_proplet(struct dtprop_def* proplet) { int i; unsigned int acc = 0; + struct dtprop_def* pl; for (i = 0; proplet[i].type && i < 10; ++i) { - proplet[i].acc_sz = acc; - acc += proplet[i].cell; + pl = &proplet[i]; + + if (pl->type == DTP_COMPX) { + if (pl->cell == 1) + pl->type = DTP_U32; + else if (pl->cell == 2) + pl->type = DTP_U64; + } + + pl->acc_sz = acc; + acc += pl->cell; } if (proplet[i - 1].type && i == 10) { @@ -856,7 +866,9 @@ dtpx_extract_at(struct dtpropx* propx, } break; case DTP_COMPX: - val->composite = enc; + { + val->composite = enc; + } break; default: diff --git a/lunaix-os/hal/devtree/dtm.c b/lunaix-os/hal/devtree/dtm.c index 7bec489..215180a 100644 --- a/lunaix-os/hal/devtree/dtm.c +++ b/lunaix-os/hal/devtree/dtm.c @@ -118,12 +118,12 @@ __try_create_categorical(struct dtn_base *p) return parent; } - if (p->binded_dev) { - cat = changeling_reveal(p->binded_dev, devcat_morpher); + if (p->binded_obj) { + cat = changeling_reveal(p->binded_obj, devcat_morpher); } else { cat = device_addcat(parent, HSTR_VAL(dt_mobj(p)->name)); - p->binded_dev = dev_mobj(cat); + p->binded_obj = dev_mobj(cat); } return dev_meta(cat); diff --git a/lunaix-os/includes/hal/devtree.h b/lunaix-os/includes/hal/devtree.h index e7e0cf3..5578284 100644 --- a/lunaix-os/includes/hal/devtree.h +++ b/lunaix-os/includes/hal/devtree.h @@ -259,7 +259,7 @@ struct dtn_base struct dtp_table *props; - morph_t *binded_dev; + morph_t *binded_obj; }; struct dtspec_key @@ -442,6 +442,12 @@ dtp_val_set(struct dtp_val* val, dt_enc_t raw, unsigned cells) val->size = cells * sizeof(u32_t); } +static inline void +dtn_bind_object(struct dtn* node, morph_t* mobj) +{ + node->base.binded_obj = changeling_ref(mobj); +} + ////////////////////////////////////// /// DT Methods: Specifier Map @@ -589,11 +595,11 @@ struct dtpropx #define dtprop_reglike(base) \ ({ \ dt_proplet p = { \ - dtprop_compx(base->addr_c), \ - dtprop_compx(base->sz_c), \ + dtprop_compx((base)->addr_c), \ + dtprop_compx((base)->sz_c), \ dtprop_end \ }; \ - dt_proplet; \ + p; \ }) #define dtprop_rangelike(node) \ @@ -604,7 +610,7 @@ struct dtpropx dtprop_compx(base->sz_c), \ dtprop_end \ }; \ - dt_proplet; \ + p; \ }) #define dtprop_strlst_foreach(pos, prop) \ diff --git a/lunaix-os/includes/hal/devtreem.h b/lunaix-os/includes/hal/devtreem.h index 2b0904d..2328f36 100644 --- a/lunaix-os/includes/hal/devtreem.h +++ b/lunaix-os/includes/hal/devtreem.h @@ -13,8 +13,6 @@ struct device; typedef struct dtn* devtree_link_t; -#define dt_node_morpher morphable_attrs(dt_node, mobj) - struct dtm_driver_info { struct list_node node; diff --git a/lunaix-os/tests/units/btrie/alloc.test b/lunaix-os/tests/units/btrie/alloc.test new file mode 100755 index 0000000..361fdd1 Binary files /dev/null and b/lunaix-os/tests/units/btrie/alloc.test differ