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