1 1.1 christos /* This file is part of the program psim. 2 1.1 christos 3 1.1 christos Copyright (C) 1994-1996, Andrew Cagney <cagney (at) highland.com.au> 4 1.1 christos 5 1.1 christos This program is free software; you can redistribute it and/or modify 6 1.1 christos it under the terms of the GNU General Public License as published by 7 1.1 christos the Free Software Foundation; either version 3 of the License, or 8 1.1 christos (at your option) any later version. 9 1.1 christos 10 1.1 christos This program is distributed in the hope that it will be useful, 11 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 12 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 1.1 christos GNU General Public License for more details. 14 1.1 christos 15 1.1 christos You should have received a copy of the GNU General Public License 16 1.1 christos along with this program; if not, see <http://www.gnu.org/licenses/>. 17 1.1 christos 18 1.1 christos */ 19 1.1 christos 20 1.1 christos 21 1.1 christos #ifndef _OS_EMUL_C_ 22 1.1 christos #define _OS_EMUL_C_ 23 1.1 christos 24 1.1 christos #include "cpu.h" 25 1.1 christos #include "idecode.h" 26 1.1 christos #include "os_emul.h" 27 1.1 christos 28 1.1 christos #include "emul_generic.h" 29 1.1 christos #include "emul_netbsd.h" 30 1.1 christos #include "emul_unix.h" 31 1.1 christos #include "emul_chirp.h" 32 1.1 christos #include "emul_bugapi.h" 33 1.1 christos 34 1.1 christos static const os_emul *(os_emulations[]) = { 35 1.1 christos &emul_chirp, 36 1.1 christos &emul_bugapi, 37 1.1 christos &emul_netbsd, 38 1.1 christos &emul_solaris, 39 1.1 christos &emul_linux, 40 1.1 christos 0 41 1.1 christos }; 42 1.1 christos 43 1.1 christos 44 1.1 christos INLINE_OS_EMUL\ 45 1.1 christos (os_emul *) 46 1.1 christos os_emul_create(const char *file_name, 47 1.1 christos device *root) 48 1.1 christos { 49 1.1 christos const char *emulation_name = NULL; 50 1.1 christos bfd *image; 51 1.1 christos os_emul *chosen_emulation = NULL; 52 1.1 christos 53 1.1 christos bfd_init(); /* would never hurt */ 54 1.1 christos 55 1.1 christos /* open the file */ 56 1.1 christos image = bfd_openr(file_name, NULL); 57 1.1 christos if (image == NULL) { 58 1.1 christos bfd_perror(file_name); 59 1.1 christos error("nothing loaded\n"); 60 1.1 christos } 61 1.1 christos 62 1.1 christos /* check it is an executable */ 63 1.1 christos if (!bfd_check_format(image, bfd_object)) { 64 1.1 christos TRACE(trace_tbd, 65 1.1 christos ("FIXME - should check more than just bfd_check_format\n")); 66 1.1 christos TRACE(trace_os_emul, 67 1.1 christos ("%s not an executable, assumeing a device file\n", file_name)); 68 1.1 christos bfd_close(image); 69 1.1 christos image = NULL; 70 1.1 christos } 71 1.1 christos 72 1.1 christos /* if a device file, load that before trying the emulations on */ 73 1.1 christos if (image == NULL) { 74 1.1 christos psim_merge_device_file(root, file_name); 75 1.1 christos } 76 1.1 christos 77 1.1 christos /* see if the device tree already specifies the required emulation */ 78 1.1 christos if (tree_find_property(root, "/openprom/options/os-emul") != NULL) 79 1.1 christos emulation_name = 80 1.1 christos tree_find_string_property(root, "/openprom/options/os-emul"); 81 1.1 christos else 82 1.1 christos emulation_name = NULL; 83 1.1 christos 84 1.1 christos /* go through each emulation to see if they reconize it. FIXME - 85 1.1 christos should have some sort of imported table from a separate file */ 86 1.1 christos { 87 1.1 christos os_emul_data *emul_data; 88 1.1 christos const os_emul **possible_emulation; 89 1.1 christos chosen_emulation = NULL; 90 1.1 christos for (possible_emulation = os_emulations, emul_data = NULL; 91 1.1 christos *possible_emulation != NULL && emul_data == NULL; 92 1.1 christos possible_emulation++) { 93 1.1 christos emul_data = (*possible_emulation)->create(root, 94 1.1 christos image, 95 1.1 christos emulation_name); 96 1.1 christos if (emul_data != NULL) { 97 1.1 christos chosen_emulation = ZALLOC(os_emul); 98 1.1 christos *chosen_emulation = **possible_emulation; 99 1.1 christos chosen_emulation->data = emul_data; 100 1.1 christos } 101 1.1 christos } 102 1.1 christos } 103 1.1 christos 104 1.1 christos /* clean up */ 105 1.1 christos if (image != NULL) 106 1.1 christos bfd_close(image); 107 1.1 christos return chosen_emulation; 108 1.1 christos } 109 1.1 christos 110 1.1 christos INLINE_OS_EMUL\ 111 1.1 christos (void) 112 1.1 christos os_emul_init(os_emul *emulation, 113 1.1 christos int nr_cpus) 114 1.1 christos { 115 1.1 christos if (emulation != (os_emul*)0) 116 1.1 christos emulation->init(emulation->data, nr_cpus); 117 1.1 christos } 118 1.1 christos 119 1.1 christos INLINE_OS_EMUL\ 120 1.1 christos (void) 121 1.1 christos os_emul_system_call(cpu *processor, 122 1.1 christos unsigned_word cia) 123 1.1 christos { 124 1.1 christos os_emul *emulation = cpu_os_emulation(processor); 125 1.1 christos if (emulation != (os_emul*)0 && emulation->system_call != 0) 126 1.1 christos emulation->system_call(processor, cia, emulation->data); 127 1.1 christos else 128 1.1 christos error("System call emulation not available\n"); 129 1.1 christos } 130 1.1 christos 131 1.1 christos INLINE_OS_EMUL\ 132 1.1 christos (int) 133 1.1 christos os_emul_instruction_call(cpu *processor, 134 1.1 christos unsigned_word cia, 135 1.1 christos unsigned_word ra) 136 1.1 christos { 137 1.1 christos os_emul *emulation = cpu_os_emulation(processor); 138 1.1 christos if (emulation != (os_emul*)0 && emulation->instruction_call != 0) 139 1.1 christos return emulation->instruction_call(processor, cia, ra, emulation->data); 140 1.1 christos else 141 1.1 christos return 0; 142 1.1 christos } 143 1.1 christos 144 1.1 christos 145 1.1 christos #endif /* _OS_EMUL_C_ */ 146