2 * (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
3 * economic rights: Technische Universität Dresden (Germany)
5 * This file is part of TUD:OS and distributed under the terms of the
6 * GNU General Public License 2.
7 * Please see the COPYING-GPL-2 file for details.
11 #include <l4/sys/l4int.h>
12 #include <l4/vbus/vbus_types.h>
13 #include <l4/cxx/minmax>
14 #include <l4/cxx/string>
20 template< typename D >
30 Device_tree() : _n(0), _p(0), _c(0), _depth(0) {}
32 D *parent() const { return _p; }
33 D *children() const { return _c; }
34 D *next() const { return _n; }
35 int depth() const { return _depth; }
37 void set_parent(D *p) { _p = p; }
39 void add_sibling(D *s)
42 void add_child(D *d, D *self)
44 for (iterator i = iterator(0, d, L4VBUS_MAX_DEPTH); i != iterator(); ++i)
45 i->set_depth(i->depth() + depth() + 1);
54 for (p = _c; p->next(); p = p->next())
60 void set_depth(int d) { _depth = d; }
65 iterator(D *p, D *c, int depth = 0)
66 : _p(p), _c(c), _d(depth + (p ? p->depth() : 0))
69 iterator(D const *p, int depth = 0)
70 : _p(p), _c(p->children()), _d(depth + p->depth())
77 bool operator == (iterator const &i) const
82 return _p == i._p && _c == i._c && _d == i._d;
85 bool operator != (iterator const &i) const
86 { return !operator == (i); }
88 D *operator -> () const { return _c; }
89 D *operator * () const { return _c; }
91 iterator operator ++ ()
93 if (_d > _c->depth() && _c->children())
94 // go to a child if not at max depth and there are children
97 // go to the next sibling
101 for (D *x = _c->parent(); x && x != _p; x = x->parent())
113 iterator operator ++ (int)
127 template< typename D >
128 class Device_tree_mixin
134 typedef typename Device_tree<D>::iterator iterator;
136 iterator begin(int depth = 0) const
137 { return iterator(static_cast<D const*>(this), depth); }
139 static iterator end() { return iterator(); }
141 void set_depth(int d) { return _dt.set_depth(d); }
142 void set_parent(D *p) { _dt.set_parent(p); }
143 void add_sibling(D *s) { _dt.add_sibling(s); }
144 virtual void add_child(D *c) { _dt.add_child(c, static_cast<D*>(this)); }
145 virtual ~Device_tree_mixin() {}
148 class Resource_container
151 virtual Resource_list const *resources() const = 0;
152 virtual bool resource_allocated(Resource const *) const = 0;
153 virtual ~Resource_container() {}
157 class Device : public Resource_container
160 virtual Device *parent() const = 0;
161 virtual Device *children() const = 0;
162 virtual Device *next() const = 0;
163 virtual int depth() const = 0;
165 virtual bool request_child_resource(Resource *, Device *) = 0;
166 virtual bool alloc_child_resource(Resource *, Device *) = 0;
168 void request_resource(Resource *r);
169 void request_resources();
170 void request_child_resources();
171 void allocate_pending_child_resources();
172 void allocate_pending_resources();
173 virtual void setup_resources() = 0;
175 virtual char const *name() const = 0;
176 virtual char const *hid() const = 0;
177 virtual bool name(cxx::String const &) = 0;
179 virtual void dump(int) const {};
183 typedef Device_tree<Device>::iterator iterator;
185 iterator begin(int depth = 0) const { return iterator(this, depth); }
186 static iterator end() { return iterator(); }
192 class Generic_device : public virtual Device
195 Resource_list _resources;
198 //typedef gen_iterator<Generic_device> iterator;
200 Resource_list const *resources() const { return &_resources; }
201 void add_resource(Resource *r)
202 { _resources.insert(r); }
204 virtual bool match_cid(cxx::String const &) const { return false; }
205 virtual char const *name() const { return "(noname)"; }
206 virtual char const *hid() const { return 0; }
207 virtual bool name(cxx::String const &) { return false; }
210 virtual bool request_child_resource(Resource *, Device *);
211 virtual bool alloc_child_resource(Resource *, Device *);
212 virtual void setup_resources();
214 virtual ~Generic_device() {}