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