allow specifiying access mode when creating twifs file node
[lunaix-os.git] / lunaix-os / hal / bus / pci.c
index 3052a90eea05bc70b5128d41d96f90682ea6c218..cbad1793c8ba653eaff05f92f0cda33766988da0 100644 (file)
@@ -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);