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

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

revision 4 by dpavlin, Mon Oct 8 16:18:00 2007 UTC revision 24 by dpavlin, Mon Oct 8 16:19:56 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-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_sgi_ip32.c,v 1.24 2005/03/18 23:20:52 debug Exp $   *  $Id: dev_sgi_ip32.c,v 1.45 2006/03/04 12:38:48 debug Exp $
29   *     *  
30   *  SGI IP32 devices.   *  SGI IP32 devices.
31   *   *
# Line 106  void dev_crime_tick(struct cpu *cpu, voi Line 106  void dev_crime_tick(struct cpu *cpu, voi
106  /*  /*
107   *  dev_crime_access():   *  dev_crime_access():
108   */   */
109  int dev_crime_access(struct cpu *cpu, struct memory *mem,  DEVICE_ACCESS(crime)
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
110  {  {
         int i;  
111          struct crime_data *d = extra;          struct crime_data *d = extra;
112          uint64_t idata;          uint64_t idata = 0;
113            size_t i;
114    
115          idata = memory_readmax64(cpu, data, len);          if (writeflag == MEM_WRITE)
116                    idata = memory_readmax64(cpu, data, len);
117    
118          /*          /*
119           *  Set crime version/revision:           *  Set crime version/revision:
120           *           *
121           *  This might not be the most elegant or correct solution,           *  This might not be the most elegant or correct solution, but it
122           *  but it seems that the IP32 PROM likes 0x11 for machines           *  seems that the IP32 PROM likes 0x11 for machines without graphics,
123           *  without graphics, and 0xa1 for machines with graphics.           *  and 0xa1 for machines with graphics.
          *  
          *  NetBSD 2.0 complains about "unknown" crime for 0x11,  
          *  but I guess that's something one has to live with.  
124           *           *
125           *  (TODO?)           *  NetBSD 2.0 complains about "unknown" crime for 0x11, but I guess
126             *  that's something one has to live with.  (TODO?)
127           */           */
128          d->reg[4] = 0x00; d->reg[5] = 0x00; d->reg[6] = 0x00;          d->reg[4] = 0x00; d->reg[5] = 0x00; d->reg[6] = 0x00;
129          d->reg[7] = d->use_fb? 0xa1 : 0x11;          d->reg[7] = d->use_fb? 0xa1 : 0x11;
# Line 154  int dev_crime_access(struct cpu *cpu, st Line 151  int dev_crime_access(struct cpu *cpu, st
151          else          else
152                  memcpy(data, &d->reg[relative_addr], len);                  memcpy(data, &d->reg[relative_addr], len);
153    
154          if (relative_addr == 0x18 || relative_addr == 0x1c) {          if ((relative_addr >= 0x18 && relative_addr <= 0x1f) ||
155                (relative_addr+len-1 >= 0x18 && relative_addr+len-1 <= 0x1f)) {
156                  /*                  /*
157                   *  Force interrupt re-assertion:                   *  Force interrupt re-assertion:
158                   *                   *
159                   *  NOTE: Ugly hack. Hopefully CRMERR is never used.                   *  NOTE: Ugly hack. Hopefully CRMERR is never used.
160                   */                   */
161  #if 0  #if 0
162    /*
163  No. If this is enabled, the mec bugs out on either NetBSD or OpenBSD.  No. If this is enabled, the mec bugs out on either NetBSD or OpenBSD.
164  TODO.  TODO.
165    */
166                  cpu_interrupt_ack(cpu, 8); /* CRM_INT_CRMERR); */                  cpu_interrupt_ack(cpu, 8); /* CRM_INT_CRMERR); */
167  #endif  #endif
168          }          }
# Line 182  TODO. Line 180  TODO.
180                                  idata &= ~0x200;                                  idata &= ~0x200;
181                          }                          }
182                          if (idata & 0x800) {                          if (idata & 0x800) {
183                                    int j;
184    
185                                  /*  This is used by the IP32 PROM's                                  /*  This is used by the IP32 PROM's
186                                      "reboot" command:  */                                      "reboot" command:  */
187                                  for (i=0; i<cpu->machine->ncpus; i++)                                  for (j=0; j<cpu->machine->ncpus; j++)
188                                          cpu->machine->cpus[i]->running = 0;                                          cpu->machine->cpus[j]->running = 0;
189                                  cpu->machine->                                  cpu->machine->
190                                      exit_without_entering_debugger = 1;                                      exit_without_entering_debugger = 1;
191                                  idata &= ~0x800;                                  idata &= ~0x800;
# Line 195  TODO. Line 195  TODO.
195                                      "control 0x%016llx ]\n", (long long)idata);                                      "control 0x%016llx ]\n", (long long)idata);
196                  }                  }
197                  break;                  break;
198  #if 1  #if 0
199          case CRIME_INTSTAT:     /*  0x010, Current interrupt status  */          case CRIME_INTSTAT:     /*  0x010, Current interrupt status  */
200          case 0x14:          case 0x14:
201          case CRIME_INTMASK:     /*  0x018,  Current interrupt mask  */          case CRIME_INTMASK:     /*  0x018,  Current interrupt mask  */
202          case 0x1c:          case 0x1c:
203          case 0x34:          case 0x34:
 #endif  
204                  /*  don't dump debug info for these  */                  /*  don't dump debug info for these  */
205                  break;                  break;
206    #endif
207          default:          default:
208                  if (writeflag==MEM_READ) {                  if (writeflag==MEM_READ) {
209                          debug("[ crime: read from 0x%x, len=%i:",                          debug("[ crime: read from 0x%x, len=%i:",
# Line 241  struct crime_data *dev_crime_init(struct Line 241  struct crime_data *dev_crime_init(struct
241          d->use_fb = use_fb;          d->use_fb = use_fb;
242    
243          memory_device_register(mem, "crime", baseaddr, DEV_CRIME_LENGTH,          memory_device_register(mem, "crime", baseaddr, DEV_CRIME_LENGTH,
244              dev_crime_access, d, MEM_DEFAULT, NULL);              dev_crime_access, d, DM_DEFAULT, NULL);
245          machine_add_tickfunction(machine, dev_crime_tick, d, CRIME_TICKSHIFT);          machine_add_tickfunction(machine, dev_crime_tick, d,
246                CRIME_TICKSHIFT, 0.0);
247    
248          return d;          return d;
249  }  }
# Line 254  struct crime_data *dev_crime_init(struct Line 255  struct crime_data *dev_crime_init(struct
255  /*  /*
256   *  dev_mace_access():   *  dev_mace_access():
257   */   */
258  int dev_mace_access(struct cpu *cpu, struct memory *mem,  DEVICE_ACCESS(mace)
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
259  {  {
260          int i;          size_t i;
261          struct mace_data *d = extra;          struct mace_data *d = extra;
262    
263          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
# Line 266  int dev_mace_access(struct cpu *cpu, str Line 265  int dev_mace_access(struct cpu *cpu, str
265          else          else
266                  memcpy(data, &d->reg[relative_addr], len);                  memcpy(data, &d->reg[relative_addr], len);
267    
268            if ((relative_addr >= 0x18 && relative_addr <= 0x1f) ||
269                (relative_addr+len-1 >= 0x18 && relative_addr+len-1 <= 0x1f))
270                    cpu_interrupt_ack(cpu, 8); /* CRM_INT_CRMERR); */
271    
272          switch (relative_addr) {          switch (relative_addr) {
273  #if 0  #if 0
274          case 0x14:      /*  Current interrupt assertions  */          case 0x10:      /*  Current interrupt assertions  */
275          case 0x18:      /*  ???  */          case 0x14:
276          case 0x1c:      /*  Interrupt mask  */                  /*  don't dump debug info for these  */
277                    if (writeflag == MEM_WRITE) {
278                            fatal("[ NOTE/TODO: WRITE to mace intr: "
279                                "reladdr=0x%x data=", (int)relative_addr);
280                            for (i=0; i<len; i++)
281                                    fatal(" %02x", data[i]);
282                            fatal(" (len=%i) ]\n", len);
283                    }
284                    break;
285            case 0x18:      /*  Interrupt mask  */
286            case 0x1c:
287                  /*  don't dump debug info for these  */                  /*  don't dump debug info for these  */
288                  break;                  break;
289  #endif  #endif
290          default:          default:
291                  if (writeflag==MEM_READ) {                  if (writeflag == MEM_READ) {
292                          debug("[ mace: read from 0x%x, len=%i ]\n",                          debug("[ mace: read from 0x%x:", (int)relative_addr);
293                              (int)relative_addr, len);                          for (i=0; i<len; i++)
294                                    debug(" %02x", data[i]);
295                            debug(" (len=%i) ]\n", len);
296                  } else {                  } else {
297                          debug("[ mace: write to 0x%x:", (int)relative_addr);                          debug("[ mace: write to 0x%x:", (int)relative_addr);
298                          for (i=0; i<len; i++)                          for (i=0; i<len; i++)
# Line 307  struct mace_data *dev_mace_init(struct m Line 322  struct mace_data *dev_mace_init(struct m
322          d->irqnr = irqnr;          d->irqnr = irqnr;
323    
324          memory_device_register(mem, "mace", baseaddr, DEV_MACE_LENGTH,          memory_device_register(mem, "mace", baseaddr, DEV_MACE_LENGTH,
325              dev_mace_access, d, MEM_DEFAULT, NULL);              dev_mace_access, d, DM_DEFAULT, NULL);
326    
327          return d;          return d;
328  }  }
# Line 319  struct mace_data *dev_mace_init(struct m Line 334  struct mace_data *dev_mace_init(struct m
334  /*  /*
335   *  dev_macepci_access():   *  dev_macepci_access():
336   */   */
337  int dev_macepci_access(struct cpu *cpu, struct memory *mem,  DEVICE_ACCESS(macepci)
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
338  {  {
339          struct macepci_data *d = (struct macepci_data *) extra;          struct macepci_data *d = (struct macepci_data *) extra;
340          uint64_t idata = 0, odata=0;          uint64_t idata = 0, odata=0;
341          int regnr, res = 1;          int regnr, res = 1, bus, dev, func, pcireg;
342    
343            if (writeflag == MEM_WRITE)
344                    idata = memory_readmax64(cpu, data, len);
345    
         idata = memory_readmax64(cpu, data, len);  
346          regnr = relative_addr / sizeof(uint32_t);          regnr = relative_addr / sizeof(uint32_t);
347    
348          /*  Read from/write to the macepci:  */          /*  Read from/write to the macepci:  */
349          switch (relative_addr) {          switch (relative_addr) {
350    
351          case 0x00:      /*  Error address  */          case 0x00:      /*  Error address  */
352                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
353                  } else {                  } else {
354                          odata = 0;                          odata = 0;
355                  }                  }
356                  break;                  break;
357    
358          case 0x04:      /*  Error flags  */          case 0x04:      /*  Error flags  */
359                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
360                  } else {                  } else {
361                          odata = 0x06;                          odata = 0x06;
362                  }                  }
363                  break;                  break;
364    
365          case 0x0c:      /*  Revision number  */          case 0x0c:      /*  Revision number  */
366                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
367                  } else {                  } else {
368                          odata = 0x01;                          odata = 0x01;
369                  }                  }
370                  break;                  break;
371    
372          case 0xcf8:     /*  PCI ADDR  */          case 0xcf8:     /*  PCI ADDR  */
373                    bus_pci_decompose_1(idata, &bus, &dev, &func, &pcireg);
374                    bus_pci_setaddr(cpu, d->pci_data, bus, dev, func, pcireg);
375                    break;
376    
377          case 0xcfc:     /*  PCI DATA  */          case 0xcfc:     /*  PCI DATA  */
378                  if (writeflag == MEM_WRITE) {                  bus_pci_data_access(cpu, d->pci_data, writeflag == MEM_READ?
379                          res = bus_pci_access(cpu, mem, relative_addr,                      &odata : &idata, len, writeflag);
                             &idata, writeflag, d->pci_data);  
                 } else {  
                         res = bus_pci_access(cpu, mem, relative_addr,  
                             &odata, writeflag, d->pci_data);  
                         /*  odata = 0;  */  
                 }  
380                  break;                  break;
381    
382          default:          default:
383                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
384                          debug("[ macepci: unimplemented write to address "                          debug("[ macepci: unimplemented write to address "
# Line 382  int dev_macepci_access(struct cpu *cpu, Line 400  int dev_macepci_access(struct cpu *cpu,
400  /*  /*
401   *  dev_macepci_init():   *  dev_macepci_init():
402   */   */
403  struct pci_data *dev_macepci_init(struct memory *mem, uint64_t baseaddr,  struct pci_data *dev_macepci_init(struct machine *machine,
404          int pciirq)          struct memory *mem, uint64_t baseaddr, int pciirq)
405  {  {
406          struct macepci_data *d = malloc(sizeof(struct macepci_data));          struct macepci_data *d = malloc(sizeof(struct macepci_data));
407          if (d == NULL) {          if (d == NULL) {
# Line 392  struct pci_data *dev_macepci_init(struct Line 410  struct pci_data *dev_macepci_init(struct
410          }          }
411          memset(d, 0, sizeof(struct macepci_data));          memset(d, 0, sizeof(struct macepci_data));
412    
413          d->pci_data = bus_pci_init(pciirq);          d->pci_data = bus_pci_init(machine, pciirq, 0,0, 0,0,0, 0,0,0);
414    
415          memory_device_register(mem, "macepci", baseaddr, DEV_MACEPCI_LENGTH,          memory_device_register(mem, "macepci", baseaddr, DEV_MACEPCI_LENGTH,
416              dev_macepci_access, (void *)d, MEM_DEFAULT, NULL);              dev_macepci_access, (void *)d, DM_DEFAULT, NULL);
417    
418          return d->pci_data;          return d->pci_data;
419  }  }
# Line 519  static int mec_try_rx(struct cpu *cpu, s Line 537  static int mec_try_rx(struct cpu *cpu, s
537          }          }
538          /*  printf("\n");  */          /*  printf("\n");  */
539    
540  #if 1  #if 0
541          printf("RX: %i bytes, index %i, base = 0x%x\n",          printf("RX: %i bytes, index %i, base = 0x%x\n",
542              d->cur_rx_packet_len, d->cur_rx_addr_index, (int)base);              d->cur_rx_packet_len, d->cur_rx_addr_index, (int)base);
543  #endif  #endif
# Line 545  skip_and_advance: Line 563  skip_and_advance:
563          d->cur_rx_addr_index ++;          d->cur_rx_addr_index ++;
564          d->cur_rx_addr_index %= N_RX_ADDRESSES;          d->cur_rx_addr_index %= N_RX_ADDRESSES;
565          d->reg[MEC_INT_STATUS / sizeof(uint64_t)] &= ~MEC_INT_RX_MCL_FIFO_ALIAS;          d->reg[MEC_INT_STATUS / sizeof(uint64_t)] &= ~MEC_INT_RX_MCL_FIFO_ALIAS;
566          d->reg[MEC_INT_STATUS / sizeof(uint64_t)] |= (d->cur_rx_addr_index & 0x1f) << 8;          d->reg[MEC_INT_STATUS / sizeof(uint64_t)] |=
567                (d->cur_rx_addr_index & 0x1f) << 8;
568          retval = 1;          retval = 1;
569    
570  skip:  skip:
# Line 749  void dev_sgi_mec_tick(struct cpu *cpu, v Line 768  void dev_sgi_mec_tick(struct cpu *cpu, v
768  /*  /*
769   *  dev_sgi_mec_access():   *  dev_sgi_mec_access():
770   */   */
771  int dev_sgi_mec_access(struct cpu *cpu, struct memory *mem,  DEVICE_ACCESS(sgi_mec)
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
772  {  {
773          struct sgi_mec_data *d = (struct sgi_mec_data *) extra;          struct sgi_mec_data *d = (struct sgi_mec_data *) extra;
774          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
775          int regnr;          int regnr;
776    
777          idata = memory_readmax64(cpu, data, len);          if (writeflag == MEM_WRITE)
778                    idata = memory_readmax64(cpu, data, len);
779    
780          regnr = relative_addr / sizeof(uint64_t);          regnr = relative_addr / sizeof(uint64_t);
781    
782          /*  Treat most registers as read/write, by default.  */          /*  Treat most registers as read/write, by default.  */
# Line 912  void dev_sgi_mec_init(struct machine *ma Line 931  void dev_sgi_mec_init(struct machine *ma
931          uint64_t baseaddr, int irq_nr, unsigned char *macaddr)          uint64_t baseaddr, int irq_nr, unsigned char *macaddr)
932  {  {
933          char *name2;          char *name2;
934            size_t nlen = 55;
935          struct sgi_mec_data *d = malloc(sizeof(struct sgi_mec_data));          struct sgi_mec_data *d = malloc(sizeof(struct sgi_mec_data));
936    
937          if (d == NULL) {          if (d == NULL) {
# Line 924  void dev_sgi_mec_init(struct machine *ma Line 944  void dev_sgi_mec_init(struct machine *ma
944    
945          mec_reset(d);          mec_reset(d);
946    
947          name2 = malloc(50);          name2 = malloc(nlen);
948          if (name2 == NULL) {          if (name2 == NULL) {
949                  fprintf(stderr, "out of memory in dev_sgi_mec_init()\n");                  fprintf(stderr, "out of memory in dev_sgi_mec_init()\n");
950                  exit(1);                  exit(1);
951          }          }
952          sprintf(name2, "mec [%02x:%02x:%02x:%02x:%02x:%02x]",          snprintf(name2, nlen, "mec [%02x:%02x:%02x:%02x:%02x:%02x]",
953              d->macaddr[0], d->macaddr[1], d->macaddr[2],              d->macaddr[0], d->macaddr[1], d->macaddr[2],
954              d->macaddr[3], d->macaddr[4], d->macaddr[5]);              d->macaddr[3], d->macaddr[4], d->macaddr[5]);
955    
956          memory_device_register(mem, name2, baseaddr,          memory_device_register(mem, name2, baseaddr,
957              DEV_SGI_MEC_LENGTH, dev_sgi_mec_access, (void *)d,              DEV_SGI_MEC_LENGTH, dev_sgi_mec_access, (void *)d,
958              MEM_DEFAULT, NULL);              DM_DEFAULT, NULL);
959    
960          machine_add_tickfunction(machine, dev_sgi_mec_tick, d, MEC_TICK_SHIFT);          machine_add_tickfunction(machine, dev_sgi_mec_tick, d,
961                MEC_TICK_SHIFT, 0.0);
962    
963          net_add_nic(machine->emul->net, d, macaddr);          net_add_nic(machine->emul->net, d, macaddr);
964  }  }
# Line 954  struct sgi_ust_data { Line 975  struct sgi_ust_data {
975  /*  /*
976   *  dev_sgi_ust_access():   *  dev_sgi_ust_access():
977   */   */
978  int dev_sgi_ust_access(struct cpu *cpu, struct memory *mem,  DEVICE_ACCESS(sgi_ust)
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
979  {  {
980          struct sgi_ust_data *d = (struct sgi_ust_data *) extra;          struct sgi_ust_data *d = (struct sgi_ust_data *) extra;
981          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
# Line 977  int dev_sgi_ust_access(struct cpu *cpu, Line 996  int dev_sgi_ust_access(struct cpu *cpu,
996                  break;                  break;
997          default:          default:
998                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
999                          debug("[ sgi_ust: unimplemented write to address 0x%llx, data=0x%016llx ]\n", (long long)relative_addr, (long long)idata);                          debug("[ sgi_ust: unimplemented write to "
1000                                "address 0x%llx, data=0x%016llx ]\n",
1001                                (long long)relative_addr, (long long)idata);
1002                  else                  else
1003                          debug("[ sgi_ust: unimplemented read from address 0x%llx ]\n", (long long)relative_addr);                          debug("[ sgi_ust: unimplemented read from address"
1004                                " 0x%llx ]\n", (long long)relative_addr);
1005          }          }
1006    
1007          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)
# Line 1002  void dev_sgi_ust_init(struct memory *mem Line 1024  void dev_sgi_ust_init(struct memory *mem
1024          memset(d, 0, sizeof(struct sgi_ust_data));          memset(d, 0, sizeof(struct sgi_ust_data));
1025    
1026          memory_device_register(mem, "sgi_ust", baseaddr,          memory_device_register(mem, "sgi_ust", baseaddr,
1027              DEV_SGI_UST_LENGTH, dev_sgi_ust_access, (void *)d, MEM_DEFAULT, NULL);              DEV_SGI_UST_LENGTH, dev_sgi_ust_access, (void *)d,
1028                DM_DEFAULT, NULL);
1029  }  }
1030    
1031    
# Line 1011  void dev_sgi_ust_init(struct memory *mem Line 1034  void dev_sgi_ust_init(struct memory *mem
1034    
1035  /*  /*
1036   *  SGI "mte". This device seems to be an accelerator for copying/clearing   *  SGI "mte". This device seems to be an accelerator for copying/clearing
1037   *  memory.  Used in SGI-IP32.   *  memory. Used by (at least) the SGI O2 PROM.
1038     *
1039     *  Actually, it seems to be used for graphics output as well. (?)
1040     *  The O2's PROM uses it to output graphics.
1041   */   */
1042    /*  #define debug fatal  */
1043    /*  #define MTE_DEBUG  */
1044  #define ZERO_CHUNK_LEN          4096  #define ZERO_CHUNK_LEN          4096
1045    
1046  struct sgi_mte_data {  struct sgi_mte_data {
1047          uint64_t        reg[DEV_SGI_MTE_LENGTH / sizeof(uint64_t)];          uint32_t        reg[DEV_SGI_MTE_LENGTH / sizeof(uint32_t)];
1048  };  };
1049    
1050  /*  /*
1051   *  dev_sgi_mte_access():   *  dev_sgi_mte_access():
1052   */   */
1053  int dev_sgi_mte_access(struct cpu *cpu, struct memory *mem,  DEVICE_ACCESS(sgi_mte)
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
1054  {  {
1055          struct sgi_mte_data *d = (struct sgi_mte_data *) extra;          struct sgi_mte_data *d = (struct sgi_mte_data *) extra;
1056          uint64_t first_addr, last_addr, zerobuflen, fill_addr, fill_len;          uint64_t first_addr, last_addr, zerobuflen, fill_addr, fill_len;
# Line 1034  int dev_sgi_mte_access(struct cpu *cpu, Line 1059  int dev_sgi_mte_access(struct cpu *cpu,
1059          int regnr;          int regnr;
1060    
1061          idata = memory_readmax64(cpu, data, len);          idata = memory_readmax64(cpu, data, len);
1062          regnr = relative_addr / sizeof(uint64_t);          regnr = relative_addr / sizeof(uint32_t);
1063    
1064            /*
1065             *  Treat all registers as read/write, by default.  Sometimes these
1066             *  are accessed as 32-bit words, sometimes as 64-bit words.
1067             */
1068            if (len != 4) {
1069                    if (writeflag == MEM_WRITE) {
1070                            d->reg[regnr] = idata >> 32;
1071                            d->reg[regnr+1] = idata;
1072                    } else
1073                            odata = ((uint64_t)d->reg[regnr] << 32) +
1074                                d->reg[regnr+1];
1075            }
1076    
         /*  Treat all registers as read/write, by default.  */  
1077          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
1078                  d->reg[regnr] = idata;                  d->reg[regnr] = idata;
1079          else          else
1080                  odata = d->reg[regnr];                  odata = d->reg[regnr];
1081    
1082    #ifdef MTE_DEBUG
1083            if (writeflag == MEM_WRITE && relative_addr >= 0x2000 &&
1084                relative_addr < 0x3000)
1085                    fatal("[ MTE: 0x%08x: 0x%016llx ]\n", (int)relative_addr,
1086                        (long long)idata);
1087    #endif
1088    
1089          /*          /*
1090           *  I've not found any docs about this 'mte' device at all, so this is just           *  I've not found any docs about this 'mte' device at all, so this is
1091           *  a guess. The mte seems to be used for copying and zeroing chunks of           *  just a guess. The mte seems to be used for copying and zeroing
1092           *  memory.           *  chunks of memory.
1093           *           *
1094           *  [ sgi_mte: unimplemented write to address 0x3030, data=0x00000000003da000 ]  <-- first address           *   write to 0x3030, data=0x00000000003da000 ]  <-- first address
1095           *  [ sgi_mte: unimplemented write to address 0x3038, data=0x00000000003f9fff ]  <-- last address           *   write to 0x3038, data=0x00000000003f9fff ]  <-- last address
1096           *  [ sgi_mte: unimplemented write to address 0x3018, data=0x0000000000000000 ]  <-- what to fill?           *   write to 0x3018, data=0x0000000000000000 ]  <-- what to fill?
1097           *  [ sgi_mte: unimplemented write to address 0x3008, data=0x00000000ffffffff ]  <-- ?           *   write to 0x3008, data=0x00000000ffffffff ]  <-- ?
1098           *  [ sgi_mte: unimplemented write to address 0x3800, data=0x0000000000000011 ]  <-- operation (0x11 = zerofill)           *   write to 0x3800, data=0x0000000000000011 ]  <-- operation
1099             *                                                   (0x11 = zerofill)
1100           *           *
1101           *  [ sgi_mte: unimplemented write to address 0x1700, data=0x80001ea080001ea1 ]  <-- also containing the address to fill (?)           *   write to 0x1700, data=0x80001ea080001ea1  <-- also containing the
1102           *  [ sgi_mte: unimplemented write to address 0x1708, data=0x80001ea280001ea3 ]           *   write to 0x1708, data=0x80001ea280001ea3      address to fill (?)
1103           *  [ sgi_mte: unimplemented write to address 0x1710, data=0x80001ea480001ea5 ]           *   write to 0x1710, data=0x80001ea480001ea5
1104           *  ...           *  ...
1105           *  [ sgi_mte: unimplemented write to address 0x1770, data=0x80001e9c80001e9d ]           *   write to 0x1770, data=0x80001e9c80001e9d
1106           *  [ sgi_mte: unimplemented write to address 0x1778, data=0x80001e9e80001e9f ]           *   write to 0x1778, data=0x80001e9e80001e9f
1107           */           */
1108          switch (relative_addr) {          switch (relative_addr) {
1109    
# Line 1089  int dev_sgi_mte_access(struct cpu *cpu, Line 1134  int dev_sgi_mte_access(struct cpu *cpu,
1134          case 0x1778:          case 0x1778:
1135                  break;                  break;
1136    
1137            /*  Graphics stuff? No warning:  */
1138            case 0x2018:
1139            case 0x2060:
1140            case 0x2070:
1141            case 0x2074:
1142            case 0x20c0:
1143            case 0x20c4:
1144            case 0x20d0:
1145            case 0x21b0:
1146            case 0x21b8:
1147                    break;
1148    
1149            /*  Perform graphics operation:  */
1150            case 0x21f8:
1151                    {
1152                            uint32_t op = d->reg[0x2060 / sizeof(uint32_t)];
1153                            uint32_t color = d->reg[0x20d0 / sizeof(uint32_t)]&255;
1154                            uint32_t x1 = (d->reg[0x2070 / sizeof(uint32_t)]
1155                                >> 16) & 0xfff;
1156                            uint32_t y1 = d->reg[0x2070 / sizeof(uint32_t)]& 0xfff;
1157                            uint32_t x2 = (d->reg[0x2074 / sizeof(uint32_t)]
1158                                >> 16) & 0xfff;
1159                            uint32_t y2 = d->reg[0x2074 / sizeof(uint32_t)]& 0xfff;
1160                            uint32_t y;
1161    
1162                            op >>= 24;
1163    
1164                            switch (op) {
1165                            case 1: /*  Unknown. Used after drawing bitmaps?  */
1166                                    break;
1167                            case 3: /*  Fill:  */
1168                                    if (x2 < x1) {
1169                                            int tmp = x1; x1 = x2; x2 = tmp;
1170                                    }
1171                                    if (y2 < y1) {
1172                                            int tmp = y1; y1 = y2; y2 = tmp;
1173                                    }
1174                                    for (y=y1; y<=y2; y++) {
1175                                            unsigned char buf[1280];
1176                                            int length = x2-x1+1;
1177                                            int addr = (x1 + y*1280);
1178                                            if (length < 1)
1179                                                    length = 1;
1180                                            memset(buf, color, length);
1181                                            if (x1 < 1280 && y < 1024)
1182                                                    cpu->memory_rw(cpu, cpu->mem,
1183                                                        0x38000000 + addr, buf,
1184                                                        length, MEM_WRITE,
1185                                                        NO_EXCEPTIONS | PHYSICAL);
1186                                    }
1187                                    break;
1188    
1189                            default:fatal("\n--- MTE OP %i color 0x%02x: %i,%i - "
1190                                        "%i,%i\n\n", op, color, x1,y1, x2,y2);
1191                            }
1192                    }
1193                    break;
1194    
1195            case 0x29f0:
1196                    /*  Pixel output:  */
1197                    {
1198                            uint32_t data = d->reg[0x20c4 / sizeof(uint32_t)];
1199                            uint32_t color = d->reg[0x20d0 / sizeof(uint32_t)]&255;
1200                            uint32_t x1 = (d->reg[0x2070 / sizeof(uint32_t)]
1201                                >> 16) & 0xfff;
1202                            uint32_t y1 = d->reg[0x2070 / sizeof(uint32_t)]& 0xfff;
1203                            uint32_t x2 = (d->reg[0x2074 / sizeof(uint32_t)]
1204                                >> 16) & 0xfff;
1205                            uint32_t y2 = d->reg[0x2074 / sizeof(uint32_t)]& 0xfff;
1206                            size_t x, y;
1207    
1208                            if (x2 < x1) {
1209                                    int tmp = x1; x1 = x2; x2 = tmp;
1210                            }
1211                            if (y2 < y1) {
1212                                    int tmp = y1; y1 = y2; y2 = tmp;
1213                            }
1214                            if (x2-x1 <= 15)
1215                                    data <<= 16;
1216    
1217                            x=x1; y=y1;
1218                            while (x <= x2 && y <= y2) {
1219                                    unsigned char buf = color;
1220                                    int addr = x + y*1280;
1221                                    int bit_set = data & 0x80000000UL;
1222                                    data <<= 1;
1223                                    if (x < 1280 && y < 1024 && bit_set)
1224                                            cpu->memory_rw(cpu, cpu->mem,
1225                                                0x38000000 + addr, &buf,1,MEM_WRITE,
1226                                                NO_EXCEPTIONS | PHYSICAL);
1227                                    x++;
1228                                    if (x > x2) {
1229                                            x = x1;
1230                                            y++;
1231                                    }
1232                            }
1233                    }
1234                    break;
1235    
1236    
1237          /*  Operations:  */          /*  Operations:  */
1238          case 0x3800:          case 0x3800:
1239                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
1240                          switch (idata) {                          switch (idata) {
1241                          case 0x11:              /*  zerofill  */                          case 0x11:              /*  zerofill  */
1242                                  first_addr = d->reg[0x3030 / sizeof(uint64_t)];                                  first_addr = d->reg[0x3030 / sizeof(uint32_t)];
1243                                  last_addr  = d->reg[0x3038 / sizeof(uint64_t)];                                  last_addr  = d->reg[0x3038 / sizeof(uint32_t)];
1244                                  zerobuflen = last_addr - first_addr + 1;                                  zerobuflen = last_addr - first_addr + 1;
1245                                  debug("[ sgi_mte: zerofill: first = 0x%016llx, last = 0x%016llx, length = 0x%llx ]\n",                                  debug("[ sgi_mte: zerofill: first = 0x%016llx,"
1246                                      (long long)first_addr, (long long)last_addr, (long long)zerobuflen);                                      " last = 0x%016llx, length = 0x%llx ]\n",
1247                                        (long long)first_addr, (long long)
1248                                        last_addr, (long long)zerobuflen);
1249    
1250                                  /*  TODO:  is there a better way to implement this?  */                                  /*  TODO:  is there a better way to
1251                                               implement this?  */
1252                                  memset(zerobuf, 0, sizeof(zerobuf));                                  memset(zerobuf, 0, sizeof(zerobuf));
1253                                  fill_addr = first_addr;                                  fill_addr = first_addr;
1254                                  while (zerobuflen != 0) {                                  while (zerobuflen != 0) {
# Line 1117  int dev_sgi_mte_access(struct cpu *cpu, Line 1265  int dev_sgi_mte_access(struct cpu *cpu,
1265    
1266                                  break;                                  break;
1267                          default:                          default:
1268                                  fatal("[ sgi_mte: UNKNOWN operation 0x%x ]\n", idata);                                  fatal("[ sgi_mte: UNKNOWN operation "
1269                                        "0x%x ]\n", idata);
1270                          }                          }
1271                  }                  }
1272                  break;                  break;
1273          default:          default:
1274                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
1275                          debug("[ sgi_mte: unimplemented write to address 0x%llx, data=0x%016llx ]\n", (long long)relative_addr, (long long)idata);                          debug("[ sgi_mte: unimplemented write to "
1276                                "address 0x%llx, data=0x%016llx ]\n",
1277                                (long long)relative_addr, (long long)idata);
1278                  else                  else
1279                          debug("[ sgi_mte: unimplemented read from address 0x%llx ]\n", (long long)relative_addr);                          debug("[ sgi_mte: unimplemented read from address"
1280                                " 0x%llx ]\n", (long long)relative_addr);
1281          }          }
1282    
1283          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)
# Line 1148  void dev_sgi_mte_init(struct memory *mem Line 1300  void dev_sgi_mte_init(struct memory *mem
1300          memset(d, 0, sizeof(struct sgi_mte_data));          memset(d, 0, sizeof(struct sgi_mte_data));
1301    
1302          memory_device_register(mem, "sgi_mte", baseaddr, DEV_SGI_MTE_LENGTH,          memory_device_register(mem, "sgi_mte", baseaddr, DEV_SGI_MTE_LENGTH,
1303              dev_sgi_mte_access, (void *)d, MEM_DEFAULT, NULL);              dev_sgi_mte_access, (void *)d, DM_DEFAULT, NULL);
1304  }  }
1305    

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

  ViewVC Help
Powered by ViewVC 1.1.26