From 5ede82b8ccb652382c106d53f656ed67997d76e8 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 9 Feb 2018 10:40:27 +0000 Subject: target/arm: Add armv7m_nvic_set_pending_derived() In order to support derived exceptions (exceptions generated in the course of trying to take an exception), we need to be able to handle prioritizing whether to take the original exception or the derived exception. We do this by introducing a new function armv7m_nvic_set_pending_derived() which the exception-taking code in helper.c will call when a derived exception occurs. Derived exceptions are dealt with mostly like normal pending exceptions, so we share the implementation with the armv7m_nvic_set_pending() function. Note that the way we structure this is significantly different from the v8M Arm ARM pseudocode: that does all the prioritization logic in the DerivedLateArrival() function, whereas we choose to let the existing "identify highest priority exception" logic do the prioritization for us. The effect is the same, though. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 1517324542-6607-2-git-send-email-peter.maydell@linaro.org --- hw/intc/trace-events | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/intc/trace-events') diff --git a/hw/intc/trace-events b/hw/intc/trace-events index be769186fc..09e87d14bd 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -177,7 +177,7 @@ nvic_set_prio(int irq, bool secure, uint8_t prio) "NVIC set irq %d secure-bank % nvic_irq_update(int vectpending, int pendprio, int exception_prio, int level) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq line to %d" nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq %d to HardFault: insufficient priority %d >= %d" nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled" -nvic_set_pending(int irq, bool secure, int en, int prio) "NVIC set pending irq %d secure-bank %d (enabled: %d priority %d)" +nvic_set_pending(int irq, bool secure, bool derived, int en, int prio) "NVIC set pending irq %d secure-bank %d derived %d (enabled: %d priority %d)" nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pending irq %d secure-bank %d (enabled: %d priority %d)" nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than vectpending: setting irq line to 1" nvic_acknowledge_irq(int irq, int prio, bool targets_secure) "NVIC acknowledge IRQ: %d now active (prio %d targets_secure %d)" -- cgit v1.2.3 From 6c9485188170e11ad31ce477c8ce200b8e8ce59d Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 9 Feb 2018 10:40:27 +0000 Subject: target/arm: Split "get pending exception info" from "acknowledge it" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently armv7m_nvic_acknowledge_irq() does three things: * make the current highest priority pending interrupt active * return a bool indicating whether that interrupt is targeting Secure or NonSecure state * implicitly tell the caller which is the highest priority pending interrupt by setting env->v7m.exception We need to split these jobs, because v7m_exception_taken() needs to know whether the pending interrupt targets Secure so it can choose to stack callee-saves registers or not, but it must not make the interrupt active until after it has done that stacking, in case the stacking causes a derived exception. Similarly, it needs to know the number of the pending interrupt so it can read the correct vector table entry before the interrupt is made active, because vector table reads might also cause a derived exception. Create a new armv7m_nvic_get_pending_irq_info() function which simply returns information about the highest priority pending interrupt, and use it to rearrange the v7m_exception_taken() code so we don't acknowledge the exception until we've done all the things which could possibly cause a derived exception. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-id: 1517324542-6607-3-git-send-email-peter.maydell@linaro.org --- hw/intc/trace-events | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'hw/intc/trace-events') diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 09e87d14bd..4092d2825e 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -180,7 +180,8 @@ nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled" nvic_set_pending(int irq, bool secure, bool derived, int en, int prio) "NVIC set pending irq %d secure-bank %d derived %d (enabled: %d priority %d)" nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pending irq %d secure-bank %d (enabled: %d priority %d)" nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than vectpending: setting irq line to 1" -nvic_acknowledge_irq(int irq, int prio, bool targets_secure) "NVIC acknowledge IRQ: %d now active (prio %d targets_secure %d)" +nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now active (prio %d)" +nvic_get_pending_irq_info(int irq, bool secure) "NVIC next IRQ %d: targets_secure: %d" nvic_complete_irq(int irq, bool secure) "NVIC complete IRQ %d (secure %d)" nvic_set_irq_level(int irq, int level) "NVIC external irq %d level set to %d" nvic_sysreg_read(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u" -- cgit v1.2.3