/[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 22 by dpavlin, Mon Oct 8 16:19:37 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.44 2006/01/01 13:17:17 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, CRIME_TICKSHIFT);
246    
247          return d;          return d;
# Line 254  struct crime_data *dev_crime_init(struct Line 254  struct crime_data *dev_crime_init(struct
254  /*  /*
255   *  dev_mace_access():   *  dev_mace_access():
256   */   */
257  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)  
258  {  {
259          int i;          size_t i;
260          struct mace_data *d = extra;          struct mace_data *d = extra;
261    
262          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
# Line 266  int dev_mace_access(struct cpu *cpu, str Line 264  int dev_mace_access(struct cpu *cpu, str
264          else          else
265                  memcpy(data, &d->reg[relative_addr], len);                  memcpy(data, &d->reg[relative_addr], len);
266    
267            if ((relative_addr >= 0x18 && relative_addr <= 0x1f) ||
268                (relative_addr+len-1 >= 0x18 && relative_addr+len-1 <= 0x1f))
269                    cpu_interrupt_ack(cpu, 8); /* CRM_INT_CRMERR); */
270    
271          switch (relative_addr) {          switch (relative_addr) {
272  #if 0  #if 0
273          case 0x14:      /*  Current interrupt assertions  */          case 0x10:      /*  Current interrupt assertions  */
274          case 0x18:      /*  ???  */          case 0x14:
275          case 0x1c:      /*  Interrupt mask  */                  /*  don't dump debug info for these  */
276                    if (writeflag == MEM_WRITE) {
277                            fatal("[ NOTE/TODO: WRITE to mace intr: "
278                                "reladdr=0x%x data=", (int)relative_addr);
279                            for (i=0; i<len; i++)
280                                    fatal(" %02x", data[i]);
281                            fatal(" (len=%i) ]\n", len);
282                    }
283                    break;
284            case 0x18:      /*  Interrupt mask  */
285            case 0x1c:
286                  /*  don't dump debug info for these  */                  /*  don't dump debug info for these  */
287                  break;                  break;
288  #endif  #endif
289          default:          default:
290                  if (writeflag==MEM_READ) {                  if (writeflag == MEM_READ) {
291                          debug("[ mace: read from 0x%x, len=%i ]\n",                          debug("[ mace: read from 0x%x:", (int)relative_addr);
292                              (int)relative_addr, len);                          for (i=0; i<len; i++)
293                                    debug(" %02x", data[i]);
294                            debug(" (len=%i) ]\n", len);
295                  } else {                  } else {
296                          debug("[ mace: write to 0x%x:", (int)relative_addr);                          debug("[ mace: write to 0x%x:", (int)relative_addr);
297                          for (i=0; i<len; i++)                          for (i=0; i<len; i++)
# Line 307  struct mace_data *dev_mace_init(struct m Line 321  struct mace_data *dev_mace_init(struct m
321          d->irqnr = irqnr;          d->irqnr = irqnr;
322    
323          memory_device_register(mem, "mace", baseaddr, DEV_MACE_LENGTH,          memory_device_register(mem, "mace", baseaddr, DEV_MACE_LENGTH,
324              dev_mace_access, d, MEM_DEFAULT, NULL);              dev_mace_access, d, DM_DEFAULT, NULL);
325    
326          return d;          return d;
327  }  }
# Line 319  struct mace_data *dev_mace_init(struct m Line 333  struct mace_data *dev_mace_init(struct m
333  /*  /*
334   *  dev_macepci_access():   *  dev_macepci_access():
335   */   */
336  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)  
337  {  {
338          struct macepci_data *d = (struct macepci_data *) extra;          struct macepci_data *d = (struct macepci_data *) extra;
339          uint64_t idata = 0, odata=0;          uint64_t idata = 0, odata=0;
340          int regnr, res = 1;          int regnr, res = 1, bus, dev, func, pcireg;
341    
342            if (writeflag == MEM_WRITE)
343                    idata = memory_readmax64(cpu, data, len);
344    
         idata = memory_readmax64(cpu, data, len);  
345          regnr = relative_addr / sizeof(uint32_t);          regnr = relative_addr / sizeof(uint32_t);
346    
347          /*  Read from/write to the macepci:  */          /*  Read from/write to the macepci:  */
348          switch (relative_addr) {          switch (relative_addr) {
349    
350          case 0x00:      /*  Error address  */          case 0x00:      /*  Error address  */
351                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
352                  } else {                  } else {
353                          odata = 0;                          odata = 0;
354                  }                  }
355                  break;                  break;
356    
357          case 0x04:      /*  Error flags  */          case 0x04:      /*  Error flags  */
358                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
359                  } else {                  } else {
360                          odata = 0x06;                          odata = 0x06;
361                  }                  }
362                  break;                  break;
363    
364          case 0x0c:      /*  Revision number  */          case 0x0c:      /*  Revision number  */
365                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
366                  } else {                  } else {
367                          odata = 0x01;                          odata = 0x01;
368                  }                  }
369                  break;                  break;
370    
371          case 0xcf8:     /*  PCI ADDR  */          case 0xcf8:     /*  PCI ADDR  */
372                    bus_pci_decompose_1(idata, &bus, &dev, &func, &pcireg);
373                    bus_pci_setaddr(cpu, d->pci_data, bus, dev, func, pcireg);
374                    break;
375    
376          case 0xcfc:     /*  PCI DATA  */          case 0xcfc:     /*  PCI DATA  */
377                  if (writeflag == MEM_WRITE) {                  bus_pci_data_access(cpu, d->pci_data, writeflag == MEM_READ?
378                          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;  */  
                 }  
379                  break;                  break;
380    
381          default:          default:
382                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
383                          debug("[ macepci: unimplemented write to address "                          debug("[ macepci: unimplemented write to address "
# Line 382  int dev_macepci_access(struct cpu *cpu, Line 399  int dev_macepci_access(struct cpu *cpu,
399  /*  /*
400   *  dev_macepci_init():   *  dev_macepci_init():
401   */   */
402  struct pci_data *dev_macepci_init(struct memory *mem, uint64_t baseaddr,  struct pci_data *dev_macepci_init(struct machine *machine,
403          int pciirq)          struct memory *mem, uint64_t baseaddr, int pciirq)
404  {  {
405          struct macepci_data *d = malloc(sizeof(struct macepci_data));          struct macepci_data *d = malloc(sizeof(struct macepci_data));
406          if (d == NULL) {          if (d == NULL) {
# Line 392  struct pci_data *dev_macepci_init(struct Line 409  struct pci_data *dev_macepci_init(struct
409          }          }
410          memset(d, 0, sizeof(struct macepci_data));          memset(d, 0, sizeof(struct macepci_data));
411    
412          d->pci_data = bus_pci_init(pciirq);          d->pci_data = bus_pci_init(machine, pciirq, 0,0, 0,0,0, 0,0,0);
413    
414          memory_device_register(mem, "macepci", baseaddr, DEV_MACEPCI_LENGTH,          memory_device_register(mem, "macepci", baseaddr, DEV_MACEPCI_LENGTH,
415              dev_macepci_access, (void *)d, MEM_DEFAULT, NULL);              dev_macepci_access, (void *)d, DM_DEFAULT, NULL);
416    
417          return d->pci_data;          return d->pci_data;
418  }  }
# Line 519  static int mec_try_rx(struct cpu *cpu, s Line 536  static int mec_try_rx(struct cpu *cpu, s
536          }          }
537          /*  printf("\n");  */          /*  printf("\n");  */
538    
539  #if 1  #if 0
540          printf("RX: %i bytes, index %i, base = 0x%x\n",          printf("RX: %i bytes, index %i, base = 0x%x\n",
541              d->cur_rx_packet_len, d->cur_rx_addr_index, (int)base);              d->cur_rx_packet_len, d->cur_rx_addr_index, (int)base);
542  #endif  #endif
# Line 545  skip_and_advance: Line 562  skip_and_advance:
562          d->cur_rx_addr_index ++;          d->cur_rx_addr_index ++;
563          d->cur_rx_addr_index %= N_RX_ADDRESSES;          d->cur_rx_addr_index %= N_RX_ADDRESSES;
564          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;
565          d->reg[MEC_INT_STATUS / sizeof(uint64_t)] |= (d->cur_rx_addr_index & 0x1f) << 8;          d->reg[MEC_INT_STATUS / sizeof(uint64_t)] |=
566                (d->cur_rx_addr_index & 0x1f) << 8;
567          retval = 1;          retval = 1;
568    
569  skip:  skip:
# Line 749  void dev_sgi_mec_tick(struct cpu *cpu, v Line 767  void dev_sgi_mec_tick(struct cpu *cpu, v
767  /*  /*
768   *  dev_sgi_mec_access():   *  dev_sgi_mec_access():
769   */   */
770  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)  
771  {  {
772          struct sgi_mec_data *d = (struct sgi_mec_data *) extra;          struct sgi_mec_data *d = (struct sgi_mec_data *) extra;
773          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
774          int regnr;          int regnr;
775    
776          idata = memory_readmax64(cpu, data, len);          if (writeflag == MEM_WRITE)
777                    idata = memory_readmax64(cpu, data, len);
778    
779          regnr = relative_addr / sizeof(uint64_t);          regnr = relative_addr / sizeof(uint64_t);
780    
781          /*  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 930  void dev_sgi_mec_init(struct machine *ma
930          uint64_t baseaddr, int irq_nr, unsigned char *macaddr)          uint64_t baseaddr, int irq_nr, unsigned char *macaddr)
931  {  {
932          char *name2;          char *name2;
933            size_t nlen = 55;
934          struct sgi_mec_data *d = malloc(sizeof(struct sgi_mec_data));          struct sgi_mec_data *d = malloc(sizeof(struct sgi_mec_data));
935    
936          if (d == NULL) {          if (d == NULL) {
# Line 924  void dev_sgi_mec_init(struct machine *ma Line 943  void dev_sgi_mec_init(struct machine *ma
943    
944          mec_reset(d);          mec_reset(d);
945    
946          name2 = malloc(50);          name2 = malloc(nlen);
947          if (name2 == NULL) {          if (name2 == NULL) {
948                  fprintf(stderr, "out of memory in dev_sgi_mec_init()\n");                  fprintf(stderr, "out of memory in dev_sgi_mec_init()\n");
949                  exit(1);                  exit(1);
950          }          }
951          sprintf(name2, "mec [%02x:%02x:%02x:%02x:%02x:%02x]",          snprintf(name2, nlen, "mec [%02x:%02x:%02x:%02x:%02x:%02x]",
952              d->macaddr[0], d->macaddr[1], d->macaddr[2],              d->macaddr[0], d->macaddr[1], d->macaddr[2],
953              d->macaddr[3], d->macaddr[4], d->macaddr[5]);              d->macaddr[3], d->macaddr[4], d->macaddr[5]);
954    
955          memory_device_register(mem, name2, baseaddr,          memory_device_register(mem, name2, baseaddr,
956              DEV_SGI_MEC_LENGTH, dev_sgi_mec_access, (void *)d,              DEV_SGI_MEC_LENGTH, dev_sgi_mec_access, (void *)d,
957              MEM_DEFAULT, NULL);              DM_DEFAULT, NULL);
958    
959          machine_add_tickfunction(machine, dev_sgi_mec_tick, d, MEC_TICK_SHIFT);          machine_add_tickfunction(machine, dev_sgi_mec_tick, d, MEC_TICK_SHIFT);
960    
# Line 954  struct sgi_ust_data { Line 973  struct sgi_ust_data {
973  /*  /*
974   *  dev_sgi_ust_access():   *  dev_sgi_ust_access():
975   */   */
976  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)  
977  {  {
978          struct sgi_ust_data *d = (struct sgi_ust_data *) extra;          struct sgi_ust_data *d = (struct sgi_ust_data *) extra;
979          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
# Line 977  int dev_sgi_ust_access(struct cpu *cpu, Line 994  int dev_sgi_ust_access(struct cpu *cpu,
994                  break;                  break;
995          default:          default:
996                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
997                          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 "
998                                "address 0x%llx, data=0x%016llx ]\n",
999                                (long long)relative_addr, (long long)idata);
1000                  else                  else
1001                          debug("[ sgi_ust: unimplemented read from address 0x%llx ]\n", (long long)relative_addr);                          debug("[ sgi_ust: unimplemented read from address"
1002                                " 0x%llx ]\n", (long long)relative_addr);
1003          }          }
1004    
1005          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)
# Line 1002  void dev_sgi_ust_init(struct memory *mem Line 1022  void dev_sgi_ust_init(struct memory *mem
1022          memset(d, 0, sizeof(struct sgi_ust_data));          memset(d, 0, sizeof(struct sgi_ust_data));
1023    
1024          memory_device_register(mem, "sgi_ust", baseaddr,          memory_device_register(mem, "sgi_ust", baseaddr,
1025              DEV_SGI_UST_LENGTH, dev_sgi_ust_access, (void *)d, MEM_DEFAULT, NULL);              DEV_SGI_UST_LENGTH, dev_sgi_ust_access, (void *)d,
1026                DM_DEFAULT, NULL);
1027  }  }
1028    
1029    
# Line 1011  void dev_sgi_ust_init(struct memory *mem Line 1032  void dev_sgi_ust_init(struct memory *mem
1032    
1033  /*  /*
1034   *  SGI "mte". This device seems to be an accelerator for copying/clearing   *  SGI "mte". This device seems to be an accelerator for copying/clearing
1035   *  memory.  Used in SGI-IP32.   *  memory. Used by (at least) the SGI O2 PROM.
1036     *
1037     *  Actually, it seems to be used for graphics output as well. (?)
1038     *  The O2's PROM uses it to output graphics.
1039   */   */
1040    /*  #define debug fatal  */
1041    /*  #define MTE_DEBUG  */
1042  #define ZERO_CHUNK_LEN          4096  #define ZERO_CHUNK_LEN          4096
1043    
1044  struct sgi_mte_data {  struct sgi_mte_data {
1045          uint64_t        reg[DEV_SGI_MTE_LENGTH / sizeof(uint64_t)];          uint32_t        reg[DEV_SGI_MTE_LENGTH / sizeof(uint32_t)];
1046  };  };
1047    
1048  /*  /*
1049   *  dev_sgi_mte_access():   *  dev_sgi_mte_access():
1050   */   */
1051  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)  
1052  {  {
1053          struct sgi_mte_data *d = (struct sgi_mte_data *) extra;          struct sgi_mte_data *d = (struct sgi_mte_data *) extra;
1054          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 1057  int dev_sgi_mte_access(struct cpu *cpu,
1057          int regnr;          int regnr;
1058    
1059          idata = memory_readmax64(cpu, data, len);          idata = memory_readmax64(cpu, data, len);
1060          regnr = relative_addr / sizeof(uint64_t);          regnr = relative_addr / sizeof(uint32_t);
1061    
1062            /*
1063             *  Treat all registers as read/write, by default.  Sometimes these
1064             *  are accessed as 32-bit words, sometimes as 64-bit words.
1065             */
1066            if (len != 4) {
1067                    if (writeflag == MEM_WRITE) {
1068                            d->reg[regnr] = idata >> 32;
1069                            d->reg[regnr+1] = idata;
1070                    } else
1071                            odata = ((uint64_t)d->reg[regnr] << 32) +
1072                                d->reg[regnr+1];
1073            }
1074    
         /*  Treat all registers as read/write, by default.  */  
1075          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
1076                  d->reg[regnr] = idata;                  d->reg[regnr] = idata;
1077          else          else
1078                  odata = d->reg[regnr];                  odata = d->reg[regnr];
1079    
1080    #ifdef MTE_DEBUG
1081            if (writeflag == MEM_WRITE && relative_addr >= 0x2000 &&
1082                relative_addr < 0x3000)
1083                    fatal("[ MTE: 0x%08x: 0x%016llx ]\n", (int)relative_addr,
1084                        (long long)idata);
1085    #endif
1086    
1087          /*          /*
1088           *  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
1089           *  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
1090           *  memory.           *  chunks of memory.
1091           *           *
1092           *  [ sgi_mte: unimplemented write to address 0x3030, data=0x00000000003da000 ]  <-- first address           *   write to 0x3030, data=0x00000000003da000 ]  <-- first address
1093           *  [ sgi_mte: unimplemented write to address 0x3038, data=0x00000000003f9fff ]  <-- last address           *   write to 0x3038, data=0x00000000003f9fff ]  <-- last address
1094           *  [ sgi_mte: unimplemented write to address 0x3018, data=0x0000000000000000 ]  <-- what to fill?           *   write to 0x3018, data=0x0000000000000000 ]  <-- what to fill?
1095           *  [ sgi_mte: unimplemented write to address 0x3008, data=0x00000000ffffffff ]  <-- ?           *   write to 0x3008, data=0x00000000ffffffff ]  <-- ?
1096           *  [ sgi_mte: unimplemented write to address 0x3800, data=0x0000000000000011 ]  <-- operation (0x11 = zerofill)           *   write to 0x3800, data=0x0000000000000011 ]  <-- operation
1097             *                                                   (0x11 = zerofill)
1098           *           *
1099           *  [ sgi_mte: unimplemented write to address 0x1700, data=0x80001ea080001ea1 ]  <-- also containing the address to fill (?)           *   write to 0x1700, data=0x80001ea080001ea1  <-- also containing the
1100           *  [ sgi_mte: unimplemented write to address 0x1708, data=0x80001ea280001ea3 ]           *   write to 0x1708, data=0x80001ea280001ea3      address to fill (?)
1101           *  [ sgi_mte: unimplemented write to address 0x1710, data=0x80001ea480001ea5 ]           *   write to 0x1710, data=0x80001ea480001ea5
1102           *  ...           *  ...
1103           *  [ sgi_mte: unimplemented write to address 0x1770, data=0x80001e9c80001e9d ]           *   write to 0x1770, data=0x80001e9c80001e9d
1104           *  [ sgi_mte: unimplemented write to address 0x1778, data=0x80001e9e80001e9f ]           *   write to 0x1778, data=0x80001e9e80001e9f
1105           */           */
1106          switch (relative_addr) {          switch (relative_addr) {
1107    
# Line 1089  int dev_sgi_mte_access(struct cpu *cpu, Line 1132  int dev_sgi_mte_access(struct cpu *cpu,
1132          case 0x1778:          case 0x1778:
1133                  break;                  break;
1134    
1135            /*  Graphics stuff? No warning:  */
1136            case 0x2018:
1137            case 0x2060:
1138            case 0x2070:
1139            case 0x2074:
1140            case 0x20c0:
1141            case 0x20c4:
1142            case 0x20d0:
1143            case 0x21b0:
1144            case 0x21b8:
1145                    break;
1146    
1147            /*  Perform graphics operation:  */
1148            case 0x21f8:
1149                    {
1150                            uint32_t op = d->reg[0x2060 / sizeof(uint32_t)];
1151                            uint32_t color = d->reg[0x20d0 / sizeof(uint32_t)]&255;
1152                            uint32_t x1 = (d->reg[0x2070 / sizeof(uint32_t)]
1153                                >> 16) & 0xfff;
1154                            uint32_t y1 = d->reg[0x2070 / sizeof(uint32_t)]& 0xfff;
1155                            uint32_t x2 = (d->reg[0x2074 / sizeof(uint32_t)]
1156                                >> 16) & 0xfff;
1157                            uint32_t y2 = d->reg[0x2074 / sizeof(uint32_t)]& 0xfff;
1158                            uint32_t y;
1159    
1160                            op >>= 24;
1161    
1162                            switch (op) {
1163                            case 1: /*  Unknown. Used after drawing bitmaps?  */
1164                                    break;
1165                            case 3: /*  Fill:  */
1166                                    if (x2 < x1) {
1167                                            int tmp = x1; x1 = x2; x2 = tmp;
1168                                    }
1169                                    if (y2 < y1) {
1170                                            int tmp = y1; y1 = y2; y2 = tmp;
1171                                    }
1172                                    for (y=y1; y<=y2; y++) {
1173                                            unsigned char buf[1280];
1174                                            int length = x2-x1+1;
1175                                            int addr = (x1 + y*1280);
1176                                            if (length < 1)
1177                                                    length = 1;
1178                                            memset(buf, color, length);
1179                                            if (x1 < 1280 && y < 1024)
1180                                                    cpu->memory_rw(cpu, cpu->mem,
1181                                                        0x38000000 + addr, buf,
1182                                                        length, MEM_WRITE,
1183                                                        NO_EXCEPTIONS | PHYSICAL);
1184                                    }
1185                                    break;
1186    
1187                            default:fatal("\n--- MTE OP %i color 0x%02x: %i,%i - "
1188                                        "%i,%i\n\n", op, color, x1,y1, x2,y2);
1189                            }
1190                    }
1191                    break;
1192    
1193            case 0x29f0:
1194                    /*  Pixel output:  */
1195                    {
1196                            uint32_t data = d->reg[0x20c4 / sizeof(uint32_t)];
1197                            uint32_t color = d->reg[0x20d0 / sizeof(uint32_t)]&255;
1198                            uint32_t x1 = (d->reg[0x2070 / sizeof(uint32_t)]
1199                                >> 16) & 0xfff;
1200                            uint32_t y1 = d->reg[0x2070 / sizeof(uint32_t)]& 0xfff;
1201                            uint32_t x2 = (d->reg[0x2074 / sizeof(uint32_t)]
1202                                >> 16) & 0xfff;
1203                            uint32_t y2 = d->reg[0x2074 / sizeof(uint32_t)]& 0xfff;
1204                            size_t x, y;
1205    
1206                            if (x2 < x1) {
1207                                    int tmp = x1; x1 = x2; x2 = tmp;
1208                            }
1209                            if (y2 < y1) {
1210                                    int tmp = y1; y1 = y2; y2 = tmp;
1211                            }
1212                            if (x2-x1 <= 15)
1213                                    data <<= 16;
1214    
1215                            x=x1; y=y1;
1216                            while (x <= x2 && y <= y2) {
1217                                    unsigned char buf = color;
1218                                    int addr = x + y*1280;
1219                                    int bit_set = data & 0x80000000UL;
1220                                    data <<= 1;
1221                                    if (x < 1280 && y < 1024 && bit_set)
1222                                            cpu->memory_rw(cpu, cpu->mem,
1223                                                0x38000000 + addr, &buf,1,MEM_WRITE,
1224                                                NO_EXCEPTIONS | PHYSICAL);
1225                                    x++;
1226                                    if (x > x2) {
1227                                            x = x1;
1228                                            y++;
1229                                    }
1230                            }
1231                    }
1232                    break;
1233    
1234    
1235          /*  Operations:  */          /*  Operations:  */
1236          case 0x3800:          case 0x3800:
1237                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
1238                          switch (idata) {                          switch (idata) {
1239                          case 0x11:              /*  zerofill  */                          case 0x11:              /*  zerofill  */
1240                                  first_addr = d->reg[0x3030 / sizeof(uint64_t)];                                  first_addr = d->reg[0x3030 / sizeof(uint32_t)];
1241                                  last_addr  = d->reg[0x3038 / sizeof(uint64_t)];                                  last_addr  = d->reg[0x3038 / sizeof(uint32_t)];
1242                                  zerobuflen = last_addr - first_addr + 1;                                  zerobuflen = last_addr - first_addr + 1;
1243                                  debug("[ sgi_mte: zerofill: first = 0x%016llx, last = 0x%016llx, length = 0x%llx ]\n",                                  debug("[ sgi_mte: zerofill: first = 0x%016llx,"
1244                                      (long long)first_addr, (long long)last_addr, (long long)zerobuflen);                                      " last = 0x%016llx, length = 0x%llx ]\n",
1245                                        (long long)first_addr, (long long)
1246                                        last_addr, (long long)zerobuflen);
1247    
1248                                  /*  TODO:  is there a better way to implement this?  */                                  /*  TODO:  is there a better way to
1249                                               implement this?  */
1250                                  memset(zerobuf, 0, sizeof(zerobuf));                                  memset(zerobuf, 0, sizeof(zerobuf));
1251                                  fill_addr = first_addr;                                  fill_addr = first_addr;
1252                                  while (zerobuflen != 0) {                                  while (zerobuflen != 0) {
# Line 1117  int dev_sgi_mte_access(struct cpu *cpu, Line 1263  int dev_sgi_mte_access(struct cpu *cpu,
1263    
1264                                  break;                                  break;
1265                          default:                          default:
1266                                  fatal("[ sgi_mte: UNKNOWN operation 0x%x ]\n", idata);                                  fatal("[ sgi_mte: UNKNOWN operation "
1267                                        "0x%x ]\n", idata);
1268                          }                          }
1269                  }                  }
1270                  break;                  break;
1271          default:          default:
1272                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
1273                          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 "
1274                                "address 0x%llx, data=0x%016llx ]\n",
1275                                (long long)relative_addr, (long long)idata);
1276                  else                  else
1277                          debug("[ sgi_mte: unimplemented read from address 0x%llx ]\n", (long long)relative_addr);                          debug("[ sgi_mte: unimplemented read from address"
1278                                " 0x%llx ]\n", (long long)relative_addr);
1279          }          }
1280    
1281          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)
# Line 1148  void dev_sgi_mte_init(struct memory *mem Line 1298  void dev_sgi_mte_init(struct memory *mem
1298          memset(d, 0, sizeof(struct sgi_mte_data));          memset(d, 0, sizeof(struct sgi_mte_data));
1299    
1300          memory_device_register(mem, "sgi_mte", baseaddr, DEV_SGI_MTE_LENGTH,          memory_device_register(mem, "sgi_mte", baseaddr, DEV_SGI_MTE_LENGTH,
1301              dev_sgi_mte_access, (void *)d, MEM_DEFAULT, NULL);              dev_sgi_mte_access, (void *)d, DM_DEFAULT, NULL);
1302  }  }
1303    

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

  ViewVC Help
Powered by ViewVC 1.1.26