arm: Add a 'clear PPI' method to gic_pl390

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.
This commit is contained in:
Matt Evans 2013-10-17 10:20:45 -05:00
parent 2b9138135e
commit 94d17a547c
3 changed files with 16 additions and 3 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 ARM Limited * Copyright (c) 2012-2013 ARM Limited
* All rights reserved * All rights reserved
* *
* The license below extends only to copyright in the software and shall * 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 * @param cpu CPU to forward interrupt to
*/ */
virtual void sendPPInt(uint32_t num, uint32_t cpu) = 0; 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. * Clear an interrupt from a device that is connected to the GIC.

View file

@ -692,7 +692,7 @@ Pl390::sendInt(uint32_t num)
void void
Pl390::sendPPInt(uint32_t num, uint32_t cpu) 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); num, cpu);
cpuPpiPending[cpu] |= 1 << (num - SGI_MAX); cpuPpiPending[cpu] |= 1 << (num - SGI_MAX);
updateIntState(intNumToWord(num)); updateIntState(intNumToWord(num));
@ -704,6 +704,15 @@ Pl390::clearInt(uint32_t number)
/* @todo assume edge triggered only at the moment. Nothing to do. */ /* @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 void
Pl390::postInt(uint32_t cpu, Tick when) Pl390::postInt(uint32_t cpu, Tick when)
{ {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010 ARM Limited * Copyright (c) 2010, 2013 ARM Limited
* All rights reserved * All rights reserved
* *
* The license below extends only to copyright in the software and shall * 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 * Depending on the configuration, the gic may de-assert it's cpu line
* @param number number of interrupt to send */ * @param number number of interrupt to send */
void clearInt(uint32_t number); void clearInt(uint32_t number);
/** Clear a (level-sensitive) PPI */
void clearPPInt(uint32_t num, uint32_t cpu);
/** @} */ /** @} */
/** @{ */ /** @{ */