target/arm: Implement the ARMv8.1-LOR extension

Provide a trivial implementation with zero limited ordering regions,
which causes the LDLAR and STLLR instructions to devolve into the
LDAR and STLR instructions from the base ARMv8.0 instruction set.

Backports commit 2d7137c10fafefe40a0a049ff8a7bd78b66e661f from qemu
This commit is contained in:
Richard Henderson 2018-12-18 04:35:48 -05:00 committed by Lioncash
parent 32208e482b
commit 8816550c10
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7
4 changed files with 93 additions and 0 deletions

View File

@ -3326,6 +3326,11 @@ static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
}
static inline bool isar_feature_aa64_lor(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0;
}
/*
* Forward to the above feature tests given an ARMCPU pointer.
*/

View File

@ -271,6 +271,7 @@ static void aarch64_max_initfn(struct uc_struct *uc, Object *obj, void *opaque)
t = cpu->isar.id_aa64mmfr1;
t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */
t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);
cpu->isar.id_aa64mmfr1 = t;
/* Replicate the same data to the 32-bit id registers. */

View File

@ -1145,6 +1145,7 @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
{
/* Begin with base v8.0 state. */
uint32_t valid_mask = 0x3fff;
ARMCPU *cpu = arm_env_get_cpu(env);
if (arm_el_is_aa64(env, 3)) {
value |= SCR_FW | SCR_AW; /* these two bits are RES1. */
@ -1167,6 +1168,9 @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
valid_mask &= ~SCR_SMD;
}
}
if (cpu_isar_feature(aa64_lor, cpu)) {
valid_mask |= SCR_TLOR;
}
/* Clear all-context RES0 bits. */
value &= valid_mask;
@ -3517,6 +3521,9 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
*/
valid_mask &= ~HCR_TSC;
}
if (cpu_isar_feature(aa64_lor, cpu)) {
valid_mask |= HCR_TLOR;
}
/* Clear RES0 bits. */
value &= valid_mask;
@ -4425,6 +4432,42 @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
return pfr0;
}
/* Shared logic between LORID and the rest of the LOR* registers.
* Secure state has already been delt with.
*/
static CPAccessResult access_lor_ns(CPUARMState *env)
{
int el = arm_current_el(env);
if (el < 2 && (arm_hcr_el2_eff(env) & HCR_TLOR)) {
return CP_ACCESS_TRAP_EL2;
}
if (el < 3 && (env->cp15.scr_el3 & SCR_TLOR)) {
return CP_ACCESS_TRAP_EL3;
}
return CP_ACCESS_OK;
}
static CPAccessResult access_lorid(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
if (arm_is_secure_below_el3(env)) {
/* Access ok in secure mode. */
return CP_ACCESS_OK;
}
return access_lor_ns(env);
}
static CPAccessResult access_lor_other(CPUARMState *env,
const ARMCPRegInfo *ri, bool isread)
{
if (arm_is_secure_below_el3(env)) {
/* Access denied in secure mode. */
return CP_ACCESS_TRAP;
}
return access_lor_ns(env);
}
void register_cp_regs_for_features(ARMCPU *cpu)
{
/* Register all the coprocessor registers based on feature bits */
@ -4981,6 +5024,38 @@ void register_cp_regs_for_features(ARMCPU *cpu)
define_one_arm_cp_reg(cpu, &sctlr);
}
if (cpu_isar_feature(aa64_lor, cpu)) {
/*
* A trivial implementation of ARMv8.1-LOR leaves all of these
* registers fixed at 0, which indicates that there are zero
* supported Limited Ordering regions.
*/
static const ARMCPRegInfo lor_reginfo[] = {
{ .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0,
.access = PL1_RW, .accessfn = access_lor_other,
.type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1,
.access = PL1_RW, .accessfn = access_lor_other,
.type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "LORN_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2,
.access = PL1_RW, .accessfn = access_lor_other,
.type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "LORC_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3,
.access = PL1_RW, .accessfn = access_lor_other,
.type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
.access = PL1_R, .accessfn = access_lorid,
.type = ARM_CP_CONST, .resetvalue = 0 },
REGINFO_SENTINEL
};
define_arm_cp_regs(cpu, lor_reginfo);
}
if (cpu_isar_feature(aa64_sve, cpu)) {
define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
if (arm_feature(env, ARM_FEATURE_EL2)) {

View File

@ -2351,6 +2351,12 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
}
return;
case 0x8: /* STLLR */
if (!dc_isar_feature(aa64_lor, s)) {
break;
}
/* StoreLORelease is the same as Store-Release for QEMU. */
/* fall through */
case 0x9: /* STLR */
/* Generate ISS for non-exclusive accesses including LASR. */
if (rn == 31) {
@ -2362,6 +2368,12 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
return;
case 0xc: /* LDLAR */
if (!dc_isar_feature(aa64_lor, s)) {
break;
}
/* LoadLOAcquire is the same as Load-Acquire for QEMU. */
/* fall through */
case 0xd: /* LDAR */
/* Generate ISS for non-exclusive accesses including LASR. */
if (rn == 31) {