]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/io/server/src/vicu.h
7c6435a3ce6095d5cbdabcbe2214d11cbdb91014
[l4.git] / l4 / pkg / io / server / src / vicu.h
1 /*
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.
6  */
7 #pragma once
8
9 #include <l4/sys/capability>
10 #include <l4/sys/irq>
11 #include <l4/sys/icu>
12
13 #include <l4/cxx/ipc_server>
14 #include <l4/cxx/avl_tree>
15 #include <l4/cxx/list>
16
17 #include <l4/re/util/cap_alloc>
18
19 #include "vdevice.h"
20
21 namespace Vi {
22
23 class Sw_icu : public Device, public Dev_feature, public L4::Server_object
24 {
25 public:
26   Sw_icu();
27   virtual ~Sw_icu();
28
29   int dispatch(l4_umword_t obj, L4::Ipc_iostream &ios);
30
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; }
34
35   bool add_irqs(Adr_resource const *r);
36   bool irqs_allocated(Adr_resource const *r);
37
38 private:
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);
43
44   class Sw_irq_pin;
45
46   class Io_irq_pin
47   {
48   public:
49     enum Flags
50     {
51       F_shareable = 0x1,
52       F_chained   = 0x2,
53     };
54
55   private:
56     friend class Sw_irq_pin;
57     int _sw_irqs;
58     L4::Cap<L4::Irq> _irq;
59     unsigned short _flags;
60     unsigned short _max_sw_irqs;
61
62     void chg_flags(bool set, unsigned flags)
63     {
64       if (set)
65         _flags |= flags;
66       else
67         _flags &= ~flags;
68     }
69
70   protected:
71     L4::Cap<L4::Irq> irq() const { return _irq; }
72
73     Io_irq_pin() : _sw_irqs(0), _irq(), _flags(0), _max_sw_irqs(0) {}
74
75     void set_shareable(bool s)
76     { chg_flags(s, F_shareable); }
77
78     void set_chained(bool s)
79     { chg_flags(s, F_chained); }
80
81   public:
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() {}
87
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; }
91   };
92
93   class Sw_irq_pin : public cxx::Avl_tree_node
94   {
95   private:
96     enum
97     {
98       S_bound = 1,
99       S_unmask_via_icu = 2,
100     };
101
102     unsigned _state;
103     unsigned _irqn;
104     Io_irq_pin *_master;
105     L4Re::Util::Auto_cap<L4::Irq>::Cap _irq;
106
107   public:
108     enum Irq_type
109     {
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,
118     };
119
120     typedef unsigned Key_type;
121
122     static unsigned key_of(Sw_irq_pin const *o) { return o->_irqn; }
123
124     Sw_irq_pin(Io_irq_pin *master, unsigned irqn, unsigned flags)
125     : _state(flags & S_irq_type_mask), _irqn(irqn), _master(master)
126     {
127       master->add_sw_irq();
128     }
129
130     unsigned irqn() const { return _irqn; }
131     L4::Cap<L4::Irq> irq() const { return _irq.get(); }
132
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(); }
139     int unbind();
140     int trigger() const;
141
142   protected:
143     int _unbind();
144 //    int share(L4Re::Util::Auto_cap<L4::Irq>::Cap const &irq);
145     void allocate_master_irq();
146   };
147
148
149   class Real_irq_pin : public Io_irq_pin
150   {
151   public:
152     Real_irq_pin() : Io_irq_pin() {}
153     int bind(L4::Cap<L4::Irq> irq, unsigned mode);
154     int unmask();
155     int unbind();
156   };
157
158   static Real_irq_pin *real_irq(unsigned n);
159   static Real_irq_pin _real_irqs[];
160
161
162   typedef cxx::Avl_tree<Sw_irq_pin, Sw_irq_pin> Irq_set;
163   Irq_set _irqs;
164   //cxx::Bitmap<512> _allowed;
165 public:
166   static void *irq_loop(void*);
167 };
168
169 }