dev-arm: Introduce the active boolean for ArmInterruptPin
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Tue, 28 Jul 2020 08:27:24 +0000 (09:27 +0100)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Thu, 30 Jul 2020 15:44:23 +0000 (15:44 +0000)
The active boolean will specify if the interrupt line is active
or not (high if it is active high or low if it is active low).

This is decoupled from the interrupt being in a pending state
within the GIC, and it can be used by a peripheral to query the
status of its interrupt pin

Change-Id: I18445b891a75767c8a72e9a7044d6d75fdb7e224
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/31934
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/dev/arm/base_gic.cc
src/dev/arm/base_gic.hh

index a2df8ab197269fdc315cf8866e208fb78249d146..3181dca8287ed5ebb72d8611d9a8feeab660322f 100644 (file)
@@ -121,7 +121,7 @@ ArmPPIGen::get(ThreadContext* tc)
 ArmInterruptPin::ArmInterruptPin(
     Platform  *_platform, ThreadContext *tc, uint32_t int_num)
       : threadContext(tc), platform(dynamic_cast<RealView*>(_platform)),
-        intNum(int_num)
+        intNum(int_num), _active(false)
 {
     fatal_if(!platform, "Interrupt not connected to a RealView platform");
 }
@@ -143,6 +143,18 @@ ArmInterruptPin::targetContext() const
     return threadContext->contextId();
 }
 
+void
+ArmInterruptPin::serialize(CheckpointOut &cp) const
+{
+    SERIALIZE_SCALAR(_active);
+}
+
+void
+ArmInterruptPin::unserialize(CheckpointIn &cp)
+{
+    UNSERIALIZE_SCALAR(_active);
+}
+
 ArmSPI::ArmSPI(
     Platform  *_platform, uint32_t int_num)
       : ArmInterruptPin(_platform, nullptr, int_num)
@@ -152,12 +164,14 @@ ArmSPI::ArmSPI(
 void
 ArmSPI::raise()
 {
+    _active = true;
     platform->gic->sendInt(intNum);
 }
 
 void
 ArmSPI::clear()
 {
+    _active = false;
     platform->gic->clearInt(intNum);
 }
 
@@ -170,12 +184,14 @@ ArmPPI::ArmPPI(
 void
 ArmPPI::raise()
 {
+    _active = true;
     platform->gic->sendPPInt(intNum, targetContext());
 }
 
 void
 ArmPPI::clear()
 {
+    _active = false;
     platform->gic->clearPPInt(intNum, targetContext());
 }
 
index 2f4a1f6c518e9e9c8d03aac858f92419a320f464..f8fd8140fc31c5f0dd5e15021e67b384432a18bb 100644 (file)
@@ -173,7 +173,7 @@ class ArmPPIGen : public ArmInterruptPinGen
 /**
  * Generic representation of an Arm interrupt pin.
  */
-class ArmInterruptPin
+class ArmInterruptPin : public Serializable
 {
     friend class ArmInterruptPinGen;
   protected:
@@ -193,11 +193,18 @@ class ArmInterruptPin
     /** Get interrupt number */
     uint32_t num() const { return intNum; }
 
+    /** True if interrupt pin is active, false otherwise */
+    bool active() const { return _active; }
+
     /** Signal an interrupt */
     virtual void raise() = 0;
     /** Clear a signalled interrupt */
     virtual void clear() = 0;
 
+  public: /* Serializable interface */
+    void serialize(CheckpointOut &cp) const override;
+    void unserialize(CheckpointIn &cp) override;
+
   protected:
     /**
      * Get the target context ID of this interrupt.
@@ -218,6 +225,9 @@ class ArmInterruptPin
 
     /** Interrupt number to generate */
     const uint32_t intNum;
+
+    /** True if interrupt pin is active, false otherwise */
+    bool _active;
 };
 
 class ArmSPI : public ArmInterruptPin