/*
- * Copyright (c) 2010, 2012-2013 ARM Limited
+ * Copyright (c) 2010, 2012-2013, 2016 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
#include "arch/arm/miscregs.hh"
#include "arch/arm/registers.hh"
#include "arch/arm/utility.hh"
+#include "arch/generic/interrupts.hh"
#include "cpu/thread_context.hh"
#include "debug/Interrupt.hh"
#include "params/ArmInterrupts.hh"
-#include "sim/sim_object.hh"
namespace ArmISA
{
-class Interrupts : public SimObject
+class Interrupts : public BaseInterrupts
{
private:
BaseCPU * cpu;
return dynamic_cast<const Params *>(_params);
}
- Interrupts(Params * p) : SimObject(p), cpu(NULL)
+ Interrupts(Params * p) : BaseInterrupts(p), cpu(NULL)
{
clearAll();
}
return false;
CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
- SCR scr = tc->readMiscReg(MISCREG_SCR);
- bool isHypMode = cpsr.mode == MODE_HYP;
- bool isSecure = inSecureState(scr, cpsr);
+ bool isHypMode = currEL(tc) == EL2;
+ bool isSecure = inSecureState(tc);
bool allowVIrq = !cpsr.i && hcr.imo && !isSecure && !isHypMode;
bool allowVFiq = !cpsr.f && hcr.fmo && !isSecure && !isHypMode;
bool allowVAbort = !cpsr.a && hcr.amo && !isSecure && !isHypMode;
+ if ( !(intStatus || (hcr.vi && allowVIrq) || (hcr.vf && allowVFiq) ||
+ (hcr.va && allowVAbort)) )
+ return false;
+
bool take_irq = takeInt(tc, INT_IRQ);
bool take_fiq = takeInt(tc, INT_FIQ);
bool take_ea = takeInt(tc, INT_ABT);
Fault
getInterrupt(ThreadContext *tc)
{
+ assert(checkInterrupts(tc));
+
HCR hcr = tc->readMiscReg(MISCREG_HCR);
CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
- SCR scr = tc->readMiscReg(MISCREG_SCR);
// Calculate a few temp vars so we can work out if there's a pending
// virtual interrupt, and if its allowed to happen
// ARM ARM Issue C section B1.9.9, B1.9.11, and B1.9.13
- bool isHypMode = cpsr.mode == MODE_HYP;
- bool isSecure = inSecureState(scr, cpsr);
+ bool isHypMode = currEL(tc) == EL2;
+ bool isSecure = inSecureState(tc);
bool allowVIrq = !cpsr.i && hcr.imo && !isSecure && !isHypMode;
bool allowVFiq = !cpsr.f && hcr.fmo && !isSecure && !isHypMode;
bool allowVAbort = !cpsr.a && hcr.amo && !isSecure && !isHypMode;
- if ( !(intStatus || (hcr.vi && allowVIrq) || (hcr.vf && allowVFiq) ||
- (hcr.va && allowVAbort)) )
- return NoFault;
-
bool take_irq = takeInt(tc, INT_IRQ);
bool take_fiq = takeInt(tc, INT_FIQ);
bool take_ea = takeInt(tc, INT_ABT);
-
if (interrupts[INT_IRQ] && take_irq)
return std::make_shared<Interrupt>();
if ((interrupts[INT_VIRT_IRQ] || hcr.vi) && allowVIrq)