2 * (c) 2010 Technische Universität Dresden
3 * This file is part of TUD:OS and distributed under the terms of the
4 * GNU General Public License 2.
5 * Please see the COPYING-GPL-2 file for details.
9 #include <l4/sys/capability>
13 #include <l4/cxx/ipc_server>
14 #include <l4/cxx/avl_tree>
15 #include <l4/cxx/list>
17 #include <l4/re/util/cap_alloc>
23 class Sw_icu : public Device, public Dev_feature, public L4::Server_object
29 int dispatch(l4_umword_t obj, L4::Ipc_iostream &ios);
31 char const *hid() const { return "L40009"; }
32 int dispatch(l4_umword_t, l4_uint32_t func, L4::Ipc_iostream &ios);
33 bool match_hw_feature(Hw::Dev_feature const *) const { return false; }
35 bool add_irqs(Adr_resource const *r);
36 bool irqs_allocated(Adr_resource const *r);
39 int bind_irq(l4_msgtag_t tag, unsigned irqn, L4::Snd_fpage const &irqc);
40 int unbind_irq(l4_msgtag_t tag, unsigned irqn, L4::Snd_fpage const &irqc);
41 int unmask_irq(l4_msgtag_t tag, unsigned irqn);
42 int set_mode(l4_msgtag_t tag, unsigned irqn, l4_umword_t mode);
56 friend class Sw_irq_pin;
58 L4::Cap<L4::Irq> _irq;
59 unsigned short _flags;
60 unsigned short _max_sw_irqs;
62 void chg_flags(bool set, unsigned flags)
71 L4::Cap<L4::Irq> irq() const { return _irq; }
73 Io_irq_pin() : _sw_irqs(0), _irq(), _flags(0), _max_sw_irqs(0) {}
75 void set_shareable(bool s)
76 { chg_flags(s, F_shareable); }
78 void set_chained(bool s)
79 { chg_flags(s, F_chained); }
82 void add_sw_irq() { ++_max_sw_irqs; }
83 virtual int bind(L4::Cap<L4::Irq> irq, unsigned mode) = 0;
84 virtual int unmask() = 0;
85 virtual int unbind() = 0;
86 virtual ~Io_irq_pin() {}
88 bool shared() const { return _max_sw_irqs > 1; }
89 bool shareable() const { return _flags & F_shareable; }
90 bool chained() const { return _flags & F_chained; }
93 class Sw_irq_pin : public cxx::Avl_tree_node
105 L4Re::Util::Auto_cap<L4::Irq>::Cap _irq;
110 S_irq_type_level = Adr_resource::Irq_level,
111 S_irq_type_edge = Adr_resource::Irq_edge,
112 S_irq_type_high = Adr_resource::Irq_high,
113 S_irq_type_low = Adr_resource::Irq_low,
114 S_irq_type_mode_mask = S_irq_type_level | S_irq_type_edge,
115 S_irq_type_polarity_mask = S_irq_type_high | S_irq_type_low,
116 S_irq_type_mask = S_irq_type_level | S_irq_type_edge
117 | S_irq_type_high | S_irq_type_low,
120 typedef unsigned Key_type;
122 static unsigned key_of(Sw_irq_pin const *o) { return o->_irqn; }
124 Sw_irq_pin(Io_irq_pin *master, unsigned irqn, unsigned flags)
125 : _state(flags & S_irq_type_mask), _irqn(irqn), _master(master)
127 master->add_sw_irq();
130 unsigned irqn() const { return _irqn; }
131 L4::Cap<L4::Irq> irq() const { return _irq.get(); }
133 bool bound() const { return _state & S_bound; }
134 bool unmask_via_icu() const { return _state & S_unmask_via_icu; }
135 unsigned type() const { return _state & S_irq_type_mask; }
136 unsigned l4_type() const;
137 int bind(L4::Cap<void> rc);
138 int unmask() { return _master->unmask(); }
144 // int share(L4Re::Util::Auto_cap<L4::Irq>::Cap const &irq);
145 void allocate_master_irq();
149 class Real_irq_pin : public Io_irq_pin
152 Real_irq_pin() : Io_irq_pin() {}
153 int bind(L4::Cap<L4::Irq> irq, unsigned mode);
158 static Real_irq_pin *real_irq(unsigned n);
159 static Real_irq_pin _real_irqs[];
162 typedef cxx::Avl_tree<Sw_irq_pin, Sw_irq_pin> Irq_set;
164 //cxx::Bitmap<512> _allowed;
166 static void *irq_loop(void*);