From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:58896) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QJ0uZ-0007kY-Dk for qemu-devel@nongnu.org; Sun, 08 May 2011 06:08:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QJ0uY-0005Kv-1y for qemu-devel@nongnu.org; Sun, 08 May 2011 06:08:27 -0400 Received: from mail-qw0-f45.google.com ([209.85.216.45]:41331) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QJ0uX-0005Ju-TO for qemu-devel@nongnu.org; Sun, 08 May 2011 06:08:26 -0400 Received: by qwj8 with SMTP id 8so3012075qwj.4 for ; Sun, 08 May 2011 03:08:25 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <1304809245-7503-3-git-send-email-agraf@suse.de> References: <1304809245-7503-1-git-send-email-agraf@suse.de> <1304809245-7503-3-git-send-email-agraf@suse.de> From: Blue Swirl Date: Sun, 8 May 2011 13:08:05 +0300 Message-ID: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH 2/7] PPC: Make MPC8544DS emulation work w/o KVM List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alexander Graf Cc: Scott Wood , "Edgar E. Iglesias" , Liu Yu , QEMU-devel Developers , Paul Brook On Sun, May 8, 2011 at 2:00 AM, Alexander Graf wrote: > The MPC8544DS board emulation was only used with KVM so far, so some > parts of the code didn't provide proper values for non-KVM execution. > > This patch makes the machine work without KVM enabled. To actually use > this, you also need proper e500v2 MMU emulation. > > Signed-off-by: Alexander Graf > > --- > > v2 -> v3: > > =C2=A0- fix mpc initial tlb size comment > =C2=A0- enable cpu reset > --- > =C2=A0hw/ppce500_mpc8544ds.c | =C2=A0 86 ++++++++++++++++++++++++++++++++= +++++++-------- > =C2=A01 files changed, 71 insertions(+), 15 deletions(-) > > diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c > index 1b8a1c4..44d6440 100644 > --- a/hw/ppce500_mpc8544ds.c > +++ b/hw/ppce500_mpc8544ds.c > @@ -28,6 +28,7 @@ > =C2=A0#include "kvm_ppc.h" > =C2=A0#include "device_tree.h" > =C2=A0#include "openpic.h" > +#include "ppc.h" > =C2=A0#include "ppce500.h" > =C2=A0#include "loader.h" > =C2=A0#include "elf.h" > @@ -50,6 +51,12 @@ > =C2=A0#define MPC8544_PCI_IO =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0x= E1000000 > =C2=A0#define MPC8544_PCI_IOLEN =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00x10000 > > +static struct boot_info > +{ > + =C2=A0 =C2=A0uint32_t dt_base; > + =C2=A0 =C2=A0uint32_t entry; > +} boot_info; I don't think there is a need to use static state here. > + > =C2=A0#ifdef CONFIG_FDT > =C2=A0static int mpc8544_copy_soc_cell(void *fdt, const char *node, const= char *prop) > =C2=A0{ > @@ -82,7 +89,7 @@ static int mpc8544_load_device_tree(target_phys_addr_t = addr, > =C2=A0{ > =C2=A0 =C2=A0 int ret =3D -1; > =C2=A0#ifdef CONFIG_FDT > - =C2=A0 =C2=A0uint32_t mem_reg_property[] =3D {0, ramsize}; > + =C2=A0 =C2=A0uint32_t mem_reg_property[] =3D {0, cpu_to_be32(ramsize)}; > =C2=A0 =C2=A0 char *filename; > =C2=A0 =C2=A0 int fdt_size; > =C2=A0 =C2=A0 void *fdt; > @@ -103,15 +110,19 @@ static int mpc8544_load_device_tree(target_phys_add= r_t addr, > =C2=A0 =C2=A0 if (ret < 0) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, "couldn't set /memory/reg\n")= ; > > - =C2=A0 =C2=A0ret =3D qemu_devtree_setprop_cell(fdt, "/chosen", "linux,i= nitrd-start", > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0initrd_base); > - =C2=A0 =C2=A0if (ret < 0) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "couldn't set /chosen/linux,= initrd-start\n"); > + =C2=A0 =C2=A0if (initrd_size) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D qemu_devtree_setprop_cell(fdt, "/cho= sen", "linux,initrd-start", > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0initrd= _base); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret < 0) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "couldn't set = /chosen/linux,initrd-start\n"); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0} > > - =C2=A0 =C2=A0ret =3D qemu_devtree_setprop_cell(fdt, "/chosen", "linux,i= nitrd-end", > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(initrd_base + initr= d_size)); > - =C2=A0 =C2=A0if (ret < 0) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "couldn't set /chosen/linux,= initrd-end\n"); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D qemu_devtree_setprop_cell(fdt, "/cho= sen", "linux,initrd-end", > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(initr= d_base + initrd_size)); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret < 0) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "couldn't set = /chosen/linux,initrd-end\n"); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0} > + =C2=A0 =C2=A0} > > =C2=A0 =C2=A0 ret =3D qemu_devtree_setprop_string(fdt, "/chosen", "bootar= gs", > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 kernel_cmdline)= ; > @@ -145,6 +156,13 @@ static int mpc8544_load_device_tree(target_phys_addr= _t addr, > > =C2=A0 =C2=A0 =C2=A0 =C2=A0 mpc8544_copy_soc_cell(fdt, buf, "clock-freque= ncy"); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 mpc8544_copy_soc_cell(fdt, buf, "timebase-fre= quency"); > + =C2=A0 =C2=A0} else { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0const uint32_t freq =3D 400000000; > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_devtree_setprop_cell(fdt, "/cpus/PowerP= C,8544@0", > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"clock-frequency", freq); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_devtree_setprop_cell(fdt, "/cpus/PowerP= C,8544@0", > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"timebase-frequency", freq)= ; > =C2=A0 =C2=A0 } > > =C2=A0 =C2=A0 ret =3D rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fd= t_size, addr); > @@ -156,6 +174,35 @@ out: > =C2=A0 =C2=A0 return ret; > =C2=A0} > > +/* Create -kernel TLB entries for BookE, linearly spanning 256MB. =C2=A0= */ > +static void mmubooke_create_initial_mapping(CPUState *env, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 target_ulong va, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 target_phys_addr_t = pa) > +{ > + =C2=A0 =C2=A0ppcemb_tlb_t *tlb =3D &env->tlb[512].tlbe; > + > + =C2=A0 =C2=A0tlb->attr =3D 0; > + =C2=A0 =C2=A0tlb->prot =3D PAGE_VALID | ((PAGE_READ | PAGE_WRITE | PAGE= _EXEC) << 4); > + =C2=A0 =C2=A0tlb->size =3D 256 * 1024 * 1024; > + =C2=A0 =C2=A0tlb->EPN =3D va & TARGET_PAGE_MASK; > + =C2=A0 =C2=A0tlb->RPN =3D pa & TARGET_PAGE_MASK; > + =C2=A0 =C2=A0tlb->PID =3D 0; > +} > + > +static void mpc8544ds_cpu_reset(void *opaque) > +{ > + =C2=A0 =C2=A0CPUState *env =3D opaque; > + =C2=A0 =C2=A0struct boot_info *bi =3D env->load_info; > + > + =C2=A0 =C2=A0cpu_reset(env); > + > + =C2=A0 =C2=A0/* Set initial guest state. */ > + =C2=A0 =C2=A0env->gpr[1] =3D (16<<20) - 8; > + =C2=A0 =C2=A0env->gpr[3] =3D bi->dt_base; > + =C2=A0 =C2=A0env->nip =3D bi->entry; > + =C2=A0 =C2=A0mmubooke_create_initial_mapping(env, 0, 0); > +} > + > =C2=A0static void mpc8544ds_init(ram_addr_t ram_size, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0const char *boot_device, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0const char *kernel_filename, > @@ -188,6 +235,13 @@ static void mpc8544ds_init(ram_addr_t ram_size, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 exit(1); > =C2=A0 =C2=A0 } > > + =C2=A0 =C2=A0/* XXX register timer? */ > + =C2=A0 =C2=A0ppc_emb_timers_init(env, 400000000, PPC_INTERRUPT_DECR); > + =C2=A0 =C2=A0ppc_dcr_init(env, NULL, NULL); > + > + =C2=A0 =C2=A0/* Register reset handler */ > + =C2=A0 =C2=A0qemu_register_reset(mpc8544ds_cpu_reset, env); > + > =C2=A0 =C2=A0 /* Fixup Memory size on a alignment boundary */ > =C2=A0 =C2=A0 ram_size &=3D ~(RAM_SIZES_ALIGN - 1); > > @@ -265,6 +319,9 @@ static void mpc8544ds_init(ram_addr_t ram_size, > > =C2=A0 =C2=A0 /* If we're loading a kernel directly, we must load the dev= ice tree too. */ > =C2=A0 =C2=A0 if (kernel_filename) { > +#ifndef CONFIG_FDT > + =C2=A0 =C2=A0 =C2=A0 =C2=A0cpu_abort(env, "Compiled without FDT support= - can't load kernel\n"); > +#endif > =C2=A0 =C2=A0 =C2=A0 =C2=A0 dt_base =3D (kernel_size + DTC_LOAD_PAD) & ~D= TC_PAD_MASK; > =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (mpc8544_load_device_tree(dt_base, ram_siz= e, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ini= trd_base, initrd_size, kernel_cmdline) < 0) { > @@ -272,15 +329,14 @@ static void mpc8544ds_init(ram_addr_t ram_size, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 exit(1); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 } > > - =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Set initial guest state. */ > - =C2=A0 =C2=A0 =C2=A0 =C2=A0env->gpr[1] =3D (16<<20) - 8; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0env->gpr[3] =3D dt_base; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0env->nip =3D entry; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0/* XXX we currently depend on KVM to create = some initial TLB entries. */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0boot_info.entry =3D entry; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0boot_info.dt_base =3D dt_base; > =C2=A0 =C2=A0 } > + =C2=A0 =C2=A0env->load_info =3D &boot_info; > > - =C2=A0 =C2=A0if (kvm_enabled()) > + =C2=A0 =C2=A0if (kvm_enabled()) { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 kvmppc_init(); > + =C2=A0 =C2=A0} > > =C2=A0 =C2=A0 return; > =C2=A0} > -- > 1.6.0.2 > > >