--- trunk/src/devices/dev_mp.c 2007/10/08 16:18:19 8 +++ trunk/src/devices/dev_mp.c 2007/10/08 16:20:26 28 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2005 Anders Gavare. All rights reserved. + * Copyright (C) 2003-2006 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_mp.c,v 1.27 2005/06/11 20:51:41 debug Exp $ + * $Id: dev_mp.c,v 1.37 2006/07/01 21:15:46 debug Exp $ * * This is a fake multiprocessor (MP) device. It can be useful for * theoretical experiments, but probably bares no resemblance to any @@ -42,7 +42,8 @@ #include "machine.h" #include "memory.h" #include "misc.h" -#include "mp.h" + +#include "testmachine/dev_mp.h" struct mp_data { @@ -63,14 +64,14 @@ /* * dev_mp_access(): */ -int dev_mp_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr, - unsigned char *data, size_t len, int writeflag, void *extra) +DEVICE_ACCESS(mp) { struct mp_data *d = extra; int i, which_cpu; uint64_t idata = 0, odata = 0; - idata = memory_readmax64(cpu, data, len); + if (writeflag == MEM_WRITE) + idata = memory_readmax64(cpu, data, len); /* * NOTE: It is up to the user of this device to read or write @@ -120,20 +121,20 @@ break; case DEV_MP_PAUSE_CPU: - /* Pause all cpus except our selves: */ + /* Pause all cpus except a specific CPU: */ which_cpu = idata; for (i=0; imachine->ncpus; i++) - if (i!=which_cpu) + if (i != which_cpu) d->cpus[i]->running = 0; break; case DEV_MP_UNPAUSE_CPU: - /* Unpause all cpus except our selves: */ + /* Unpause a specific CPU: */ which_cpu = idata; - for (i=0; imachine->ncpus; i++) - if (i!=which_cpu) - d->cpus[i]->running = 1; + + if (which_cpu >= 0 && which_cpu machine->ncpus) + d->cpus[which_cpu]->running = 1; break; case DEV_MP_STARTUPSTACK: @@ -143,7 +144,12 @@ break; case DEV_MP_HARDWARE_RANDOM: - /* Return (up to) 64 bits of "hardware random": */ + /* + * Return (up to) 64 bits of "hardware random": + * + * NOTE: Remember that random() is (usually) 31 bits of + * random data, _NOT_ 32, hence this construction. + */ odata = random(); odata = (odata << 31) ^ random(); odata = (odata << 31) ^ random(); @@ -221,6 +227,19 @@ cpu_interrupt_ack(d->cpus[cpu->cpu_id], MIPS_IPI_INT); break; + case DEV_MP_NCYCLES: + /* + * Return _approximately_ the number of cycles executed + * in this machine. + * + * Note: At the moment, this is actually the number of + * instructions executed on CPU 0. + * + * (This value is not updated for each instruction.) + */ + odata = cpu->machine->ninstrs; + break; + default: fatal("[ dev_mp: unimplemented relative addr 0x%x ]\n", relative_addr); @@ -233,10 +252,7 @@ } -/* - * devinit_mp(): - */ -int devinit_mp(struct devinit *devinit) +DEVINIT(mp) { struct mp_data *d; int n; @@ -262,7 +278,7 @@ memset(d->ipi, 0, sizeof(int *) * n); memory_device_register(devinit->machine->memory, devinit->name, - devinit->addr, DEV_MP_LENGTH, dev_mp_access, d, MEM_DEFAULT, NULL); + devinit->addr, DEV_MP_LENGTH, dev_mp_access, d, DM_DEFAULT, NULL); return 1; }