FIELD(ICC_PCR, PRIORITY, 0, 5)
+FIELD(ICC_HPPIR_EL1, ID, 0, 24)
+FIELD(ICC_HPPIR_EL1, TYPE, 29, 3)
+FIELD(ICC_HPPIR_EL1, HPPIV, 32, 1)
+
/*
* We implement 24 bits of interrupt ID, the mandated 5 bits of priority,
* and no legacy GICv3.3 vcpu interface (yet)
return hap < 32 ? hap : PRIO_IDLE;
}
+static GICv5PendingIrq gic_hppi(CPUARMState *env, GICv5Domain domain)
+{
+ /*
+ * Return the current highest priority pending interrupt for the
+ * specified domain, if it has sufficient priority to preempt. The
+ * intid field of the return value will be in the format of the
+ * ICC_HPPIR register (and will be zero if and only if there is no
+ * interrupt that can preempt).
+ */
+
+ GICv5Common *gic = gicv5_get_gic(env);
+ GICv5PendingIrq best, irs_hppi;
+
+ if (!(env->gicv5_cpuif.icc_cr0[domain] & R_ICC_CR0_EN_MASK)) {
+ /* If cpuif is disabled there is no HPPI */
+ return (GICv5PendingIrq) { .intid = 0, .prio = PRIO_IDLE };
+ }
+
+ irs_hppi = gicv5_get_hppi(gic, domain, env->gicv5_iaffid);
+
+ /*
+ * If the best PPI and the best interrupt from the IRS have the
+ * same priority, it's IMPDEF which we pick (R_VVBPS). We choose
+ * the PPI.
+ */
+ if (env->gicv5_cpuif.ppi_hppi[domain].prio <= irs_hppi.prio) {
+ best = env->gicv5_cpuif.ppi_hppi[domain];
+ } else {
+ best = irs_hppi;
+ }
+
+ /*
+ * D_MSQKF: an interrupt has sufficient priority if its priority
+ * is higher than the current running priority and equal to or
+ * higher than the priority mask.
+ */
+ if (best.prio == PRIO_IDLE ||
+ best.prio > env->gicv5_cpuif.icc_pcr[domain] ||
+ best.prio >= gic_running_prio(env, domain)) {
+ return (GICv5PendingIrq) { .intid = 0, .prio = PRIO_IDLE };
+ }
+ best.intid |= R_ICC_HPPIR_EL1_HPPIV_MASK;
+ return best;
+}
+
static void gic_recalc_ppi_hppi(CPUARMState *env)
{
/*
}
}
+static uint64_t gic_icc_hppir_el1_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ GICv5Domain domain = gicv5_logical_domain(env);
+ GICv5PendingIrq hppi = gic_hppi(env, domain);
+ return hppi.intid;
+}
+
static const ARMCPRegInfo gicv5_cpuif_reginfo[] = {
/*
* Barrier: wait until the effects of a cpuif system register
.fieldoffset = offsetof(CPUARMState, gicv5_cpuif.ppi_hm[1]),
.resetvalue = PPI_HMR1_RESET,
},
+ { .name = "ICC_HPPIR_EL1", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 10, .opc2 = 3,
+ .access = PL1_R, .type = ARM_CP_IO | ARM_CP_NO_RAW,
+ .readfn = gic_icc_hppir_el1_read,
+ },
{ .name = "ICC_PPI_ENABLER0_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 10, .opc2 = 6,
.access = PL1_RW, .type = ARM_CP_IO | ARM_CP_NO_RAW,