]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/io/server/src/vbus.cc
update
[l4.git] / l4 / pkg / io / server / src / vbus.cc
index 58dd6d7a0b6a723d157735f23d2f190d9dd747c1..9c39ba163ada436eacda9d00e118362b6e0958d6 100644 (file)
@@ -10,8 +10,6 @@
 #include <l4/re/protocols>
 
 #include <l4/cxx/ipc_server>
-#include <l4/cxx/iostream>
-#include <l4/cxx/l4iostream>
 
 #include <l4/re/env>
 #include <l4/re/namespace>
 
 #include <cstdio>
 
+#include "debug.h"
+#include "hw_msi.h"
 #include "vbus.h"
+#include "vmsi.h"
 #include "vicu.h"
 #include "server.h"
 #include "res.h"
 #include "cfg.h"
 #include "vbus_factory.h"
 
+Vi::System_bus::Root_resource_factory::Factory_list
+  Vi::System_bus::Root_resource_factory::_factories;
+
 namespace {
 
 class Root_irq_rs : public Resource_space
@@ -40,30 +44,73 @@ private:
   Vi::Sw_icu *_icu;
 
 public:
-  Root_irq_rs(Vi::System_bus *bus) : Resource_space(), _bus(bus), _icu(0)
-  {}
+  Root_irq_rs(Vi::System_bus *bus)
+    : Resource_space(), _bus(bus), _icu(new Vi::Sw_icu())
+  {
+    _bus->add_child(_icu);
+    _bus->sw_icu(_icu);
+  }
 
   bool request(Resource *parent, Device *, Resource *child, Device *)
   {
     // printf("VBUS: IRQ resource request: "); child->dump();
-    Adr_resource *r = dynamic_cast<Adr_resource*>(child);
-    if (!r || !parent)
+    if (!parent)
       return false;
 
     if (!_icu)
       {
        _icu = new Vi::Sw_icu();
        _bus->add_child(_icu);
+       _bus->sw_icu(_icu);
       }
 
-    _icu->add_irqs(r);
-    _bus->resource_set()->insert(r);
+    d_printf(DBG_DEBUG2, "Add IRQ resources to vbus: ");
+    if (dlevel(DBG_DEBUG2))
+      child->dump();
+
+    _icu->add_irqs(child);
+    _bus->resource_set()->insert(child);
 
     return true;
   };
 
-  bool alloc(Resource *, Device *, Resource *, Device *, bool)
-  { return false; }
+  bool alloc(Resource *parent, Device *, Resource *child, Device *, bool)
+  {
+    d_printf(DBG_DEBUG2, "Allocate virtual IRQ resource ...\n");
+    if (dlevel(DBG_DEBUG2))
+      child->dump();
+
+    Vi::Msi_resource *msi = dynamic_cast<Vi::Msi_resource*>(child);
+    if (!msi || !parent)
+      return false;
+
+    d_printf(DBG_DEBUG2, "  Allocate Virtual MSI...\n");
+
+    if (!_icu)
+      {
+       _icu = new Vi::Sw_icu();
+       _bus->add_child(_icu);
+      }
+
+    int nr = _icu->alloc_irq(msi->flags(), msi->hw_msi());
+    if (nr < 0)
+      {
+       d_printf(DBG_ERR, "ERROR: cannot allocate MSI resource\n");
+       return false;
+      }
+
+    msi->start_end(nr, nr);
+    msi->del_flags(Resource::F_disabled);
+
+    if (dlevel(DBG_DEBUG2))
+      {
+       msi->dump(4);
+       msi->hw_msi()->dump(4);
+      }
+
+    _bus->resource_set()->insert(msi);
+    return true;
+  }
 
   ~Root_irq_rs() {}
 };
@@ -80,12 +127,11 @@ public:
   bool request(Resource *parent, Device *, Resource *child, Device *)
   {
     //printf("VBUS: X resource request: "); child->dump();
-    Adr_resource *r = dynamic_cast<Adr_resource*>(child);
-    if (!r || !parent)
+    if (!parent)
       return false;
 
 
-    _bus->resource_set()->insert(r);
+    _bus->resource_set()->insert(child);
     return true;
   }
 
@@ -101,25 +147,21 @@ public:
 namespace Vi {
 
 bool
-System_bus::resource_allocated(Resource const *_r) const
+System_bus::resource_allocated(Resource const *r) const
 {
-  Adr_resource const *r = dynamic_cast<Adr_resource const *>(_r);
-  if (!r)
-    return false;
-
-  Resource_set::const_iterator i = _resources.find(const_cast<Adr_resource*>(r));
+  Resource_set::const_iterator i = _resources.find(const_cast<Resource*>(r));
   if (i == _resources.end())
     return false;
 
-  if ((*i)->data().start() <= r->data().start()
-      && (*i)->data().end() >= r->data().end())
+  if ((*i)->start() <= r->start()
+      && (*i)->end() >= r->end())
     return true;
 
   return false;
 }
 
 
-System_bus::System_bus()
+System_bus::System_bus() : _sw_icu(0)
 {
   add_feature(this);
   add_resource(new Root_resource(Resource::Irq_res, new Root_irq_rs(this)));
@@ -127,6 +169,11 @@ System_bus::System_bus()
   add_resource(new Root_resource(Resource::Mmio_res, x));
   add_resource(new Root_resource(Resource::Mmio_res | Resource::F_prefetchable, x));
   add_resource(new Root_resource(Resource::Io_res, x));
+  typedef Root_resource_factory RF;
+  for (RF::Factory_list::Const_iterator i = RF::_factories.begin();
+      i != RF::_factories.end();
+      ++i)
+    add_resource((*i)->create(this));
 }
 
 System_bus::~System_bus()
@@ -144,16 +191,16 @@ System_bus::dump_resources() const
 }
 
 int
-System_bus::request_resource(L4::Ipc_iostream &ios)
+System_bus::request_resource(L4::Ipc::Iostream &ios)
 {
   l4vbus_resource_t res;
   ios.get(res);
 
-  ::Adr_resource ires(res.type, res.start, res.end);
-  if (Io_config::cfg->verbose() > 1)
+  Resource ires(res.type, res.start, res.end);
+  if (dlevel(DBG_DEBUG2))
     {
       printf("request resource: ");
-      Adr_resource(ires).dump();
+      ires.dump();
       puts("");
     }
 
@@ -166,7 +213,7 @@ System_bus::request_resource(L4::Ipc_iostream &ios)
     }
 #endif
 
-  if (i == _resources.end())
+  if (i == _resources.end() || !(*i)->contains(ires))
     return -L4_ENOENT;
 
 #if 0
@@ -189,7 +236,7 @@ System_bus::request_resource(L4::Ipc_iostream &ios)
       if ((1UL << szl2) > sz)
        --szl2;
 
-      ios << L4::Snd_fpage::io(res.start, szl2, L4_FPAGE_RWX);
+      ios << L4::Ipc::Snd_fpage::io(res.start, szl2, L4_FPAGE_RWX);
       return L4_EOK;
     }
 
@@ -198,7 +245,7 @@ System_bus::request_resource(L4::Ipc_iostream &ios)
 }
 
 int
-System_bus::request_iomem(L4::Ipc_iostream &ios)
+System_bus::request_iomem(L4::Ipc::Iostream &ios)
 {
   L4::Opcode op;
   ios >> op;
@@ -211,7 +258,7 @@ System_bus::request_iomem(L4::Ipc_iostream &ios)
          ios >> offset >> spot >> flags;
 
 //       printf("map iomem: %lx...\n", offset);
-         Adr_resource pivot(L4VBUS_RESOURCE_MEM, offset, offset);
+         Resource pivot(L4VBUS_RESOURCE_MEM, offset, offset);
          Resource_set::iterator r = _resources.find(&pivot);
 
          if (r == _resources.end())
@@ -233,10 +280,10 @@ System_bus::request_iomem(L4::Ipc_iostream &ios)
                                  addr, addr, addr + (*r)->size(), spot);
 
           // we also might want to do WB instead of UNCACHED...
-          ios << L4::Snd_fpage::mem(l4_trunc_size(addr, order), order,
+          ios << L4::Ipc::Snd_fpage::mem(l4_trunc_size(addr, order), order,
                                     L4_FPAGE_RWX, l4_trunc_page(spot),
-                                    L4::Snd_fpage::Map,
-                                    L4::Snd_fpage::Uncached);
+                                    L4::Ipc::Snd_fpage::Map,
+                                    L4::Ipc::Snd_fpage::Uncached);
          return L4_EOK;
        }
     }
@@ -244,7 +291,7 @@ System_bus::request_iomem(L4::Ipc_iostream &ios)
 };
 
 int
-System_bus::dispatch(l4_umword_t obj, L4::Ipc_iostream &ios)
+System_bus::dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios)
 {
   l4_msgtag_t tag;
   ios >> tag;
@@ -268,7 +315,7 @@ System_bus::dispatch(l4_umword_t obj, L4::Ipc_iostream &ios)
 }
 
 int
-System_bus::dispatch(l4_umword_t, l4_uint32_t func, L4::Ipc_iostream &ios)
+System_bus::dispatch(l4_umword_t, l4_uint32_t func, L4::Ipc::Iostream &ios)
 {
   switch (func)
     {