#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
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() {}
};
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;
}
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)));
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()
}
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("");
}
}
#endif
- if (i == _resources.end())
+ if (i == _resources.end() || !(*i)->contains(ires))
return -L4_ENOENT;
#if 0
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;
}
}
int
-System_bus::request_iomem(L4::Ipc_iostream &ios)
+System_bus::request_iomem(L4::Ipc::Iostream &ios)
{
L4::Opcode op;
ios >> op;
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())
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;
}
}
};
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;
}
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)
{