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 int set_mode(Mword, Mode) { return 0; }
86 bool is_edge_triggered(Mword) const { return false; }
87 void set_cpu(Mword, Cpu_number) {}
94 assert(cpu_lock.test());
95 //Pic::disable_locked(irq);
102 assert(cpu_lock.test());
103 //Pic::acknowledge_locked(irq);
108 Chip::mask_and_ack(Mword)
110 assert(cpu_lock.test());
111 //Pic::disable_locked(irq());
112 //Pic::acknowledge_locked(irq());
119 assert(cpu_lock.test());
120 //Pic::enable_locked(irq());
123 IMPLEMENT FIASCO_INIT
129 //------------------------------------------------------------------------------
131 * Irq number translations
135 Pic::irq_num(unsigned line, unsigned pic_num)
136 { return (line << IRQ_SHIFT) | pic_num; }
141 Pic::get_irq_num(const char *name, const char *type)
143 (void)name; (void)type;
147 PRIVATE static inline NEEDS[<cassert>]
149 Pic::pic_line(unsigned irq_num)
151 unsigned line = irq_num >> IRQ_SHIFT;
156 PRIVATE static inline NEEDS[Pic::pic_line]
158 Pic::pic_num(unsigned irq_num)
160 unsigned line = pic_line(irq_num);
161 unsigned num = irq_num & ~(~0U << IRQ_SHIFT);
166 assert(num < NUM_CRIT);
169 assert(num < NUM_MAIN);
172 assert(num < NUM_PER);
179 //-------------------------------------------------------------------------------
181 * Interface implementation
185 Pic::block_locked (unsigned irq_num)
187 disable_locked(irq_num);
190 IMPLEMENT inline NEEDS["io.h", Pic::pic_line, Pic::pic_num, Pic::set_stat_msb]
192 Pic::acknowledge_locked(unsigned irq_num)
194 unsigned line = pic_line(irq_num);
195 unsigned num = pic_num(irq_num);
197 if((line == IRQ_MAIN && (num >= 1 || num <= 3)) ||
198 (line == IRQ_CRIT && num == 0))
199 Io::set<Unsigned32>(1U << (27 - num), ext());
201 set_stat_msb(irq_num);
204 PRIVATE static inline
206 Pic::dispatch_mask(unsigned irq_num, Address *addr, unsigned *bit_offs)
208 switch(pic_line(irq_num))
219 panic("%s: Cannot handle IRQ %u", __PRETTY_FUNCTION__, irq_num);
223 PRIVATE static inline
225 Pic::set_stat_msb(unsigned irq_num)
227 switch(pic_line(irq_num))
230 Io::set<Unsigned32>(0x00200000, stat());
233 Io::set<Unsigned32>(0x20000000, stat());
236 panic("CRIT not implemented");
240 IMPLEMENT inline NEEDS[Pic::pic_num, Pic::dispatch_mask]
242 Pic::disable_locked (unsigned irq_num)
246 dispatch_mask(irq_num, &addr, &bit_offs);
247 Io::set<Unsigned32>(1U << (bit_offs - pic_num(irq_num)), addr);
250 IMPLEMENT inline NEEDS[Pic::dispatch_mask]
252 Pic::enable_locked (unsigned irq_num, unsigned /*prio*/)
256 dispatch_mask(irq_num, &addr, &bit_offs);
258 Io::clear<Unsigned32>(1U << (bit_offs - pic_num(irq_num)), addr);
261 PUBLIC static inline NEEDS["panic.h"]
266 PRIVATE static inline
268 Pic::pending_per(Unsigned32 state)
270 Unsigned32 irq = state >> 24 & 0x1f; //5 bit
273 panic("No support for bestcomm interrupt, yet\n");
275 return irq_num(IRQ_PER, irq);
278 PRIVATE static inline
280 Pic::pending_main(Unsigned32 state)
282 Unsigned32 irq = state >> 16 & 0x1f;
286 return pending_per(state);
288 return irq_num(IRQ_MAIN, irq);
291 PUBLIC static inline NEEDS[Pic::pending_main, Pic::pending_per]
295 Unsigned32 irq = No_irq_pending;
300 * disable interrupt lines [0-3]
304 Pic::disable_all_save()
312 Pic::restore_all(Status s)
314 Io::write<Unsigned32>(s, ext());
317 // ------------------------------------------------------------------------
318 IMPLEMENTATION [debug && sparc && leon3]:
322 Chip::chip_type() const
323 { return "HW Mpc52xx IRQ"; }