/[gxemul]/trunk/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

Diff of /trunk/src/devices/dev_jazz.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2004-2006  Anders Gavare.  All rights reserved.   *  Copyright (C) 2004-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_jazz.c,v 1.23 2006/02/09 20:02:59 debug Exp $   *  $Id: dev_jazz.c,v 1.29 2007/06/15 19:11:15 debug Exp $
29   *     *  
30   *  Microsoft Jazz-related stuff (Acer PICA-61, etc).   *  COMMENT: Microsoft Jazz-related stuff (Acer PICA-61, etc)
31   *   *
32   *  TODO/NOTE: This is mostly a quick hack, it doesn't really implement   *  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   *  much of the Jazz architecture.  Also, the a0/20 isa-like stuff is
34   *  not supposed to be here.   *  not supposed to be here.
35     *
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   */   */
45    
46  #include <stdio.h>  #include <stdio.h>
# Line 41  Line 50 
50  #include "cpu.h"  #include "cpu.h"
51  #include "device.h"  #include "device.h"
52  #include "devices.h"  #include "devices.h"
53    #include "interrupt.h"
54  #include "machine.h"  #include "machine.h"
55  #include "memory.h"  #include "memory.h"
56  #include "misc.h"  #include "misc.h"
57    #include "timer.h"
58    
59  #include "jazz_r4030_dma.h"  #include "jazz_r4030_dma.h"
60  #include "pica.h"  #include "pica.h"
61    
62    
63    #define DEV_JAZZ_LENGTH                 0x280
64  #define DEV_JAZZ_TICKSHIFT              14  #define DEV_JAZZ_TICKSHIFT              14
   
65  #define PICA_TIMER_IRQ                  15  #define PICA_TIMER_IRQ                  15
66    
67    struct jazz_data {
68            struct interrupt mips_irq_3;
69            struct interrupt mips_irq_4;
70            struct interrupt mips_irq_6;
71    
72            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  /*  /*
150   *  dev_jazz_dma_controller():   *  dev_jazz_dma_controller():
# Line 134  size_t dev_jazz_dma_controller(void *dma Line 226  size_t dev_jazz_dma_controller(void *dma
226  }  }
227    
228    
229  /*  static void timer_tick(struct timer *t, void *extra)
230   *  dev_jazz_tick():  {
231   */          struct jazz_data *d = extra;
232  void dev_jazz_tick(struct cpu *cpu, void *extra)          d->pending_timer_interrupts ++;
233    }
234    
235    
236    DEVICE_TICK(jazz)
237  {  {
238          struct jazz_data *d = extra;          struct jazz_data *d = extra;
239    
# Line 146  void dev_jazz_tick(struct cpu *cpu, void Line 242  void dev_jazz_tick(struct cpu *cpu, void
242              && (d->int_enable_mask & 2) /* Hm? */ ) {              && (d->int_enable_mask & 2) /* Hm? */ ) {
243                  d->interval -= 2;                  d->interval -= 2;
244                  if (d->interval <= 0) {                  if (d->interval <= 0) {
245                          debug("[ jazz: interval timer interrupt ]\n");                          /*  debug("[ jazz: interval timer interrupt ]\n");
246                          cpu_interrupt(cpu, 8 + PICA_TIMER_IRQ);                            INTERRUPT_ASSERT(d->jazz_timer_irq);  */
247                  }                  }
248    
249                    /*  New timer system:  */
250                    if (d->pending_timer_interrupts > 0)
251                            INTERRUPT_ASSERT(d->jazz_timer_irq);
252          }          }
253    
254          /*  Linux?  */          /*  Linux?  */
# Line 156  void dev_jazz_tick(struct cpu *cpu, void Line 256  void dev_jazz_tick(struct cpu *cpu, void
256                  d->jazz_timer_current -= 5;                  d->jazz_timer_current -= 5;
257                  if (d->jazz_timer_current < 1) {                  if (d->jazz_timer_current < 1) {
258                          d->jazz_timer_current = d->jazz_timer_value;                          d->jazz_timer_current = d->jazz_timer_value;
259                          cpu_interrupt(cpu, 6);                          /*  INTERRUPT_ASSERT(d->mips_irq_6);  */
260                  }                  }
261    
262                    /*  New timer system:  */
263                    if (d->pending_timer_interrupts > 0)
264                            INTERRUPT_ASSERT(d->mips_irq_6);
265          }          }
266  }  }
267    
268    
 /*  
  *  dev_jazz_access():  
  */  
269  DEVICE_ACCESS(jazz)  DEVICE_ACCESS(jazz)
270  {  {
271          struct jazz_data *d = (struct jazz_data *) extra;          struct jazz_data *d = extra;
272          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
273          int regnr;          int regnr;
274    
# Line 264  printf("R4030_SYS_ISA_VECTOR: w=%i\n", w Line 365  printf("R4030_SYS_ISA_VECTOR: w=%i\n", w
365                  break;                  break;
366          case R4030_SYS_IT_STAT:          case R4030_SYS_IT_STAT:
367                  /*  Accessing this word seems to acknowledge interrupts?  */                  /*  Accessing this word seems to acknowledge interrupts?  */
368                  cpu_interrupt_ack(cpu, 8 + PICA_TIMER_IRQ);                  INTERRUPT_DEASSERT(d->jazz_timer_irq);
369                    if (d->pending_timer_interrupts > 0)
370                            d->pending_timer_interrupts --;
371    
372                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
373                          d->interval = idata;                          d->interval = idata;
374                  else                  else
# Line 273  printf("R4030_SYS_ISA_VECTOR: w=%i\n", w Line 377  printf("R4030_SYS_ISA_VECTOR: w=%i\n", w
377                  break;                  break;
378          case R4030_SYS_EXT_IMASK:          case R4030_SYS_EXT_IMASK:
379                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
380                            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                          d->int_enable_mask = idata;                          d->int_enable_mask = idata;
387                          /*  Do a "nonsense" interrupt recalibration:  */  
388                          cpu_interrupt_ack(cpu, 8);                          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                  } else                  } else
403                          odata = d->int_enable_mask;                          odata = d->int_enable_mask;
404                  break;                  break;
# Line 297  printf("R4030_SYS_ISA_VECTOR: w=%i\n", w Line 420  printf("R4030_SYS_ISA_VECTOR: w=%i\n", w
420  }  }
421    
422    
 /*  
  *  dev_jazz_led_access():  
  */  
423  DEVICE_ACCESS(jazz_led)  DEVICE_ACCESS(jazz_led)
424  {  {
425          struct jazz_data *d = (struct jazz_data *) extra;          struct jazz_data *d = extra;
426          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
427          int regnr;          int regnr;
428    
# Line 348  DEVICE_ACCESS(jazz_led) Line 468  DEVICE_ACCESS(jazz_led)
468   */   */
469  DEVICE_ACCESS(jazz_a0)  DEVICE_ACCESS(jazz_a0)
470  {  {
471          struct jazz_data *d = (struct jazz_data *) extra;          struct jazz_data *d = extra;
472          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
473    
474          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
# Line 359  DEVICE_ACCESS(jazz_a0) Line 479  DEVICE_ACCESS(jazz_a0)
479                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
480                          /*  TODO: only if idata == 0x20?  */                          /*  TODO: only if idata == 0x20?  */
481                          d->isa_int_asserted &= 0xff;                          d->isa_int_asserted &= 0xff;
482                          cpu_interrupt_ack(cpu, 8 + 0);  
483                            reassert_isa_interrupts(d);
484                  }                  }
485                  break;                  break;
486          case 1:          case 1:
# Line 369  DEVICE_ACCESS(jazz_a0) Line 490  DEVICE_ACCESS(jazz_a0)
490                              (d->isa_int_enable_mask & 0xff) | idata;                              (d->isa_int_enable_mask & 0xff) | idata;
491                          debug("[ jazz_isa_a0: setting isa_int_enable_mask "                          debug("[ jazz_isa_a0: setting isa_int_enable_mask "
492                              "to 0x%04x ]\n", (int)d->isa_int_enable_mask);                              "to 0x%04x ]\n", (int)d->isa_int_enable_mask);
493                          /*  Recompute interrupt stuff:  */  
494                          cpu_interrupt_ack(cpu, 8 + 0);                          reassert_isa_interrupts(d);
495                  } else                  } else
496                          odata = d->isa_int_enable_mask;                          odata = d->isa_int_enable_mask;
497                  break;                  break;
# Line 399  DEVICE_ACCESS(jazz_a0) Line 520  DEVICE_ACCESS(jazz_a0)
520   */   */
521  DEVICE_ACCESS(jazz_20)  DEVICE_ACCESS(jazz_20)
522  {  {
523          struct jazz_data *d = (struct jazz_data *) extra;          struct jazz_data *d = extra;
524          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
525    
526          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
# Line 410  DEVICE_ACCESS(jazz_20) Line 531  DEVICE_ACCESS(jazz_20)
531                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
532                          /*  TODO: only if idata == 0x20?  */                          /*  TODO: only if idata == 0x20?  */
533                          d->isa_int_asserted &= 0xff00;                          d->isa_int_asserted &= 0xff00;
534                          cpu_interrupt_ack(cpu, 8 + 0);                          reassert_isa_interrupts(d);
535                  }                  }
536                  break;                  break;
537          case 1:          case 1:
# Line 420  DEVICE_ACCESS(jazz_20) Line 541  DEVICE_ACCESS(jazz_20)
541                              (d->isa_int_enable_mask & 0xff00) | idata;                              (d->isa_int_enable_mask & 0xff00) | idata;
542                          debug("[ jazz_isa_20: setting isa_int_enable_mask "                          debug("[ jazz_isa_20: setting isa_int_enable_mask "
543                              "to 0x%04x ]\n", (int)d->isa_int_enable_mask);                              "to 0x%04x ]\n", (int)d->isa_int_enable_mask);
544                          /*  Recompute interrupt stuff:  */  
545                          cpu_interrupt_ack(cpu, 8 + 0);                          reassert_isa_interrupts(d);
546                  } else                  } else
547                          odata = d->isa_int_enable_mask;                          odata = d->isa_int_enable_mask;
548                  break;                  break;
# Line 451  DEVICE_ACCESS(jazz_20) Line 572  DEVICE_ACCESS(jazz_20)
572   */   */
573  DEVICE_ACCESS(jazz_jazzio)  DEVICE_ACCESS(jazz_jazzio)
574  {  {
575          struct jazz_data *d = (struct jazz_data *) extra;          struct jazz_data *d = extra;
576          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
577          int i, v;          int i, v;
578    
# Line 489  DEVICE_ACCESS(jazz_jazzio) Line 610  DEVICE_ACCESS(jazz_jazzio)
610          }          }
611    
612          /*  This is needed by Windows NT during startup:  */          /*  This is needed by Windows NT during startup:  */
613          cpu_interrupt_ack(cpu, 3);          INTERRUPT_DEASSERT(d->mips_irq_3);
614    
615          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)
616                  memory_writemax64(cpu, data, len, odata);                  memory_writemax64(cpu, data, len, odata);
# Line 500  DEVICE_ACCESS(jazz_jazzio) Line 621  DEVICE_ACCESS(jazz_jazzio)
621    
622  DEVINIT(jazz)  DEVINIT(jazz)
623  {  {
624          struct jazz_data *d = malloc(sizeof(struct jazz_data));          struct jazz_data *d;
625          if (d == NULL) {          char tmpstr[300];
626                  fprintf(stderr, "out of memory\n");          int i;
627                  exit(1);  
628          }          CHECK_ALLOCATION(d = malloc(sizeof(struct jazz_data)));
629          memset(d, 0, sizeof(struct jazz_data));          memset(d, 0, sizeof(struct jazz_data));
630    
631          d->cpu = devinit->machine->cpus[0];     /*  TODO  */          d->cpu = devinit->machine->cpus[0];     /*  TODO  */
632    
633          d->isa_int_enable_mask = 0xffff;          d->isa_int_enable_mask = 0xffff;
634    
635            /*
636             *  Register 16 native JAZZ irqs, and 16 ISA irqs:
637             *
638             *  emul[x].machine[y].cpu[z].jazz.%i           (native)
639             *  emul[x].machine[y].cpu[z].jazz.isa.%i       (ISA)
640             */
641            for (i=0; i<16; i++) {
642                    struct interrupt template;
643                    char n[300];
644                    snprintf(n, sizeof(n), "%s.jazz.%i",
645                        devinit->interrupt_path, i);
646                    memset(&template, 0, sizeof(template));
647                    template.line = i;
648                    template.name = n;
649                    template.extra = d;
650                    template.interrupt_assert = jazz_interrupt_assert;
651                    template.interrupt_deassert = jazz_interrupt_deassert;
652                    interrupt_handler_register(&template);
653            }
654            for (i=0; i<16; i++) {
655                    struct interrupt template;
656                    char n[300];
657                    snprintf(n, sizeof(n), "%s.jazz.isa.%i",
658                        devinit->interrupt_path, i);
659                    memset(&template, 0, sizeof(template));
660                    template.line = i;
661                    template.name = n;
662                    template.extra = d;
663                    template.interrupt_assert = jazz_isa_interrupt_assert;
664                    template.interrupt_deassert = jazz_isa_interrupt_deassert;
665                    interrupt_handler_register(&template);
666            }
667    
668            /*  Connect to MIPS CPU interrupt lines:  */
669            snprintf(tmpstr, sizeof(tmpstr), "%s.3", devinit->interrupt_path);
670            INTERRUPT_CONNECT(tmpstr, d->mips_irq_3);
671            snprintf(tmpstr, sizeof(tmpstr), "%s.4", devinit->interrupt_path);
672            INTERRUPT_CONNECT(tmpstr, d->mips_irq_4);
673            snprintf(tmpstr, sizeof(tmpstr), "%s.6", devinit->interrupt_path);
674            INTERRUPT_CONNECT(tmpstr, d->mips_irq_6);
675    
676            /*  Connect to JAZZ timer interrupt:  */
677            snprintf(tmpstr, sizeof(tmpstr), "%s.jazz.%i",
678                devinit->interrupt_path, PICA_TIMER_IRQ);
679            INTERRUPT_CONNECT(tmpstr, d->jazz_timer_irq);
680    
681          memory_device_register(devinit->machine->memory, "jazz",          memory_device_register(devinit->machine->memory, "jazz",
682              devinit->addr, DEV_JAZZ_LENGTH,              devinit->addr, DEV_JAZZ_LENGTH,
683              dev_jazz_access, (void *)d, DM_DEFAULT, NULL);              dev_jazz_access, (void *)d, DM_DEFAULT, NULL);
# Line 530  DEVINIT(jazz) Line 697  DEVINIT(jazz)
697              0xf0000000ULL, 4, dev_jazz_jazzio_access, (void *)d,              0xf0000000ULL, 4, dev_jazz_jazzio_access, (void *)d,
698              DM_DEFAULT, NULL);              DM_DEFAULT, NULL);
699    
700            /*  Add a timer, hardcoded to 100 Hz. TODO: Don't hardcode!  */
701            d->timer = timer_add(100.0, timer_tick, d);
702          machine_add_tickfunction(devinit->machine, dev_jazz_tick,          machine_add_tickfunction(devinit->machine, dev_jazz_tick,
703              d, DEV_JAZZ_TICKSHIFT);              d, DEV_JAZZ_TICKSHIFT);
704    

Legend:
Removed from v.22  
changed lines
  Added in v.42

  ViewVC Help
Powered by ViewVC 1.1.26