From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1N95wy-0002vn-NN for qemu-devel@nongnu.org; Fri, 13 Nov 2009 18:53:08 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1N95wx-0002v7-JJ for qemu-devel@nongnu.org; Fri, 13 Nov 2009 18:53:08 -0500 Received: from [199.232.76.173] (port=45448 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N95wx-0002v0-Fw for qemu-devel@nongnu.org; Fri, 13 Nov 2009 18:53:07 -0500 Received: from hall.aurel32.net ([88.191.82.174]:57204) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1N95ww-0005sN-Oj for qemu-devel@nongnu.org; Fri, 13 Nov 2009 18:53:07 -0500 Date: Sat, 14 Nov 2009 00:53:00 +0100 From: Aurelien Jarno Subject: Re: [Qemu-devel] [PATCH] mips: fix CPU reset Message-ID: <20091113235300.GA8763@volta.aurel32.net> References: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-15 Content-Disposition: inline In-Reply-To: List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Blue Swirl Cc: qemu-devel 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 > --- > 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 aurelien@aurel32.net http://www.aurel32.net