25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: machine.c,v 1.673 2006/06/24 19:52:27 debug Exp $ |
* $Id: machine.c,v 1.679 2006/07/16 13:32:25 debug Exp $ |
29 |
*/ |
*/ |
30 |
|
|
31 |
#include <stdio.h> |
#include <stdio.h> |
32 |
#include <stdlib.h> |
#include <stdlib.h> |
33 |
#include <stdarg.h> |
#include <stdarg.h> |
|
#ifdef SOLARIS |
|
|
/* TODO: is this strings vs string separation really necessary? */ |
|
|
#include <strings.h> |
|
|
#else |
|
34 |
#include <string.h> |
#include <string.h> |
|
#endif |
|
35 |
#include <time.h> |
#include <time.h> |
36 |
#include <unistd.h> |
#include <unistd.h> |
37 |
|
|
88 |
m->machine_subtype = MACHINE_NONE; |
m->machine_subtype = MACHINE_NONE; |
89 |
m->arch_pagesize = 4096; /* Should be overriden in |
m->arch_pagesize = 4096; /* Should be overriden in |
90 |
emul.c for other pagesizes. */ |
emul.c for other pagesizes. */ |
|
m->dyntrans_alignment_check = 1; |
|
91 |
m->prom_emulation = 1; |
m->prom_emulation = 1; |
92 |
m->speed_tricks = 1; |
m->allow_instruction_combinations = 1; |
93 |
m->byte_order_override = NO_BYTE_ORDER_OVERRIDE; |
m->byte_order_override = NO_BYTE_ORDER_OVERRIDE; |
94 |
m->boot_kernel_filename = ""; |
m->boot_kernel_filename = ""; |
95 |
m->boot_string_argument = NULL; |
m->boot_string_argument = NULL; |
252 |
|
|
253 |
|
|
254 |
/* |
/* |
255 |
|
* machine_statistics_init(): |
256 |
|
* |
257 |
|
* Initialize the parts of a machine struct that deal with instruction |
258 |
|
* statistics gathering. |
259 |
|
* |
260 |
|
* Note: The fname argument contains "flags:filename". |
261 |
|
*/ |
262 |
|
void machine_statistics_init(struct machine *machine, char *fname) |
263 |
|
{ |
264 |
|
int n_fields = 0; |
265 |
|
char *pcolon = fname; |
266 |
|
char *mode = "a"; /* Append by default */ |
267 |
|
|
268 |
|
machine->allow_instruction_combinations = 0; |
269 |
|
|
270 |
|
if (machine->statistics_fields != NULL) { |
271 |
|
fprintf(stderr, "Only one -s option is allowed.\n"); |
272 |
|
exit(1); |
273 |
|
} |
274 |
|
|
275 |
|
machine->statistics_fields = malloc(MAX_STATISTICS_FIELDS + 1); |
276 |
|
machine->statistics_enabled = 1; |
277 |
|
|
278 |
|
while (*pcolon && *pcolon != ':') |
279 |
|
pcolon ++; |
280 |
|
|
281 |
|
if (*pcolon != ':') { |
282 |
|
fprintf(stderr, "The syntax for the -s option is: " |
283 |
|
"-s flags:filename\nYou omitted the flags. Run g" |
284 |
|
"xemul -h for a list of available flags.\n"); |
285 |
|
exit(1); |
286 |
|
} |
287 |
|
|
288 |
|
while (*fname != ':') { |
289 |
|
switch (*fname) { |
290 |
|
|
291 |
|
/* Type flags: */ |
292 |
|
case 'v': |
293 |
|
case 'i': |
294 |
|
case 'p': |
295 |
|
machine->statistics_fields[n_fields ++] = *fname; |
296 |
|
if (n_fields >= MAX_STATISTICS_FIELDS) { |
297 |
|
fprintf(stderr, "Internal error: Too many " |
298 |
|
"statistics fields used. Increase " |
299 |
|
"MAX_STATISTICS_FIELDS.\n"); |
300 |
|
exit(1); |
301 |
|
} |
302 |
|
machine->statistics_fields[n_fields] = '\0'; |
303 |
|
break; |
304 |
|
|
305 |
|
/* Optional flags: */ |
306 |
|
case 'o': |
307 |
|
mode = "w"; |
308 |
|
break; |
309 |
|
case 'd': |
310 |
|
machine->statistics_enabled = 0; |
311 |
|
break; |
312 |
|
|
313 |
|
default:fprintf(stderr, "Unknown flag '%c' used with the" |
314 |
|
" -s option. Aborting.\n", *fname); |
315 |
|
exit(1); |
316 |
|
} |
317 |
|
fname ++; |
318 |
|
} |
319 |
|
|
320 |
|
fname ++; /* point to the filename after the colon */ |
321 |
|
|
322 |
|
machine->statistics_filename = strdup(fname); |
323 |
|
machine->statistics_file = fopen(machine->statistics_filename, mode); |
324 |
|
} |
325 |
|
|
326 |
|
|
327 |
|
/* |
328 |
* machine_bus_register(): |
* machine_bus_register(): |
329 |
* |
* |
330 |
* Registers a bus in a machine. |
* Registers a bus in a machine. |
984 |
|
|
985 |
for (i=0; i<ncpus; i++) { |
for (i=0; i<ncpus; i++) { |
986 |
if (cpus[i]->running) { |
if (cpus[i]->running) { |
987 |
int instrs_run = machine->cpu_family->run_instr( |
int instrs_run = cpus[i]->run_instr(cpus[i]); |
|
machine->emul, cpus[i]); |
|
988 |
if (i == 0) |
if (i == 0) |
989 |
cpu0instrs += instrs_run; |
cpu0instrs += instrs_run; |
990 |
} |
} |
993 |
/* |
/* |
994 |
* Hardware 'ticks': (clocks, interrupt sources...) |
* Hardware 'ticks': (clocks, interrupt sources...) |
995 |
* |
* |
996 |
* Here, cpu0instrs is the number of instructions |
* Here, cpu0instrs is the number of instructions executed on cpu0. |
997 |
* executed on cpu0. (TODO: don't use cpu 0 for this, |
* |
998 |
* use some kind of "mainbus" instead.) |
* TODO: This should be redesigned into some "mainbus" stuff instead! |
999 |
*/ |
*/ |
1000 |
|
|
1001 |
machine->ncycles += cpu0instrs; |
machine->ninstrs += cpu0instrs; |
1002 |
|
|
1003 |
for (te=0; te<machine->n_tick_entries; te++) { |
for (te=0; te<machine->n_tick_entries; te++) { |
1004 |
machine->ticks_till_next[te] -= cpu0instrs; |
machine->ticks_till_next[te] -= cpu0instrs; |