mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 09:13:55 -06:00
hw/arm/smmuv3: Event queue recording helper
Let's introduce a helper function aiming at recording an event in the event queue. Signed-off-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 1524665762-31355-9-git-send-email-eric.auger@redhat.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
fae4be38b3
commit
bb981004ea
3 changed files with 249 additions and 8 deletions
108
hw/arm/smmuv3.c
108
hw/arm/smmuv3.c
|
@ -117,23 +117,119 @@ static MemTxResult queue_write(SMMUQueue *q, void *data)
|
|||
return MEMTX_OK;
|
||||
}
|
||||
|
||||
void smmuv3_write_eventq(SMMUv3State *s, Evt *evt)
|
||||
static MemTxResult smmuv3_write_eventq(SMMUv3State *s, Evt *evt)
|
||||
{
|
||||
SMMUQueue *q = &s->eventq;
|
||||
MemTxResult r;
|
||||
|
||||
if (!smmuv3_eventq_enabled(s)) {
|
||||
return MEMTX_ERROR;
|
||||
}
|
||||
|
||||
if (smmuv3_q_full(q)) {
|
||||
return MEMTX_ERROR;
|
||||
}
|
||||
|
||||
r = queue_write(q, evt);
|
||||
if (r != MEMTX_OK) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (smmuv3_q_empty(q)) {
|
||||
smmuv3_trigger_irq(s, SMMU_IRQ_EVTQ, 0);
|
||||
}
|
||||
return MEMTX_OK;
|
||||
}
|
||||
|
||||
void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *info)
|
||||
{
|
||||
Evt evt;
|
||||
MemTxResult r;
|
||||
|
||||
if (!smmuv3_eventq_enabled(s)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (smmuv3_q_full(q)) {
|
||||
EVT_SET_TYPE(&evt, info->type);
|
||||
EVT_SET_SID(&evt, info->sid);
|
||||
|
||||
switch (info->type) {
|
||||
case SMMU_EVT_OK:
|
||||
return;
|
||||
case SMMU_EVT_F_UUT:
|
||||
EVT_SET_SSID(&evt, info->u.f_uut.ssid);
|
||||
EVT_SET_SSV(&evt, info->u.f_uut.ssv);
|
||||
EVT_SET_ADDR(&evt, info->u.f_uut.addr);
|
||||
EVT_SET_RNW(&evt, info->u.f_uut.rnw);
|
||||
EVT_SET_PNU(&evt, info->u.f_uut.pnu);
|
||||
EVT_SET_IND(&evt, info->u.f_uut.ind);
|
||||
break;
|
||||
case SMMU_EVT_C_BAD_STREAMID:
|
||||
EVT_SET_SSID(&evt, info->u.c_bad_streamid.ssid);
|
||||
EVT_SET_SSV(&evt, info->u.c_bad_streamid.ssv);
|
||||
break;
|
||||
case SMMU_EVT_F_STE_FETCH:
|
||||
EVT_SET_SSID(&evt, info->u.f_ste_fetch.ssid);
|
||||
EVT_SET_SSV(&evt, info->u.f_ste_fetch.ssv);
|
||||
EVT_SET_ADDR(&evt, info->u.f_ste_fetch.addr);
|
||||
break;
|
||||
case SMMU_EVT_C_BAD_STE:
|
||||
EVT_SET_SSID(&evt, info->u.c_bad_ste.ssid);
|
||||
EVT_SET_SSV(&evt, info->u.c_bad_ste.ssv);
|
||||
break;
|
||||
case SMMU_EVT_F_STREAM_DISABLED:
|
||||
break;
|
||||
case SMMU_EVT_F_TRANS_FORBIDDEN:
|
||||
EVT_SET_ADDR(&evt, info->u.f_transl_forbidden.addr);
|
||||
EVT_SET_RNW(&evt, info->u.f_transl_forbidden.rnw);
|
||||
break;
|
||||
case SMMU_EVT_C_BAD_SUBSTREAMID:
|
||||
EVT_SET_SSID(&evt, info->u.c_bad_substream.ssid);
|
||||
break;
|
||||
case SMMU_EVT_F_CD_FETCH:
|
||||
EVT_SET_SSID(&evt, info->u.f_cd_fetch.ssid);
|
||||
EVT_SET_SSV(&evt, info->u.f_cd_fetch.ssv);
|
||||
EVT_SET_ADDR(&evt, info->u.f_cd_fetch.addr);
|
||||
break;
|
||||
case SMMU_EVT_C_BAD_CD:
|
||||
EVT_SET_SSID(&evt, info->u.c_bad_cd.ssid);
|
||||
EVT_SET_SSV(&evt, info->u.c_bad_cd.ssv);
|
||||
break;
|
||||
case SMMU_EVT_F_WALK_EABT:
|
||||
case SMMU_EVT_F_TRANSLATION:
|
||||
case SMMU_EVT_F_ADDR_SIZE:
|
||||
case SMMU_EVT_F_ACCESS:
|
||||
case SMMU_EVT_F_PERMISSION:
|
||||
EVT_SET_STALL(&evt, info->u.f_walk_eabt.stall);
|
||||
EVT_SET_STAG(&evt, info->u.f_walk_eabt.stag);
|
||||
EVT_SET_SSID(&evt, info->u.f_walk_eabt.ssid);
|
||||
EVT_SET_SSV(&evt, info->u.f_walk_eabt.ssv);
|
||||
EVT_SET_S2(&evt, info->u.f_walk_eabt.s2);
|
||||
EVT_SET_ADDR(&evt, info->u.f_walk_eabt.addr);
|
||||
EVT_SET_RNW(&evt, info->u.f_walk_eabt.rnw);
|
||||
EVT_SET_PNU(&evt, info->u.f_walk_eabt.pnu);
|
||||
EVT_SET_IND(&evt, info->u.f_walk_eabt.ind);
|
||||
EVT_SET_CLASS(&evt, info->u.f_walk_eabt.class);
|
||||
EVT_SET_ADDR2(&evt, info->u.f_walk_eabt.addr2);
|
||||
break;
|
||||
case SMMU_EVT_F_CFG_CONFLICT:
|
||||
EVT_SET_SSID(&evt, info->u.f_cfg_conflict.ssid);
|
||||
EVT_SET_SSV(&evt, info->u.f_cfg_conflict.ssv);
|
||||
break;
|
||||
/* rest is not implemented */
|
||||
case SMMU_EVT_F_BAD_ATS_TREQ:
|
||||
case SMMU_EVT_F_TLB_CONFLICT:
|
||||
case SMMU_EVT_E_PAGE_REQ:
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
queue_write(q, evt);
|
||||
|
||||
if (smmuv3_q_empty(q)) {
|
||||
smmuv3_trigger_irq(s, SMMU_IRQ_EVTQ, 0);
|
||||
trace_smmuv3_record_event(smmu_event_string(info->type), info->sid);
|
||||
r = smmuv3_write_eventq(s, &evt);
|
||||
if (r != MEMTX_OK) {
|
||||
smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, R_GERROR_EVENTQ_ABT_ERR_MASK);
|
||||
}
|
||||
info->recorded = true;
|
||||
}
|
||||
|
||||
static void smmuv3_init_regs(SMMUv3State *s)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue