1 |
/* |
/* |
2 |
* Copyright (C) 2004-2005 Anders Gavare. All rights reserved. |
* Copyright (C) 2004-2007 Anders Gavare. All rights reserved. |
3 |
* |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions are met: |
* modification, are permitted provided that the following conditions are met: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: dev_sgi_ip22.c,v 1.25 2005/10/26 14:37:04 debug Exp $ |
* $Id: dev_sgi_ip22.c,v 1.33 2007/06/15 19:57:34 debug Exp $ |
29 |
* |
* |
30 |
* SGI IP22 stuff. |
* COMMENT: SGI IP22 stuff |
31 |
*/ |
*/ |
32 |
|
|
33 |
#include <stdio.h> |
#include <stdio.h> |
46 |
#define SGI_IP22_TICK_SHIFT 14 |
#define SGI_IP22_TICK_SHIFT 14 |
47 |
|
|
48 |
|
|
49 |
/* |
DEVICE_TICK(sgi_ip22) |
|
* dev_sgi_ip22_tick(): |
|
|
*/ |
|
|
void dev_sgi_ip22_tick(struct cpu *cpu, void *extra) |
|
50 |
{ |
{ |
51 |
struct sgi_ip22_data *d = (struct sgi_ip22_data *) extra; |
struct sgi_ip22_data *d = extra; |
52 |
|
|
53 |
if (d->reg[0x38 / 4] != 0) |
if (d->reg[0x38 / 4] != 0) |
54 |
d->reg[0x38 / 4] --; |
d->reg[0x38 / 4] --; |
60 |
* |
* |
61 |
* The memory controller (?). |
* The memory controller (?). |
62 |
*/ |
*/ |
63 |
int dev_sgi_ip22_imc_access(struct cpu *cpu, struct memory *mem, |
DEVICE_ACCESS(sgi_ip22_imc) |
|
uint64_t relative_addr, unsigned char *data, size_t len, |
|
|
int writeflag, void *extra) |
|
64 |
{ |
{ |
65 |
struct sgi_ip22_data *d = (struct sgi_ip22_data *) extra; |
struct sgi_ip22_data *d = extra; |
66 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
67 |
int regnr; |
int regnr; |
68 |
|
|
164 |
* |
* |
165 |
* A so far unknown device, used by the IP22 prom during startup. |
* A so far unknown device, used by the IP22 prom during startup. |
166 |
*/ |
*/ |
167 |
int dev_sgi_ip22_unknown_access(struct cpu *cpu, struct memory *mem, |
DEVICE_ACCESS(sgi_ip22_unknown) |
|
uint64_t relative_addr, unsigned char *data, size_t len, |
|
|
int writeflag, void *extra) |
|
168 |
{ |
{ |
169 |
struct sgi_ip22_data *d = (struct sgi_ip22_data *) extra; |
struct sgi_ip22_data *d = extra; |
170 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
171 |
|
|
172 |
idata = memory_readmax64(cpu, data, len); |
idata = memory_readmax64(cpu, data, len); |
207 |
* |
* |
208 |
* A so far unknown device, used by the IP22 prom during startup. |
* A so far unknown device, used by the IP22 prom during startup. |
209 |
*/ |
*/ |
210 |
int dev_sgi_ip22_unknown2_access(struct cpu *cpu, struct memory *mem, |
DEVICE_ACCESS(sgi_ip22_unknown2) |
|
uint64_t relative_addr, unsigned char *data, size_t len, |
|
|
int writeflag, void *extra) |
|
211 |
{ |
{ |
212 |
struct sgi_ip22_data *d = (struct sgi_ip22_data *) extra; |
struct sgi_ip22_data *d = extra; |
213 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
214 |
int regnr; |
int regnr; |
215 |
|
|
241 |
} |
} |
242 |
|
|
243 |
|
|
244 |
/* |
DEVICE_ACCESS(sgi_ip22_sysid) |
|
* dev_sgi_ip22_sysid_access(): |
|
|
*/ |
|
|
int dev_sgi_ip22_sysid_access(struct cpu *cpu, struct memory *mem, |
|
|
uint64_t relative_addr, unsigned char *data, size_t len, |
|
|
int writeflag, void *extra) |
|
245 |
{ |
{ |
246 |
struct sgi_ip22_data *d = (struct sgi_ip22_data *) extra; |
struct sgi_ip22_data *d = extra; |
247 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
248 |
|
|
249 |
idata = memory_readmax64(cpu, data, len); |
idata = memory_readmax64(cpu, data, len); |
275 |
} |
} |
276 |
|
|
277 |
|
|
278 |
/* |
DEVICE_ACCESS(sgi_ip22) |
|
* dev_sgi_ip22_access(): |
|
|
* |
|
|
* Returns 1 if ok, 0 on error. |
|
|
*/ |
|
|
int dev_sgi_ip22_access(struct cpu *cpu, struct memory *mem, |
|
|
uint64_t relative_addr, unsigned char *data, size_t len, |
|
|
int writeflag, void *extra) |
|
279 |
{ |
{ |
280 |
struct sgi_ip22_data *d = (struct sgi_ip22_data *) extra; |
struct sgi_ip22_data *d = extra; |
281 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
282 |
int regnr; |
int regnr; |
283 |
|
|
311 |
* some interrupt which should never be used anyway. |
* some interrupt which should never be used anyway. |
312 |
* (TODO: Fix this.) |
* (TODO: Fix this.) |
313 |
*/ |
*/ |
314 |
cpu_interrupt_ack(cpu, 8 + 63); |
|
315 |
debug("[ sgi_ip22: write to local0 IRQ MASK, " |
fatal("TODO: ip22 legacy interrupt rewrite!\n"); |
316 |
"data=0x%llx ]\n", (long long)idata); |
abort(); |
317 |
|
|
318 |
|
// cpu_interrupt_ack(cpu, 8 + 63); |
319 |
|
// debug("[ sgi_ip22: write to local0 IRQ MASK, " |
320 |
|
// "data=0x%llx ]\n", (long long)idata); |
321 |
} else { |
} else { |
322 |
debug("[ sgi_ip22: read from local0 IRQ MASK, " |
debug("[ sgi_ip22: read from local0 IRQ MASK, " |
323 |
"data=0x%llx ]\n", (long long)odata); |
"data=0x%llx ]\n", (long long)odata); |
335 |
case 0x0c: /* local1 irq mask */ |
case 0x0c: /* local1 irq mask */ |
336 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
337 |
/* See commen above, about local0 irq mask. */ |
/* See commen above, about local0 irq mask. */ |
338 |
cpu_interrupt_ack(cpu, 8 + 63); |
|
339 |
debug("[ sgi_ip22: write to local1 IRQ MASK, " |
fatal("TODO: ip22 legacy interrupt rewrite!\n"); |
340 |
"data=0x%llx ]\n", (long long)idata); |
abort(); |
341 |
|
// cpu_interrupt_ack(cpu, 8 + 63); |
342 |
|
// debug("[ sgi_ip22: write to local1 IRQ MASK, " |
343 |
|
// "data=0x%llx ]\n", (long long)idata); |
344 |
} else { |
} else { |
345 |
debug("[ sgi_ip22: read from local1 IRQ MASK, " |
debug("[ sgi_ip22: read from local1 IRQ MASK, " |
346 |
"data=0x%llx ]\n", (long long)odata); |
"data=0x%llx ]\n", (long long)odata); |
407 |
} |
} |
408 |
|
|
409 |
|
|
|
/* |
|
|
* dev_sgi_ip22_init(): |
|
|
*/ |
|
410 |
struct sgi_ip22_data *dev_sgi_ip22_init(struct machine *machine, |
struct sgi_ip22_data *dev_sgi_ip22_init(struct machine *machine, |
411 |
struct memory *mem, uint64_t baseaddr, int guiness_flag) |
struct memory *mem, uint64_t baseaddr, int guiness_flag) |
412 |
{ |
{ |
413 |
struct sgi_ip22_data *d = malloc(sizeof(struct sgi_ip22_data)); |
struct sgi_ip22_data *d; |
414 |
if (d == NULL) { |
|
415 |
fprintf(stderr, "out of memory\n"); |
CHECK_ALLOCATION(d = malloc(sizeof(struct sgi_ip22_data))); |
|
exit(1); |
|
|
} |
|
416 |
memset(d, 0, sizeof(struct sgi_ip22_data)); |
memset(d, 0, sizeof(struct sgi_ip22_data)); |
417 |
|
|
418 |
d->guiness_flag = guiness_flag; |
d->guiness_flag = guiness_flag; |
419 |
|
|
420 |
memory_device_register(mem, "sgi_ip22", baseaddr, DEV_SGI_IP22_LENGTH, |
memory_device_register(mem, "sgi_ip22", baseaddr, DEV_SGI_IP22_LENGTH, |
421 |
dev_sgi_ip22_access, (void *)d, MEM_DEFAULT, NULL); |
dev_sgi_ip22_access, (void *)d, DM_DEFAULT, NULL); |
422 |
memory_device_register(mem, "sgi_ip22_sysid", 0x1fbd9858, 0x8, |
memory_device_register(mem, "sgi_ip22_sysid", 0x1fbd9858, 0x8, |
423 |
dev_sgi_ip22_sysid_access, (void *)d, MEM_DEFAULT, NULL); |
dev_sgi_ip22_sysid_access, (void *)d, DM_DEFAULT, NULL); |
424 |
memory_device_register(mem, "sgi_ip22_imc", IP22_IMC_BASE, |
memory_device_register(mem, "sgi_ip22_imc", IP22_IMC_BASE, |
425 |
DEV_SGI_IP22_IMC_LENGTH, dev_sgi_ip22_imc_access, (void *)d, |
DEV_SGI_IP22_IMC_LENGTH, dev_sgi_ip22_imc_access, (void *)d, |
426 |
MEM_DEFAULT, NULL); |
DM_DEFAULT, NULL); |
427 |
memory_device_register(mem, "sgi_ip22_unknown", 0x1fa01000, 0x10, |
memory_device_register(mem, "sgi_ip22_unknown", 0x1fa01000, 0x10, |
428 |
dev_sgi_ip22_unknown_access, (void *)d, MEM_DEFAULT, NULL); |
dev_sgi_ip22_unknown_access, (void *)d, DM_DEFAULT, NULL); |
429 |
memory_device_register(mem, "sgi_ip22_unknown2", IP22_UNKNOWN2_BASE, |
memory_device_register(mem, "sgi_ip22_unknown2", IP22_UNKNOWN2_BASE, |
430 |
DEV_SGI_IP22_UNKNOWN2_LENGTH, dev_sgi_ip22_unknown2_access, |
DEV_SGI_IP22_UNKNOWN2_LENGTH, dev_sgi_ip22_unknown2_access, |
431 |
(void *)d, MEM_DEFAULT, NULL); |
(void *)d, DM_DEFAULT, NULL); |
432 |
|
|
433 |
machine_add_tickfunction(machine, dev_sgi_ip22_tick, d, |
machine_add_tickfunction(machine, dev_sgi_ip22_tick, d, |
434 |
SGI_IP22_TICK_SHIFT); |
SGI_IP22_TICK_SHIFT); |