1 /* This file is part of the program psim.
3 Copyright 1994, 1995, 1996, 1997, 2003 Andrew Cagney
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #include "cpu.h" /* includes psim.h */
52 #include "libiberty.h"
55 /* system structure, actual size of processor array determined at
62 os_emul *os_emulation;
65 /* escape routine for inner functions */
67 void *path_to_restart;
69 /* status from last halt */
70 psim_status halt_status;
72 /* the processors proper */
74 int last_cpu; /* CPU that last (tried to) execute an instruction */
75 cpu *processors[MAX_NR_PROCESSORS];
79 int current_target_byte_order;
80 int current_host_byte_order;
81 int current_environment;
82 int current_alignment;
83 int current_floating_point;
84 int current_model_issue = MODEL_ISSUE_IGNORE;
85 int current_stdio = DO_USE_STDIO;
86 model_enum current_model = WITH_DEFAULT_MODEL;
89 /* create the device tree */
95 device *root = tree_parse(NULL, "core");
96 tree_parse(root, "/aliases");
97 tree_parse(root, "/options");
98 tree_parse(root, "/chosen");
99 tree_parse(root, "/packages");
100 tree_parse(root, "/cpus");
101 tree_parse(root, "/openprom");
102 tree_parse(root, "/openprom/init");
103 tree_parse(root, "/openprom/trace");
104 tree_parse(root, "/openprom/options");
110 find_arg(char *err_msg,
115 if (argv[*ptr_to_argp] == NULL)
117 return argv[*ptr_to_argp];
122 psim_usage(int verbose)
124 printf_filtered("Usage:\n");
125 printf_filtered("\n");
126 printf_filtered("\tpsim [ <psim-option> ... ] <image> [ <image-arg> ... ]\n");
127 printf_filtered("\n");
128 printf_filtered("Where\n");
129 printf_filtered("\n");
130 printf_filtered("\t<image> Name of the PowerPC program to run.\n");
132 printf_filtered("\t This can either be a PowerPC binary or\n");
133 printf_filtered("\t a text file containing a device tree\n");
134 printf_filtered("\t specification.\n");
135 printf_filtered("\t PSIM will attempt to determine from the\n");
136 printf_filtered("\t specified <image> the intended emulation\n");
137 printf_filtered("\t environment.\n");
138 printf_filtered("\t If PSIM gets it wrong, the emulation\n");
139 printf_filtered("\t environment can be specified using the\n");
140 printf_filtered("\t `-e' option (described below).\n");
141 printf_filtered("\n"); }
142 printf_filtered("\t<image-arg> Argument to be passed to <image>\n");
144 printf_filtered("\t These arguments will be passed to\n");
145 printf_filtered("\t <image> (as standard C argv, argc)\n");
146 printf_filtered("\t when <image> is started.\n");
147 printf_filtered("\n"); }
148 printf_filtered("\t<psim-option> See below\n");
149 printf_filtered("\n");
150 printf_filtered("The following are valid <psim-option>s:\n");
151 printf_filtered("\n");
153 printf_filtered("\t-c <count> Limit the simulation to <count> iterations\n");
155 printf_filtered("\n");
158 printf_filtered("\t-i or -i2 Print instruction counting statistics\n");
160 printf_filtered("\t Specify -i2 for a more detailed display\n");
161 printf_filtered("\n");
164 printf_filtered("\t-I Print execution unit statistics\n");
165 if (verbose) { printf_filtered("\n"); }
167 printf_filtered("\t-e <os-emul> specify an OS or platform to model\n");
169 printf_filtered("\t Can be any of the following:\n");
170 printf_filtered("\t bug - OEA + MOTO BUG ROM calls\n");
171 printf_filtered("\t netbsd - UEA + NetBSD system calls\n");
172 printf_filtered("\t solaris - UEA + Solaris system calls\n");
173 printf_filtered("\t linux - UEA + Linux system calls\n");
174 printf_filtered("\t chirp - OEA + a few OpenBoot calls\n");
175 printf_filtered("\n"); }
177 printf_filtered("\t-E <endian> Specify the endianness of the target\n");
179 printf_filtered("\t Can be any of the following:\n");
180 printf_filtered("\t big - big endian target\n");
181 printf_filtered("\t little - little endian target\n");
182 printf_filtered("\n"); }
184 printf_filtered("\t-f <file> Merge <file> into the device tree\n");
185 if (verbose) { printf_filtered("\n"); }
187 printf_filtered("\t-h -? -H give more detailed usage\n");
188 if (verbose) { printf_filtered("\n"); }
190 printf_filtered("\t-m <model> Specify the processor to model (604)\n");
192 printf_filtered("\t Selects the processor to use when\n");
193 printf_filtered("\t modeling execution units. Includes:\n");
194 printf_filtered("\t 604, 603 and 603e\n");
195 printf_filtered("\n"); }
197 printf_filtered("\t-n <nr-smp> Specify the number of processors in SMP simulations\n");
199 printf_filtered("\t Specifies the number of processors that are\n");
200 printf_filtered("\t to be modeled in a symetric multi-processor (SMP)\n");
201 printf_filtered("\t simulation\n");
202 printf_filtered("\n"); }
204 printf_filtered("\t-o <dev-spec> Add device <dev-spec> to the device tree\n");
205 if (verbose) { printf_filtered("\n"); }
207 printf_filtered("\t-r <ram-size> Set RAM size in bytes (OEA environments)\n");
208 if (verbose) { printf_filtered("\n"); }
210 printf_filtered("\t-t [!]<trace> Enable (disable) <trace> option\n");
211 if (verbose) { printf_filtered("\n"); }
213 printf_filtered("\n");
214 trace_usage(verbose);
215 device_usage(verbose);
217 printf_filtered("\n");
223 /* Test "string" for containing a string of digits that form a number
224 between "min" and "max". The return value is the number or "err". */
226 int is_num( char *string, int min, int max, int err)
230 for ( ; *string; ++string)
232 if (!isdigit(*string))
237 result = result * 10 + (*string - '0');
239 if (result < min || result > max)
247 psim_options(device *root,
250 device *current = root;
255 while (argv[argp] != NULL && argv[argp][0] == '-') {
256 char *p = argv[argp] + 1;
265 param = find_arg("Missing <count> option for -c (max-iterations)\n", &argp, argv);
266 tree_parse(root, "/openprom/options/max-iterations %s", param);
269 param = find_arg("Missing <emul> option for -e (os-emul)\n", &argp, argv);
270 tree_parse(root, "/openprom/options/os-emul %s", param);
273 /* endian spec, ignored for now */
274 param = find_arg("Missing <endian> option for -E (target-endian)\n", &argp, argv);
275 if (strcmp (param, "big") == 0)
276 tree_parse (root, "/options/little-endian? false");
277 else if (strcmp (param, "little") == 0)
278 tree_parse (root, "/options/little-endian? true");
281 printf_filtered ("Invalid <endian> option for -E (target-endian)\n");
286 param = find_arg("Missing <file> option for -f\n", &argp, argv);
287 psim_merge_device_file(root, param);
298 tree_parse(root, "/openprom/trace/print-info %c", p[1]);
302 tree_parse(root, "/openprom/trace/print-info 1");
306 tree_parse(root, "/openprom/trace/print-info 2");
307 tree_parse(root, "/openprom/options/model-issue %d",
308 MODEL_ISSUE_PROCESS);
311 param = find_arg("Missing <model> option for -m (model)\n", &argp, argv);
312 tree_parse(root, "/openprom/options/model \"%s", param);
315 param = find_arg("Missing <nr-smp> option for -n (smp)\n", &argp, argv);
316 tree_parse(root, "/openprom/options/smp %s", param);
319 param = find_arg("Missing <dev-spec> option for -o\n", &argp, argv);
320 if (memcmp(param, "mpc860c0", 8) == 0)
322 if (param[8] == '\0')
323 tree_parse(root, "/options/mpc860c0 5");
324 else if (param[8] == '=' && is_num(param+9, 1, 10, 0))
326 tree_parse(root, "/options/mpc860c0 %s", param+9);
328 else error("Invalid mpc860c0 option for -o\n");
331 current = tree_parse(current, "%s", param);
334 param = find_arg("Missing <ram-size> option for -r (oea-memory-size)\n", &argp, argv);
335 tree_parse(root, "/openprom/options/oea-memory-size %s",
339 param = find_arg("Missing <trace> option for -t (trace/*)\n", &argp, argv);
341 tree_parse(root, "/openprom/trace/%s 0", param+1);
343 tree_parse(root, "/openprom/trace/%s 1", param);
346 /* it's a long option of the form --optionname=optionvalue.
347 Such options can be passed through if we are invoked by
349 if (strstr(argv[argp], "architecture") != NULL) {
350 /* we must consume the argument here, so that we get out
352 p = argv[argp] + strlen(argv[argp]) - 1;
353 printf_filtered("Warning - architecture parameter ignored\n");
356 error("Unrecognized option");
363 /* force the trace node to process its options now *before* the tree
364 initialization occures */
365 device_ioctl(tree_find_device(root, "/openprom/trace"),
367 device_ioctl_set_trace);
370 void semantic_init(device* root);
374 /* return where the options end */
380 psim_command(device *root,
384 if (argv[argp] == NULL) {
387 else if (strcmp(argv[argp], "trace") == 0) {
388 const char *opt = find_arg("Missing <trace> option", &argp, argv);
390 trace_option(opt + 1, 0);
392 trace_option(opt, 1);
394 else if (strcmp(*argv, "change-media") == 0) {
395 char *device = find_arg("Missing device name", &argp, argv);
396 char *media = argv[++argp];
397 device_ioctl(tree_find_device(root, device), NULL, 0,
398 device_ioctl_change_media, media);
401 printf_filtered("Unknown PSIM command %s, try\n", argv[argp]);
402 printf_filtered(" trace <trace-option>\n");
403 printf_filtered(" change-media <device> [ <new-image> ]\n");
408 /* create the simulator proper from the device tree and executable */
412 psim_create(const char *file_name,
418 os_emul *os_emulation;
421 /* given this partially populated device tree, os_emul_create() uses
422 it and file_name to determine the selected emulation and hence
423 further populate the tree with any other required nodes. */
425 os_emulation = os_emul_create(file_name, root);
426 if (os_emulation == NULL)
427 error("psim: either file %s was not reconized or unreconized or unknown os-emulation type\n", file_name);
429 /* fill in the missing real number of CPU's */
430 nr_cpus = tree_find_integer_property(root, "/openprom/options/smp");
431 if (MAX_NR_PROCESSORS < nr_cpus)
432 error("target and configured number of cpus conflict\n");
434 /* fill in the missing TARGET BYTE ORDER information */
435 current_target_byte_order
436 = (tree_find_boolean_property(root, "/options/little-endian?")
439 if (CURRENT_TARGET_BYTE_ORDER != current_target_byte_order)
440 error("target and configured byte order conflict\n");
442 /* fill in the missing HOST BYTE ORDER information */
443 current_host_byte_order = (current_host_byte_order = 1,
444 (*(char*)(¤t_host_byte_order)
447 if (CURRENT_HOST_BYTE_ORDER != current_host_byte_order)
448 error("host and configured byte order conflict\n");
450 /* fill in the missing OEA/VEA information */
451 env = tree_find_string_property(root, "/openprom/options/env");
452 current_environment = ((strcmp(env, "user") == 0
453 || strcmp(env, "uea") == 0)
455 : (strcmp(env, "virtual") == 0
456 || strcmp(env, "vea") == 0)
457 ? VIRTUAL_ENVIRONMENT
458 : (strcmp(env, "operating") == 0
459 || strcmp(env, "oea") == 0)
460 ? OPERATING_ENVIRONMENT
462 if (current_environment == 0)
463 error("unreconized /options env property\n");
464 if (CURRENT_ENVIRONMENT != current_environment)
465 error("target and configured environment conflict\n");
467 /* fill in the missing ALLIGNMENT information */
469 = (tree_find_boolean_property(root, "/openprom/options/strict-alignment?")
471 : NONSTRICT_ALIGNMENT);
472 if (CURRENT_ALIGNMENT != current_alignment)
473 error("target and configured alignment conflict\n");
475 /* fill in the missing FLOATING POINT information */
476 current_floating_point
477 = (tree_find_boolean_property(root, "/openprom/options/floating-point?")
478 ? HARD_FLOATING_POINT
479 : SOFT_FLOATING_POINT);
480 if (CURRENT_FLOATING_POINT != current_floating_point)
481 error("target and configured floating-point conflict\n");
483 /* fill in the missing STDIO information */
485 = (tree_find_boolean_property(root, "/openprom/options/use-stdio?")
488 if (CURRENT_STDIO != current_stdio)
489 error("target and configured stdio interface conflict\n");
491 /* sort out the level of detail for issue modeling */
493 = tree_find_integer_property(root, "/openprom/options/model-issue");
494 if (CURRENT_MODEL_ISSUE != current_model_issue)
495 error("target and configured model-issue conflict\n");
497 /* sort out our model architecture - wrong.
499 FIXME: this should be obtaining the required information from the
500 device tree via the "/chosen" property "cpu" which is an instance
501 (ihandle) for the only executing processor. By converting that
502 ihandle into the corresponding cpu's phandle and then querying
503 the "name" property, the cpu type can be determined. Ok? */
505 model_set(tree_find_string_property(root, "/openprom/options/model"));
508 system = ZALLOC(psim);
509 system->events = event_queue_create();
510 system->memory = core_from_device(root);
511 system->monitor = mon_create();
512 system->nr_cpus = nr_cpus;
513 system->os_emulation = os_emulation;
514 system->devices = root;
516 /* now all the processors attaching to each their per-cpu information */
517 for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++) {
518 system->processors[cpu_nr] = cpu_create(system,
520 mon_cpu(system->monitor,
522 system->os_emulation,
526 /* dump out the contents of the device tree */
527 if (ppc_trace[trace_print_device_tree] || ppc_trace[trace_dump_device_tree])
529 if (ppc_trace[trace_dump_device_tree])
536 /* allow the simulation to stop/restart abnormaly */
540 psim_set_halt_and_restart(psim *system,
542 void *restart_jmp_buf)
544 system->path_to_halt = halt_jmp_buf;
545 system->path_to_restart = restart_jmp_buf;
550 psim_clear_halt_and_restart(psim *system)
552 system->path_to_halt = NULL;
553 system->path_to_restart = NULL;
558 psim_restart(psim *system,
561 ASSERT(current_cpu >= 0 && current_cpu < system->nr_cpus);
562 ASSERT(system->path_to_restart != NULL);
563 system->last_cpu = current_cpu;
564 longjmp(*(jmp_buf*)(system->path_to_restart), current_cpu + 1);
569 cntrl_c_simulation(void *data)
573 psim_nr_cpus(system),
580 psim_stop(psim *system)
582 event_queue_schedule_after_signal(psim_event_queue(system),
590 psim_halt(psim *system,
595 ASSERT(current_cpu >= 0 && current_cpu <= system->nr_cpus);
596 ASSERT(system->path_to_halt != NULL);
597 system->last_cpu = current_cpu;
598 system->halt_status.reason = reason;
599 system->halt_status.signal = signal;
600 if (current_cpu == system->nr_cpus) {
601 system->halt_status.cpu_nr = 0;
602 system->halt_status.program_counter =
603 cpu_get_program_counter(system->processors[0]);
606 system->halt_status.cpu_nr = current_cpu;
607 system->halt_status.program_counter =
608 cpu_get_program_counter(system->processors[current_cpu]);
610 longjmp(*(jmp_buf*)(system->path_to_halt), current_cpu + 1);
616 psim_last_cpu(psim *system)
618 return system->last_cpu;
623 psim_nr_cpus(psim *system)
625 return system->nr_cpus;
630 psim_get_status(psim *system)
632 return system->halt_status;
638 psim_cpu(psim *system,
641 if (cpu_nr < 0 || cpu_nr >= system->nr_cpus)
644 return system->processors[cpu_nr];
650 psim_device(psim *system,
653 return tree_find_device(system->devices, path);
658 psim_event_queue(psim *system)
660 return system->events;
667 psim_max_iterations_exceeded(void *data)
671 system->nr_cpus, /* halted during an event */
679 psim_init(psim *system)
683 /* scrub the monitor */
684 mon_init(system->monitor, system->nr_cpus);
686 /* trash any pending events */
687 event_queue_init(system->events);
689 /* if needed, schedule a halt event. FIXME - In the future this
690 will be replaced by a more generic change to psim_command(). A
691 new command `schedule NNN halt' being added. */
692 if (tree_find_property(system->devices, "/openprom/options/max-iterations")) {
693 event_queue_schedule(system->events,
694 tree_find_integer_property(system->devices,
695 "/openprom/options/max-iterations") - 2,
696 psim_max_iterations_exceeded,
700 /* scrub all the cpus */
701 for (cpu_nr = 0; cpu_nr < system->nr_cpus; cpu_nr++)
702 cpu_init(system->processors[cpu_nr]);
704 /* init all the devices (which updates the cpus) */
705 tree_init(system->devices, system);
707 /* and the emulation (which needs an initialized device tree) */
708 os_emul_init(system->os_emulation, system->nr_cpus);
710 /* now sync each cpu against the initialized state of its registers */
711 for (cpu_nr = 0; cpu_nr < system->nr_cpus; cpu_nr++) {
712 cpu *processor = system->processors[cpu_nr];
713 cpu_synchronize_context(processor, cpu_get_program_counter(processor));
714 cpu_page_tlb_invalidate_all(processor);
717 /* force loop to start with first cpu */
718 system->last_cpu = -1;
723 psim_stack(psim *system,
727 /* pass the stack device the argv/envp and let it work out what to
729 device *stack_device = tree_find_device(system->devices,
730 "/openprom/init/stack");
731 if (stack_device != (device*)0) {
732 unsigned_word stack_pointer;
733 ASSERT (psim_read_register(system, 0, &stack_pointer, "sp",
734 cooked_transfer) > 0);
735 device_ioctl(stack_device,
738 device_ioctl_create_stack,
747 /* SIMULATE INSTRUCTIONS, various different ways of achieving the same
752 psim_step(psim *system)
754 volatile int keep_running = 0;
755 idecode_run_until_stop(system, &keep_running,
756 system->events, system->processors, system->nr_cpus);
761 psim_run(psim *system)
764 system->events, system->processors, system->nr_cpus);
768 /* storage manipulation functions */
772 psim_read_register(psim *system,
778 register_descriptions description;
782 /* find our processor */
783 if (which_cpu == MAX_NR_PROCESSORS) {
784 if (system->last_cpu == system->nr_cpus
785 || system->last_cpu == -1)
788 which_cpu = system->last_cpu;
790 ASSERT(which_cpu >= 0 && which_cpu < system->nr_cpus);
792 processor = system->processors[which_cpu];
794 /* find the register description */
795 description = register_description(reg);
796 if (description.type == reg_invalid)
798 cooked_buf = alloca (description.size);
800 /* get the cooked value */
801 switch (description.type) {
804 *(gpreg*)cooked_buf = cpu_registers(processor)->gpr[description.index];
808 *(spreg*)cooked_buf = cpu_registers(processor)->spr[description.index];
812 *(sreg*)cooked_buf = cpu_registers(processor)->sr[description.index];
816 *(fpreg*)cooked_buf = cpu_registers(processor)->fpr[description.index];
820 *(unsigned_word*)cooked_buf = cpu_get_program_counter(processor);
824 *(creg*)cooked_buf = cpu_registers(processor)->cr;
828 *(msreg*)cooked_buf = cpu_registers(processor)->msr;
832 *(fpscreg*)cooked_buf = cpu_registers(processor)->fpscr;
836 *(unsigned_word*)cooked_buf = mon_get_number_of_insns(system->monitor,
841 if (cpu_model(processor) == NULL)
842 error("$stalls only valid if processor unit model enabled (-I)\n");
843 *(unsigned_word*)cooked_buf = model_get_number_of_stalls(cpu_model(processor));
847 if (cpu_model(processor) == NULL)
848 error("$cycles only valid if processor unit model enabled (-I)\n");
849 *(unsigned_word*)cooked_buf = model_get_number_of_cycles(cpu_model(processor));
854 *(vreg*)cooked_buf = cpu_registers(processor)->altivec.vr[description.index];
858 *(vscreg*)cooked_buf = cpu_registers(processor)->altivec.vscr;
864 *(gpreg*)cooked_buf = cpu_registers(processor)->e500.gprh[description.index];
868 *(unsigned64*)cooked_buf = EVR(description.index);
872 *(accreg*)cooked_buf = cpu_registers(processor)->e500.acc;
877 printf_filtered("psim_read_register(processor=0x%lx,buf=0x%lx,reg=%s) %s\n",
878 (unsigned long)processor, (unsigned long)buf, reg,
879 "read of this register unimplemented");
884 /* the PSIM internal values are in host order. To fetch raw data,
885 they need to be converted into target order and then returned */
886 if (mode == raw_transfer) {
887 /* FIXME - assumes that all registers are simple integers */
888 switch (description.size) {
890 *(unsigned_1*)buf = H2T_1(*(unsigned_1*)cooked_buf);
893 *(unsigned_2*)buf = H2T_2(*(unsigned_2*)cooked_buf);
896 *(unsigned_4*)buf = H2T_4(*(unsigned_4*)cooked_buf);
899 *(unsigned_8*)buf = H2T_8(*(unsigned_8*)cooked_buf);
903 if (CURRENT_HOST_BYTE_ORDER != CURRENT_TARGET_BYTE_ORDER)
905 union { vreg v; unsigned_8 d[2]; } h, t;
906 memcpy(&h.v/*dest*/, cooked_buf/*src*/, description.size);
907 { _SWAP_8(t.d[0] =, h.d[1]); }
908 { _SWAP_8(t.d[1] =, h.d[0]); }
909 memcpy(buf/*dest*/, &t/*src*/, description.size);
913 memcpy(buf/*dest*/, cooked_buf/*src*/, description.size);
919 memcpy(buf/*dest*/, cooked_buf/*src*/, description.size);
922 return description.size;
929 psim_write_register(psim *system,
936 register_descriptions description;
939 /* find our processor */
940 if (which_cpu == MAX_NR_PROCESSORS) {
941 if (system->last_cpu == system->nr_cpus
942 || system->last_cpu == -1)
945 which_cpu = system->last_cpu;
948 /* find the description of the register */
949 description = register_description(reg);
950 if (description.type == reg_invalid)
952 cooked_buf = alloca (description.size);
954 if (which_cpu == -1) {
956 for (i = 0; i < system->nr_cpus; i++)
957 psim_write_register(system, i, buf, reg, mode);
958 return description.size;
960 ASSERT(which_cpu >= 0 && which_cpu < system->nr_cpus);
962 processor = system->processors[which_cpu];
964 /* If the data is comming in raw (target order), need to cook it
965 into host order before putting it into PSIM's internal structures */
966 if (mode == raw_transfer) {
967 switch (description.size) {
969 *(unsigned_1*)cooked_buf = T2H_1(*(unsigned_1*)buf);
972 *(unsigned_2*)cooked_buf = T2H_2(*(unsigned_2*)buf);
975 *(unsigned_4*)cooked_buf = T2H_4(*(unsigned_4*)buf);
978 *(unsigned_8*)cooked_buf = T2H_8(*(unsigned_8*)buf);
982 if (CURRENT_HOST_BYTE_ORDER != CURRENT_TARGET_BYTE_ORDER)
984 union { vreg v; unsigned_8 d[2]; } h, t;
985 memcpy(&t.v/*dest*/, buf/*src*/, description.size);
986 { _SWAP_8(h.d[0] =, t.d[1]); }
987 { _SWAP_8(h.d[1] =, t.d[0]); }
988 memcpy(cooked_buf/*dest*/, &h/*src*/, description.size);
992 memcpy(cooked_buf/*dest*/, buf/*src*/, description.size);
997 memcpy(cooked_buf/*dest*/, buf/*src*/, description.size);
1000 /* put the cooked value into the register */
1001 switch (description.type) {
1004 cpu_registers(processor)->gpr[description.index] = *(gpreg*)cooked_buf;
1008 cpu_registers(processor)->fpr[description.index] = *(fpreg*)cooked_buf;
1012 cpu_set_program_counter(processor, *(unsigned_word*)cooked_buf);
1016 cpu_registers(processor)->spr[description.index] = *(spreg*)cooked_buf;
1020 cpu_registers(processor)->sr[description.index] = *(sreg*)cooked_buf;
1024 cpu_registers(processor)->cr = *(creg*)cooked_buf;
1028 cpu_registers(processor)->msr = *(msreg*)cooked_buf;
1032 cpu_registers(processor)->fpscr = *(fpscreg*)cooked_buf;
1037 cpu_registers(processor)->e500.gprh[description.index] = *(gpreg*)cooked_buf;
1043 v = *(unsigned64*)cooked_buf;
1044 cpu_registers(processor)->e500.gprh[description.index] = v >> 32;
1045 cpu_registers(processor)->gpr[description.index] = v;
1050 cpu_registers(processor)->e500.acc = *(accreg*)cooked_buf;
1056 cpu_registers(processor)->altivec.vr[description.index] = *(vreg*)cooked_buf;
1060 cpu_registers(processor)->altivec.vscr = *(vscreg*)cooked_buf;
1065 printf_filtered("psim_write_register(processor=0x%lx,cooked_buf=0x%lx,reg=%s) %s\n",
1066 (unsigned long)processor, (unsigned long)cooked_buf, reg,
1067 "read of this register unimplemented");
1072 return description.size;
1079 psim_read_memory(psim *system,
1082 unsigned_word vaddr,
1086 if (which_cpu == MAX_NR_PROCESSORS) {
1087 if (system->last_cpu == system->nr_cpus
1088 || system->last_cpu == -1)
1091 which_cpu = system->last_cpu;
1093 processor = system->processors[which_cpu];
1094 return vm_data_map_read_buffer(cpu_data_map(processor),
1095 buffer, vaddr, nr_bytes,
1102 psim_write_memory(psim *system,
1105 unsigned_word vaddr,
1107 int violate_read_only_section)
1110 if (which_cpu == MAX_NR_PROCESSORS) {
1111 if (system->last_cpu == system->nr_cpus
1112 || system->last_cpu == -1)
1115 which_cpu = system->last_cpu;
1117 ASSERT(which_cpu >= 0 && which_cpu < system->nr_cpus);
1118 processor = system->processors[which_cpu];
1119 return vm_data_map_write_buffer(cpu_data_map(processor),
1120 buffer, vaddr, nr_bytes, 1/*violate-read-only*/,
1127 psim_print_info(psim *system,
1130 mon_print_info(system, system->monitor, verbose);
1134 /* Merge a device tree and a device file. */
1138 psim_merge_device_file(device *root,
1139 const char *file_name)
1143 char device_path[1000];
1146 /* try opening the file */
1147 description = fopen(file_name, "r");
1148 if (description == NULL) {
1150 error("Invalid file %s specified", file_name);
1155 while (fgets(device_path, sizeof(device_path), description)) {
1157 /* check that the full line was read */
1158 if (strchr(device_path, '\n') == NULL) {
1159 fclose(description);
1160 error("%s:%d: line to long - %s",
1161 file_name, line_nr, device_path);
1164 *strchr(device_path, '\n') = '\0';
1166 /* skip comments ("#" or ";") and blank lines lines */
1167 for (device = device_path;
1168 *device != '\0' && isspace(*device);
1170 if (device[0] == '#'
1172 || device[0] == '\0')
1174 /* merge any appended lines */
1175 while (device_path[strlen(device_path) - 1] == '\\') {
1176 int curlen = strlen(device_path) - 1;
1178 device_path[curlen] = '\0';
1179 /* append the next line */
1180 if (!fgets(device_path + curlen, sizeof(device_path) - curlen, description)) {
1181 fclose(description);
1182 error("%s:%s: unexpected eof in line continuation - %s",
1183 file_name, line_nr, device_path);
1185 if (strchr(device_path, '\n') == NULL) {
1186 fclose(description);
1187 error("%s:%d: line to long - %s",
1188 file_name, line_nr, device_path);
1191 *strchr(device_path, '\n') = '\0';
1194 /* parse this line */
1195 current = tree_parse(current, "%s", device);
1197 fclose(description);
1201 #endif /* _PSIM_C_ */