1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#include <common.h>
35#include <asm/processor.h>
36#include <command.h>
37#include "i8259.h"
38
39#undef DEBUG
40#ifdef DEBUG
41#define PRINTF(fmt,args...) printf (fmt ,##args)
42#else
43#define PRINTF(fmt,args...)
44#endif
45#define NR_IRQS 16
46
47void irq_alloc_init(void);
48long irq_alloc(long wanted);
49
50
51
52unsigned decrementer_count;
53
54struct irq_action {
55 interrupt_handler_t *handler;
56 void *arg;
57 ulong count;
58};
59
60static struct irq_action irq_handlers[NR_IRQS];
61
62
63
64static __inline__ unsigned long
65get_msr(void)
66{
67 unsigned long msr;
68
69 asm volatile("mfmsr %0" : "=r" (msr) :);
70 return msr;
71}
72
73static __inline__ void
74set_msr(unsigned long msr)
75{
76 asm volatile("mtmsr %0" : : "r" (msr));
77}
78
79static __inline__ unsigned long
80get_dec(void)
81{
82 unsigned long val;
83
84 asm volatile("mfdec %0" : "=r" (val) :);
85 return val;
86}
87
88
89static __inline__ void
90set_dec(unsigned long val)
91{
92 asm volatile("mtdec %0" : : "r" (val));
93}
94
95
96void
97enable_interrupts(void)
98{
99 set_msr (get_msr() | MSR_EE);
100}
101
102
103int
104disable_interrupts(void)
105{
106 ulong msr;
107
108 msr = get_msr();
109 set_msr (msr & ~MSR_EE);
110 return ((msr & MSR_EE) != 0);
111}
112
113
114
115int interrupt_init (void)
116{
117 extern void new_reset(void);
118 extern void new_reset_end(void);
119#ifdef DEBUG
120 puts("interrupt_init: setting decrementer_count\n");
121#endif
122 decrementer_count = get_tbclk() / CONFIG_SYS_HZ;
123
124#ifdef DEBUG
125 puts("interrupt_init: setting actual decremter\n");
126#endif
127 set_dec (get_tbclk() / CONFIG_SYS_HZ);
128
129#ifdef DEBUG
130 puts("interrupt_init: clearing external interrupt table\n");
131#endif
132
133 memset(irq_handlers, 0, sizeof(irq_handlers));
134
135#ifdef DEBUG
136 puts("interrupt_init: initializing interrupt controller\n");
137#endif
138 i8259_init();
139
140#ifdef DEBUG
141 puts("Copying reset trampoline\n");
142#endif
143
144 memcpy((void *)0x100, new_reset, new_reset_end - new_reset);
145
146#ifdef DEBUG
147 PRINTF("interrupt_init: enabling interrupts (msr = %08x)\n",
148 get_msr());
149#endif
150 set_msr (get_msr() | MSR_EE);
151
152#ifdef DEBUG
153 PRINTF("interrupt_init: done. (msr = %08x)\n", get_msr());
154#endif
155
156}
157
158
159
160
161
162
163void
164external_interrupt(struct pt_regs *regs)
165{
166 extern int i8259_irq(void);
167
168 int irq, unmask = 1;
169
170 irq = i8259_irq();
171
172 i8259_mask_and_ack(irq);
173
174 if (irq_handlers[irq].handler != NULL)
175 (*irq_handlers[irq].handler)(irq_handlers[irq].arg);
176 else {
177 PRINTF ("\nBogus External Interrupt IRQ %d\n", irq);
178
179
180
181
182 unmask = 0;
183 }
184
185 if (unmask) i8259_unmask_irq(irq);
186}
187
188volatile ulong timestamp = 0;
189
190
191
192
193
194
195void
196timer_interrupt(struct pt_regs *regs)
197{
198 set_dec(decrementer_count);
199 timestamp++;
200}
201
202
203
204void
205reset_timer(void)
206{
207 timestamp = 0;
208}
209
210ulong
211get_timer(ulong base)
212{
213 return (timestamp - base);
214}
215
216void
217set_timer(ulong t)
218{
219 timestamp = t;
220}
221
222
223
224
225
226
227
228void
229irq_install_handler(int irq, interrupt_handler_t *handler, void *arg)
230{
231 if (irq < 0 || irq >= NR_IRQS) {
232 PRINTF("irq_install_handler: bad irq number %d\n", irq);
233 return;
234 }
235
236 if (irq_handlers[irq].handler != NULL)
237 PRINTF("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
238 (ulong)handler, (ulong)irq_handlers[irq].handler);
239
240 irq_handlers[irq].handler = handler;
241 irq_handlers[irq].arg = arg;
242
243 i8259_unmask_irq(irq);
244}
245
246void
247irq_free_handler(int irq)
248{
249 if (irq < 0 || irq >= NR_IRQS) {
250 PRINTF("irq_free_handler: bad irq number %d\n", irq);
251 return;
252 }
253
254 i8259_mask_irq(irq);
255
256 irq_handlers[irq].handler = NULL;
257 irq_handlers[irq].arg = NULL;
258}
259
260
261
262void
263do_irqinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
264{
265 puts("IRQ related functions are unimplemented currently.\n");
266}
267