/*
- * 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 new Interrupt;
+ return std::make_shared<Interrupt>();
if ((interrupts[INT_VIRT_IRQ] || hcr.vi) && allowVIrq)
- return new VirtualInterrupt;
+ return std::make_shared<VirtualInterrupt>();
if (interrupts[INT_FIQ] && take_fiq)
- return new FastInterrupt;
+ return std::make_shared<FastInterrupt>();
if ((interrupts[INT_VIRT_FIQ] || hcr.vf) && allowVFiq)
- return new VirtualFastInterrupt;
+ return std::make_shared<VirtualFastInterrupt>();
if (interrupts[INT_ABT] && take_ea)
- return new SystemError;
+ return std::make_shared<SystemError>();
if (hcr.va && allowVAbort)
- return new VirtualDataAbort(0, TlbEntry::DomainType::NoAccess, false,
- ArmFault::AsynchronousExternalAbort);
+ return std::make_shared<VirtualDataAbort>(
+ 0, TlbEntry::DomainType::NoAccess, false,
+ ArmFault::AsynchronousExternalAbort);
if (interrupts[INT_RST])
- return new Reset;
+ return std::make_shared<Reset>();
if (interrupts[INT_SEV])
- return new ArmSev;
+ return std::make_shared<ArmSev>();
panic("intStatus and interrupts not in sync\n");
}
}
void
- serialize(std::ostream &os)
+ serialize(CheckpointOut &cp) const
{
SERIALIZE_ARRAY(interrupts, NumInterruptTypes);
SERIALIZE_SCALAR(intStatus);
}
void
- unserialize(Checkpoint *cp, const std::string §ion)
+ unserialize(CheckpointIn &cp)
{
UNSERIALIZE_ARRAY(interrupts, NumInterruptTypes);
UNSERIALIZE_SCALAR(intStatus);