]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/irq_pin.cpp
update
[l4.git] / kernel / fiasco / src / kern / irq_pin.cpp
1 INTERFACE:
2
3 #include "types.h"
4 #include "globals.h"
5
6 #include <cstddef>
7 #include <cstring>
8
9 class Irq_pin
10 {
11 private:
12   enum Flags
13   {
14     F_enabled = 1,
15   };
16
17 public:
18   bool __mask() { bool o = masked(); _flags &= ~F_enabled; return o; }
19   bool __unmask() { bool o = masked(); _flags |= F_enabled; return o; }
20
21 public:
22   void *operator new (size_t, void *p) { return p; }
23
24   virtual void do_mask() = 0;
25   virtual void do_unmask() = 0;
26   virtual void do_mask_and_ack() = 0;
27   virtual void do_set_mode(unsigned) {};
28
29   virtual void ack() = 0;
30   virtual void set_cpu(unsigned) = 0;
31   virtual bool check_debug_irq() { return true; }
32   virtual void disable() {}
33   virtual void unbind_irq() = 0;
34
35   void mask() { if (!__mask()) do_mask(); }
36   void mask_and_ack() { do_mask_and_ack(); }
37   void unmask() { if (__unmask()) do_unmask(); }
38   void set_mode(unsigned m)
39   { _flags = (_flags & ~6) | (m & 6); do_set_mode(m); }
40
41   unsigned get_mode() const
42   { return _flags & 6; }
43
44   bool masked() const { return !(_flags & F_enabled); }
45   Mword flags() const { return _flags; }
46
47   Mword *payload() { return _payload; }
48
49 private:
50   void __redo_flags()
51   {
52     do_set_mode(_flags & 6);
53
54     if (masked())
55       do_mask();
56     else
57       do_unmask();
58   }
59
60 public:
61   template<typename Pin>
62   void replace()
63   { new (this) Pin(); __redo_flags(); }
64
65   template<typename Pin, typename Arg>
66   void replace(Arg a)
67   { new (this) Pin(a); __redo_flags(); }
68
69   template<typename Pin, typename A1, typename A2>
70   void replace(A1 a1, A2 a2)
71   { new (this) Pin(a1, a2); __redo_flags(); }
72
73   Mword const *payload() const { return _payload; }
74
75 private:
76   Mword _flags;
77   Mword _payload[1];
78
79 };
80
81
82 class Irq_pin_dummy : public Irq_pin
83 {
84 public:
85   void do_unmask() {}
86   void do_mask() {}
87   void unbind_irq() {}
88   void ack() {}
89   void do_mask_and_ack() { __mask(); }
90   void do_set_mode(unsigned) {}
91   void set_cpu(unsigned) {}
92   char const *pin_type() const { return "DUMMY"; }
93 };
94
95 class Kobject_iface;
96
97 class Sw_irq_pin : public Irq_pin_dummy
98 {};
99
100 class Irq_base
101 {
102 public:
103   Irq_base() : _next(0)
104   {
105     memset(&_pin, 0, sizeof(_pin));
106     new (&_pin) Irq_pin_dummy();
107   }
108
109   Irq_pin *pin() { return (Irq_pin*)_pin; }
110   Irq_pin const *pin() const { return (Irq_pin const*)_pin; }
111   virtual void hit() {}
112
113 protected:
114   typedef char Pin[sizeof (Irq_pin)] __attribute__((aligned(__alignof__(Irq_pin))));
115   Pin _pin;
116
117 public:
118   Irq_base *_next;
119
120   static Irq_base *(*dcast)(Kobject_iface *);
121 };
122
123 //----------------------------------------------------------------------------
124 INTERFACE [debug]:
125
126 EXTENSION class Irq_pin
127 {
128 public:
129   virtual char const *pin_type() const = 0;
130 };
131
132
133 //----------------------------------------------------------------------------
134 IMPLEMENTATION:
135
136 #include "types.h"
137 #include "cpu_lock.h"
138 #include "lock_guard.h"
139
140 Irq_base *(*Irq_base::dcast)(Kobject_iface *);
141
142 PUBLIC static inline NEEDS["types.h"]
143 Irq_base *
144 Irq_base::self(Irq_pin const *pin)
145 {
146 #define MYoffsetof(TYPE, MEMBER) (((size_t) &((TYPE *)10)->MEMBER) - 10)
147   return reinterpret_cast<Irq_base*>(reinterpret_cast<Mword>(pin)
148       - MYoffsetof(Irq_base, _pin));
149 #undef MYoffsetof
150 }
151
152 PUBLIC inline NEEDS["lock_guard.h", "cpu_lock.h"]
153 void
154 Irq_base::destroy()
155 {
156   Lock_guard<Cpu_lock> g(&cpu_lock);
157   pin()->unbind_irq();
158   pin()->replace<Sw_irq_pin>();
159 }
160
161 PUBLIC
162 char const *
163 Sw_irq_pin::pin_type() const
164 { return "SW IRQ"; }
165