]> 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 <string>
17 #include <typeinfo>
18
19 #include "hw_device.h"
20 #include "vdevice.h"
21
22 namespace Vi {
23
24 template< typename VI, typename HW >
25 class Generic_type_factory
26 {
27 public:
28   virtual VI *vcreate(HW *f) = 0;
29   virtual ~Generic_type_factory() {}
30
31   typedef cxx::Avl_map<std::type_info const *, Generic_type_factory *> Type_map;
32
33 protected:
34   static Type_map &type_map()
35   {
36     static Type_map _tm;
37     return _tm;
38   }
39
40 public:
41   static VI *create(HW *f, bool warn = true);
42 };
43
44 typedef Generic_type_factory<Dev_feature, Hw::Dev_feature> Feature_factory;
45 typedef Generic_type_factory<Resource, Resource> Resource_factory;
46
47 class Dev_factory
48 : public Generic_type_factory<Device, Hw::Device>
49 {
50 public:
51   virtual Device *vcreate() = 0;
52
53   typedef cxx::Avl_map<std::string, Dev_factory *> Name_map;
54
55 protected:
56   static Name_map &name_map()
57   {
58     static Name_map _name_map;
59     return _name_map;
60   }
61
62 public:
63   using Generic_type_factory<Device, Hw::Device>::create;
64   static Device *create(std::string const &_class);
65 };
66
67
68 template< typename VI,  typename HW_BASE, typename HW, typename BASE >
69 class Generic_factory_t : public BASE
70 {
71 public:
72   Generic_factory_t()
73   { BASE::type_map()[&typeid(HW)] = this; }
74
75
76   VI *vcreate(HW_BASE *dev)
77   {
78 #if 0
79     if (dev->ref_count())
80       printf("WARNING: device '%s' already assigned to an other virtual bus.\n",
81              dev->name());
82 #endif
83
84     VI *d = 0;
85     if (HW* h = dynamic_cast<HW*>(dev))
86       d = new VI(h);
87 //    dev->inc_ref_count();
88     return d;
89   }
90
91   VI *vcreate()
92   { return 0; }
93
94 };
95
96 template< typename VI, typename HW >
97 class Feature_factory_t
98 : public Generic_factory_t<VI, Hw::Dev_feature, HW, Feature_factory >
99 {};
100
101 template< typename VI, typename HW >
102 class Resource_factory_t
103 : public Generic_factory_t<VI, Resource, HW, Resource_factory >
104 {};
105
106 template< typename V_DEV, typename HW_DEV = void >
107 class Dev_factory_t :  public Dev_factory
108 {
109 public:
110   typedef HW_DEV Hw_dev;
111   typedef V_DEV  V_dev;
112
113   Dev_factory_t()
114   {
115     type_map()[&typeid(Hw_dev)] = this;
116   }
117
118
119   virtual Device *vcreate(Hw::Device *dev)
120   {
121     if (dev->ref_count())
122       printf("WARNING: device '%s' already assigned to an other virtual bus.\n",
123              dev->name());
124
125     Device *d = new V_dev(static_cast<Hw_dev*>(dev));
126     dev->inc_ref_count();
127     return d;
128   }
129
130   virtual Device *vcreate()
131   { return 0; }
132
133 };
134
135 template< typename V_DEV >
136 class Dev_factory_t<V_DEV, void> :  public Dev_factory
137 {
138 public:
139   typedef void  Hw_dev;
140   typedef V_DEV V_dev;
141
142   explicit Dev_factory_t(std::string const &_class)
143   {
144     name_map()[_class] = this;
145   }
146
147
148   virtual Device *vcreate(Hw::Device *)
149   { return 0; }
150
151   virtual Device *vcreate()
152   {
153     Device *d = new V_dev();
154     return d;
155   }
156
157 };
158
159
160 template< typename VI, typename HW >
161 VI *
162 Generic_type_factory<VI, HW>::create(HW *f, bool warn)
163 {
164   if (!f)
165     return 0;
166
167   Type_map &tm = type_map();
168   typename Type_map::const_iterator i = tm.find(&typeid(*f));
169   if (i == tm.end())
170     {
171       if (warn)
172         d_printf(DBG_WARN, "WARNING: cannot fabricate buddy object for '%s'\n",
173                 typeid(*f).name());
174       return 0;
175     }
176
177     return i->second->vcreate(f);
178 }
179
180 }
181