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.
15 #include <l4/cxx/avl_map>
16 #include <l4/cxx/hlist>
20 #include "hw_device.h"
23 #include "tagged_parameter.h"
27 template< typename VI, typename HW >
28 class Generic_type_factory
29 : public cxx::H_list_item
32 typedef Generic_type_factory<VI, HW> Self;
33 typedef cxx::H_list<Self> List;
34 typedef typename List::Iterator Iterator;
36 static List _for_type;
39 virtual VI *vcreate(HW *f) = 0;
40 virtual ~Generic_type_factory() {}
42 static VI *create(HW *f, bool warn = true);
45 explicit Generic_type_factory(std::type_info const *type);
48 std::type_info const *_type;
51 template< typename VI, typename HW >
52 cxx::H_list<Generic_type_factory<VI,HW> > Generic_type_factory<VI,HW>::_for_type(true);
54 typedef Generic_type_factory<Dev_feature, Hw::Dev_feature> Feature_factory;
55 typedef Generic_type_factory<Resource, Resource> Resource_factory;
57 class Dev_factory : public cxx::H_list_item
60 virtual Device *vcreate() = 0;
61 virtual Device *vcreate(Hw::Device *f, Tagged_parameter *filter) = 0;
63 // typedef cxx::Avl_map<std::type_info const *, Dev_factory *> Type_map;
64 typedef cxx::Avl_map<std::string, Dev_factory *> Name_map;
65 typedef cxx::H_list<Dev_factory> List;
66 typedef List::Iterator Iterator;
68 static List _for_type;
69 std::type_info const *_type;
72 explicit Dev_factory(std::type_info const *type);
74 static Name_map &name_map()
76 static Name_map _name_map;
81 static Device *create(std::string const &_class);
82 static Device *create(Hw::Device *f, Tagged_parameter *filter, bool warn = true);
85 Dev_factory(Dev_factory const &);
86 void operator = (Dev_factory const &);
90 template< typename VI, typename HW_BASE, typename HW, typename BASE >
91 class Generic_factory_t : public BASE
96 Generic_factory_t() : BASE(&typeid(HW)) {}
98 VI *vcreate(HW_BASE *dev)
101 if (dev->ref_count())
102 printf("WARNING: device '%s' already assigned to an other virtual bus.\n",
107 if (HW* h = dynamic_cast<HW*>(dev))
109 // dev->inc_ref_count();
118 template< typename VI, typename HW >
119 class Feature_factory_t
120 : public Generic_factory_t<VI, Hw::Dev_feature, HW, Feature_factory >
123 template< typename VI, typename HW >
124 class Resource_factory_t
125 : public Generic_factory_t<VI, Resource, HW, Resource_factory >
128 template< typename V_DEV, typename HW_DEV = void >
129 class Dev_factory_t : public Dev_factory
132 typedef HW_DEV Hw_dev;
135 Dev_factory_t() : Dev_factory(&typeid(Hw_dev))
139 virtual Device *vcreate(Hw::Device *dev, Tagged_parameter *filter)
141 if (dev->ref_count())
142 printf("WARNING: device '%s' already assigned to an other virtual bus.\n",
145 if (!dynamic_cast<HW_DEV const*>(dev))
148 Device *d = new V_dev(static_cast<Hw_dev*>(dev), filter);
149 dev->inc_ref_count();
153 virtual Device *vcreate()
158 template< typename V_DEV >
159 class Dev_factory_t<V_DEV, void> : public Dev_factory
165 explicit Dev_factory_t(std::string const &_class) : Dev_factory(0)
167 name_map()[_class] = this;
171 virtual Device *vcreate(Hw::Device *, Tagged_parameter *)
174 virtual Device *vcreate()
176 Device *d = new V_dev();
182 template< typename VI, typename HW >
183 Generic_type_factory<VI, HW>::Generic_type_factory(std::type_info const *type)
189 printf("GTF: register factory for %s\n", type->name());
191 Iterator i = _for_type.end();
192 for (Iterator c = _for_type.begin(); c != _for_type.end(); ++c)
195 // use the compiler catch logic to figure out if TYPE
196 // is a base class of c->_type, if it is we must put
197 // this behind c in the list.
198 if (type->__do_catch(c->_type, &x, 0))
202 _for_type.insert(this, i);
205 template< typename VI, typename HW >
207 Generic_type_factory<VI, HW>::create(HW *f, bool warn)
212 for (Iterator c = _for_type.begin(); c != _for_type.end(); ++c)
215 VI *v = c->vcreate(f);
221 d_printf(DBG_WARN, "WARNING: cannot fabricate buddy object for '%s'\n",