968
}
969
}
970
971
+static bool irs_pe_selr_valid(GICv5Common *cs, GICv5Domain domain)
972
+{
973
+ /*
974
+ * Return true if IRS_PE_SELR has a valid AFFID in it. We don't
975
+ * expect the guest to do this except perhaps once at startup, so
976
+ * do a simple linear scan through the cpu_iaffids array.
977
+ */
978
+ for (int i = 0; i < cs->num_cpu_iaffids; i++) {
979
+ if (cs->irs_pe_selr[domain] == cs->cpu_iaffids[i]) {
980
+ return true;
981
+ }
982
+ }
983
+ return false;
984
+}
985
+
986
static bool config_readl(GICv5 *s, GICv5Domain domain, hwaddr offset,
987
uint64_t *data, MemTxAttrs attrs)
988
{
1106
/* Sync is a no-op for QEMU: we are always IDLE */
1107
*data = R_IRS_SYNC_STATUSR_IDLE_MASK;
1108
return true;
1109
+ case A_IRS_PE_SELR:
1110
+ *data = cs->irs_pe_selr[domain];
1111
+ return true;
1112
+ case A_IRS_PE_CR0:
1113
+ /* We don't implement 1ofN, so this is RAZ/WI for us */
1114
+ *data = 0;
1115
+ return true;
1116
+ case A_IRS_PE_STATUSR:
1117
+ /*
1118
+ * Our CPUs are always online, so we're really just reporting
1119
+ * whether the guest wrote a valid AFFID to IRS_PE_SELR
1120
+ */
1121
+ v = R_IRS_PE_STATUSR_IDLE_MASK;
1122
+ if (irs_pe_selr_valid(cs, domain)) {
1123
+ v |= R_IRS_PE_STATUSR_V_MASK | R_IRS_PE_STATUSR_ONLINE_MASK;
1124
+ }
1125
+ *data = v;
1126
+ return true;
1127
}
1128
1129
return false;
1212
case A_IRS_SYNCR:
1213
/* Sync is a no-op for QEMU: ignore write */
1214
return true;
1215
+ case A_IRS_PE_SELR:
1216
+ cs->irs_pe_selr[domain] = data;
1217
+ return true;
1218
+ case A_IRS_PE_CR0:
1219
+ /* We don't implement 1ofN, so this is RAZ/WI for us */
1220
+ return true;
1221
}
1222
1223
return false;