arm: Add a 'clear PPI' method to gic_pl390
authorMatt Evans <matt.evans@arm.com>
Thu, 17 Oct 2013 15:20:45 +0000 (10:20 -0500)
committerMatt Evans <matt.evans@arm.com>
Thu, 17 Oct 2013 15:20:45 +0000 (10:20 -0500)
The underlying assumption that all PPIs must be edge-triggered is
strained when the architected timers and VGIC interfaces make
level-behaviour observable. For example, a virtual timer interrupt
'goes away' when the hypervisor is entered and the vtimer is disabled;
this requires a PPI to be de-activated.

The new method simply clears the interrupt pending state.

src/dev/arm/base_gic.hh
src/dev/arm/gic_pl390.cc
src/dev/arm/gic_pl390.hh

index d177487edb12d08ebcfeffbc8ec9144ee3fa1fcd..facc99084616c873877ed9fc016d4d9f7aacc63b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012-2013 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -75,6 +75,7 @@ class BaseGic :  public PioDevice
      * @param cpu CPU to forward interrupt to
      */
     virtual void sendPPInt(uint32_t num, uint32_t cpu) = 0;
+    virtual void clearPPInt(uint32_t num, uint32_t cpu) = 0;
 
     /**
      * Clear an interrupt from a device that is connected to the GIC.
index 1acfdc707b8540ad1798f698a26344db3c9f56c5..fc49aa63e5bfe6eeb2022849569752cbf4054a81 100644 (file)
@@ -692,7 +692,7 @@ Pl390::sendInt(uint32_t num)
 void
 Pl390::sendPPInt(uint32_t num, uint32_t cpu)
 {
-    DPRINTF(Interrupt, "Received Interrupt number %d, cpuTarget %#x: \n",
+    DPRINTF(Interrupt, "Received PPI %d, cpuTarget %#x: \n",
             num, cpu);
     cpuPpiPending[cpu] |= 1 << (num - SGI_MAX);
     updateIntState(intNumToWord(num));
@@ -704,6 +704,15 @@ Pl390::clearInt(uint32_t number)
     /* @todo assume edge triggered only at the moment. Nothing to do. */
 }
 
+void
+Pl390::clearPPInt(uint32_t num, uint32_t cpu)
+{
+    DPRINTF(Interrupt, "Clearing PPI %d, cpuTarget %#x: \n",
+            num, cpu);
+    cpuPpiPending[cpu] &= ~(1 << (num - SGI_MAX));
+    updateIntState(intNumToWord(num));
+}
+
 void
 Pl390::postInt(uint32_t cpu, Tick when)
 {
index c2b0988f87b6a45e4286e7307493c3ae9453279f..2621e1a2790a19c199c0a4f4b5068d97e50175c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 ARM Limited
+ * Copyright (c) 2010, 2013 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -287,6 +287,9 @@ class Pl390 : public BaseGic
      * Depending on the configuration, the gic may de-assert it's cpu line
      * @param number number of interrupt to send */
     void clearInt(uint32_t number);
+
+    /** Clear a (level-sensitive) PPI */
+    void clearPPInt(uint32_t num, uint32_t cpu);
     /** @} */
 
     /** @{ */