--- trunk/src/devices/dev_sgi_ip30.c 2007/10/08 16:18:00 4 +++ trunk/src/devices/dev_sgi_ip30.c 2007/10/08 16:21:17 34 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2005 Anders Gavare. All rights reserved. + * Copyright (C) 2004-2007 Anders Gavare. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: dev_sgi_ip30.c,v 1.17 2005/02/25 06:14:30 debug Exp $ + * $Id: dev_sgi_ip30.c,v 1.24 2007/02/03 20:14:23 debug Exp $ * * SGI IP30 stuff. * @@ -37,12 +37,36 @@ #include #include "cpu.h" -#include "devices.h" +#include "device.h" #include "machine.h" #include "memory.h" #include "misc.h" +#define DEV_SGI_IP30_LENGTH 0x80000 + +struct sgi_ip30_data { + /* ip30: */ + uint64_t imask0; /* 0x10000 */ + uint64_t reg_0x10018; + uint64_t isr; /* 0x10030 */ + uint64_t reg_0x20000; + uint64_t reg_0x30000; + + /* ip30_2: */ + uint64_t reg_0x0029c; + + /* ip30_3: */ + uint64_t reg_0x00284; + + /* ip30_4: */ + uint64_t reg_0x000b0; + + /* ip30_5: */ + uint64_t reg_0x00000; +}; + + void dev_sgi_ip30_tick(struct cpu *cpu, void *extra) { struct sgi_ip30_data *d = extra; @@ -52,7 +76,9 @@ if (d->imask0 & ((int64_t)1<<50)) { /* TODO: Only interrupt if reg 0x20000 (the counter) has passed the compare (0x30000). */ - cpu_interrupt(cpu, 8+1 + 50); +fatal("IP30 legacy interrupt rewrite: TODO\n"); +abort(); +// cpu_interrupt(cpu, 8+1 + 50); } } @@ -60,14 +86,13 @@ /* * dev_sgi_ip30_access(): */ -int dev_sgi_ip30_access(struct cpu *cpu, struct memory *mem, - uint64_t relative_addr, unsigned char *data, size_t len, - int writeflag, void *extra) +DEVICE_ACCESS(sgi_ip30) { struct sgi_ip30_data *d = (struct sgi_ip30_data *) extra; uint64_t idata = 0, odata = 0; - idata = memory_readmax64(cpu, data, len); + if (writeflag == MEM_WRITE) + idata = memory_readmax64(cpu, data, len); switch (relative_addr) { case 0x20: @@ -99,19 +124,25 @@ case 0x10020: /* Set ISR, according to Linux/IP30 */ d->isr = idata; /* Recalculate CPU interrupt assertions: */ - cpu_interrupt(cpu, 8); +fatal("IP30 legacy interrupt rewrite: TODO\n"); +abort(); +// cpu_interrupt(cpu, 8); break; case 0x10028: /* Clear ISR, according to Linux/IP30 */ d->isr &= ~idata; /* Recalculate CPU interrupt assertions: */ - cpu_interrupt(cpu, 8); +fatal("IP30 legacy interrupt rewrite: TODO\n"); +abort(); +// cpu_interrupt(cpu, 8); break; case 0x10030: /* Interrupt Status Register */ if (writeflag == MEM_WRITE) { /* Clear-on-write (TODO: is this correct?) */ d->isr &= ~idata; /* Recalculate CPU interrupt assertions: */ - cpu_interrupt(cpu, 8); +fatal("IP30 legacy interrupt rewrite: TODO\n"); +abort(); +// cpu_interrupt(cpu, 8); } else { odata = d->isr; } @@ -152,9 +183,7 @@ /* * dev_sgi_ip30_2_access(): */ -int dev_sgi_ip30_2_access(struct cpu *cpu, struct memory *mem, - uint64_t relative_addr, unsigned char *data, size_t len, - int writeflag, void *extra) +DEVICE_ACCESS(sgi_ip30_2) { struct sgi_ip30_data *d = (struct sgi_ip30_data *) extra; uint64_t idata = 0, odata = 0; @@ -207,9 +236,7 @@ /* * dev_sgi_ip30_3_access(): */ -int dev_sgi_ip30_3_access(struct cpu *cpu, struct memory *mem, - uint64_t relative_addr, unsigned char *data, size_t len, - int writeflag, void *extra) +DEVICE_ACCESS(sgi_ip30_3) { struct sgi_ip30_data *d = (struct sgi_ip30_data *) extra; uint64_t idata = 0, odata = 0; @@ -272,9 +299,7 @@ /* * dev_sgi_ip30_4_access(): */ -int dev_sgi_ip30_4_access(struct cpu *cpu, struct memory *mem, - uint64_t relative_addr, unsigned char *data, size_t len, - int writeflag, void *extra) +DEVICE_ACCESS(sgi_ip30_4) { struct sgi_ip30_data *d = (struct sgi_ip30_data *) extra; uint64_t idata = 0, odata = 0; @@ -318,9 +343,7 @@ /* * dev_sgi_ip30_5_access(): */ -int dev_sgi_ip30_5_access(struct cpu *cpu, struct memory *mem, - uint64_t relative_addr, unsigned char *data, size_t len, - int writeflag, void *extra) +DEVICE_ACCESS(sgi_ip30_5) { struct sgi_ip30_data *d = (struct sgi_ip30_data *) extra; uint64_t idata = 0, odata = 0; @@ -353,11 +376,7 @@ } -/* - * dev_sgi_ip30_init(): - */ -struct sgi_ip30_data *dev_sgi_ip30_init(struct machine *machine, - struct memory *mem, uint64_t baseaddr) +DEVINIT(sgi_ip30) { struct sgi_ip30_data *d = malloc(sizeof(struct sgi_ip30_data)); if (d == NULL) { @@ -366,20 +385,25 @@ } memset(d, 0, sizeof(struct sgi_ip30_data)); - memory_device_register(mem, "sgi_ip30_1", baseaddr, - DEV_SGI_IP30_LENGTH, dev_sgi_ip30_access, (void *)d, - MEM_DEFAULT, NULL); - memory_device_register(mem, "sgi_ip30_2", 0x10000000, - 0x10000, dev_sgi_ip30_2_access, (void *)d, MEM_DEFAULT, NULL); - memory_device_register(mem, "sgi_ip30_3", 0x1f000000, - 0x10000, dev_sgi_ip30_3_access, (void *)d, MEM_DEFAULT, NULL); - memory_device_register(mem, "sgi_ip30_4", 0x1f600000, - 0x10000, dev_sgi_ip30_4_access, (void *)d, MEM_DEFAULT, NULL); - memory_device_register(mem, "sgi_ip30_5", 0x1f6c0000, - 0x10000, dev_sgi_ip30_5_access, (void *)d, MEM_DEFAULT, NULL); + memory_device_register(devinit->machine->memory, "sgi_ip30_1", + devinit->addr, DEV_SGI_IP30_LENGTH, dev_sgi_ip30_access, (void *)d, + DM_DEFAULT, NULL); + memory_device_register(devinit->machine->memory, "sgi_ip30_2", + 0x10000000, 0x10000, dev_sgi_ip30_2_access, (void *)d, DM_DEFAULT, + NULL); + memory_device_register(devinit->machine->memory, "sgi_ip30_3", + 0x1f000000, 0x10000, dev_sgi_ip30_3_access, (void *)d, DM_DEFAULT, + NULL); + memory_device_register(devinit->machine->memory, "sgi_ip30_4", + 0x1f600000, 0x10000, dev_sgi_ip30_4_access, (void *)d, DM_DEFAULT, + NULL); + memory_device_register(devinit->machine->memory, "sgi_ip30_5", + 0x1f6c0000, 0x10000, dev_sgi_ip30_5_access, (void *)d, DM_DEFAULT, + NULL); - machine_add_tickfunction(machine, dev_sgi_ip30_tick, d, 16); + machine_add_tickfunction(devinit->machine, + dev_sgi_ip30_tick, d, 16, 0.0); - return d; + return 1; }