On Wed, Nov 11, 2015 at 11:27:35AM +1100, Benjamin Herrenschmidt wrote: > Those instructions are only available in hypervisor real mode and > allow cache inhibited garded access to devices in that mode. > > Signed-off-by: Benjamin Herrenschmidt <b...@kernel.crashing.org> > --- > target-ppc/cpu.h | 4 +++- > target-ppc/translate.c | 56 > +++++++++++++++++++++++++++++++++++---------- > target-ppc/translate_init.c | 6 +++-- > 3 files changed, 51 insertions(+), 15 deletions(-) > > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h > index 23479b1..3d22a4f 100644 > --- a/target-ppc/cpu.h > +++ b/target-ppc/cpu.h > @@ -1913,6 +1913,8 @@ enum { > PPC_POPCNTB = 0x0000000000001000ULL, > /* string load / store > */ > PPC_STRING = 0x0000000000002000ULL, > + /* real mode cache inhibited load / store > */ > + PPC_CILDST = 0x0000000000004000ULL, > > /* Floating-point unit extensions > */ > /* Optional floating point instructions > */ > @@ -2027,7 +2029,7 @@ enum { > | PPC_MFAPIDI | PPC_TLBIVA | PPC_TLBIVAX \ > | PPC_4xx_COMMON | PPC_40x_ICBT | PPC_RFMCI \ > | PPC_RFDI | PPC_DCR | PPC_DCRX | PPC_DCRUX \ > - | PPC_POPCNTWD) > + | PPC_POPCNTWD | PPC_CILDST) > > /* extended type values */ > > diff --git a/target-ppc/translate.c b/target-ppc/translate.c > index 3f657b1..4d01fd0 100644 > --- a/target-ppc/translate.c > +++ b/target-ppc/translate.c > @@ -189,7 +189,7 @@ struct DisasContext { > uint32_t opcode; > uint32_t exception; > /* Routine used to access memory */ > - bool pr, hv; > + bool pr, hv, dr; > int mem_idx; > int access_type; > /* Translation flags */ > @@ -380,9 +380,11 @@ typedef struct opcode_t { > #if defined(CONFIG_USER_ONLY) > #define CHK_HV GEN_PRIV > #define CHK_SV GEN_PRIV > +#define CHK_HVDR GEN_PRIV
I'm guessing this is supposed to be CHK_HVRM as below. > #else > #define CHK_HV do { if (unlikely(ctx->pr || !ctx->hv)) GEN_PRIV; } while(0) > #define CHK_SV do { if (unlikely(ctx->pr)) GEN_PRIV; } while(0) > +#define CHK_HVRM do { if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) > GEN_PRIV; } while(0) > #endif > > #define CHK_NONE > @@ -2887,7 +2889,7 @@ static void glue(gen_, name##u)(DisasContext *ctx) > } > > #define GEN_LDUX(name, ldop, opc2, opc3, type) > \ > -static void glue(gen_, name##ux)(DisasContext *ctx) > \ > +static void glue(gen_, name##ux)(DisasContext *ctx) > \ Extraneous change. > { > \ > TCGv EA; > \ > if (unlikely(rA(ctx->opcode) == 0 || > \ > @@ -2903,18 +2905,23 @@ static void glue(gen_, name##ux)(DisasContext *ctx) > tcg_temp_free(EA); > \ > } > > -#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2) > \ > +#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk) > \ > static void glue(gen_, name##x)(DisasContext *ctx) > \ > { > \ > TCGv EA; > \ > + chk; > \ > gen_set_access_type(ctx, ACCESS_INT); > \ > EA = tcg_temp_new(); > \ > gen_addr_reg_index(ctx, EA); > \ > gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); > \ > tcg_temp_free(EA); > \ > } > + > #define GEN_LDX(name, ldop, opc2, opc3, type) > \ > - GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE) > + GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_NONE) > + > +#define GEN_LDX_HVRM(name, ldop, opc2, opc3, type) > \ > + GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_HVRM) > > #define GEN_LDS(name, ldop, op, type) > \ > GEN_LD(name, ldop, op | 0x20, type); > \ > @@ -2940,6 +2947,12 @@ GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B); > /* ldx */ > GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B); > > +/* CI load/store variants */ > +GEN_LDX_HVRM(ldcix, ld64, 0x15, 0x1b, PPC_CILDST) > +GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x15, PPC_CILDST) > +GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST) > +GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST) > + > static void gen_ld(DisasContext *ctx) > { > TCGv EA; > @@ -3058,10 +3071,11 @@ static void glue(gen_, name##ux)(DisasContext *ctx) > tcg_temp_free(EA); > \ > } > > -#define GEN_STX_E(name, stop, opc2, opc3, type, type2) > \ > +#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk) > \ > static void glue(gen_, name##x)(DisasContext *ctx) > \ > { > \ > TCGv EA; > \ > + chk; > \ > gen_set_access_type(ctx, ACCESS_INT); > \ > EA = tcg_temp_new(); > \ > gen_addr_reg_index(ctx, EA); > \ > @@ -3069,7 +3083,10 @@ static void glue(gen_, name##x)(DisasContext *ctx) > \ > tcg_temp_free(EA); > \ > } > #define GEN_STX(name, stop, opc2, opc3, type) > \ > - GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE) > + GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_NONE) > + > +#define GEN_STX_HVRM(name, stop, opc2, opc3, type) > \ > + GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_HVRM) > > #define GEN_STS(name, stop, op, type) > \ > GEN_ST(name, stop, op | 0x20, type); > \ > @@ -3086,6 +3103,10 @@ GEN_STS(stw, st32, 0x04, PPC_INTEGER); > #if defined(TARGET_PPC64) > GEN_STUX(std, st64, 0x15, 0x05, PPC_64B); > GEN_STX(std, st64, 0x15, 0x04, PPC_64B); > +GEN_STX_HVRM(stdcix, st64, 0x15, 0x1f, PPC_CILDST) > +GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST) > +GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST) > +GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST) > > static void gen_std(DisasContext *ctx) > { > @@ -3171,7 +3192,7 @@ static inline void gen_qemu_ld64ur(DisasContext *ctx, > TCGv arg1, TCGv arg2) > TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP); > tcg_gen_qemu_ld_i64(arg1, arg2, ctx->mem_idx, op); > } > -GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX); > +GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE); > #endif /* TARGET_PPC64 */ > > /* sthbrx */ > @@ -3197,7 +3218,7 @@ static inline void gen_qemu_st64r(DisasContext *ctx, > TCGv arg1, TCGv arg2) > TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP); > tcg_gen_qemu_st_i64(arg1, arg2, ctx->mem_idx, op); > } > -GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX); > +GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE); > #endif /* TARGET_PPC64 */ > > /*** Integer load and store multiple > ***/ > @@ -10156,7 +10177,7 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type), > GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type), > #define GEN_LDUX(name, ldop, opc2, opc3, type) > \ > GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type), > -#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2) > \ > +#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk) > \ > GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2), > #define GEN_LDS(name, ldop, op, type) > \ > GEN_LD(name, ldop, op | 0x20, type) > \ > @@ -10173,7 +10194,13 @@ GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B) > GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B) > GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B) > GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B) > -GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX) > +GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE) > + > +/* HV/P7 and later only */ > +GEN_LDX_HVRM(ldcix, ld64, 0x15, 0x1b, PPC_CILDST) > +GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x18, PPC_CILDST) > +GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST) > +GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST) > #endif > GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER) > GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER) > @@ -10189,7 +10216,7 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type), > GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type), > #define GEN_STUX(name, stop, opc2, opc3, type) > \ > GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type), > -#define GEN_STX_E(name, stop, opc2, opc3, type, type2) > \ > +#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk) > \ > GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2), > #define GEN_STS(name, stop, op, type) > \ > GEN_ST(name, stop, op | 0x20, type) > \ > @@ -10203,7 +10230,11 @@ GEN_STS(stw, st32, 0x04, PPC_INTEGER) > #if defined(TARGET_PPC64) > GEN_STUX(std, st64, 0x15, 0x05, PPC_64B) > GEN_STX(std, st64, 0x15, 0x04, PPC_64B) > -GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX) > +GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE) > +GEN_STX_HVRM(stdcix, st64, 0x15, 0x1f, PPC_CILDST) > +GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST) > +GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST) > +GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST) > #endif > GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER) > GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER) > @@ -11369,6 +11400,7 @@ void gen_intermediate_code(CPUPPCState *env, struct > TranslationBlock *tb) > ctx.spr_cb = env->spr_cb; > ctx.pr = msr_pr; > ctx.mem_idx = env->dmmu_idx; > + ctx.dr = msr_dr; > #if !defined(CONFIG_USER_ONLY) > ctx.hv = !msr_pr && (msr_hv || !env->has_hv_mode); > #endif > diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c > index 5210b25..8d82bc8 100644 > --- a/target-ppc/translate_init.c > +++ b/target-ppc/translate_init.c > @@ -8320,7 +8320,8 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) > PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | > PPC_64B | PPC_64H | PPC_ALTIVEC | > PPC_SEGMENT_64B | PPC_SLBI | > - PPC_POPCNTB | PPC_POPCNTWD; > + PPC_POPCNTB | PPC_POPCNTWD | > + PPC_CILDST; > pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 | > PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | > PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | > @@ -8397,7 +8398,8 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) > PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | > PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC | > PPC_SEGMENT_64B | PPC_SLBI | > - PPC_POPCNTB | PPC_POPCNTWD; > + PPC_POPCNTB | PPC_POPCNTWD | > + PPC_CILDST; > pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX | > PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | > PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
signature.asc
Description: PGP signature