From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43223) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yn77m-0003Es-39 for qemu-devel@nongnu.org; Tue, 28 Apr 2015 11:08:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Yn77h-0004np-5C for qemu-devel@nongnu.org; Tue, 28 Apr 2015 11:08:38 -0400 Received: from mailapp01.imgtec.com ([195.59.15.196]:44606 helo=imgpgp01.kl.imgtec.org) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yn77g-0004nR-PX for qemu-devel@nongnu.org; Tue, 28 Apr 2015 11:08:33 -0400 Message-ID: <553FA267.9060903@imgtec.com> Date: Tue, 28 Apr 2015 16:08:23 +0100 From: James Hogan MIME-Version: 1.0 References: <1430224874-18513-1-git-send-email-leon.alrae@imgtec.com> <1430224874-18513-4-git-send-email-leon.alrae@imgtec.com> In-Reply-To: <1430224874-18513-4-git-send-email-leon.alrae@imgtec.com> Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="qsRsN1KjRqBaqHkiXp0EQueUBwrClopqN" Subject: Re: [Qemu-devel] [PATCH 3/7] target-mips: add CP0.PageGrain.ELPA support List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Leon Alrae , qemu-devel@nongnu.org Cc: aurelien@aurel32.net --qsRsN1KjRqBaqHkiXp0EQueUBwrClopqN Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable Hi Leon, On 28/04/15 13:41, Leon Alrae wrote: > CP0.PageGrain.ELPA enables support for large physical addresses. This f= ield > is encoded as follows: > 0: Large physical address support is disabled. > 1: Large physical address support is enabled. >=20 > If this bit is a 1, the following changes occur to coprocessor 0 regist= ers: > - The PFNX field of the EntryLo0 and EntryLo1 registers is writable and= > concatenated with the PFN field to form the full page frame number. > - Access to optional COP0 registers with PA extension, LLAddr, TagLo is= > defined. >=20 > P5600 can operate in 32-bit or 40-bit Physical Address Mode. Therefore = if > XPA is disabled (CP0.PageGrain.ELPA =3D 0) then assuming 32-bit Address= Mode. > For MIPS64 default PABITS are 36. >=20 > env->PABITS value is constant and indicates maximum PABITS available on= > a core, whereas env->PAMask is calculated from env->PABITS and is also > affected by CP0.PageGrain.ELPA. >=20 > Signed-off-by: Leon Alrae > --- > target-mips/cpu.h | 27 +++++++++++++++++++++++++-- > target-mips/machine.c | 1 + > target-mips/mips-defs.h | 4 ++-- > target-mips/op_helper.c | 24 +++++++++++++++++------- > target-mips/translate.c | 3 ++- > 5 files changed, 47 insertions(+), 12 deletions(-) >=20 > diff --git a/target-mips/cpu.h b/target-mips/cpu.h > index 2dfa139..bcd1e2b 100644 > --- a/target-mips/cpu.h > +++ b/target-mips/cpu.h > @@ -224,8 +224,14 @@ struct CPUMIPSState { > =20 > uint32_t SEGBITS; > uint32_t PABITS; > +#if defined(TARGET_MIPS64) > +# define DEFAULT_PABITS 36 > +#else > +# define DEFAULT_PABITS 32 > +#endif > target_ulong SEGMask; > uint64_t PAMask; > +#define DEFAULT_PAMASK ((1ULL << DEFAULT_PABITS) - 1) > =20 > int32_t msair; > #define MSAIR_ProcID 8 > @@ -289,6 +295,7 @@ struct CPUMIPSState { > int32_t CP0_PageGrain; > #define CP0PG_RIE 31 > #define CP0PG_XIE 30 > +#define CP0PG_ELPA 29 > #define CP0PG_IEC 27 > int32_t CP0_Wired; > int32_t CP0_SRSConf0_rw_bitmask; > @@ -517,7 +524,7 @@ struct CPUMIPSState { > #define EXCP_INST_NOTAVAIL 0x2 /* No valid instruction word for BadIns= tr */ > uint32_t hflags; /* CPU State */ > /* TMASK defines different execution modes */ > -#define MIPS_HFLAG_TMASK 0x35807FF > +#define MIPS_HFLAG_TMASK 0x75807FF > #define MIPS_HFLAG_MODE 0x00007 /* execution modes = */ > /* The KSU flags must be the lowest bits in hflags. The flag order= > must be the same as defined for CP0 Status. This allows to use > @@ -565,6 +572,7 @@ struct CPUMIPSState { > #define MIPS_HFLAG_FBNSLOT 0x800000 /* Forbidden slot = */ > #define MIPS_HFLAG_MSA 0x1000000 > #define MIPS_HFLAG_FRE 0x2000000 /* FRE enabled */ > +#define MIPS_HFLAG_ELPA 0x4000000 > target_ulong btarget; /* Jump / branch target = */ > target_ulong bcond; /* Branch condition (if needed) = */ > =20 > @@ -800,6 +808,15 @@ static inline void restore_msa_fp_status(CPUMIPSSt= ate *env) > set_flush_inputs_to_zero(flush_to_zero, status); > } > =20 > +static inline void restore_pamask(CPUMIPSState *env) > +{ > + if (env->hflags & MIPS_HFLAG_ELPA) { > + env->PAMask =3D (1ULL << env->PABITS) - 1; > + } else { > + env->PAMask =3D DEFAULT_PAMASK; > + } > +} > + > static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulon= g *pc, > target_ulong *cs_base, int *fl= ags) > { > @@ -847,7 +864,8 @@ static inline void compute_hflags(CPUMIPSState *env= ) > env->hflags &=3D ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_C= P0 | > MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU = | > MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DS= PR2 | > - MIPS_HFLAG_SBRI | MIPS_HFLAG_MSA | MIPS_HFLAG_FRE= ); > + MIPS_HFLAG_SBRI | MIPS_HFLAG_MSA | MIPS_HFLAG_FRE= | > + MIPS_HFLAG_ELPA); > if (!(env->CP0_Status & (1 << CP0St_EXL)) && > !(env->CP0_Status & (1 << CP0St_ERL)) && > !(env->hflags & MIPS_HFLAG_DM)) { > @@ -933,6 +951,11 @@ static inline void compute_hflags(CPUMIPSState *en= v) > env->hflags |=3D MIPS_HFLAG_FRE; > } > } > + if (env->CP0_Config3 & (1 << CP0C3_LPA)) { > + if (env->CP0_PageGrain & (1 << CP0PG_ELPA)) { > + env->hflags |=3D MIPS_HFLAG_ELPA; > + } > + } > } > =20 > #ifndef CONFIG_USER_ONLY > diff --git a/target-mips/machine.c b/target-mips/machine.c > index 559402c..8fa755c 100644 > --- a/target-mips/machine.c > +++ b/target-mips/machine.c > @@ -10,6 +10,7 @@ static int cpu_post_load(void *opaque, int version_id= ) > restore_fp_status(env); > restore_msa_fp_status(env); > compute_hflags(env); > + restore_pamask(env); > =20 > return 0; > } > diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h > index 1784227..20aa87c 100644 > --- a/target-mips/mips-defs.h > +++ b/target-mips/mips-defs.h > @@ -10,11 +10,11 @@ > =20 > #if defined(TARGET_MIPS64) > #define TARGET_LONG_BITS 64 > -#define TARGET_PHYS_ADDR_SPACE_BITS 36 > +#define TARGET_PHYS_ADDR_SPACE_BITS 48 > #define TARGET_VIRT_ADDR_SPACE_BITS 42 > #else > #define TARGET_LONG_BITS 32 > -#define TARGET_PHYS_ADDR_SPACE_BITS 36 > +#define TARGET_PHYS_ADDR_SPACE_BITS 40 Out of interest, is there a particular reason not to put this up to 59, the max supported by the architecture, rather than just what P5600 suppor= ts? > #define TARGET_VIRT_ADDR_SPACE_BITS 32 > #endif > =20 > diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c > index 6bff927..4b1b0ec 100644 > --- a/target-mips/op_helper.c > +++ b/target-mips/op_helper.c > @@ -1067,19 +1067,28 @@ void helper_mtc0_vpeopt(CPUMIPSState *env, targ= et_ulong arg1) > env->CP0_VPEOpt =3D arg1 & 0x0000ffff; > } > =20 > +static inline target_ulong get_mtc0_entrylo_mask(const CPUMIPSState *e= nv) > +{ > +#if defined(TARGET_MIPS64) > + return env->PAMask >> 6; I think this case is suitable for dmtc0 EntryLo regardless of MIPS64/MIPS= 32? > +#else > + return (env->PAMask >> 6) & 0x3FFFFFFF; mtc0 sets bits 61:30 of EntryLo to 0 on MIPS64 too, so this case is suitable for mtc0 regardless of MIPS64/MIPS32? Cheers James > +#endif > +} > + > void helper_mtc0_entrylo0(CPUMIPSState *env, target_ulong arg1) > { > - /* Large physaddr (PABITS) not implemented */ > /* 1k pages not implemented */ > target_ulong rxi =3D arg1 & (env->CP0_PageGrain & (3u << CP0PG_XIE= )); > - env->CP0_EntryLo0 =3D (arg1 & 0x3FFFFFFF) | (rxi << (CP0EnLo_XI - = 30)); > + env->CP0_EntryLo0 =3D (arg1 & get_mtc0_entrylo_mask(env)) > + | (rxi << (CP0EnLo_XI - 30)); > } > =20 > #if defined(TARGET_MIPS64) > void helper_dmtc0_entrylo0(CPUMIPSState *env, uint64_t arg1) > { > uint64_t rxi =3D arg1 & ((env->CP0_PageGrain & (3ull << CP0PG_XIE)= ) << 32); > - env->CP0_EntryLo0 =3D (arg1 & 0x3FFFFFFF) | rxi; > + env->CP0_EntryLo0 =3D (arg1 & get_mtc0_entrylo_mask(env)) | rxi; > } > #endif > =20 > @@ -1245,17 +1254,17 @@ void helper_mttc0_tcschefback(CPUMIPSState *env= , target_ulong arg1) > =20 > void helper_mtc0_entrylo1(CPUMIPSState *env, target_ulong arg1) > { > - /* Large physaddr (PABITS) not implemented */ > /* 1k pages not implemented */ > target_ulong rxi =3D arg1 & (env->CP0_PageGrain & (3u << CP0PG_XIE= )); > - env->CP0_EntryLo1 =3D (arg1 & 0x3FFFFFFF) | (rxi << (CP0EnLo_XI - = 30)); > + env->CP0_EntryLo1 =3D (arg1 & get_mtc0_entrylo_mask(env)) > + | (rxi << (CP0EnLo_XI - 30)); > } > =20 > #if defined(TARGET_MIPS64) > void helper_dmtc0_entrylo1(CPUMIPSState *env, uint64_t arg1) > { > uint64_t rxi =3D arg1 & ((env->CP0_PageGrain & (3ull << CP0PG_XIE)= ) << 32); > - env->CP0_EntryLo1 =3D (arg1 & 0x3FFFFFFF) | rxi; > + env->CP0_EntryLo1 =3D (arg1 & get_mtc0_entrylo_mask(env)) | rxi; > } > #endif > =20 > @@ -1278,10 +1287,11 @@ void helper_mtc0_pagemask(CPUMIPSState *env, ta= rget_ulong arg1) > void helper_mtc0_pagegrain(CPUMIPSState *env, target_ulong arg1) > { > /* SmartMIPS not implemented */ > - /* Large physaddr (PABITS) not implemented */ > /* 1k pages not implemented */ > env->CP0_PageGrain =3D (arg1 & env->CP0_PageGrain_rw_bitmask) | > (env->CP0_PageGrain & ~env->CP0_PageGrain_rw_= bitmask); > + compute_hflags(env); > + restore_pamask(env); > } > =20 > void helper_mtc0_wired(CPUMIPSState *env, target_ulong arg1) > diff --git a/target-mips/translate.c b/target-mips/translate.c > index 0f875be..bb219ea 100644 > --- a/target-mips/translate.c > +++ b/target-mips/translate.c > @@ -5666,6 +5666,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg,= int reg, int sel) > check_insn(ctx, ISA_MIPS32R2); > gen_helper_mtc0_pagegrain(cpu_env, arg); > rn =3D "PageGrain"; > + ctx->bstate =3D BS_STOP; > break; > default: > goto cp0_unimplemented; > @@ -19526,7 +19527,6 @@ void cpu_state_reset(CPUMIPSState *env) > } > #endif > env->PABITS =3D env->cpu_model->PABITS; > - env->PAMask =3D (1ULL << env->cpu_model->PABITS) - 1; > env->CP0_SRSConf0_rw_bitmask =3D env->cpu_model->CP0_SRSConf0_rw_b= itmask; > env->CP0_SRSConf0 =3D env->cpu_model->CP0_SRSConf0; > env->CP0_SRSConf1_rw_bitmask =3D env->cpu_model->CP0_SRSConf1_rw_b= itmask; > @@ -19647,6 +19647,7 @@ void cpu_state_reset(CPUMIPSState *env) > compute_hflags(env); > restore_rounding_mode(env); > restore_flush_mode(env); > + restore_pamask(env); > cs->exception_index =3D EXCP_NONE; > } > =20 >=20 --qsRsN1KjRqBaqHkiXp0EQueUBwrClopqN Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBAgAGBQJVP6JuAAoJEGwLaZPeOHZ6EHUP/jG+z/tAZdvi4iynEiv9GomK rZ+3wQRWPUpzOgmD13qYvS+eNuXvyxG/sByXuNhBj91SxE7hOBkidwVS+OyzWkt1 Tt9gRqCj9mh51gO4UyeMKYv+7eoEa3dGywkEot8rpvQMVWVwjJduegru38/3rq5L xBa03yifFb6iKd32kjw1Fu5rhISDMTsMzCEoUj34l8qx0S/xq7nWa7JpOmf88Sli 38zFhZeIY7odXncw+wIIo/8K85gN0gon9rsGMA/FYmAgk/ICEdUgMhAmFzQbnUU7 J8pxw7Wcm2x8Cad+Ugek0CvU92Nh7rW13f3JEi6aVXx4wUlfLZnaobFnfElukupe bX1eswwz5IdmRzRudV0HS4yG6VxUb8ThtdN0odrGrYgcGzQpqwhsQtbhgvPJr7Jj aPPZn7pNan8F8jSYUHHuXSdj7PGywZa8wHEpbrzYHrjoV0GHD39Quq9aRrT8O8RL y97r8L4ZsyqsVqvpJsMQOKGPavmueQfUeRCw+aBGmXPMDHfbcUCyHgxx1Wy60Be3 AWEG8J/qJ9GJ5ezJZ2PVa329gDmc9Z00q9Fiz3qZ6QM4gBS0px6YN7b7LsbDo3y5 U34s3wLpajWIcjOIZIaC6PLnnXW9sAjbdQlFwEUdYqp+1r89AVhhHqDeMqjH7vxh D+4CtcTF5fLK3shoBf3B =I/Fy -----END PGP SIGNATURE----- --qsRsN1KjRqBaqHkiXp0EQueUBwrClopqN--