os_emul.c revision 1.1 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