target/arm: Implement v7m_update_fpccr()

Implement the code which updates the FPCCR register on an
exception entry where we are going to use lazy FP stacking.
We have to defer to the NVIC to determine whether the
various exceptions are currently ready or not.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20190416125744.27770-12-peter.maydell@linaro.org
This commit is contained in:
Peter Maydell 2019-04-29 17:36:00 +01:00
parent 0ed377a801
commit b593c2b812
3 changed files with 114 additions and 1 deletions

View file

@ -746,6 +746,40 @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
return ret;
}
bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
{
/*
* Return whether an exception is "ready", i.e. it is enabled and is
* configured at a priority which would allow it to interrupt the
* current execution priority.
*
* irq and secure have the same semantics as for armv7m_nvic_set_pending():
* for non-banked exceptions secure is always false; for banked exceptions
* it indicates which of the exceptions is required.
*/
NVICState *s = (NVICState *)opaque;
bool banked = exc_is_banked(irq);
VecInfo *vec;
int running = nvic_exec_prio(s);
assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
assert(!secure || banked);
/*
* HardFault is an odd special case: we always check against -1,
* even if we're secure and HardFault has priority -3; we never
* need to check for enabled state.
*/
if (irq == ARMV7M_EXCP_HARD) {
return running > -1;
}
vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
return vec->enabled &&
exc_group_prio(s, vec->prio, secure) < running;
}
/* callback when external interrupt line is changed */
static void set_irq_level(void *opaque, int n, int level)
{