]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/io/server/src/vicu.h
update
[l4.git] / l4 / pkg / io / server / src / vicu.h
1 /*
2  * (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
3  *     economic rights: Technische Universität Dresden (Germany)
4  *
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.
8  */
9 #pragma once
10
11 #include <l4/sys/capability>
12 #include <l4/sys/irq>
13 #include <l4/sys/icu>
14
15 #include <l4/cxx/ipc_server>
16 #include <l4/cxx/avl_tree>
17 #include <l4/cxx/list>
18
19 #include <l4/re/util/cap_alloc>
20
21 #include "irqs.h"
22 #include "vdevice.h"
23
24 namespace Vi {
25
26 class Sw_icu : public Device, public Dev_feature, public L4::Server_object
27 {
28 public:
29   Sw_icu();
30   virtual ~Sw_icu();
31
32   int dispatch(l4_umword_t obj, L4::Ipc_iostream &ios);
33
34   char const *hid() const { return "L40009"; }
35   int dispatch(l4_umword_t, l4_uint32_t func, L4::Ipc_iostream &ios);
36   bool match_hw_feature(Hw::Dev_feature const *) const { return false; }
37
38   bool add_irqs(Adr_resource const *r);
39   bool add_irq(unsigned n, unsigned flags, Io_irq_pin *be);
40   int alloc_irq(unsigned flags, Io_irq_pin *be);
41   bool irqs_allocated(Adr_resource const *r);
42
43 private:
44   int bind_irq(l4_msgtag_t tag, unsigned irqn, L4::Snd_fpage const &irqc);
45   int unbind_irq(l4_msgtag_t tag, unsigned irqn, L4::Snd_fpage const &irqc);
46   int unmask_irq(l4_msgtag_t tag, unsigned irqn);
47   int set_mode(l4_msgtag_t tag, unsigned irqn, l4_umword_t mode);
48
49
50   class Sw_irq_pin : public cxx::Avl_tree_node
51   {
52   private:
53     enum
54     {
55       S_bound = 1,
56       S_unmask_via_icu = 2,
57     };
58
59     unsigned _state;
60     unsigned _irqn;
61     Io_irq_pin *_master;
62     L4Re::Util::Auto_cap<L4::Irq>::Cap _irq;
63
64   public:
65     enum Irq_type
66     {
67       S_irq_type_level = Adr_resource::Irq_level,
68       S_irq_type_edge  = Adr_resource::Irq_edge,
69       S_irq_type_high  = Adr_resource::Irq_high,
70       S_irq_type_low   = Adr_resource::Irq_low,
71       S_irq_type_mode_mask = S_irq_type_level | S_irq_type_edge,
72       S_irq_type_polarity_mask = S_irq_type_high | S_irq_type_low,
73       S_irq_type_mask  = S_irq_type_level | S_irq_type_edge
74                          | S_irq_type_high | S_irq_type_low,
75     };
76
77     typedef unsigned Key_type;
78
79     static unsigned key_of(Sw_irq_pin const *o) { return o->_irqn; }
80
81     Sw_irq_pin(Io_irq_pin *master, unsigned irqn, unsigned flags)
82     : _state(flags & S_irq_type_mask), _irqn(irqn), _master(master)
83     {
84       master->add_sw_irq();
85     }
86
87     unsigned irqn() const { return _irqn; }
88     L4::Cap<L4::Irq> irq() const { return _irq.get(); }
89
90     bool bound() const { return _state & S_bound; }
91     bool unmask_via_icu() const { return _state & S_unmask_via_icu; }
92     unsigned type() const { return _state & S_irq_type_mask; }
93     unsigned l4_type() const;
94     int bind(L4::Cap<void> rc);
95     int unmask() { return _master->unmask(); }
96     int unbind();
97     int trigger() const;
98
99   protected:
100     int _unbind();
101 //    int share(L4Re::Util::Auto_cap<L4::Irq>::Cap const &irq);
102     void allocate_master_irq();
103   };
104
105   static Kernel_irq_pin *real_irq(unsigned n);
106   static Kernel_irq_pin *_real_irqs[];
107
108   typedef cxx::Avl_tree<Sw_irq_pin, Sw_irq_pin> Irq_set;
109   Irq_set _irqs;
110
111 public:
112   static void *irq_loop(void*);
113   void set_host(Device *d) { _host = d; }
114   Device *host() const { return _host; }
115
116 private:
117   Device *_host;
118 };
119
120 }