]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/arm/bsp/kirkwood/pic-arm-kirkwood.cpp
update
[l4.git] / kernel / fiasco / src / kern / arm / bsp / kirkwood / pic-arm-kirkwood.cpp
1 INTERFACE [arm && kirkwood]:
2
3 #include "kmem.h"
4
5 class Irq_base;
6
7 EXTENSION class Pic
8 {
9 public:
10   enum
11   {
12     Main_Irq_cause_low_reg     = Mem_layout::Pic_map_base + 0x20200,
13     Main_Irq_mask_low_reg      = Mem_layout::Pic_map_base + 0x20204,
14     Main_Fiq_mask_low_reg      = Mem_layout::Pic_map_base + 0x20208,
15     Endpoint_irq_mask_low_reg  = Mem_layout::Pic_map_base + 0x2020c,
16     Main_Irq_cause_high_reg    = Mem_layout::Pic_map_base + 0x20210,
17     Main_Irq_mask_high_reg     = Mem_layout::Pic_map_base + 0x20214,
18     Main_Fiq_mask_high_reg     = Mem_layout::Pic_map_base + 0x20218,
19     Endpoint_irq_mask_high_reg = Mem_layout::Pic_map_base + 0x2021c,
20
21     Bridge_int_num = 1,
22
23     Multi_irq_pending = 0,
24     No_irq_pending = 1023,
25   };
26 };
27
28 //-------------------------------------------------------------------
29 IMPLEMENTATION [arm && kirkwood]:
30
31 #include <cstring>
32 #include <cstdio>
33
34 #include "config.h"
35 #include "initcalls.h"
36 #include "io.h"
37 #include "irq.h"
38 #include "irq_pin.h"
39 #include "irq_chip_generic.h"
40 #include "types.h"
41 #include "vkey.h"
42
43 class Kirkwood_pin : public Irq_pin
44 {
45 public:
46   unsigned irq() const { return payload()[0]; }
47 };
48
49 class Kirkwood_pin_low : public Kirkwood_pin
50 {
51 public:
52   explicit Kirkwood_pin_low(unsigned irq) { payload()[0] = irq; }
53 };
54
55 class Kirkwood_pin_high : public Kirkwood_pin
56 {
57 public:
58   explicit Kirkwood_pin_high(unsigned irq) { payload()[0] = irq; }
59 };
60
61
62 PUBLIC
63 void
64 Kirkwood_pin::unbind_irq()
65 {
66   mask();
67   disable();
68   Irq_chip::hw_chip->free(Irq::self(this), irq());
69   replace<Sw_irq_pin>();
70 }
71
72 PUBLIC
73 void
74 Kirkwood_pin_low::do_mask()
75 {
76   assert (cpu_lock.test());
77   Io::clear<Unsigned32>(1 << irq(), Pic::Main_Irq_mask_low_reg);
78 }
79
80 PUBLIC
81 void
82 Kirkwood_pin_high::do_mask()
83 {
84   assert (cpu_lock.test());
85   Io::clear<Unsigned32>(1 << (irq() - 32), Pic::Main_Irq_mask_high_reg);
86 }
87
88 PUBLIC
89 void
90 Kirkwood_pin_low::do_mask_and_ack()
91 {
92   assert (cpu_lock.test());
93   __mask();
94   Io::clear<Unsigned32>(1 << irq(), Pic::Main_Irq_mask_low_reg);
95   // ack is empty
96 }
97
98 PUBLIC
99 void
100 Kirkwood_pin_high::do_mask_and_ack()
101 {
102   assert (cpu_lock.test());
103   __mask();
104   Io::clear<Unsigned32>(1 << (irq() - 32), Pic::Main_Irq_mask_high_reg);
105   // ack is empty
106 }
107
108 PUBLIC
109 void
110 Kirkwood_pin::ack()
111 {
112   // ack is empty
113 }
114
115 PUBLIC
116 void
117 Kirkwood_pin::hit()
118 {
119   Irq::self(this)->Irq::hit();
120 }
121
122 PUBLIC
123 void
124 Kirkwood_pin_low::do_unmask()
125 {
126   assert (cpu_lock.test());
127   Io::set<Unsigned32>(1 << irq(), Pic::Main_Irq_mask_low_reg);
128 }
129
130 PUBLIC
131 void
132 Kirkwood_pin_high::do_unmask()
133 {
134   assert (cpu_lock.test());
135   Io::set<Unsigned32>(1 << (irq() - 32), Pic::Main_Irq_mask_high_reg);
136 }
137
138 PUBLIC
139 bool
140 Kirkwood_pin::check_debug_irq()
141 {
142   return !Vkey::check_(irq());
143 }
144
145 PUBLIC
146 void
147 Kirkwood_pin::set_cpu(unsigned)
148 {
149 }
150
151
152 class Irq_chip_kirkwood : public Irq_chip_gen
153 {
154 };
155
156 PUBLIC
157 void
158 Irq_chip_kirkwood::setup(Irq_base *irq, unsigned irqnum)
159 {
160   if (irqnum < 32)
161     irq->pin()->replace<Kirkwood_pin_low>(irqnum);
162   else if (irqnum < Config::Max_num_dirqs)
163     irq->pin()->replace<Kirkwood_pin_high>(irqnum);
164 }
165
166 IMPLEMENT FIASCO_INIT
167 void Pic::init()
168 {
169   static Irq_chip_kirkwood _ia;
170   Irq_chip::hw_chip = &_ia;
171
172   // Disable all interrupts
173   Io::write<Unsigned32>(0U, Main_Irq_mask_low_reg);
174   Io::write<Unsigned32>(0U, Main_Fiq_mask_low_reg);
175   Io::write<Unsigned32>(0U, Main_Irq_mask_high_reg);
176   Io::write<Unsigned32>(0U, Main_Fiq_mask_high_reg);
177
178   // enable bridge (chain) IRQ
179   Io::set<Unsigned32>(1 << Bridge_int_num, Main_Irq_mask_low_reg);
180 }
181
182 IMPLEMENT inline
183 Pic::Status Pic::disable_all_save()
184 { return 0; }
185
186 IMPLEMENT inline
187 void Pic::restore_all(Status)
188 {}
189
190 PUBLIC static inline NEEDS[<cstdio>,"io.h"]
191 Unsigned32 Pic::pending()
192 {
193   Unsigned32 v;
194
195   v = Io::read<Unsigned32>(Main_Irq_cause_low_reg);
196   if (v & 1)
197     {
198       v = Io::read<Unsigned32>(Main_Irq_cause_high_reg);
199       for (int i = 1; i < 32; ++i)
200         if ((1 << i) & v)
201           return 32 + i;
202     }
203   for (int i = 1; i < 32; ++i)
204     if ((1 << i) & v)
205       return i;
206
207   return No_irq_pending;
208 }
209
210 PUBLIC static inline
211 Mword Pic::is_pending(Mword &irqs, Mword irq)
212 { return irqs == irq; }
213
214 //---------------------------------------------------------------------------
215 IMPLEMENTATION [debug && kirkwood]:
216
217 PUBLIC
218 char const *
219 Kirkwood_pin::pin_type() const
220 { return "HW Kirkwood IRQ"; }