/[gxemul]/trunk/src/devices/dev_vr41xx.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_vr41xx.c

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

revision 12 by dpavlin, Mon Oct 8 16:18:38 2007 UTC revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2004-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2004-2006  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_vr41xx.c,v 1.30 2005/08/05 09:11:48 debug Exp $   *  $Id: dev_vr41xx.c,v 1.41 2006/10/02 09:26:53 debug Exp $
29   *     *  
30   *  VR41xx (actually, VR4122 and VR4131) misc functions.   *  VR41xx (actually, VR4122 and VR4131) misc functions.
31   *   *
# Line 43  Line 43 
43  #include "machine.h"  #include "machine.h"
44  #include "memory.h"  #include "memory.h"
45  #include "misc.h"  #include "misc.h"
46    #include "timer.h"
47    
48  #include "bcureg.h"  #include "bcureg.h"
49  #include "vripreg.h"  #include "vripreg.h"
50  #include "vrkiureg.h"  #include "vrkiureg.h"
51    #include "vr_rtcreg.h"
52    
53    
54  #define DEV_VR41XX_TICKSHIFT            15  #define DEV_VR41XX_TICKSHIFT            14
55    
56  /*  #define debug fatal  */  /*  #define debug fatal  */
57    
# Line 73  static void vr41xx_keytick(struct cpu *c Line 75  static void vr41xx_keytick(struct cpu *c
75          /*          /*
76           *  Keyboard input:           *  Keyboard input:
77           *           *
78           *  Hardcoded for MobilePro 780. (See NetBSD's hpckbdkeymap.h for           *  Hardcoded for MobilePro. (See NetBSD's hpckbdkeymap.h for
79           *  info on other keyboard layouts. mobilepro780_keytrans is the           *  info on other keyboard layouts. mobilepro780_keytrans is the
80           *  one used here.)           *  one used here.)
81           *           *
82           *  TODO: Make this work with "any" keyboard layout.           *  TODO: Make this work with "any" keyboard layout.
83           *           *
          *  (Even MobilePro 770 seems to be different? Hm. TODO)  
          *  
84           *  ofs 0:           *  ofs 0:
85           *      8000='o' 4000='.' 2000=DOWN  1000=UP           *      8000='o' 4000='.' 2000=DOWN  1000=UP
86           *       800=';'  400='''  200='['    100=?           *       800=';'  400='''  200='['    100=?
# Line 147  static void vr41xx_keytick(struct cpu *c Line 147  static void vr41xx_keytick(struct cpu *c
147                                          d->escape_state = 2;                                          d->escape_state = 2;
148                                  break;                                  break;
149                          case 2: /*  cursor keys etc:  */                          case 2: /*  cursor keys etc:  */
150                                  switch (ch) {                                  /*  Ugly hack for Mobilepro770:  */
151                                  case 'A':       d->d0 = 0x1000; break;                                  if (cpu->machine->machine_subtype ==
152                                  case 'B':       d->d0 = 0x2000; break;                                      MACHINE_HPCMIPS_NEC_MOBILEPRO_770) {
153                                  case 'C':       d->d0 = 0x20; break;                                          switch (ch) {
154                                  case 'D':       d->d0 = 0x10; break;                                          case 'A': d->d0 = 0x2000; break;
155                                  default:        fatal("[ vr41xx kiu: "                                          case 'B': d->d0 = 0x20; break;
156                                      "unimplemented escape 0x%02 ]\n", ch);                                          case 'C': d->d0 = 0x1000; break;
157                                            case 'D': d->d0 = 0x10; break;
158                                            default:  fatal("[ vr41xx kiu: unimpl"
159                                                "emented escape 0x%02 ]\n", ch);
160                                            }
161                                    } else {
162                                            switch (ch) {
163                                            case 'A': d->d0 = 0x1000; break;
164                                            case 'B': d->d0 = 0x2000; break;
165                                            case 'C': d->d0 = 0x20; break;
166                                            case 'D': d->d0 = 0x10; break;
167                                            default:  fatal("[ vr41xx kiu: unimpl"
168                                                "emented escape 0x%02 ]\n", ch);
169                                            }
170                                  }                                  }
171                                  d->escape_state = 0;                                  d->escape_state = 0;
172                          }                          }
# Line 290  static void vr41xx_keytick(struct cpu *c Line 303  static void vr41xx_keytick(struct cpu *c
303    
304    
305  /*  /*
306   *  dev_vr41xx_tick():   *  timer_tick():
307   */   */
308  void dev_vr41xx_tick(struct cpu *cpu, void *extra)  static void timer_tick(struct timer *timer, void *extra)
309    {
310            struct vr41xx_data *d = (struct vr41xx_data *) extra;
311            d->pending_timer_interrupts ++;
312    }
313    
314    
315    DEVICE_TICK(vr41xx)
316  {  {
317          struct vr41xx_data *d = extra;          struct vr41xx_data *d = extra;
318    
319          /*          if (d->pending_timer_interrupts > 0) {
320           *  UGLY! TODO: fix this.                  if (d->cpumodel == 4121 || d->cpumodel == 4181)
321           *                          cpu_interrupt(cpu, 3);
322           *  Interrupts should be triggered if the corresponding unit (for                  else
323           *  example the RTC unit) is activated.                          cpu_interrupt(cpu, 8 + VRIP_INTR_ETIMER);
          */  
         {  
                 static unsigned int x = 0;  
                 x++;  
   
                 if (x > 100 && (x&3)==0) {  
                         if (d->cpumodel == 4121 || d->cpumodel == 4181)  
                                 cpu_interrupt(cpu, 3);  
                         else  
                                 cpu_interrupt(cpu, 8 + VRIP_INTR_ETIMER);  
                 }  
324          }          }
325    
326          if (cpu->machine->use_x11)          if (cpu->machine->use_x11)
# Line 376  static uint64_t vr41xx_kiu(struct cpu *c Line 385  static uint64_t vr41xx_kiu(struct cpu *c
385          default:          default:
386                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
387                          debug("[ vr41xx KIU: unimplemented write to offset "                          debug("[ vr41xx KIU: unimplemented write to offset "
388                              "0x%x, data=0x%016llx ]\n", ofs, (long long)idata);                              "0x%x, data=0x%016"PRIx64" ]\n", ofs,
389                                (uint64_t) idata);
390                  else                  else
391                          debug("[ vr41xx KIU: unimplemented read from offset "                          debug("[ vr41xx KIU: unimplemented read from offset "
392                              "0x%x ]\n", ofs);                              "0x%x ]\n", ofs);
# Line 386  static uint64_t vr41xx_kiu(struct cpu *c Line 396  static uint64_t vr41xx_kiu(struct cpu *c
396  }  }
397    
398    
399  /*  DEVICE_ACCESS(vr41xx)
  *  dev_vr41xx_access():  
  */  
 int dev_vr41xx_access(struct cpu *cpu, struct memory *mem,  
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
400  {  {
401          struct vr41xx_data *d = (struct vr41xx_data *) extra;          struct vr41xx_data *d = (struct vr41xx_data *) extra;
402          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
403          int regnr;          int regnr;
404          int revision = 0;          int revision = 0;
405    
406          idata = memory_readmax64(cpu, data, len);          if (writeflag == MEM_WRITE)
407                    idata = memory_readmax64(cpu, data, len);
408    
409          regnr = relative_addr / sizeof(uint64_t);          regnr = relative_addr / sizeof(uint64_t);
410    
411          /*  KIU ("Keyboard Interface Unit") is handled separately.  */          /*  KIU ("Keyboard Interface Unit") is handled separately.  */
# Line 412  int dev_vr41xx_access(struct cpu *cpu, s Line 419  int dev_vr41xx_access(struct cpu *cpu, s
419          /*  TODO: Maybe these should be handled separately as well?  */          /*  TODO: Maybe these should be handled separately as well?  */
420    
421          switch (relative_addr) {          switch (relative_addr) {
422    
423          /*  BCU:  0x00 .. 0x1c  */          /*  BCU:  0x00 .. 0x1c  */
424          case BCUREVID_REG_W:    /*  0x010  */          case BCUREVID_REG_W:    /*  0x010  */
425          case BCU81REVID_REG_W:  /*  0x014  */          case BCU81REVID_REG_W:  /*  0x014  */
# Line 488  int dev_vr41xx_access(struct cpu *cpu, s Line 496  int dev_vr41xx_access(struct cpu *cpu, s
496                          d->msysint2 = idata;                          d->msysint2 = idata;
497                  break;                  break;
498    
499          /*  PMU:  0xc0 .. 0xfc  */          /*  RTC:  */
500          /*  RTC:  0x100 .. ?  */          case 0xc0:
501            case 0xc2:
502            case 0xc4:
503                    {
504                            struct timeval tv;
505                            gettimeofday(&tv, NULL);
506                            /*  Adjust time by 120 years and 29 days.  */
507                            tv.tv_sec += (int64_t) (120*365 + 29) * 24*60*60;
508    
509                            switch (relative_addr) {
510                            case 0xc0:
511                                    odata = (tv.tv_sec & 1) << 15;
512                                    break;
513                            case 0xc2:
514                                    odata = (tv.tv_sec >> 1) & 0xffff;
515                                    break;
516                            case 0xc4:
517                                    odata = (tv.tv_sec >> 17) & 0xffff;
518                                    break;
519                            }
520                    }
521                    break;
522    
523            case 0xd0:      /*  RTCL1_L_REG_W  */
524                    if (writeflag == MEM_WRITE && idata != 0) {
525                            int hz = RTCL1_L_HZ / idata;
526                            debug("[ vr41xx: rtc interrupts at %i Hz ]\n", hz);
527                            if (d->timer == NULL)
528                                    d->timer = timer_add(hz, timer_tick, d);
529                            else
530                                    timer_update_frequency(d->timer, hz);
531                    }
532                    break;
533            case 0xd2:      /*  RTCL1_H_REG_W  */
534                    break;
535    
536          case 0x108:          case 0x108:
537                  if (writeflag == MEM_READ)                  if (writeflag == MEM_READ)
# Line 506  int dev_vr41xx_access(struct cpu *cpu, s Line 548  int dev_vr41xx_access(struct cpu *cpu, s
548                  /*  RTC interrupt register...  */                  /*  RTC interrupt register...  */
549                  /*  Ack. timer interrupts?  */                  /*  Ack. timer interrupts?  */
550                  cpu_interrupt_ack(cpu, 8 + VRIP_INTR_ETIMER);                  cpu_interrupt_ack(cpu, 8 + VRIP_INTR_ETIMER);
551                    if (d->pending_timer_interrupts > 0)
552                            d->pending_timer_interrupts --;
553                  break;                  break;
554    
555          case 0x1de:     /*  on 4121?  */          case 0x1de:     /*  on 4121?  */
556                  /*  RTC interrupt register...  */                  /*  RTC interrupt register...  */
557                  /*  Ack. timer interrupts?  */                  /*  Ack. timer interrupts?  */
558                  cpu_interrupt_ack(cpu, 3);                  cpu_interrupt_ack(cpu, 3);
559                    if (d->pending_timer_interrupts > 0)
560                            d->pending_timer_interrupts --;
561                  break;                  break;
562    
563          default:          default:
564                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
565                          debug("[ vr41xx: unimplemented write to address "                          debug("[ vr41xx: unimplemented write to address "
566                              "0x%llx, data=0x%016llx ]\n",                              "0x%"PRIx64", data=0x%016"PRIx64" ]\n",
567                              (long long)relative_addr, (long long)idata);                              (uint64_t) relative_addr, (uint64_t) idata);
568                  else                  else
569                          debug("[ vr41xx: unimplemented read from address "                          debug("[ vr41xx: unimplemented read from address "
570                              "0x%llx ]\n", (long long)relative_addr);                              "0x%"PRIx64" ]\n", (uint64_t) relative_addr);
571          }          }
572    
573  ret:  ret:
# Line 557  struct vr41xx_data *dev_vr41xx_init(stru Line 603  struct vr41xx_data *dev_vr41xx_init(stru
603    
604          /*  TODO: VRC4173 has the KIU at offset 0x100?  */          /*  TODO: VRC4173 has the KIU at offset 0x100?  */
605          d->kiu_offset = 0x180;          d->kiu_offset = 0x180;
606          d->kiu_console_handle = console_start_slave_inputonly(machine, "kiu");          d->kiu_console_handle = console_start_slave_inputonly(
607                machine, "kiu", 1);
608          d->kiu_irq_nr = VRIP_INTR_KIU;          d->kiu_irq_nr = VRIP_INTR_KIU;
609    
610          switch (cpumodel) {          switch (cpumodel) {
# Line 569  struct vr41xx_data *dev_vr41xx_init(stru Line 616  struct vr41xx_data *dev_vr41xx_init(stru
616                  break;                  break;
617          case 4181:          case 4181:
618                  baseaddr = 0xa000000;                  baseaddr = 0xa000000;
619                  dev_ram_init(mem, 0xb000000, 0x1000000, DEV_RAM_MIRROR,                  dev_ram_init(machine, 0xb000000, 0x1000000, DEV_RAM_MIRROR,
620                      0xa000000);                      0xa000000);
621                  break;                  break;
622          case 4122:          case 4122:
# Line 582  struct vr41xx_data *dev_vr41xx_init(stru Line 629  struct vr41xx_data *dev_vr41xx_init(stru
629          }          }
630    
631          memory_device_register(mem, "vr41xx", baseaddr, DEV_VR41XX_LENGTH,          memory_device_register(mem, "vr41xx", baseaddr, DEV_VR41XX_LENGTH,
632              dev_vr41xx_access, (void *)d, MEM_DEFAULT, NULL);              dev_vr41xx_access, (void *)d, DM_DEFAULT, NULL);
633    
634          /*          /*
635           *  TODO: Find out which controllers are at which addresses on           *  TODO: Find out which controllers are at which addresses on
636           *  which chips.           *  which chips.
637           */           */
638          if (cpumodel == 4131) {          if (cpumodel == 4131) {
639                  snprintf(tmps, sizeof(tmps), "ns16550 irq=%i addr=0x%llx "                  snprintf(tmps, sizeof(tmps), "ns16550 irq=%i addr=0x%"PRIx64" "
640                      "name2=siu", 8+VRIP_INTR_SIU, (long long)(baseaddr+0x800));                      "name2=siu", 8+VRIP_INTR_SIU, (uint64_t) (baseaddr+0x800));
641                  device_add(machine, tmps);                  device_add(machine, tmps);
642          } else {          } else {
643                  /*  This is used by Linux and NetBSD:  */                  /*  This is used by Linux and NetBSD:  */
# Line 603  struct vr41xx_data *dev_vr41xx_init(stru Line 650  struct vr41xx_data *dev_vr41xx_init(stru
650          device_add(machine, "pcic addr=0x140003e0");          device_add(machine, "pcic addr=0x140003e0");
651    
652          machine_add_tickfunction(machine, dev_vr41xx_tick, d,          machine_add_tickfunction(machine, dev_vr41xx_tick, d,
653              DEV_VR41XX_TICKSHIFT);              DEV_VR41XX_TICKSHIFT, 0.0);
654    
655          /*  Some machines (?) use ISA space at 0x15000000 instead of          /*  Some machines (?) use ISA space at 0x15000000 instead of
656              0x14000000, eg IBM WorkPad Z50.  */              0x14000000, eg IBM WorkPad Z50.  */
657          dev_ram_init(mem, 0x15000000, 0x1000000, DEV_RAM_MIRROR, 0x14000000);          dev_ram_init(machine, 0x15000000, 0x1000000, DEV_RAM_MIRROR,
658                0x14000000);
659    
660          return d;          return d;
661  }  }

Legend:
Removed from v.12  
changed lines
  Added in v.32

  ViewVC Help
Powered by ViewVC 1.1.26