mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-22 13:01:05 +00:00
target/arm: Implement ARMv8.5-RNG
Use the newly introduced infrastructure for guest random numbers. Backports commit de390645675966cce113bf5394445bc1f8d07c85 from qemu (with the actual RNG portion disabled to preserve determinism for the time being).
This commit is contained in:
parent
a8df33c37c
commit
3dd7358a53
|
@ -3474,6 +3474,11 @@ static inline bool isar_feature_aa64_condm_5(const ARMISARegisters *id)
|
|||
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) >= 2;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_rndr(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RNDR) != 0;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
|
||||
|
|
|
@ -268,6 +268,7 @@ static void aarch64_max_initfn(struct uc_struct *uc, Object *obj, void *opaque)
|
|||
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */
|
||||
t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1);
|
||||
cpu->isar.id_aa64isar0 = t;
|
||||
|
||||
t = cpu->isar.id_aa64isar1;
|
||||
|
|
|
@ -5559,6 +5559,50 @@ static const ARMCPRegInfo pauth_reginfo[] = {
|
|||
.fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
|
||||
REGINFO_SENTINEL
|
||||
};
|
||||
|
||||
static uint64_t rndr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
{
|
||||
uint64_t ret = 0;
|
||||
|
||||
/* Success sets NZCV = 0000. */
|
||||
env->NF = env->CF = env->VF = 0, env->ZF = 1;
|
||||
|
||||
// Unicorn: commented out.
|
||||
// Currently we don't rely on host state.
|
||||
#if 0
|
||||
Error *err = NULL;
|
||||
if (qemu_guest_getrandom(&ret, sizeof(ret), &err) < 0) {
|
||||
/*
|
||||
* ??? Failed, for unknown reasons in the crypto subsystem.
|
||||
* The best we can do is log the reason and return the
|
||||
* timed-out indication to the guest. There is no reason
|
||||
* we know to expect this failure to be transitory, so the
|
||||
* guest may well hang retrying the operation.
|
||||
*/
|
||||
qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s",
|
||||
ri->name, error_get_pretty(err));
|
||||
error_free(err);
|
||||
|
||||
env->ZF = 0; /* NZCF = 0100 */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* We do not support re-seeding, so the two registers operate the same. */
|
||||
static const ARMCPRegInfo rndr_reginfo[] = {
|
||||
{ .name = "RNDR", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
|
||||
.opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 0,
|
||||
.access = PL0_R, .readfn = rndr_readfn },
|
||||
{ .name = "RNDRRS", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
|
||||
.opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 1,
|
||||
.access = PL0_R, .readfn = rndr_readfn },
|
||||
REGINFO_SENTINEL
|
||||
};
|
||||
#endif
|
||||
|
||||
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
|
@ -6503,6 +6547,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
|||
if (cpu_isar_feature(aa64_pauth, cpu)) {
|
||||
define_arm_cp_regs(cpu, pauth_reginfo);
|
||||
}
|
||||
if (cpu_isar_feature(aa64_rndr, cpu)) {
|
||||
define_arm_cp_regs(cpu, rndr_reginfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue