qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] mips: fix CPU reset


From: Blue Swirl
Subject: [Qemu-devel] [PATCH] mips: fix CPU reset
Date: Fri, 13 Nov 2009 22:44:29 +0200

This patch fixes the MIPS reset problem, so that using instructions
from http://www.aurel32.net/info/debian_mips_qemu.php, I get the
installer prompt.
---
See f2d74978764f62d832d61ac17bb5d934ade58816.

Signed-off-by: Blue Swirl <address@hidden>
---
 hw/mips_malta.c   |   23 +++++++++++++++++------
 hw/mips_mipssim.c |   25 +++++++++++++++++--------
 hw/mips_r4k.c     |   25 +++++++++++++++++--------
 3 files changed, 51 insertions(+), 22 deletions(-)

diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 30fa6b8..706962b 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -80,6 +80,11 @@ static struct _loaderparams {
     const char *initrd_filename;
 } loaderparams;

+typedef struct ResetData {
+    CPUState *env;
+    uint64_t vector;
+} ResetData;
+
 /* Malta FPGA */
 static void malta_fpga_update_display(void *opaque)
 {
@@ -683,7 +688,7 @@ static void prom_set(int index, const char *string, ...)
 }

 /* Kernel */
-static int64_t load_kernel (CPUState *env)
+static int64_t load_kernel(void)
 {
     int64_t kernel_entry, kernel_low, kernel_high;
     int index = 0;
@@ -750,15 +755,16 @@ static int64_t load_kernel (CPUState *env)

 static void main_cpu_reset(void *opaque)
 {
-    CPUState *env = opaque;
-    cpu_reset(env);
+    ResetData *s = (ResetData *)opaque;
+    CPUState *env = s->env;

+    cpu_reset(env);
+    env->active_tc.PC = s->vector;
     /* The bootload does not need to be rewritten as it is located in a
        read only location. The kernel location and the arguments table
        location does not change. */
     if (loaderparams.kernel_filename) {
         env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
-        load_kernel (env);
     }
 }

@@ -776,6 +782,7 @@ void mips_malta_init (ram_addr_t ram_size,
     PCIBus *pci_bus;
     ISADevice *isa_dev;
     CPUState *env;
+    ResetData *reset_info;
     RTCState *rtc_state;
     fdctrl_t *floppy_controller;
     MaltaFPGAState *malta_fpga;
@@ -812,7 +819,10 @@ void mips_malta_init (ram_addr_t ram_size,
         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 */
     if (ram_size > (256 << 20)) {
@@ -843,7 +853,8 @@ void mips_malta_init (ram_addr_t ram_size,
         loaderparams.kernel_filename = kernel_filename;
         loaderparams.kernel_cmdline = kernel_cmdline;
         loaderparams.initrd_filename = initrd_filename;
-        kernel_entry = load_kernel(env);
+        kernel_entry = load_kernel();
+        reset_info->vector = kernel_entry;
         env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
         write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry);
     } else {
diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c
index 9aed40e..aa90116 100644
--- a/hw/mips_mipssim.c
+++ b/hw/mips_mipssim.c
@@ -50,7 +50,12 @@ static struct _loaderparams {
     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;
     long kernel_size;
@@ -70,7 +75,6 @@ static void load_kernel (CPUState *env)
     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);
@@ -99,15 +103,16 @@ static void load_kernel (CPUState *env)
             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
@@ -120,6 +125,7 @@ mips_mipssim_init (ram_addr_t ram_size,
     ram_addr_t ram_offset;
     ram_addr_t bios_offset;
     CPUState *env;
+    ResetData *reset_info;
     int bios_size;

     /* Init CPUs. */
@@ -135,7 +141,10 @@ mips_mipssim_init (ram_addr_t ram_size,
         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);
@@ -172,7 +181,7 @@ mips_mipssim_init (ram_addr_t ram_size,
         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. */
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index d525c63..497885b 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -70,7 +70,12 @@ static CPUReadMemoryFunc * const mips_qemu_read[] = {

 static int mips_qemu_iomemtype = 0;

-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;
     long kernel_size, initrd_size;
@@ -89,7 +94,6 @@ static void load_kernel (CPUState *env)
     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);
@@ -135,15 +139,16 @@ static void load_kernel (CPUState *env)

     stl_phys((16 << 20) - 260, 0x12345678);
     stl_phys((16 << 20) - 264, ram_size);
+    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 const int sector_len = 32 * 1024;
@@ -158,6 +163,7 @@ void mips_r4k_init (ram_addr_t ram_size,
     ram_addr_t bios_offset;
     int bios_size;
     CPUState *env;
+    ResetData *reset_info;
     RTCState *rtc_state;
     int i;
     qemu_irq *i8259;
@@ -177,7 +183,10 @@ void mips_r4k_init (ram_addr_t ram_size,
         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 */
     if (ram_size > (256 << 20)) {
@@ -237,7 +246,7 @@ void mips_r4k_init (ram_addr_t ram_size,
         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 */
-- 
1.6.2.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]