#ifndef _OS_EMUL_C_
#define _OS_EMUL_C_
#include "cpu.h"
#include "idecode.h"
#include "os_emul.h"
#include "emul_generic.h"
#include "emul_netbsd.h"
#include "emul_unix.h"
#include "emul_chirp.h"
#include "emul_bugapi.h"
static const os_emul *(os_emulations[]) = {
&emul_chirp,
&emul_bugapi,
&emul_netbsd,
&emul_solaris,
&emul_linux,
0
};
INLINE_OS_EMUL\
(os_emul *)
os_emul_create(const char *file_name,
device *root)
{
const char *emulation_name = NULL;
bfd *image;
os_emul *chosen_emulation = NULL;
bfd_init();
image = bfd_openr(file_name, NULL);
if (image == NULL) {
bfd_perror(file_name);
error("nothing loaded\n");
}
if (!bfd_check_format(image, bfd_object)) {
TRACE(trace_tbd,
("FIXME - should check more than just bfd_check_format\n"));
TRACE(trace_os_emul,
("%s not an executable, assumeing a device file\n", file_name));
bfd_close(image);
image = NULL;
}
if (image == NULL) {
psim_merge_device_file(root, file_name);
}
if (tree_find_property(root, "/openprom/options/os-emul") != NULL)
emulation_name =
tree_find_string_property(root, "/openprom/options/os-emul");
else
emulation_name = NULL;
{
os_emul_data *emul_data;
const os_emul **possible_emulation;
chosen_emulation = NULL;
for (possible_emulation = os_emulations, emul_data = NULL;
*possible_emulation != NULL && emul_data == NULL;
possible_emulation++) {
emul_data = (*possible_emulation)->create(root,
image,
emulation_name);
if (emul_data != NULL) {
chosen_emulation = ZALLOC(os_emul);
*chosen_emulation = **possible_emulation;
chosen_emulation->data = emul_data;
}
}
}
if (image != NULL)
bfd_close(image);
return chosen_emulation;
}
INLINE_OS_EMUL\
(void)
os_emul_init(os_emul *emulation,
int nr_cpus)
{
if (emulation != (os_emul*)0)
emulation->init(emulation->data, nr_cpus);
}
INLINE_OS_EMUL\
(void)
os_emul_system_call(cpu *processor,
unsigned_word cia)
{
os_emul *emulation = cpu_os_emulation(processor);
if (emulation != (os_emul*)0 && emulation->system_call != 0)
emulation->system_call(processor, cia, emulation->data);
else
error("System call emulation not available\n");
}
INLINE_OS_EMUL\
(int)
os_emul_instruction_call(cpu *processor,
unsigned_word cia,
unsigned_word ra)
{
os_emul *emulation = cpu_os_emulation(processor);
if (emulation != (os_emul*)0 && emulation->instruction_call != 0)
return emulation->instruction_call(processor, cia, ra, emulation->data);
else
return 0;
}
#endif