dev-arm: Add several LPI methods in Gicv3Redistributor
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Mon, 15 Apr 2019 15:42:43 +0000 (16:42 +0100)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Thu, 2 May 2019 14:42:42 +0000 (14:42 +0000)
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>
src/dev/arm/gic_v3_redistributor.cc
src/dev/arm/gic_v3_redistributor.hh

index 79de7d55c42fc76cc5af3d280177b834ad8bfcc3..0ee6b8adc9cff1174ade0502a769f18ac77aa5b0 100644 (file)
@@ -860,6 +860,43 @@ Gicv3Redistributor::update()
     }
 }
 
+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 @@ Gicv3Redistributor::setClrLPI(uint64_t data, bool set)
         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 @@ Gicv3Redistributor::setClrLPI(uint64_t data, bool set)
         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();
 }
 
index 0e99b746da0a0e5d79ada6605fe443e697f1dee8..6aff91db5f4ef59c42297acf075b3b2005e024bf 100644 (file)
@@ -190,8 +190,17 @@ class Gicv3Redistributor : public Serializable
         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);