1 INTERFACE [sparc && leon3]:
10 /** Pic interrupt control registers (incomplete) */
11 ///+0x00: Peripheral Interrupt Mask Register
12 static Address per_mask() { return _pic_base; }
13 ///+0x04: Peripheral Priority & HI/LO Select Register1
14 static Address per_prio1() { return _pic_base + 0x04; }
15 ///+0x08: Peripheral Priority & HI/LO Select Register2
16 static Address per_prio2() { return _pic_base + 0x08; }
17 ///+0x0c: Peripheral Priority & HI/LO Select Register3
18 static Address per_prio3() { return _pic_base + 0x0c; }
19 ///+0x10: External Enable & External Types Register
20 static Address ext() { return _pic_base + 0x10; }
21 ///+0x14: Critical Priority & Main Inter. Mask Register
22 static Address main_mask() { return _pic_base + 0x14; }
23 ///+0x18: Main Inter. Priority1
24 static Address main_prio1() { return _pic_base + 0x18; }
25 ///+0x1c: Main Inter. Priority2
26 static Address main_prio2() { return _pic_base + 0x1c; }
27 ///+0x24: PerStat, MainStat, CritStat Encoded Registers
28 static Address stat() { return _pic_base + 0x24; }
31 /** Interrupt lines (sdma is missing) */
34 IRQ_CRIT = 0x0, ///Critical line
35 IRQ_MAIN = 0x1, ///Main line
36 IRQ_PER = 0x2, ///Periphal line
47 /** Interrupt senses */
51 SENSE_EDGE_RISING = 1,
52 SENSE_EDGE_FALLING = 2,
56 static Address _pic_base;
59 enum { IRQ_MAX = (IRQ_PER << IRQ_SHIFT) + NUM_PER};
60 enum { No_irq_pending = ~0U };
62 static Irq_chip_icu *main;
65 //------------------------------------------------------------------------------
66 IMPLEMENTATION [sparc && leon3]:
68 #include "boot_info.h"
71 #include "irq_chip_generic.h"
74 #include "sparc_types.h"
79 Irq_chip_icu *Pic::main;
81 class Chip : public Irq_chip_gen
84 Chip() : Irq_chip_gen(Pic::IRQ_MAX) {}
85 unsigned set_mode(Mword, unsigned) { return Irq_base::Trigger_level; }
86 void set_cpu(Mword, unsigned) {}
93 assert(cpu_lock.test());
94 //Pic::disable_locked(irq);
101 assert(cpu_lock.test());
102 //Pic::acknowledge_locked(irq);
107 Chip::mask_and_ack(Mword)
109 assert(cpu_lock.test());
110 //Pic::disable_locked(irq());
111 //Pic::acknowledge_locked(irq());
118 assert(cpu_lock.test());
119 //Pic::enable_locked(irq());
122 IMPLEMENT FIASCO_INIT
128 //------------------------------------------------------------------------------
130 * Irq number translations
134 Pic::irq_num(unsigned line, unsigned pic_num)
135 { return (line << IRQ_SHIFT) | pic_num; }
140 Pic::get_irq_num(const char *name, const char *type)
142 (void)name; (void)type;
146 PRIVATE static inline NEEDS[<cassert>]
148 Pic::pic_line(unsigned irq_num)
150 unsigned line = irq_num >> IRQ_SHIFT;
155 PRIVATE static inline NEEDS[Pic::pic_line]
157 Pic::pic_num(unsigned irq_num)
159 unsigned line = pic_line(irq_num);
160 unsigned num = irq_num & ~(~0U << IRQ_SHIFT);
165 assert(num < NUM_CRIT);
168 assert(num < NUM_MAIN);
171 assert(num < NUM_PER);
178 //-------------------------------------------------------------------------------
180 * Interface implementation
184 Pic::block_locked (unsigned irq_num)
186 disable_locked(irq_num);
189 IMPLEMENT inline NEEDS["io.h", Pic::pic_line, Pic::pic_num, Pic::set_stat_msb]
191 Pic::acknowledge_locked(unsigned irq_num)
193 unsigned line = pic_line(irq_num);
194 unsigned num = pic_num(irq_num);
196 if((line == IRQ_MAIN && (num >= 1 || num <= 3)) ||
197 (line == IRQ_CRIT && num == 0))
198 Io::set<Unsigned32>(1U << (27 - num), ext());
200 set_stat_msb(irq_num);
203 PRIVATE static inline
205 Pic::dispatch_mask(unsigned irq_num, Address *addr, unsigned *bit_offs)
207 switch(pic_line(irq_num))
218 panic("%s: Cannot handle IRQ %u", __PRETTY_FUNCTION__, irq_num);
222 PRIVATE static inline
224 Pic::set_stat_msb(unsigned irq_num)
226 switch(pic_line(irq_num))
229 Io::set<Unsigned32>(0x00200000, stat());
232 Io::set<Unsigned32>(0x20000000, stat());
235 panic("CRIT not implemented");
239 IMPLEMENT inline NEEDS[Pic::pic_num, Pic::dispatch_mask]
241 Pic::disable_locked (unsigned irq_num)
245 dispatch_mask(irq_num, &addr, &bit_offs);
246 Io::set<Unsigned32>(1U << (bit_offs - pic_num(irq_num)), addr);
249 IMPLEMENT inline NEEDS[Pic::dispatch_mask]
251 Pic::enable_locked (unsigned irq_num, unsigned /*prio*/)
255 dispatch_mask(irq_num, &addr, &bit_offs);
257 Io::clear<Unsigned32>(1U << (bit_offs - pic_num(irq_num)), addr);
260 PUBLIC static inline NEEDS["panic.h"]
265 PRIVATE static inline
267 Pic::pending_per(Unsigned32 state)
269 Unsigned32 irq = state >> 24 & 0x1f; //5 bit
272 panic("No support for bestcomm interrupt, yet\n");
274 return irq_num(IRQ_PER, irq);
277 PRIVATE static inline
279 Pic::pending_main(Unsigned32 state)
281 Unsigned32 irq = state >> 16 & 0x1f;
285 return pending_per(state);
287 return irq_num(IRQ_MAIN, irq);
290 PUBLIC static inline NEEDS[Pic::pending_main, Pic::pending_per]
294 Unsigned32 irq = No_irq_pending;
299 * disable interrupt lines [0-3]
303 Pic::disable_all_save()
311 Pic::restore_all(Status s)
313 Io::write<Unsigned32>(s, ext());
316 // ------------------------------------------------------------------------
317 IMPLEMENTATION [debug && sparc && leon3]:
321 Chip::chip_type() const
322 { return "HW Mpc52xx IRQ"; }