[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 29/39] hw/intc/arm_gicv3_its: Keep CTEs as a struct, not a raw uin
From: |
Peter Maydell |
Subject: |
[PULL 29/39] hw/intc/arm_gicv3_its: Keep CTEs as a struct, not a raw uint64_t |
Date: |
Tue, 8 Feb 2022 11:39:38 +0000 |
In the ITS, a CTE is an entry in the collection table, which contains
multiple fields. Currently the function get_cte() which reads one
entry from the device table returns a success/failure boolean and
passes back the raw 64-bit integer CTE value via a pointer argument.
We then extract fields from the CTE as we need them.
Create a real C struct with the same fields as the CTE, and
populate it in get_cte(), so that that function and update_cte()
are the only ones which need to care about the in-guest-memory
format of the CTE.
This brings get_cte()'s API into line with get_dte().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220201193207.2771604-5-peter.maydell@linaro.org
---
hw/intc/arm_gicv3_its.c | 96 ++++++++++++++++++++++-------------------
1 file changed, 52 insertions(+), 44 deletions(-)
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
index 1856210e79a..482a71ba73c 100644
--- a/hw/intc/arm_gicv3_its.c
+++ b/hw/intc/arm_gicv3_its.c
@@ -52,6 +52,11 @@ typedef struct DTEntry {
uint64_t ittaddr;
} DTEntry;
+typedef struct CTEntry {
+ bool valid;
+ uint32_t rdbase;
+} CTEntry;
+
/*
* The ITS spec permits a range of CONSTRAINED UNPREDICTABLE options
* if a command parameter is not correct. These include both "stall
@@ -135,18 +140,32 @@ static uint64_t table_entry_addr(GICv3ITSState *s,
TableDesc *td,
return (l2 & ((1ULL << 51) - 1)) + (idx % num_l2_entries) * td->entry_sz;
}
-static bool get_cte(GICv3ITSState *s, uint16_t icid, uint64_t *cte,
- MemTxResult *res)
+/*
+ * Read the Collection Table entry at index @icid. On success (including
+ * successfully determining that there is no valid CTE for this index),
+ * we return MEMTX_OK and populate the CTEntry struct @cte accordingly.
+ * If there is an error reading memory then we return the error code.
+ */
+static MemTxResult get_cte(GICv3ITSState *s, uint16_t icid, CTEntry *cte)
{
AddressSpace *as = &s->gicv3->dma_as;
- uint64_t entry_addr = table_entry_addr(s, &s->ct, icid, res);
+ MemTxResult res = MEMTX_OK;
+ uint64_t entry_addr = table_entry_addr(s, &s->ct, icid, &res);
+ uint64_t cteval;
if (entry_addr == -1) {
- return false; /* not valid */
+ /* No L2 table entry, i.e. no valid CTE, or a memory error */
+ cte->valid = false;
+ return res;
}
- *cte = address_space_ldq_le(as, entry_addr, MEMTXATTRS_UNSPECIFIED, res);
- return FIELD_EX64(*cte, CTE, VALID);
+ cteval = address_space_ldq_le(as, entry_addr, MEMTXATTRS_UNSPECIFIED,
&res);
+ if (res != MEMTX_OK) {
+ return res;
+ }
+ cte->valid = FIELD_EX64(cteval, CTE, VALID);
+ cte->rdbase = FIELD_EX64(cteval, CTE, RDBASE);
+ return MEMTX_OK;
}
static bool update_ite(GICv3ITSState *s, uint32_t eventid, const DTEntry *dte,
@@ -248,10 +267,8 @@ static ItsCmdResult do_process_its_cmd(GICv3ITSState *s,
uint32_t devid,
uint16_t icid = 0;
uint32_t pIntid = 0;
bool ite_valid = false;
- uint64_t cte = 0;
- bool cte_valid = false;
- uint64_t rdbase;
DTEntry dte;
+ CTEntry cte;
if (devid >= s->dt.num_entries) {
qemu_log_mask(LOG_GUEST_ERROR,
@@ -298,15 +315,13 @@ static ItsCmdResult do_process_its_cmd(GICv3ITSState *s,
uint32_t devid,
return CMD_CONTINUE;
}
- cte_valid = get_cte(s, icid, &cte, &res);
- if (res != MEMTX_OK) {
+ if (get_cte(s, icid, &cte) != MEMTX_OK) {
return CMD_STALL;
}
- if (!cte_valid) {
+ if (!cte.valid) {
qemu_log_mask(LOG_GUEST_ERROR,
- "%s: invalid command attributes: "
- "invalid cte: %"PRIx64"\n",
- __func__, cte);
+ "%s: invalid command attributes: invalid CTE\n",
+ __func__);
return CMD_CONTINUE;
}
@@ -314,16 +329,14 @@ static ItsCmdResult do_process_its_cmd(GICv3ITSState *s,
uint32_t devid,
* Current implementation only supports rdbase == procnum
* Hence rdbase physical address is ignored
*/
- rdbase = FIELD_EX64(cte, CTE, RDBASE);
-
- if (rdbase >= s->gicv3->num_cpu) {
+ if (cte.rdbase >= s->gicv3->num_cpu) {
return CMD_CONTINUE;
}
if ((cmd == CLEAR) || (cmd == DISCARD)) {
- gicv3_redist_process_lpi(&s->gicv3->cpu[rdbase], pIntid, 0);
+ gicv3_redist_process_lpi(&s->gicv3->cpu[cte.rdbase], pIntid, 0);
} else {
- gicv3_redist_process_lpi(&s->gicv3->cpu[rdbase], pIntid, 1);
+ gicv3_redist_process_lpi(&s->gicv3->cpu[cte.rdbase], pIntid, 1);
}
if (cmd == DISCARD) {
@@ -564,12 +577,11 @@ static ItsCmdResult process_movi(GICv3ITSState *s, const
uint64_t *cmdpkt)
MemTxResult res = MEMTX_OK;
uint32_t devid, eventid, intid;
uint16_t old_icid, new_icid;
- uint64_t old_cte, new_cte;
- uint64_t old_rdbase, new_rdbase;
- bool ite_valid, cte_valid;
+ bool ite_valid;
uint64_t num_eventids;
IteEntry ite = {};
DTEntry dte;
+ CTEntry old_cte, new_cte;
devid = FIELD_EX64(cmdpkt[0], MOVI_0, DEVICEID);
eventid = FIELD_EX64(cmdpkt[1], MOVI_1, EVENTID);
@@ -627,50 +639,46 @@ static ItsCmdResult process_movi(GICv3ITSState *s, const
uint64_t *cmdpkt)
return CMD_CONTINUE;
}
- cte_valid = get_cte(s, old_icid, &old_cte, &res);
- if (res != MEMTX_OK) {
+ if (get_cte(s, old_icid, &old_cte) != MEMTX_OK) {
return CMD_STALL;
}
- if (!cte_valid) {
+ if (!old_cte.valid) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid command attributes: "
- "invalid cte: %"PRIx64"\n",
- __func__, old_cte);
+ "invalid CTE for old ICID 0x%x\n",
+ __func__, old_icid);
return CMD_CONTINUE;
}
- cte_valid = get_cte(s, new_icid, &new_cte, &res);
- if (res != MEMTX_OK) {
+ if (get_cte(s, new_icid, &new_cte) != MEMTX_OK) {
return CMD_STALL;
}
- if (!cte_valid) {
+ if (!new_cte.valid) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid command attributes: "
- "invalid cte: %"PRIx64"\n",
- __func__, new_cte);
+ "invalid CTE for new ICID 0x%x\n",
+ __func__, new_icid);
return CMD_CONTINUE;
}
- old_rdbase = FIELD_EX64(old_cte, CTE, RDBASE);
- if (old_rdbase >= s->gicv3->num_cpu) {
+ if (old_cte.rdbase >= s->gicv3->num_cpu) {
qemu_log_mask(LOG_GUEST_ERROR,
- "%s: CTE has invalid rdbase 0x%"PRIx64"\n",
- __func__, old_rdbase);
+ "%s: CTE has invalid rdbase 0x%x\n",
+ __func__, old_cte.rdbase);
return CMD_CONTINUE;
}
- new_rdbase = FIELD_EX64(new_cte, CTE, RDBASE);
- if (new_rdbase >= s->gicv3->num_cpu) {
+ if (new_cte.rdbase >= s->gicv3->num_cpu) {
qemu_log_mask(LOG_GUEST_ERROR,
- "%s: CTE has invalid rdbase 0x%"PRIx64"\n",
- __func__, new_rdbase);
+ "%s: CTE has invalid rdbase 0x%x\n",
+ __func__, new_cte.rdbase);
return CMD_CONTINUE;
}
- if (old_rdbase != new_rdbase) {
+ if (old_cte.rdbase != new_cte.rdbase) {
/* Move the LPI from the old redistributor to the new one */
- gicv3_redist_mov_lpi(&s->gicv3->cpu[old_rdbase],
- &s->gicv3->cpu[new_rdbase],
+ gicv3_redist_mov_lpi(&s->gicv3->cpu[old_cte.rdbase],
+ &s->gicv3->cpu[new_cte.rdbase],
intid);
}
--
2.25.1
- [PULL 10/39] hw/arm: allwinner: Don't enable PSCI conduit when booting guest in EL3, (continued)
- [PULL 10/39] hw/arm: allwinner: Don't enable PSCI conduit when booting guest in EL3, Peter Maydell, 2022/02/08
- [PULL 13/39] hw/arm/virt: Let boot.c handle PSCI enablement, Peter Maydell, 2022/02/08
- [PULL 12/39] hw/arm/versal: Let boot.c handle PSCI enablement, Peter Maydell, 2022/02/08
- [PULL 03/39] target/arm: Fix {fp, sve}_exception_el for VHE mode running, Peter Maydell, 2022/02/08
- [PULL 07/39] cpu.c: Make start-powered-off settable after realize, Peter Maydell, 2022/02/08
- [PULL 17/39] hw/arm/boot: Prevent setting both psci_conduit and secure_board_setup, Peter Maydell, 2022/02/08
- [PULL 04/39] target/arm: Use CPTR_TFP with CPTR_EL3 in fp_exception_el, Peter Maydell, 2022/02/08
- [PULL 14/39] hw/arm: highbank: For EL3 guests, don't enable PSCI, start all cores, Peter Maydell, 2022/02/08
- [PULL 27/39] hw/intc/arm_gicv3_its: Keep DTEs as a struct, not a raw uint64_t, Peter Maydell, 2022/02/08
- [PULL 39/39] hw/sensor: Add lsm303dlhc magnetometer device, Peter Maydell, 2022/02/08
- [PULL 29/39] hw/intc/arm_gicv3_its: Keep CTEs as a struct, not a raw uint64_t,
Peter Maydell <=
- [PULL 28/39] hw/intc/arm_gicv3_its: Pass DTEntry to update_dte(), Peter Maydell, 2022/02/08
- [PULL 09/39] hw/arm: imx: Don't enable PSCI conduit when booting guest in EL3, Peter Maydell, 2022/02/08
- [PULL 16/39] hw/arm/highbank: Drop use of secure_board_setup, Peter Maydell, 2022/02/08
- [PULL 23/39] arm: force flag recalculation when messing with DAIF, Peter Maydell, 2022/02/08
- [PULL 22/39] hw/arm: versal-virt: Always call arm_load_kernel(), Peter Maydell, 2022/02/08
- [PULL 20/39] hw/arm/boot: Drop nb_cpus field from arm_boot_info, Peter Maydell, 2022/02/08
- [PULL 21/39] hw/arm/boot: Drop existing dtb /psci node rather than retaining it, Peter Maydell, 2022/02/08
- [PULL 26/39] hw/intc/arm_gicv3_its: Use address_space_map() to access command queue packets, Peter Maydell, 2022/02/08
- [PULL 24/39] hw/timer/armv7m_systick: Update clock source before enabling timer, Peter Maydell, 2022/02/08
- [PULL 33/39] hw/intc/arm_gicv3_its: Pass ITE values back from get_ite() via a struct, Peter Maydell, 2022/02/08