hw/intc/arm_gicv3_its: Add trace events for table reads and writes

For debugging guest use of the ITS, it can be helpful to trace
when the ITS reads and writes the in-memory tables.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220303202341.2232284-3-peter.maydell@linaro.org
This commit is contained in:
Peter Maydell 2022-03-03 20:23:38 +00:00
parent e40509801d
commit 930f40e90b
2 changed files with 40 additions and 6 deletions

View File

@ -161,16 +161,22 @@ static MemTxResult get_cte(GICv3ITSState *s, uint16_t icid, CTEntry *cte)
if (entry_addr == -1) {
/* No L2 table entry, i.e. no valid CTE, or a memory error */
cte->valid = false;
return res;
goto out;
}
cteval = address_space_ldq_le(as, entry_addr, MEMTXATTRS_UNSPECIFIED, &res);
if (res != MEMTX_OK) {
return res;
goto out;
}
cte->valid = FIELD_EX64(cteval, CTE, VALID);
cte->rdbase = FIELD_EX64(cteval, CTE, RDBASE);
return MEMTX_OK;
out:
if (res != MEMTX_OK) {
trace_gicv3_its_cte_read_fault(icid);
} else {
trace_gicv3_its_cte_read(icid, cte->valid, cte->rdbase);
}
return res;
}
/*
@ -187,6 +193,10 @@ static bool update_ite(GICv3ITSState *s, uint32_t eventid, const DTEntry *dte,
uint64_t itel = 0;
uint32_t iteh = 0;
trace_gicv3_its_ite_write(dte->ittaddr, eventid, ite->valid,
ite->inttype, ite->intid, ite->icid,
ite->vpeid, ite->doorbell);
if (ite->valid) {
itel = FIELD_DP64(itel, ITE_L, VALID, 1);
itel = FIELD_DP64(itel, ITE_L, INTTYPE, ite->inttype);
@ -221,11 +231,13 @@ static MemTxResult get_ite(GICv3ITSState *s, uint32_t eventid,
itel = address_space_ldq_le(as, iteaddr, MEMTXATTRS_UNSPECIFIED, &res);
if (res != MEMTX_OK) {
trace_gicv3_its_ite_read_fault(dte->ittaddr, eventid);
return res;
}
iteh = address_space_ldl_le(as, iteaddr + 8, MEMTXATTRS_UNSPECIFIED, &res);
if (res != MEMTX_OK) {
trace_gicv3_its_ite_read_fault(dte->ittaddr, eventid);
return res;
}
@ -235,6 +247,9 @@ static MemTxResult get_ite(GICv3ITSState *s, uint32_t eventid,
ite->icid = FIELD_EX64(itel, ITE_L, ICID);
ite->vpeid = FIELD_EX64(itel, ITE_L, VPEID);
ite->doorbell = FIELD_EX64(iteh, ITE_H, DOORBELL);
trace_gicv3_its_ite_read(dte->ittaddr, eventid, ite->valid,
ite->inttype, ite->intid, ite->icid,
ite->vpeid, ite->doorbell);
return MEMTX_OK;
}
@ -254,17 +269,23 @@ static MemTxResult get_dte(GICv3ITSState *s, uint32_t devid, DTEntry *dte)
if (entry_addr == -1) {
/* No L2 table entry, i.e. no valid DTE, or a memory error */
dte->valid = false;
return res;
goto out;
}
dteval = address_space_ldq_le(as, entry_addr, MEMTXATTRS_UNSPECIFIED, &res);
if (res != MEMTX_OK) {
return res;
goto out;
}
dte->valid = FIELD_EX64(dteval, DTE, VALID);
dte->size = FIELD_EX64(dteval, DTE, SIZE);
/* DTE word field stores bits [51:8] of the ITT address */
dte->ittaddr = FIELD_EX64(dteval, DTE, ITTADDR) << ITTADDR_SHIFT;
return MEMTX_OK;
out:
if (res != MEMTX_OK) {
trace_gicv3_its_dte_read_fault(devid);
} else {
trace_gicv3_its_dte_read(devid, dte->valid, dte->size, dte->ittaddr);
}
return res;
}
/*
@ -465,6 +486,8 @@ static bool update_cte(GICv3ITSState *s, uint16_t icid, const CTEntry *cte)
uint64_t cteval = 0;
MemTxResult res = MEMTX_OK;
trace_gicv3_its_cte_write(icid, cte->valid, cte->rdbase);
if (cte->valid) {
/* add mapping entry to collection table */
cteval = FIELD_DP64(cteval, CTE, VALID, 1);
@ -524,6 +547,8 @@ static bool update_dte(GICv3ITSState *s, uint32_t devid, const DTEntry *dte)
uint64_t dteval = 0;
MemTxResult res = MEMTX_OK;
trace_gicv3_its_dte_write(devid, dte->valid, dte->size, dte->ittaddr);
if (dte->valid) {
/* add mapping entry to device table */
dteval = FIELD_DP64(dteval, DTE, VALID, 1);

View File

@ -188,6 +188,15 @@ gicv3_its_cmd_inv(void) "GICv3 ITS: command INV or INVALL"
gicv3_its_cmd_movall(uint64_t rd1, uint64_t rd2) "GICv3 ITS: command MOVALL RDbase1 0x%" PRIx64 " RDbase2 0x%" PRIx64
gicv3_its_cmd_movi(uint32_t devid, uint32_t eventid, uint32_t icid) "GICv3 ITS: command MOVI DeviceID 0x%x EventID 0x%x ICID 0x%x"
gicv3_its_cmd_unknown(unsigned cmd) "GICv3 ITS: unknown command 0x%x"
gicv3_its_cte_read(uint32_t icid, int valid, uint32_t rdbase) "GICv3 ITS: Collection Table read for ICID 0x%x: valid %d RDBase 0x%x"
gicv3_its_cte_write(uint32_t icid, int valid, uint32_t rdbase) "GICv3 ITS: Collection Table write for ICID 0x%x: valid %d RDBase 0x%x"
gicv3_its_cte_read_fault(uint32_t icid) "GICv3 ITS: Collection Table read for ICID 0x%x: faulted"
gicv3_its_ite_read(uint64_t ittaddr, uint32_t eventid, int valid, int inttype, uint32_t intid, uint32_t icid, uint32_t vpeid, uint32_t doorbell) "GICv3 ITS: Interrupt Table read for ITTaddr 0x%" PRIx64 " EventID 0x%x: valid %d inttype %d intid 0x%x ICID 0x%x vPEID 0x%x doorbell 0x%x"
gicv3_its_ite_read_fault(uint64_t ittaddr, uint32_t eventid) "GICv3 ITS: Interrupt Table read for ITTaddr 0x%" PRIx64 " EventID 0x%x: faulted"
gicv3_its_ite_write(uint64_t ittaddr, uint32_t eventid, int valid, int inttype, uint32_t intid, uint32_t icid, uint32_t vpeid, uint32_t doorbell) "GICv3 ITS: Interrupt Table write for ITTaddr 0x%" PRIx64 " EventID 0x%x: valid %d inttype %d intid 0x%x ICID 0x%x vPEID 0x%x doorbell 0x%x"
gicv3_its_dte_read(uint32_t devid, int valid, uint32_t size, uint64_t ittaddr) "GICv3 ITS: Device Table read for DeviceID 0x%x: valid %d size 0x%x ITTaddr 0x%" PRIx64
gicv3_its_dte_write(uint32_t devid, int valid, uint32_t size, uint64_t ittaddr) "GICv3 ITS: Device Table write for DeviceID 0x%x: valid %d size 0x%x ITTaddr 0x%" PRIx64
gicv3_its_dte_read_fault(uint32_t devid) "GICv3 ITS: Device Table read for DeviceID 0x%x: faulted"
# armv7m_nvic.c
nvic_recompute_state(int vectpending, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d vectpending_prio %d exception_prio %d"