]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/io/server/src/virt/vbus_factory.h
update
[l4.git] / l4 / pkg / io / server / src / virt / 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 "type_matcher.h"
22 #include "vdevice.h"
23
24 namespace Vi {
25
26 template< typename VI, typename HW >
27 class Generic_type_factory
28 : public Type_matcher<Generic_type_factory<VI, HW>, VI*>
29 {
30 private:
31   typedef Generic_type_factory<VI, HW> Self;
32
33 public:
34   virtual VI *do_match(HW *f) = 0;
35
36 protected:
37   explicit Generic_type_factory(std::type_info const *type)
38   : Type_matcher<Self, VI*>(type) {}
39 };
40
41
42 typedef Generic_type_factory<Dev_feature, Hw::Dev_feature> Feature_factory;
43 typedef Generic_type_factory<Resource, Resource> Resource_factory;
44
45 class Dev_factory : public Type_matcher<Dev_factory, Device *>
46 {
47 public:
48   virtual Device *vcreate() = 0;
49   virtual Device *do_match(Hw::Device *f) = 0;
50
51   typedef cxx::Avl_map<std::string, Dev_factory *> Name_map;
52
53 protected:
54   explicit Dev_factory(std::type_info const *type)
55   : Type_matcher<Dev_factory, Device *>(type)
56   {}
57
58   static Name_map &name_map()
59   {
60     static Name_map _name_map;
61     return _name_map;
62   }
63
64 public:
65   static Device *create(std::string const &_class);
66   static Device *create(Hw::Device *f)
67   { return match(f); }
68
69 private:
70   Dev_factory(Dev_factory const &);
71   void operator = (Dev_factory const &);
72 };
73
74
75 template< typename VI,  typename HW_BASE, typename HW, typename BASE >
76 class Generic_factory_t : public BASE
77 {
78 public:
79
80   Generic_factory_t() : BASE(&typeid(HW)) {}
81
82   VI *do_match(HW_BASE *dev)
83   {
84 #if 0
85     if (dev->ref_count())
86       printf("WARNING: device '%s' already assigned to another virtual bus.\n",
87              dev->name());
88 #endif
89
90     VI *d = 0;
91     if (HW* h = dynamic_cast<HW*>(dev))
92       d = new VI(h);
93 //    dev->inc_ref_count();
94     return d;
95   }
96
97   VI *vcreate()
98   { return 0; }
99
100 };
101
102 template< typename VI, typename HW >
103 class Feature_factory_t
104 : public Generic_factory_t<VI, Hw::Dev_feature, HW, Feature_factory >
105 {};
106
107 template< typename VI, typename HW >
108 class Resource_factory_t
109 : public Generic_factory_t<VI, Resource, HW, Resource_factory >
110 {};
111
112 template< typename V_DEV, typename HW_DEV = void >
113 class Dev_factory_t :  public Dev_factory
114 {
115 public:
116   typedef HW_DEV Hw_dev;
117   typedef V_DEV  V_dev;
118
119   Dev_factory_t() : Dev_factory(&typeid(Hw_dev))
120   { }
121
122
123   Device *do_match(Hw::Device *dev)
124   {
125     if (dev->ref_count())
126       printf("WARNING: device '%s' already assigned to another virtual bus.\n",
127              dev->name());
128
129     if (!dynamic_cast<HW_DEV const*>(dev))
130       return 0;
131
132     Device *d = new V_dev(static_cast<Hw_dev*>(dev));
133     dev->inc_ref_count();
134     return d;
135   }
136
137   Device *vcreate()
138   { return 0; }
139
140 };
141
142 template< typename V_DEV >
143 class Dev_factory_t<V_DEV, void> :  public Dev_factory
144 {
145 public:
146   typedef void  Hw_dev;
147   typedef V_DEV V_dev;
148
149   explicit Dev_factory_t(std::string const &_class) : Dev_factory(0)
150   { name_map()[_class] = this; }
151
152
153   Device *do_match(Hw::Device *)
154   { return 0; }
155
156   Device *vcreate()
157   { return new V_dev; }
158
159 };
160
161
162 }
163