dev-arm: Add several LPI methods in Gicv3Redistributor

Refactoring the existing in code in smaller methods will be crucial when
adding the ITS module, which is a client for the redistributor class and
which will require it to take different actions depending on the command
it receives from software.

List of methods:

* read/writeEntryLPI
Reading/Writing a byte from the LPI pending table

* isPendingLPI
Checks if the pINTID LPI is set. Knowing if an LPI is set is needed by
the MOVI command, which is transfering the pending state from one
redistributor to the other only if the LPI is pending.

Change-Id: If14b1c28ff7f2aa20b12dcd822bf6a490cbe0270
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/18596
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/dev/arm/gic_v3_redistributor.cc b/src/dev/arm/gic_v3_redistributor.cc
index 79de7d5..0ee6b8a 100644
--- a/src/dev/arm/gic_v3_redistributor.cc
+++ b/src/dev/arm/gic_v3_redistributor.cc
@@ -860,6 +860,43 @@
     }
 }
 
+uint8_t
+Gicv3Redistributor::readEntryLPI(uint32_t lpi_id)
+{
+    Addr lpi_pending_entry_ptr = lpiPendingTablePtr + (lpi_id / 8);
+
+    uint8_t lpi_pending_entry;
+    ThreadContext * tc = gic->getSystem()->getThreadContext(cpuId);
+    tc->getPhysProxy().readBlob(lpi_pending_entry_ptr,
+            (uint8_t*) &lpi_pending_entry,
+            sizeof(lpi_pending_entry));
+
+    return lpi_pending_entry;
+}
+
+void
+Gicv3Redistributor::writeEntryLPI(uint32_t lpi_id, uint8_t lpi_pending_entry)
+{
+    Addr lpi_pending_entry_ptr = lpiPendingTablePtr + (lpi_id / 8);
+
+    ThreadContext * tc = gic->getSystem()->getThreadContext(cpuId);
+    tc->getPhysProxy().writeBlob(lpi_pending_entry_ptr,
+            (uint8_t*) &lpi_pending_entry,
+            sizeof(lpi_pending_entry));
+}
+
+bool
+Gicv3Redistributor::isPendingLPI(uint32_t lpi_id)
+{
+    // Fetch the LPI pending entry from memory
+    uint8_t lpi_pending_entry = readEntryLPI(lpi_id);
+
+    uint8_t lpi_pending_entry_bit_position = lpi_id % 8;
+    bool is_set = lpi_pending_entry & (1 << lpi_pending_entry_bit_position);
+
+    return is_set;
+}
+
 void
 Gicv3Redistributor::setClrLPI(uint64_t data, bool set)
 {
@@ -878,12 +915,9 @@
         return;
     }
 
-    Addr lpi_pending_entry_ptr = lpiPendingTablePtr + (lpi_id / 8);
-    uint8_t lpi_pending_entry;
-    ThreadContext * tc = gic->getSystem()->getThreadContext(cpuId);
-    tc->getPhysProxy().readBlob(lpi_pending_entry_ptr,
-            (uint8_t*) &lpi_pending_entry,
-            sizeof(lpi_pending_entry));
+    // Fetch the LPI pending entry from memory
+    uint8_t lpi_pending_entry = readEntryLPI(lpi_id);
+
     uint8_t lpi_pending_entry_bit_position = lpi_id % 8;
     bool is_set = lpi_pending_entry & (1 << lpi_pending_entry_bit_position);
 
@@ -905,9 +939,8 @@
         lpi_pending_entry &= ~(1 << (lpi_pending_entry_bit_position));
     }
 
-    tc->getPhysProxy().writeBlob(lpi_pending_entry_ptr,
-            (uint8_t*) &lpi_pending_entry,
-            sizeof(lpi_pending_entry));
+    writeEntryLPI(lpi_id, lpi_pending_entry);
+
     updateAndInformCPUInterface();
 }
 
diff --git a/src/dev/arm/gic_v3_redistributor.hh b/src/dev/arm/gic_v3_redistributor.hh
index 0e99b74..6aff91d 100644
--- a/src/dev/arm/gic_v3_redistributor.hh
+++ b/src/dev/arm/gic_v3_redistributor.hh
@@ -190,8 +190,17 @@
         return cpuInterface;
     }
 
+    uint32_t
+    processorNumber() const
+    {
+        return cpuId;
+    }
+
     Gicv3::GroupId getIntGroup(int int_id) const;
     Gicv3::IntStatus intStatus(uint32_t int_id) const;
+    uint8_t readEntryLPI(uint32_t intid);
+    void writeEntryLPI(uint32_t intid, uint8_t lpi_entry);
+    bool isPendingLPI(uint32_t intid);
     void setClrLPI(uint64_t data, bool set);
     void reset();
     void sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns);