hw/intc/arm_gicv3_its: Make update_ite() use ITEntry

Make the update_ite() struct use the new ITEntry struct, so that
callers don't need to assemble the in-memory ITE data themselves, and
only get_ite() and update_ite() need to care about that in-memory
layout.  We can then drop the no-longer-used IteEntry struct
definition.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220201193207.2771604-10-peter.maydell@linaro.org
This commit is contained in:
Peter Maydell 2022-02-01 19:32:03 +00:00
parent 244194fe24
commit 7eb54267f2
1 changed files with 32 additions and 30 deletions

View File

@ -41,11 +41,6 @@ typedef enum ItsCmdType {
INTERRUPT = 3, INTERRUPT = 3,
} ItsCmdType; } ItsCmdType;
typedef struct {
uint32_t iteh;
uint64_t itel;
} IteEntry;
typedef struct DTEntry { typedef struct DTEntry {
bool valid; bool valid;
unsigned size; unsigned size;
@ -178,24 +173,35 @@ static MemTxResult get_cte(GICv3ITSState *s, uint16_t icid, CTEntry *cte)
return MEMTX_OK; return MEMTX_OK;
} }
/*
* Update the Interrupt Table entry at index @evinted in the table specified
* by the dte @dte. Returns true on success, false if there was a memory
* access error.
*/
static bool update_ite(GICv3ITSState *s, uint32_t eventid, const DTEntry *dte, static bool update_ite(GICv3ITSState *s, uint32_t eventid, const DTEntry *dte,
IteEntry ite) const ITEntry *ite)
{ {
AddressSpace *as = &s->gicv3->dma_as; AddressSpace *as = &s->gicv3->dma_as;
MemTxResult res = MEMTX_OK; MemTxResult res = MEMTX_OK;
hwaddr iteaddr = dte->ittaddr + eventid * ITS_ITT_ENTRY_SIZE; hwaddr iteaddr = dte->ittaddr + eventid * ITS_ITT_ENTRY_SIZE;
uint64_t itel = 0;
uint32_t iteh = 0;
address_space_stq_le(as, iteaddr, ite.itel, MEMTXATTRS_UNSPECIFIED, &res); if (ite->valid) {
itel = FIELD_DP64(itel, ITE_L, VALID, 1);
if (res == MEMTX_OK) { itel = FIELD_DP64(itel, ITE_L, INTTYPE, ite->inttype);
address_space_stl_le(as, iteaddr + 8, ite.iteh, itel = FIELD_DP64(itel, ITE_L, INTID, ite->intid);
MEMTXATTRS_UNSPECIFIED, &res); itel = FIELD_DP64(itel, ITE_L, ICID, ite->icid);
itel = FIELD_DP64(itel, ITE_L, VPEID, ite->vpeid);
iteh = FIELD_DP32(iteh, ITE_H, DOORBELL, ite->doorbell);
} }
address_space_stq_le(as, iteaddr, itel, MEMTXATTRS_UNSPECIFIED, &res);
if (res != MEMTX_OK) { if (res != MEMTX_OK) {
return false; return false;
} else {
return true;
} }
address_space_stl_le(as, iteaddr + 8, iteh, MEMTXATTRS_UNSPECIFIED, &res);
return res == MEMTX_OK;
} }
/* /*
@ -346,9 +352,10 @@ static ItsCmdResult do_process_its_cmd(GICv3ITSState *s, uint32_t devid,
} }
if (cmd == DISCARD) { if (cmd == DISCARD) {
IteEntry itee = {}; ITEntry ite = {};
/* remove mapping from interrupt translation table */ /* remove mapping from interrupt translation table */
return update_ite(s, eventid, &dte, itee) ? CMD_CONTINUE : CMD_STALL; ite.valid = false;
return update_ite(s, eventid, &dte, &ite) ? CMD_CONTINUE : CMD_STALL;
} }
return CMD_CONTINUE; return CMD_CONTINUE;
} }
@ -370,8 +377,8 @@ static ItsCmdResult process_mapti(GICv3ITSState *s, const uint64_t *cmdpkt,
uint64_t num_eventids; uint64_t num_eventids;
uint32_t num_intids; uint32_t num_intids;
uint16_t icid = 0; uint16_t icid = 0;
IteEntry ite = {};
DTEntry dte; DTEntry dte;
ITEntry ite;
devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT; devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT;
eventid = cmdpkt[1] & EVENTID_MASK; eventid = cmdpkt[1] & EVENTID_MASK;
@ -415,13 +422,13 @@ static ItsCmdResult process_mapti(GICv3ITSState *s, const uint64_t *cmdpkt,
} }
/* add ite entry to interrupt translation table */ /* add ite entry to interrupt translation table */
ite.itel = FIELD_DP64(ite.itel, ITE_L, VALID, true); ite.valid = true;
ite.itel = FIELD_DP64(ite.itel, ITE_L, INTTYPE, ITE_INTTYPE_PHYSICAL); ite.inttype = ITE_INTTYPE_PHYSICAL;
ite.itel = FIELD_DP64(ite.itel, ITE_L, INTID, pIntid); ite.intid = pIntid;
ite.itel = FIELD_DP64(ite.itel, ITE_L, ICID, icid); ite.icid = icid;
ite.iteh = FIELD_DP32(ite.iteh, ITE_H, DOORBELL, INTID_SPURIOUS); ite.doorbell = INTID_SPURIOUS;
ite.vpeid = 0;
return update_ite(s, eventid, &dte, ite) ? CMD_CONTINUE : CMD_STALL; return update_ite(s, eventid, &dte, &ite) ? CMD_CONTINUE : CMD_STALL;
} }
/* /*
@ -585,7 +592,6 @@ static ItsCmdResult process_movi(GICv3ITSState *s, const uint64_t *cmdpkt)
uint32_t devid, eventid; uint32_t devid, eventid;
uint16_t new_icid; uint16_t new_icid;
uint64_t num_eventids; uint64_t num_eventids;
IteEntry ite = {};
DTEntry dte; DTEntry dte;
CTEntry old_cte, new_cte; CTEntry old_cte, new_cte;
ITEntry old_ite; ITEntry old_ite;
@ -689,12 +695,8 @@ static ItsCmdResult process_movi(GICv3ITSState *s, const uint64_t *cmdpkt)
} }
/* Update the ICID field in the interrupt translation table entry */ /* Update the ICID field in the interrupt translation table entry */
ite.itel = FIELD_DP64(ite.itel, ITE_L, VALID, 1); old_ite.icid = new_icid;
ite.itel = FIELD_DP64(ite.itel, ITE_L, INTTYPE, ITE_INTTYPE_PHYSICAL); return update_ite(s, eventid, &dte, &old_ite) ? CMD_CONTINUE : CMD_STALL;
ite.itel = FIELD_DP64(ite.itel, ITE_L, INTID, old_ite.intid);
ite.itel = FIELD_DP64(ite.itel, ITE_L, ICID, new_icid);
ite.iteh = FIELD_DP32(ite.iteh, ITE_H, DOORBELL, INTID_SPURIOUS);
return update_ite(s, eventid, &dte, ite) ? CMD_CONTINUE : CMD_STALL;
} }
/* /*