25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: dev_sgi_ip30.c,v 1.24 2007/02/03 20:14:23 debug Exp $ |
* $Id: dev_sgi_ip30.c,v 1.26 2007/06/15 19:57:34 debug Exp $ |
29 |
* |
* |
30 |
* SGI IP30 stuff. |
* COMMENT: SGI IP30 stuff |
31 |
* |
* |
32 |
* This is just comprised of hardcoded guesses so far. (Ugly.) |
* NOTE/TODO: This is just comprised of hardcoded guesses so far. (Ugly.) |
33 |
*/ |
*/ |
34 |
|
|
35 |
#include <stdio.h> |
#include <stdio.h> |
67 |
}; |
}; |
68 |
|
|
69 |
|
|
70 |
void dev_sgi_ip30_tick(struct cpu *cpu, void *extra) |
DEVICE_TICK(sgi_ip30) |
71 |
{ |
{ |
72 |
struct sgi_ip30_data *d = extra; |
struct sgi_ip30_data *d = extra; |
73 |
|
|
83 |
} |
} |
84 |
|
|
85 |
|
|
|
/* |
|
|
* dev_sgi_ip30_access(): |
|
|
*/ |
|
86 |
DEVICE_ACCESS(sgi_ip30) |
DEVICE_ACCESS(sgi_ip30) |
87 |
{ |
{ |
88 |
struct sgi_ip30_data *d = (struct sgi_ip30_data *) extra; |
struct sgi_ip30_data *d = extra; |
89 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
90 |
|
|
91 |
if (writeflag == MEM_WRITE) |
if (writeflag == MEM_WRITE) |
92 |
idata = memory_readmax64(cpu, data, len); |
idata = memory_readmax64(cpu, data, len); |
93 |
|
|
94 |
switch (relative_addr) { |
switch (relative_addr) { |
95 |
|
|
96 |
case 0x20: |
case 0x20: |
97 |
/* Memory bank configuration: */ |
/* Memory bank configuration: */ |
98 |
odata = 0x80010000ULL; |
odata = 0x80010000ULL; |
99 |
break; |
break; |
100 |
|
|
101 |
case 0x10000: /* Interrupt mask register 0: */ |
case 0x10000: /* Interrupt mask register 0: */ |
102 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
103 |
d->imask0 = idata; |
d->imask0 = idata; |
105 |
odata = d->imask0; |
odata = d->imask0; |
106 |
} |
} |
107 |
break; |
break; |
108 |
|
|
109 |
case 0x10018: |
case 0x10018: |
110 |
/* |
/* |
111 |
* If this is not implemented, the IP30 PROM complains during |
* If this is not implemented, the IP30 PROM complains during |
121 |
odata = d->reg_0x10018; |
odata = d->reg_0x10018; |
122 |
} |
} |
123 |
break; |
break; |
124 |
|
|
125 |
case 0x10020: /* Set ISR, according to Linux/IP30 */ |
case 0x10020: /* Set ISR, according to Linux/IP30 */ |
126 |
d->isr = idata; |
d->isr = idata; |
127 |
/* Recalculate CPU interrupt assertions: */ |
/* Recalculate CPU interrupt assertions: */ |
129 |
abort(); |
abort(); |
130 |
// cpu_interrupt(cpu, 8); |
// cpu_interrupt(cpu, 8); |
131 |
break; |
break; |
132 |
|
|
133 |
case 0x10028: /* Clear ISR, according to Linux/IP30 */ |
case 0x10028: /* Clear ISR, according to Linux/IP30 */ |
134 |
d->isr &= ~idata; |
d->isr &= ~idata; |
135 |
/* Recalculate CPU interrupt assertions: */ |
/* Recalculate CPU interrupt assertions: */ |
137 |
abort(); |
abort(); |
138 |
// cpu_interrupt(cpu, 8); |
// cpu_interrupt(cpu, 8); |
139 |
break; |
break; |
140 |
|
|
141 |
case 0x10030: /* Interrupt Status Register */ |
case 0x10030: /* Interrupt Status Register */ |
142 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
143 |
/* Clear-on-write (TODO: is this correct?) */ |
/* Clear-on-write (TODO: is this correct?) */ |
150 |
odata = d->isr; |
odata = d->isr; |
151 |
} |
} |
152 |
break; |
break; |
153 |
|
|
154 |
case 0x20000: |
case 0x20000: |
155 |
/* A counter */ |
/* A counter */ |
156 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
159 |
odata = d->reg_0x20000; |
odata = d->reg_0x20000; |
160 |
} |
} |
161 |
break; |
break; |
162 |
|
|
163 |
case 0x30000: |
case 0x30000: |
164 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
165 |
d->reg_0x30000 = idata; |
d->reg_0x30000 = idata; |
167 |
odata = d->reg_0x30000; |
odata = d->reg_0x30000; |
168 |
} |
} |
169 |
break; |
break; |
170 |
|
|
171 |
default: |
default: |
172 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
173 |
debug("[ sgi_ip30: unimplemented write to address " |
debug("[ sgi_ip30: unimplemented write to address " |
186 |
} |
} |
187 |
|
|
188 |
|
|
|
/* |
|
|
* dev_sgi_ip30_2_access(): |
|
|
*/ |
|
189 |
DEVICE_ACCESS(sgi_ip30_2) |
DEVICE_ACCESS(sgi_ip30_2) |
190 |
{ |
{ |
191 |
struct sgi_ip30_data *d = (struct sgi_ip30_data *) extra; |
struct sgi_ip30_data *d = extra; |
192 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
193 |
|
|
194 |
idata = memory_readmax64(cpu, data, len); |
idata = memory_readmax64(cpu, data, len); |
236 |
} |
} |
237 |
|
|
238 |
|
|
|
/* |
|
|
* dev_sgi_ip30_3_access(): |
|
|
*/ |
|
239 |
DEVICE_ACCESS(sgi_ip30_3) |
DEVICE_ACCESS(sgi_ip30_3) |
240 |
{ |
{ |
241 |
struct sgi_ip30_data *d = (struct sgi_ip30_data *) extra; |
struct sgi_ip30_data *d = extra; |
242 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
243 |
|
|
244 |
idata = memory_readmax64(cpu, data, len); |
idata = memory_readmax64(cpu, data, len); |
245 |
|
|
246 |
switch (relative_addr) { |
switch (relative_addr) { |
247 |
|
|
248 |
case 0xb4: |
case 0xb4: |
249 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
250 |
debug("[ sgi_ip30_3: unimplemented write to " |
debug("[ sgi_ip30_3: unimplemented write to " |
254 |
odata = 2; /* should be 2, or Irix loops */ |
odata = 2; /* should be 2, or Irix loops */ |
255 |
} |
} |
256 |
break; |
break; |
257 |
|
|
258 |
case 0x00104: |
case 0x00104: |
259 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
260 |
debug("[ sgi_ip30_3: unimplemented write to address " |
debug("[ sgi_ip30_3: unimplemented write to address " |
265 |
complains */ |
complains */ |
266 |
} |
} |
267 |
break; |
break; |
268 |
|
|
269 |
case 0x00284: |
case 0x00284: |
270 |
/* |
/* |
271 |
* If this is not implemented, the IP30 PROM complains during |
* If this is not implemented, the IP30 PROM complains during |
281 |
odata = d->reg_0x00284; |
odata = d->reg_0x00284; |
282 |
} |
} |
283 |
break; |
break; |
284 |
|
|
285 |
default: |
default: |
286 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
287 |
debug("[ sgi_ip30_3: unimplemented write to address " |
debug("[ sgi_ip30_3: unimplemented write to address " |
300 |
} |
} |
301 |
|
|
302 |
|
|
|
/* |
|
|
* dev_sgi_ip30_4_access(): |
|
|
*/ |
|
303 |
DEVICE_ACCESS(sgi_ip30_4) |
DEVICE_ACCESS(sgi_ip30_4) |
304 |
{ |
{ |
305 |
struct sgi_ip30_data *d = (struct sgi_ip30_data *) extra; |
struct sgi_ip30_data *d = extra; |
306 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
307 |
|
|
308 |
idata = memory_readmax64(cpu, data, len); |
idata = memory_readmax64(cpu, data, len); |
309 |
|
|
310 |
switch (relative_addr) { |
switch (relative_addr) { |
311 |
|
|
312 |
case 0x000b0: |
case 0x000b0: |
313 |
/* |
/* |
314 |
* If this is not implemented, the IP30 PROM complains during |
* If this is not implemented, the IP30 PROM complains during |
324 |
odata = d->reg_0x000b0; |
odata = d->reg_0x000b0; |
325 |
} |
} |
326 |
break; |
break; |
327 |
|
|
328 |
default: |
default: |
329 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
330 |
debug("[ sgi_ip30_4: unimplemented write to address" |
debug("[ sgi_ip30_4: unimplemented write to address" |
343 |
} |
} |
344 |
|
|
345 |
|
|
|
/* |
|
|
* dev_sgi_ip30_5_access(): |
|
|
*/ |
|
346 |
DEVICE_ACCESS(sgi_ip30_5) |
DEVICE_ACCESS(sgi_ip30_5) |
347 |
{ |
{ |
348 |
struct sgi_ip30_data *d = (struct sgi_ip30_data *) extra; |
struct sgi_ip30_data *d = extra; |
349 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
350 |
|
|
351 |
idata = memory_readmax64(cpu, data, len); |
idata = memory_readmax64(cpu, data, len); |
352 |
|
|
353 |
switch (relative_addr) { |
switch (relative_addr) { |
354 |
|
|
355 |
case 0x00000: |
case 0x00000: |
356 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
357 |
d->reg_0x00000 = idata; |
d->reg_0x00000 = idata; |
359 |
odata = d->reg_0x00000; |
odata = d->reg_0x00000; |
360 |
} |
} |
361 |
break; |
break; |
362 |
|
|
363 |
default: |
default: |
364 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
365 |
debug("[ sgi_ip30_5: unimplemented write to address " |
debug("[ sgi_ip30_5: unimplemented write to address " |
380 |
|
|
381 |
DEVINIT(sgi_ip30) |
DEVINIT(sgi_ip30) |
382 |
{ |
{ |
383 |
struct sgi_ip30_data *d = malloc(sizeof(struct sgi_ip30_data)); |
struct sgi_ip30_data *d; |
384 |
if (d == NULL) { |
|
385 |
fprintf(stderr, "out of memory\n"); |
CHECK_ALLOCATION(d = malloc(sizeof(struct sgi_ip30_data))); |
|
exit(1); |
|
|
} |
|
386 |
memset(d, 0, sizeof(struct sgi_ip30_data)); |
memset(d, 0, sizeof(struct sgi_ip30_data)); |
387 |
|
|
388 |
memory_device_register(devinit->machine->memory, "sgi_ip30_1", |
memory_device_register(devinit->machine->memory, "sgi_ip30_1", |
402 |
NULL); |
NULL); |
403 |
|
|
404 |
machine_add_tickfunction(devinit->machine, |
machine_add_tickfunction(devinit->machine, |
405 |
dev_sgi_ip30_tick, d, 16, 0.0); |
dev_sgi_ip30_tick, d, 16); |
406 |
|
|
407 |
return 1; |
return 1; |
408 |
} |
} |