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.
14 #include <l4/vbus/vbus_types.h>
17 #include <l4/re/dataspace>
18 #include <l4/re/util/cap_alloc>
27 class Resource_list : public std::vector<Resource *>
31 * \brief Find a resource by their ID.
32 * \param id The resource id (usually 4 letters ASCII, little endian
34 * \return The first resource with the given ID, or null_ptr if non found.
36 Resource *find(l4_uint32_t id) const;
39 * \brief Find a resource by their ID (using a 4-letter string).
40 * \param id The resource id (usually up to 4 letters ASCII).
41 * \return The first resource with the given ID, or null_ptr if non found.
43 Resource *find(char const *id) const;
49 virtual bool request(Resource *parent, Device *pdev,
50 Resource *child, Device *cdev) = 0;
51 virtual bool alloc(Resource *parent, Device *pdev,
52 Resource *child, Device *cdev, bool resize) = 0;
53 virtual ~Resource_space() = 0;
56 inline Resource_space::~Resource_space() {}
66 typedef l4_uint64_t Addr;
67 typedef l4_int64_t Size;
71 Invalid_res = L4VBUS_RESOURCE_INVALID,
72 Irq_res = L4VBUS_RESOURCE_IRQ,
73 Mmio_res = L4VBUS_RESOURCE_MEM,
74 Io_res = L4VBUS_RESOURCE_PORT,
75 Bus_res = L4VBUS_RESOURCE_BUS,
76 Gpio_res = L4VBUS_RESOURCE_GPIO
83 F_hierarchical = 0x0200,
84 F_prefetchable = 0x0400,
85 F_size_aligned = 0x0800,
88 F_can_resize = 0x4000,
91 F_width_64bit = 0x010000,
92 F_relative = 0x040000,
94 Irq_type_base = 0x100000,
95 Irq_type_mask = L4_IRQ_F_MASK * Irq_type_base,
96 Irq_type_none = L4_IRQ_F_NONE * Irq_type_base,
97 Irq_type_level_high = L4_IRQ_F_LEVEL_HIGH * Irq_type_base,
98 Irq_type_level_low = L4_IRQ_F_LEVEL_LOW * Irq_type_base,
99 Irq_type_raising_edge = L4_IRQ_F_POS_EDGE * Irq_type_base,
100 Irq_type_falling_edge = L4_IRQ_F_NEG_EDGE * Irq_type_base,
101 Irq_type_both_edges = L4_IRQ_F_BOTH_EDGE * Irq_type_base,
104 bool irq_is_level_triggered() const
105 { return (_f & Irq_type_mask) & (L4_IRQ_F_LEVEL * Irq_type_base); }
107 bool irq_is_low_polarity() const
108 { return (_f & Irq_type_mask) & (L4_IRQ_F_NEG * Irq_type_base); }
110 explicit Resource(unsigned long flags = 0)
111 : _f(flags), _id(0), _p(0), _s(0), _e(0), _a(0) {}
113 Resource(unsigned long flags, Addr start, Addr end)
114 : _f(flags), _id(0), _p(0), _s(start), _e(end), _a(end - start)
117 Resource(unsigned type, unsigned long flags, Addr start, Addr end)
118 : _f((type & F_type_mask) | (flags & ~(unsigned long)F_type_mask)),
119 _id(0), _p(0), _s(start), _e(end), _a(end - start)
122 unsigned long flags() const { return _f; }
123 void add_flags(unsigned long flags) { _f |= flags; }
124 void del_flags(unsigned long flags) { _f &= ~flags; }
125 bool hierarchical() const { return _f & F_hierarchical; }
126 bool disabled() const { return _f & F_disabled; }
127 bool prefetchable() const { return _f & F_prefetchable; }
128 bool empty() const { return _f & F_empty; }
129 bool fixed_addr() const { return !(_f & F_can_move); }
130 bool fixed_size() const { return !(_f & F_can_resize); }
131 bool relative() const { return _f & F_relative; }
132 unsigned type() const { return _f & F_type_mask; }
134 virtual bool lt_compare(Resource const *o) const
135 { return end() < o->start(); }
137 static l4_uint32_t str_to_id(char const *id)
140 for (unsigned i = 0; i < 4 && id && id[i]; ++i)
141 res |= (l4_uint32_t)id[i] << (8 * i);
145 void set_id(l4_uint32_t id)
148 void set_id(char const *id)
149 { _id = str_to_id(id); }
151 l4_uint32_t id() const { return _id; }
156 void set_empty(bool empty)
165 void disable() { _f |= F_disabled; }
166 void enable() { _f &= ~F_disabled; }
168 virtual Resource_space *provided() const { return 0; }
170 void dump(char const *type, int indent) const;
171 virtual void dump(int indent = 0) const;
173 virtual bool compatible(Resource *consumer, bool pref = true) const
175 if (type() != consumer->type())
178 return prefetchable() == (consumer->prefetchable() && pref);
181 Resource *parent() const { return _p; }
182 void parent(Resource *p) { _p = p; }
184 virtual ~Resource() {}
190 void _start_end(Addr s, Addr e) { _s = s; _e = e; }
193 void set_empty() { _s = _e = 0; set_empty(true); }
194 void alignment(Size a)
197 del_flags(F_size_aligned);
200 bool valid() const { return flags() && _s <= _e; }
208 Addr start() const { return _s; }
209 Addr end() const { return _e; }
210 Size size() const { return (Size)_e + 1 - _s; }
212 bool contains(Resource const &o) const
213 { return start() <= o.start() && end() >= o.end(); }
215 void start(Addr start) { _e = start + (_e - _s); _s = start; }
228 void start_end(Addr start, Addr end)
230 _start_end(start, end);
234 void start_size(Addr start, Size s)
236 _start_end(start, start - 1 + s);
240 bool is_64bit() const { return flags() & F_width_64bit; }
242 l4_umword_t alignment() const
244 return flags() & F_size_aligned ? (_e - _s) : _a;
247 virtual l4_addr_t map_iomem() const
249 if (type() != Mmio_res)
251 return res_map_iomem(start(), size());
254 virtual l4vbus_device_handle_t provider_device_handle() const
258 class Resource_provider : public Resource
261 class _RS : public Resource_space
264 typedef Resource::Addr Addr;
265 typedef Resource::Size Size;
269 bool request(Resource *parent, Device *pdev, Resource *child, Device *cdev);
270 bool alloc(Resource *parent, Device *pdev, Resource *child, Device *cdev,
279 explicit Resource_provider(unsigned long flags)
280 : Resource(flags), _rs() {}
282 Resource_provider(unsigned long flags, Addr s, Addr e)
283 : Resource(flags, s, e), _rs() {}
285 Resource_space *provided() const
289 class Root_resource : public Resource
295 Root_resource(unsigned long flags, Resource_space *rs)
296 : Resource(flags), _rs(rs) {}
298 Resource_space *provided() const { return _rs; }
299 void dump(int) const {}
303 class Mmio_data_space : public Resource
306 L4Re::Util::Auto_cap<L4Re::Dataspace>::Cap _ds_ram;
309 L4Re::Rm::Auto_region<l4_addr_t> _r;
311 Mmio_data_space(Size size, unsigned long alloc_flags = 0)
312 : Resource(Mmio_res, 0, size - 1)
314 alloc_ram(size, alloc_flags);
317 void alloc_ram(Size size, unsigned long alloc_flags);
319 l4_addr_t map_iomem() const