Home | History | Annotate | Line # | Download | only in ppc
      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