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>
21 template< typename D >
31 Device_tree() : _n(0), _p(0), _c(0), _depth(0) {}
33 D *parent() const { return _p; }
34 D *children() const { return _c; }
35 D *next() const { return _n; }
36 int depth() const { return _depth; }
38 void set_parent(D *p) { _p = p; }
40 void add_sibling(D *s)
43 void add_child(D *d, D *self)
45 for (iterator i = iterator(0, d, L4VBUS_MAX_DEPTH); i != iterator(); ++i)
46 i->set_depth(i->depth() + depth() + 1);
55 for (p = _c; p->next(); p = p->next())
61 void set_depth(int d) { _depth = d; }
66 iterator(D *p, D *c, int depth = 0)
67 : _p(p), _c(c), _d(depth + (p ? p->depth() : 0))
70 iterator(D const *p, int depth = 0)
71 : _p(p), _c(p->children()), _d(depth + p->depth())
78 bool operator == (iterator const &i) const
83 return _p == i._p && _c == i._c && _d == i._d;
86 bool operator != (iterator const &i) const
87 { return !operator == (i); }
89 D *operator -> () const { return _c; }
90 D *operator * () const { return _c; }
92 iterator operator ++ ()
94 if (_d > _c->depth() && _c->children())
95 // go to a child if not at max depth and there are children
98 // go to the next sibling
102 for (D *x = _c->parent(); x && x != _p; x = x->parent())
114 iterator operator ++ (int)
128 template< typename D >
129 class Device_tree_mixin
135 typedef typename Device_tree<D>::iterator iterator;
137 iterator begin(int depth = 0) const
138 { return iterator(static_cast<D const*>(this), depth); }
140 static iterator end() { return iterator(); }
142 D *find_by_name(char const *name) const
144 for (iterator c = begin(0); c != end(); ++c)
145 if (strcmp((*c)->name(), name) == 0)
151 void set_depth(int d) { return _dt.set_depth(d); }
152 void set_parent(D *p) { _dt.set_parent(p); }
153 void add_sibling(D *s) { _dt.add_sibling(s); }
154 virtual void add_child(D *c) { _dt.add_child(c, static_cast<D*>(this)); }
155 virtual ~Device_tree_mixin() {}
158 class Resource_container
161 virtual Resource_list const *resources() const = 0;
162 virtual bool resource_allocated(Resource const *) const = 0;
163 virtual ~Resource_container() {}
167 class Device : public Resource_container
170 virtual Device *parent() const = 0;
171 virtual Device *children() const = 0;
172 virtual Device *next() const = 0;
173 virtual int depth() const = 0;
175 virtual bool request_child_resource(Resource *, Device *) = 0;
176 virtual bool alloc_child_resource(Resource *, Device *) = 0;
178 void request_resource(Resource *r);
179 void request_resources();
180 void request_child_resources();
181 void allocate_pending_child_resources();
182 void allocate_pending_resources();
183 virtual void setup_resources() = 0;
185 virtual char const *name() const = 0;
186 virtual char const *hid() const = 0;
187 virtual bool name(cxx::String const &) = 0;
189 virtual void dump(int) const {};
193 typedef Device_tree<Device>::iterator iterator;
195 iterator begin(int depth = 0) const { return iterator(this, depth); }
196 static iterator end() { return iterator(); }
202 class Generic_device : public Device
205 Resource_list _resources;
208 //typedef gen_iterator<Generic_device> iterator;
210 Resource_list const *resources() const { return &_resources; }
211 void add_resource(Resource *r)
212 { _resources.push_back(r); }
214 virtual bool match_cid(cxx::String const &) const { return false; }
215 virtual char const *name() const { return "(noname)"; }
216 virtual char const *hid() const { return 0; }
217 virtual bool name(cxx::String const &) { return false; }
220 virtual bool request_child_resource(Resource *, Device *);
221 virtual bool alloc_child_resource(Resource *, Device *);
222 virtual void setup_resources();
224 virtual ~Generic_device() {}