1 /* This file is part of the program psim.
3 Copyright (C) 1994-1996, 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.
36 #include "cpu.h" /* includes psim.h */
51 /* system structure, actual size of processor array determined at
58 os_emul
*os_emulation
;
61 /* escape routine for inner functions */
63 void *path_to_restart
;
65 /* status from last halt */
66 psim_status halt_status
;
68 /* the processors proper */
70 int last_cpu
; /* CPU that last (tried to) execute an instruction */
71 cpu
*processors
[MAX_NR_PROCESSORS
];
75 int current_target_byte_order
;
76 int current_host_byte_order
;
77 int current_environment
;
78 int current_alignment
;
79 int current_floating_point
;
80 int current_model_issue
= MODEL_ISSUE_IGNORE
;
81 model_enum current_model
= WITH_DEFAULT_MODEL
;
84 /* create the device tree */
90 device
*root
= core_device_create();
91 device_tree_add_parsed(root
, "/aliases");
92 device_tree_add_parsed(root
, "/options");
93 device_tree_add_parsed(root
, "/chosen");
94 device_tree_add_parsed(root
, "/packages");
95 device_tree_add_parsed(root
, "/cpus");
96 device_tree_add_parsed(root
, "/openprom");
97 device_tree_add_parsed(root
, "/openprom/init");
98 device_tree_add_parsed(root
, "/openprom/trace");
99 device_tree_add_parsed(root
, "/openprom/options");
105 find_arg(char *err_msg
,
110 if (argv
[*ptr_to_argp
] == NULL
)
112 return argv
[*ptr_to_argp
];
117 psim_usage(int verbose
)
119 printf_filtered("Usage:\n");
120 printf_filtered("\n");
121 printf_filtered("\tpsim [ <psim-option> ... ] <image> [ <image-arg> ... ]\n");
122 printf_filtered("\n");
123 printf_filtered("Where\n");
124 printf_filtered("\n");
125 printf_filtered("\t<image> Name of the PowerPC program to run.\n");
127 printf_filtered("\t This can either be a PowerPC binary or\n");
128 printf_filtered("\t a text file containing a device tree\n");
129 printf_filtered("\t specification.\n");
130 printf_filtered("\t PSIM will attempt to determine from the\n");
131 printf_filtered("\t specified <image> the intended emulation\n");
132 printf_filtered("\t environment.\n");
133 printf_filtered("\t If PSIM gets it wrong, the emulation\n");
134 printf_filtered("\t environment can be specified using the\n");
135 printf_filtered("\t `-e' option (described below).\n");
136 printf_filtered("\n"); }
137 printf_filtered("\t<image-arg> Argument to be passed to <image>\n");
139 printf_filtered("\t These arguments will be passed to\n");
140 printf_filtered("\t <image> (as standard C argv, argc)\n");
141 printf_filtered("\t when <image> is started.\n");
142 printf_filtered("\n"); }
143 printf_filtered("\t<psim-option> See below\n");
144 printf_filtered("\n");
145 printf_filtered("The following are valid <psim-option>s:\n");
146 printf_filtered("\n");
147 printf_filtered("\t-m <model> Specify the processor to model (604)\n");
149 printf_filtered("\t Selects the processor to use when\n");
150 printf_filtered("\t modeling execution units. Includes:\n");
151 printf_filtered("\t 604, 603 and 603e\n");
152 printf_filtered("\n"); }
153 printf_filtered("\t-e <os-emul> specify an OS or platform to model\n");
155 printf_filtered("\t Can be any of the following:\n");
156 printf_filtered("\t bug - OEA + MOTO BUG ROM calls\n");
157 printf_filtered("\t netbsd - UEA + NetBSD system calls\n");
158 printf_filtered("\t solaris - UEA + Solaris system calls\n");
159 printf_filtered("\t linux - UEA + Linux system calls\n");
160 printf_filtered("\t chirp - OEA + a few OpenBoot calls\n");
161 printf_filtered("\n"); }
162 printf_filtered("\t-i Print instruction counting statistics\n");
163 if (verbose
) { printf_filtered("\n"); }
164 printf_filtered("\t-I Print execution unit statistics\n");
165 if (verbose
) { printf_filtered("\n"); }
166 printf_filtered("\t-r <size> Set RAM size in bytes (OEA environments)\n");
167 if (verbose
) { printf_filtered("\n"); }
168 printf_filtered("\t-t [!]<trace> Enable (disable) <trace> option\n");
169 if (verbose
) { printf_filtered("\n"); }
170 printf_filtered("\t-o <spec> add device <spec> to the device tree\n");
171 if (verbose
) { printf_filtered("\n"); }
172 printf_filtered("\t-h -? -H give more detailed usage\n");
173 if (verbose
) { printf_filtered("\n"); }
174 printf_filtered("\n");
175 trace_usage(verbose
);
176 device_usage(verbose
);
178 printf_filtered("\n");
186 psim_options(device
*root
,
189 device
*current
= root
;
194 while (argv
[argp
] != NULL
&& argv
[argp
][0] == '-') {
195 char *p
= argv
[argp
] + 1;
204 param
= find_arg("Missing <emul> option for -e\n", &argp
, argv
);
205 device_tree_add_parsed(root
, "/openprom/options/os-emul %s", param
);
215 device_tree_add_parsed(root
, "/openprom/trace/print-info 1");
218 device_tree_add_parsed(root
, "/openprom/trace/print-info 2");
219 device_tree_add_parsed(root
, "/openprom/options/model-issue %d",
220 MODEL_ISSUE_PROCESS
);
223 param
= find_arg("Missing <model> option for -m\n", &argp
, argv
);
224 device_tree_add_parsed(root
, "/openprom/options/model \"%s", param
);
227 param
= find_arg("Missing <device> option for -o\n", &argp
, argv
);
228 current
= device_tree_add_parsed(current
, "%s", param
);
231 param
= find_arg("Missing <ram-size> option for -r\n", &argp
, argv
);
232 device_tree_add_parsed(root
, "/openprom/options/oea-memory-size 0x%lx",
236 param
= find_arg("Missing <trace> option for -t\n", &argp
, argv
);
238 device_tree_add_parsed(root
, "/openprom/trace/%s 0", param
+1);
240 device_tree_add_parsed(root
, "/openprom/trace/%s 1", param
);
247 /* force the trace node to (re)process its options */
248 device_init_data(device_tree_find_device(root
, "/openprom/trace"), NULL
);
249 /* return where the options end */
254 /* create the simulator proper from the device tree and executable */
258 psim_create(const char *file_name
,
264 os_emul
*os_emulation
;
267 /* given this partially populated device tree, os_emul_create() uses
268 it and file_name to determine the selected emulation and hence
269 further populate the tree with any other required nodes. */
271 os_emulation
= os_emul_create(file_name
, root
);
272 if (os_emulation
== NULL
)
273 error("psim: either file %s was not reconized or unreconized or unknown os-emulation type\n", file_name
);
275 /* fill in the missing real number of CPU's */
276 nr_cpus
= device_find_integer_property(root
, "/openprom/options/smp");
277 if (MAX_NR_PROCESSORS
< nr_cpus
)
278 error("target and configured number of cpus conflict\n");
280 /* fill in the missing TARGET BYTE ORDER information */
281 current_target_byte_order
282 = (device_find_boolean_property(root
, "/options/little-endian?")
285 if (CURRENT_TARGET_BYTE_ORDER
!= current_target_byte_order
)
286 error("target and configured byte order conflict\n");
288 /* fill in the missing HOST BYTE ORDER information */
289 current_host_byte_order
= (current_host_byte_order
= 1,
290 (*(char*)(¤t_host_byte_order
)
293 if (CURRENT_HOST_BYTE_ORDER
!= current_host_byte_order
)
294 error("host and configured byte order conflict\n");
296 /* fill in the missing OEA/VEA information */
297 env
= device_find_string_property(root
, "/openprom/options/env");
298 current_environment
= ((strcmp(env
, "user") == 0
299 || strcmp(env
, "uea") == 0)
301 : (strcmp(env
, "virtual") == 0
302 || strcmp(env
, "vea") == 0)
303 ? VIRTUAL_ENVIRONMENT
304 : (strcmp(env
, "operating") == 0
305 || strcmp(env
, "oea") == 0)
306 ? OPERATING_ENVIRONMENT
308 if (current_environment
== 0)
309 error("unreconized /options env property\n");
310 if (CURRENT_ENVIRONMENT
!= current_environment
)
311 error("target and configured environment conflict\n");
313 /* fill in the missing ALLIGNMENT information */
315 = (device_find_boolean_property(root
, "/openprom/options/strict-alignment?")
317 : NONSTRICT_ALIGNMENT
);
318 if (CURRENT_ALIGNMENT
!= current_alignment
)
319 error("target and configured alignment conflict\n");
321 /* fill in the missing FLOATING POINT information */
322 current_floating_point
323 = (device_find_boolean_property(root
, "/openprom/options/floating-point?")
324 ? HARD_FLOATING_POINT
325 : SOFT_FLOATING_POINT
);
326 if (CURRENT_FLOATING_POINT
!= current_floating_point
)
327 error("target and configured floating-point conflict\n");
329 /* sort out the level of detail for issue modeling */
331 = device_find_integer_property(root
, "/openprom/options/model-issue");
332 if (CURRENT_MODEL_ISSUE
!= current_model_issue
)
333 error("target and configured model-issue conflict\n");
335 /* sort out our model architecture - wrong.
337 FIXME: this should be obtaining the required information from the
338 device tree via the "/chosen" property "cpu" which is an instance
339 (ihandle) for the only executing processor. By converting that
340 ihandle into the corresponding cpu's phandle and then querying
341 the "name" property, the cpu type can be determined. Ok? */
343 model_set(device_find_string_property(root
, "/openprom/options/model"));
346 system
= ZALLOC(psim
);
347 system
->events
= event_queue_create();
348 system
->memory
= core_create(root
);
349 system
->monitor
= mon_create();
350 system
->nr_cpus
= nr_cpus
;
351 system
->os_emulation
= os_emulation
;
352 system
->devices
= root
;
354 /* now all the processors attaching to each their per-cpu information */
355 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++) {
356 system
->processors
[cpu_nr
] = cpu_create(system
,
358 mon_cpu(system
->monitor
,
360 system
->os_emulation
,
364 /* dump out the contents of the device tree */
365 if (ppc_trace
[trace_print_device_tree
] || ppc_trace
[trace_dump_device_tree
])
366 device_tree_traverse(root
, device_tree_print_device
, NULL
, NULL
);
367 if (ppc_trace
[trace_dump_device_tree
])
374 /* allow the simulation to stop/restart abnormaly */
378 psim_set_halt_and_restart(psim
*system
,
380 void *restart_jmp_buf
)
382 system
->path_to_halt
= halt_jmp_buf
;
383 system
->path_to_restart
= restart_jmp_buf
;
388 psim_clear_halt_and_restart(psim
*system
)
390 system
->path_to_halt
= NULL
;
391 system
->path_to_restart
= NULL
;
396 psim_restart(psim
*system
,
399 system
->last_cpu
= current_cpu
;
400 longjmp(*(jmp_buf*)(system
->path_to_restart
), current_cpu
+ 1);
406 psim_halt(psim
*system
,
411 ASSERT(current_cpu
>= 0 && current_cpu
< system
->nr_cpus
);
412 system
->last_cpu
= current_cpu
;
413 system
->halt_status
.cpu_nr
= current_cpu
;
414 system
->halt_status
.reason
= reason
;
415 system
->halt_status
.signal
= signal
;
416 system
->halt_status
.program_counter
=
417 cpu_get_program_counter(system
->processors
[current_cpu
]);
418 longjmp(*(jmp_buf*)(system
->path_to_halt
), current_cpu
+ 1);
423 psim_get_status(psim
*system
)
425 return system
->halt_status
;
431 psim_cpu(psim
*system
,
434 if (cpu_nr
< 0 || cpu_nr
>= system
->nr_cpus
)
437 return system
->processors
[cpu_nr
];
443 psim_device(psim
*system
,
446 return device_tree_find_device(system
->devices
, path
);
451 psim_event_queue(psim
*system
)
453 return system
->events
;
460 psim_init(psim
*system
)
464 /* scrub the monitor */
465 mon_init(system
->monitor
, system
->nr_cpus
);
466 os_emul_init(system
->os_emulation
, system
->nr_cpus
);
467 event_queue_init(system
->events
);
469 /* scrub all the cpus */
470 for (cpu_nr
= 0; cpu_nr
< system
->nr_cpus
; cpu_nr
++)
471 cpu_init(system
->processors
[cpu_nr
]);
473 /* init all the devices (which updates the cpus) */
474 device_tree_init(system
->devices
, system
);
476 /* now sync each cpu against the initialized state of its registers */
477 for (cpu_nr
= 0; cpu_nr
< system
->nr_cpus
; cpu_nr
++) {
478 cpu_synchronize_context(system
->processors
[cpu_nr
]);
479 cpu_page_tlb_invalidate_all(system
->processors
[cpu_nr
]);
482 /* force loop to restart */
483 system
->last_cpu
= system
->nr_cpus
- 1;
488 psim_stack(psim
*system
,
492 /* pass the stack device the argv/envp and let it work out what to
494 device
*stack_device
= device_tree_find_device(system
->devices
,
495 "/openprom/init/stack");
496 if (stack_device
!= (device
*)0) {
497 unsigned_word stack_pointer
;
498 psim_read_register(system
, 0, &stack_pointer
, "sp", cooked_transfer
);
499 device_ioctl(stack_device
,
511 /* EXECUTE REAL CODE:
513 Unfortunatly, there are multiple cases to consider vis:
515 <icache> X <smp> X <events> X <keep-running-flag> X ...
517 Consequently this function is written in multiple different ways */
521 run_until_stop(psim
*system
,
522 volatile int *keep_running
)
526 #if WITH_IDECODE_CACHE_SIZE
528 for (cpu_nr
= 0; cpu_nr
< system
->nr_cpus
; cpu_nr
++)
529 cpu_flush_icache(system
->processors
[cpu_nr
]);
531 psim_set_halt_and_restart(system
, &halt
, &restart
);
533 #if (!WITH_IDECODE_CACHE_SIZE && WITH_SMP == 0)
535 /* CASE 1: No instruction cache and no SMP.
537 In this case, we can take advantage of the fact that the current
538 instruction address does not need to be returned to the cpu
539 object after every execution of an instruction. Instead it only
540 needs to be saved when either A. the main loop exits or B. a
541 cpu-{halt,restart} call forces the loop to be re-entered. The
542 later functions always save the current cpu instruction
547 if (!setjmp(restart
)) {
548 cpu
*const processor
= system
->processors
[0];
549 unsigned_word cia
= cpu_get_program_counter(processor
);
552 if (event_queue_tick(system
->events
)) {
553 cpu_set_program_counter(processor
, cia
);
554 event_queue_process(system
->events
);
555 cia
= cpu_get_program_counter(processor
);
559 instruction_word
const instruction
560 = vm_instruction_map_read(cpu_instruction_map(processor
),
562 cia
= idecode_issue(processor
, instruction
, cia
);
564 } while (keep_running
== NULL
|| *keep_running
);
565 cpu_set_program_counter(processor
, cia
);
567 } while(keep_running
== NULL
|| *keep_running
);
572 #if (WITH_IDECODE_CACHE_SIZE && WITH_SMP == 0)
574 /* CASE 2: Instruction case but no SMP
576 Here, the additional complexity comes from there being two
577 different cache implementations. A simple function address cache
578 or a full cracked instruction cache */
582 if (!setjmp(restart
)) {
583 cpu
*const processor
= system
->processors
[0];
584 unsigned_word cia
= cpu_get_program_counter(processor
);
587 if (event_queue_tick(system
->events
)) {
588 cpu_set_program_counter(processor
, cia
);
589 event_queue_process(system
->events
);
590 cia
= cpu_get_program_counter(processor
);
593 idecode_cache
*const cache_entry
= cpu_icache_entry(processor
,
595 if (cache_entry
->address
== cia
) {
596 idecode_semantic
*const semantic
= cache_entry
->semantic
;
597 cia
= semantic(processor
, cache_entry
, cia
);
600 instruction_word
const instruction
601 = vm_instruction_map_read(cpu_instruction_map(processor
),
604 idecode_semantic
*const semantic
= idecode(processor
,
610 mon_event(mon_event_icache_miss
, processor
, cia
);
611 cache_entry
->address
= cia
;
612 cache_entry
->semantic
= semantic
;
613 cia
= semantic(processor
, cache_entry
, cia
);
616 } while (keep_running
== NULL
|| *keep_running
);
617 cpu_set_program_counter(processor
, cia
);
619 } while(keep_running
== NULL
|| *keep_running
);
624 #if (!WITH_IDECODE_CACHE_SIZE && WITH_SMP > 0)
626 /* CASE 3: No ICACHE but SMP
628 The complexity here comes from needing to correctly restart the
629 system when it is aborted. In particular if cpu0 requests a
630 restart, the next cpu is still cpu1. Cpu0 being restarted after
631 all the other CPU's and the event queue have been processed */
634 int first_cpu
= setjmp(restart
);
636 first_cpu
= system
->last_cpu
+ 1;
639 for (current_cpu
= first_cpu
, first_cpu
= 0;
640 current_cpu
< system
->nr_cpus
+ (WITH_EVENTS
? 1 : 0);
642 if (WITH_EVENTS
&& current_cpu
== system
->nr_cpus
) {
643 if (event_queue_tick(system
->events
))
644 event_queue_process(system
->events
);
647 cpu
*const processor
= system
->processors
[current_cpu
];
648 unsigned_word
const cia
= cpu_get_program_counter(processor
);
649 instruction_word instruction
=
650 vm_instruction_map_read(cpu_instruction_map(processor
),
653 cpu_set_program_counter(processor
,
654 idecode_issue(processor
, instruction
, cia
));
656 if (!(keep_running
== NULL
|| *keep_running
)) {
657 system
->last_cpu
= current_cpu
;
661 } while (keep_running
== NULL
|| *keep_running
);
665 #if (WITH_IDECODE_CACHE_SIZE && WITH_SMP > 0)
667 /* CASE 4: ICACHE and SMP ...
669 This time, everything goes wrong. Need to restart loops
670 correctly, need to save the program counter and finally need to
671 keep track of each processors current address! */
674 int first_cpu
= setjmp(restart
);
676 first_cpu
= system
->last_cpu
+ 1;
679 for (current_cpu
= first_cpu
, first_cpu
= 0;
680 current_cpu
< system
->nr_cpus
+ (WITH_EVENTS
? 1 : 0);
682 if (WITH_EVENTS
&& current_cpu
== system
->nr_cpus
) {
683 if (event_queue_tick(system
->events
))
684 event_queue_process(system
->events
);
687 cpu
*processor
= system
->processors
[current_cpu
];
688 unsigned_word
const cia
= cpu_get_program_counter(processor
);
689 idecode_cache
*cache_entry
= cpu_icache_entry(processor
, cia
);
690 if (cache_entry
->address
== cia
) {
691 idecode_semantic
*semantic
= cache_entry
->semantic
;
692 cpu_set_program_counter(processor
,
693 semantic(processor
, cache_entry
, cia
));
696 instruction_word instruction
=
697 vm_instruction_map_read(cpu_instruction_map(processor
),
700 idecode_semantic
*semantic
= idecode(processor
,
706 mon_event(mon_event_icache_miss
, system
->processors
[current_cpu
], cia
);
707 cache_entry
->address
= cia
;
708 cache_entry
->semantic
= semantic
;
709 cpu_set_program_counter(processor
,
710 semantic(processor
, cache_entry
, cia
));
713 if (!(keep_running
== NULL
|| *keep_running
))
716 } while (keep_running
== NULL
|| *keep_running
);
720 psim_clear_halt_and_restart(system
);
724 /* SIMULATE INSTRUCTIONS, various different ways of achieving the same
729 psim_step(psim
*system
)
731 volatile int keep_running
= 0;
732 run_until_stop(system
, &keep_running
);
737 psim_run(psim
*system
)
739 run_until_stop(system
, NULL
);
744 psim_run_until_stop(psim
*system
,
745 volatile int *keep_running
)
747 run_until_stop(system
, keep_running
);
752 /* storage manipulation functions */
756 psim_read_register(psim
*system
,
762 register_descriptions description
;
763 char cooked_buf
[sizeof(unsigned_8
)];
766 /* find our processor */
767 if (which_cpu
== MAX_NR_PROCESSORS
)
768 which_cpu
= system
->last_cpu
;
769 if (which_cpu
< 0 || which_cpu
>= system
->nr_cpus
)
770 error("psim_read_register() - invalid processor %d\n", which_cpu
);
771 processor
= system
->processors
[which_cpu
];
773 /* find the register description */
774 description
= register_description(reg
);
775 if (description
.type
== reg_invalid
)
776 error("psim_read_register() invalid register name `%s'\n", reg
);
778 /* get the cooked value */
779 switch (description
.type
) {
782 *(gpreg
*)cooked_buf
= cpu_registers(processor
)->gpr
[description
.index
];
786 *(spreg
*)cooked_buf
= cpu_registers(processor
)->spr
[description
.index
];
790 *(sreg
*)cooked_buf
= cpu_registers(processor
)->sr
[description
.index
];
794 *(fpreg
*)cooked_buf
= cpu_registers(processor
)->fpr
[description
.index
];
798 *(unsigned_word
*)cooked_buf
= cpu_get_program_counter(processor
);
802 *(creg
*)cooked_buf
= cpu_registers(processor
)->cr
;
806 *(msreg
*)cooked_buf
= cpu_registers(processor
)->msr
;
810 printf_filtered("psim_read_register(processor=0x%lx,buf=0x%lx,reg=%s) %s\n",
811 (unsigned long)processor
, (unsigned long)buf
, reg
,
812 "read of this register unimplemented");
817 /* the PSIM internal values are in host order. To fetch raw data,
818 they need to be converted into target order and then returned */
819 if (mode
== raw_transfer
) {
820 /* FIXME - assumes that all registers are simple integers */
821 switch (description
.size
) {
823 *(unsigned_1
*)buf
= H2T_1(*(unsigned_1
*)cooked_buf
);
826 *(unsigned_2
*)buf
= H2T_2(*(unsigned_2
*)cooked_buf
);
829 *(unsigned_4
*)buf
= H2T_4(*(unsigned_4
*)cooked_buf
);
832 *(unsigned_8
*)buf
= H2T_8(*(unsigned_8
*)cooked_buf
);
837 memcpy(buf
/*dest*/, cooked_buf
/*src*/, description
.size
);
846 psim_write_register(psim
*system
,
853 register_descriptions description
;
854 char cooked_buf
[sizeof(unsigned_8
)];
856 /* find our processor */
857 if (which_cpu
== MAX_NR_PROCESSORS
)
858 which_cpu
= system
->last_cpu
;
859 if (which_cpu
== -1) {
861 for (i
= 0; i
< system
->nr_cpus
; i
++)
862 psim_write_register(system
, i
, buf
, reg
, mode
);
865 else if (which_cpu
< 0 || which_cpu
>= system
->nr_cpus
) {
866 error("psim_read_register() - invalid processor %d\n", which_cpu
);
869 processor
= system
->processors
[which_cpu
];
871 /* find the description of the register */
872 description
= register_description(reg
);
873 if (description
.type
== reg_invalid
)
874 error("psim_write_register() invalid register name %s\n", reg
);
876 /* If the data is comming in raw (target order), need to cook it
877 into host order before putting it into PSIM's internal structures */
878 if (mode
== raw_transfer
) {
879 switch (description
.size
) {
881 *(unsigned_1
*)cooked_buf
= T2H_1(*(unsigned_1
*)buf
);
884 *(unsigned_2
*)cooked_buf
= T2H_2(*(unsigned_2
*)buf
);
887 *(unsigned_4
*)cooked_buf
= T2H_4(*(unsigned_4
*)buf
);
890 *(unsigned_8
*)cooked_buf
= T2H_8(*(unsigned_8
*)buf
);
895 memcpy(cooked_buf
/*dest*/, buf
/*src*/, description
.size
);
898 /* put the cooked value into the register */
899 switch (description
.type
) {
902 cpu_registers(processor
)->gpr
[description
.index
] = *(gpreg
*)cooked_buf
;
906 cpu_registers(processor
)->fpr
[description
.index
] = *(fpreg
*)cooked_buf
;
910 cpu_set_program_counter(processor
, *(unsigned_word
*)cooked_buf
);
914 cpu_registers(processor
)->spr
[description
.index
] = *(spreg
*)cooked_buf
;
918 cpu_registers(processor
)->sr
[description
.index
] = *(sreg
*)cooked_buf
;
922 cpu_registers(processor
)->cr
= *(creg
*)cooked_buf
;
926 cpu_registers(processor
)->msr
= *(msreg
*)cooked_buf
;
930 printf_filtered("psim_write_register(processor=0x%lx,cooked_buf=0x%lx,reg=%s) %s\n",
931 (unsigned long)processor
, (unsigned long)cooked_buf
, reg
,
932 "read of this register unimplemented");
943 psim_read_memory(psim
*system
,
950 if (which_cpu
== MAX_NR_PROCESSORS
)
951 which_cpu
= system
->last_cpu
;
952 if (which_cpu
< 0 || which_cpu
>= system
->nr_cpus
)
953 error("psim_read_memory() invalid cpu\n");
954 processor
= system
->processors
[which_cpu
];
955 return vm_data_map_read_buffer(cpu_data_map(processor
),
956 buffer
, vaddr
, nr_bytes
);
962 psim_write_memory(psim
*system
,
967 int violate_read_only_section
)
970 if (which_cpu
== MAX_NR_PROCESSORS
)
971 which_cpu
= system
->last_cpu
;
972 if (which_cpu
< 0 || which_cpu
>= system
->nr_cpus
)
973 error("psim_read_memory() invalid cpu\n");
974 processor
= system
->processors
[which_cpu
];
975 return vm_data_map_write_buffer(cpu_data_map(processor
),
976 buffer
, vaddr
, nr_bytes
, 1);
982 psim_print_info(psim
*system
,
985 mon_print_info(system
, system
->monitor
, verbose
);
989 /* Merge a device tree and a device file. */
993 psim_merge_device_file(device
*root
,
994 const char *file_name
)
996 FILE *description
= fopen(file_name
, "r");
998 char device_path
[1000];
999 device
*current
= root
;
1000 while (fgets(device_path
, sizeof(device_path
), description
)) {
1001 /* check all of line was read */
1002 if (strchr(device_path
, '\n') == NULL
) {
1003 fclose(description
);
1004 error("create_filed_device_tree() line %d to long: %s\n",
1005 line_nr
, device_path
);
1008 /* parse this line */
1009 current
= device_tree_add_parsed(current
, "%s", device_path
);
1011 fclose(description
);
1015 #endif /* _PSIM_C_ */