#include "sysemu.h"
#include "boards.h"
#include "mips-bios.h"
-
-#ifdef TARGET_MIPS64
-#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
-#else
-#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffU)
-#endif
-
-#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
+#include "loader.h"
+#include "elf.h"
static struct _loaderparams {
int ram_size;
const char *initrd_filename;
} loaderparams;
-static void load_kernel (CPUState *env)
+typedef struct ResetData {
+ CPUState *env;
+ uint64_t vector;
+} ResetData;
+
+static int64_t load_kernel(void)
{
- int64_t entry, kernel_low, kernel_high;
+ int64_t entry, kernel_high;
long kernel_size;
long initrd_size;
ram_addr_t initrd_offset;
+ int big_endian;
+
+#ifdef TARGET_WORDS_BIGENDIAN
+ big_endian = 1;
+#else
+ big_endian = 0;
+#endif
- kernel_size = load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND,
- (uint64_t *)&entry, (uint64_t *)&kernel_low,
- (uint64_t *)&kernel_high);
+ kernel_size = load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys,
+ NULL, (uint64_t *)&entry, NULL,
+ (uint64_t *)&kernel_high, big_endian,
+ ELF_MACHINE, 1);
if (kernel_size >= 0) {
if ((entry & ~0x7fffffffULL) == 0x80000000)
entry = (int32_t)entry;
- env->active_tc.PC = entry;
} else {
fprintf(stderr, "qemu: could not load kernel '%s'\n",
loaderparams.kernel_filename);
exit(1);
}
}
+ return entry;
}
static void main_cpu_reset(void *opaque)
{
- CPUState *env = opaque;
- cpu_reset(env);
+ ResetData *s = (ResetData *)opaque;
+ CPUState *env = s->env;
- if (loaderparams.kernel_filename)
- load_kernel (env);
+ cpu_reset(env);
+ env->active_tc.PC = s->vector;
}
static void
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
{
- char buf[1024];
+ char *filename;
ram_addr_t ram_offset;
ram_addr_t bios_offset;
CPUState *env;
+ ResetData *reset_info;
int bios_size;
/* Init CPUs. */
fprintf(stderr, "Unable to find CPU definition\n");
exit(1);
}
- qemu_register_reset(main_cpu_reset, env);
+ reset_info = qemu_mallocz(sizeof(ResetData));
+ reset_info->env = env;
+ reset_info->vector = env->active_tc.PC;
+ qemu_register_reset(main_cpu_reset, reset_info);
/* Allocate RAM. */
ram_offset = qemu_ram_alloc(ram_size);
/* Load a BIOS / boot exception handler image. */
if (bios_name == NULL)
bios_name = BIOS_FILENAME;
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
- bios_size = load_image_targphys(buf, 0x1fc00000LL, BIOS_SIZE);
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+ if (filename) {
+ bios_size = load_image_targphys(filename, 0x1fc00000LL, BIOS_SIZE);
+ qemu_free(filename);
+ } else {
+ bios_size = -1;
+ }
if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
/* Bail out if we have neither a kernel image nor boot vector code. */
fprintf(stderr,
"qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n",
- buf);
+ filename);
exit(1);
} else {
/* We have a boot vector start address. */
loaderparams.kernel_filename = kernel_filename;
loaderparams.kernel_cmdline = kernel_cmdline;
loaderparams.initrd_filename = initrd_filename;
- load_kernel(env);
+ reset_info->vector = load_kernel();
}
/* Init CPU internal devices. */
mipsnet_init(0x4200, env->irq[2], &nd_table[0]);
}
-QEMUMachine mips_mipssim_machine = {
+static QEMUMachine mips_mipssim_machine = {
.name = "mipssim",
.desc = "MIPS MIPSsim platform",
.init = mips_mipssim_init,
};
+
+static void mips_mipssim_machine_init(void)
+{
+ qemu_register_machine(&mips_mipssim_machine);
+}
+
+machine_init(mips_mipssim_machine_init);