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"
25 template< typename VI, typename HW >
26 class Generic_type_factory
27 : public cxx::H_list_item
30 typedef Generic_type_factory<VI, HW> Self;
31 typedef cxx::H_list<Self> List;
32 typedef typename List::Iterator Iterator;
34 static List _for_type;
37 virtual VI *vcreate(HW *f) = 0;
38 virtual ~Generic_type_factory() {}
40 static VI *create(HW *f, bool warn = true);
43 explicit Generic_type_factory(std::type_info const *type);
46 std::type_info const *_type;
49 template< typename VI, typename HW >
50 cxx::H_list<Generic_type_factory<VI,HW> > Generic_type_factory<VI,HW>::_for_type(true);
52 typedef Generic_type_factory<Dev_feature, Hw::Dev_feature> Feature_factory;
53 typedef Generic_type_factory<Resource, Resource> Resource_factory;
55 class Dev_factory : public cxx::H_list_item
58 virtual Device *vcreate() = 0;
59 virtual Device *vcreate(Hw::Device *f) = 0;
61 typedef cxx::Avl_map<std::string, Dev_factory *> Name_map;
62 typedef cxx::H_list<Dev_factory> List;
63 typedef List::Iterator Iterator;
65 static List _for_type;
66 std::type_info const *_type;
69 explicit Dev_factory(std::type_info const *type);
71 static Name_map &name_map()
73 static Name_map _name_map;
78 static Device *create(std::string const &_class);
79 static Device *create(Hw::Device *f, bool warn = true);
82 Dev_factory(Dev_factory const &);
83 void operator = (Dev_factory const &);
87 template< typename VI, typename HW_BASE, typename HW, typename BASE >
88 class Generic_factory_t : public BASE
93 Generic_factory_t() : BASE(&typeid(HW)) {}
95 VI *vcreate(HW_BASE *dev)
99 printf("WARNING: device '%s' already assigned to an other virtual bus.\n",
104 if (HW* h = dynamic_cast<HW*>(dev))
106 // dev->inc_ref_count();
115 template< typename VI, typename HW >
116 class Feature_factory_t
117 : public Generic_factory_t<VI, Hw::Dev_feature, HW, Feature_factory >
120 template< typename VI, typename HW >
121 class Resource_factory_t
122 : public Generic_factory_t<VI, Resource, HW, Resource_factory >
125 template< typename V_DEV, typename HW_DEV = void >
126 class Dev_factory_t : public Dev_factory
129 typedef HW_DEV Hw_dev;
132 Dev_factory_t() : Dev_factory(&typeid(Hw_dev))
136 virtual Device *vcreate(Hw::Device *dev)
138 if (dev->ref_count())
139 printf("WARNING: device '%s' already assigned to an other virtual bus.\n",
142 if (!dynamic_cast<HW_DEV const*>(dev))
145 Device *d = new V_dev(static_cast<Hw_dev*>(dev));
146 dev->inc_ref_count();
150 virtual Device *vcreate()
155 template< typename V_DEV >
156 class Dev_factory_t<V_DEV, void> : public Dev_factory
162 explicit Dev_factory_t(std::string const &_class) : Dev_factory(0)
163 { name_map()[_class] = this; }
166 virtual Device *vcreate(Hw::Device *)
169 virtual Device *vcreate()
170 { return new V_dev; }
174 template< typename VI, typename HW >
175 Generic_type_factory<VI, HW>::Generic_type_factory(std::type_info const *type)
181 printf("GTF: register factory for %s\n", type->name());
183 Iterator i = _for_type.end();
184 for (Iterator c = _for_type.begin(); c != _for_type.end(); ++c)
187 // use the compiler catch logic to figure out if TYPE
188 // is a base class of c->_type, if it is we must put
189 // this behind c in the list.
190 if (type->__do_catch(c->_type, &x, 0))
194 _for_type.insert(this, i);
197 template< typename VI, typename HW >
199 Generic_type_factory<VI, HW>::create(HW *f, bool warn)
204 for (Iterator c = _for_type.begin(); c != _for_type.end(); ++c)
207 VI *v = c->vcreate(f);
213 d_printf(DBG_WARN, "WARNING: cannot fabricate buddy object for '%s'\n",