25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: emul_parse.c,v 1.36 2006/01/14 12:51:59 debug Exp $ |
* $Id: emul_parse.c,v 1.42 2006/06/22 13:22:41 debug Exp $ |
29 |
* |
* |
30 |
* Set up an emulation by parsing a config file. |
* Set up an emulation by parsing a config file. |
31 |
* |
* |
32 |
* TODO: This could be extended to support XML config files as well, but |
* TODO: REWRITE THIS FROM SCRATCH! :-) |
|
* XML is ugly. It is ugly right now as well. The question is: which |
|
|
* solution is the least ugly? |
|
33 |
*/ |
*/ |
34 |
|
|
35 |
#include <stdio.h> |
#include <stdio.h> |
47 |
(ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || \ |
(ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || \ |
48 |
ch == '_' || ch == '$' || (ch >= '0' && ch <= '9') ) |
ch == '_' || ch == '$' || (ch >= '0' && ch <= '9') ) |
49 |
|
|
50 |
|
#define MAX_WORD_LEN 200 |
51 |
|
|
52 |
#define EXPECT_WORD 1 |
#define EXPECT_WORD 1 |
53 |
#define EXPECT_LEFT_PARENTHESIS 2 |
#define EXPECT_LEFT_PARENTHESIS 2 |
54 |
#define EXPECT_RIGHT_PARENTHESIS 4 |
#define EXPECT_RIGHT_PARENTHESIS 4 |
55 |
|
|
56 |
|
static int parenthesis_level = 0; |
57 |
|
|
58 |
|
|
59 |
/* |
/* |
60 |
* read_one_word(): |
* read_one_word(): |
174 |
done = 1; |
done = 1; |
175 |
} else { |
} else { |
176 |
if ((expect & EXPECT_LEFT_PARENTHESIS) && ch == '(') { |
if ((expect & EXPECT_LEFT_PARENTHESIS) && ch == '(') { |
177 |
|
parenthesis_level ++; |
178 |
buf[curlen++] = ch; |
buf[curlen++] = ch; |
179 |
break; |
break; |
180 |
} |
} |
181 |
if ((expect & EXPECT_RIGHT_PARENTHESIS) && ch == ')') { |
if ((expect & EXPECT_RIGHT_PARENTHESIS) && ch == ')') { |
182 |
|
parenthesis_level --; |
183 |
buf[curlen++] = ch; |
buf[curlen++] = ch; |
184 |
break; |
break; |
185 |
} |
} |
214 |
static char cur_machine_bootname[150]; |
static char cur_machine_bootname[150]; |
215 |
static char cur_machine_bootarg[250]; |
static char cur_machine_bootarg[250]; |
216 |
static char cur_machine_slowsi[10]; |
static char cur_machine_slowsi[10]; |
|
static char cur_machine_debugger_on_badaddr[10]; |
|
217 |
static char cur_machine_prom_emulation[10]; |
static char cur_machine_prom_emulation[10]; |
218 |
static char cur_machine_use_x11[10]; |
static char cur_machine_use_x11[10]; |
219 |
static char cur_machine_x11_scaledown[10]; |
static char cur_machine_x11_scaledown[10]; |
|
static char cur_machine_bintrans[10]; |
|
|
static char cur_machine_old_bintrans[10]; |
|
|
static char cur_machine_bintrans_size[10]; |
|
220 |
static char cur_machine_byte_order[20]; |
static char cur_machine_byte_order[20]; |
221 |
static char cur_machine_random_mem[10]; |
static char cur_machine_random_mem[10]; |
222 |
static char cur_machine_random_cpu[10]; |
static char cur_machine_random_cpu[10]; |
227 |
static char cur_machine_serial_nr[10]; |
static char cur_machine_serial_nr[10]; |
228 |
static char cur_machine_emulated_hz[10]; |
static char cur_machine_emulated_hz[10]; |
229 |
static char cur_machine_memory[10]; |
static char cur_machine_memory[10]; |
|
static char cur_machine_max_random_cycles[10]; |
|
230 |
#define MAX_N_LOAD 15 |
#define MAX_N_LOAD 15 |
231 |
#define MAX_LOAD_LEN 2000 |
#define MAX_LOAD_LEN 2000 |
232 |
static char *cur_machine_load[MAX_N_LOAD]; |
static char *cur_machine_load[MAX_N_LOAD]; |
256 |
} \ |
} \ |
257 |
} |
} |
258 |
|
|
259 |
|
static void parse__machine(struct emul *e, FILE *f, int *in_emul, int *line, |
260 |
|
int *parsestate, char *word, size_t maxbuflen); |
261 |
|
|
262 |
|
|
263 |
/* |
/* |
264 |
* parse_on_off(): |
* parse_on_off(): |
276 |
strcasecmp(s, "disable") == 0 || strcasecmp(s, "0") == 0) |
strcasecmp(s, "disable") == 0 || strcasecmp(s, "0") == 0) |
277 |
return 0; |
return 0; |
278 |
|
|
279 |
fatal("parse_on_off(): unknown value '%s'\n", s); |
fprintf(stderr, "parse_on_off(): WARNING: unknown value '%s'\n", s); |
|
exit(1); |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
* parse__none(): |
|
|
* |
|
|
* emul ( [...] ) |
|
|
*/ |
|
|
static void parse__none(struct emul *e, FILE *f, int *in_emul, int *line, |
|
|
int *parsestate, char *word, size_t maxbuflen) |
|
|
{ |
|
|
if (strcmp(word, "emul") == 0) { |
|
|
if (*in_emul) { |
|
|
fatal("line %i: only one emul per config " |
|
|
"file is supported!\n", *line); |
|
|
exit(1); |
|
|
} |
|
|
*parsestate = PARSESTATE_EMUL; |
|
|
*in_emul = 1; |
|
|
read_one_word(f, word, maxbuflen, |
|
|
line, EXPECT_LEFT_PARENTHESIS); |
|
|
return; |
|
|
} |
|
280 |
|
|
281 |
fatal("line %i: expecting 'emul', not '%s'\n", *line, word); |
return 0; |
|
exit(1); |
|
282 |
} |
} |
283 |
|
|
284 |
|
|
345 |
cur_machine_n_device = 0; |
cur_machine_n_device = 0; |
346 |
cur_machine_n_x11_disp = 0; |
cur_machine_n_x11_disp = 0; |
347 |
cur_machine_slowsi[0] = '\0'; |
cur_machine_slowsi[0] = '\0'; |
|
cur_machine_debugger_on_badaddr[0] = '\0'; |
|
348 |
cur_machine_prom_emulation[0] = '\0'; |
cur_machine_prom_emulation[0] = '\0'; |
349 |
cur_machine_use_x11[0] = '\0'; |
cur_machine_use_x11[0] = '\0'; |
350 |
cur_machine_x11_scaledown[0] = '\0'; |
cur_machine_x11_scaledown[0] = '\0'; |
|
cur_machine_bintrans[0] = '\0'; |
|
|
cur_machine_old_bintrans[0] = '\0'; |
|
|
cur_machine_bintrans_size[0] = '\0'; |
|
351 |
cur_machine_byte_order[0] = '\0'; |
cur_machine_byte_order[0] = '\0'; |
352 |
cur_machine_random_mem[0] = '\0'; |
cur_machine_random_mem[0] = '\0'; |
353 |
cur_machine_random_cpu[0] = '\0'; |
cur_machine_random_cpu[0] = '\0'; |
358 |
cur_machine_serial_nr[0] = '\0'; |
cur_machine_serial_nr[0] = '\0'; |
359 |
cur_machine_emulated_hz[0] = '\0'; |
cur_machine_emulated_hz[0] = '\0'; |
360 |
cur_machine_memory[0] = '\0'; |
cur_machine_memory[0] = '\0'; |
|
cur_machine_max_random_cycles[0] = '\0'; |
|
361 |
return; |
return; |
362 |
} |
} |
363 |
|
|
480 |
m->slow_serial_interrupts_hack_for_linux = |
m->slow_serial_interrupts_hack_for_linux = |
481 |
parse_on_off(cur_machine_slowsi); |
parse_on_off(cur_machine_slowsi); |
482 |
|
|
|
if (!cur_machine_debugger_on_badaddr[0]) |
|
|
strlcpy(cur_machine_debugger_on_badaddr, "no", |
|
|
sizeof(cur_machine_debugger_on_badaddr)); |
|
|
m->single_step_on_bad_addr = |
|
|
parse_on_off(cur_machine_debugger_on_badaddr); |
|
|
|
|
483 |
if (!cur_machine_prom_emulation[0]) |
if (!cur_machine_prom_emulation[0]) |
484 |
strlcpy(cur_machine_prom_emulation, "yes", |
strlcpy(cur_machine_prom_emulation, "yes", |
485 |
sizeof(cur_machine_prom_emulation)); |
sizeof(cur_machine_prom_emulation)); |
511 |
} |
} |
512 |
} |
} |
513 |
|
|
|
if (!cur_machine_bintrans[0]) |
|
|
strlcpy(cur_machine_bintrans, "yes", |
|
|
sizeof(cur_machine_bintrans)); |
|
|
m->bintrans_enable = m->bintrans_enabled_from_start = |
|
|
parse_on_off(cur_machine_bintrans); |
|
|
|
|
|
if (!cur_machine_old_bintrans[0]) |
|
|
strlcpy(cur_machine_old_bintrans, "yes", |
|
|
sizeof(cur_machine_old_bintrans)); |
|
|
m->old_bintrans_enable = parse_on_off(cur_machine_old_bintrans); |
|
|
|
|
|
if (!m->bintrans_enable && m->old_bintrans_enable) |
|
|
m->old_bintrans_enable = 0; |
|
|
|
|
|
/* TODO: Hm... */ |
|
|
if (m->bintrans_enable && m->arch == ARCH_MIPS) |
|
|
m->speed_tricks = 0; |
|
|
|
|
|
if (cur_machine_bintrans_size[0]) |
|
|
m->bintrans_size = 1048576 * |
|
|
atoi(cur_machine_bintrans_size); |
|
|
|
|
514 |
if (!cur_machine_force_netboot[0]) |
if (!cur_machine_force_netboot[0]) |
515 |
strlcpy(cur_machine_force_netboot, "no", |
strlcpy(cur_machine_force_netboot, "no", |
516 |
sizeof(cur_machine_force_netboot)); |
sizeof(cur_machine_force_netboot)); |
547 |
sizeof(cur_machine_memory)); |
sizeof(cur_machine_memory)); |
548 |
m->physical_ram_in_mb = atoi(cur_machine_memory); |
m->physical_ram_in_mb = atoi(cur_machine_memory); |
549 |
|
|
|
if (cur_machine_max_random_cycles[0]) { |
|
|
if (m->bintrans_enable) { |
|
|
fprintf(stderr, "max_random_cycles doesn't" |
|
|
" work with bintrans\n"); |
|
|
exit(1); |
|
|
} |
|
|
m->max_random_cycles_per_chunk = atoi( |
|
|
cur_machine_max_random_cycles); |
|
|
} |
|
|
|
|
550 |
if (!cur_machine_x11_scaledown[0]) |
if (!cur_machine_x11_scaledown[0]) |
551 |
m->x11_scaledown = 1; |
m->x11_scaledown = 1; |
552 |
else { |
else { |
618 |
WORD("bootname", cur_machine_bootname); |
WORD("bootname", cur_machine_bootname); |
619 |
WORD("bootarg", cur_machine_bootarg); |
WORD("bootarg", cur_machine_bootarg); |
620 |
WORD("slow_serial_interrupts_hack_for_linux", cur_machine_slowsi); |
WORD("slow_serial_interrupts_hack_for_linux", cur_machine_slowsi); |
|
WORD("debugger_on_badaddr", cur_machine_debugger_on_badaddr); |
|
621 |
WORD("prom_emulation", cur_machine_prom_emulation); |
WORD("prom_emulation", cur_machine_prom_emulation); |
622 |
WORD("use_x11", cur_machine_use_x11); |
WORD("use_x11", cur_machine_use_x11); |
623 |
WORD("x11_scaledown", cur_machine_x11_scaledown); |
WORD("x11_scaledown", cur_machine_x11_scaledown); |
|
WORD("bintrans", cur_machine_bintrans); |
|
|
WORD("old_bintrans", cur_machine_old_bintrans); |
|
|
WORD("bintrans_size", cur_machine_bintrans_size); |
|
624 |
WORD("byte_order", cur_machine_byte_order); |
WORD("byte_order", cur_machine_byte_order); |
625 |
WORD("random_mem_contents", cur_machine_random_mem); |
WORD("random_mem_contents", cur_machine_random_mem); |
626 |
WORD("use_random_bootstrap_cpu", cur_machine_random_cpu); |
WORD("use_random_bootstrap_cpu", cur_machine_random_cpu); |
630 |
WORD("n_gfx_cards", cur_machine_n_gfx_cards); |
WORD("n_gfx_cards", cur_machine_n_gfx_cards); |
631 |
WORD("emulated_hz", cur_machine_emulated_hz); |
WORD("emulated_hz", cur_machine_emulated_hz); |
632 |
WORD("memory", cur_machine_memory); |
WORD("memory", cur_machine_memory); |
|
WORD("max_random_cycles", cur_machine_max_random_cycles); |
|
633 |
WORD("start_paused", cur_machine_start_paused); |
WORD("start_paused", cur_machine_start_paused); |
634 |
|
|
635 |
if (strcmp(word, "load") == 0) { |
if (strcmp(word, "load") == 0) { |
725 |
* |
* |
726 |
* Set up an emulation by parsing a config file. |
* Set up an emulation by parsing a config file. |
727 |
*/ |
*/ |
728 |
void emul_parse_config(struct emul *e, FILE *f) |
void emul_parse_config(struct emul *e, char *fname) |
729 |
{ |
{ |
730 |
char word[500]; |
FILE *f = fopen(fname, "r"); |
731 |
|
char word[MAX_WORD_LEN]; |
732 |
int in_emul = 0; |
int in_emul = 0; |
733 |
int line = 1; |
int line = 1; |
734 |
int parsestate = PARSESTATE_NONE; |
int parsestate = PARSESTATE_EMUL; |
735 |
|
|
736 |
/* debug("emul_parse_config()\n"); */ |
/* debug("emul_parse_config()\n"); */ |
737 |
|
if (f == NULL) { |
738 |
|
perror(fname); |
739 |
|
exit(1); |
740 |
|
} |
741 |
|
|
742 |
while (!feof(f)) { |
while (!feof(f)) { |
743 |
read_one_word(f, word, sizeof(word), &line, |
read_one_word(f, word, sizeof(word), &line, |
748 |
/* debug("word = '%s'\n", word); */ |
/* debug("word = '%s'\n", word); */ |
749 |
|
|
750 |
switch (parsestate) { |
switch (parsestate) { |
|
case PARSESTATE_NONE: |
|
|
parse__none(e, f, &in_emul, &line, &parsestate, |
|
|
word, sizeof(word)); |
|
|
break; |
|
751 |
case PARSESTATE_EMUL: |
case PARSESTATE_EMUL: |
752 |
parse__emul(e, f, &in_emul, &line, &parsestate, |
parse__emul(e, f, &in_emul, &line, &parsestate, |
753 |
word, sizeof(word)); |
word, sizeof(word)); |
760 |
parse__machine(e, f, &in_emul, &line, &parsestate, |
parse__machine(e, f, &in_emul, &line, &parsestate, |
761 |
word, sizeof(word)); |
word, sizeof(word)); |
762 |
break; |
break; |
763 |
|
case PARSESTATE_NONE: |
764 |
|
break; |
765 |
default: |
default: |
766 |
fatal("INTERNAL ERROR in emul_parse.c (" |
fatal("INTERNAL ERROR in emul_parse.c (" |
767 |
"parsestate %i is not imlemented yet?)\n", |
"parsestate %i is not imlemented yet?)\n", |
770 |
} |
} |
771 |
} |
} |
772 |
|
|
773 |
if (parsestate != PARSESTATE_NONE) { |
if (parenthesis_level != 0) { |
774 |
fatal("EOF but not enough right parentheses?\n"); |
fatal("EOF but not enough right parentheses?\n"); |
775 |
exit(1); |
exit(1); |
776 |
} |
} |
777 |
|
|
778 |
|
fclose(f); |
779 |
} |
} |
780 |
|
|