/[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 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC
# 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.38 2005/11/21 09:17:27 debug Exp $
29   *     *  
30   *  SGI IP32 devices.   *  SGI IP32 devices.
31   *   *
# Line 110  int dev_crime_access(struct cpu *cpu, st Line 110  int dev_crime_access(struct cpu *cpu, st
110          uint64_t relative_addr, unsigned char *data, size_t len,          uint64_t relative_addr, unsigned char *data, size_t len,
111          int writeflag, void *extra)          int writeflag, void *extra)
112  {  {
         int i;  
113          struct crime_data *d = extra;          struct crime_data *d = extra;
114          uint64_t idata;          uint64_t idata = 0;
115            int i;
116    
117          idata = memory_readmax64(cpu, data, len);          if (writeflag == MEM_WRITE)
118                    idata = memory_readmax64(cpu, data, len);
119    
120          /*          /*
121           *  Set crime version/revision:           *  Set crime version/revision:
122           *           *
123           *  This might not be the most elegant or correct solution,           *  This might not be the most elegant or correct solution, but it
124           *  but it seems that the IP32 PROM likes 0x11 for machines           *  seems that the IP32 PROM likes 0x11 for machines without graphics,
125           *  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.  
126           *           *
127           *  (TODO?)           *  NetBSD 2.0 complains about "unknown" crime for 0x11, but I guess
128             *  that's something one has to live with.  (TODO?)
129           */           */
130          d->reg[4] = 0x00; d->reg[5] = 0x00; d->reg[6] = 0x00;          d->reg[4] = 0x00; d->reg[5] = 0x00; d->reg[6] = 0x00;
131          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 153  int dev_crime_access(struct cpu *cpu, st
153          else          else
154                  memcpy(data, &d->reg[relative_addr], len);                  memcpy(data, &d->reg[relative_addr], len);
155    
156          if (relative_addr == 0x18 || relative_addr == 0x1c) {          if ((relative_addr >= 0x18 && relative_addr <= 0x1f) ||
157                (relative_addr+len-1 >= 0x18 && relative_addr+len-1 <= 0x1f)) {
158                  /*                  /*
159                   *  Force interrupt re-assertion:                   *  Force interrupt re-assertion:
160                   *                   *
161                   *  NOTE: Ugly hack. Hopefully CRMERR is never used.                   *  NOTE: Ugly hack. Hopefully CRMERR is never used.
162                   */                   */
163  #if 0  #if 0
164    /*
165  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.
166  TODO.  TODO.
167    */
168                  cpu_interrupt_ack(cpu, 8); /* CRM_INT_CRMERR); */                  cpu_interrupt_ack(cpu, 8); /* CRM_INT_CRMERR); */
169  #endif  #endif
170          }          }
# 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 266  int dev_mace_access(struct cpu *cpu, str Line 266  int dev_mace_access(struct cpu *cpu, str
266          else          else
267                  memcpy(data, &d->reg[relative_addr], len);                  memcpy(data, &d->reg[relative_addr], len);
268    
269            if ((relative_addr >= 0x18 && relative_addr <= 0x1f) ||
270                (relative_addr+len-1 >= 0x18 && relative_addr+len-1 <= 0x1f))
271                    cpu_interrupt_ack(cpu, 8); /* CRM_INT_CRMERR); */
272    
273          switch (relative_addr) {          switch (relative_addr) {
274  #if 0  #if 0
275          case 0x14:      /*  Current interrupt assertions  */          case 0x10:      /*  Current interrupt assertions  */
276          case 0x18:      /*  ???  */          case 0x14:
277          case 0x1c:      /*  Interrupt mask  */                  /*  don't dump debug info for these  */
278                    if (writeflag == MEM_WRITE) {
279                            fatal("[ NOTE/TODO: WRITE to mace intr: "
280                                "reladdr=0x%x data=", (int)relative_addr);
281                            for (i=0; i<len; i++)
282                                    fatal(" %02x", data[i]);
283                            fatal(" (len=%i) ]\n", len);
284                    }
285                    break;
286            case 0x18:      /*  Interrupt mask  */
287            case 0x1c:
288                  /*  don't dump debug info for these  */                  /*  don't dump debug info for these  */
289                  break;                  break;
290  #endif  #endif
291          default:          default:
292                  if (writeflag==MEM_READ) {                  if (writeflag == MEM_READ) {
293                          debug("[ mace: read from 0x%x, len=%i ]\n",                          debug("[ mace: read from 0x%x:", (int)relative_addr);
294                              (int)relative_addr, len);                          for (i=0; i<len; i++)
295                                    debug(" %02x", data[i]);
296                            debug(" (len=%i) ]\n", len);
297                  } else {                  } else {
298                          debug("[ mace: write to 0x%x:", (int)relative_addr);                          debug("[ mace: write to 0x%x:", (int)relative_addr);
299                          for (i=0; i<len; i++)                          for (i=0; i<len; i++)
# Line 307  struct mace_data *dev_mace_init(struct m Line 323  struct mace_data *dev_mace_init(struct m
323          d->irqnr = irqnr;          d->irqnr = irqnr;
324    
325          memory_device_register(mem, "mace", baseaddr, DEV_MACE_LENGTH,          memory_device_register(mem, "mace", baseaddr, DEV_MACE_LENGTH,
326              dev_mace_access, d, MEM_DEFAULT, NULL);              dev_mace_access, d, DM_DEFAULT, NULL);
327    
328          return d;          return d;
329  }  }
# Line 327  int dev_macepci_access(struct cpu *cpu, Line 343  int dev_macepci_access(struct cpu *cpu,
343          uint64_t idata = 0, odata=0;          uint64_t idata = 0, odata=0;
344          int regnr, res = 1;          int regnr, res = 1;
345    
346          idata = memory_readmax64(cpu, data, len);          if (writeflag == MEM_WRITE)
347                    idata = memory_readmax64(cpu, data, len);
348    
349          regnr = relative_addr / sizeof(uint32_t);          regnr = relative_addr / sizeof(uint32_t);
350    
351          /*  Read from/write to the macepci:  */          /*  Read from/write to the macepci:  */
# Line 354  int dev_macepci_access(struct cpu *cpu, Line 372  int dev_macepci_access(struct cpu *cpu,
372          case 0xcfc:     /*  PCI DATA  */          case 0xcfc:     /*  PCI DATA  */
373                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
374                          res = bus_pci_access(cpu, mem, relative_addr,                          res = bus_pci_access(cpu, mem, relative_addr,
375                              &idata, writeflag, d->pci_data);                              &idata, len, writeflag, d->pci_data);
376                  } else {                  } else {
377                          res = bus_pci_access(cpu, mem, relative_addr,                          res = bus_pci_access(cpu, mem, relative_addr,
378                              &odata, writeflag, d->pci_data);                              &odata, len, writeflag, d->pci_data);
                         /*  odata = 0;  */  
379                  }                  }
380                  break;                  break;
381          default:          default:
# 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(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 757  int dev_sgi_mec_access(struct cpu *cpu, Line 775  int dev_sgi_mec_access(struct cpu *cpu,
775          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
776          int regnr;          int regnr;
777    
778          idata = memory_readmax64(cpu, data, len);          if (writeflag == MEM_WRITE)
779                    idata = memory_readmax64(cpu, data, len);
780    
781          regnr = relative_addr / sizeof(uint64_t);          regnr = relative_addr / sizeof(uint64_t);
782    
783          /*  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 932  void dev_sgi_mec_init(struct machine *ma
932          uint64_t baseaddr, int irq_nr, unsigned char *macaddr)          uint64_t baseaddr, int irq_nr, unsigned char *macaddr)
933  {  {
934          char *name2;          char *name2;
935            size_t nlen = 55;
936          struct sgi_mec_data *d = malloc(sizeof(struct sgi_mec_data));          struct sgi_mec_data *d = malloc(sizeof(struct sgi_mec_data));
937    
938          if (d == NULL) {          if (d == NULL) {
# Line 924  void dev_sgi_mec_init(struct machine *ma Line 945  void dev_sgi_mec_init(struct machine *ma
945    
946          mec_reset(d);          mec_reset(d);
947    
948          name2 = malloc(50);          name2 = malloc(nlen);
949          if (name2 == NULL) {          if (name2 == NULL) {
950                  fprintf(stderr, "out of memory in dev_sgi_mec_init()\n");                  fprintf(stderr, "out of memory in dev_sgi_mec_init()\n");
951                  exit(1);                  exit(1);
952          }          }
953          sprintf(name2, "mec [%02x:%02x:%02x:%02x:%02x:%02x]",          snprintf(name2, nlen, "mec [%02x:%02x:%02x:%02x:%02x:%02x]",
954              d->macaddr[0], d->macaddr[1], d->macaddr[2],              d->macaddr[0], d->macaddr[1], d->macaddr[2],
955              d->macaddr[3], d->macaddr[4], d->macaddr[5]);              d->macaddr[3], d->macaddr[4], d->macaddr[5]);
956    
957          memory_device_register(mem, name2, baseaddr,          memory_device_register(mem, name2, baseaddr,
958              DEV_SGI_MEC_LENGTH, dev_sgi_mec_access, (void *)d,              DEV_SGI_MEC_LENGTH, dev_sgi_mec_access, (void *)d,
959              MEM_DEFAULT, NULL);              DM_DEFAULT, NULL);
960    
961          machine_add_tickfunction(machine, dev_sgi_mec_tick, d, MEC_TICK_SHIFT);          machine_add_tickfunction(machine, dev_sgi_mec_tick, d, MEC_TICK_SHIFT);
962    
# Line 977  int dev_sgi_ust_access(struct cpu *cpu, Line 998  int dev_sgi_ust_access(struct cpu *cpu,
998                  break;                  break;
999          default:          default:
1000                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
1001                          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 "
1002                                "address 0x%llx, data=0x%016llx ]\n",
1003                                (long long)relative_addr, (long long)idata);
1004                  else                  else
1005                          debug("[ sgi_ust: unimplemented read from address 0x%llx ]\n", (long long)relative_addr);                          debug("[ sgi_ust: unimplemented read from address"
1006                                " 0x%llx ]\n", (long long)relative_addr);
1007          }          }
1008    
1009          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)
# Line 1002  void dev_sgi_ust_init(struct memory *mem Line 1026  void dev_sgi_ust_init(struct memory *mem
1026          memset(d, 0, sizeof(struct sgi_ust_data));          memset(d, 0, sizeof(struct sgi_ust_data));
1027    
1028          memory_device_register(mem, "sgi_ust", baseaddr,          memory_device_register(mem, "sgi_ust", baseaddr,
1029              DEV_SGI_UST_LENGTH, dev_sgi_ust_access, (void *)d, MEM_DEFAULT, NULL);              DEV_SGI_UST_LENGTH, dev_sgi_ust_access, (void *)d,
1030                DM_DEFAULT, NULL);
1031  }  }
1032    
1033    
# Line 1011  void dev_sgi_ust_init(struct memory *mem Line 1036  void dev_sgi_ust_init(struct memory *mem
1036    
1037  /*  /*
1038   *  SGI "mte". This device seems to be an accelerator for copying/clearing   *  SGI "mte". This device seems to be an accelerator for copying/clearing
1039   *  memory.  Used in SGI-IP32.   *  memory. Used by (at least) the SGI O2 PROM.
1040     *
1041     *  Actually, it seems to be used for graphics output as well. (?)
1042     *  The O2's PROM uses it to output graphics.
1043   */   */
1044    /*  #define debug fatal  */
1045    /*  #define MTE_DEBUG  */
1046  #define ZERO_CHUNK_LEN          4096  #define ZERO_CHUNK_LEN          4096
1047    
1048  struct sgi_mte_data {  struct sgi_mte_data {
1049          uint64_t        reg[DEV_SGI_MTE_LENGTH / sizeof(uint64_t)];          uint32_t        reg[DEV_SGI_MTE_LENGTH / sizeof(uint32_t)];
1050  };  };
1051    
1052  /*  /*
# Line 1034  int dev_sgi_mte_access(struct cpu *cpu, Line 1063  int dev_sgi_mte_access(struct cpu *cpu,
1063          int regnr;          int regnr;
1064    
1065          idata = memory_readmax64(cpu, data, len);          idata = memory_readmax64(cpu, data, len);
1066          regnr = relative_addr / sizeof(uint64_t);          regnr = relative_addr / sizeof(uint32_t);
1067    
1068            /*
1069             *  Treat all registers as read/write, by default.  Sometimes these
1070             *  are accessed as 32-bit words, sometimes as 64-bit words.
1071             */
1072            if (len != 4) {
1073                    if (writeflag == MEM_WRITE) {
1074                            d->reg[regnr] = idata >> 32;
1075                            d->reg[regnr+1] = idata;
1076                    } else
1077                            odata = ((uint64_t)d->reg[regnr] << 32) +
1078                                d->reg[regnr+1];
1079            }
1080    
         /*  Treat all registers as read/write, by default.  */  
1081          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
1082                  d->reg[regnr] = idata;                  d->reg[regnr] = idata;
1083          else          else
1084                  odata = d->reg[regnr];                  odata = d->reg[regnr];
1085    
1086    #ifdef MTE_DEBUG
1087            if (writeflag == MEM_WRITE && relative_addr >= 0x2000 &&
1088                relative_addr < 0x3000)
1089                    fatal("[ MTE: 0x%08x: 0x%016llx ]\n", (int)relative_addr,
1090                        (long long)idata);
1091    #endif
1092    
1093          /*          /*
1094           *  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
1095           *  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
1096           *  memory.           *  chunks of memory.
1097           *           *
1098           *  [ sgi_mte: unimplemented write to address 0x3030, data=0x00000000003da000 ]  <-- first address           *   write to 0x3030, data=0x00000000003da000 ]  <-- first address
1099           *  [ sgi_mte: unimplemented write to address 0x3038, data=0x00000000003f9fff ]  <-- last address           *   write to 0x3038, data=0x00000000003f9fff ]  <-- last address
1100           *  [ sgi_mte: unimplemented write to address 0x3018, data=0x0000000000000000 ]  <-- what to fill?           *   write to 0x3018, data=0x0000000000000000 ]  <-- what to fill?
1101           *  [ sgi_mte: unimplemented write to address 0x3008, data=0x00000000ffffffff ]  <-- ?           *   write to 0x3008, data=0x00000000ffffffff ]  <-- ?
1102           *  [ sgi_mte: unimplemented write to address 0x3800, data=0x0000000000000011 ]  <-- operation (0x11 = zerofill)           *   write to 0x3800, data=0x0000000000000011 ]  <-- operation
1103             *                                                   (0x11 = zerofill)
1104           *           *
1105           *  [ sgi_mte: unimplemented write to address 0x1700, data=0x80001ea080001ea1 ]  <-- also containing the address to fill (?)           *   write to 0x1700, data=0x80001ea080001ea1  <-- also containing the
1106           *  [ sgi_mte: unimplemented write to address 0x1708, data=0x80001ea280001ea3 ]           *   write to 0x1708, data=0x80001ea280001ea3      address to fill (?)
1107           *  [ sgi_mte: unimplemented write to address 0x1710, data=0x80001ea480001ea5 ]           *   write to 0x1710, data=0x80001ea480001ea5
1108           *  ...           *  ...
1109           *  [ sgi_mte: unimplemented write to address 0x1770, data=0x80001e9c80001e9d ]           *   write to 0x1770, data=0x80001e9c80001e9d
1110           *  [ sgi_mte: unimplemented write to address 0x1778, data=0x80001e9e80001e9f ]           *   write to 0x1778, data=0x80001e9e80001e9f
1111           */           */
1112          switch (relative_addr) {          switch (relative_addr) {
1113    
# Line 1089  int dev_sgi_mte_access(struct cpu *cpu, Line 1138  int dev_sgi_mte_access(struct cpu *cpu,
1138          case 0x1778:          case 0x1778:
1139                  break;                  break;
1140    
1141            /*  Graphics stuff? No warning:  */
1142            case 0x2018:
1143            case 0x2060:
1144            case 0x2070:
1145            case 0x2074:
1146            case 0x20c0:
1147            case 0x20c4:
1148            case 0x20d0:
1149            case 0x21b0:
1150            case 0x21b8:
1151                    break;
1152    
1153            /*  Perform graphics operation:  */
1154            case 0x21f8:
1155                    {
1156                            uint32_t op = d->reg[0x2060 / sizeof(uint32_t)];
1157                            uint32_t color = d->reg[0x20d0 / sizeof(uint32_t)]&255;
1158                            uint32_t x1 = (d->reg[0x2070 / sizeof(uint32_t)]
1159                                >> 16) & 0xfff;
1160                            uint32_t y1 = d->reg[0x2070 / sizeof(uint32_t)]& 0xfff;
1161                            uint32_t x2 = (d->reg[0x2074 / sizeof(uint32_t)]
1162                                >> 16) & 0xfff;
1163                            uint32_t y2 = d->reg[0x2074 / sizeof(uint32_t)]& 0xfff;
1164                            int y;
1165    
1166                            op >>= 24;
1167    
1168                            switch (op) {
1169                            case 1: /*  Unknown. Used after drawing bitmaps?  */
1170                                    break;
1171                            case 3: /*  Fill:  */
1172                                    if (x2 < x1) {
1173                                            int tmp = x1; x1 = x2; x2 = tmp;
1174                                    }
1175                                    if (y2 < y1) {
1176                                            int tmp = y1; y1 = y2; y2 = tmp;
1177                                    }
1178                                    for (y=y1; y<=y2; y++) {
1179                                            unsigned char buf[1280];
1180                                            int length = x2-x1+1;
1181                                            int addr = (x1 + y*1280);
1182                                            if (length < 1)
1183                                                    length = 1;
1184                                            memset(buf, color, length);
1185                                            if (x1 < 1280 && y < 1024)
1186                                                    cpu->memory_rw(cpu, cpu->mem,
1187                                                        0x38000000 + addr, buf,
1188                                                        length, MEM_WRITE,
1189                                                        NO_EXCEPTIONS | PHYSICAL);
1190                                    }
1191                                    break;
1192    
1193                            default:fatal("\n--- MTE OP %i color 0x%02x: %i,%i - "
1194                                        "%i,%i\n\n", op, color, x1,y1, x2,y2);
1195                            }
1196                    }
1197                    break;
1198    
1199            case 0x29f0:
1200                    /*  Pixel output:  */
1201                    {
1202                            uint32_t data = d->reg[0x20c4 / sizeof(uint32_t)];
1203                            uint32_t color = d->reg[0x20d0 / sizeof(uint32_t)]&255;
1204                            uint32_t x1 = (d->reg[0x2070 / sizeof(uint32_t)]
1205                                >> 16) & 0xfff;
1206                            uint32_t y1 = d->reg[0x2070 / sizeof(uint32_t)]& 0xfff;
1207                            uint32_t x2 = (d->reg[0x2074 / sizeof(uint32_t)]
1208                                >> 16) & 0xfff;
1209                            uint32_t y2 = d->reg[0x2074 / sizeof(uint32_t)]& 0xfff;
1210                            int x,y;
1211                            if (x2 < x1) {
1212                                    int tmp = x1; x1 = x2; x2 = tmp;
1213                            }
1214                            if (y2 < y1) {
1215                                    int tmp = y1; y1 = y2; y2 = tmp;
1216                            }
1217                            if (x2-x1 <= 15)
1218                                    data <<= 16;
1219                            x=x1; y=y1;
1220                            while (x <= x2 && y <= y2) {
1221                                    unsigned char buf = color;
1222                                    int addr = x + y*1280;
1223                                    int bit_set = data & 0x80000000UL;
1224                                    data <<= 1;
1225                                    if (x < 1280 && y < 1024 && bit_set)
1226                                            cpu->memory_rw(cpu, cpu->mem,
1227                                                0x38000000 + addr, &buf,1,MEM_WRITE,
1228                                                NO_EXCEPTIONS | PHYSICAL);
1229                                    x++;
1230                                    if (x > x2) {
1231                                            x = x1;
1232                                            y++;
1233                                    }
1234                            }
1235                    }
1236                    break;
1237    
1238    
1239          /*  Operations:  */          /*  Operations:  */
1240          case 0x3800:          case 0x3800:
1241                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
1242                          switch (idata) {                          switch (idata) {
1243                          case 0x11:              /*  zerofill  */                          case 0x11:              /*  zerofill  */
1244                                  first_addr = d->reg[0x3030 / sizeof(uint64_t)];                                  first_addr = d->reg[0x3030 / sizeof(uint32_t)];
1245                                  last_addr  = d->reg[0x3038 / sizeof(uint64_t)];                                  last_addr  = d->reg[0x3038 / sizeof(uint32_t)];
1246                                  zerobuflen = last_addr - first_addr + 1;                                  zerobuflen = last_addr - first_addr + 1;
1247                                  debug("[ sgi_mte: zerofill: first = 0x%016llx, last = 0x%016llx, length = 0x%llx ]\n",                                  debug("[ sgi_mte: zerofill: first = 0x%016llx,"
1248                                      (long long)first_addr, (long long)last_addr, (long long)zerobuflen);                                      " last = 0x%016llx, length = 0x%llx ]\n",
1249                                        (long long)first_addr, (long long)
1250                                        last_addr, (long long)zerobuflen);
1251    
1252                                  /*  TODO:  is there a better way to implement this?  */                                  /*  TODO:  is there a better way to
1253                                               implement this?  */
1254                                  memset(zerobuf, 0, sizeof(zerobuf));                                  memset(zerobuf, 0, sizeof(zerobuf));
1255                                  fill_addr = first_addr;                                  fill_addr = first_addr;
1256                                  while (zerobuflen != 0) {                                  while (zerobuflen != 0) {
# Line 1117  int dev_sgi_mte_access(struct cpu *cpu, Line 1267  int dev_sgi_mte_access(struct cpu *cpu,
1267    
1268                                  break;                                  break;
1269                          default:                          default:
1270                                  fatal("[ sgi_mte: UNKNOWN operation 0x%x ]\n", idata);                                  fatal("[ sgi_mte: UNKNOWN operation "
1271                                        "0x%x ]\n", idata);
1272                          }                          }
1273                  }                  }
1274                  break;                  break;
1275          default:          default:
1276                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
1277                          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 "
1278                                "address 0x%llx, data=0x%016llx ]\n",
1279                                (long long)relative_addr, (long long)idata);
1280                  else                  else
1281                          debug("[ sgi_mte: unimplemented read from address 0x%llx ]\n", (long long)relative_addr);                          debug("[ sgi_mte: unimplemented read from address"
1282                                " 0x%llx ]\n", (long long)relative_addr);
1283          }          }
1284    
1285          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)
# Line 1148  void dev_sgi_mte_init(struct memory *mem Line 1302  void dev_sgi_mte_init(struct memory *mem
1302          memset(d, 0, sizeof(struct sgi_mte_data));          memset(d, 0, sizeof(struct sgi_mte_data));
1303    
1304          memory_device_register(mem, "sgi_mte", baseaddr, DEV_SGI_MTE_LENGTH,          memory_device_register(mem, "sgi_mte", baseaddr, DEV_SGI_MTE_LENGTH,
1305              dev_sgi_mte_access, (void *)d, MEM_DEFAULT, NULL);              dev_sgi_mte_access, (void *)d, DM_DEFAULT, NULL);
1306  }  }
1307    

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

  ViewVC Help
Powered by ViewVC 1.1.26