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.

Backports part of commit 5ede82b8ccb652382c106d53f656ed67997d76e8 from qemu
This commit is contained in:
Peter Maydell 2018-03-07 08:09:53 -05:00 committed by Lioncash
parent d1da0b8f6d
commit 49010633f0
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -1460,6 +1460,29 @@ static inline bool armv7m_nvic_can_take_pending_exception(void *opaque)
}
#endif
void armv7m_nvic_set_pending(void *opaque, int irq);
/**
* armv7m_nvic_set_pending_derived: mark this derived exception as pending
* @opaque: the NVIC
* @irq: the exception number to mark pending
* @secure: false for non-banked exceptions or for the nonsecure
* version of a banked exception, true for the secure version of a banked
* exception.
*
* Similar to armv7m_nvic_set_pending(), but specifically for derived
* exceptions (exceptions generated in the course of trying to take
* a different exception).
*/
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
/**
* armv7m_nvic_acknowledge_irq: make highest priority pending exception active
* @opaque: the NVIC
*
* Move the current highest priority pending exception from the pending
* state to the active state, and update v7m.exception to indicate that
* it is the exception currently being handled.
*
* Returns: true if exception should be taken to Secure state, false for NS
*/
void armv7m_nvic_acknowledge_irq(void *opaque);
/**
* armv7m_nvic_complete_irq: complete specified interrupt or exception