/[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 24 by dpavlin, Mon Oct 8 16:19:56 2007 UTC revision 34 by dpavlin, Mon Oct 8 16:21:17 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.24 2006/03/04 12:38:47 debug Exp $   *  $Id: dev_jazz.c,v 1.27 2007/01/28 13:28:27 debug Exp $
29   *     *  
30   *  Microsoft Jazz-related stuff (Acer PICA-61, etc).   *  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 = (struct jazz_data *) extra;
# 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 = (struct jazz_data *) extra;
# 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 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 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            char tmpstr[300];
625            int i;
626          struct jazz_data *d = malloc(sizeof(struct jazz_data));          struct jazz_data *d = malloc(sizeof(struct jazz_data));
627          if (d == NULL) {          if (d == NULL) {
628                  fprintf(stderr, "out of memory\n");                  fprintf(stderr, "out of memory\n");
# Line 511  DEVINIT(jazz) Line 634  DEVINIT(jazz)
634    
635          d->isa_int_enable_mask = 0xffff;          d->isa_int_enable_mask = 0xffff;
636    
637            /*
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          memory_device_register(devinit->machine->memory, "jazz",          memory_device_register(devinit->machine->memory, "jazz",
684              devinit->addr, DEV_JAZZ_LENGTH,              devinit->addr, DEV_JAZZ_LENGTH,
685              dev_jazz_access, (void *)d, DM_DEFAULT, NULL);              dev_jazz_access, (void *)d, DM_DEFAULT, NULL);
# Line 530  DEVINIT(jazz) Line 699  DEVINIT(jazz)
699              0xf0000000ULL, 4, dev_jazz_jazzio_access, (void *)d,              0xf0000000ULL, 4, dev_jazz_jazzio_access, (void *)d,
700              DM_DEFAULT, NULL);              DM_DEFAULT, NULL);
701    
702            /*  Add a timer, hardcoded to 100 Hz. TODO: Don't hardcode!  */
703            d->timer = timer_add(100.0, timer_tick, d);
704          machine_add_tickfunction(devinit->machine, dev_jazz_tick,          machine_add_tickfunction(devinit->machine, dev_jazz_tick,
705              d, DEV_JAZZ_TICKSHIFT, 0.0);              d, DEV_JAZZ_TICKSHIFT, 0.0);
706    

Legend:
Removed from v.24  
changed lines
  Added in v.34

  ViewVC Help
Powered by ViewVC 1.1.26