summary refs log tree commit diff stats
path: root/hw/intc/arm_gicv3_its.c
diff options
context:
space:
mode:
authorShashi Mallela <shashi.mallela@linaro.org>2021-09-13 16:07:24 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-09-13 21:01:08 +0100
commit17fb5e36aabd4b2c12549eba62ae0e78b635cd36 (patch)
tree88a461fca5e23425c3d00e3d016fbbfc71e8356c /hw/intc/arm_gicv3_its.c
parentac30dec39652c6fe43484448617c4ca6f26b0841 (diff)
downloadfocaccia-qemu-17fb5e36aabd4b2c12549eba62ae0e78b635cd36.tar.gz
focaccia-qemu-17fb5e36aabd4b2c12549eba62ae0e78b635cd36.zip
hw/intc: GICv3 redistributor ITS processing
Implemented lpi processing at redistributor to get lpi config info
from lpi configuration table,determine priority,set pending state in
lpi pending table and forward the lpi to cpuif.Added logic to invoke
redistributor lpi processing with translated LPI which set/clear LPI
from ITS device as part of ITS INT,CLEAR,DISCARD command and
GITS_TRANSLATER processing.

Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
Tested-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20210910143951.92242-7-shashi.mallela@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/intc/arm_gicv3_its.c')
-rw-r--r--hw/intc/arm_gicv3_its.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
index 9761b644f7..84bcbb5f56 100644
--- a/hw/intc/arm_gicv3_its.c
+++ b/hw/intc/arm_gicv3_its.c
@@ -233,6 +233,7 @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
     uint64_t cte = 0;
     bool cte_valid = false;
     bool result = false;
+    uint64_t rdbase;
 
     if (cmd == NONE) {
         devid = offset;
@@ -293,6 +294,18 @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
          * Current implementation only supports rdbase == procnum
          * Hence rdbase physical address is ignored
          */
+        rdbase = (cte & GITS_CTE_RDBASE_PROCNUM_MASK) >> 1U;
+
+        if (rdbase > s->gicv3->num_cpu) {
+            return result;
+        }
+
+        if ((cmd == CLEAR) || (cmd == DISCARD)) {
+            gicv3_redist_process_lpi(&s->gicv3->cpu[rdbase], pIntid, 0);
+        } else {
+            gicv3_redist_process_lpi(&s->gicv3->cpu[rdbase], pIntid, 1);
+        }
+
         if (cmd == DISCARD) {
             IteEntry ite = {};
             /* remove mapping from interrupt translation table */
@@ -621,6 +634,7 @@ static void process_cmdq(GICv3ITSState *s)
     MemTxResult res = MEMTX_OK;
     bool result = true;
     uint8_t cmd;
+    int i;
 
     if (!(s->ctlr & ITS_CTLR_ENABLED)) {
         return;
@@ -685,6 +699,15 @@ static void process_cmdq(GICv3ITSState *s)
             break;
         case GITS_CMD_INV:
         case GITS_CMD_INVALL:
+            /*
+             * Current implementation doesn't cache any ITS tables,
+             * but the calculated lpi priority information. We only
+             * need to trigger lpi priority re-calculation to be in
+             * sync with LPI config table or pending table changes.
+             */
+            for (i = 0; i < s->gicv3->num_cpu; i++) {
+                gicv3_redist_update_lpi(&s->gicv3->cpu[i]);
+            }
             break;
         default:
             break;