psim_command(device *root, char **argv) { int argp = 0; if (argv[argp] == NULL) { return; } else if (strcmp(argv[argp], "trace") == 0) { const char *opt = find_arg("Missing <trace> option", &argp, argv); if (opt[0] == '!') trace_option(opt + 1, 0); else trace_option(opt, 1); } else if (strcmp(*argv, "change-media") == 0) { char *device = find_arg("Missing device name", &argp, argv); char *media = argv[++argp]; device_ioctl(tree_find_device(root, device), NULL, 0, device_ioctl_change_media, media); } else { printf_filtered("Unknown PSIM command %s, try\n", argv[argp]); printf_filtered(" trace <trace-option>\n"); printf_filtered(" change-media <device> [ <new-image> ]\n"); } }
INLINE_EMUL_GENERIC void emul_add_tree_hardware(device *root) { int i; int nr_cpus = tree_find_integer_property(root, "/openprom/options/smp"); /* sanity check the number of processors */ if (nr_cpus > MAX_NR_PROCESSORS) error("Specified number of processors (%d) exceeds the number configured (%d).\n", nr_cpus, MAX_NR_PROCESSORS); /* set the number of address cells (1 or 2) */ tree_parse(root, "#address-cells %d", WITH_TARGET_WORD_BITSIZE / 32); /* add some memory */ if (tree_find_device(root, "/memory") == NULL) { unsigned_word memory_size = tree_find_integer_property(root, "/openprom/options/oea-memory-size"); const unsigned_word avail_start = 0x3000; tree_parse(root, "/memory@0/reg 0x0 0x%lx", (unsigned long)memory_size); /* reserve the first 0x3000 for the PowerPC interrupt table */ tree_parse(root, "/memory@0/available 0x%lx 0x%lx", (unsigned long)avail_start, (unsigned long)memory_size - avail_start); } /* our processors */ for (i = 0; i < nr_cpus; i++) { tree_parse(root, "/cpus/cpu@%d/cpu-nr %d", i, i); } /* the debugging pal - hide it in the openprom and don't attach it to any bus */ tree_parse(root, "/openprom/pal"); /* chosen etc */ tree_parse(root, "/chosen/stdin */openprom/pal"); tree_parse(root, "/chosen/stdout !/chosen/stdin"); tree_parse(root, "/chosen/memory */memory"); }
psim_stack(psim *system, char **argv, char **envp) { /* pass the stack device the argv/envp and let it work out what to do with it */ device *stack_device = tree_find_device(system->devices, "/openprom/init/stack"); if (stack_device != (device*)0) { unsigned_word stack_pointer; ASSERT (psim_read_register(system, 0, &stack_pointer, "sp", cooked_transfer) > 0); device_ioctl(stack_device, NULL, /*cpu*/ 0, /*cia*/ device_ioctl_create_stack, stack_pointer, argv, envp); } }
split_device_specifier(device *current, const char *device_specifier, name_specifier *spec) { char *chp = NULL; /* expand any leading alias if present */ if (current != NULL && *device_specifier != '\0' && *device_specifier != '.' && *device_specifier != '/') { device *aliases = tree_find_device(current, "/aliases"); char alias[32]; int len = 0; while (device_specifier[len] != '\0' && device_specifier[len] != '/' && device_specifier[len] != ':' && !isspace(device_specifier[len])) { alias[len] = device_specifier[len]; len++; if (len >= sizeof(alias)) error("split_device_specifier: buffer overflow"); } alias[len] = '\0'; if (aliases != NULL && device_find_property(aliases, alias)) { strcpy(spec->buf, device_find_string_property(aliases, alias)); strcat(spec->buf, device_specifier + len); } else { strcpy(spec->buf, device_specifier); } } else { strcpy(spec->buf, device_specifier); } /* check no overflow */ if (strlen(spec->buf) >= sizeof(spec->buf)) error("split_device_specifier: buffer overflow\n"); /* strip leading spaces */ chp = spec->buf; while (*chp != '\0' && isspace(*chp)) chp++; if (*chp == '\0') return 0; /* find the path and terminate it with null */ spec->path = chp; while (*chp != '\0' && !isspace(*chp)) chp++; if (*chp != '\0') { *chp = '\0'; chp++; } /* and any value */ while (*chp != '\0' && isspace(*chp)) chp++; spec->value = chp; /* now go back and chop the property off of the path */ if (spec->value[0] == '\0') { spec->property = NULL; /*not a property*/ spec->value = NULL; } else if (spec->value[0] == '>' || spec->value[0] == '<') { /* an interrupt spec */ spec->property = NULL; } else { chp = strrchr(spec->path, '/'); if (chp == NULL) { spec->property = spec->path; spec->path = strchr(spec->property, '\0'); } else { *chp = '\0'; spec->property = chp+1; } } /* and mark the rest as invalid */ spec->name = NULL; spec->base = NULL; spec->unit = NULL; spec->args = NULL; spec->last_name = NULL; spec->last_base = NULL; spec->last_unit = NULL; spec->last_args = NULL; return 1; }
psim_device(psim *system, const char *path) { return tree_find_device(system->devices, path); }
psim_options(device *root, char **argv) { device *current = root; int argp; if (argv == NULL) return NULL; argp = 0; while (argv[argp] != NULL && argv[argp][0] == '-') { char *p = argv[argp] + 1; char *param; while (*p != '\0') { switch (*p) { default: psim_usage(0); error (""); break; case 'c': param = find_arg("Missing <count> option for -c (max-iterations)\n", &argp, argv); tree_parse(root, "/openprom/options/max-iterations %s", param); break; case 'e': param = find_arg("Missing <emul> option for -e (os-emul)\n", &argp, argv); tree_parse(root, "/openprom/options/os-emul %s", param); break; case 'E': /* endian spec, ignored for now */ param = find_arg("Missing <endian> option for -E (target-endian)\n", &argp, argv); if (strcmp (param, "big") == 0) tree_parse (root, "/options/little-endian? false"); else if (strcmp (param, "little") == 0) tree_parse (root, "/options/little-endian? true"); else { printf_filtered ("Invalid <endian> option for -E (target-endian)\n"); psim_usage (0); } break; case 'f': param = find_arg("Missing <file> option for -f\n", &argp, argv); psim_merge_device_file(root, param); break; case 'h': case '?': psim_usage(1); break; case 'H': psim_usage(2); break; case 'i': if (isdigit(p[1])) { tree_parse(root, "/openprom/trace/print-info %c", p[1]); p++; } else { tree_parse(root, "/openprom/trace/print-info 1"); } break; case 'I': tree_parse(root, "/openprom/trace/print-info 2"); tree_parse(root, "/openprom/options/model-issue %d", MODEL_ISSUE_PROCESS); break; case 'm': param = find_arg("Missing <model> option for -m (model)\n", &argp, argv); tree_parse(root, "/openprom/options/model \"%s", param); break; case 'n': param = find_arg("Missing <nr-smp> option for -n (smp)\n", &argp, argv); tree_parse(root, "/openprom/options/smp %s", param); break; case 'o': param = find_arg("Missing <dev-spec> option for -o\n", &argp, argv); if (memcmp(param, "mpc860c0", 8) == 0) { if (param[8] == '\0') tree_parse(root, "/options/mpc860c0 5"); else if (param[8] == '=' && is_num(param+9, 1, 10, 0)) { tree_parse(root, "/options/mpc860c0 %s", param+9); } else error("Invalid mpc860c0 option for -o\n"); } else current = tree_parse(current, "%s", param); break; case 'r': param = find_arg("Missing <ram-size> option for -r (oea-memory-size)\n", &argp, argv); tree_parse(root, "/openprom/options/oea-memory-size %s", param); break; case 't': param = find_arg("Missing <trace> option for -t (trace/*)\n", &argp, argv); if (param[0] == '!') tree_parse(root, "/openprom/trace/%s 0", param+1); else tree_parse(root, "/openprom/trace/%s 1", param); break; case '-': /* it's a long option of the form --optionname=optionvalue. Such options can be passed through if we are invoked by gdb. */ if (strstr(argv[argp], "architecture") != NULL) { /* we must consume the argument here, so that we get out of the loop. */ p = argv[argp] + strlen(argv[argp]) - 1; printf_filtered("Warning - architecture parameter ignored\n"); } else error("Unrecognized option"); break; } p += 1; } argp += 1; } /* force the trace node to process its options now *before* the tree initialization occures */ device_ioctl(tree_find_device(root, "/openprom/trace"), NULL, 0, device_ioctl_set_trace); { void semantic_init(device* root); semantic_init(root); } /* return where the options end */ return argv + argp; }