95
return gicv5_logical_domain(env);
96
}
97
98
+static uint64_t gic_running_prio(CPUARMState *env, GICv5Domain domain)
99
+{
100
+ /*
101
+ * Return the current running priority; this is the lowest set bit in
102
+ * the Active Priority Register, or the idle priority if none (D_XMBQZ)
103
+ */
104
+ uint64_t hap = ctz64(env->gicv5_cpuif.icc_apr[domain]);
105
+ return hap < 32 ? hap : PRIO_IDLE;
106
+}
107
+
108
static void gic_cddis_write(CPUARMState *env, const ARMCPRegInfo *ri,
109
uint64_t value)
110
{
241
raw_write(env, ri, value);
242
}
243
244
+/*
245
+ * ICC_APR_EL1 is banked and reads/writes as the version for the
246
+ * current logical interrupt domain.
247
+ */
248
+static void gic_icc_apr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
249
+ uint64_t value)
250
+{
251
+ /*
252
+ * With an architectural 5 bits of priority, this register has 32
253
+ * non-RES0 bits
254
+ */
255
+ GICv5Domain domain = gicv5_logical_domain(env);
256
+ value &= 0xffffffff;
257
+ env->gicv5_cpuif.icc_apr[domain] = value;
258
+}
259
+
260
+static uint64_t gic_icc_apr_el1_read(CPUARMState *env, const ARMCPRegInfo *ri)
261
+{
262
+ GICv5Domain domain = gicv5_logical_domain(env);
263
+ return env->gicv5_cpuif.icc_apr[domain];
264
+}
265
+
266
+static void gic_icc_apr_el1_reset(CPUARMState *env, const ARMCPRegInfo *ri)
267
+{
268
+ for (int i = 0; i < ARRAY_SIZE(env->gicv5_cpuif.icc_apr); i++) {
269
+ env->gicv5_cpuif.icc_apr[i] = 0;
270
+ }
271
+}
272
+
273
+static uint64_t gic_icc_hapr_el1_read(CPUARMState *env, const ARMCPRegInfo *ri)
274
+{
275
+ /*
276
+ * ICC_HAPR_EL1 reports the current running priority, which can be
277
+ * calculated from the APR register.
278
+ */
279
+ return gic_running_prio(env, gicv5_current_phys_domain(env));
280
+}
281
+
282
static const ARMCPRegInfo gicv5_cpuif_reginfo[] = {
283
/*
284
* Barrier: wait until the effects of a cpuif system register
430
.fieldoffset = offsetof(CPUARMState, gicv5_cpuif.ppi_pend[1]),
431
.writefn = gic_ppi_spend_write,
432
},
433
+ { .name = "ICC_APR_EL1", .state = ARM_CP_STATE_AA64,
434
+ .opc0 = 3, .opc1 = 1, .crn = 12, .crm = 0, .opc2 = 0,
435
+ .access = PL1_RW, .type = ARM_CP_IO | ARM_CP_NO_RAW,
436
+ .readfn = gic_icc_apr_el1_read,
437
+ .writefn = gic_icc_apr_el1_write,
438
+ .resetfn = gic_icc_apr_el1_reset,
439
+ },
440
+ { .name = "ICC_HAPR_EL1", .state = ARM_CP_STATE_AA64,
441
+ .opc0 = 3, .opc1 = 1, .crn = 12, .crm = 0, .opc2 = 3,
442
+ .access = PL1_R, .type = ARM_CP_IO | ARM_CP_NO_RAW,
443
+ .readfn = gic_icc_hapr_el1_read, .raw_writefn = arm_cp_write_ignore,
444
+ },
445
};
446
447
void define_gicv5_cpuif_regs(ARMCPU *cpu)