25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: dev_mp.c,v 1.40 2007/01/28 13:45:46 debug Exp $ |
* $Id: dev_mp.c,v 1.42 2007/06/15 19:57:33 debug Exp $ |
29 |
|
* |
30 |
|
* COMMENT: Generic Multi-processor controller for the test machines |
31 |
* |
* |
32 |
* This is a fake multiprocessor (MP) device. It can be useful for |
* This is a fake multiprocessor (MP) device. It can be useful for |
33 |
* theoretical experiments, but probably bares no resemblance to any |
* theoretical experiments, but probably bares no resemblance to any |
194 |
send_it = 1; |
send_it = 1; |
195 |
if (send_it) { |
if (send_it) { |
196 |
d->n_pending_ipis[i] ++; |
d->n_pending_ipis[i] ++; |
197 |
d->ipi[i] = realloc(d->ipi[i], |
CHECK_ALLOCATION(d->ipi[i] = realloc(d->ipi[i], |
198 |
d->n_pending_ipis[i] * sizeof(int)); |
d->n_pending_ipis[i] * sizeof(int))); |
|
if (d->ipi[i] == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
199 |
|
|
200 |
/* Add the IPI last in the array: */ |
/* Add the IPI last in the array: */ |
201 |
d->ipi[i][d->n_pending_ipis[i] - 1] = |
d->ipi[i][d->n_pending_ipis[i] - 1] = |
234 |
case DEV_MP_NCYCLES: |
case DEV_MP_NCYCLES: |
235 |
/* |
/* |
236 |
* Return _approximately_ the number of cycles executed |
* Return _approximately_ the number of cycles executed |
237 |
* in this machine. |
* on this CPU. |
|
* |
|
|
* Note: At the moment, this is actually the number of |
|
|
* instructions executed on CPU 0. |
|
238 |
* |
* |
239 |
* (This value is not updated for each instruction.) |
* (This value is not updated for each instruction.) |
240 |
*/ |
*/ |
241 |
odata = cpu->machine->ninstrs; |
odata = cpu->ninstrs; |
242 |
break; |
break; |
243 |
|
|
244 |
default: |
default: |
258 |
struct mp_data *d; |
struct mp_data *d; |
259 |
int n, i; |
int n, i; |
260 |
|
|
261 |
d = malloc(sizeof(struct mp_data)); |
CHECK_ALLOCATION(d = malloc(sizeof(struct mp_data))); |
|
if (d == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
262 |
memset(d, 0, sizeof(struct mp_data)); |
memset(d, 0, sizeof(struct mp_data)); |
263 |
|
|
264 |
d->cpus = devinit->machine->cpus; |
d->cpus = devinit->machine->cpus; |
265 |
d->startup_addr = INITIAL_PC; |
d->startup_addr = INITIAL_PC; |
266 |
d->stack_addr = INITIAL_STACK_POINTER; |
d->stack_addr = INITIAL_STACK_POINTER; |
268 |
n = devinit->machine->ncpus; |
n = devinit->machine->ncpus; |
269 |
|
|
270 |
/* Connect to all CPUs' IPI pins: */ |
/* Connect to all CPUs' IPI pins: */ |
271 |
d->ipi_irq = malloc(n * sizeof(struct interrupt)); |
CHECK_ALLOCATION(d->ipi_irq = malloc(n * sizeof(struct interrupt))); |
272 |
if (d->ipi_irq == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
273 |
for (i=0; i<n; i++) { |
for (i=0; i<n; i++) { |
274 |
char tmpstr[200]; |
char tmpstr[200]; |
275 |
snprintf(tmpstr, sizeof(tmpstr), "%s.cpu[%i].%s", |
snprintf(tmpstr, sizeof(tmpstr), "%s.cpu[%i].%s", |
277 |
INTERRUPT_CONNECT(tmpstr, d->ipi_irq[i]); |
INTERRUPT_CONNECT(tmpstr, d->ipi_irq[i]); |
278 |
} |
} |
279 |
|
|
280 |
d->n_pending_ipis = malloc(n * sizeof(int)); |
CHECK_ALLOCATION(d->n_pending_ipis = malloc(n * sizeof(int))); |
|
d->ipi = malloc(n * sizeof(int *)); |
|
|
if (d->ipi == NULL || d->n_pending_ipis == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
281 |
memset(d->n_pending_ipis, 0, sizeof(int) * n); |
memset(d->n_pending_ipis, 0, sizeof(int) * n); |
282 |
|
|
283 |
|
CHECK_ALLOCATION(d->ipi = malloc(n * sizeof(int *))); |
284 |
memset(d->ipi, 0, sizeof(int *) * n); |
memset(d->ipi, 0, sizeof(int *) * n); |
285 |
|
|
286 |
memory_device_register(devinit->machine->memory, devinit->name, |
memory_device_register(devinit->machine->memory, devinit->name, |