]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/io/server/src/virt/vbus.cc
Update
[l4.git] / l4 / pkg / io / server / src / virt / vbus.cc
diff --git a/l4/pkg/io/server/src/virt/vbus.cc b/l4/pkg/io/server/src/virt/vbus.cc
deleted file mode 100644 (file)
index a5bd28b..0000000
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
- *          Alexander Warg <warg@os.inf.tu-dresden.de>
- *     economic rights: Technische Universität Dresden (Germany)
- *
- * This file is part of TUD:OS and distributed under the terms of the
- * GNU General Public License 2.
- * Please see the COPYING-GPL-2 file for details.
- */
-#include <l4/re/protocols>
-
-#include <l4/cxx/ipc_server>
-
-#include <l4/re/env>
-#include <l4/re/namespace>
-#include <l4/re/dataspace-sys.h>
-#include <l4/re/inhibitor-sys.h>
-
-#include <l4/re/error_helper>
-
-#include <l4/vbus/vbus_types.h>
-#include <l4/vbus/vdevice-ops.h>
-
-#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
-{
-private:
-  Vi::System_bus *_bus;
-  Vi::Sw_icu *_icu;
-
-public:
-  Root_irq_rs(Vi::System_bus *bus)
-    : Resource_space(), _bus(bus), _icu(new Vi::Sw_icu())
-  {
-    _bus->add_child(_icu);
-    _bus->sw_icu(_icu);
-    _icu->name("L4ICU");
-  }
-
-  bool request(Resource *parent, Device *, Resource *child, Device *)
-  {
-    if (0)
-      {
-        printf("VBUS: IRQ resource request: ");
-        child->dump();
-      }
-
-    if (!parent)
-      return false;
-
-    if (!_icu)
-      {
-        _icu = new Vi::Sw_icu();
-        _bus->add_child(_icu);
-        _bus->sw_icu(_icu);
-      }
-
-    d_printf(DBG_DEBUG2, "Add IRQ resources to vbus: ");
-    if (dlevel(DBG_DEBUG2))
-      child->dump();
-
-    _icu->add_irqs(child);
-    return _bus->add_resource_to_bus(child);
-  };
-
-  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);
-      }
-
-    return _bus->add_resource_to_bus(msi);
-  }
-
-  ~Root_irq_rs() {}
-};
-
-class Root_x_rs : public Resource_space
-{
-private:
-  Vi::System_bus *_bus;
-
-public:
-  Root_x_rs(Vi::System_bus *bus) : Resource_space(), _bus(bus)
-  {}
-
-  bool request(Resource *parent, Device *, Resource *child, Device *)
-  {
-    if (0)
-      {
-        printf("VBUS: X resource request: ");
-        child->dump();
-      }
-
-    if (!parent)
-      return false;
-
-
-    return _bus->add_resource_to_bus(child);
-  }
-
-  bool alloc(Resource *, Device *, Resource *, Device *, bool)
-  { return false; }
-
-  ~Root_x_rs() {}
-};
-}
-
-
-
-namespace Vi {
-
-System_bus::System_bus(Inhibitor_mux *mux)
-: Inhibitor_provider(mux), _sw_icu(0)
-{
-  add_feature(this);
-  add_resource(new Root_resource(Resource::Irq_res, new Root_irq_rs(this)));
-  Resource_space *x = new Root_x_rs(this);
-  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()
-{
-  registry->unregister_obj(this);
-  // FIXME: must delete all devices
-}
-
-/**
- * \brief Add the region described by \a r to the VBUS resources.
- *
- * Adds the resource to the resources available through this V-BUS.
- * This also supports overlapping resources by merging them together.
- */
-bool
-System_bus::add_resource_to_bus(Resource *r)
-{
-  auto x = _resources.find(r);
-  if (x == _resources.end())
-    {
-      _resources.insert(r);
-      return true;
-    }
-
-  // overlapping resource entry already found
-  if (typeid (*r) != typeid (**x))
-    {
-      if (dlevel(DBG_ERR))
-        {
-          printf("error: overlapping incompatible resources for vbus\n");
-          printf("       new:   "); r->dump(); puts(" conflicts with");
-          printf("       found: "); (*x)->dump(); puts("");
-        }
-      return false;
-    }
-
-  if ((*x)->contains(*r))
-    // already fully included
-    return true;
-
-  if (r->contains(**x))
-    {
-      _resources.erase(x);
-      _resources.insert(r);
-      return true;
-    }
-
-  if (dlevel(DBG_ERR))
-    {
-      printf("error: oddly overlaping resources for vbus\n");
-      printf("       new:   "); r->dump(); puts(" confilicts with");
-      printf("       found: "); (*x)->dump(); puts("");
-    }
-  return false;
-}
-
-bool
-System_bus::resource_allocated(Resource const *r) const
-{
-  if (r->disabled())
-    return false;
-
-  auto i = _resources.find(const_cast<Resource *>(r));
-  if (i == _resources.end())
-    return false;
-
-  return (*i)->contains(*r);
-}
-
-int
-System_bus::pm_suspend()
-{
-  inhibitor_release(L4VBUS_INHIBITOR_SUSPEND);
-
-  return 0;
-}
-
-int
-System_bus::pm_resume()
-{
-  inhibitor_acquire(L4VBUS_INHIBITOR_SUSPEND, "vbus active");
-
-  return 0;
-}
-
-void
-System_bus::dump_resources() const
-{
-  for (auto i = _resources.begin();
-       i != _resources.end(); ++i)
-    (*i)->dump();
-}
-
-int
-System_bus::request_resource(L4::Ipc::Iostream &ios)
-{
-  l4vbus_resource_t res;
-  ios.get(res);
-
-  Resource ires(res.type, res.start, res.end);
-  if (dlevel(DBG_DEBUG2))
-    {
-      printf("request resource: ");
-      ires.dump();
-      puts("");
-    }
-
-  auto i = _resources.find(&ires);
-
-  if (0)
-    dump_resources();
-
-  if (i == _resources.end() || !(*i)->contains(ires))
-    return -L4_ENOENT;
-
-  if (0)
-    if (dlevel(DBG_DEBUG))
-      {
-        printf("  found resource: ");
-        (*i)->dump();
-        puts("");
-      }
-
-  if (res.type == L4VBUS_RESOURCE_PORT)
-    {
-      l4_uint64_t sz = res.end + 1 - res.start;
-
-      int szl2 = 0;
-      while ((1UL << szl2) < sz)
-        ++szl2;
-
-      if ((1UL << szl2) > sz)
-        --szl2;
-
-      ios << L4::Ipc::Snd_fpage::io(res.start, szl2, L4_FPAGE_RWX);
-      return L4_EOK;
-    }
-
-
-  return -L4_ENOENT;
-}
-
-int
-System_bus::request_iomem(L4::Ipc::Iostream &ios)
-{
-  L4::Opcode op;
-  ios >> op;
-  switch (op)
-    {
-    case L4Re::Dataspace_::Map:
-        {
-          l4_addr_t offset, spot;
-          unsigned long flags;
-          ios >> offset >> spot >> flags;
-
-          Resource pivot(L4VBUS_RESOURCE_MEM, offset, offset);
-          auto r = _resources.find(&pivot);
-
-          if (r == _resources.end())
-            {
-              if (dlevel(DBG_INFO))
-                {
-                  printf("Request: No resource at %lx\n", offset);
-                  printf("Available resources:\n");
-                  dump_resources();
-                }
-              return -L4_ERANGE;
-            }
-
-          offset = l4_trunc_page(offset);
-
-          l4_addr_t st = l4_trunc_page((*r)->start());
-          l4_addr_t adr = (*r)->map_iomem();
-
-          if (!adr)
-            return -L4_ENOMEM;
-
-          adr = l4_trunc_page(adr);
-
-          l4_addr_t addr = offset - st + adr;
-          unsigned char order
-            = l4_fpage_max_order(L4_PAGESHIFT,
-                                 addr, addr, addr + (*r)->size(), spot);
-
-          // we also might want to do WB instead of UNCACHED...
-          ios << L4::Ipc::Snd_fpage::mem(l4_trunc_size(addr, order), order,
-                                    L4_FPAGE_RWX, l4_trunc_page(spot),
-                                    L4::Ipc::Snd_fpage::Map,
-                                    L4::Ipc::Snd_fpage::Uncached);
-          return L4_EOK;
-        }
-    }
-  return -L4_ENOSYS;
-};
-
-int
-System_bus::inhibitor_dispatch(L4::Ipc::Iostream &ios)
-{
-  L4::Opcode op;
-  ios >> op;
-
-  switch (op)
-    {
-    case L4Re::Inhibitor_::Acquire:
-      inhibitor_acquire(ios);
-      return L4_EOK;
-    case L4Re::Inhibitor_::Release:
-        {
-          l4_umword_t id;
-          ios >> id;
-          inhibitor_release(id);
-          return L4_EOK;
-        }
-    case L4Re::Inhibitor_::Next_lock_info:
-        {
-          l4_mword_t id;
-          ios >> id;
-          ++id;
-          if (id >= L4VBUS_INHIBITOR_MAX)
-            return -L4_ENODEV;
-
-          static char const *const names[] =
-          {
-            /* [L4VBUS_INHIBITOR_SUSPEND]  = */ "suspend",
-            /* [L4VBUS_INHIBITOR_SHUTDOWN] = */ "shutdown",
-            /* [L4VBUS_INHIBITOR_WAKEUP]   = */ "wakeup"
-          };
-
-          ios << (l4_umword_t)id << names[id];
-          return L4_EOK;
-        }
-    default:
-      return -L4_ENOSYS;
-    }
-}
-
-int
-System_bus::dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios)
-{
-  l4_msgtag_t tag;
-  ios >> tag;
-
-  switch (tag.label())
-    {
-    case L4_PROTO_IRQ: // The ICU for event source
-    case L4Re::Protocol::Event:
-      return Vbus_event_source::dispatch(obj, ios);
-    case L4Re::Protocol::Inhibitor:
-      return inhibitor_dispatch(ios);
-
-    case L4Re::Protocol::Dataspace:
-      return request_iomem(ios);
-
-    case 0:
-        {
-          l4vbus_device_handle_t devid;
-          l4_uint32_t func;
-          ios >> devid >> func;
-          Device *dev = get_dev_by_id(devid);
-          if (!dev)
-            return -L4_ENODEV;
-          return dev->vdevice_dispatch(obj, func, ios);
-        }
-
-    default:
-      return -L4_EBADPROTO;
-    }
-
-}
-
-int
-System_bus::dispatch(l4_umword_t, l4_uint32_t func, L4::Ipc::Iostream &ios)
-{
-  switch (func)
-    {
-    case L4vbus_vbus_request_resource:
-      return request_resource(ios);
-    default:
-      return -L4_ENOSYS;
-    }
-}
-
-Vbus_event_source::Vbus_event_source()
-{
-  using L4Re::Util::Auto_cap;
-  using L4Re::chkcap;
-  using L4Re::chksys;
-
-  Auto_cap<L4Re::Dataspace>::Cap buffer_ds
-    = chkcap(L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>(),
-             "allocate event-buffer data-space capability");
-
-  chksys(L4Re::Env::env()->mem_alloc()->alloc(L4_PAGESIZE, buffer_ds.get()),
-         "allocate event-buffer data-space");
-
-  chksys(buffer.attach(buffer_ds.get(), L4Re::Env::env()->rm()),
-         "attach event-buffer data-space");
-
-  _ds = buffer_ds.release();
-}
-
-/**
- * \brief Send device notification to client.
- *
- * \param dev device the notification is originating from.
- * \param type event type to be sent, see event_enums.h for types.
- * \param event event ID.
- * \param value value for the event.
- * \param syn trigger an IRQ for the event if true.
- */
-bool
-System_bus::dev_notify(Device const *dev, unsigned type,
-                       unsigned event, unsigned value, bool syn)
-{
-  Vbus_event_source::Event ev;
-  ev.time = l4_kip_clock(l4re_kip());
-  ev.payload.type = type;
-  ev.payload.code = event;
-  ev.payload.value = value;
-  ev.payload.stream_id = (l4vbus_device_handle_t)dev;
-
-  return Vbus_event_source::put(ev, syn);
-}
-
-int
-System_bus::get_stream_info_for_id(l4_umword_t dev_id, L4Re::Event_stream_info *info)
-{
-  Device *dev = get_dev_by_id(dev_id);
-  if (!dev)
-    return -L4_ENOSYS;
-
-  Io::Event_source_infos const *_info = dev->get_event_infos();
-  if (!_info)
-    return -L4_ENOSYS;
-
-  *info = _info->info;
-  return 0;
-}
-
-int
-System_bus::get_stream_state_for_id(l4_umword_t dev_id, L4Re::Event_stream_state *state)
-{
-  Device *dev = get_dev_by_id(dev_id);
-  if (!dev)
-    return -L4_ENOSYS;
-
-  Io::Event_source_infos const *_info = dev->get_event_infos();
-  if (!_info)
-    return -L4_ENOSYS;
-
-  *state = _info->state;
-  return 0;
-}
-
-L4::Cap<void>
-Vbus_event_source::rcv_cap()
-{
-  return ::rcv_cap;
-}
-
-void
-System_bus::inhibitor_signal(l4_umword_t id)
-{
-  // FIXME: need a subscribed flag!
-  // only signal if this inhibitor is actually acquired
-  if (!inhibitor_acquired(id))
-    return;
-
-  Vbus_event_source::Event ev;
-  ev.time = l4_kip_clock(l4re_kip());
-  ev.payload.type = L4RE_EV_PM;
-  ev.payload.code = id;
-  ev.payload.value = 1;
-  ev.payload.stream_id = (l4vbus_device_handle_t)0;
-
-  put(ev);
-}
-
-}