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.29 2005/08/13 08:25:48 debug Exp $ |
29 |
* |
* |
30 |
* SGI IP32 devices. |
* SGI IP32 devices. |
31 |
* |
* |
154 |
else |
else |
155 |
memcpy(data, &d->reg[relative_addr], len); |
memcpy(data, &d->reg[relative_addr], len); |
156 |
|
|
157 |
if (relative_addr == 0x18 || relative_addr == 0x1c) { |
if ((relative_addr >= 0x18 && relative_addr <= 0x1f) || |
158 |
|
(relative_addr+len-1 >= 0x18 && relative_addr+len-1 <= 0x1f)) { |
159 |
/* |
/* |
160 |
* Force interrupt re-assertion: |
* Force interrupt re-assertion: |
161 |
* |
* |
162 |
* NOTE: Ugly hack. Hopefully CRMERR is never used. |
* NOTE: Ugly hack. Hopefully CRMERR is never used. |
163 |
*/ |
*/ |
164 |
#if 0 |
#if 0 |
165 |
|
/* |
166 |
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. |
167 |
TODO. |
TODO. |
168 |
|
*/ |
169 |
cpu_interrupt_ack(cpu, 8); /* CRM_INT_CRMERR); */ |
cpu_interrupt_ack(cpu, 8); /* CRM_INT_CRMERR); */ |
170 |
#endif |
#endif |
171 |
} |
} |
196 |
"control 0x%016llx ]\n", (long long)idata); |
"control 0x%016llx ]\n", (long long)idata); |
197 |
} |
} |
198 |
break; |
break; |
199 |
#if 1 |
#if 0 |
200 |
case CRIME_INTSTAT: /* 0x010, Current interrupt status */ |
case CRIME_INTSTAT: /* 0x010, Current interrupt status */ |
201 |
case 0x14: |
case 0x14: |
202 |
case CRIME_INTMASK: /* 0x018, Current interrupt mask */ |
case CRIME_INTMASK: /* 0x018, Current interrupt mask */ |
203 |
case 0x1c: |
case 0x1c: |
204 |
case 0x34: |
case 0x34: |
|
#endif |
|
205 |
/* don't dump debug info for these */ |
/* don't dump debug info for these */ |
206 |
break; |
break; |
207 |
|
#endif |
208 |
default: |
default: |
209 |
if (writeflag==MEM_READ) { |
if (writeflag==MEM_READ) { |
210 |
debug("[ crime: read from 0x%x, len=%i:", |
debug("[ crime: read from 0x%x, len=%i:", |
267 |
else |
else |
268 |
memcpy(data, &d->reg[relative_addr], len); |
memcpy(data, &d->reg[relative_addr], len); |
269 |
|
|
270 |
|
if ((relative_addr >= 0x18 && relative_addr <= 0x1f) || |
271 |
|
(relative_addr+len-1 >= 0x18 && relative_addr+len-1 <= 0x1f)) |
272 |
|
cpu_interrupt_ack(cpu, 8); /* CRM_INT_CRMERR); */ |
273 |
|
|
274 |
switch (relative_addr) { |
switch (relative_addr) { |
275 |
#if 0 |
#if 0 |
276 |
case 0x14: /* Current interrupt assertions */ |
case 0x10: /* Current interrupt assertions */ |
277 |
case 0x18: /* ??? */ |
case 0x14: |
278 |
case 0x1c: /* Interrupt mask */ |
/* don't dump debug info for these */ |
279 |
|
if (writeflag == MEM_WRITE) { |
280 |
|
fatal("[ NOTE/TODO: WRITE to mace intr: " |
281 |
|
"reladdr=0x%x data=", (int)relative_addr); |
282 |
|
for (i=0; i<len; i++) |
283 |
|
fatal(" %02x", data[i]); |
284 |
|
fatal(" (len=%i) ]\n", len); |
285 |
|
} |
286 |
|
break; |
287 |
|
case 0x18: /* Interrupt mask */ |
288 |
|
case 0x1c: |
289 |
/* don't dump debug info for these */ |
/* don't dump debug info for these */ |
290 |
break; |
break; |
291 |
#endif |
#endif |
292 |
default: |
default: |
293 |
if (writeflag==MEM_READ) { |
if (writeflag == MEM_READ) { |
294 |
debug("[ mace: read from 0x%x, len=%i ]\n", |
debug("[ mace: read from 0x%x:", (int)relative_addr); |
295 |
(int)relative_addr, len); |
for (i=0; i<len; i++) |
296 |
|
debug(" %02x", data[i]); |
297 |
|
debug(" (len=%i) ]\n", len); |
298 |
} else { |
} else { |
299 |
debug("[ mace: write to 0x%x:", (int)relative_addr); |
debug("[ mace: write to 0x%x:", (int)relative_addr); |
300 |
for (i=0; i<len; i++) |
for (i=0; i<len; i++) |
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 |
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: |
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) { |
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 |
|
|
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) |
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 |
|
|
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 |
|
* TODO: Run the O2's prom and try to figure out what it really does. |
1041 |
*/ |
*/ |
1042 |
|
/* #define debug fatal */ |
1043 |
#define ZERO_CHUNK_LEN 4096 |
#define ZERO_CHUNK_LEN 4096 |
1044 |
|
|
1045 |
struct sgi_mte_data { |
struct sgi_mte_data { |
1069 |
odata = d->reg[regnr]; |
odata = d->reg[regnr]; |
1070 |
|
|
1071 |
/* |
/* |
1072 |
* 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 |
1073 |
* 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 |
1074 |
* memory. |
* chunks of memory. |
1075 |
* |
* |
1076 |
* [ sgi_mte: unimplemented write to address 0x3030, data=0x00000000003da000 ] <-- first address |
* [ sgi_mte: unimplemented write to address 0x3030, data=0x00000000003da000 ] <-- first address |
1077 |
* [ sgi_mte: unimplemented write to address 0x3038, data=0x00000000003f9fff ] <-- last address |
* [ sgi_mte: unimplemented write to address 0x3038, data=0x00000000003f9fff ] <-- last address |
1115 |
case 0x1778: |
case 0x1778: |
1116 |
break; |
break; |
1117 |
|
|
1118 |
|
#if 1 |
1119 |
|
case 0x2074: |
1120 |
|
{ |
1121 |
|
/* This seems to have to do with graphical output: |
1122 |
|
0x000000000xxx0yyy where x is usually 0..1279 and y is 0..1023? */ |
1123 |
|
/* Gaaah... */ |
1124 |
|
int x = (idata >> 16) & 0xfff; |
1125 |
|
int y = idata & 0xfff; |
1126 |
|
int addr; |
1127 |
|
unsigned char buf[3]; |
1128 |
|
printf("x = %i, y = %i\n", x, y); |
1129 |
|
buf[0] = buf[1] = buf[2] = random() | 0x80; |
1130 |
|
addr = (x/2 + (y/2)*640) * 3; |
1131 |
|
if (x < 640 && y < 480) |
1132 |
|
cpu->memory_rw(cpu, cpu->mem, 0x38000000 + addr, |
1133 |
|
buf, 3, MEM_WRITE, NO_EXCEPTIONS | PHYSICAL); |
1134 |
|
|
1135 |
|
} |
1136 |
|
break; |
1137 |
|
#endif |
1138 |
|
|
1139 |
/* Operations: */ |
/* Operations: */ |
1140 |
case 0x3800: |
case 0x3800: |
1141 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |