/[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 10 by dpavlin, Mon Oct 8 16:18:27 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.27 2005/06/26 11:43:48 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.
126           *           *
127           *  NetBSD 2.0 complains about "unknown" crime for 0x11,           *  NetBSD 2.0 complains about "unknown" crime for 0x11, but I guess
128           *  but I guess that's something one has to live with.           *  that's something one has to live with.  (TODO?)
          *  
          *  (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 242  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 324  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 344  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 371  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 409  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 562  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 774  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 953  void dev_sgi_mec_init(struct machine *ma Line 956  void dev_sgi_mec_init(struct machine *ma
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 995  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 1020  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 1029  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 1052  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 1107  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 1135  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 1166  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.10  
changed lines
  Added in v.20

  ViewVC Help
Powered by ViewVC 1.1.26