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"
53 #include "gdb/signals.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, int help)
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");
221 if (REPORT_BUGS_TO[0])
222 printf ("Report bugs to %s\n", REPORT_BUGS_TO);
226 /* Test "string" for containing a string of digits that form a number
227 between "min" and "max". The return value is the number or "err". */
229 int is_num( char *string, int min, int max, int err)
233 for ( ; *string; ++string)
235 if (!isdigit(*string))
240 result = result * 10 + (*string - '0');
242 if (result < min || result > max)
250 psim_options(device *root,
253 device *current = root;
258 while (argv[argp] != NULL && argv[argp][0] == '-') {
259 char *p = argv[argp] + 1;
268 param = find_arg("Missing <count> option for -c (max-iterations)\n", &argp, argv);
269 tree_parse(root, "/openprom/options/max-iterations %s", param);
272 param = find_arg("Missing <emul> option for -e (os-emul)\n", &argp, argv);
273 tree_parse(root, "/openprom/options/os-emul %s", param);
276 /* endian spec, ignored for now */
277 param = find_arg("Missing <endian> option for -E (target-endian)\n", &argp, argv);
278 if (strcmp (param, "big") == 0)
279 tree_parse (root, "/options/little-endian? false");
280 else if (strcmp (param, "little") == 0)
281 tree_parse (root, "/options/little-endian? true");
284 printf_filtered ("Invalid <endian> option for -E (target-endian)\n");
289 param = find_arg("Missing <file> option for -f\n", &argp, argv);
290 psim_merge_device_file(root, param);
301 tree_parse(root, "/openprom/trace/print-info %c", p[1]);
305 tree_parse(root, "/openprom/trace/print-info 1");
309 tree_parse(root, "/openprom/trace/print-info 2");
310 tree_parse(root, "/openprom/options/model-issue %d",
311 MODEL_ISSUE_PROCESS);
314 param = find_arg("Missing <model> option for -m (model)\n", &argp, argv);
315 tree_parse(root, "/openprom/options/model \"%s", param);
318 param = find_arg("Missing <nr-smp> option for -n (smp)\n", &argp, argv);
319 tree_parse(root, "/openprom/options/smp %s", param);
322 param = find_arg("Missing <dev-spec> option for -o\n", &argp, argv);
323 if (memcmp(param, "mpc860c0", 8) == 0)
325 if (param[8] == '\0')
326 tree_parse(root, "/options/mpc860c0 5");
327 else if (param[8] == '=' && is_num(param+9, 1, 10, 0))
329 tree_parse(root, "/options/mpc860c0 %s", param+9);
331 else error("Invalid mpc860c0 option for -o\n");
334 current = tree_parse(current, "%s", param);
337 param = find_arg("Missing <ram-size> option for -r (oea-memory-size)\n", &argp, argv);
338 tree_parse(root, "/openprom/options/oea-memory-size %s",
342 param = find_arg("Missing <trace> option for -t (trace/*)\n", &argp, argv);
344 tree_parse(root, "/openprom/trace/%s 0", param+1);
346 tree_parse(root, "/openprom/trace/%s 1", param);
349 /* it's a long option of the form --optionname=optionvalue.
350 Such options can be passed through if we are invoked by
352 if (strstr(argv[argp], "architecture") != NULL) {
353 /* we must consume the argument here, so that we get out
355 p = argv[argp] + strlen(argv[argp]) - 1;
356 printf_filtered("Warning - architecture parameter ignored\n");
358 else if (strcmp (argv[argp], "--help") == 0)
360 else if (strncmp (argv[argp], "--sysroot=",
361 sizeof ("--sysroot=")) == 0)
362 /* Ignore this option. */
363 p = argv[argp] + strlen(argv[argp]) - 1;
364 else if (strcmp (argv[argp], "--version") == 0)
366 extern const char version[];
367 printf ("GNU simulator %s%s\n", PKGVERSION, version);
371 error("Unrecognized option");
378 /* force the trace node to process its options now *before* the tree
379 initialization occures */
380 device_ioctl(tree_find_device(root, "/openprom/trace"),
382 device_ioctl_set_trace);
385 void semantic_init(device* root);
389 /* return where the options end */
395 psim_command(device *root,
399 if (argv[argp] == NULL) {
402 else if (strcmp(argv[argp], "trace") == 0) {
403 const char *opt = find_arg("Missing <trace> option", &argp, argv);
405 trace_option(opt + 1, 0);
407 trace_option(opt, 1);
409 else if (strcmp(*argv, "change-media") == 0) {
410 char *device = find_arg("Missing device name", &argp, argv);
411 char *media = argv[++argp];
412 device_ioctl(tree_find_device(root, device), NULL, 0,
413 device_ioctl_change_media, media);
416 printf_filtered("Unknown PSIM command %s, try\n", argv[argp]);
417 printf_filtered(" trace <trace-option>\n");
418 printf_filtered(" change-media <device> [ <new-image> ]\n");
423 /* create the simulator proper from the device tree and executable */
427 psim_create(const char *file_name,
433 os_emul *os_emulation;
436 /* given this partially populated device tree, os_emul_create() uses
437 it and file_name to determine the selected emulation and hence
438 further populate the tree with any other required nodes. */
440 os_emulation = os_emul_create(file_name, root);
441 if (os_emulation == NULL)
442 error("psim: either file %s was not reconized or unreconized or unknown os-emulation type\n", file_name);
444 /* fill in the missing real number of CPU's */
445 nr_cpus = tree_find_integer_property(root, "/openprom/options/smp");
446 if (MAX_NR_PROCESSORS < nr_cpus)
447 error("target and configured number of cpus conflict\n");
449 /* fill in the missing TARGET BYTE ORDER information */
450 current_target_byte_order
451 = (tree_find_boolean_property(root, "/options/little-endian?")
454 if (CURRENT_TARGET_BYTE_ORDER != current_target_byte_order)
455 error("target and configured byte order conflict\n");
457 /* fill in the missing HOST BYTE ORDER information */
458 current_host_byte_order = (current_host_byte_order = 1,
459 (*(char*)(¤t_host_byte_order)
462 if (CURRENT_HOST_BYTE_ORDER != current_host_byte_order)
463 error("host and configured byte order conflict\n");
465 /* fill in the missing OEA/VEA information */
466 env = tree_find_string_property(root, "/openprom/options/env");
467 current_environment = ((strcmp(env, "user") == 0
468 || strcmp(env, "uea") == 0)
470 : (strcmp(env, "virtual") == 0
471 || strcmp(env, "vea") == 0)
472 ? VIRTUAL_ENVIRONMENT
473 : (strcmp(env, "operating") == 0
474 || strcmp(env, "oea") == 0)
475 ? OPERATING_ENVIRONMENT
477 if (current_environment == 0)
478 error("unreconized /options env property\n");
479 if (CURRENT_ENVIRONMENT != current_environment)
480 error("target and configured environment conflict\n");
482 /* fill in the missing ALLIGNMENT information */
484 = (tree_find_boolean_property(root, "/openprom/options/strict-alignment?")
486 : NONSTRICT_ALIGNMENT);
487 if (CURRENT_ALIGNMENT != current_alignment)
488 error("target and configured alignment conflict\n");
490 /* fill in the missing FLOATING POINT information */
491 current_floating_point
492 = (tree_find_boolean_property(root, "/openprom/options/floating-point?")
493 ? HARD_FLOATING_POINT
494 : SOFT_FLOATING_POINT);
495 if (CURRENT_FLOATING_POINT != current_floating_point)
496 error("target and configured floating-point conflict\n");
498 /* fill in the missing STDIO information */
500 = (tree_find_boolean_property(root, "/openprom/options/use-stdio?")
503 if (CURRENT_STDIO != current_stdio)
504 error("target and configured stdio interface conflict\n");
506 /* sort out the level of detail for issue modeling */
508 = tree_find_integer_property(root, "/openprom/options/model-issue");
509 if (CURRENT_MODEL_ISSUE != current_model_issue)
510 error("target and configured model-issue conflict\n");
512 /* sort out our model architecture - wrong.
514 FIXME: this should be obtaining the required information from the
515 device tree via the "/chosen" property "cpu" which is an instance
516 (ihandle) for the only executing processor. By converting that
517 ihandle into the corresponding cpu's phandle and then querying
518 the "name" property, the cpu type can be determined. Ok? */
520 model_set(tree_find_string_property(root, "/openprom/options/model"));
523 system = ZALLOC(psim);
524 system->events = event_queue_create();
525 system->memory = core_from_device(root);
526 system->monitor = mon_create();
527 system->nr_cpus = nr_cpus;
528 system->os_emulation = os_emulation;
529 system->devices = root;
531 /* now all the processors attaching to each their per-cpu information */
532 for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++) {
533 system->processors[cpu_nr] = cpu_create(system,
535 mon_cpu(system->monitor,
537 system->os_emulation,
541 /* dump out the contents of the device tree */
542 if (ppc_trace[trace_print_device_tree] || ppc_trace[trace_dump_device_tree])
544 if (ppc_trace[trace_dump_device_tree])
551 /* allow the simulation to stop/restart abnormaly */
555 psim_set_halt_and_restart(psim *system,
557 void *restart_jmp_buf)
559 system->path_to_halt = halt_jmp_buf;
560 system->path_to_restart = restart_jmp_buf;
565 psim_clear_halt_and_restart(psim *system)
567 system->path_to_halt = NULL;
568 system->path_to_restart = NULL;
573 psim_restart(psim *system,
576 ASSERT(current_cpu >= 0 && current_cpu < system->nr_cpus);
577 ASSERT(system->path_to_restart != NULL);
578 system->last_cpu = current_cpu;
579 longjmp(*(jmp_buf*)(system->path_to_restart), current_cpu + 1);
584 cntrl_c_simulation(void *data)
588 psim_nr_cpus(system),
595 psim_stop(psim *system)
597 event_queue_schedule_after_signal(psim_event_queue(system),
605 psim_halt(psim *system,
610 ASSERT(current_cpu >= 0 && current_cpu <= system->nr_cpus);
611 ASSERT(system->path_to_halt != NULL);
612 system->last_cpu = current_cpu;
613 system->halt_status.reason = reason;
614 system->halt_status.signal = signal;
615 if (current_cpu == system->nr_cpus) {
616 system->halt_status.cpu_nr = 0;
617 system->halt_status.program_counter =
618 cpu_get_program_counter(system->processors[0]);
621 system->halt_status.cpu_nr = current_cpu;
622 system->halt_status.program_counter =
623 cpu_get_program_counter(system->processors[current_cpu]);
625 longjmp(*(jmp_buf*)(system->path_to_halt), current_cpu + 1);
631 psim_last_cpu(psim *system)
633 return system->last_cpu;
638 psim_nr_cpus(psim *system)
640 return system->nr_cpus;
645 psim_get_status(psim *system)
647 return system->halt_status;
653 psim_cpu(psim *system,
656 if (cpu_nr < 0 || cpu_nr >= system->nr_cpus)
659 return system->processors[cpu_nr];
665 psim_device(psim *system,
668 return tree_find_device(system->devices, path);
673 psim_event_queue(psim *system)
675 return system->events;
682 psim_max_iterations_exceeded(void *data)
686 system->nr_cpus, /* halted during an event */
694 psim_init(psim *system)
698 /* scrub the monitor */
699 mon_init(system->monitor, system->nr_cpus);
701 /* trash any pending events */
702 event_queue_init(system->events);
704 /* if needed, schedule a halt event. FIXME - In the future this
705 will be replaced by a more generic change to psim_command(). A
706 new command `schedule NNN halt' being added. */
707 if (tree_find_property(system->devices, "/openprom/options/max-iterations")) {
708 event_queue_schedule(system->events,
709 tree_find_integer_property(system->devices,
710 "/openprom/options/max-iterations") - 2,
711 psim_max_iterations_exceeded,
715 /* scrub all the cpus */
716 for (cpu_nr = 0; cpu_nr < system->nr_cpus; cpu_nr++)
717 cpu_init(system->processors[cpu_nr]);
719 /* init all the devices (which updates the cpus) */
720 tree_init(system->devices, system);
722 /* and the emulation (which needs an initialized device tree) */
723 os_emul_init(system->os_emulation, system->nr_cpus);
725 /* now sync each cpu against the initialized state of its registers */
726 for (cpu_nr = 0; cpu_nr < system->nr_cpus; cpu_nr++) {
727 cpu *processor = system->processors[cpu_nr];
728 cpu_synchronize_context(processor, cpu_get_program_counter(processor));
729 cpu_page_tlb_invalidate_all(processor);
732 /* force loop to start with first cpu */
733 system->last_cpu = -1;
738 psim_stack(psim *system,
742 /* pass the stack device the argv/envp and let it work out what to
744 device *stack_device = tree_find_device(system->devices,
745 "/openprom/init/stack");
746 if (stack_device != (device*)0) {
747 unsigned_word stack_pointer;
748 ASSERT (psim_read_register(system, 0, &stack_pointer, "sp",
749 cooked_transfer) > 0);
750 device_ioctl(stack_device,
753 device_ioctl_create_stack,
762 /* SIMULATE INSTRUCTIONS, various different ways of achieving the same
767 psim_step(psim *system)
769 volatile int keep_running = 0;
770 idecode_run_until_stop(system, &keep_running,
771 system->events, system->processors, system->nr_cpus);
776 psim_run(psim *system)
779 system->events, system->processors, system->nr_cpus);
783 /* storage manipulation functions */
787 psim_read_register(psim *system,
793 register_descriptions description;
797 /* find our processor */
798 if (which_cpu == MAX_NR_PROCESSORS) {
799 if (system->last_cpu == system->nr_cpus
800 || system->last_cpu == -1)
803 which_cpu = system->last_cpu;
805 ASSERT(which_cpu >= 0 && which_cpu < system->nr_cpus);
807 processor = system->processors[which_cpu];
809 /* find the register description */
810 description = register_description(reg);
811 if (description.type == reg_invalid)
813 cooked_buf = alloca (description.size);
815 /* get the cooked value */
816 switch (description.type) {
819 *(gpreg*)cooked_buf = cpu_registers(processor)->gpr[description.index];
823 *(spreg*)cooked_buf = cpu_registers(processor)->spr[description.index];
827 *(sreg*)cooked_buf = cpu_registers(processor)->sr[description.index];
831 *(fpreg*)cooked_buf = cpu_registers(processor)->fpr[description.index];
835 *(unsigned_word*)cooked_buf = cpu_get_program_counter(processor);
839 *(creg*)cooked_buf = cpu_registers(processor)->cr;
843 *(msreg*)cooked_buf = cpu_registers(processor)->msr;
847 *(fpscreg*)cooked_buf = cpu_registers(processor)->fpscr;
851 *(unsigned_word*)cooked_buf = mon_get_number_of_insns(system->monitor,
856 if (cpu_model(processor) == NULL)
857 error("$stalls only valid if processor unit model enabled (-I)\n");
858 *(unsigned_word*)cooked_buf = model_get_number_of_stalls(cpu_model(processor));
862 if (cpu_model(processor) == NULL)
863 error("$cycles only valid if processor unit model enabled (-I)\n");
864 *(unsigned_word*)cooked_buf = model_get_number_of_cycles(cpu_model(processor));
869 *(vreg*)cooked_buf = cpu_registers(processor)->altivec.vr[description.index];
873 *(vscreg*)cooked_buf = cpu_registers(processor)->altivec.vscr;
879 *(gpreg*)cooked_buf = cpu_registers(processor)->e500.gprh[description.index];
883 *(unsigned64*)cooked_buf = EVR(description.index);
887 *(accreg*)cooked_buf = cpu_registers(processor)->e500.acc;
892 printf_filtered("psim_read_register(processor=0x%lx,buf=0x%lx,reg=%s) %s\n",
893 (unsigned long)processor, (unsigned long)buf, reg,
894 "read of this register unimplemented");
899 /* the PSIM internal values are in host order. To fetch raw data,
900 they need to be converted into target order and then returned */
901 if (mode == raw_transfer) {
902 /* FIXME - assumes that all registers are simple integers */
903 switch (description.size) {
905 *(unsigned_1*)buf = H2T_1(*(unsigned_1*)cooked_buf);
908 *(unsigned_2*)buf = H2T_2(*(unsigned_2*)cooked_buf);
911 *(unsigned_4*)buf = H2T_4(*(unsigned_4*)cooked_buf);
914 *(unsigned_8*)buf = H2T_8(*(unsigned_8*)cooked_buf);
918 if (CURRENT_HOST_BYTE_ORDER != CURRENT_TARGET_BYTE_ORDER)
920 union { vreg v; unsigned_8 d[2]; } h, t;
921 memcpy(&h.v/*dest*/, cooked_buf/*src*/, description.size);
922 { _SWAP_8(t.d[0] =, h.d[1]); }
923 { _SWAP_8(t.d[1] =, h.d[0]); }
924 memcpy(buf/*dest*/, &t/*src*/, description.size);
928 memcpy(buf/*dest*/, cooked_buf/*src*/, description.size);
934 memcpy(buf/*dest*/, cooked_buf/*src*/, description.size);
937 return description.size;
944 psim_write_register(psim *system,
951 register_descriptions description;
954 /* find our processor */
955 if (which_cpu == MAX_NR_PROCESSORS) {
956 if (system->last_cpu == system->nr_cpus
957 || system->last_cpu == -1)
960 which_cpu = system->last_cpu;
963 /* find the description of the register */
964 description = register_description(reg);
965 if (description.type == reg_invalid)
967 cooked_buf = alloca (description.size);
969 if (which_cpu == -1) {
971 for (i = 0; i < system->nr_cpus; i++)
972 psim_write_register(system, i, buf, reg, mode);
973 return description.size;
975 ASSERT(which_cpu >= 0 && which_cpu < system->nr_cpus);
977 processor = system->processors[which_cpu];
979 /* If the data is comming in raw (target order), need to cook it
980 into host order before putting it into PSIM's internal structures */
981 if (mode == raw_transfer) {
982 switch (description.size) {
984 *(unsigned_1*)cooked_buf = T2H_1(*(unsigned_1*)buf);
987 *(unsigned_2*)cooked_buf = T2H_2(*(unsigned_2*)buf);
990 *(unsigned_4*)cooked_buf = T2H_4(*(unsigned_4*)buf);
993 *(unsigned_8*)cooked_buf = T2H_8(*(unsigned_8*)buf);
997 if (CURRENT_HOST_BYTE_ORDER != CURRENT_TARGET_BYTE_ORDER)
999 union { vreg v; unsigned_8 d[2]; } h, t;
1000 memcpy(&t.v/*dest*/, buf/*src*/, description.size);
1001 { _SWAP_8(h.d[0] =, t.d[1]); }
1002 { _SWAP_8(h.d[1] =, t.d[0]); }
1003 memcpy(cooked_buf/*dest*/, &h/*src*/, description.size);
1007 memcpy(cooked_buf/*dest*/, buf/*src*/, description.size);
1012 memcpy(cooked_buf/*dest*/, buf/*src*/, description.size);
1015 /* put the cooked value into the register */
1016 switch (description.type) {
1019 cpu_registers(processor)->gpr[description.index] = *(gpreg*)cooked_buf;
1023 cpu_registers(processor)->fpr[description.index] = *(fpreg*)cooked_buf;
1027 cpu_set_program_counter(processor, *(unsigned_word*)cooked_buf);
1031 cpu_registers(processor)->spr[description.index] = *(spreg*)cooked_buf;
1035 cpu_registers(processor)->sr[description.index] = *(sreg*)cooked_buf;
1039 cpu_registers(processor)->cr = *(creg*)cooked_buf;
1043 cpu_registers(processor)->msr = *(msreg*)cooked_buf;
1047 cpu_registers(processor)->fpscr = *(fpscreg*)cooked_buf;
1052 cpu_registers(processor)->e500.gprh[description.index] = *(gpreg*)cooked_buf;
1058 v = *(unsigned64*)cooked_buf;
1059 cpu_registers(processor)->e500.gprh[description.index] = v >> 32;
1060 cpu_registers(processor)->gpr[description.index] = v;
1065 cpu_registers(processor)->e500.acc = *(accreg*)cooked_buf;
1071 cpu_registers(processor)->altivec.vr[description.index] = *(vreg*)cooked_buf;
1075 cpu_registers(processor)->altivec.vscr = *(vscreg*)cooked_buf;
1080 printf_filtered("psim_write_register(processor=0x%lx,cooked_buf=0x%lx,reg=%s) %s\n",
1081 (unsigned long)processor, (unsigned long)cooked_buf, reg,
1082 "read of this register unimplemented");
1087 return description.size;
1094 psim_read_memory(psim *system,
1097 unsigned_word vaddr,
1101 if (which_cpu == MAX_NR_PROCESSORS) {
1102 if (system->last_cpu == system->nr_cpus
1103 || system->last_cpu == -1)
1106 which_cpu = system->last_cpu;
1108 processor = system->processors[which_cpu];
1109 return vm_data_map_read_buffer(cpu_data_map(processor),
1110 buffer, vaddr, nr_bytes,
1117 psim_write_memory(psim *system,
1120 unsigned_word vaddr,
1122 int violate_read_only_section)
1125 if (which_cpu == MAX_NR_PROCESSORS) {
1126 if (system->last_cpu == system->nr_cpus
1127 || system->last_cpu == -1)
1130 which_cpu = system->last_cpu;
1132 ASSERT(which_cpu >= 0 && which_cpu < system->nr_cpus);
1133 processor = system->processors[which_cpu];
1134 return vm_data_map_write_buffer(cpu_data_map(processor),
1135 buffer, vaddr, nr_bytes, 1/*violate-read-only*/,
1142 psim_print_info(psim *system,
1145 mon_print_info(system, system->monitor, verbose);
1149 /* Merge a device tree and a device file. */
1153 psim_merge_device_file(device *root,
1154 const char *file_name)
1158 char device_path[1000];
1161 /* try opening the file */
1162 description = fopen(file_name, "r");
1163 if (description == NULL) {
1165 error("Invalid file %s specified", file_name);
1170 while (fgets(device_path, sizeof(device_path), description)) {
1172 /* check that the full line was read */
1173 if (strchr(device_path, '\n') == NULL) {
1174 fclose(description);
1175 error("%s:%d: line to long - %s",
1176 file_name, line_nr, device_path);
1179 *strchr(device_path, '\n') = '\0';
1181 /* skip comments ("#" or ";") and blank lines lines */
1182 for (device = device_path;
1183 *device != '\0' && isspace(*device);
1185 if (device[0] == '#'
1187 || device[0] == '\0')
1189 /* merge any appended lines */
1190 while (device_path[strlen(device_path) - 1] == '\\') {
1191 int curlen = strlen(device_path) - 1;
1193 device_path[curlen] = '\0';
1194 /* append the next line */
1195 if (!fgets(device_path + curlen, sizeof(device_path) - curlen, description)) {
1196 fclose(description);
1197 error("%s:%s: unexpected eof in line continuation - %s",
1198 file_name, line_nr, device_path);
1200 if (strchr(device_path, '\n') == NULL) {
1201 fclose(description);
1202 error("%s:%d: line to long - %s",
1203 file_name, line_nr, device_path);
1206 *strchr(device_path, '\n') = '\0';
1209 /* parse this line */
1210 current = tree_parse(current, "%s", device);
1212 fclose(description);
1216 #endif /* _PSIM_C_ */