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 chirp - OEA + a few OpenBoot calls\n");
159 printf_filtered("\n"); }
160 printf_filtered("\t-i Print instruction counting statistics\n");
161 if (verbose
) { printf_filtered("\n"); }
162 printf_filtered("\t-I Print execution unit statistics\n");
163 if (verbose
) { printf_filtered("\n"); }
164 printf_filtered("\t-r <size> Set RAM size in bytes (OEA environments)\n");
165 if (verbose
) { printf_filtered("\n"); }
166 printf_filtered("\t-t [!]<trace> Enable (disable) <trace> option\n");
167 if (verbose
) { printf_filtered("\n"); }
168 printf_filtered("\t-o <spec> add device <spec> to the device tree\n");
169 if (verbose
) { printf_filtered("\n"); }
170 printf_filtered("\t-h -? -H give more detailed usage\n");
171 if (verbose
) { printf_filtered("\n"); }
172 printf_filtered("\n");
173 trace_usage(verbose
);
174 device_usage(verbose
);
176 printf_filtered("\n");
184 psim_options(device
*root
,
187 device
*current
= root
;
192 while (argv
[argp
] != NULL
&& argv
[argp
][0] == '-') {
193 char *p
= argv
[argp
] + 1;
202 param
= find_arg("Missing <emul> option for -e\n", &argp
, argv
);
203 device_tree_add_parsed(root
, "/openprom/options/os-emul %s", param
);
213 device_tree_add_parsed(root
, "/openprom/trace/print-info 1");
216 device_tree_add_parsed(root
, "/openprom/trace/print-info 2");
217 device_tree_add_parsed(root
, "/openprom/options/model-issue %d",
218 MODEL_ISSUE_PROCESS
);
221 param
= find_arg("Missing <model> option for -m\n", &argp
, argv
);
222 device_tree_add_parsed(root
, "/openprom/options/model \"%s", param
);
225 param
= find_arg("Missing <device> option for -o\n", &argp
, argv
);
226 current
= device_tree_add_parsed(current
, "%s", param
);
229 param
= find_arg("Missing <ram-size> option for -r\n", &argp
, argv
);
230 device_tree_add_parsed(root
, "/openprom/options/oea-memory-size 0x%lx",
234 param
= find_arg("Missing <trace> option for -t\n", &argp
, argv
);
236 device_tree_add_parsed(root
, "/openprom/trace/%s 0", param
+1);
238 device_tree_add_parsed(root
, "/openprom/trace/%s 1", param
);
245 /* force the trace node to (re)process its options */
246 device_init_data(device_tree_find_device(root
, "/openprom/trace"), NULL
);
247 /* return where the options end */
252 /* create the simulator proper from the device tree and executable */
256 psim_create(const char *file_name
,
262 os_emul
*os_emulation
;
265 /* given this partially populated device tree, os_emul_create() uses
266 it and file_name to determine the selected emulation and hence
267 further populate the tree with any other required nodes. */
269 os_emulation
= os_emul_create(file_name
, root
);
270 if (os_emulation
== NULL
)
271 error("psim: either file %s was not reconized or unreconized or unknown os-emulation type\n", file_name
);
273 /* fill in the missing real number of CPU's */
274 nr_cpus
= device_find_integer_property(root
, "/openprom/options/smp");
275 if (MAX_NR_PROCESSORS
< nr_cpus
)
276 error("target and configured number of cpus conflict\n");
278 /* fill in the missing TARGET BYTE ORDER information */
279 current_target_byte_order
280 = (device_find_boolean_property(root
, "/options/little-endian?")
283 if (CURRENT_TARGET_BYTE_ORDER
!= current_target_byte_order
)
284 error("target and configured byte order conflict\n");
286 /* fill in the missing HOST BYTE ORDER information */
287 current_host_byte_order
= (current_host_byte_order
= 1,
288 (*(char*)(¤t_host_byte_order
)
291 if (CURRENT_HOST_BYTE_ORDER
!= current_host_byte_order
)
292 error("host and configured byte order conflict\n");
294 /* fill in the missing OEA/VEA information */
295 env
= device_find_string_property(root
, "/openprom/options/env");
296 current_environment
= ((strcmp(env
, "user") == 0
297 || strcmp(env
, "uea") == 0)
299 : (strcmp(env
, "virtual") == 0
300 || strcmp(env
, "vea") == 0)
301 ? VIRTUAL_ENVIRONMENT
302 : (strcmp(env
, "operating") == 0
303 || strcmp(env
, "oea") == 0)
304 ? OPERATING_ENVIRONMENT
306 if (current_environment
== 0)
307 error("unreconized /options env property\n");
308 if (CURRENT_ENVIRONMENT
!= current_environment
)
309 error("target and configured environment conflict\n");
311 /* fill in the missing ALLIGNMENT information */
313 = (device_find_boolean_property(root
, "/openprom/options/strict-alignment?")
315 : NONSTRICT_ALIGNMENT
);
316 if (CURRENT_ALIGNMENT
!= current_alignment
)
317 error("target and configured alignment conflict\n");
319 /* fill in the missing FLOATING POINT information */
320 current_floating_point
321 = (device_find_boolean_property(root
, "/openprom/options/floating-point?")
322 ? HARD_FLOATING_POINT
323 : SOFT_FLOATING_POINT
);
324 if (CURRENT_FLOATING_POINT
!= current_floating_point
)
325 error("target and configured floating-point conflict\n");
327 /* sort out the level of detail for issue modeling */
329 = device_find_integer_property(root
, "/openprom/options/model-issue");
330 if (CURRENT_MODEL_ISSUE
!= current_model_issue
)
331 error("target and configured model-issue conflict\n");
333 /* sort out our model architecture - wrong.
335 FIXME: this should be obtaining the required information from the
336 device tree via the "/chosen" property "cpu" which is an instance
337 (ihandle) for the only executing processor. By converting that
338 ihandle into the corresponding cpu's phandle and then querying
339 the "name" property, the cpu type can be determined. Ok? */
341 model_set(device_find_string_property(root
, "/openprom/options/model"));
344 system
= ZALLOC(psim
);
345 system
->events
= event_queue_create();
346 system
->memory
= core_create(root
);
347 system
->monitor
= mon_create();
348 system
->nr_cpus
= nr_cpus
;
349 system
->os_emulation
= os_emulation
;
350 system
->devices
= root
;
352 /* now all the processors attaching to each their per-cpu information */
353 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++) {
354 system
->processors
[cpu_nr
] = cpu_create(system
,
357 mon_cpu(system
->monitor
,
359 system
->os_emulation
,
363 /* dump out the contents of the device tree */
364 if (ppc_trace
[trace_print_device_tree
] || ppc_trace
[trace_dump_device_tree
])
365 device_tree_traverse(root
, device_tree_print_device
, NULL
, NULL
);
366 if (ppc_trace
[trace_dump_device_tree
])
373 /* allow the simulation to stop/restart abnormaly */
377 psim_set_halt_and_restart(psim
*system
,
379 void *restart_jmp_buf
)
381 system
->path_to_halt
= halt_jmp_buf
;
382 system
->path_to_restart
= restart_jmp_buf
;
387 psim_clear_halt_and_restart(psim
*system
)
389 system
->path_to_halt
= NULL
;
390 system
->path_to_restart
= NULL
;
395 psim_restart(psim
*system
,
398 system
->last_cpu
= current_cpu
;
399 longjmp(*(jmp_buf*)(system
->path_to_restart
), current_cpu
+ 1);
405 psim_halt(psim
*system
,
411 system
->last_cpu
= current_cpu
;
412 system
->halt_status
.cpu_nr
= current_cpu
;
413 system
->halt_status
.reason
= reason
;
414 system
->halt_status
.signal
= signal
;
415 system
->halt_status
.program_counter
= cia
;
416 longjmp(*(jmp_buf*)(system
->path_to_halt
), current_cpu
+ 1);
421 psim_get_status(psim
*system
)
423 return system
->halt_status
;
429 psim_cpu(psim
*system
,
432 if (cpu_nr
< 0 || cpu_nr
>= system
->nr_cpus
)
435 return system
->processors
[cpu_nr
];
441 psim_device(psim
*system
,
444 return device_tree_find_device(system
->devices
, path
);
451 psim_init(psim
*system
)
455 /* scrub the monitor */
456 mon_init(system
->monitor
, system
->nr_cpus
);
457 os_emul_init(system
->os_emulation
, system
->nr_cpus
);
458 event_queue_init(system
->events
);
460 /* scrub all the cpus */
461 for (cpu_nr
= 0; cpu_nr
< system
->nr_cpus
; cpu_nr
++)
462 cpu_init(system
->processors
[cpu_nr
]);
464 /* init all the devices (which updates the cpus) */
465 device_tree_init(system
->devices
, system
);
467 /* now sync each cpu against the initialized state of its registers */
468 for (cpu_nr
= 0; cpu_nr
< system
->nr_cpus
; cpu_nr
++) {
469 cpu_synchronize_context(system
->processors
[cpu_nr
]);
470 cpu_page_tlb_invalidate_all(system
->processors
[cpu_nr
]);
473 /* force loop to restart */
474 system
->last_cpu
= system
->nr_cpus
- 1;
479 psim_stack(psim
*system
,
483 /* pass the stack device the argv/envp and let it work out what to
485 device
*stack_device
= device_tree_find_device(system
->devices
,
486 "/openprom/init/stack");
487 if (stack_device
!= (device
*)0) {
488 unsigned_word stack_pointer
;
489 psim_read_register(system
, 0, &stack_pointer
, "sp", cooked_transfer
);
490 device_ioctl(stack_device
,
502 /* EXECUTE REAL CODE:
504 Unfortunatly, there are multiple cases to consider vis:
506 <icache> X <smp> X <events> X <keep-running-flag> X ...
508 Consequently this function is written in multiple different ways */
512 run_until_stop(psim
*system
,
513 volatile int *keep_running
)
517 #if WITH_IDECODE_CACHE_SIZE
519 for (cpu_nr
= 0; cpu_nr
< system
->nr_cpus
; cpu_nr
++)
520 cpu_flush_icache(system
->processors
[cpu_nr
]);
522 psim_set_halt_and_restart(system
, &halt
, &restart
);
524 #if (!WITH_IDECODE_CACHE_SIZE && WITH_SMP == 0)
526 /* CASE 1: No instruction cache and no SMP.
528 In this case, we can take advantage of the fact that the current
529 instruction address does not need to be returned to the cpu
530 object after every execution of an instruction. Instead it only
531 needs to be saved when either A. the main loop exits or B. a
532 cpu-{halt,restart} call forces the loop to be re-entered. The
533 later functions always save the current cpu instruction
538 if (!setjmp(restart
)) {
539 cpu
*const processor
= system
->processors
[0];
540 unsigned_word cia
= cpu_get_program_counter(processor
);
543 if (event_queue_tick(system
->events
)) {
544 cpu_set_program_counter(processor
, cia
);
545 event_queue_process(system
->events
);
546 cia
= cpu_get_program_counter(processor
);
550 instruction_word
const instruction
551 = vm_instruction_map_read(cpu_instruction_map(processor
),
553 cia
= idecode_issue(processor
, instruction
, cia
);
555 } while (keep_running
== NULL
|| *keep_running
);
556 cpu_set_program_counter(processor
, cia
);
558 } while(keep_running
== NULL
|| *keep_running
);
563 #if (WITH_IDECODE_CACHE_SIZE && WITH_SMP == 0)
565 /* CASE 2: Instruction case but no SMP
567 Here, the additional complexity comes from there being two
568 different cache implementations. A simple function address cache
569 or a full cracked instruction cache */
573 if (!setjmp(restart
)) {
574 cpu
*const processor
= system
->processors
[0];
575 unsigned_word cia
= cpu_get_program_counter(processor
);
578 if (event_queue_tick(system
->events
)) {
579 cpu_set_program_counter(processor
, cia
);
580 event_queue_process(system
->events
);
581 cia
= cpu_get_program_counter(processor
);
584 idecode_cache
*const cache_entry
= cpu_icache_entry(processor
,
586 if (cache_entry
->address
== cia
) {
587 idecode_semantic
*const semantic
= cache_entry
->semantic
;
588 cia
= semantic(processor
, cache_entry
, cia
);
591 instruction_word
const instruction
592 = vm_instruction_map_read(cpu_instruction_map(processor
),
595 idecode_semantic
*const semantic
= idecode(processor
,
601 mon_event(mon_event_icache_miss
, processor
, cia
);
602 cache_entry
->address
= cia
;
603 cache_entry
->semantic
= semantic
;
604 cia
= semantic(processor
, cache_entry
, cia
);
607 } while (keep_running
== NULL
|| *keep_running
);
608 cpu_set_program_counter(processor
, cia
);
610 } while(keep_running
== NULL
|| *keep_running
);
615 #if (!WITH_IDECODE_CACHE_SIZE && WITH_SMP > 0)
617 /* CASE 3: No ICACHE but SMP
619 The complexity here comes from needing to correctly restart the
620 system when it is aborted. In particular if cpu0 requests a
621 restart, the next cpu is still cpu1. Cpu0 being restarted after
622 all the other CPU's and the event queue have been processed */
625 int first_cpu
= setjmp(restart
);
627 first_cpu
= system
->last_cpu
+ 1;
630 for (current_cpu
= first_cpu
, first_cpu
= 0;
631 current_cpu
< system
->nr_cpus
+ (WITH_EVENTS
? 1 : 0);
633 if (WITH_EVENTS
&& current_cpu
== system
->nr_cpus
) {
634 if (event_queue_tick(system
->events
))
635 event_queue_process(system
->events
);
638 cpu
*const processor
= system
->processors
[current_cpu
];
639 unsigned_word
const cia
= cpu_get_program_counter(processor
);
640 instruction_word instruction
=
641 vm_instruction_map_read(cpu_instruction_map(processor
),
644 cpu_set_program_counter(processor
,
645 idecode_issue(processor
, instruction
, cia
));
647 if (!(keep_running
== NULL
|| *keep_running
)) {
648 system
->last_cpu
= current_cpu
;
652 } while (keep_running
== NULL
|| *keep_running
);
656 #if (WITH_IDECODE_CACHE_SIZE && WITH_SMP > 0)
658 /* CASE 4: ICACHE and SMP ...
660 This time, everything goes wrong. Need to restart loops
661 correctly, need to save the program counter and finally need to
662 keep track of each processors current address! */
665 int first_cpu
= setjmp(restart
);
667 first_cpu
= system
->last_cpu
+ 1;
670 for (current_cpu
= first_cpu
, first_cpu
= 0;
671 current_cpu
< system
->nr_cpus
+ (WITH_EVENTS
? 1 : 0);
673 if (WITH_EVENTS
&& current_cpu
== system
->nr_cpus
) {
674 if (event_queue_tick(system
->events
))
675 event_queue_process(system
->events
);
678 cpu
*processor
= system
->processors
[current_cpu
];
679 unsigned_word
const cia
= cpu_get_program_counter(processor
);
680 idecode_cache
*cache_entry
= cpu_icache_entry(processor
, cia
);
681 if (cache_entry
->address
== cia
) {
682 idecode_semantic
*semantic
= cache_entry
->semantic
;
683 cpu_set_program_counter(processor
,
684 semantic(processor
, cache_entry
, cia
));
687 instruction_word instruction
=
688 vm_instruction_map_read(cpu_instruction_map(processor
),
691 idecode_semantic
*semantic
= idecode(processor
,
697 mon_event(mon_event_icache_miss
, system
->processors
[current_cpu
], cia
);
698 cache_entry
->address
= cia
;
699 cache_entry
->semantic
= semantic
;
700 cpu_set_program_counter(processor
,
701 semantic(processor
, cache_entry
, cia
));
704 if (!(keep_running
== NULL
|| *keep_running
))
707 } while (keep_running
== NULL
|| *keep_running
);
711 psim_clear_halt_and_restart(system
);
715 /* SIMULATE INSTRUCTIONS, various different ways of achieving the same
720 psim_step(psim
*system
)
722 volatile int keep_running
= 0;
723 run_until_stop(system
, &keep_running
);
728 psim_run(psim
*system
)
730 run_until_stop(system
, NULL
);
735 psim_run_until_stop(psim
*system
,
736 volatile int *keep_running
)
738 run_until_stop(system
, keep_running
);
743 /* storage manipulation functions */
747 psim_read_register(psim
*system
,
753 register_descriptions description
;
754 char cooked_buf
[sizeof(unsigned_8
)];
757 /* find our processor */
758 if (which_cpu
== MAX_NR_PROCESSORS
)
759 which_cpu
= system
->last_cpu
;
760 if (which_cpu
< 0 || which_cpu
>= system
->nr_cpus
)
761 error("psim_read_register() - invalid processor %d\n", which_cpu
);
762 processor
= system
->processors
[which_cpu
];
764 /* find the register description */
765 description
= register_description(reg
);
766 if (description
.type
== reg_invalid
)
767 error("psim_read_register() invalid register name `%s'\n", reg
);
769 /* get the cooked value */
770 switch (description
.type
) {
773 *(gpreg
*)cooked_buf
= cpu_registers(processor
)->gpr
[description
.index
];
777 *(spreg
*)cooked_buf
= cpu_registers(processor
)->spr
[description
.index
];
781 *(sreg
*)cooked_buf
= cpu_registers(processor
)->sr
[description
.index
];
785 *(fpreg
*)cooked_buf
= cpu_registers(processor
)->fpr
[description
.index
];
789 *(unsigned_word
*)cooked_buf
= cpu_get_program_counter(processor
);
793 *(creg
*)cooked_buf
= cpu_registers(processor
)->cr
;
797 *(msreg
*)cooked_buf
= cpu_registers(processor
)->msr
;
801 printf_filtered("psim_read_register(processor=0x%lx,buf=0x%lx,reg=%s) %s\n",
802 (unsigned long)processor
, (unsigned long)buf
, reg
,
803 "read of this register unimplemented");
808 /* the PSIM internal values are in host order. To fetch raw data,
809 they need to be converted into target order and then returned */
810 if (mode
== raw_transfer
) {
811 /* FIXME - assumes that all registers are simple integers */
812 switch (description
.size
) {
814 *(unsigned_1
*)buf
= H2T_1(*(unsigned_1
*)cooked_buf
);
817 *(unsigned_2
*)buf
= H2T_2(*(unsigned_2
*)cooked_buf
);
820 *(unsigned_4
*)buf
= H2T_4(*(unsigned_4
*)cooked_buf
);
823 *(unsigned_8
*)buf
= H2T_8(*(unsigned_8
*)cooked_buf
);
828 memcpy(buf
/*dest*/, cooked_buf
/*src*/, description
.size
);
837 psim_write_register(psim
*system
,
844 register_descriptions description
;
845 char cooked_buf
[sizeof(unsigned_8
)];
847 /* find our processor */
848 if (which_cpu
== MAX_NR_PROCESSORS
)
849 which_cpu
= system
->last_cpu
;
850 if (which_cpu
== -1) {
852 for (i
= 0; i
< system
->nr_cpus
; i
++)
853 psim_write_register(system
, i
, buf
, reg
, mode
);
856 else if (which_cpu
< 0 || which_cpu
>= system
->nr_cpus
) {
857 error("psim_read_register() - invalid processor %d\n", which_cpu
);
860 processor
= system
->processors
[which_cpu
];
862 /* find the description of the register */
863 description
= register_description(reg
);
864 if (description
.type
== reg_invalid
)
865 error("psim_write_register() invalid register name %s\n", reg
);
867 /* If the data is comming in raw (target order), need to cook it
868 into host order before putting it into PSIM's internal structures */
869 if (mode
== raw_transfer
) {
870 switch (description
.size
) {
872 *(unsigned_1
*)cooked_buf
= T2H_1(*(unsigned_1
*)buf
);
875 *(unsigned_2
*)cooked_buf
= T2H_2(*(unsigned_2
*)buf
);
878 *(unsigned_4
*)cooked_buf
= T2H_4(*(unsigned_4
*)buf
);
881 *(unsigned_8
*)cooked_buf
= T2H_8(*(unsigned_8
*)buf
);
886 memcpy(cooked_buf
/*dest*/, buf
/*src*/, description
.size
);
889 /* put the cooked value into the register */
890 switch (description
.type
) {
893 cpu_registers(processor
)->gpr
[description
.index
] = *(gpreg
*)cooked_buf
;
897 cpu_registers(processor
)->fpr
[description
.index
] = *(fpreg
*)cooked_buf
;
901 cpu_set_program_counter(processor
, *(unsigned_word
*)cooked_buf
);
905 cpu_registers(processor
)->spr
[description
.index
] = *(spreg
*)cooked_buf
;
909 cpu_registers(processor
)->sr
[description
.index
] = *(sreg
*)cooked_buf
;
913 cpu_registers(processor
)->cr
= *(creg
*)cooked_buf
;
917 cpu_registers(processor
)->msr
= *(msreg
*)cooked_buf
;
921 printf_filtered("psim_write_register(processor=0x%lx,cooked_buf=0x%lx,reg=%s) %s\n",
922 (unsigned long)processor
, (unsigned long)cooked_buf
, reg
,
923 "read of this register unimplemented");
934 psim_read_memory(psim
*system
,
941 if (which_cpu
== MAX_NR_PROCESSORS
)
942 which_cpu
= system
->last_cpu
;
943 if (which_cpu
< 0 || which_cpu
>= system
->nr_cpus
)
944 error("psim_read_memory() invalid cpu\n");
945 processor
= system
->processors
[which_cpu
];
946 return vm_data_map_read_buffer(cpu_data_map(processor
),
947 buffer
, vaddr
, nr_bytes
);
953 psim_write_memory(psim
*system
,
958 int violate_read_only_section
)
961 if (which_cpu
== MAX_NR_PROCESSORS
)
962 which_cpu
= system
->last_cpu
;
963 if (which_cpu
< 0 || which_cpu
>= system
->nr_cpus
)
964 error("psim_read_memory() invalid cpu\n");
965 processor
= system
->processors
[which_cpu
];
966 return vm_data_map_write_buffer(cpu_data_map(processor
),
967 buffer
, vaddr
, nr_bytes
, 1);
973 psim_print_info(psim
*system
,
976 mon_print_info(system
, system
->monitor
, verbose
);
980 /* Merge a device tree and a device file. */
984 psim_merge_device_file(device
*root
,
985 const char *file_name
)
987 FILE *description
= fopen(file_name
, "r");
989 char device_path
[1000];
990 device
*current
= root
;
991 while (fgets(device_path
, sizeof(device_path
), description
)) {
992 /* check all of line was read */
993 if (strchr(device_path
, '\n') == NULL
) {
995 error("create_filed_device_tree() line %d to long: %s\n",
996 line_nr
, device_path
);
999 /* parse this line */
1000 current
= device_tree_add_parsed(current
, "%s", device_path
);
1002 fclose(description
);
1006 #endif /* _PSIM_C_ */