From 94d17a547cc11b017f292f6b22cfd5169e1eef86 Mon Sep 17 00:00:00 2001 From: Matt Evans Date: Thu, 17 Oct 2013 10:20:45 -0500 Subject: [PATCH] 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. --- src/dev/arm/base_gic.hh | 3 ++- src/dev/arm/gic_pl390.cc | 11 ++++++++++- src/dev/arm/gic_pl390.hh | 5 ++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/dev/arm/base_gic.hh b/src/dev/arm/base_gic.hh index d177487ed..facc99084 100644 --- a/src/dev/arm/base_gic.hh +++ b/src/dev/arm/base_gic.hh @@ -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. diff --git a/src/dev/arm/gic_pl390.cc b/src/dev/arm/gic_pl390.cc index 1acfdc707..fc49aa63e 100644 --- a/src/dev/arm/gic_pl390.cc +++ b/src/dev/arm/gic_pl390.cc @@ -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) { diff --git a/src/dev/arm/gic_pl390.hh b/src/dev/arm/gic_pl390.hh index c2b0988f8..2621e1a27 100644 --- a/src/dev/arm/gic_pl390.hh +++ b/src/dev/arm/gic_pl390.hh @@ -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); /** @} */ /** @{ */ -- 2.30.2