2 * (c) 2010 Technische Universität Dresden
3 * This file is part of TUD:OS and distributed under the terms of the
4 * GNU General Public License 2.
5 * Please see the COPYING-GPL-2 file for details.
7 #include <l4/re/protocols>
9 #include <l4/cxx/ipc_server>
10 #include <l4/cxx/iostream>
11 #include <l4/cxx/l4iostream>
14 #include <l4/re/namespace>
15 #include <l4/re/dataspace-sys.h>
17 #include <l4/re/error_helper>
19 #include <l4/vbus/vbus_types.h>
20 #include <l4/vbus/vdevice-ops.h>
29 #include "vbus_factory.h"
33 class Root_irq_rs : public Resource_space
40 Root_irq_rs(Vi::System_bus *bus) : Resource_space(), _bus(bus), _icu(0)
43 bool request(Resource *parent, Device *, Resource *child, Device *)
45 // printf("VBUS: IRQ resource request: "); child->dump();
46 Adr_resource *r = dynamic_cast<Adr_resource*>(child);
52 _icu = new Vi::Sw_icu();
53 _bus->add_child(_icu);
57 _bus->resource_set()->insert(r);
62 bool alloc(Resource *, Device *, Resource *, Device *, bool)
68 class Root_x_rs : public Resource_space
74 Root_x_rs(Vi::System_bus *bus) : Resource_space(), _bus(bus)
77 bool request(Resource *parent, Device *, Resource *child, Device *)
79 //printf("VBUS: X resource request: "); child->dump();
80 Adr_resource *r = dynamic_cast<Adr_resource*>(child);
85 _bus->resource_set()->insert(r);
89 bool alloc(Resource *, Device *, Resource *, Device *, bool)
101 System_bus::resource_allocated(Resource const *_r) const
103 Adr_resource const *r = dynamic_cast<Adr_resource const *>(_r);
107 Resource_set::const_iterator i = _resources.find(const_cast<Adr_resource*>(r));
108 if (i == _resources.end())
111 if ((*i)->data().start() <= r->data().start()
112 && (*i)->data().end() >= r->data().end())
119 System_bus::System_bus()
122 add_resource(new Root_resource(Resource::Irq_res, new Root_irq_rs(this)));
123 Resource_space *x = new Root_x_rs(this);
124 add_resource(new Root_resource(Resource::Mmio_res, x));
125 add_resource(new Root_resource(Resource::Mmio_res | Resource::F_prefetchable, x));
126 add_resource(new Root_resource(Resource::Io_res, x));
129 System_bus::~System_bus()
131 registry->unregister_obj(this);
132 // FIXME: must delete all devices
137 System_bus::dump_resources() const
139 for (Resource_set::const_iterator i = _resources.begin(); i != _resources.end(); ++i)
144 System_bus::request_resource(L4::Ipc_iostream &ios)
146 l4vbus_resource_t res;
149 ::Adr_resource ires(res.type, res.start, res.end);
150 if (Io_config::cfg->verbose() > 1)
152 printf("request resource: ");
153 Adr_resource(ires).dump();
157 Resource_set::const_iterator i = _resources.find(&ires);
159 for (Resource_set::Const_iterator m = _resources.begin(); m != _resources.end(); ++m)
166 if (i == _resources.end())
170 if (Io_config::cfg->verbose() > 1)
172 printf(" found resource: ");
178 if (res.type == L4VBUS_RESOURCE_PORT)
180 l4_uint64_t sz = res.end + 1 - res.start;
183 while ((1UL << szl2) < sz)
186 if ((1UL << szl2) > sz)
189 ios << L4::Snd_fpage::io(res.start, szl2, L4_FPAGE_RWX);
199 System_bus::request_iomem(L4::Ipc_iostream &ios)
205 case L4Re::Dataspace_::Map:
207 l4_addr_t offset, spot;
209 ios >> offset >> spot >> flags;
211 // printf("map iomem: %lx...\n", offset);
212 Adr_resource pivot(L4VBUS_RESOURCE_MEM, offset, offset);
213 Resource_set::iterator r = _resources.find(&pivot);
215 if (r == _resources.end())
218 offset = l4_trunc_page(offset);
220 l4_addr_t st = l4_trunc_page((*r)->_data().start());
221 l4_addr_t adr = (*r)->map_iomem();
226 adr = l4_trunc_page(adr);
228 ios << L4::Snd_fpage::mem(offset - st + adr, L4_PAGESHIFT, L4_FPAGE_RWX, l4_trunc_page(spot));
236 System_bus::dispatch(l4_umword_t obj, L4::Ipc_iostream &ios)
241 if (tag.label() == 0)
243 l4vbus_device_handle_t devid;
245 ios >> devid >> func;
246 Device *dev = get_dev_by_id(devid);
249 return dev->vdevice_dispatch(obj, func, ios);
252 if (tag.label() == L4Re::Protocol::Dataspace)
253 return request_iomem(ios);
255 return -L4_EBADPROTO;
260 System_bus::dispatch(l4_umword_t, l4_uint32_t func, L4::Ipc_iostream &ios)
264 case L4vbus_vbus_request_resource:
265 return request_resource(ios);
272 static Dev_factory_t<System_bus> __sb_root_factory("System_bus");