]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/io/server/src/vbus_factory.h
update
[l4.git] / l4 / pkg / io / server / src / vbus_factory.h
1 /*
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)
5  *
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.
9  */
10 #pragma once
11
12 #include "main.h"
13 #include "debug.h"
14
15 #include <l4/cxx/avl_map>
16 #include <l4/cxx/hlist>
17 #include <string>
18 #include <typeinfo>
19
20 #include "hw_device.h"
21 #include "vdevice.h"
22
23 #include "tagged_parameter.h"
24
25 namespace Vi {
26
27 template< typename VI, typename HW >
28 class Generic_type_factory
29 : public cxx::H_list_item
30 {
31 private:
32   typedef Generic_type_factory<VI, HW> Self;
33   typedef cxx::H_list<Self> List;
34   typedef typename List::Iterator Iterator;
35
36   static List _for_type;
37
38 public:
39   virtual VI *vcreate(HW *f) = 0;
40   virtual ~Generic_type_factory() {}
41
42   static VI *create(HW *f, bool warn = true);
43
44 protected:
45   explicit Generic_type_factory(std::type_info const *type);
46
47 private:
48   std::type_info const *_type;
49 };
50
51 template< typename VI, typename HW >
52 cxx::H_list<Generic_type_factory<VI,HW> > Generic_type_factory<VI,HW>::_for_type(true);
53
54 typedef Generic_type_factory<Dev_feature, Hw::Dev_feature> Feature_factory;
55 typedef Generic_type_factory<Resource, Resource> Resource_factory;
56
57 class Dev_factory : public cxx::H_list_item
58 {
59 public:
60   virtual Device *vcreate() = 0;
61   virtual Device *vcreate(Hw::Device *f, Tagged_parameter *filter) = 0;
62
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;
67
68   static List _for_type;
69   std::type_info const *_type;
70
71 protected:
72   explicit Dev_factory(std::type_info const *type);
73
74   static Name_map &name_map()
75   {
76     static Name_map _name_map;
77     return _name_map;
78   }
79
80 public:
81   static Device *create(std::string const &_class);
82   static Device *create(Hw::Device *f, Tagged_parameter *filter, bool warn = true);
83
84 private:
85   Dev_factory(Dev_factory const &);
86   void operator = (Dev_factory const &);
87 };
88
89
90 template< typename VI,  typename HW_BASE, typename HW, typename BASE >
91 class Generic_factory_t : public BASE
92
93 {
94 public:
95
96   Generic_factory_t() : BASE(&typeid(HW)) {}
97
98   VI *vcreate(HW_BASE *dev)
99   {
100 #if 0
101     if (dev->ref_count())
102       printf("WARNING: device '%s' already assigned to an other virtual bus.\n",
103              dev->name());
104 #endif
105
106     VI *d = 0;
107     if (HW* h = dynamic_cast<HW*>(dev))
108       d = new VI(h);
109 //    dev->inc_ref_count();
110     return d;
111   }
112
113   VI *vcreate()
114   { return 0; }
115
116 };
117
118 template< typename VI, typename HW >
119 class Feature_factory_t
120 : public Generic_factory_t<VI, Hw::Dev_feature, HW, Feature_factory >
121 {};
122
123 template< typename VI, typename HW >
124 class Resource_factory_t
125 : public Generic_factory_t<VI, Resource, HW, Resource_factory >
126 {};
127
128 template< typename V_DEV, typename HW_DEV = void >
129 class Dev_factory_t :  public Dev_factory
130 {
131 public:
132   typedef HW_DEV Hw_dev;
133   typedef V_DEV  V_dev;
134
135   Dev_factory_t() : Dev_factory(&typeid(Hw_dev))
136   { }
137
138
139   virtual Device *vcreate(Hw::Device *dev, Tagged_parameter *filter)
140   {
141     if (dev->ref_count())
142       printf("WARNING: device '%s' already assigned to an other virtual bus.\n",
143              dev->name());
144
145     if (!dynamic_cast<HW_DEV const*>(dev))
146       return 0;
147
148     Device *d = new V_dev(static_cast<Hw_dev*>(dev), filter);
149     dev->inc_ref_count();
150     return d;
151   }
152
153   virtual Device *vcreate()
154   { return 0; }
155
156 };
157
158 template< typename V_DEV >
159 class Dev_factory_t<V_DEV, void> :  public Dev_factory
160 {
161 public:
162   typedef void  Hw_dev;
163   typedef V_DEV V_dev;
164
165   explicit Dev_factory_t(std::string const &_class) : Dev_factory(0)
166   {
167     name_map()[_class] = this;
168   }
169
170
171   virtual Device *vcreate(Hw::Device *, Tagged_parameter *)
172   { return 0; }
173
174   virtual Device *vcreate()
175   {
176     Device *d = new V_dev();
177     return d;
178   }
179
180 };
181
182 template< typename VI, typename HW >
183 Generic_type_factory<VI, HW>::Generic_type_factory(std::type_info const *type)
184 : _type(type)
185 {
186   if (!type)
187     return;
188
189   printf("GTF: register factory for %s\n", type->name());
190
191   Iterator i = _for_type.end();
192   for (Iterator c = _for_type.begin(); c != _for_type.end(); ++c)
193     {
194       void *x = 0;
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))
199         i = c;
200     }
201
202   _for_type.insert(this, i);
203 }
204
205 template< typename VI, typename HW >
206 VI *
207 Generic_type_factory<VI, HW>::create(HW *f, bool warn)
208 {
209   if (!f)
210     return 0;
211
212   for (Iterator c = _for_type.begin(); c != _for_type.end(); ++c)
213
214     {
215       VI *v = c->vcreate(f);
216       if (v)
217         return v;
218     }
219
220   if (warn)
221     d_printf(DBG_WARN, "WARNING: cannot fabricate buddy object for '%s'\n",
222              typeid(*f).name());
223   return 0;
224 }
225
226 }
227