X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/35a7d633d3f16c1e0539af6ca5d8e7482926cd93..0fd474df7001837bde53da0e42e83081827c9641:/lunaix-os/hal/bus/pci.c diff --git a/lunaix-os/hal/bus/pci.c b/lunaix-os/hal/bus/pci.c index 3052a90..cbad179 100644 --- a/lunaix-os/hal/bus/pci.c +++ b/lunaix-os/hal/bus/pci.c @@ -107,6 +107,7 @@ __pci_add_prober(pciaddr_t loc, ptr_t pci_base, int devinfo) prober->cspace_base = pci_base; prober->intr_info = intr; prober->loc = loc; + prober->irq_domain = irq_get_domain(pci_bridge); changeling_morph_anon(pci_probers, prober->mobj, pci_probe_morpher); @@ -271,12 +272,12 @@ pci_scan() } static void -__pci_config_msi(struct pci_probe* probe, msi_vector_t msiv) +__pci_config_msi(struct pci_probe* probe, irq_t irq) { // PCI LB Spec. (Rev 3) Section 6.8 & 6.8.1 - ptr_t msi_addr = msi_addr(msiv); - u32_t msi_data = msi_data(msiv); + ptr_t msi_addr = irq->msi->wr_addr; + u32_t msi_data = irq->msi->message; pci_reg_t reg1 = pci_read_cspace(probe->cspace_base, probe->msi_loc); pci_reg_t msg_ctl = reg1 >> 16; @@ -306,39 +307,26 @@ __pci_config_msi(struct pci_probe* probe, msi_vector_t msiv) pci_write_cspace(probe->cspace_base, probe->msi_loc, reg1); } -msienv_t -pci_msi_start(struct pci_probe* probe) +irq_t +pci_declare_msi_irq(irq_servant callback, struct pci_probe* probe) { - /* - As a PCI bridge/root complex can be initialised from device tree node, - in that case, general information such as routing, rid remapping, - are vital to all msi setup of all peripherals under it. - - Therefore, a wrapper around isrm_msi_* is needed in order to - improve overall readability and usability, where the bridge - device instance that contain these information will be - automatically passed to the underlay as credential to perform - configuration. - */ - - msienv_t env; - - env = isrm_msi_start(pci_bridge); - isrm_msi_set_sideband(env, pci_requester_id(probe)); - - return env; + return irq_declare_msg(callback, probe->loc, probe->loc); } -msi_vector_t -pci_msi_setup_at(msienv_t msienv, struct pci_probe* probe, - int i, isr_cb handler) +int +pci_assign_msi(struct pci_probe* probe, irq_t irq, void* irq_spec) { - msi_vector_t msiv; + int err = 0; + + assert(irq->type == IRQ_MESSAGE); - msiv = isrm_msi_alloc(msienv, 0, i, handler); - __pci_config_msi(probe, msiv); + err = irq_assign(probe->irq_domain, irq, irq_spec); + if (err) { + return err; + } - return msiv; + __pci_config_msi(probe, irq); + return 0; } size_t @@ -383,7 +371,7 @@ pci_apply_command(struct pci_probe* probe, pci_reg_t cmd) } static void -__pci_read_cspace(struct twimap* map) +__twimap_read_config(struct twimap* map) { struct pci_probe* probe; @@ -400,7 +388,7 @@ __pci_read_cspace(struct twimap* map) /*---------- TwiFS interface definition ----------*/ static void -__pci_read_revid(struct twimap* map) +__twimap_read_revision(struct twimap* map) { struct pci_probe* probe; @@ -409,7 +397,7 @@ __pci_read_revid(struct twimap* map) } static void -__pci_read_class(struct twimap* map) +__twimap_read_class(struct twimap* map) { struct pci_probe* probe; @@ -418,7 +406,7 @@ __pci_read_class(struct twimap* map) } static void -__pci_read_devinfo(struct twimap* map) +__twimap_read_pci_devinfo(struct twimap* map) { struct pci_probe* probe; @@ -429,7 +417,7 @@ __pci_read_devinfo(struct twimap* map) } static void -__pci_bar_read(struct twimap* map) +__twimap_read_io_bases(struct twimap* map) { struct pci_probe* probe; int bar_index; @@ -460,7 +448,7 @@ __pci_bar_read(struct twimap* map) } static int -__pci_bar_gonext(struct twimap* map) +__twimap_gonext_io_bases(struct twimap* map) { if (twimap_index(map, int) >= 5) { return 0; @@ -470,7 +458,13 @@ __pci_bar_gonext(struct twimap* map) } static void -__pci_read_binding(struct twimap* map) +__twimap_reset_io_bases(struct twimap* map) +{ + map->index = 0; +} + +static void +__twimap_read_binding(struct twimap* map) { struct pci_probe* probe; struct devident* devid; @@ -511,26 +505,39 @@ pci_build_fsmapping() probe = changeling_reveal(pos, pci_probe_morpher); pci_dev = twifs_dir_node(pci_class, "%x", probe->loc); - map = twifs_mapping(pci_dev, probe, "config"); - map->read = __pci_read_cspace; + twimap_export_value(pci_dev, config, FSACL_aR, probe); + twimap_export_value(pci_dev, revision, FSACL_aR, probe); + twimap_export_value(pci_dev, class, FSACL_aR, probe); + twimap_export_value(pci_dev, binding, FSACL_aR, probe); + twimap_export_list (pci_dev, io_bases, FSACL_aR, probe); + } +} +EXPORT_TWIFS_PLUGIN(pci_devs, pci_build_fsmapping); - map = twifs_mapping(pci_dev, probe, "revision"); - map->read = __pci_read_revid; +/*---------- PCI 3.0 HBA device definition ----------*/ - map = twifs_mapping(pci_dev, probe, "class"); - map->read = __pci_read_class; +static int +__pci_irq_install(struct irq_domain* domain, irq_t irq) +{ + struct irq_domain* parent; + int err; - map = twifs_mapping(pci_dev, probe, "binding"); - map->read = __pci_read_binding; + parent = domain->parent; + err = parent->ops->install_irq(parent, irq); + if (err) { + return err; + } - map = twifs_mapping(pci_dev, probe, "io_bases"); - map->read = __pci_bar_read; - map->go_next = __pci_bar_gonext; + if (irq->type == IRQ_MESSAGE) { + irq->msi->message = irq->vector; } + + return 0; } -EXPORT_TWIFS_PLUGIN(pci_devs, pci_build_fsmapping); -/*---------- PCI 3.0 HBA device definition ----------*/ +static struct irq_domain_ops pci_irq_ops = { + .install_irq = __pci_irq_install +}; static int pci_register(struct device_def* def) @@ -543,15 +550,19 @@ pci_register(struct device_def* def) static int pci_create(struct device_def* def, morph_t* obj) { - devtree_link_t devtree_node; + struct irq_domain *pci_domain; + pci_bridge = device_allocsys(NULL, NULL); +#ifdef CONFIG_USE_DEVICETREE + devtree_link_t devtree_node; devtree_node = changeling_try_reveal(obj, dt_node_morpher); - - pci_bridge = device_allocsys(NULL, NULL); device_set_devtree_node(pci_bridge, devtree_node); +#endif - register_device(pci_bridge, &def->class, "pci_bridge"); + pci_domain = irq_create_domain(pci_bridge, &pci_irq_ops); + irq_attach_domain(irq_get_default_domain(), pci_domain); + register_device(pci_bridge, &def->class, "pci_bridge"); pci_scan(); return 0; @@ -564,4 +575,4 @@ static struct device_def pci_def = { def_on_register(pci_register), def_on_create(pci_create) }; -EXPORT_DEVICE(pci3hba, &pci_def, load_sysconf); +EXPORT_DEVICE(pci3hba, &pci_def, load_onboot);