1 /* This file is part of the program psim.
3 Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
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 of "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 #ifdef WITH_OPTION_MPC860C0
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 #endif // WITH_OPTION_MPC860C0
332 current
= tree_parse(current
, "%s", param
);
335 param
= find_arg("Missing <ram-size> option for -r (oea-memory-size)\n", &argp
, argv
);
336 tree_parse(root
, "/openprom/options/oea-memory-size %s",
340 param
= find_arg("Missing <trace> option for -t (trace/*)\n", &argp
, argv
);
342 tree_parse(root
, "/openprom/trace/%s 0", param
+1);
344 tree_parse(root
, "/openprom/trace/%s 1", param
);
351 /* force the trace node to process its options now *before* the tree
352 initialization occures */
353 device_ioctl(tree_find_device(root
, "/openprom/trace"),
355 device_ioctl_set_trace
);
357 #ifdef WITH_OPTION_MPC860C0
359 #endif // WITH_OPTION_MPC860C0
361 /* return where the options end */
367 psim_command(device
*root
,
371 if (argv
[argp
] == NULL
) {
374 else if (strcmp(argv
[argp
], "trace") == 0) {
375 const char *opt
= find_arg("Missing <trace> option", &argp
, argv
);
377 trace_option(opt
+ 1, 0);
379 trace_option(opt
, 1);
381 else if (strcmp(*argv
, "change-media") == 0) {
382 char *device
= find_arg("Missing device name", &argp
, argv
);
383 char *media
= argv
[++argp
];
384 device_ioctl(tree_find_device(root
, device
), NULL
, 0,
385 device_ioctl_change_media
, media
);
388 printf_filtered("Unknown PSIM command %s, try\n", argv
[argp
]);
389 printf_filtered(" trace <trace-option>\n");
390 printf_filtered(" change-media <device> [ <new-image> ]\n");
395 /* create the simulator proper from the device tree and executable */
399 psim_create(const char *file_name
,
405 os_emul
*os_emulation
;
408 /* given this partially populated device tree, os_emul_create() uses
409 it and file_name to determine the selected emulation and hence
410 further populate the tree with any other required nodes. */
412 os_emulation
= os_emul_create(file_name
, root
);
413 if (os_emulation
== NULL
)
414 error("psim: either file %s was not reconized or unreconized or unknown os-emulation type\n", file_name
);
416 /* fill in the missing real number of CPU's */
417 nr_cpus
= tree_find_integer_property(root
, "/openprom/options/smp");
418 if (MAX_NR_PROCESSORS
< nr_cpus
)
419 error("target and configured number of cpus conflict\n");
421 /* fill in the missing TARGET BYTE ORDER information */
422 current_target_byte_order
423 = (tree_find_boolean_property(root
, "/options/little-endian?")
426 if (CURRENT_TARGET_BYTE_ORDER
!= current_target_byte_order
)
427 error("target and configured byte order conflict\n");
429 /* fill in the missing HOST BYTE ORDER information */
430 current_host_byte_order
= (current_host_byte_order
= 1,
431 (*(char*)(¤t_host_byte_order
)
434 if (CURRENT_HOST_BYTE_ORDER
!= current_host_byte_order
)
435 error("host and configured byte order conflict\n");
437 /* fill in the missing OEA/VEA information */
438 env
= tree_find_string_property(root
, "/openprom/options/env");
439 current_environment
= ((strcmp(env
, "user") == 0
440 || strcmp(env
, "uea") == 0)
442 : (strcmp(env
, "virtual") == 0
443 || strcmp(env
, "vea") == 0)
444 ? VIRTUAL_ENVIRONMENT
445 : (strcmp(env
, "operating") == 0
446 || strcmp(env
, "oea") == 0)
447 ? OPERATING_ENVIRONMENT
449 if (current_environment
== 0)
450 error("unreconized /options env property\n");
451 if (CURRENT_ENVIRONMENT
!= current_environment
)
452 error("target and configured environment conflict\n");
454 /* fill in the missing ALLIGNMENT information */
456 = (tree_find_boolean_property(root
, "/openprom/options/strict-alignment?")
458 : NONSTRICT_ALIGNMENT
);
459 if (CURRENT_ALIGNMENT
!= current_alignment
)
460 error("target and configured alignment conflict\n");
462 /* fill in the missing FLOATING POINT information */
463 current_floating_point
464 = (tree_find_boolean_property(root
, "/openprom/options/floating-point?")
465 ? HARD_FLOATING_POINT
466 : SOFT_FLOATING_POINT
);
467 if (CURRENT_FLOATING_POINT
!= current_floating_point
)
468 error("target and configured floating-point conflict\n");
470 /* fill in the missing STDIO information */
472 = (tree_find_boolean_property(root
, "/openprom/options/use-stdio?")
475 if (CURRENT_STDIO
!= current_stdio
)
476 error("target and configured stdio interface conflict\n");
478 /* sort out the level of detail for issue modeling */
480 = tree_find_integer_property(root
, "/openprom/options/model-issue");
481 if (CURRENT_MODEL_ISSUE
!= current_model_issue
)
482 error("target and configured model-issue conflict\n");
484 /* sort out our model architecture - wrong.
486 FIXME: this should be obtaining the required information from the
487 device tree via the "/chosen" property "cpu" which is an instance
488 (ihandle) for the only executing processor. By converting that
489 ihandle into the corresponding cpu's phandle and then querying
490 the "name" property, the cpu type can be determined. Ok? */
492 model_set(tree_find_string_property(root
, "/openprom/options/model"));
495 system
= ZALLOC(psim
);
496 system
->events
= event_queue_create();
497 system
->memory
= core_from_device(root
);
498 system
->monitor
= mon_create();
499 system
->nr_cpus
= nr_cpus
;
500 system
->os_emulation
= os_emulation
;
501 system
->devices
= root
;
503 /* now all the processors attaching to each their per-cpu information */
504 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++) {
505 system
->processors
[cpu_nr
] = cpu_create(system
,
507 mon_cpu(system
->monitor
,
509 system
->os_emulation
,
513 /* dump out the contents of the device tree */
514 if (ppc_trace
[trace_print_device_tree
] || ppc_trace
[trace_dump_device_tree
])
516 if (ppc_trace
[trace_dump_device_tree
])
523 /* allow the simulation to stop/restart abnormaly */
527 psim_set_halt_and_restart(psim
*system
,
529 void *restart_jmp_buf
)
531 system
->path_to_halt
= halt_jmp_buf
;
532 system
->path_to_restart
= restart_jmp_buf
;
537 psim_clear_halt_and_restart(psim
*system
)
539 system
->path_to_halt
= NULL
;
540 system
->path_to_restart
= NULL
;
545 psim_restart(psim
*system
,
548 ASSERT(current_cpu
>= 0 && current_cpu
< system
->nr_cpus
);
549 ASSERT(system
->path_to_restart
!= NULL
);
550 system
->last_cpu
= current_cpu
;
551 longjmp(*(jmp_buf*)(system
->path_to_restart
), current_cpu
+ 1);
556 cntrl_c_simulation(void *data
)
560 psim_nr_cpus(system
),
567 psim_stop(psim
*system
)
569 event_queue_schedule_after_signal(psim_event_queue(system
),
577 psim_halt(psim
*system
,
582 ASSERT(current_cpu
>= 0 && current_cpu
<= system
->nr_cpus
);
583 ASSERT(system
->path_to_halt
!= NULL
);
584 system
->last_cpu
= current_cpu
;
585 system
->halt_status
.reason
= reason
;
586 system
->halt_status
.signal
= signal
;
587 if (current_cpu
== system
->nr_cpus
) {
588 system
->halt_status
.cpu_nr
= 0;
589 system
->halt_status
.program_counter
=
590 cpu_get_program_counter(system
->processors
[0]);
593 system
->halt_status
.cpu_nr
= current_cpu
;
594 system
->halt_status
.program_counter
=
595 cpu_get_program_counter(system
->processors
[current_cpu
]);
597 longjmp(*(jmp_buf*)(system
->path_to_halt
), current_cpu
+ 1);
603 psim_last_cpu(psim
*system
)
605 return system
->last_cpu
;
610 psim_nr_cpus(psim
*system
)
612 return system
->nr_cpus
;
617 psim_get_status(psim
*system
)
619 return system
->halt_status
;
625 psim_cpu(psim
*system
,
628 if (cpu_nr
< 0 || cpu_nr
>= system
->nr_cpus
)
631 return system
->processors
[cpu_nr
];
637 psim_device(psim
*system
,
640 return tree_find_device(system
->devices
, path
);
645 psim_event_queue(psim
*system
)
647 return system
->events
;
654 psim_max_iterations_exceeded(void *data
)
658 system
->nr_cpus
, /* halted during an event */
666 psim_init(psim
*system
)
670 /* scrub the monitor */
671 mon_init(system
->monitor
, system
->nr_cpus
);
673 /* trash any pending events */
674 event_queue_init(system
->events
);
676 /* if needed, schedule a halt event. FIXME - In the future this
677 will be replaced by a more generic change to psim_command(). A
678 new command `schedule NNN halt' being added. */
679 if (tree_find_property(system
->devices
, "/openprom/options/max-iterations")) {
680 event_queue_schedule(system
->events
,
681 tree_find_integer_property(system
->devices
,
682 "/openprom/options/max-iterations") - 2,
683 psim_max_iterations_exceeded
,
687 /* scrub all the cpus */
688 for (cpu_nr
= 0; cpu_nr
< system
->nr_cpus
; cpu_nr
++)
689 cpu_init(system
->processors
[cpu_nr
]);
691 /* init all the devices (which updates the cpus) */
692 tree_init(system
->devices
, system
);
694 /* and the emulation (which needs an initialized device tree) */
695 os_emul_init(system
->os_emulation
, system
->nr_cpus
);
697 /* now sync each cpu against the initialized state of its registers */
698 for (cpu_nr
= 0; cpu_nr
< system
->nr_cpus
; cpu_nr
++) {
699 cpu
*processor
= system
->processors
[cpu_nr
];
700 cpu_synchronize_context(processor
, cpu_get_program_counter(processor
));
701 cpu_page_tlb_invalidate_all(processor
);
704 /* force loop to start with first cpu */
705 system
->last_cpu
= -1;
710 psim_stack(psim
*system
,
714 /* pass the stack device the argv/envp and let it work out what to
716 device
*stack_device
= tree_find_device(system
->devices
,
717 "/openprom/init/stack");
718 if (stack_device
!= (device
*)0) {
719 unsigned_word stack_pointer
;
720 psim_read_register(system
, 0, &stack_pointer
, "sp", cooked_transfer
);
721 device_ioctl(stack_device
,
724 device_ioctl_create_stack
,
733 /* SIMULATE INSTRUCTIONS, various different ways of achieving the same
738 psim_step(psim
*system
)
740 volatile int keep_running
= 0;
741 idecode_run_until_stop(system
, &keep_running
,
742 system
->events
, system
->processors
, system
->nr_cpus
);
747 psim_run(psim
*system
)
750 system
->events
, system
->processors
, system
->nr_cpus
);
754 /* storage manipulation functions */
758 psim_read_register(psim
*system
,
764 register_descriptions description
;
765 char cooked_buf
[sizeof(unsigned_8
)];
768 /* find our processor */
769 if (which_cpu
== MAX_NR_PROCESSORS
) {
770 if (system
->last_cpu
== system
->nr_cpus
771 || system
->last_cpu
== -1)
774 which_cpu
= system
->last_cpu
;
776 ASSERT(which_cpu
>= 0 && which_cpu
< system
->nr_cpus
);
778 processor
= system
->processors
[which_cpu
];
780 /* find the register description */
781 description
= register_description(reg
);
782 if (description
.type
== reg_invalid
)
783 error("psim_read_register() invalid register name `%s'\n", reg
);
785 /* get the cooked value */
786 switch (description
.type
) {
789 *(gpreg
*)cooked_buf
= cpu_registers(processor
)->gpr
[description
.index
];
793 *(spreg
*)cooked_buf
= cpu_registers(processor
)->spr
[description
.index
];
797 *(sreg
*)cooked_buf
= cpu_registers(processor
)->sr
[description
.index
];
801 *(fpreg
*)cooked_buf
= cpu_registers(processor
)->fpr
[description
.index
];
805 *(unsigned_word
*)cooked_buf
= cpu_get_program_counter(processor
);
809 *(creg
*)cooked_buf
= cpu_registers(processor
)->cr
;
813 *(msreg
*)cooked_buf
= cpu_registers(processor
)->msr
;
817 *(fpscreg
*)cooked_buf
= cpu_registers(processor
)->fpscr
;
821 *(unsigned_word
*)cooked_buf
= mon_get_number_of_insns(system
->monitor
,
826 if (cpu_model(processor
) == NULL
)
827 error("$stalls only valid if processor unit model enabled (-I)\n");
828 *(unsigned_word
*)cooked_buf
= model_get_number_of_stalls(cpu_model(processor
));
832 if (cpu_model(processor
) == NULL
)
833 error("$cycles only valid if processor unit model enabled (-I)\n");
834 *(unsigned_word
*)cooked_buf
= model_get_number_of_cycles(cpu_model(processor
));
838 printf_filtered("psim_read_register(processor=0x%lx,buf=0x%lx,reg=%s) %s\n",
839 (unsigned long)processor
, (unsigned long)buf
, reg
,
840 "read of this register unimplemented");
845 /* the PSIM internal values are in host order. To fetch raw data,
846 they need to be converted into target order and then returned */
847 if (mode
== raw_transfer
) {
848 /* FIXME - assumes that all registers are simple integers */
849 switch (description
.size
) {
851 *(unsigned_1
*)buf
= H2T_1(*(unsigned_1
*)cooked_buf
);
854 *(unsigned_2
*)buf
= H2T_2(*(unsigned_2
*)cooked_buf
);
857 *(unsigned_4
*)buf
= H2T_4(*(unsigned_4
*)cooked_buf
);
860 *(unsigned_8
*)buf
= H2T_8(*(unsigned_8
*)cooked_buf
);
865 memcpy(buf
/*dest*/, cooked_buf
/*src*/, description
.size
);
874 psim_write_register(psim
*system
,
881 register_descriptions description
;
882 char cooked_buf
[sizeof(unsigned_8
)];
884 /* find our processor */
885 if (which_cpu
== MAX_NR_PROCESSORS
) {
886 if (system
->last_cpu
== system
->nr_cpus
887 || system
->last_cpu
== -1)
890 which_cpu
= system
->last_cpu
;
892 if (which_cpu
== -1) {
894 for (i
= 0; i
< system
->nr_cpus
; i
++)
895 psim_write_register(system
, i
, buf
, reg
, mode
);
898 ASSERT(which_cpu
>= 0 && which_cpu
< system
->nr_cpus
);
900 processor
= system
->processors
[which_cpu
];
902 /* find the description of the register */
903 description
= register_description(reg
);
904 if (description
.type
== reg_invalid
)
905 error("psim_write_register() invalid register name %s\n", reg
);
907 /* If the data is comming in raw (target order), need to cook it
908 into host order before putting it into PSIM's internal structures */
909 if (mode
== raw_transfer
) {
910 switch (description
.size
) {
912 *(unsigned_1
*)cooked_buf
= T2H_1(*(unsigned_1
*)buf
);
915 *(unsigned_2
*)cooked_buf
= T2H_2(*(unsigned_2
*)buf
);
918 *(unsigned_4
*)cooked_buf
= T2H_4(*(unsigned_4
*)buf
);
921 *(unsigned_8
*)cooked_buf
= T2H_8(*(unsigned_8
*)buf
);
926 memcpy(cooked_buf
/*dest*/, buf
/*src*/, description
.size
);
929 /* put the cooked value into the register */
930 switch (description
.type
) {
933 cpu_registers(processor
)->gpr
[description
.index
] = *(gpreg
*)cooked_buf
;
937 cpu_registers(processor
)->fpr
[description
.index
] = *(fpreg
*)cooked_buf
;
941 cpu_set_program_counter(processor
, *(unsigned_word
*)cooked_buf
);
945 cpu_registers(processor
)->spr
[description
.index
] = *(spreg
*)cooked_buf
;
949 cpu_registers(processor
)->sr
[description
.index
] = *(sreg
*)cooked_buf
;
953 cpu_registers(processor
)->cr
= *(creg
*)cooked_buf
;
957 cpu_registers(processor
)->msr
= *(msreg
*)cooked_buf
;
961 cpu_registers(processor
)->fpscr
= *(fpscreg
*)cooked_buf
;
965 printf_filtered("psim_write_register(processor=0x%lx,cooked_buf=0x%lx,reg=%s) %s\n",
966 (unsigned long)processor
, (unsigned long)cooked_buf
, reg
,
967 "read of this register unimplemented");
978 psim_read_memory(psim
*system
,
985 if (which_cpu
== MAX_NR_PROCESSORS
) {
986 if (system
->last_cpu
== system
->nr_cpus
987 || system
->last_cpu
== -1)
990 which_cpu
= system
->last_cpu
;
992 processor
= system
->processors
[which_cpu
];
993 return vm_data_map_read_buffer(cpu_data_map(processor
),
994 buffer
, vaddr
, nr_bytes
,
1001 psim_write_memory(psim
*system
,
1004 unsigned_word vaddr
,
1006 int violate_read_only_section
)
1009 if (which_cpu
== MAX_NR_PROCESSORS
) {
1010 if (system
->last_cpu
== system
->nr_cpus
1011 || system
->last_cpu
== -1)
1014 which_cpu
= system
->last_cpu
;
1016 ASSERT(which_cpu
>= 0 && which_cpu
< system
->nr_cpus
);
1017 processor
= system
->processors
[which_cpu
];
1018 return vm_data_map_write_buffer(cpu_data_map(processor
),
1019 buffer
, vaddr
, nr_bytes
, 1/*violate-read-only*/,
1026 psim_print_info(psim
*system
,
1029 mon_print_info(system
, system
->monitor
, verbose
);
1033 /* Merge a device tree and a device file. */
1037 psim_merge_device_file(device
*root
,
1038 const char *file_name
)
1042 char device_path
[1000];
1045 /* try opening the file */
1046 description
= fopen(file_name
, "r");
1047 if (description
== NULL
) {
1049 error("Invalid file %s specified", file_name
);
1054 while (fgets(device_path
, sizeof(device_path
), description
)) {
1056 /* check that the full line was read */
1057 if (strchr(device_path
, '\n') == NULL
) {
1058 fclose(description
);
1059 error("%s:%d: line to long - %s",
1060 file_name
, line_nr
, device_path
);
1063 *strchr(device_path
, '\n') = '\0';
1065 /* skip comments ("#" or ";") and blank lines lines */
1066 for (device
= device_path
;
1067 *device
!= '\0' && isspace(*device
);
1069 if (device
[0] == '#'
1071 || device
[0] == '\0')
1073 /* merge any appended lines */
1074 while (device_path
[strlen(device_path
) - 1] == '\\') {
1075 int curlen
= strlen(device_path
) - 1;
1077 device_path
[curlen
] = '\0';
1078 /* append the next line */
1079 if (!fgets(device_path
+ curlen
, sizeof(device_path
) - curlen
, description
)) {
1080 fclose(description
);
1081 error("%s:%s: unexpected eof in line continuation - %s",
1082 file_name
, line_nr
, device_path
);
1084 if (strchr(device_path
, '\n') == NULL
) {
1085 fclose(description
);
1086 error("%s:%d: line to long - %s",
1087 file_name
, line_nr
, device_path
);
1090 *strchr(device_path
, '\n') = '\0';
1093 /* parse this line */
1094 current
= tree_parse(current
, "%s", device
);
1096 fclose(description
);
1100 #endif /* _PSIM_C_ */