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 */
54 /* system structure, actual size of processor array determined at
61 os_emul
*os_emulation
;
64 /* escape routine for inner functions */
66 void *path_to_restart
;
68 /* status from last halt */
69 psim_status halt_status
;
71 /* the processors proper */
73 int last_cpu
; /* CPU that last (tried to) execute an instruction */
74 cpu
*processors
[MAX_NR_PROCESSORS
];
78 int current_target_byte_order
;
79 int current_host_byte_order
;
80 int current_environment
;
81 int current_alignment
;
82 int current_floating_point
;
83 int current_model_issue
= MODEL_ISSUE_IGNORE
;
84 int current_stdio
= DO_USE_STDIO
;
85 model_enum current_model
= WITH_DEFAULT_MODEL
;
88 /* create the device tree */
94 device
*root
= tree_parse(NULL
, "core");
95 tree_parse(root
, "/aliases");
96 tree_parse(root
, "/options");
97 tree_parse(root
, "/chosen");
98 tree_parse(root
, "/packages");
99 tree_parse(root
, "/cpus");
100 tree_parse(root
, "/openprom");
101 tree_parse(root
, "/openprom/init");
102 tree_parse(root
, "/openprom/trace");
103 tree_parse(root
, "/openprom/options");
109 find_arg(char *err_msg
,
114 if (argv
[*ptr_to_argp
] == NULL
)
116 return argv
[*ptr_to_argp
];
121 psim_usage(int verbose
)
123 printf_filtered("Usage:\n");
124 printf_filtered("\n");
125 printf_filtered("\tpsim [ <psim-option> ... ] <image> [ <image-arg> ... ]\n");
126 printf_filtered("\n");
127 printf_filtered("Where\n");
128 printf_filtered("\n");
129 printf_filtered("\t<image> Name of the PowerPC program to run.\n");
131 printf_filtered("\t This can either be a PowerPC binary or\n");
132 printf_filtered("\t a text file containing a device tree\n");
133 printf_filtered("\t specification.\n");
134 printf_filtered("\t PSIM will attempt to determine from the\n");
135 printf_filtered("\t specified <image> the intended emulation\n");
136 printf_filtered("\t environment.\n");
137 printf_filtered("\t If PSIM gets it wrong, the emulation\n");
138 printf_filtered("\t environment can be specified using the\n");
139 printf_filtered("\t `-e' option (described below).\n");
140 printf_filtered("\n"); }
141 printf_filtered("\t<image-arg> Argument to be passed to <image>\n");
143 printf_filtered("\t These arguments will be passed to\n");
144 printf_filtered("\t <image> (as standard C argv, argc)\n");
145 printf_filtered("\t when <image> is started.\n");
146 printf_filtered("\n"); }
147 printf_filtered("\t<psim-option> See below\n");
148 printf_filtered("\n");
149 printf_filtered("The following are valid <psim-option>s:\n");
150 printf_filtered("\n");
152 printf_filtered("\t-c <count> Limit the simulation to <count> iterations\n");
154 printf_filtered("\n");
157 printf_filtered("\t-i or -i2 Print instruction counting statistics\n");
159 printf_filtered("\t Specify -i2 for a more detailed display\n");
160 printf_filtered("\n");
163 printf_filtered("\t-I Print execution unit statistics\n");
164 if (verbose
) { printf_filtered("\n"); }
166 printf_filtered("\t-e <os-emul> specify an OS or platform to model\n");
168 printf_filtered("\t Can be any of the following:\n");
169 printf_filtered("\t bug - OEA + MOTO BUG ROM calls\n");
170 printf_filtered("\t netbsd - UEA + NetBSD system calls\n");
171 printf_filtered("\t solaris - UEA + Solaris system calls\n");
172 printf_filtered("\t linux - UEA + Linux system calls\n");
173 printf_filtered("\t chirp - OEA + a few OpenBoot calls\n");
174 printf_filtered("\n"); }
176 printf_filtered("\t-E <endian> Specify the endianness of the target\n");
178 printf_filtered("\t Can be any of the following:\n");
179 printf_filtered("\t big - big endian target\n");
180 printf_filtered("\t little - little endian target\n");
181 printf_filtered("\n"); }
183 printf_filtered("\t-f <file> Merge <file> into the device tree\n");
184 if (verbose
) { printf_filtered("\n"); }
186 printf_filtered("\t-h -? -H give more detailed usage\n");
187 if (verbose
) { printf_filtered("\n"); }
189 printf_filtered("\t-m <model> Specify the processor to model (604)\n");
191 printf_filtered("\t Selects the processor to use when\n");
192 printf_filtered("\t modeling execution units. Includes:\n");
193 printf_filtered("\t 604, 603 and 603e\n");
194 printf_filtered("\n"); }
196 printf_filtered("\t-n <nr-smp> Specify the number of processors in SMP simulations\n");
198 printf_filtered("\t Specifies the number of processors that are\n");
199 printf_filtered("\t to be modeled in a symetric multi-processor (SMP)\n");
200 printf_filtered("\t simulation\n");
201 printf_filtered("\n"); }
203 printf_filtered("\t-o <dev-spec> Add device <dev-spec> to the device tree\n");
204 if (verbose
) { printf_filtered("\n"); }
206 printf_filtered("\t-r <ram-size> Set RAM size in bytes (OEA environments)\n");
207 if (verbose
) { printf_filtered("\n"); }
209 printf_filtered("\t-t [!]<trace> Enable (disable) <trace> option\n");
210 if (verbose
) { printf_filtered("\n"); }
212 printf_filtered("\n");
213 trace_usage(verbose
);
214 device_usage(verbose
);
216 printf_filtered("\n");
222 /* Test "string" for containing a string of digits that form a number
223 between "min" and "max". The return value is the number or "err". */
225 int is_num( char *string
, int min
, int max
, int err
)
229 for ( ; *string
; ++string
)
231 if (!isdigit(*string
))
236 result
= result
* 10 + (*string
- '0');
238 if (result
< min
|| result
> max
)
246 psim_options(device
*root
,
249 device
*current
= root
;
254 while (argv
[argp
] != NULL
&& argv
[argp
][0] == '-') {
255 char *p
= argv
[argp
] + 1;
264 param
= find_arg("Missing <count> option for -c (max-iterations)\n", &argp
, argv
);
265 tree_parse(root
, "/openprom/options/max-iterations %s", param
);
268 param
= find_arg("Missing <emul> option for -e (os-emul)\n", &argp
, argv
);
269 tree_parse(root
, "/openprom/options/os-emul %s", param
);
272 /* endian spec, ignored for now */
273 param
= find_arg("Missing <endian> option for -E (target-endian)\n", &argp
, argv
);
274 if (strcmp (param
, "big") == 0)
275 tree_parse (root
, "/options/little-endian? false");
276 else if (strcmp (param
, "little") == 0)
277 tree_parse (root
, "/options/little-endian? true");
280 printf_filtered ("Invalid <endian> option for -E (target-endian)\n");
285 param
= find_arg("Missing <file> option for -f\n", &argp
, argv
);
286 psim_merge_device_file(root
, param
);
297 tree_parse(root
, "/openprom/trace/print-info %c", p
[1]);
301 tree_parse(root
, "/openprom/trace/print-info 1");
305 tree_parse(root
, "/openprom/trace/print-info 2");
306 tree_parse(root
, "/openprom/options/model-issue %d",
307 MODEL_ISSUE_PROCESS
);
310 param
= find_arg("Missing <model> option for -m (model)\n", &argp
, argv
);
311 tree_parse(root
, "/openprom/options/model \"%s", param
);
314 param
= find_arg("Missing <nr-smp> option for -n (smp)\n", &argp
, argv
);
315 tree_parse(root
, "/openprom/options/smp %s", param
);
318 param
= find_arg("Missing <dev-spec> option for -o\n", &argp
, argv
);
319 if (memcmp(param
, "mpc860c0", 8) == 0)
321 if (param
[8] == '\0')
322 tree_parse(root
, "/options/mpc860c0 5");
323 else if (param
[8] == '=' && is_num(param
+9, 1, 10, 0))
325 tree_parse(root
, "/options/mpc860c0 %s", param
+9);
327 else error("Invalid mpc860c0 option for -o\n");
330 current
= tree_parse(current
, "%s", param
);
333 param
= find_arg("Missing <ram-size> option for -r (oea-memory-size)\n", &argp
, argv
);
334 tree_parse(root
, "/openprom/options/oea-memory-size %s",
338 param
= find_arg("Missing <trace> option for -t (trace/*)\n", &argp
, argv
);
340 tree_parse(root
, "/openprom/trace/%s 0", param
+1);
342 tree_parse(root
, "/openprom/trace/%s 1", param
);
345 /* it's a long option of the form --optionname=optionvalue.
346 Such options can be passed through if we are invoked by
348 if (strstr(argv
[argp
], "architecture") != NULL
) {
349 /* we must consume the argument here, so that we get out
351 p
= argv
[argp
] + strlen(argv
[argp
]) - 1;
352 printf_filtered("Warning - architecture parameter ignored\n");
355 error("Unrecognized option");
362 /* force the trace node to process its options now *before* the tree
363 initialization occures */
364 device_ioctl(tree_find_device(root
, "/openprom/trace"),
366 device_ioctl_set_trace
);
369 void semantic_init(device
* root
);
373 /* return where the options end */
379 psim_command(device
*root
,
383 if (argv
[argp
] == NULL
) {
386 else if (strcmp(argv
[argp
], "trace") == 0) {
387 const char *opt
= find_arg("Missing <trace> option", &argp
, argv
);
389 trace_option(opt
+ 1, 0);
391 trace_option(opt
, 1);
393 else if (strcmp(*argv
, "change-media") == 0) {
394 char *device
= find_arg("Missing device name", &argp
, argv
);
395 char *media
= argv
[++argp
];
396 device_ioctl(tree_find_device(root
, device
), NULL
, 0,
397 device_ioctl_change_media
, media
);
400 printf_filtered("Unknown PSIM command %s, try\n", argv
[argp
]);
401 printf_filtered(" trace <trace-option>\n");
402 printf_filtered(" change-media <device> [ <new-image> ]\n");
407 /* create the simulator proper from the device tree and executable */
411 psim_create(const char *file_name
,
417 os_emul
*os_emulation
;
420 /* given this partially populated device tree, os_emul_create() uses
421 it and file_name to determine the selected emulation and hence
422 further populate the tree with any other required nodes. */
424 os_emulation
= os_emul_create(file_name
, root
);
425 if (os_emulation
== NULL
)
426 error("psim: either file %s was not reconized or unreconized or unknown os-emulation type\n", file_name
);
428 /* fill in the missing real number of CPU's */
429 nr_cpus
= tree_find_integer_property(root
, "/openprom/options/smp");
430 if (MAX_NR_PROCESSORS
< nr_cpus
)
431 error("target and configured number of cpus conflict\n");
433 /* fill in the missing TARGET BYTE ORDER information */
434 current_target_byte_order
435 = (tree_find_boolean_property(root
, "/options/little-endian?")
438 if (CURRENT_TARGET_BYTE_ORDER
!= current_target_byte_order
)
439 error("target and configured byte order conflict\n");
441 /* fill in the missing HOST BYTE ORDER information */
442 current_host_byte_order
= (current_host_byte_order
= 1,
443 (*(char*)(¤t_host_byte_order
)
446 if (CURRENT_HOST_BYTE_ORDER
!= current_host_byte_order
)
447 error("host and configured byte order conflict\n");
449 /* fill in the missing OEA/VEA information */
450 env
= tree_find_string_property(root
, "/openprom/options/env");
451 current_environment
= ((strcmp(env
, "user") == 0
452 || strcmp(env
, "uea") == 0)
454 : (strcmp(env
, "virtual") == 0
455 || strcmp(env
, "vea") == 0)
456 ? VIRTUAL_ENVIRONMENT
457 : (strcmp(env
, "operating") == 0
458 || strcmp(env
, "oea") == 0)
459 ? OPERATING_ENVIRONMENT
461 if (current_environment
== 0)
462 error("unreconized /options env property\n");
463 if (CURRENT_ENVIRONMENT
!= current_environment
)
464 error("target and configured environment conflict\n");
466 /* fill in the missing ALLIGNMENT information */
468 = (tree_find_boolean_property(root
, "/openprom/options/strict-alignment?")
470 : NONSTRICT_ALIGNMENT
);
471 if (CURRENT_ALIGNMENT
!= current_alignment
)
472 error("target and configured alignment conflict\n");
474 /* fill in the missing FLOATING POINT information */
475 current_floating_point
476 = (tree_find_boolean_property(root
, "/openprom/options/floating-point?")
477 ? HARD_FLOATING_POINT
478 : SOFT_FLOATING_POINT
);
479 if (CURRENT_FLOATING_POINT
!= current_floating_point
)
480 error("target and configured floating-point conflict\n");
482 /* fill in the missing STDIO information */
484 = (tree_find_boolean_property(root
, "/openprom/options/use-stdio?")
487 if (CURRENT_STDIO
!= current_stdio
)
488 error("target and configured stdio interface conflict\n");
490 /* sort out the level of detail for issue modeling */
492 = tree_find_integer_property(root
, "/openprom/options/model-issue");
493 if (CURRENT_MODEL_ISSUE
!= current_model_issue
)
494 error("target and configured model-issue conflict\n");
496 /* sort out our model architecture - wrong.
498 FIXME: this should be obtaining the required information from the
499 device tree via the "/chosen" property "cpu" which is an instance
500 (ihandle) for the only executing processor. By converting that
501 ihandle into the corresponding cpu's phandle and then querying
502 the "name" property, the cpu type can be determined. Ok? */
504 model_set(tree_find_string_property(root
, "/openprom/options/model"));
507 system
= ZALLOC(psim
);
508 system
->events
= event_queue_create();
509 system
->memory
= core_from_device(root
);
510 system
->monitor
= mon_create();
511 system
->nr_cpus
= nr_cpus
;
512 system
->os_emulation
= os_emulation
;
513 system
->devices
= root
;
515 /* now all the processors attaching to each their per-cpu information */
516 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++) {
517 system
->processors
[cpu_nr
] = cpu_create(system
,
519 mon_cpu(system
->monitor
,
521 system
->os_emulation
,
525 /* dump out the contents of the device tree */
526 if (ppc_trace
[trace_print_device_tree
] || ppc_trace
[trace_dump_device_tree
])
528 if (ppc_trace
[trace_dump_device_tree
])
535 /* allow the simulation to stop/restart abnormaly */
539 psim_set_halt_and_restart(psim
*system
,
541 void *restart_jmp_buf
)
543 system
->path_to_halt
= halt_jmp_buf
;
544 system
->path_to_restart
= restart_jmp_buf
;
549 psim_clear_halt_and_restart(psim
*system
)
551 system
->path_to_halt
= NULL
;
552 system
->path_to_restart
= NULL
;
557 psim_restart(psim
*system
,
560 ASSERT(current_cpu
>= 0 && current_cpu
< system
->nr_cpus
);
561 ASSERT(system
->path_to_restart
!= NULL
);
562 system
->last_cpu
= current_cpu
;
563 longjmp(*(jmp_buf*)(system
->path_to_restart
), current_cpu
+ 1);
568 cntrl_c_simulation(void *data
)
572 psim_nr_cpus(system
),
579 psim_stop(psim
*system
)
581 event_queue_schedule_after_signal(psim_event_queue(system
),
589 psim_halt(psim
*system
,
594 ASSERT(current_cpu
>= 0 && current_cpu
<= system
->nr_cpus
);
595 ASSERT(system
->path_to_halt
!= NULL
);
596 system
->last_cpu
= current_cpu
;
597 system
->halt_status
.reason
= reason
;
598 system
->halt_status
.signal
= signal
;
599 if (current_cpu
== system
->nr_cpus
) {
600 system
->halt_status
.cpu_nr
= 0;
601 system
->halt_status
.program_counter
=
602 cpu_get_program_counter(system
->processors
[0]);
605 system
->halt_status
.cpu_nr
= current_cpu
;
606 system
->halt_status
.program_counter
=
607 cpu_get_program_counter(system
->processors
[current_cpu
]);
609 longjmp(*(jmp_buf*)(system
->path_to_halt
), current_cpu
+ 1);
615 psim_last_cpu(psim
*system
)
617 return system
->last_cpu
;
622 psim_nr_cpus(psim
*system
)
624 return system
->nr_cpus
;
629 psim_get_status(psim
*system
)
631 return system
->halt_status
;
637 psim_cpu(psim
*system
,
640 if (cpu_nr
< 0 || cpu_nr
>= system
->nr_cpus
)
643 return system
->processors
[cpu_nr
];
649 psim_device(psim
*system
,
652 return tree_find_device(system
->devices
, path
);
657 psim_event_queue(psim
*system
)
659 return system
->events
;
666 psim_max_iterations_exceeded(void *data
)
670 system
->nr_cpus
, /* halted during an event */
678 psim_init(psim
*system
)
682 /* scrub the monitor */
683 mon_init(system
->monitor
, system
->nr_cpus
);
685 /* trash any pending events */
686 event_queue_init(system
->events
);
688 /* if needed, schedule a halt event. FIXME - In the future this
689 will be replaced by a more generic change to psim_command(). A
690 new command `schedule NNN halt' being added. */
691 if (tree_find_property(system
->devices
, "/openprom/options/max-iterations")) {
692 event_queue_schedule(system
->events
,
693 tree_find_integer_property(system
->devices
,
694 "/openprom/options/max-iterations") - 2,
695 psim_max_iterations_exceeded
,
699 /* scrub all the cpus */
700 for (cpu_nr
= 0; cpu_nr
< system
->nr_cpus
; cpu_nr
++)
701 cpu_init(system
->processors
[cpu_nr
]);
703 /* init all the devices (which updates the cpus) */
704 tree_init(system
->devices
, system
);
706 /* and the emulation (which needs an initialized device tree) */
707 os_emul_init(system
->os_emulation
, system
->nr_cpus
);
709 /* now sync each cpu against the initialized state of its registers */
710 for (cpu_nr
= 0; cpu_nr
< system
->nr_cpus
; cpu_nr
++) {
711 cpu
*processor
= system
->processors
[cpu_nr
];
712 cpu_synchronize_context(processor
, cpu_get_program_counter(processor
));
713 cpu_page_tlb_invalidate_all(processor
);
716 /* force loop to start with first cpu */
717 system
->last_cpu
= -1;
722 psim_stack(psim
*system
,
726 /* pass the stack device the argv/envp and let it work out what to
728 device
*stack_device
= tree_find_device(system
->devices
,
729 "/openprom/init/stack");
730 if (stack_device
!= (device
*)0) {
731 unsigned_word stack_pointer
;
732 ASSERT (psim_read_register(system
, 0, &stack_pointer
, "sp",
733 cooked_transfer
) > 0);
734 device_ioctl(stack_device
,
737 device_ioctl_create_stack
,
746 /* SIMULATE INSTRUCTIONS, various different ways of achieving the same
751 psim_step(psim
*system
)
753 volatile int keep_running
= 0;
754 idecode_run_until_stop(system
, &keep_running
,
755 system
->events
, system
->processors
, system
->nr_cpus
);
760 psim_run(psim
*system
)
763 system
->events
, system
->processors
, system
->nr_cpus
);
767 /* storage manipulation functions */
771 psim_read_register(psim
*system
,
777 register_descriptions description
;
781 /* find our processor */
782 if (which_cpu
== MAX_NR_PROCESSORS
) {
783 if (system
->last_cpu
== system
->nr_cpus
784 || system
->last_cpu
== -1)
787 which_cpu
= system
->last_cpu
;
789 ASSERT(which_cpu
>= 0 && which_cpu
< system
->nr_cpus
);
791 processor
= system
->processors
[which_cpu
];
793 /* find the register description */
794 description
= register_description(reg
);
795 if (description
.type
== reg_invalid
)
797 cooked_buf
= alloca (description
.size
);
799 /* get the cooked value */
800 switch (description
.type
) {
803 *(gpreg
*)cooked_buf
= cpu_registers(processor
)->gpr
[description
.index
];
807 *(spreg
*)cooked_buf
= cpu_registers(processor
)->spr
[description
.index
];
811 *(sreg
*)cooked_buf
= cpu_registers(processor
)->sr
[description
.index
];
815 *(fpreg
*)cooked_buf
= cpu_registers(processor
)->fpr
[description
.index
];
819 *(unsigned_word
*)cooked_buf
= cpu_get_program_counter(processor
);
823 *(creg
*)cooked_buf
= cpu_registers(processor
)->cr
;
827 *(msreg
*)cooked_buf
= cpu_registers(processor
)->msr
;
831 *(fpscreg
*)cooked_buf
= cpu_registers(processor
)->fpscr
;
835 *(unsigned_word
*)cooked_buf
= mon_get_number_of_insns(system
->monitor
,
840 if (cpu_model(processor
) == NULL
)
841 error("$stalls only valid if processor unit model enabled (-I)\n");
842 *(unsigned_word
*)cooked_buf
= model_get_number_of_stalls(cpu_model(processor
));
846 if (cpu_model(processor
) == NULL
)
847 error("$cycles only valid if processor unit model enabled (-I)\n");
848 *(unsigned_word
*)cooked_buf
= model_get_number_of_cycles(cpu_model(processor
));
852 printf_filtered("psim_read_register(processor=0x%lx,buf=0x%lx,reg=%s) %s\n",
853 (unsigned long)processor
, (unsigned long)buf
, reg
,
854 "read of this register unimplemented");
859 /* the PSIM internal values are in host order. To fetch raw data,
860 they need to be converted into target order and then returned */
861 if (mode
== raw_transfer
) {
862 /* FIXME - assumes that all registers are simple integers */
863 switch (description
.size
) {
865 *(unsigned_1
*)buf
= H2T_1(*(unsigned_1
*)cooked_buf
);
868 *(unsigned_2
*)buf
= H2T_2(*(unsigned_2
*)cooked_buf
);
871 *(unsigned_4
*)buf
= H2T_4(*(unsigned_4
*)cooked_buf
);
874 *(unsigned_8
*)buf
= H2T_8(*(unsigned_8
*)cooked_buf
);
879 memcpy(buf
/*dest*/, cooked_buf
/*src*/, description
.size
);
882 return description
.size
;
889 psim_write_register(psim
*system
,
896 register_descriptions description
;
899 /* find our processor */
900 if (which_cpu
== MAX_NR_PROCESSORS
) {
901 if (system
->last_cpu
== system
->nr_cpus
902 || system
->last_cpu
== -1)
905 which_cpu
= system
->last_cpu
;
908 /* find the description of the register */
909 description
= register_description(reg
);
910 if (description
.type
== reg_invalid
)
912 cooked_buf
= alloca (description
.size
);
914 if (which_cpu
== -1) {
916 for (i
= 0; i
< system
->nr_cpus
; i
++)
917 psim_write_register(system
, i
, buf
, reg
, mode
);
918 return description
.size
;
920 ASSERT(which_cpu
>= 0 && which_cpu
< system
->nr_cpus
);
922 processor
= system
->processors
[which_cpu
];
924 /* If the data is comming in raw (target order), need to cook it
925 into host order before putting it into PSIM's internal structures */
926 if (mode
== raw_transfer
) {
927 switch (description
.size
) {
929 *(unsigned_1
*)cooked_buf
= T2H_1(*(unsigned_1
*)buf
);
932 *(unsigned_2
*)cooked_buf
= T2H_2(*(unsigned_2
*)buf
);
935 *(unsigned_4
*)cooked_buf
= T2H_4(*(unsigned_4
*)buf
);
938 *(unsigned_8
*)cooked_buf
= T2H_8(*(unsigned_8
*)buf
);
943 memcpy(cooked_buf
/*dest*/, buf
/*src*/, description
.size
);
946 /* put the cooked value into the register */
947 switch (description
.type
) {
950 cpu_registers(processor
)->gpr
[description
.index
] = *(gpreg
*)cooked_buf
;
954 cpu_registers(processor
)->fpr
[description
.index
] = *(fpreg
*)cooked_buf
;
958 cpu_set_program_counter(processor
, *(unsigned_word
*)cooked_buf
);
962 cpu_registers(processor
)->spr
[description
.index
] = *(spreg
*)cooked_buf
;
966 cpu_registers(processor
)->sr
[description
.index
] = *(sreg
*)cooked_buf
;
970 cpu_registers(processor
)->cr
= *(creg
*)cooked_buf
;
974 cpu_registers(processor
)->msr
= *(msreg
*)cooked_buf
;
978 cpu_registers(processor
)->fpscr
= *(fpscreg
*)cooked_buf
;
982 printf_filtered("psim_write_register(processor=0x%lx,cooked_buf=0x%lx,reg=%s) %s\n",
983 (unsigned long)processor
, (unsigned long)cooked_buf
, reg
,
984 "read of this register unimplemented");
989 return description
.size
;
996 psim_read_memory(psim
*system
,
1003 if (which_cpu
== MAX_NR_PROCESSORS
) {
1004 if (system
->last_cpu
== system
->nr_cpus
1005 || system
->last_cpu
== -1)
1008 which_cpu
= system
->last_cpu
;
1010 processor
= system
->processors
[which_cpu
];
1011 return vm_data_map_read_buffer(cpu_data_map(processor
),
1012 buffer
, vaddr
, nr_bytes
,
1019 psim_write_memory(psim
*system
,
1022 unsigned_word vaddr
,
1024 int violate_read_only_section
)
1027 if (which_cpu
== MAX_NR_PROCESSORS
) {
1028 if (system
->last_cpu
== system
->nr_cpus
1029 || system
->last_cpu
== -1)
1032 which_cpu
= system
->last_cpu
;
1034 ASSERT(which_cpu
>= 0 && which_cpu
< system
->nr_cpus
);
1035 processor
= system
->processors
[which_cpu
];
1036 return vm_data_map_write_buffer(cpu_data_map(processor
),
1037 buffer
, vaddr
, nr_bytes
, 1/*violate-read-only*/,
1044 psim_print_info(psim
*system
,
1047 mon_print_info(system
, system
->monitor
, verbose
);
1051 /* Merge a device tree and a device file. */
1055 psim_merge_device_file(device
*root
,
1056 const char *file_name
)
1060 char device_path
[1000];
1063 /* try opening the file */
1064 description
= fopen(file_name
, "r");
1065 if (description
== NULL
) {
1067 error("Invalid file %s specified", file_name
);
1072 while (fgets(device_path
, sizeof(device_path
), description
)) {
1074 /* check that the full line was read */
1075 if (strchr(device_path
, '\n') == NULL
) {
1076 fclose(description
);
1077 error("%s:%d: line to long - %s",
1078 file_name
, line_nr
, device_path
);
1081 *strchr(device_path
, '\n') = '\0';
1083 /* skip comments ("#" or ";") and blank lines lines */
1084 for (device
= device_path
;
1085 *device
!= '\0' && isspace(*device
);
1087 if (device
[0] == '#'
1089 || device
[0] == '\0')
1091 /* merge any appended lines */
1092 while (device_path
[strlen(device_path
) - 1] == '\\') {
1093 int curlen
= strlen(device_path
) - 1;
1095 device_path
[curlen
] = '\0';
1096 /* append the next line */
1097 if (!fgets(device_path
+ curlen
, sizeof(device_path
) - curlen
, description
)) {
1098 fclose(description
);
1099 error("%s:%s: unexpected eof in line continuation - %s",
1100 file_name
, line_nr
, device_path
);
1102 if (strchr(device_path
, '\n') == NULL
) {
1103 fclose(description
);
1104 error("%s:%d: line to long - %s",
1105 file_name
, line_nr
, device_path
);
1108 *strchr(device_path
, '\n') = '\0';
1111 /* parse this line */
1112 current
= tree_parse(current
, "%s", device
);
1114 fclose(description
);
1118 #endif /* _PSIM_C_ */