2 * (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
3 * economic rights: Technische Universität Dresden (Germany)
5 * This file is part of TUD:OS and distributed under the terms of the
6 * GNU General Public License 2.
7 * Please see the COPYING-GPL-2 file for details.
11 #include <l4/sys/capability>
15 #include <l4/cxx/ipc_server>
16 #include <l4/cxx/avl_tree>
17 #include <l4/cxx/list>
19 #include <l4/re/util/cap_alloc>
25 class Sw_icu : public Device, public Dev_feature, public L4::Server_object
31 int dispatch(l4_umword_t obj, L4::Ipc_iostream &ios);
33 char const *hid() const { return "L40009"; }
34 int dispatch(l4_umword_t, l4_uint32_t func, L4::Ipc_iostream &ios);
35 bool match_hw_feature(Hw::Dev_feature const *) const { return false; }
37 bool add_irqs(Adr_resource const *r);
38 bool irqs_allocated(Adr_resource const *r);
41 int bind_irq(l4_msgtag_t tag, unsigned irqn, L4::Snd_fpage const &irqc);
42 int unbind_irq(l4_msgtag_t tag, unsigned irqn, L4::Snd_fpage const &irqc);
43 int unmask_irq(l4_msgtag_t tag, unsigned irqn);
44 int set_mode(l4_msgtag_t tag, unsigned irqn, l4_umword_t mode);
58 friend class Sw_irq_pin;
60 L4::Cap<L4::Irq> _irq;
61 unsigned short _flags;
62 unsigned short _max_sw_irqs;
64 void chg_flags(bool set, unsigned flags)
73 L4::Cap<L4::Irq> irq() const { return _irq; }
75 Io_irq_pin() : _sw_irqs(0), _irq(), _flags(0), _max_sw_irqs(0) {}
77 void set_shareable(bool s)
78 { chg_flags(s, F_shareable); }
80 void set_chained(bool s)
81 { chg_flags(s, F_chained); }
84 void add_sw_irq() { ++_max_sw_irqs; }
85 virtual int bind(L4::Cap<L4::Irq> irq, unsigned mode) = 0;
86 virtual int unmask() = 0;
87 virtual int unbind() = 0;
88 virtual ~Io_irq_pin() {}
90 bool shared() const { return _max_sw_irqs > 1; }
91 bool shareable() const { return _flags & F_shareable; }
92 bool chained() const { return _flags & F_chained; }
95 class Sw_irq_pin : public cxx::Avl_tree_node
101 S_unmask_via_icu = 2,
107 L4Re::Util::Auto_cap<L4::Irq>::Cap _irq;
112 S_irq_type_level = Adr_resource::Irq_level,
113 S_irq_type_edge = Adr_resource::Irq_edge,
114 S_irq_type_high = Adr_resource::Irq_high,
115 S_irq_type_low = Adr_resource::Irq_low,
116 S_irq_type_mode_mask = S_irq_type_level | S_irq_type_edge,
117 S_irq_type_polarity_mask = S_irq_type_high | S_irq_type_low,
118 S_irq_type_mask = S_irq_type_level | S_irq_type_edge
119 | S_irq_type_high | S_irq_type_low,
122 typedef unsigned Key_type;
124 static unsigned key_of(Sw_irq_pin const *o) { return o->_irqn; }
126 Sw_irq_pin(Io_irq_pin *master, unsigned irqn, unsigned flags)
127 : _state(flags & S_irq_type_mask), _irqn(irqn), _master(master)
129 master->add_sw_irq();
132 unsigned irqn() const { return _irqn; }
133 L4::Cap<L4::Irq> irq() const { return _irq.get(); }
135 bool bound() const { return _state & S_bound; }
136 bool unmask_via_icu() const { return _state & S_unmask_via_icu; }
137 unsigned type() const { return _state & S_irq_type_mask; }
138 unsigned l4_type() const;
139 int bind(L4::Cap<void> rc);
140 int unmask() { return _master->unmask(); }
146 // int share(L4Re::Util::Auto_cap<L4::Irq>::Cap const &irq);
147 void allocate_master_irq();
151 class Real_irq_pin : public Io_irq_pin
154 Real_irq_pin() : Io_irq_pin() {}
155 int bind(L4::Cap<L4::Irq> irq, unsigned mode);
160 static Real_irq_pin *real_irq(unsigned n);
161 static Real_irq_pin _real_irqs[];
164 typedef cxx::Avl_tree<Sw_irq_pin, Sw_irq_pin> Irq_set;
166 //cxx::Bitmap<512> _allowed;
168 static void *irq_loop(void*);