Skip to content

Commit c7d76f6

Browse files
committed
target/ppc: Implement hashst(p) and hashchk(p) instructions
Implementation for instructions hashst, hashchk, and its privileged versions. Signed-off-by: Víctor Colombo <[email protected]>
1 parent aea6e47 commit c7d76f6

File tree

8 files changed

+146
-0
lines changed

8 files changed

+146
-0
lines changed

linux-headers/asm-powerpc/kvm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,8 @@ struct kvm_ppc_cpu_char {
646646
#define KVM_REG_PPC_SIER3 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc3)
647647
#define KVM_REG_PPC_DAWR1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc4)
648648
#define KVM_REG_PPC_DAWRX1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc5)
649+
#define KVM_REG_PPC_HASHKEYR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x00) /* TODO */
650+
#define KVM_REG_PPC_HASHPKEYR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x00) /* TODO */
649651

650652
/* Transactional Memory checkpointed state:
651653
* This is all GPRs, all VSX regs and a subset of SPRs

target/ppc/cpu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,6 +1674,8 @@ void ppc_compat_add_property(Object *obj, const char *name,
16741674
#define SPR_BOOKE_GIVOR14 (0x1BD)
16751675
#define SPR_TIR (0x1BE)
16761676
#define SPR_PTCR (0x1D0)
1677+
#define SPR_POWER_HASHKEYR (0x1D4)
1678+
#define SPR_POWER_HASHPKEYR (0x1D5)
16771679
#define SPR_BOOKE_SPEFSCR (0x200)
16781680
#define SPR_Exxx_BBEAR (0x201)
16791681
#define SPR_Exxx_BBTAR (0x202)

target/ppc/cpu_init.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6478,6 +6478,13 @@ static void init_proc_POWER10(CPUPPCState *env)
64786478
spr_read_generic, spr_write_generic,
64796479
KVM_REG_PPC_PSSCR, 0);
64806480

6481+
spr_register_kvm(env, SPR_POWER_HASHKEYR, "HASHPKEYR",
6482+
SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic,
6483+
KVM_REG_PPC_HASHKEYR, 0x0);
6484+
spr_register_kvm(env, SPR_POWER_HASHPKEYR, "HASHPKEYR",
6485+
SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic,
6486+
KVM_REG_PPC_HASHPKEYR, 0x0);
6487+
64816488
/* env variables */
64826489
env->dcache_line_size = 128;
64836490
env->icache_line_size = 128;

target/ppc/excp_helper.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2172,6 +2172,92 @@ void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
21722172
#endif
21732173
#endif
21742174

2175+
static uint32_t helper_SIMON_LIKE_32_64(uint32_t x, uint64_t key, uint32_t lane)
2176+
{
2177+
uint32_t c = 0xfffc;
2178+
uint64_t z0 = 0xfa2561cdf44ac398;
2179+
uint16_t z = 0, temp;
2180+
uint16_t k[32], eff_k[32], xleft[33], xright[33], fxleft[32];
2181+
2182+
for (int i = 3; i >= 0; i--) {
2183+
k[i] = key & 0xffff;
2184+
key >>= 16;
2185+
}
2186+
xleft[0] = x & 0xffff;
2187+
xright[0] = (x >> 16) & 0xffff;
2188+
2189+
for (int i = 0; i < 28; i++) {
2190+
z |= ((z0 >> (63 - i)) & 1) << 48;
2191+
temp = ror16(k[i + 3], 3) ^ k[i + 1];
2192+
k[i + 4] = c ^ z ^ k[i] ^ temp ^ ror16(temp, 1);
2193+
}
2194+
2195+
for (int i = 0; i < 8; i++)
2196+
{
2197+
eff_k[4 * i + 0] = k[4 * i + ((0 + lane) % 4)];
2198+
eff_k[4 * i + 1] = k[4 * i + ((1 + lane) % 4)];
2199+
eff_k[4 * i + 2] = k[4 * i + ((2 + lane) % 4)];
2200+
eff_k[4 * i + 3] = k[4 * i + ((3 + lane) % 4)];
2201+
}
2202+
2203+
for (int i = 0; i < 32; i++)
2204+
{
2205+
fxleft[i] = (rol16(xleft[i], 1) &
2206+
rol16(xleft[i], 8)) ^ rol16(xleft[i], 2);
2207+
xleft[i + 1] = xright[i] ^ fxleft[i] ^ eff_k[i];
2208+
xright[i + 1] = xleft[i];
2209+
}
2210+
2211+
return (((uint32_t)xright[32]) << 16) | xleft[32];
2212+
}
2213+
2214+
/* TODO: check this implementation correctness; make it better */
2215+
static uint64_t hash_digest(uint64_t ra, uint64_t rb, uint64_t key)
2216+
{
2217+
uint64_t stage0_h = 0ULL, stage0_l = 0ULL;
2218+
uint64_t stage1_h, stage1_l;
2219+
2220+
for (int i = 0; i < 4; i++) {
2221+
stage0_h |= ror64(rb & 0xff, 8 * (2 * i + 1));
2222+
stage0_h |= ((ra >> 32) & 0xff) << (8 * 2 * i);
2223+
stage0_l |= ror64((rb >> 32) & 0xff, 8 * (2 * i +1));
2224+
stage0_l |= (ra & 0xff) << (8 * 2 * i);
2225+
rb >>= 8;
2226+
ra >>= 8;
2227+
}
2228+
2229+
stage1_h = (uint64_t)helper_SIMON_LIKE_32_64(stage0_h >> 32, key, 0) << 32;
2230+
stage1_h |= helper_SIMON_LIKE_32_64(stage0_h, key, 1);
2231+
stage1_l = (uint64_t)helper_SIMON_LIKE_32_64(stage0_l >> 32, key, 2) << 32;
2232+
stage1_l |= helper_SIMON_LIKE_32_64(stage0_l, key, 3);
2233+
2234+
return (stage1_h ^ stage1_l);
2235+
}
2236+
2237+
#define HELPER_HASH(op, key, store) \
2238+
void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \
2239+
target_ulong rb) \
2240+
{ \
2241+
uint64_t chash = hash_digest(ra, rb, key), lhash; \
2242+
\
2243+
if (store) { \
2244+
cpu_stq_data_ra(env, ea, chash, GETPC()); \
2245+
} \
2246+
else { \
2247+
lhash = cpu_ldq_data_ra(env, ea, GETPC()); \
2248+
if (lhash != chash) { \
2249+
/* hashes don't match, trap */ \
2250+
raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, \
2251+
POWERPC_EXCP_TRAP, GETPC()); \
2252+
} \
2253+
} \
2254+
}
2255+
2256+
HELPER_HASH(HASHST, env->spr[SPR_POWER_HASHKEYR], true)
2257+
HELPER_HASH(HASHCHK, env->spr[SPR_POWER_HASHKEYR], false)
2258+
HELPER_HASH(HASHSTP, env->spr[SPR_POWER_HASHPKEYR], true)
2259+
HELPER_HASH(HASHCHKP, env->spr[SPR_POWER_HASHPKEYR], false)
2260+
21752261
#if !defined(CONFIG_USER_ONLY)
21762262

21772263
#ifdef CONFIG_TCG

target/ppc/helper.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ DEF_HELPER_FLAGS_4(tw, TCG_CALL_NO_WG, void, env, tl, tl, i32)
44
#if defined(TARGET_PPC64)
55
DEF_HELPER_FLAGS_4(td, TCG_CALL_NO_WG, void, env, tl, tl, i32)
66
#endif
7+
DEF_HELPER_4(HASHST, void, env, tl, tl, tl)
8+
DEF_HELPER_4(HASHCHK, void, env, tl, tl, tl)
9+
DEF_HELPER_4(HASHSTP, void, env, tl, tl, tl)
10+
DEF_HELPER_4(HASHCHKP, void, env, tl, tl, tl)
711
#if !defined(CONFIG_USER_ONLY)
812
DEF_HELPER_2(store_msr, void, env, tl)
913
DEF_HELPER_1(rfi, void, env)

target/ppc/insn32.decode

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@
142142
@X_TSX ...... ..... ra:5 rb:5 .......... . &X rt=%x_rt_tsx
143143
@X_TSXP ...... ..... ra:5 rb:5 .......... . &X rt=%rt_tsxp
144144

145+
%x_dw 0:1 21:5 !function=dw_compose_ea
146+
@X_DW ...... ..... ra:5 rb:5 .......... . &X rt=%x_dw
147+
145148
&X_frtp_vrb frtp vrb
146149
@X_frtp_vrb ...... ....0 ..... vrb:5 .......... . &X_frtp_vrb frtp=%x_frtp
147150

@@ -281,6 +284,13 @@ CNTTZDM 011111 ..... ..... ..... 1000111011 - @X
281284
PDEPD 011111 ..... ..... ..... 0010011100 - @X
282285
PEXTD 011111 ..... ..... ..... 0010111100 - @X
283286

287+
# Fixed-Point Hash Instructions
288+
289+
HASHST 011111 ..... ..... ..... 1011010010 . @X_DW
290+
HASHCHK 011111 ..... ..... ..... 1011110010 . @X_DW
291+
HASHSTP 011111 ..... ..... ..... 1010010010 . @X_DW
292+
HASHCHKP 011111 ..... ..... ..... 1010110010 . @X_DW
293+
284294
### Float-Point Load Instructions
285295

286296
LFS 110000 ..... ..... ................ @D

target/ppc/translate.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6547,6 +6547,12 @@ static int times_16(DisasContext *ctx, int x)
65476547
return x * 16;
65486548
}
65496549

6550+
static int64_t dw_compose_ea(DisasContext *ctx, int x)
6551+
{
6552+
int64_t ea = 0xfffffffffffffe00 | (x << 3);
6553+
return ea;
6554+
}
6555+
65506556
/*
65516557
* Helpers for trans_* functions to check for specific insns flags.
65526558
* Use token pasting to ensure that we use the proper flag with the

target/ppc/translate/fixedpoint-impl.c.inc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,3 +492,32 @@ static bool trans_PEXTD(DisasContext *ctx, arg_X *a)
492492
#endif
493493
return true;
494494
}
495+
496+
static bool do_hash(DisasContext *ctx, arg_X *a, bool priv,
497+
void (*helper)(TCGv_ptr, TCGv, TCGv, TCGv))
498+
{
499+
TCGv ea = tcg_temp_new();
500+
501+
if (!(ctx->insns_flags2 & PPC2_ISA310)) {
502+
/* if version is before v3.1, this operation is a nop */
503+
return true;
504+
}
505+
506+
if (unlikely(priv && ctx->pr)) {
507+
/* if instruction is privileged but the context is in user space */
508+
gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
509+
return 0;
510+
}
511+
512+
tcg_gen_addi_tl(ea, cpu_gpr[a->ra], a->rt);
513+
helper(cpu_env, ea, cpu_gpr[a->ra], cpu_gpr[a->rb]);
514+
515+
tcg_temp_free(ea);
516+
517+
return true;
518+
}
519+
520+
TRANS(HASHST, do_hash, false, gen_helper_HASHST)
521+
TRANS(HASHCHK, do_hash, false, gen_helper_HASHCHK)
522+
TRANS(HASHSTP, do_hash, true, gen_helper_HASHSTP)
523+
TRANS(HASHCHKP, do_hash, true, gen_helper_HASHCHKP)

0 commit comments

Comments
 (0)