Home | History | Annotate | Line # | Download | only in ppc
os_emul.c revision 1.1
      1 /*  This file is part of the program psim.
      2 
      3     Copyright (C) 1994-1996, Andrew Cagney <cagney (at) 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