fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/arch/simarm/intc.c *
7 * Created: 2004-11-13 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2004-2013 Hampa Hug <hampa@hampa.ch> *
9 * Copyright: (C) 2004-2006 Lukas Ruf <ruf@lpr.ch> *
10 *****************************************************************************/
11
12/*****************************************************************************
13 * This program is free software. You can redistribute it and / or modify it *
14 * under the terms of the GNU General Public License version 2 as published *
15 * by the Free Software Foundation. *
16 * *
17 * This program is distributed in the hope that it will be useful, but *
18 * WITHOUT ANY WARRANTY, without even the implied warranty of *
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
20 * Public License for more details. *
21 *****************************************************************************/
22
23/*****************************************************************************
24 * This software was developed at the Computer Engineering and Networks *
25 * Laboratory (TIK), Swiss Federal Institute of Technology (ETH) Zurich. *
26 *****************************************************************************/
27
28
29#include "main.h"
30#include "intc.h"
31
32#include <stdlib.h>
33
34#include <lib/log.h>
35
36
37static unsigned char ict_get_uint8 (ixp_intc_t *ic, unsigned long addr);
38static unsigned short ict_get_uint16 (ixp_intc_t *ic, unsigned long addr);
39static unsigned long ict_get_uint32 (ixp_intc_t *ic, unsigned long addr);
40static void ict_set_uint8 (ixp_intc_t *ic, unsigned long addr, unsigned char val);
41static void ict_set_uint16 (ixp_intc_t *ic, unsigned long addr, unsigned short val);
42static void ict_set_uint32 (ixp_intc_t *ic, unsigned long addr, unsigned long val);
43
44
45static
46void *ict_irqf[32] = {
47 ict_set_irq0, ict_set_irq1, ict_set_irq2, ict_set_irq3,
48 ict_set_irq4, ict_set_irq5, ict_set_irq6, ict_set_irq7,
49 ict_set_irq8, ict_set_irq9, ict_set_irq10, ict_set_irq11,
50 ict_set_irq12, ict_set_irq13, ict_set_irq14, ict_set_irq15,
51 ict_set_irq16, ict_set_irq17, ict_set_irq18, ict_set_irq19,
52 ict_set_irq20, ict_set_irq21, ict_set_irq22, ict_set_irq23,
53 ict_set_irq24, ict_set_irq25, ict_set_irq26, ict_set_irq27,
54 ict_set_irq28, ict_set_irq29, ict_set_irq30, ict_set_irq31
55};
56
57
58void ict_init (ixp_intc_t *ict, unsigned long base)
59{
60 ict->base = base;
61
62 mem_blk_init (&ict->io, base, 0x01000000UL, 0);
63 ict->io.ext = ict;
64 ict->io.get_uint8 = (mem_get_uint8_f) ict_get_uint8;
65 ict->io.set_uint8 = (mem_set_uint8_f) ict_set_uint8;
66 ict->io.get_uint16 = (mem_get_uint16_f) ict_get_uint16;
67 ict->io.set_uint16 = (mem_set_uint16_f) ict_set_uint16;
68 ict->io.get_uint32 = (mem_get_uint32_f) ict_get_uint32;
69 ict->io.set_uint32 = (mem_set_uint32_f) ict_set_uint32;
70
71 ict->fiq = NULL;
72 ict->fiq_ext = NULL;
73 ict->fiq_val = 0;
74
75 ict->irq = NULL;
76 ict->irq_ext = NULL;
77 ict->irq_val = 0;
78
79 ict->status_raw = 0;
80 ict->status_fiq = 0;
81 ict->status_irq = 0;
82 ict->enable_fiq = 0;
83 ict->enable_irq = 0;
84}
85
86ixp_intc_t *ict_new (unsigned long base)
87{
88 ixp_intc_t *ict;
89
90 ict = malloc (sizeof (ixp_intc_t));
91 if (ict == NULL) {
92 return (NULL);
93 }
94
95 ict_init (ict, base);
96
97 return (ict);
98}
99
100void ict_free (ixp_intc_t *ict)
101{
102 mem_blk_free (&ict->io);
103}
104
105void ict_del (ixp_intc_t *ict)
106{
107 if (ict != NULL) {
108 ict_free (ict);
109 free (ict);
110 }
111}
112
113mem_blk_t *ict_get_io (ixp_intc_t *ict, unsigned i)
114{
115 if (i == 0) {
116 return (&ict->io);
117 }
118
119 return (NULL);
120}
121
122void ict_set_fiq_f (ixp_intc_t *ict, void *f, void *ext)
123{
124 ict->fiq = f;
125 ict->fiq_ext = ext;
126}
127
128void ict_set_irq_f (ixp_intc_t *ict, void *f, void *ext)
129{
130 ict->irq = f;
131 ict->irq_ext = ext;
132}
133
134void *ict_get_irq_f (ixp_intc_t *ict, unsigned irq)
135{
136 return (ict_irqf[irq & 0x1f]);
137}
138
139static
140void ict_check_fiq (ixp_intc_t *ict)
141{
142 ict->status_fiq = ict->status_raw & ict->enable_fiq;
143
144 if (ict->status_fiq) {
145 if ((ict->fiq != NULL) && (ict->fiq_val == 0)) {
146 ict->fiq (ict->fiq_ext, 1);
147 ict->fiq_val = 1;
148 }
149 }
150 else {
151 if ((ict->fiq != NULL) && (ict->fiq_val != 0)) {
152 ict->fiq (ict->fiq_ext, 0);
153 ict->fiq_val = 0;
154 }
155 }
156}
157
158static
159void ict_check_irq (ixp_intc_t *ict)
160{
161 ict->status_irq = ict->status_raw & ict->enable_irq;
162
163 if (ict->status_irq) {
164 if ((ict->irq != NULL) && (ict->irq_val == 0)) {
165 ict->irq (ict->irq_ext, 1);
166 ict->irq_val = 1;
167 }
168 }
169 else {
170 if ((ict->irq != NULL) && (ict->irq_val != 0)) {
171 ict->irq (ict->irq_ext, 0);
172 ict->irq_val = 0;
173 }
174 }
175}
176
177void ict_set_irq (ixp_intc_t *ict, unsigned i, unsigned char val)
178{
179 if (val) {
180 ict->status_raw |= (1UL << i);
181 }
182 else {
183 ict->status_raw &= ~(1UL << i);
184 }
185
186 ict_check_fiq (ict);
187 ict_check_irq (ict);
188}
189
190void ict_set_irq0 (ixp_intc_t *ict, unsigned char val)
191{
192 ict_set_irq (ict, 0, val);
193}
194
195void ict_set_irq1 (ixp_intc_t *ict, unsigned char val)
196{
197 ict_set_irq (ict, 1, val);
198}
199
200void ict_set_irq2 (ixp_intc_t *ict, unsigned char val)
201{
202 ict_set_irq (ict, 2, val);
203}
204
205void ict_set_irq3 (ixp_intc_t *ict, unsigned char val)
206{
207 ict_set_irq (ict, 3, val);
208}
209
210void ict_set_irq4 (ixp_intc_t *ict, unsigned char val)
211{
212 ict_set_irq (ict, 4, val);
213}
214
215void ict_set_irq5 (ixp_intc_t *ict, unsigned char val)
216{
217 ict_set_irq (ict, 5, val);
218}
219
220void ict_set_irq6 (ixp_intc_t *ict, unsigned char val)
221{
222 ict_set_irq (ict, 6, val);
223}
224
225void ict_set_irq7 (ixp_intc_t *ict, unsigned char val)
226{
227 ict_set_irq (ict, 7, val);
228}
229
230void ict_set_irq8 (ixp_intc_t *ict, unsigned char val)
231{
232 ict_set_irq (ict, 8, val);
233}
234
235void ict_set_irq9 (ixp_intc_t *ict, unsigned char val)
236{
237 ict_set_irq (ict, 9, val);
238}
239
240void ict_set_irq10 (ixp_intc_t *ict, unsigned char val)
241{
242 ict_set_irq (ict, 10, val);
243}
244
245void ict_set_irq11 (ixp_intc_t *ict, unsigned char val)
246{
247 ict_set_irq (ict, 11, val);
248}
249
250void ict_set_irq12 (ixp_intc_t *ict, unsigned char val)
251{
252 ict_set_irq (ict, 12, val);
253}
254
255void ict_set_irq13 (ixp_intc_t *ict, unsigned char val)
256{
257 ict_set_irq (ict, 13, val);
258}
259
260void ict_set_irq14 (ixp_intc_t *ict, unsigned char val)
261{
262 ict_set_irq (ict, 14, val);
263}
264
265void ict_set_irq15 (ixp_intc_t *ict, unsigned char val)
266{
267 ict_set_irq (ict, 15, val);
268}
269
270void ict_set_irq16 (ixp_intc_t *ict, unsigned char val)
271{
272 ict_set_irq (ict, 16, val);
273}
274
275void ict_set_irq17 (ixp_intc_t *ict, unsigned char val)
276{
277 ict_set_irq (ict, 17, val);
278}
279
280void ict_set_irq18 (ixp_intc_t *ict, unsigned char val)
281{
282 ict_set_irq (ict, 18, val);
283}
284
285void ict_set_irq19 (ixp_intc_t *ict, unsigned char val)
286{
287 ict_set_irq (ict, 19, val);
288}
289
290void ict_set_irq20 (ixp_intc_t *ict, unsigned char val)
291{
292 ict_set_irq (ict, 20, val);
293}
294
295void ict_set_irq21 (ixp_intc_t *ict, unsigned char val)
296{
297 ict_set_irq (ict, 21, val);
298}
299
300void ict_set_irq22 (ixp_intc_t *ict, unsigned char val)
301{
302 ict_set_irq (ict, 22, val);
303}
304
305void ict_set_irq23 (ixp_intc_t *ict, unsigned char val)
306{
307 ict_set_irq (ict, 23, val);
308}
309
310void ict_set_irq24 (ixp_intc_t *ict, unsigned char val)
311{
312 ict_set_irq (ict, 24, val);
313}
314
315void ict_set_irq25 (ixp_intc_t *ict, unsigned char val)
316{
317 ict_set_irq (ict, 25, val);
318}
319
320void ict_set_irq26 (ixp_intc_t *ict, unsigned char val)
321{
322 ict_set_irq (ict, 26, val);
323}
324
325void ict_set_irq27 (ixp_intc_t *ict, unsigned char val)
326{
327 ict_set_irq (ict, 27, val);
328}
329
330void ict_set_irq28 (ixp_intc_t *ict, unsigned char val)
331{
332 ict_set_irq (ict, 28, val);
333}
334
335void ict_set_irq29 (ixp_intc_t *ict, unsigned char val)
336{
337 ict_set_irq (ict, 29, val);
338}
339
340void ict_set_irq30 (ixp_intc_t *ict, unsigned char val)
341{
342 ict_set_irq (ict, 30, val);
343}
344
345void ict_set_irq31 (ixp_intc_t *ict, unsigned char val)
346{
347 ict_set_irq (ict, 31, val);
348}
349
350static
351unsigned char ict_get_uint8 (ixp_intc_t *ict, unsigned long addr)
352{
353 pce_log (MSG_DEB, "ICT: get_uint8 (%08lX)\n", addr);
354
355 return (0);
356}
357
358static
359unsigned short ict_get_uint16 (ixp_intc_t *ict, unsigned long addr)
360{
361 pce_log (MSG_DEB, "ICT: get_uint16 (%08lX)\n", addr);
362
363 return (0);
364}
365
366static
367unsigned long ict_get_uint32 (ixp_intc_t *ict, unsigned long addr)
368{
369 switch (addr) {
370 case 0x00:
371 return (ict->status_raw);
372
373 case 0x04:
374 return (ict->status_fiq);
375
376 case 0x08:
377 return (ict->status_irq);
378
379 case 0x0c:
380 return (ict->enable_fiq);
381
382 case 0x10:
383 return (ict->enable_irq);
384
385 case 0x14: /* fiq enable clr */
386 return (0);
387
388 case 0x18: /* irq enable clr */
389 return (0);
390 }
391
392 return (0);
393}
394
395static
396void ict_set_uint8 (ixp_intc_t *ict, unsigned long addr, unsigned char val)
397{
398 pce_log (MSG_DEB, "ICT: set_uint8 (%08lX, %02X)\n", addr, (unsigned) val);
399}
400
401static
402void ict_set_uint16 (ixp_intc_t *ict, unsigned long addr, unsigned short val)
403{
404 pce_log (MSG_DEB, "ICT: set_uint16 (%08lX, %04X)\n", addr, (unsigned) val);
405}
406
407static
408void ict_set_uint32 (ixp_intc_t *ict, unsigned long addr, unsigned long val)
409{
410 switch (addr) {
411 case 0x0c: /* fiq enable set */
412 ict->enable_fiq |= val;
413 ict_check_fiq (ict);
414 break;
415
416 case 0x10: /* irq enable set */
417 ict->enable_irq |= val;
418 ict_check_irq (ict);
419 break;
420
421 case 0x14: /* fiq enable clr */
422 ict->enable_fiq &= ~val;
423 ict_check_fiq (ict);
424 break;
425
426 case 0x18: /* irq enable clr */
427 ict->enable_irq &= ~val;
428 ict_check_irq (ict);
429 break;
430 }
431}