/[gxemul]/upstream/0.4.5.1/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 /upstream/0.4.5.1/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 14 by dpavlin, Mon Oct 8 16:18:51 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.32 2005/08/19 09:43:35 debug Exp $
29   *     *  
30   *  SGI IP32 devices.   *  SGI IP32 devices.
31   *   *
# 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 995  int dev_sgi_ust_access(struct cpu *cpu, Line 996  int dev_sgi_ust_access(struct cpu *cpu,
996                  break;                  break;
997          default:          default:
998                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
999                          debug("[ sgi_ust: unimplemented write to address 0x%llx, data=0x%016llx ]\n", (long long)relative_addr, (long long)idata);                          debug("[ sgi_ust: unimplemented write to "
1000                                "address 0x%llx, data=0x%016llx ]\n",
1001                                (long long)relative_addr, (long long)idata);
1002                  else                  else
1003                          debug("[ sgi_ust: unimplemented read from address 0x%llx ]\n", (long long)relative_addr);                          debug("[ sgi_ust: unimplemented read from address"
1004                                " 0x%llx ]\n", (long long)relative_addr);
1005          }          }
1006    
1007          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)
# Line 1020  void dev_sgi_ust_init(struct memory *mem Line 1024  void dev_sgi_ust_init(struct memory *mem
1024          memset(d, 0, sizeof(struct sgi_ust_data));          memset(d, 0, sizeof(struct sgi_ust_data));
1025    
1026          memory_device_register(mem, "sgi_ust", baseaddr,          memory_device_register(mem, "sgi_ust", baseaddr,
1027              DEV_SGI_UST_LENGTH, dev_sgi_ust_access, (void *)d, MEM_DEFAULT, NULL);              DEV_SGI_UST_LENGTH, dev_sgi_ust_access, (void *)d,
1028                MEM_DEFAULT, NULL);
1029  }  }
1030    
1031    
# Line 1029  void dev_sgi_ust_init(struct memory *mem Line 1034  void dev_sgi_ust_init(struct memory *mem
1034    
1035  /*  /*
1036   *  SGI "mte". This device seems to be an accelerator for copying/clearing   *  SGI "mte". This device seems to be an accelerator for copying/clearing
1037   *  memory.  Used in SGI-IP32.   *  memory. Used by (at least) the SGI O2 PROM.
1038     *
1039     *  Actually, it seems to be used for graphics output as well. (?)
1040     *  The O2's PROM uses it to output graphics.
1041   */   */
1042    /*  #define debug fatal  */
1043    /*  #define MTE_DEBUG  */
1044  #define ZERO_CHUNK_LEN          4096  #define ZERO_CHUNK_LEN          4096
1045    
1046  struct sgi_mte_data {  struct sgi_mte_data {
1047          uint64_t        reg[DEV_SGI_MTE_LENGTH / sizeof(uint64_t)];          uint32_t        reg[DEV_SGI_MTE_LENGTH / sizeof(uint32_t)];
1048  };  };
1049    
1050  /*  /*
# Line 1052  int dev_sgi_mte_access(struct cpu *cpu, Line 1061  int dev_sgi_mte_access(struct cpu *cpu,
1061          int regnr;          int regnr;
1062    
1063          idata = memory_readmax64(cpu, data, len);          idata = memory_readmax64(cpu, data, len);
1064          regnr = relative_addr / sizeof(uint64_t);          regnr = relative_addr / sizeof(uint32_t);
1065    
1066            /*
1067             *  Treat all registers as read/write, by default.  Sometimes these
1068             *  are accessed as 32-bit words, sometimes as 64-bit words.
1069             */
1070            if (len != 4) {
1071                    if (writeflag == MEM_WRITE) {
1072                            d->reg[regnr] = idata >> 32;
1073                            d->reg[regnr+1] = idata;
1074                    } else
1075                            odata = ((uint64_t)d->reg[regnr] << 32) +
1076                                d->reg[regnr+1];
1077            }
1078    
         /*  Treat all registers as read/write, by default.  */  
1079          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
1080                  d->reg[regnr] = idata;                  d->reg[regnr] = idata;
1081          else          else
1082                  odata = d->reg[regnr];                  odata = d->reg[regnr];
1083    
1084    #ifdef MTE_DEBUG
1085            if (writeflag == MEM_WRITE && relative_addr >= 0x2000 &&
1086                relative_addr < 0x3000)
1087                    fatal("[ MTE: 0x%08x: 0x%016llx ]\n", (int)relative_addr,
1088                        (long long)idata);
1089    #endif
1090    
1091          /*          /*
1092           *  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
1093           *  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
1094           *  memory.           *  chunks of memory.
1095           *           *
1096           *  [ sgi_mte: unimplemented write to address 0x3030, data=0x00000000003da000 ]  <-- first address           *   write to 0x3030, data=0x00000000003da000 ]  <-- first address
1097           *  [ sgi_mte: unimplemented write to address 0x3038, data=0x00000000003f9fff ]  <-- last address           *   write to 0x3038, data=0x00000000003f9fff ]  <-- last address
1098           *  [ sgi_mte: unimplemented write to address 0x3018, data=0x0000000000000000 ]  <-- what to fill?           *   write to 0x3018, data=0x0000000000000000 ]  <-- what to fill?
1099           *  [ sgi_mte: unimplemented write to address 0x3008, data=0x00000000ffffffff ]  <-- ?           *   write to 0x3008, data=0x00000000ffffffff ]  <-- ?
1100           *  [ sgi_mte: unimplemented write to address 0x3800, data=0x0000000000000011 ]  <-- operation (0x11 = zerofill)           *   write to 0x3800, data=0x0000000000000011 ]  <-- operation
1101             *                                                   (0x11 = zerofill)
1102           *           *
1103           *  [ sgi_mte: unimplemented write to address 0x1700, data=0x80001ea080001ea1 ]  <-- also containing the address to fill (?)           *   write to 0x1700, data=0x80001ea080001ea1  <-- also containing the
1104           *  [ sgi_mte: unimplemented write to address 0x1708, data=0x80001ea280001ea3 ]           *   write to 0x1708, data=0x80001ea280001ea3      address to fill (?)
1105           *  [ sgi_mte: unimplemented write to address 0x1710, data=0x80001ea480001ea5 ]           *   write to 0x1710, data=0x80001ea480001ea5
1106           *  ...           *  ...
1107           *  [ sgi_mte: unimplemented write to address 0x1770, data=0x80001e9c80001e9d ]           *   write to 0x1770, data=0x80001e9c80001e9d
1108           *  [ sgi_mte: unimplemented write to address 0x1778, data=0x80001e9e80001e9f ]           *   write to 0x1778, data=0x80001e9e80001e9f
1109           */           */
1110          switch (relative_addr) {          switch (relative_addr) {
1111    
# Line 1107  int dev_sgi_mte_access(struct cpu *cpu, Line 1136  int dev_sgi_mte_access(struct cpu *cpu,
1136          case 0x1778:          case 0x1778:
1137                  break;                  break;
1138    
1139            /*  Graphics stuff? No warning:  */
1140            case 0x2018:
1141            case 0x2060:
1142            case 0x2070:
1143            case 0x2074:
1144            case 0x20c0:
1145            case 0x20c4:
1146            case 0x20d0:
1147            case 0x21b0:
1148            case 0x21b8:
1149                    break;
1150    
1151            /*  Perform graphics operation:  */
1152            case 0x21f8:
1153                    {
1154                            uint32_t op = d->reg[0x2060 / sizeof(uint32_t)];
1155                            uint32_t color = d->reg[0x20d0 / sizeof(uint32_t)]&255;
1156                            uint32_t x1 = (d->reg[0x2070 / sizeof(uint32_t)]
1157                                >> 16) & 0xfff;
1158                            uint32_t y1 = d->reg[0x2070 / sizeof(uint32_t)]& 0xfff;
1159                            uint32_t x2 = (d->reg[0x2074 / sizeof(uint32_t)]
1160                                >> 16) & 0xfff;
1161                            uint32_t y2 = d->reg[0x2074 / sizeof(uint32_t)]& 0xfff;
1162                            int y;
1163    
1164                            op >>= 24;
1165    
1166                            switch (op) {
1167                            case 1: /*  Unknown. Used after drawing bitmaps?  */
1168                                    break;
1169                            case 3: /*  Fill:  */
1170                                    if (x2 < x1) {
1171                                            int tmp = x1; x1 = x2; x2 = tmp;
1172                                    }
1173                                    if (y2 < y1) {
1174                                            int tmp = y1; y1 = y2; y2 = tmp;
1175                                    }
1176                                    for (y=y1; y<=y2; y++) {
1177                                            unsigned char buf[1280];
1178                                            int length = x2-x1+1;
1179                                            int addr = (x1 + y*1280);
1180                                            if (length < 1)
1181                                                    length = 1;
1182                                            memset(buf, color, length);
1183                                            if (x1 < 1280 && y < 1024)
1184                                                    cpu->memory_rw(cpu, cpu->mem,
1185                                                        0x38000000 + addr, buf,
1186                                                        length, MEM_WRITE,
1187                                                        NO_EXCEPTIONS | PHYSICAL);
1188                                    }
1189                                    break;
1190    
1191                            default:fatal("\n--- MTE OP %i color 0x%02x: %i,%i - "
1192                                        "%i,%i\n\n", op, color, x1,y1, x2,y2);
1193                            }
1194                    }
1195                    break;
1196    
1197            case 0x29f0:
1198                    /*  Pixel output:  */
1199                    {
1200                            uint32_t data = d->reg[0x20c4 / sizeof(uint32_t)];
1201                            uint32_t color = d->reg[0x20d0 / sizeof(uint32_t)]&255;
1202                            uint32_t x1 = (d->reg[0x2070 / sizeof(uint32_t)]
1203                                >> 16) & 0xfff;
1204                            uint32_t y1 = d->reg[0x2070 / sizeof(uint32_t)]& 0xfff;
1205                            uint32_t x2 = (d->reg[0x2074 / sizeof(uint32_t)]
1206                                >> 16) & 0xfff;
1207                            uint32_t y2 = d->reg[0x2074 / sizeof(uint32_t)]& 0xfff;
1208                            int x,y;
1209                            if (x2 < x1) {
1210                                    int tmp = x1; x1 = x2; x2 = tmp;
1211                            }
1212                            if (y2 < y1) {
1213                                    int tmp = y1; y1 = y2; y2 = tmp;
1214                            }
1215                            if (x2-x1 <= 15)
1216                                    data <<= 16;
1217                            x=x1; y=y1;
1218                            while (x <= x2 && y <= y2) {
1219                                    unsigned char buf = color;
1220                                    int addr = x + y*1280;
1221                                    int bit_set = data & 0x80000000UL;
1222                                    data <<= 1;
1223                                    if (x < 1280 && y < 1024 && bit_set)
1224                                            cpu->memory_rw(cpu, cpu->mem,
1225                                                0x38000000 + addr, &buf,1,MEM_WRITE,
1226                                                NO_EXCEPTIONS | PHYSICAL);
1227                                    x++;
1228                                    if (x > x2) {
1229                                            x = x1;
1230                                            y++;
1231                                    }
1232                            }
1233                    }
1234                    break;
1235    
1236    
1237          /*  Operations:  */          /*  Operations:  */
1238          case 0x3800:          case 0x3800:
1239                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
1240                          switch (idata) {                          switch (idata) {
1241                          case 0x11:              /*  zerofill  */                          case 0x11:              /*  zerofill  */
1242                                  first_addr = d->reg[0x3030 / sizeof(uint64_t)];                                  first_addr = d->reg[0x3030 / sizeof(uint32_t)];
1243                                  last_addr  = d->reg[0x3038 / sizeof(uint64_t)];                                  last_addr  = d->reg[0x3038 / sizeof(uint32_t)];
1244                                  zerobuflen = last_addr - first_addr + 1;                                  zerobuflen = last_addr - first_addr + 1;
1245                                  debug("[ sgi_mte: zerofill: first = 0x%016llx, last = 0x%016llx, length = 0x%llx ]\n",                                  debug("[ sgi_mte: zerofill: first = 0x%016llx,"
1246                                      (long long)first_addr, (long long)last_addr, (long long)zerobuflen);                                      " last = 0x%016llx, length = 0x%llx ]\n",
1247                                        (long long)first_addr, (long long)
1248                                        last_addr, (long long)zerobuflen);
1249    
1250                                  /*  TODO:  is there a better way to implement this?  */                                  /*  TODO:  is there a better way to
1251                                               implement this?  */
1252                                  memset(zerobuf, 0, sizeof(zerobuf));                                  memset(zerobuf, 0, sizeof(zerobuf));
1253                                  fill_addr = first_addr;                                  fill_addr = first_addr;
1254                                  while (zerobuflen != 0) {                                  while (zerobuflen != 0) {
# Line 1135  int dev_sgi_mte_access(struct cpu *cpu, Line 1265  int dev_sgi_mte_access(struct cpu *cpu,
1265    
1266                                  break;                                  break;
1267                          default:                          default:
1268                                  fatal("[ sgi_mte: UNKNOWN operation 0x%x ]\n", idata);                                  fatal("[ sgi_mte: UNKNOWN operation "
1269                                        "0x%x ]\n", idata);
1270                          }                          }
1271                  }                  }
1272                  break;                  break;
1273          default:          default:
1274                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
1275                          debug("[ sgi_mte: unimplemented write to address 0x%llx, data=0x%016llx ]\n", (long long)relative_addr, (long long)idata);                          debug("[ sgi_mte: unimplemented write to "
1276                                "address 0x%llx, data=0x%016llx ]\n",
1277                                (long long)relative_addr, (long long)idata);
1278                  else                  else
1279                          debug("[ sgi_mte: unimplemented read from address 0x%llx ]\n", (long long)relative_addr);                          debug("[ sgi_mte: unimplemented read from address"
1280                                " 0x%llx ]\n", (long long)relative_addr);
1281          }          }
1282    
1283          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)

Legend:
Removed from v.10  
changed lines
  Added in v.14

  ViewVC Help
Powered by ViewVC 1.1.26