--- trunk/src/devices/dev_mp.c 2007/10/08 16:20:26 28 +++ trunk/src/devices/dev_mp.c 2007/10/08 16:21:17 34 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2006 Anders Gavare. All rights reserved. + * Copyright (C) 2003-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,11 +25,14 @@ * SUCH DAMAGE. * * - * $Id: dev_mp.c,v 1.37 2006/07/01 21:15:46 debug Exp $ + * $Id: dev_mp.c,v 1.40 2007/01/28 13:45:46 debug Exp $ * * This is a fake multiprocessor (MP) device. It can be useful for * theoretical experiments, but probably bares no resemblance to any * multiprocessor controller used in any real machine. + * + * NOTE: The devinit irq string should be the part _after_ "cpu[%i].". + * For MIPS, it will be MIPS_IPI_INT. */ #include @@ -37,9 +40,9 @@ #include #include "cpu.h" -#include "cpu_mips.h" #include "device.h" #include "machine.h" +#include "interrupt.h" #include "memory.h" #include "misc.h" @@ -55,15 +58,15 @@ /* Each CPU has an array of pending ipis. */ int *n_pending_ipis; int **ipi; + + /* Connections to all CPUs' IPI pins: */ + struct interrupt *ipi_irq; }; extern int single_step; -/* - * dev_mp_access(): - */ DEVICE_ACCESS(mp) { struct mp_data *d = extra; @@ -195,10 +198,12 @@ fprintf(stderr, "out of memory\n"); exit(1); } + /* Add the IPI last in the array: */ d->ipi[i][d->n_pending_ipis[i] - 1] = idata >> 16; - cpu_interrupt(d->cpus[i], MIPS_IPI_INT); + + INTERRUPT_ASSERT(d->ipi_irq[i]); } } break; @@ -222,9 +227,10 @@ &d->ipi[cpu->cpu_id][1], d->n_pending_ipis[cpu->cpu_id]); } + /* Deassert the interrupt, if there are no pending IPIs: */ if (d->n_pending_ipis[cpu->cpu_id] == 0) - cpu_interrupt_ack(d->cpus[cpu->cpu_id], MIPS_IPI_INT); + INTERRUPT_DEASSERT(d->ipi_irq[cpu->cpu_id]); break; case DEV_MP_NCYCLES: @@ -255,7 +261,7 @@ DEVINIT(mp) { struct mp_data *d; - int n; + int n, i; d = malloc(sizeof(struct mp_data)); if (d == NULL) { @@ -268,6 +274,20 @@ d->stack_addr = INITIAL_STACK_POINTER; n = devinit->machine->ncpus; + + /* Connect to all CPUs' IPI pins: */ + d->ipi_irq = malloc(n * sizeof(struct interrupt)); + if (d->ipi_irq == NULL) { + fprintf(stderr, "out of memory\n"); + exit(1); + } + for (i=0; imachine->path, i, devinit->interrupt_path); + INTERRUPT_CONNECT(tmpstr, d->ipi_irq[i]); + } + d->n_pending_ipis = malloc(n * sizeof(int)); d->ipi = malloc(n * sizeof(int *)); if (d->ipi == NULL || d->n_pending_ipis == NULL) {