/[gxemul]/upstream/0.4.4/src/devices/dev_jazz.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /upstream/0.4.4/src/devices/dev_jazz.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 35 - (hide annotations)
Mon Oct 8 16:21:26 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 18332 byte(s)
0.4.4
1 dpavlin 4 /*
2 dpavlin 34 * Copyright (C) 2004-2007 Anders Gavare. All rights reserved.
3 dpavlin 4 *
4     * Redistribution and use in source and binary forms, with or without
5     * modification, are permitted provided that the following conditions are met:
6     *
7     * 1. Redistributions of source code must retain the above copyright
8     * notice, this list of conditions and the following disclaimer.
9     * 2. Redistributions in binary form must reproduce the above copyright
10     * notice, this list of conditions and the following disclaimer in the
11     * documentation and/or other materials provided with the distribution.
12     * 3. The name of the author may not be used to endorse or promote products
13     * derived from this software without specific prior written permission.
14     *
15     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18     * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25     * SUCH DAMAGE.
26     *
27     *
28 dpavlin 34 * $Id: dev_jazz.c,v 1.27 2007/01/28 13:28:27 debug Exp $
29 dpavlin 4 *
30     * Microsoft Jazz-related stuff (Acer PICA-61, etc).
31 dpavlin 22 *
32     * TODO/NOTE: This is mostly a quick hack, it doesn't really implement
33     * much of the Jazz architecture. Also, the a0/20 isa-like stuff is
34     * not supposed to be here.
35 dpavlin 34 *
36     * TODO: Figure out how the int enable mask works; it seems to be shifted
37     * 10 bits (?) according to NetBSD/arc sources.
38     *
39     * TODO: Don't hardcode the timer to 100 Hz.
40     *
41     * JAZZ interrupts 0..14 are connected to MIPS irq 3,
42     * JAZZ interrupt 15 (the timer) is connected to MIPS irq 6,
43     * and ISA interrupts 0..15 are connected to MIPS irq 4.
44 dpavlin 4 */
45    
46     #include <stdio.h>
47     #include <stdlib.h>
48     #include <string.h>
49    
50     #include "cpu.h"
51     #include "device.h"
52     #include "devices.h"
53 dpavlin 34 #include "interrupt.h"
54 dpavlin 4 #include "machine.h"
55     #include "memory.h"
56     #include "misc.h"
57 dpavlin 34 #include "timer.h"
58 dpavlin 4
59     #include "jazz_r4030_dma.h"
60     #include "pica.h"
61    
62    
63 dpavlin 34 #define DEV_JAZZ_LENGTH 0x280
64 dpavlin 4 #define DEV_JAZZ_TICKSHIFT 14
65     #define PICA_TIMER_IRQ 15
66    
67 dpavlin 34 struct jazz_data {
68     struct interrupt mips_irq_3;
69     struct interrupt mips_irq_4;
70     struct interrupt mips_irq_6;
71 dpavlin 4
72 dpavlin 34 struct cpu *cpu;
73    
74     /* Jazz stuff: */
75     uint32_t int_enable_mask; /* TODO! */
76     uint32_t int_asserted;
77    
78     /* ISA stuff: */
79     uint32_t isa_int_enable_mask;
80     uint32_t isa_int_asserted;
81    
82     int interval;
83     int interval_start;
84    
85     struct timer *timer;
86     int pending_timer_interrupts;
87     int jazz_timer_value;
88     int jazz_timer_current;
89     struct interrupt jazz_timer_irq;
90    
91     uint64_t dma_translation_table_base;
92     uint64_t dma_translation_table_limit;
93    
94     uint32_t dma0_mode;
95     uint32_t dma0_enable;
96     uint32_t dma0_count;
97     uint32_t dma0_addr;
98    
99     uint32_t dma1_mode;
100     /* same for dma1,2,3 actually (TODO) */
101    
102     int led;
103     };
104    
105    
106     void reassert_isa_interrupts(struct jazz_data *d)
107     {
108     if (d->isa_int_asserted & d->isa_int_enable_mask)
109     INTERRUPT_ASSERT(d->mips_irq_4);
110     else
111     INTERRUPT_DEASSERT(d->mips_irq_4);
112     }
113    
114    
115     void jazz_interrupt_assert(struct interrupt *interrupt)
116     {
117     struct jazz_data *d = interrupt->extra;
118     d->int_asserted |= (1 << interrupt->line);
119    
120     if (d->int_asserted & 0x7fff)
121     INTERRUPT_ASSERT(d->mips_irq_3);
122     if (d->int_asserted & 0x8000)
123     INTERRUPT_ASSERT(d->mips_irq_6);
124     }
125     void jazz_interrupt_deassert(struct interrupt *interrupt)
126     {
127     struct jazz_data *d = interrupt->extra;
128     d->int_asserted &= ~(1 << interrupt->line);
129    
130     if (!(d->int_asserted & 0x7fff))
131     INTERRUPT_DEASSERT(d->mips_irq_3);
132     if (!(d->int_asserted & 0x8000))
133     INTERRUPT_DEASSERT(d->mips_irq_6);
134     }
135     void jazz_isa_interrupt_assert(struct interrupt *interrupt)
136     {
137     struct jazz_data *d = interrupt->extra;
138     d->isa_int_asserted |= (1 << interrupt->line);
139     reassert_isa_interrupts(d);
140     }
141     void jazz_isa_interrupt_deassert(struct interrupt *interrupt)
142     {
143     struct jazz_data *d = interrupt->extra;
144     d->isa_int_asserted &= ~(1 << interrupt->line);
145     reassert_isa_interrupts(d);
146     }
147    
148    
149 dpavlin 4 /*
150     * dev_jazz_dma_controller():
151     */
152     size_t dev_jazz_dma_controller(void *dma_controller_data,
153     unsigned char *data, size_t len, int writeflag)
154     {
155     struct jazz_data *d = (struct jazz_data *) dma_controller_data;
156     struct cpu *cpu = d->cpu;
157     int i, enab_writeflag;
158     int res, ncpy;
159     uint32_t dma_addr;
160     unsigned char tr[sizeof(uint32_t)];
161     uint32_t phys_addr;
162    
163     #if 0
164     fatal("[ dev_jazz_dma_controller(): writeflag=%i, len=%i, data =",
165     writeflag, (int)len);
166     for (i=0; i<len; i++)
167     fatal(" %02x", data[i]);
168     fatal(" mode=%08x enable=%08x count=%08x addr=%08x",
169     d->dma0_mode, d->dma0_enable, d->dma0_count, d->dma0_addr);
170     fatal(" table=%08x",
171     d->dma_translation_table_base);
172     fatal(" ]\n");
173     #endif
174    
175     if (!(d->dma0_enable & R4030_DMA_ENAB_RUN)) {
176     fatal("[ dev_jazz_dma_controller(): dma not enabled? ]\n");
177     /* return 0; */
178     }
179    
180     /* R4030 "write" means write to the device, writeflag as the
181     argument to this function means write to memory. */
182     enab_writeflag = (d->dma0_enable & R4030_DMA_ENAB_WRITE)? 0 : 1;
183     if (enab_writeflag != writeflag) {
184     fatal("[ dev_jazz_dma_controller(): wrong direction? ]\n");
185     return 0;
186     }
187    
188     dma_addr = d->dma0_addr;
189     i = 0;
190 dpavlin 22 while (dma_addr < d->dma0_addr + d->dma0_count && i < (int32_t)len) {
191 dpavlin 4
192     res = cpu->memory_rw(cpu, cpu->mem,
193     d->dma_translation_table_base + (dma_addr >> 12) * 8,
194     tr, sizeof(tr), 0, PHYSICAL | NO_EXCEPTIONS);
195    
196     if (cpu->byte_order==EMUL_BIG_ENDIAN)
197     phys_addr = (tr[0] << 24) + (tr[1] << 16) +
198     (tr[2] << 8) + tr[3];
199     else
200     phys_addr = (tr[3] << 24) + (tr[2] << 16) +
201     (tr[1] << 8) + tr[0];
202     phys_addr &= ~0xfff; /* just in case */
203     phys_addr += (dma_addr & 0xfff);
204    
205     /* fatal(" !!! dma_addr = %08x, phys_addr = %08x\n",
206     (int)dma_addr, (int)phys_addr); */
207    
208     /* Speed up the copying by copying 16 or 256 bytes: */
209     ncpy = 1;
210 dpavlin 22 if ((phys_addr & 15) == 0 && i + 15 <= (int32_t)len)
211 dpavlin 4 ncpy = 15;
212 dpavlin 22 if ((phys_addr & 255) == 0 && i + 255 <= (int32_t)len)
213 dpavlin 4 ncpy = 255;
214    
215     res = cpu->memory_rw(cpu, cpu->mem, phys_addr,
216     &data[i], ncpy, writeflag, PHYSICAL | NO_EXCEPTIONS);
217    
218     dma_addr += ncpy;
219     i += ncpy;
220     }
221    
222     /* TODO: Is this correct? */
223     d->dma0_count = 0;
224    
225     return len;
226     }
227    
228    
229 dpavlin 34 static void timer_tick(struct timer *t, void *extra)
230 dpavlin 4 {
231     struct jazz_data *d = extra;
232 dpavlin 34 d->pending_timer_interrupts ++;
233     }
234 dpavlin 4
235 dpavlin 34
236     DEVICE_TICK(jazz)
237     {
238     struct jazz_data *d = extra;
239    
240 dpavlin 4 /* Used by NetBSD/arc and OpenBSD/arc: */
241     if (d->interval_start > 0 && d->interval > 0
242     && (d->int_enable_mask & 2) /* Hm? */ ) {
243     d->interval -= 2;
244     if (d->interval <= 0) {
245 dpavlin 34 /* debug("[ jazz: interval timer interrupt ]\n");
246     INTERRUPT_ASSERT(d->jazz_timer_irq); */
247 dpavlin 4 }
248 dpavlin 34
249     /* New timer system: */
250     if (d->pending_timer_interrupts > 0)
251     INTERRUPT_ASSERT(d->jazz_timer_irq);
252 dpavlin 4 }
253    
254     /* Linux? */
255     if (d->jazz_timer_value != 0) {
256     d->jazz_timer_current -= 5;
257     if (d->jazz_timer_current < 1) {
258     d->jazz_timer_current = d->jazz_timer_value;
259 dpavlin 34 /* INTERRUPT_ASSERT(d->mips_irq_6); */
260 dpavlin 4 }
261 dpavlin 34
262     /* New timer system: */
263     if (d->pending_timer_interrupts > 0)
264     INTERRUPT_ASSERT(d->mips_irq_6);
265 dpavlin 4 }
266     }
267    
268    
269 dpavlin 22 DEVICE_ACCESS(jazz)
270 dpavlin 4 {
271     struct jazz_data *d = (struct jazz_data *) extra;
272     uint64_t idata = 0, odata = 0;
273     int regnr;
274    
275 dpavlin 18 if (writeflag == MEM_WRITE)
276     idata = memory_readmax64(cpu, data, len);
277    
278 dpavlin 4 regnr = relative_addr / sizeof(uint32_t);
279    
280     switch (relative_addr) {
281     case R4030_SYS_CONFIG:
282     if (writeflag == MEM_WRITE) {
283     fatal("[ jazz: unimplemented write to R4030_SYS_CONFIG"
284     ", data=0x%08x ]\n", (int)idata);
285     } else {
286     /* Reading the config register should give
287     0x0104 or 0x0410. Why? TODO */
288     odata = 0x104;
289     }
290     break;
291     case R4030_SYS_TL_BASE:
292     if (writeflag == MEM_WRITE) {
293     d->dma_translation_table_base = idata;
294     } else {
295     odata = d->dma_translation_table_base;
296     }
297     break;
298     case R4030_SYS_TL_LIMIT:
299     if (writeflag == MEM_WRITE) {
300     d->dma_translation_table_limit = idata;
301     } else {
302     odata = d->dma_translation_table_limit;
303     }
304     break;
305     case R4030_SYS_TL_IVALID:
306     /* TODO: Does invalidation actually need to be implemented? */
307     break;
308     case R4030_SYS_DMA0_REGS:
309     if (writeflag == MEM_WRITE) {
310     d->dma0_mode = idata;
311     } else {
312     odata = d->dma0_mode;
313     }
314     break;
315     case R4030_SYS_DMA0_REGS + 0x8:
316     if (writeflag == MEM_WRITE) {
317     d->dma0_enable = idata;
318     } else {
319     odata = d->dma0_enable;
320     }
321     break;
322     case R4030_SYS_DMA0_REGS + 0x10:
323     if (writeflag == MEM_WRITE) {
324     d->dma0_count = idata;
325     } else {
326     odata = d->dma0_count;
327     }
328     break;
329     case R4030_SYS_DMA0_REGS + 0x18:
330     if (writeflag == MEM_WRITE) {
331     d->dma0_addr = idata;
332     } else {
333     odata = d->dma0_addr;
334     }
335     break;
336     case R4030_SYS_DMA1_REGS:
337     if (writeflag == MEM_WRITE) {
338     d->dma1_mode = idata;
339     } else {
340     odata = d->dma1_mode;
341     }
342     break;
343     case R4030_SYS_ISA_VECTOR:
344     /* ? */
345     printf("R4030_SYS_ISA_VECTOR: w=%i\n", writeflag);
346     {
347     uint32_t x = d->isa_int_asserted
348     & d->isa_int_enable_mask;
349     odata = 0;
350     while (odata < 16) {
351     if (x & (1 << odata))
352     break;
353     odata ++;
354     }
355     if (odata >= 16)
356     odata = 0;
357     }
358     break;
359     case R4030_SYS_IT_VALUE: /* Interval timer reload value */
360     if (writeflag == MEM_WRITE) {
361     d->interval_start = idata;
362     d->interval = d->interval_start;
363     } else
364     odata = d->interval_start;
365     break;
366     case R4030_SYS_IT_STAT:
367     /* Accessing this word seems to acknowledge interrupts? */
368 dpavlin 34 INTERRUPT_DEASSERT(d->jazz_timer_irq);
369     if (d->pending_timer_interrupts > 0)
370     d->pending_timer_interrupts --;
371    
372 dpavlin 4 if (writeflag == MEM_WRITE)
373     d->interval = idata;
374     else
375     odata = d->interval;
376     d->interval = d->interval_start;
377     break;
378     case R4030_SYS_EXT_IMASK:
379     if (writeflag == MEM_WRITE) {
380 dpavlin 34 int old_assert_3 = (0x7fff &
381     d->int_asserted & d->int_enable_mask);
382     int old_assert_6 = (0x8000 &
383     d->int_asserted & d->int_enable_mask);
384     int new_assert_3, new_assert_6;
385    
386 dpavlin 4 d->int_enable_mask = idata;
387 dpavlin 34
388     new_assert_3 =
389     d->int_asserted & d->int_enable_mask & 0x7fff;
390     new_assert_6 =
391     d->int_asserted & d->int_enable_mask & 0x8000;
392    
393     if (old_assert_3 && !new_assert_3)
394     INTERRUPT_DEASSERT(d->mips_irq_3);
395     else if (!old_assert_3 && new_assert_3)
396     INTERRUPT_ASSERT(d->mips_irq_3);
397    
398     if (old_assert_6 && !new_assert_6)
399     INTERRUPT_DEASSERT(d->mips_irq_6);
400     else if (!old_assert_6 && new_assert_6)
401     INTERRUPT_ASSERT(d->mips_irq_6);
402 dpavlin 4 } else
403     odata = d->int_enable_mask;
404     break;
405     default:
406     if (writeflag == MEM_WRITE) {
407     fatal("[ jazz: unimplemented write to address 0x%x"
408     ", data=0x%02x ]\n", (int)relative_addr,
409     (int)idata);
410     } else {
411     fatal("[ jazz: unimplemented read from address 0x%x"
412     " ]\n", (int)relative_addr);
413     }
414     }
415    
416     if (writeflag == MEM_READ)
417     memory_writemax64(cpu, data, len, odata);
418    
419     return 1;
420     }
421    
422    
423 dpavlin 22 DEVICE_ACCESS(jazz_led)
424 dpavlin 4 {
425     struct jazz_data *d = (struct jazz_data *) extra;
426     uint64_t idata = 0, odata = 0;
427     int regnr;
428    
429 dpavlin 18 if (writeflag == MEM_WRITE)
430     idata = memory_readmax64(cpu, data, len);
431    
432 dpavlin 4 regnr = relative_addr / sizeof(uint32_t);
433    
434     switch (relative_addr) {
435     case 0:
436     if (writeflag == MEM_WRITE) {
437     d->led = idata;
438     debug("[ jazz_led: write to LED: 0x%02x ]\n",
439     (int)idata);
440     } else {
441     odata = d->led;
442     }
443     break;
444     default:
445     if (writeflag == MEM_WRITE) {
446     fatal("[ jazz_led: unimplemented write to address 0x%x"
447     ", data=0x%02x ]\n", (int)relative_addr,
448     (int)idata);
449     } else {
450     fatal("[ jazz_led: unimplemented read from address 0x%x"
451     " ]\n", (int)relative_addr);
452     }
453     }
454    
455     if (writeflag == MEM_READ)
456     memory_writemax64(cpu, data, len, odata);
457    
458     return 1;
459     }
460    
461    
462     /*
463 dpavlin 22 * dev_jazz_a0_access():
464 dpavlin 4 *
465     * ISA interrupt stuff, high 8 interrupts.
466 dpavlin 22 *
467     * TODO: use isa8 stuff instead!
468 dpavlin 4 */
469 dpavlin 22 DEVICE_ACCESS(jazz_a0)
470 dpavlin 4 {
471     struct jazz_data *d = (struct jazz_data *) extra;
472     uint64_t idata = 0, odata = 0;
473    
474 dpavlin 18 if (writeflag == MEM_WRITE)
475     idata = memory_readmax64(cpu, data, len);
476 dpavlin 4
477     switch (relative_addr) {
478     case 0:
479     if (writeflag == MEM_WRITE) {
480     /* TODO: only if idata == 0x20? */
481     d->isa_int_asserted &= 0xff;
482 dpavlin 34
483     reassert_isa_interrupts(d);
484 dpavlin 4 }
485     break;
486     case 1:
487     if (writeflag == MEM_WRITE) {
488     idata = ((idata ^ 0xff) & 0xff) << 8;
489     d->isa_int_enable_mask =
490     (d->isa_int_enable_mask & 0xff) | idata;
491     debug("[ jazz_isa_a0: setting isa_int_enable_mask "
492     "to 0x%04x ]\n", (int)d->isa_int_enable_mask);
493 dpavlin 34
494     reassert_isa_interrupts(d);
495 dpavlin 4 } else
496     odata = d->isa_int_enable_mask;
497     break;
498     default:
499     if (writeflag == MEM_WRITE) {
500     fatal("[ jazz_isa_a0: unimplemented write to "
501     "address 0x%x, data=0x%02x ]\n",
502     (int)relative_addr, (int)idata);
503     } else {
504     fatal("[ jazz_isa_a0: unimplemented read from "
505     "address 0x%x ]\n", (int)relative_addr);
506     }
507     }
508    
509     if (writeflag == MEM_READ)
510     memory_writemax64(cpu, data, len, odata);
511    
512     return 1;
513     }
514    
515    
516     /*
517 dpavlin 22 * dev_jazz_20_access():
518 dpavlin 4 *
519     * ISA interrupt stuff, low 8 interrupts.
520     */
521 dpavlin 22 DEVICE_ACCESS(jazz_20)
522 dpavlin 4 {
523     struct jazz_data *d = (struct jazz_data *) extra;
524     uint64_t idata = 0, odata = 0;
525    
526 dpavlin 18 if (writeflag == MEM_WRITE)
527     idata = memory_readmax64(cpu, data, len);
528 dpavlin 4
529     switch (relative_addr) {
530     case 0:
531     if (writeflag == MEM_WRITE) {
532     /* TODO: only if idata == 0x20? */
533     d->isa_int_asserted &= 0xff00;
534 dpavlin 34 reassert_isa_interrupts(d);
535 dpavlin 4 }
536     break;
537     case 1:
538     if (writeflag == MEM_WRITE) {
539     idata = (idata ^ 0xff) & 0xff;
540     d->isa_int_enable_mask =
541     (d->isa_int_enable_mask & 0xff00) | idata;
542     debug("[ jazz_isa_20: setting isa_int_enable_mask "
543     "to 0x%04x ]\n", (int)d->isa_int_enable_mask);
544 dpavlin 34
545     reassert_isa_interrupts(d);
546 dpavlin 4 } else
547     odata = d->isa_int_enable_mask;
548     break;
549     default:
550     if (writeflag == MEM_WRITE) {
551     fatal("[ jazz_isa_20: unimplemented write to "
552     "address 0x%x, data=0x%02x ]\n",
553     (int)relative_addr, (int)idata);
554     } else {
555     fatal("[ jazz_isa_20: unimplemented read from "
556     "address 0x%x ]\n", (int)relative_addr);
557     }
558     }
559    
560     if (writeflag == MEM_READ)
561     memory_writemax64(cpu, data, len, odata);
562    
563     return 1;
564     }
565    
566    
567     /*
568 dpavlin 22 * dev_jazz_jazzio_access():
569 dpavlin 4 *
570     * See jazzio_intr() in NetBSD's
571     * /usr/src/sys/arch/arc/jazz/jazzio.c for more info.
572     */
573 dpavlin 22 DEVICE_ACCESS(jazz_jazzio)
574 dpavlin 4 {
575     struct jazz_data *d = (struct jazz_data *) extra;
576     uint64_t idata = 0, odata = 0;
577     int i, v;
578    
579 dpavlin 18 if (writeflag == MEM_WRITE)
580     idata = memory_readmax64(cpu, data, len);
581 dpavlin 4
582     switch (relative_addr) {
583     case 0:
584     v = 0;
585     for (i=0; i<15; i++) {
586     if (d->int_asserted & (1<<i)) {
587     v = i+1;
588     break;
589     }
590     }
591     odata = v << 2;
592     break;
593     case 2:
594     /* TODO: Should this be here?! */
595    
596     if (writeflag == MEM_WRITE)
597     d->jazz_timer_value = idata;
598     else
599     odata = d->jazz_timer_value;
600     break;
601     default:
602     if (writeflag == MEM_WRITE) {
603     fatal("[ jazzio: unimplemented write to address 0x%x"
604     ", data=0x%02x ]\n", (int)relative_addr,
605     (int)idata);
606     } else {
607     fatal("[ jazzio: unimplemented read from address 0x%x"
608     " ]\n", (int)relative_addr);
609     }
610     }
611    
612     /* This is needed by Windows NT during startup: */
613 dpavlin 34 INTERRUPT_DEASSERT(d->mips_irq_3);
614 dpavlin 4
615     if (writeflag == MEM_READ)
616     memory_writemax64(cpu, data, len, odata);
617    
618     return 1;
619     }
620    
621    
622 dpavlin 22 DEVINIT(jazz)
623 dpavlin 4 {
624 dpavlin 34 char tmpstr[300];
625     int i;
626 dpavlin 4 struct jazz_data *d = malloc(sizeof(struct jazz_data));
627     if (d == NULL) {
628     fprintf(stderr, "out of memory\n");
629     exit(1);
630     }
631     memset(d, 0, sizeof(struct jazz_data));
632    
633     d->cpu = devinit->machine->cpus[0]; /* TODO */
634    
635     d->isa_int_enable_mask = 0xffff;
636    
637 dpavlin 34 /*
638     * Register 16 native JAZZ irqs, and 16 ISA irqs:
639     *
640     * emul[x].machine[y].cpu[z].jazz.%i (native)
641     * emul[x].machine[y].cpu[z].jazz.isa.%i (ISA)
642     */
643     for (i=0; i<16; i++) {
644     struct interrupt template;
645     char n[300];
646     snprintf(n, sizeof(n), "%s.jazz.%i",
647     devinit->interrupt_path, i);
648     memset(&template, 0, sizeof(template));
649     template.line = i;
650     template.name = n;
651     template.extra = d;
652     template.interrupt_assert = jazz_interrupt_assert;
653     template.interrupt_deassert = jazz_interrupt_deassert;
654     interrupt_handler_register(&template);
655     }
656     for (i=0; i<16; i++) {
657     struct interrupt template;
658     char n[300];
659     snprintf(n, sizeof(n), "%s.jazz.isa.%i",
660     devinit->interrupt_path, i);
661     memset(&template, 0, sizeof(template));
662     template.line = i;
663     template.name = n;
664     template.extra = d;
665     template.interrupt_assert = jazz_isa_interrupt_assert;
666     template.interrupt_deassert = jazz_isa_interrupt_deassert;
667     interrupt_handler_register(&template);
668     }
669    
670     /* Connect to MIPS CPU interrupt lines: */
671     snprintf(tmpstr, sizeof(tmpstr), "%s.3", devinit->interrupt_path);
672     INTERRUPT_CONNECT(tmpstr, d->mips_irq_3);
673     snprintf(tmpstr, sizeof(tmpstr), "%s.4", devinit->interrupt_path);
674     INTERRUPT_CONNECT(tmpstr, d->mips_irq_4);
675     snprintf(tmpstr, sizeof(tmpstr), "%s.6", devinit->interrupt_path);
676     INTERRUPT_CONNECT(tmpstr, d->mips_irq_6);
677    
678     /* Connect to JAZZ timer interrupt: */
679     snprintf(tmpstr, sizeof(tmpstr), "%s.jazz.%i",
680     devinit->interrupt_path, PICA_TIMER_IRQ);
681     INTERRUPT_CONNECT(tmpstr, d->jazz_timer_irq);
682    
683 dpavlin 4 memory_device_register(devinit->machine->memory, "jazz",
684     devinit->addr, DEV_JAZZ_LENGTH,
685 dpavlin 20 dev_jazz_access, (void *)d, DM_DEFAULT, NULL);
686 dpavlin 4
687     /* At least for Magnum and Pica-61: */
688     memory_device_register(devinit->machine->memory, "jazz_led",
689     0x08000f000ULL, 4, dev_jazz_led_access, (void *)d,
690 dpavlin 20 DM_DEFAULT, NULL);
691 dpavlin 4
692     memory_device_register(devinit->machine->memory, "jazz_isa_20",
693 dpavlin 22 0x90000020ULL, 2, dev_jazz_20_access, (void *)d, DM_DEFAULT, NULL);
694 dpavlin 4
695     memory_device_register(devinit->machine->memory, "jazz_isa_a0",
696 dpavlin 22 0x900000a0ULL, 2, dev_jazz_a0_access, (void *)d, DM_DEFAULT, NULL);
697 dpavlin 4
698     memory_device_register(devinit->machine->memory, "pica_jazzio",
699 dpavlin 22 0xf0000000ULL, 4, dev_jazz_jazzio_access, (void *)d,
700 dpavlin 20 DM_DEFAULT, NULL);
701 dpavlin 4
702 dpavlin 34 /* Add a timer, hardcoded to 100 Hz. TODO: Don't hardcode! */
703     d->timer = timer_add(100.0, timer_tick, d);
704 dpavlin 4 machine_add_tickfunction(devinit->machine, dev_jazz_tick,
705 dpavlin 24 d, DEV_JAZZ_TICKSHIFT, 0.0);
706 dpavlin 4
707     devinit->return_ptr = d;
708    
709     return 1;
710     }
711    

  ViewVC Help
Powered by ViewVC 1.1.26