123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- /* This file is part of the program psim.
- Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- */
- #ifndef _OS_EMUL_C_
- #define _OS_EMUL_C_
- #include "cpu.h"
- #include "idecode.h"
- #include "os_emul.h"
- #include "emul_generic.h"
- #include "emul_netbsd.h"
- #include "emul_unix.h"
- #include "emul_chirp.h"
- #include "emul_bugapi.h"
- static const os_emul *(os_emulations[]) = {
- &emul_chirp,
- &emul_bugapi,
- &emul_netbsd,
- &emul_solaris,
- &emul_linux,
- 0
- };
- INLINE_OS_EMUL\
- (os_emul *)
- os_emul_create(const char *file_name,
- device *root)
- {
- const char *emulation_name = NULL;
- bfd *image;
- os_emul *chosen_emulation = NULL;
- bfd_init(); /* would never hurt */
- /* open the file */
- image = bfd_openr(file_name, NULL);
- if (image == NULL) {
- bfd_perror(file_name);
- error("nothing loaded\n");
- }
- /* check it is an executable */
- if (!bfd_check_format(image, bfd_object)) {
- TRACE(trace_tbd,
- ("FIXME - should check more than just bfd_check_format\n"));
- TRACE(trace_os_emul,
- ("%s not an executable, assumeing a device file\n", file_name));
- bfd_close(image);
- image = NULL;
- }
- /* if a device file, load that before trying the emulations on */
- if (image == NULL) {
- psim_merge_device_file(root, file_name);
- }
- /* see if the device tree already specifies the required emulation */
- if (tree_find_property(root, "/openprom/options/os-emul") != NULL)
- emulation_name =
- tree_find_string_property(root, "/openprom/options/os-emul");
- else
- emulation_name = NULL;
- /* go through each emulation to see if they reconize it. FIXME -
- should have some sort of imported table from a separate file */
- {
- os_emul_data *emul_data;
- const os_emul **possible_emulation;
- chosen_emulation = NULL;
- for (possible_emulation = os_emulations, emul_data = NULL;
- *possible_emulation != NULL && emul_data == NULL;
- possible_emulation++) {
- emul_data = (*possible_emulation)->create(root,
- image,
- emulation_name);
- if (emul_data != NULL) {
- chosen_emulation = ZALLOC(os_emul);
- *chosen_emulation = **possible_emulation;
- chosen_emulation->data = emul_data;
- }
- }
- }
- /* clean up */
- if (image != NULL)
- bfd_close(image);
- return chosen_emulation;
- }
- INLINE_OS_EMUL\
- (void)
- os_emul_init(os_emul *emulation,
- int nr_cpus)
- {
- if (emulation != (os_emul*)0)
- emulation->init(emulation->data, nr_cpus);
- }
- INLINE_OS_EMUL\
- (void)
- os_emul_system_call(cpu *processor,
- unsigned_word cia)
- {
- os_emul *emulation = cpu_os_emulation(processor);
- if (emulation != (os_emul*)0 && emulation->system_call != 0)
- emulation->system_call(processor, cia, emulation->data);
- else
- error("System call emulation not available\n");
- }
- INLINE_OS_EMUL\
- (int)
- os_emul_instruction_call(cpu *processor,
- unsigned_word cia,
- unsigned_word ra)
- {
- os_emul *emulation = cpu_os_emulation(processor);
- if (emulation != (os_emul*)0 && emulation->instruction_call != 0)
- return emulation->instruction_call(processor, cia, ra, emulation->data);
- else
- return 0;
- }
- #endif /* _OS_EMUL_C_ */
|