]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/io/server/src/resource.h
69f223f47adec9e04369986db870233af601722a
[l4.git] / l4 / pkg / io / server / src / resource.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 <l4/sys/icu>
13
14 #include <l4/vbus/vbus_types.h>
15 #include <vector>
16
17 #include <l4/re/dataspace>
18 #include <l4/re/util/cap_alloc>
19 #include <l4/re/rm>
20
21 #include "res.h"
22
23 class Resource;
24 class Device;
25
26
27 typedef std::vector<Resource *> Resource_list;
28
29 class Resource_space
30 {
31 public:
32   virtual bool request(Resource *parent, Device *pdev,
33                        Resource *child, Device *cdev) = 0;
34   virtual bool alloc(Resource *parent, Device *pdev,
35                      Resource *child, Device *cdev, bool resize) = 0;
36   virtual ~Resource_space() {}
37 };
38
39 class Resource
40 {
41 private:
42   unsigned long _f;
43   Resource *_p;
44
45 public:
46   typedef l4_uint64_t Addr;
47   typedef l4_int64_t Size;
48
49   enum Type
50   {
51     Invalid_res = L4VBUS_RESOURCE_INVALID,
52     Irq_res     = L4VBUS_RESOURCE_IRQ,
53     Mmio_res    = L4VBUS_RESOURCE_MEM,
54     Io_res      = L4VBUS_RESOURCE_PORT,
55     Bus_res
56   };
57
58   enum Flags
59   {
60     F_type_mask    = 0x00ff,
61     F_disabled     = 0x0100,
62     F_hierarchical = 0x0200,
63     F_prefetchable = 0x0400,
64     F_size_aligned = 0x0800,
65     F_empty        = 0x1000,
66     F_rom          = 0x2000,
67     F_fixed_size   = 0x4000,
68     F_fixed_addr   = 0x8000,
69
70     F_width_64bit   = 0x010000,
71     F_relative      = 0x040000,
72
73     Irq_info_base   = 0x100000,
74     Irq_info_factor = Irq_info_base / 2,
75     Irq_level       = L4_IRQ_F_LEVEL * Irq_info_factor, //0x000000,
76     Irq_edge        = L4_IRQ_F_EDGE  * Irq_info_factor, //0x100000,
77     Irq_high        = L4_IRQ_F_POS   * Irq_info_factor, //0x000000,
78     Irq_low         = L4_IRQ_F_NEG   * Irq_info_factor, //0x200000,
79     Irq_both        = L4_IRQ_F_BOTH  * Irq_info_factor, //0x400000,
80   };
81
82   explicit Resource(unsigned long flags = 0)
83   : _f(flags | F_fixed_size), _p(0), _s(0), _e(0), _a(0) {}
84
85   Resource(unsigned long flags, Addr start, Addr end)
86   : _f(flags | F_fixed_size), _p(0), _s(start), _e(end), _a(end - start)
87   {}
88
89   unsigned long flags() const { return _f; }
90   void add_flags(unsigned long flags) { _f |= flags; }
91   void del_flags(unsigned long flags) { _f &= ~flags; }
92   bool hierarchical() const { return _f & F_hierarchical; }
93   bool disabled() const { return _f & F_disabled; }
94   bool prefetchable() const { return _f & F_prefetchable; }
95   bool empty() const { return _f & F_empty; }
96   bool fixed_addr() const { return _f & F_fixed_addr; }
97   bool fixed_size() const { return _f & F_fixed_size; }
98   bool relative() const { return _f & F_relative; }
99   unsigned type() const { return _f & F_type_mask; }
100
101 public:
102 //private:
103   void set_empty(bool empty)
104   {
105     if (empty)
106       _f |= F_empty;
107     else
108       _f &= ~F_empty;
109   }
110
111 public:
112   void disable() { _f |= F_disabled; }
113   void enable()  { _f &= ~F_disabled; }
114
115   virtual Resource_space *provided() const { return 0; }
116
117   void dump(char const *type, int indent) const;
118   virtual void dump(int indent = 0) const;
119
120   virtual bool compatible(Resource *consumer, bool pref = true) const
121   {
122     if (type() != consumer->type())
123       return false;
124
125     return prefetchable() == (consumer->prefetchable() && pref);
126   }
127
128   Resource *parent() const { return _p; }
129   void parent(Resource *p) { _p = p; }
130
131   virtual ~Resource() {}
132
133 private:
134   Addr _s, _e;
135   l4_umword_t _a;
136
137   void _start_end(Addr s, Addr e) { _s = s; _e = e; }
138
139 public:
140   void set_empty() { _s = _e = 0; set_empty(true); }
141   void alignment(Size a)
142   {
143     _a = a;
144     del_flags(F_size_aligned);
145   }
146
147   bool valid() const { return flags() && _s <= _e; }
148
149   void validate()
150   {
151     if (!valid())
152       disable();
153   }
154
155   Addr start() const { return _s; }
156   Addr end() const { return _e; }
157   Size size() const { return (Size)_e + 1 - _s; }
158
159   bool contains(Resource const &o) const
160   { return start() <= o.start() && end() >= o.end(); }
161
162   void start(Addr start) { _e = start + (_e - _s); _s = start; }
163   void end(Addr end)
164   {
165     _e = end;
166     set_empty(false);
167   }
168
169   void size(Size size)
170   {
171     _e = _s - 1 + size;
172     set_empty(false);
173   }
174
175   void start_end(Addr start, Addr end)
176   {
177     _start_end(start, end);
178     set_empty(false);
179   }
180
181   void start_size(Addr start, Size s)
182   {
183     _start_end(start, start - 1 + s);
184     set_empty(false);
185   }
186
187   bool is_64bit() const { return flags() & F_width_64bit; }
188
189   l4_umword_t alignment() const
190   {
191     return  flags() & F_size_aligned ? (_e - _s) : _a;
192   }
193
194   virtual l4_addr_t map_iomem() const
195   {
196     if (type() != Mmio_res)
197       return 0;
198     return res_map_iomem(start(), size());
199   }
200
201
202 };
203
204 class Resource_provider : public Resource
205 {
206 private:
207   class _RS : public Resource_space
208   {
209   private:
210     typedef Resource::Addr Addr;
211     typedef Resource::Size Size;
212     Resource_list _rl;
213
214   public:
215     bool request(Resource *parent, Device *pdev, Resource *child, Device *cdev);
216     bool alloc(Resource *parent, Device *pdev, Resource *child, Device *cdev,
217                bool resize);
218
219     ~_RS() {}
220   };
221
222   mutable _RS _rs;
223
224 public:
225   explicit Resource_provider(unsigned long flags)
226   : Resource(flags), _rs() {}
227
228   Resource_provider(unsigned long flags, Addr s, Addr e)
229   : Resource(flags, s, e), _rs() {}
230
231   Resource_space *provided() const
232   { return &_rs; }
233
234   ~Resource_provider() {}
235
236 };
237
238 class Root_resource : public Resource
239 {
240 private:
241   Resource_space *_rs;
242
243 public:
244   Root_resource(unsigned long flags, Resource_space *rs)
245   : Resource(flags), _rs(rs) {}
246
247   Resource_space *provided() const { return _rs; }
248   void dump(int) const {}
249
250   ~Root_resource() {}
251 };
252
253
254 class Mmio_data_space : public Resource
255 {
256 private:
257   L4Re::Util::Auto_cap<L4Re::Dataspace>::Cap _ds_ram;
258
259 public:
260   L4Re::Rm::Auto_region<l4_addr_t> _r;
261
262   Mmio_data_space(Size size, unsigned long alloc_flags = 0)
263   : Resource(Mmio_res, 0, size - 1)
264   {
265     alloc_ram(size, alloc_flags);
266   }
267
268   void alloc_ram(Size size, unsigned long alloc_flags);
269
270   l4_addr_t map_iomem() const
271   {
272     return _r.get();
273   }
274 };