From ec98d05af80e6e68c889dac10b8478ce92bd5161 Mon Sep 17 00:00:00 2001 From: Lunaixsky Date: Sat, 14 Dec 2024 14:12:01 +0000 Subject: [PATCH] move gic to new devtree interface --- .../arch/aarch64/includes/asm/aa64_isrm.h | 10 - lunaix-os/arch/aarch64/includes/asm/soc/gic.h | 6 +- lunaix-os/arch/aarch64/soc/gic/gic.c | 191 +++--------------- lunaix-os/arch/aarch64/soc/gic/gic_dt.c | 101 ++++----- lunaix-os/hal/bus/pci.c | 2 +- lunaix-os/hal/devtree/dt.c | 18 +- lunaix-os/hal/devtree/dtm.c | 6 +- lunaix-os/includes/hal/devtree.h | 16 +- lunaix-os/includes/hal/devtreem.h | 2 - lunaix-os/tests/units/btrie/alloc.test | Bin 0 -> 97616 bytes 10 files changed, 103 insertions(+), 249 deletions(-) delete mode 100644 lunaix-os/arch/aarch64/includes/asm/aa64_isrm.h create mode 100755 lunaix-os/tests/units/btrie/alloc.test 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 0000000000000000000000000000000000000000..361fdd183268d9f878e6a0ac38a2a6605fe3e552 GIT binary patch literal 97616 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 JysWDD{{YPivW@@% literal 0 HcmV?d00001 -- 2.27.0