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);
}
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;
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
}
static void
-__pci_read_cspace(struct twimap* map)
+__twimap_read_config(struct twimap* map)
{
struct pci_probe* probe;
/*---------- TwiFS interface definition ----------*/
static void
-__pci_read_revid(struct twimap* map)
+__twimap_read_revision(struct twimap* map)
{
struct pci_probe* probe;
}
static void
-__pci_read_class(struct twimap* map)
+__twimap_read_class(struct twimap* map)
{
struct pci_probe* probe;
}
static void
-__pci_read_devinfo(struct twimap* map)
+__twimap_read_pci_devinfo(struct twimap* map)
{
struct pci_probe* probe;
}
static void
-__pci_bar_read(struct twimap* map)
+__twimap_read_io_bases(struct twimap* map)
{
struct pci_probe* probe;
int bar_index;
}
static int
-__pci_bar_gonext(struct twimap* map)
+__twimap_gonext_io_bases(struct twimap* map)
{
if (twimap_index(map, int) >= 5) {
return 0;
}
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;
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)
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;
def_on_register(pci_register),
def_on_create(pci_create)
};
-EXPORT_DEVICE(pci3hba, &pci_def, load_sysconf);
+EXPORT_DEVICE(pci3hba, &pci_def, load_onboot);