qemu-devel
[Top][All Lists]
Advanced

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

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


From: Aurelien Jarno
Subject: Re: [Qemu-devel] [PATCH] mips: fix CPU reset
Date: Sat, 14 Nov 2009 00:53:00 +0100
User-agent: Mutt/1.5.20 (2009-06-14)

On Fri, Nov 13, 2009 at 10:44:29PM +0200, Blue Swirl wrote:
> 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.

Thanks for this patch. It seems ok, except for malta. The reset vector
is the default one as we have a bootloader at this address. The patch
from Stefan Weil is correct for the Malta part.

However the reboot is still broken, as we need to reload the kernel into
memory. How it should done now?

> 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
> 
> 
> 

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
address@hidden                 http://www.aurel32.net




reply via email to

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