target/ppc: Restrict various common helpers to TCG
Move helpers common to system/user emulation to tcg-excp_helper.c. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Harsh Prateek Bora <harshpb@linux.ibm.com> Message-ID: <20250127102620.39159-12-philmd@linaro.org> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
This commit is contained in:
parent
1d0b82f86d
commit
ad8ad893a3
@ -2711,148 +2711,7 @@ void helper_rfmci(CPUPPCState *env)
|
||||
/* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
|
||||
do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
|
||||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
void helper_TW(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
|
||||
uint32_t flags)
|
||||
{
|
||||
if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) ||
|
||||
((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) ||
|
||||
((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) ||
|
||||
((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) ||
|
||||
((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) {
|
||||
raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
|
||||
POWERPC_EXCP_TRAP, GETPC());
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TARGET_PPC64
|
||||
void helper_TD(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
|
||||
uint32_t flags)
|
||||
{
|
||||
if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) ||
|
||||
((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) ||
|
||||
((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) ||
|
||||
((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) ||
|
||||
((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) {
|
||||
raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
|
||||
POWERPC_EXCP_TRAP, GETPC());
|
||||
}
|
||||
}
|
||||
#endif /* TARGET_PPC64 */
|
||||
|
||||
static uint32_t helper_SIMON_LIKE_32_64(uint32_t x, uint64_t key, uint32_t lane)
|
||||
{
|
||||
const uint16_t c = 0xfffc;
|
||||
const uint64_t z0 = 0xfa2561cdf44ac398ULL;
|
||||
uint16_t z = 0, temp;
|
||||
uint16_t k[32], eff_k[32], xleft[33], xright[33], fxleft[32];
|
||||
|
||||
for (int i = 3; i >= 0; i--) {
|
||||
k[i] = key & 0xffff;
|
||||
key >>= 16;
|
||||
}
|
||||
xleft[0] = x & 0xffff;
|
||||
xright[0] = (x >> 16) & 0xffff;
|
||||
|
||||
for (int i = 0; i < 28; i++) {
|
||||
z = (z0 >> (63 - i)) & 1;
|
||||
temp = ror16(k[i + 3], 3) ^ k[i + 1];
|
||||
k[i + 4] = c ^ z ^ k[i] ^ temp ^ ror16(temp, 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
eff_k[4 * i + 0] = k[4 * i + ((0 + lane) % 4)];
|
||||
eff_k[4 * i + 1] = k[4 * i + ((1 + lane) % 4)];
|
||||
eff_k[4 * i + 2] = k[4 * i + ((2 + lane) % 4)];
|
||||
eff_k[4 * i + 3] = k[4 * i + ((3 + lane) % 4)];
|
||||
}
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
fxleft[i] = (rol16(xleft[i], 1) &
|
||||
rol16(xleft[i], 8)) ^ rol16(xleft[i], 2);
|
||||
xleft[i + 1] = xright[i] ^ fxleft[i] ^ eff_k[i];
|
||||
xright[i + 1] = xleft[i];
|
||||
}
|
||||
|
||||
return (((uint32_t)xright[32]) << 16) | xleft[32];
|
||||
}
|
||||
|
||||
static uint64_t hash_digest(uint64_t ra, uint64_t rb, uint64_t key)
|
||||
{
|
||||
uint64_t stage0_h = 0ULL, stage0_l = 0ULL;
|
||||
uint64_t stage1_h, stage1_l;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
stage0_h |= ror64(rb & 0xff, 8 * (2 * i + 1));
|
||||
stage0_h |= ((ra >> 32) & 0xff) << (8 * 2 * i);
|
||||
stage0_l |= ror64((rb >> 32) & 0xff, 8 * (2 * i + 1));
|
||||
stage0_l |= (ra & 0xff) << (8 * 2 * i);
|
||||
rb >>= 8;
|
||||
ra >>= 8;
|
||||
}
|
||||
|
||||
stage1_h = (uint64_t)helper_SIMON_LIKE_32_64(stage0_h >> 32, key, 0) << 32;
|
||||
stage1_h |= helper_SIMON_LIKE_32_64(stage0_h, key, 1);
|
||||
stage1_l = (uint64_t)helper_SIMON_LIKE_32_64(stage0_l >> 32, key, 2) << 32;
|
||||
stage1_l |= helper_SIMON_LIKE_32_64(stage0_l, key, 3);
|
||||
|
||||
return stage1_h ^ stage1_l;
|
||||
}
|
||||
|
||||
static void do_hash(CPUPPCState *env, target_ulong ea, target_ulong ra,
|
||||
target_ulong rb, uint64_t key, bool store)
|
||||
{
|
||||
uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash;
|
||||
|
||||
if (store) {
|
||||
cpu_stq_data_ra(env, ea, calculated_hash, GETPC());
|
||||
} else {
|
||||
loaded_hash = cpu_ldq_data_ra(env, ea, GETPC());
|
||||
if (loaded_hash != calculated_hash) {
|
||||
raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
|
||||
POWERPC_EXCP_TRAP, GETPC());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "qemu/guest-random.h"
|
||||
|
||||
#ifdef TARGET_PPC64
|
||||
#define HELPER_HASH(op, key, store, dexcr_aspect) \
|
||||
void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \
|
||||
target_ulong rb) \
|
||||
{ \
|
||||
if (env->msr & R_MSR_PR_MASK) { \
|
||||
if (!(env->spr[SPR_DEXCR] & R_DEXCR_PRO_##dexcr_aspect##_MASK || \
|
||||
env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \
|
||||
return; \
|
||||
} else if (!(env->msr & R_MSR_HV_MASK)) { \
|
||||
if (!(env->spr[SPR_DEXCR] & R_DEXCR_PNH_##dexcr_aspect##_MASK || \
|
||||
env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \
|
||||
return; \
|
||||
} else if (!(env->msr & R_MSR_S_MASK)) { \
|
||||
if (!(env->spr[SPR_HDEXCR] & R_HDEXCR_HNU_##dexcr_aspect##_MASK)) \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
do_hash(env, ea, ra, rb, key, store); \
|
||||
}
|
||||
#else
|
||||
#define HELPER_HASH(op, key, store, dexcr_aspect) \
|
||||
void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \
|
||||
target_ulong rb) \
|
||||
{ \
|
||||
do_hash(env, ea, ra, rb, key, store); \
|
||||
}
|
||||
#endif /* TARGET_PPC64 */
|
||||
|
||||
HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true, NPHIE)
|
||||
HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false, NPHIE)
|
||||
HELPER_HASH(HASHSTP, env->spr[SPR_HASHPKEYR], true, PHIE)
|
||||
HELPER_HASH(HASHCHKP, env->spr[SPR_HASHPKEYR], false, PHIE)
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
/* Embedded.Processor Control */
|
||||
static int dbell2irq(target_ulong rb)
|
||||
{
|
||||
|
@ -66,6 +66,149 @@ void raise_exception(CPUPPCState *env, uint32_t exception)
|
||||
raise_exception_err_ra(env, exception, 0, 0);
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
void helper_TW(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
|
||||
uint32_t flags)
|
||||
{
|
||||
if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) ||
|
||||
((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) ||
|
||||
((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) ||
|
||||
((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) ||
|
||||
((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) {
|
||||
raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
|
||||
POWERPC_EXCP_TRAP, GETPC());
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TARGET_PPC64
|
||||
void helper_TD(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
|
||||
uint32_t flags)
|
||||
{
|
||||
if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) ||
|
||||
((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) ||
|
||||
((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) ||
|
||||
((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) ||
|
||||
((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) {
|
||||
raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
|
||||
POWERPC_EXCP_TRAP, GETPC());
|
||||
}
|
||||
}
|
||||
#endif /* TARGET_PPC64 */
|
||||
|
||||
static uint32_t helper_SIMON_LIKE_32_64(uint32_t x, uint64_t key, uint32_t lane)
|
||||
{
|
||||
const uint16_t c = 0xfffc;
|
||||
const uint64_t z0 = 0xfa2561cdf44ac398ULL;
|
||||
uint16_t z = 0, temp;
|
||||
uint16_t k[32], eff_k[32], xleft[33], xright[33], fxleft[32];
|
||||
|
||||
for (int i = 3; i >= 0; i--) {
|
||||
k[i] = key & 0xffff;
|
||||
key >>= 16;
|
||||
}
|
||||
xleft[0] = x & 0xffff;
|
||||
xright[0] = (x >> 16) & 0xffff;
|
||||
|
||||
for (int i = 0; i < 28; i++) {
|
||||
z = (z0 >> (63 - i)) & 1;
|
||||
temp = ror16(k[i + 3], 3) ^ k[i + 1];
|
||||
k[i + 4] = c ^ z ^ k[i] ^ temp ^ ror16(temp, 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
eff_k[4 * i + 0] = k[4 * i + ((0 + lane) % 4)];
|
||||
eff_k[4 * i + 1] = k[4 * i + ((1 + lane) % 4)];
|
||||
eff_k[4 * i + 2] = k[4 * i + ((2 + lane) % 4)];
|
||||
eff_k[4 * i + 3] = k[4 * i + ((3 + lane) % 4)];
|
||||
}
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
fxleft[i] = (rol16(xleft[i], 1) &
|
||||
rol16(xleft[i], 8)) ^ rol16(xleft[i], 2);
|
||||
xleft[i + 1] = xright[i] ^ fxleft[i] ^ eff_k[i];
|
||||
xright[i + 1] = xleft[i];
|
||||
}
|
||||
|
||||
return (((uint32_t)xright[32]) << 16) | xleft[32];
|
||||
}
|
||||
|
||||
static uint64_t hash_digest(uint64_t ra, uint64_t rb, uint64_t key)
|
||||
{
|
||||
uint64_t stage0_h = 0ULL, stage0_l = 0ULL;
|
||||
uint64_t stage1_h, stage1_l;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
stage0_h |= ror64(rb & 0xff, 8 * (2 * i + 1));
|
||||
stage0_h |= ((ra >> 32) & 0xff) << (8 * 2 * i);
|
||||
stage0_l |= ror64((rb >> 32) & 0xff, 8 * (2 * i + 1));
|
||||
stage0_l |= (ra & 0xff) << (8 * 2 * i);
|
||||
rb >>= 8;
|
||||
ra >>= 8;
|
||||
}
|
||||
|
||||
stage1_h = (uint64_t)helper_SIMON_LIKE_32_64(stage0_h >> 32, key, 0) << 32;
|
||||
stage1_h |= helper_SIMON_LIKE_32_64(stage0_h, key, 1);
|
||||
stage1_l = (uint64_t)helper_SIMON_LIKE_32_64(stage0_l >> 32, key, 2) << 32;
|
||||
stage1_l |= helper_SIMON_LIKE_32_64(stage0_l, key, 3);
|
||||
|
||||
return stage1_h ^ stage1_l;
|
||||
}
|
||||
|
||||
static void do_hash(CPUPPCState *env, target_ulong ea, target_ulong ra,
|
||||
target_ulong rb, uint64_t key, bool store)
|
||||
{
|
||||
uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash;
|
||||
|
||||
if (store) {
|
||||
cpu_stq_data_ra(env, ea, calculated_hash, GETPC());
|
||||
} else {
|
||||
loaded_hash = cpu_ldq_data_ra(env, ea, GETPC());
|
||||
if (loaded_hash != calculated_hash) {
|
||||
raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
|
||||
POWERPC_EXCP_TRAP, GETPC());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "qemu/guest-random.h"
|
||||
|
||||
#ifdef TARGET_PPC64
|
||||
#define HELPER_HASH(op, key, store, dexcr_aspect) \
|
||||
void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \
|
||||
target_ulong rb) \
|
||||
{ \
|
||||
if (env->msr & R_MSR_PR_MASK) { \
|
||||
if (!(env->spr[SPR_DEXCR] & R_DEXCR_PRO_##dexcr_aspect##_MASK || \
|
||||
env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \
|
||||
return; \
|
||||
} else if (!(env->msr & R_MSR_HV_MASK)) { \
|
||||
if (!(env->spr[SPR_DEXCR] & R_DEXCR_PNH_##dexcr_aspect##_MASK || \
|
||||
env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \
|
||||
return; \
|
||||
} else if (!(env->msr & R_MSR_S_MASK)) { \
|
||||
if (!(env->spr[SPR_HDEXCR] & R_HDEXCR_HNU_##dexcr_aspect##_MASK)) \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
do_hash(env, ea, ra, rb, key, store); \
|
||||
}
|
||||
#else
|
||||
#define HELPER_HASH(op, key, store, dexcr_aspect) \
|
||||
void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \
|
||||
target_ulong rb) \
|
||||
{ \
|
||||
do_hash(env, ea, ra, rb, key, store); \
|
||||
}
|
||||
#endif /* TARGET_PPC64 */
|
||||
|
||||
HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true, NPHIE)
|
||||
HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false, NPHIE)
|
||||
HELPER_HASH(HASHSTP, env->spr[SPR_HASHPKEYR], true, PHIE)
|
||||
HELPER_HASH(HASHCHKP, env->spr[SPR_HASHPKEYR], false, PHIE)
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
|
||||
void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
|
||||
MMUAccessType access_type,
|
||||
int mmu_idx, uintptr_t retaddr)
|
||||
|
Loading…
x
Reference in New Issue
Block a user