2 * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
6 * This file is part of TUD:OS and distributed under the terms of the
7 * GNU General Public License 2.
8 * Please see the COPYING-GPL-2 file for details.
10 #include <l4/re/protocols>
12 #include <l4/cxx/ipc_server>
13 #include <l4/cxx/iostream>
14 #include <l4/cxx/l4iostream>
17 #include <l4/re/namespace>
18 #include <l4/re/dataspace-sys.h>
20 #include <l4/re/error_helper>
22 #include <l4/vbus/vbus_types.h>
23 #include <l4/vbus/vdevice-ops.h>
32 #include "vbus_factory.h"
36 class Root_irq_rs : public Resource_space
43 Root_irq_rs(Vi::System_bus *bus) : Resource_space(), _bus(bus), _icu(0)
46 bool request(Resource *parent, Device *, Resource *child, Device *)
48 // printf("VBUS: IRQ resource request: "); child->dump();
49 Adr_resource *r = dynamic_cast<Adr_resource*>(child);
55 _icu = new Vi::Sw_icu();
56 _bus->add_child(_icu);
60 _bus->resource_set()->insert(r);
65 bool alloc(Resource *, Device *, Resource *, Device *, bool)
71 class Root_x_rs : public Resource_space
77 Root_x_rs(Vi::System_bus *bus) : Resource_space(), _bus(bus)
80 bool request(Resource *parent, Device *, Resource *child, Device *)
82 //printf("VBUS: X resource request: "); child->dump();
83 Adr_resource *r = dynamic_cast<Adr_resource*>(child);
88 _bus->resource_set()->insert(r);
92 bool alloc(Resource *, Device *, Resource *, Device *, bool)
104 System_bus::resource_allocated(Resource const *_r) const
106 Adr_resource const *r = dynamic_cast<Adr_resource const *>(_r);
110 Resource_set::const_iterator i = _resources.find(const_cast<Adr_resource*>(r));
111 if (i == _resources.end())
114 if ((*i)->data().start() <= r->data().start()
115 && (*i)->data().end() >= r->data().end())
122 System_bus::System_bus()
125 add_resource(new Root_resource(Resource::Irq_res, new Root_irq_rs(this)));
126 Resource_space *x = new Root_x_rs(this);
127 add_resource(new Root_resource(Resource::Mmio_res, x));
128 add_resource(new Root_resource(Resource::Mmio_res | Resource::F_prefetchable, x));
129 add_resource(new Root_resource(Resource::Io_res, x));
132 System_bus::~System_bus()
134 registry->unregister_obj(this);
135 // FIXME: must delete all devices
140 System_bus::dump_resources() const
142 for (Resource_set::const_iterator i = _resources.begin(); i != _resources.end(); ++i)
147 System_bus::request_resource(L4::Ipc_iostream &ios)
149 l4vbus_resource_t res;
152 ::Adr_resource ires(res.type, res.start, res.end);
153 if (Io_config::cfg->verbose() > 1)
155 printf("request resource: ");
156 Adr_resource(ires).dump();
160 Resource_set::const_iterator i = _resources.find(&ires);
162 for (Resource_set::Const_iterator m = _resources.begin(); m != _resources.end(); ++m)
169 if (i == _resources.end() || !(*i)->contains(ires))
173 if (Io_config::cfg->verbose() > 1)
175 printf(" found resource: ");
181 if (res.type == L4VBUS_RESOURCE_PORT)
183 l4_uint64_t sz = res.end + 1 - res.start;
186 while ((1UL << szl2) < sz)
189 if ((1UL << szl2) > sz)
192 ios << L4::Snd_fpage::io(res.start, szl2, L4_FPAGE_RWX);
201 System_bus::request_iomem(L4::Ipc_iostream &ios)
207 case L4Re::Dataspace_::Map:
209 l4_addr_t offset, spot;
211 ios >> offset >> spot >> flags;
213 // printf("map iomem: %lx...\n", offset);
214 Adr_resource pivot(L4VBUS_RESOURCE_MEM, offset, offset);
215 Resource_set::iterator r = _resources.find(&pivot);
217 if (r == _resources.end())
220 offset = l4_trunc_page(offset);
222 l4_addr_t st = l4_trunc_page((*r)->start());
223 l4_addr_t adr = (*r)->map_iomem();
228 adr = l4_trunc_page(adr);
230 l4_addr_t addr = offset - st + adr;
232 = l4_fpage_max_order(L4_PAGESHIFT,
233 addr, addr, addr + (*r)->size(), spot);
235 // we also might want to do WB instead of UNCACHED...
236 ios << L4::Snd_fpage::mem(l4_trunc_size(addr, order), order,
237 L4_FPAGE_RWX, l4_trunc_page(spot),
239 L4::Snd_fpage::Uncached);
247 System_bus::dispatch(l4_umword_t obj, L4::Ipc_iostream &ios)
252 if (tag.label() == 0)
254 l4vbus_device_handle_t devid;
256 ios >> devid >> func;
257 Device *dev = get_dev_by_id(devid);
260 return dev->vdevice_dispatch(obj, func, ios);
263 if (tag.label() == L4Re::Protocol::Dataspace)
264 return request_iomem(ios);
266 return -L4_EBADPROTO;
271 System_bus::dispatch(l4_umword_t, l4_uint32_t func, L4::Ipc_iostream &ios)
275 case L4vbus_vbus_request_resource:
276 return request_resource(ios);
283 static Dev_factory_t<System_bus> __sb_root_factory("System_bus");