arch: Make a base class for Interrupts.
That abstracts the ISA further from the CPU, getting us a small step closer to being able to build in more than one ISA at a time. Change-Id: Ibf7e26a3df411ffe994ac1e11d2a53b656863223 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20831 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
@@ -26,9 +26,9 @@
|
||||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
from m5.SimObject import SimObject
|
||||
from m5.objects.BaseInterrupts import BaseInterrupts
|
||||
|
||||
class AlphaInterrupts(SimObject):
|
||||
class AlphaInterrupts(BaseInterrupts):
|
||||
type = 'AlphaInterrupts'
|
||||
cxx_class = 'AlphaISA::Interrupts'
|
||||
cxx_header = "arch/alpha/interrupts.hh"
|
||||
|
||||
@@ -36,17 +36,17 @@
|
||||
|
||||
#include "arch/alpha/faults.hh"
|
||||
#include "arch/alpha/isa_traits.hh"
|
||||
#include "arch/generic/interrupts.hh"
|
||||
#include "base/compiler.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "debug/Flow.hh"
|
||||
#include "debug/Interrupt.hh"
|
||||
#include "params/AlphaInterrupts.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
|
||||
namespace AlphaISA {
|
||||
|
||||
class Interrupts : public SimObject
|
||||
class Interrupts : public BaseInterrupts
|
||||
{
|
||||
private:
|
||||
bool newInfoSet;
|
||||
@@ -67,7 +67,7 @@ class Interrupts : public SimObject
|
||||
return dynamic_cast<const Params *>(_params);
|
||||
}
|
||||
|
||||
Interrupts(Params * p) : SimObject(p), cpu(NULL)
|
||||
Interrupts(Params * p) : BaseInterrupts(p), cpu(NULL)
|
||||
{
|
||||
memset(interrupts, 0, sizeof(interrupts));
|
||||
intstatus = 0;
|
||||
|
||||
@@ -982,7 +982,7 @@ decode OPCODE default Unknown::unknown() {
|
||||
}}, IsNonSpeculative);
|
||||
0x01: quiesce({{
|
||||
// Don't sleep if (unmasked) interrupts are pending
|
||||
Interrupts* interrupts =
|
||||
BaseInterrupts* interrupts =
|
||||
xc->tcBase()->getCpuPtr()->getInterruptController(0);
|
||||
if (interrupts->checkInterrupts(xc->tcBase())) {
|
||||
PseudoInst::quiesceSkip(xc->tcBase());
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
#
|
||||
# Authors: Ali Saidi
|
||||
|
||||
from m5.SimObject import SimObject
|
||||
from m5.objects.BaseInterrupts import BaseInterrupts
|
||||
|
||||
class ArmInterrupts(SimObject):
|
||||
class ArmInterrupts(BaseInterrupts):
|
||||
type = 'ArmInterrupts'
|
||||
cxx_class = 'ArmISA::Interrupts'
|
||||
cxx_header = "arch/arm/interrupts.hh"
|
||||
|
||||
@@ -48,15 +48,15 @@
|
||||
#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;
|
||||
@@ -80,7 +80,7 @@ class Interrupts : public SimObject
|
||||
return dynamic_cast<const Params *>(_params);
|
||||
}
|
||||
|
||||
Interrupts(Params * p) : SimObject(p), cpu(NULL)
|
||||
Interrupts(Params * p) : BaseInterrupts(p), cpu(NULL)
|
||||
{
|
||||
clearAll();
|
||||
}
|
||||
|
||||
@@ -39,6 +39,9 @@
|
||||
*/
|
||||
|
||||
#include "arch/arm/isa.hh"
|
||||
|
||||
#include "arch/arm/faults.hh"
|
||||
#include "arch/arm/interrupts.hh"
|
||||
#include "arch/arm/pmu.hh"
|
||||
#include "arch/arm/system.hh"
|
||||
#include "arch/arm/tlb.hh"
|
||||
@@ -672,15 +675,23 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
|
||||
case MISCREG_DBGDSCRint:
|
||||
return 0;
|
||||
case MISCREG_ISR:
|
||||
return tc->getCpuPtr()->getInterruptController(tc->threadId())->getISR(
|
||||
readMiscRegNoEffect(MISCREG_HCR),
|
||||
readMiscRegNoEffect(MISCREG_CPSR),
|
||||
readMiscRegNoEffect(MISCREG_SCR));
|
||||
{
|
||||
auto ic = dynamic_cast<ArmISA::Interrupts *>(
|
||||
tc->getCpuPtr()->getInterruptController(tc->threadId()));
|
||||
return ic->getISR(
|
||||
readMiscRegNoEffect(MISCREG_HCR),
|
||||
readMiscRegNoEffect(MISCREG_CPSR),
|
||||
readMiscRegNoEffect(MISCREG_SCR));
|
||||
}
|
||||
case MISCREG_ISR_EL1:
|
||||
return tc->getCpuPtr()->getInterruptController(tc->threadId())->getISR(
|
||||
readMiscRegNoEffect(MISCREG_HCR_EL2),
|
||||
readMiscRegNoEffect(MISCREG_CPSR),
|
||||
readMiscRegNoEffect(MISCREG_SCR_EL3));
|
||||
{
|
||||
auto ic = dynamic_cast<ArmISA::Interrupts *>(
|
||||
tc->getCpuPtr()->getInterruptController(tc->threadId()));
|
||||
return ic->getISR(
|
||||
readMiscRegNoEffect(MISCREG_HCR_EL2),
|
||||
readMiscRegNoEffect(MISCREG_CPSR),
|
||||
readMiscRegNoEffect(MISCREG_SCR_EL3));
|
||||
}
|
||||
case MISCREG_DCZID_EL0:
|
||||
return 0x04; // DC ZVA clear 64-byte chunks
|
||||
case MISCREG_HCPTR:
|
||||
|
||||
@@ -96,6 +96,7 @@ output exec {{
|
||||
#include <cmath>
|
||||
|
||||
#include "arch/arm/faults.hh"
|
||||
#include "arch/arm/interrupts.hh"
|
||||
#include "arch/arm/isa.hh"
|
||||
#include "arch/arm/isa_traits.hh"
|
||||
#include "arch/arm/utility.hh"
|
||||
|
||||
@@ -756,8 +756,9 @@ let {{
|
||||
|
||||
// WFI doesn't sleep if interrupts are pending (masked or not)
|
||||
ThreadContext *tc = xc->tcBase();
|
||||
if (tc->getCpuPtr()->getInterruptController(
|
||||
tc->threadId())->checkWfiWake(hcr, cpsr, scr)) {
|
||||
auto *ic = dynamic_cast<ArmISA::Interrupts *>(
|
||||
tc->getCpuPtr()->getInterruptController(tc->threadId()));
|
||||
if (ic->checkWfiWake(hcr, cpsr, scr)) {
|
||||
PseudoInst::quiesceSkip(tc);
|
||||
} else {
|
||||
fault = trapWFx(tc, cpsr, scr, false);
|
||||
|
||||
34
src/arch/generic/BaseInterrupts.py
Normal file
34
src/arch/generic/BaseInterrupts.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# Copyright 2019 Google, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met: redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer;
|
||||
# redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution;
|
||||
# neither the name of the copyright holders nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
from m5.params import *
|
||||
from m5.SimObject import SimObject
|
||||
|
||||
class BaseInterrupts(SimObject):
|
||||
type = 'BaseInterrupts'
|
||||
abstract = True
|
||||
cxx_header = "arch/generic/interrupts.hh"
|
||||
@@ -46,6 +46,7 @@ if env['TARGET_ISA'] == 'null':
|
||||
Source('decode_cache.cc')
|
||||
Source('mmapped_ipr.cc')
|
||||
|
||||
SimObject('BaseInterrupts.py')
|
||||
SimObject('BaseTLB.py')
|
||||
SimObject('ISACommon.py')
|
||||
|
||||
|
||||
98
src/arch/generic/interrupts.hh
Normal file
98
src/arch/generic/interrupts.hh
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2019 Google, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_GENERIC_INTERRUPTS_HH__
|
||||
#define __ARCH_GENERIC_INTERRUPTS_HH__
|
||||
|
||||
#include "params/BaseInterrupts.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
|
||||
class ThreadContext;
|
||||
class BaseCPU;
|
||||
|
||||
class BaseInterrupts : public SimObject
|
||||
{
|
||||
protected:
|
||||
BaseCPU *cpu;
|
||||
|
||||
public:
|
||||
typedef BaseInterruptsParams Params;
|
||||
|
||||
BaseInterrupts(Params *p) : SimObject(p) {}
|
||||
|
||||
virtual void setCPU(BaseCPU * newCPU) = 0;
|
||||
|
||||
const Params *
|
||||
params() const
|
||||
{
|
||||
return dynamic_cast<const Params *>(_params);
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions for retrieving interrupts for the CPU to handle.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Return whether there are any interrupts waiting to be recognized.
|
||||
*/
|
||||
virtual bool checkInterrupts(ThreadContext *tc) const = 0;
|
||||
/*
|
||||
* Return an interrupt to process. This should return an interrupt exactly
|
||||
* when checkInterrupts returns true.
|
||||
*/
|
||||
virtual Fault getInterrupt(ThreadContext *tc) = 0;
|
||||
/*
|
||||
* Update interrupt related state after an interrupt has been processed.
|
||||
*/
|
||||
virtual void updateIntrInfo(ThreadContext *tc) = 0;
|
||||
|
||||
/*
|
||||
* Old functions needed for compatability but which will be phased out
|
||||
* eventually.
|
||||
*/
|
||||
virtual void
|
||||
post(int int_num, int index)
|
||||
{
|
||||
panic("Interrupts::post unimplemented!\n");
|
||||
}
|
||||
|
||||
virtual void
|
||||
clear(int int_num, int index)
|
||||
{
|
||||
panic("Interrupts::clear unimplemented!\n");
|
||||
}
|
||||
|
||||
virtual void
|
||||
clearAll()
|
||||
{
|
||||
panic("Interrupts::clearAll unimplemented!\n");
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __ARCH_GENERIC_INTERRUPTS_HH__
|
||||
@@ -26,9 +26,9 @@
|
||||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
from m5.SimObject import SimObject
|
||||
from m5.objects.BaseInterrupts import BaseInterrupts
|
||||
|
||||
class MipsInterrupts(SimObject):
|
||||
class MipsInterrupts(BaseInterrupts):
|
||||
type = 'MipsInterrupts'
|
||||
cxx_class = 'MipsISA::Interrupts'
|
||||
cxx_header = 'arch/mips/interrupts.hh'
|
||||
|
||||
@@ -153,7 +153,7 @@ Interrupts::onCpuTimerInterrupt(ThreadContext * tc) const
|
||||
}
|
||||
|
||||
void
|
||||
Interrupts::updateIntrInfo(ThreadContext *tc) const
|
||||
Interrupts::updateIntrInfo(ThreadContext *tc)
|
||||
{
|
||||
//Nothing needs to be done.
|
||||
}
|
||||
|
||||
@@ -33,12 +33,12 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "arch/generic/interrupts.hh"
|
||||
#include "arch/mips/faults.hh"
|
||||
#include "base/compiler.hh"
|
||||
#include "base/logging.hh"
|
||||
#include "params/MipsInterrupts.hh"
|
||||
#include "sim/serialize.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
|
||||
class BaseCPU;
|
||||
class Checkpoint;
|
||||
@@ -46,7 +46,7 @@ class Checkpoint;
|
||||
namespace MipsISA
|
||||
{
|
||||
|
||||
class Interrupts : public SimObject
|
||||
class Interrupts : public BaseInterrupts
|
||||
{
|
||||
public:
|
||||
typedef MipsInterruptsParams Params;
|
||||
@@ -57,7 +57,7 @@ class Interrupts : public SimObject
|
||||
return dynamic_cast<const Params *>(_params);
|
||||
}
|
||||
|
||||
Interrupts(Params * p) : SimObject(p)
|
||||
Interrupts(Params * p) : BaseInterrupts(p)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ class Interrupts : public SimObject
|
||||
// MIPS cause register with the instatus variable. instatus
|
||||
// is essentially a copy of the MIPS cause[IP7:IP0]
|
||||
//
|
||||
void updateIntrInfo(ThreadContext *tc) const;
|
||||
void updateIntrInfo(ThreadContext *tc);
|
||||
bool interruptsPending(ThreadContext *tc) const;
|
||||
bool onCpuTimerInterrupt(ThreadContext *tc) const;
|
||||
bool checkInterrupts(ThreadContext *tc) const;
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
from m5.SimObject import SimObject
|
||||
from m5.objects.BaseInterrupts import BaseInterrupts
|
||||
|
||||
class PowerInterrupts(SimObject):
|
||||
class PowerInterrupts(BaseInterrupts):
|
||||
type = 'PowerInterrupts'
|
||||
cxx_class = 'PowerISA::Interrupts'
|
||||
cxx_header = 'arch/power/interrupts.hh'
|
||||
|
||||
@@ -31,16 +31,16 @@
|
||||
#ifndef __ARCH_POWER_INTERRUPT_HH__
|
||||
#define __ARCH_POWER_INTERRUPT_HH__
|
||||
|
||||
#include "arch/generic/interrupts.hh"
|
||||
#include "base/logging.hh"
|
||||
#include "params/PowerInterrupts.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
|
||||
class BaseCPU;
|
||||
class ThreadContext;
|
||||
|
||||
namespace PowerISA {
|
||||
|
||||
class Interrupts : public SimObject
|
||||
class Interrupts : public BaseInterrupts
|
||||
{
|
||||
private:
|
||||
BaseCPU * cpu;
|
||||
@@ -54,7 +54,7 @@ class Interrupts : public SimObject
|
||||
return dynamic_cast<const Params *>(_params);
|
||||
}
|
||||
|
||||
Interrupts(Params * p) : SimObject(p), cpu(NULL)
|
||||
Interrupts(Params * p) : BaseInterrupts(p), cpu(NULL)
|
||||
{}
|
||||
|
||||
void
|
||||
|
||||
@@ -31,9 +31,9 @@
|
||||
# Sven Karlsson
|
||||
# Alec Roelke
|
||||
|
||||
from m5.SimObject import SimObject
|
||||
from m5.objects.BaseInterrupts import BaseInterrupts
|
||||
|
||||
class RiscvInterrupts(SimObject):
|
||||
class RiscvInterrupts(BaseInterrupts):
|
||||
type = 'RiscvInterrupts'
|
||||
cxx_class = 'RiscvISA::Interrupts'
|
||||
cxx_header = 'arch/riscv/interrupts.hh'
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <bitset>
|
||||
#include <memory>
|
||||
|
||||
#include "arch/generic/interrupts.hh"
|
||||
#include "arch/riscv/faults.hh"
|
||||
#include "arch/riscv/registers.hh"
|
||||
#include "base/logging.hh"
|
||||
@@ -51,7 +52,7 @@ namespace RiscvISA {
|
||||
* This is based on version 1.10 of the RISC-V privileged ISA reference,
|
||||
* chapter 3.1.14.
|
||||
*/
|
||||
class Interrupts : public SimObject
|
||||
class Interrupts : public BaseInterrupts
|
||||
{
|
||||
private:
|
||||
BaseCPU * cpu;
|
||||
@@ -67,7 +68,7 @@ class Interrupts : public SimObject
|
||||
return dynamic_cast<const Params *>(_params);
|
||||
}
|
||||
|
||||
Interrupts(Params * p) : SimObject(p), cpu(nullptr), ip(0), ie(0) {}
|
||||
Interrupts(Params * p) : BaseInterrupts(p), cpu(nullptr), ip(0), ie(0) {}
|
||||
|
||||
void setCPU(BaseCPU * _cpu) { cpu = _cpu; }
|
||||
|
||||
@@ -92,7 +93,7 @@ class Interrupts : public SimObject
|
||||
}
|
||||
|
||||
Fault
|
||||
getInterrupt(ThreadContext *tc) const
|
||||
getInterrupt(ThreadContext *tc)
|
||||
{
|
||||
assert(checkInterrupts(tc));
|
||||
std::bitset<NumInterruptTypes> mask = globalMask(tc);
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
|
||||
#include "arch/riscv/interrupts.hh"
|
||||
#include "arch/riscv/registers.hh"
|
||||
#include "base/bitfield.hh"
|
||||
#include "cpu/base.hh"
|
||||
@@ -142,11 +143,17 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
|
||||
return 0;
|
||||
}
|
||||
case MISCREG_IP:
|
||||
return tc->getCpuPtr()->getInterruptController(tc->threadId())
|
||||
->readIP();
|
||||
{
|
||||
auto ic = dynamic_cast<RiscvISA::Interrupts *>(
|
||||
tc->getCpuPtr()->getInterruptController(tc->threadId()));
|
||||
return ic->readIP();
|
||||
}
|
||||
case MISCREG_IE:
|
||||
return tc->getCpuPtr()->getInterruptController(tc->threadId())
|
||||
->readIE();
|
||||
{
|
||||
auto ic = dynamic_cast<RiscvISA::Interrupts *>(
|
||||
tc->getCpuPtr()->getInterruptController(tc->threadId()));
|
||||
return ic->readIE();
|
||||
}
|
||||
default:
|
||||
// Try reading HPM counters
|
||||
// As a placeholder, all HPM counters are just cycle counters
|
||||
@@ -185,11 +192,19 @@ ISA::setMiscReg(int misc_reg, RegVal val, ThreadContext *tc)
|
||||
} else {
|
||||
switch (misc_reg) {
|
||||
case MISCREG_IP:
|
||||
return tc->getCpuPtr()->getInterruptController(tc->threadId())
|
||||
->setIP(val);
|
||||
{
|
||||
auto ic = dynamic_cast<RiscvISA::Interrupts *>(
|
||||
tc->getCpuPtr()->getInterruptController(tc->threadId()));
|
||||
ic->setIP(val);
|
||||
}
|
||||
break;
|
||||
case MISCREG_IE:
|
||||
return tc->getCpuPtr()->getInterruptController(tc->threadId())
|
||||
->setIE(val);
|
||||
{
|
||||
auto ic = dynamic_cast<RiscvISA::Interrupts *>(
|
||||
tc->getCpuPtr()->getInterruptController(tc->threadId()));
|
||||
ic->setIE(val);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
setMiscRegNoEffect(misc_reg, val);
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
from m5.SimObject import SimObject
|
||||
from m5.objects.BaseInterrupts import BaseInterrupts
|
||||
|
||||
class SparcInterrupts(SimObject):
|
||||
class SparcInterrupts(BaseInterrupts):
|
||||
type = 'SparcInterrupts'
|
||||
cxx_class = 'SparcISA::Interrupts'
|
||||
cxx_header = 'arch/sparc/interrupts.hh'
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#ifndef __ARCH_SPARC_INTERRUPT_HH__
|
||||
#define __ARCH_SPARC_INTERRUPT_HH__
|
||||
|
||||
#include "arch/generic/interrupts.hh"
|
||||
#include "arch/sparc/faults.hh"
|
||||
#include "arch/sparc/isa_traits.hh"
|
||||
#include "arch/sparc/registers.hh"
|
||||
@@ -55,7 +56,7 @@ enum InterruptTypes
|
||||
NumInterruptTypes
|
||||
};
|
||||
|
||||
class Interrupts : public SimObject
|
||||
class Interrupts : public BaseInterrupts
|
||||
{
|
||||
private:
|
||||
BaseCPU * cpu;
|
||||
@@ -79,7 +80,7 @@ class Interrupts : public SimObject
|
||||
return dynamic_cast<const Params *>(_params);
|
||||
}
|
||||
|
||||
Interrupts(Params * p) : SimObject(p), cpu(NULL)
|
||||
Interrupts(Params * p) : BaseInterrupts(p), cpu(NULL)
|
||||
{
|
||||
clearAll();
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "arch/sparc/asi.hh"
|
||||
#include "arch/sparc/decoder.hh"
|
||||
#include "arch/sparc/interrupts.hh"
|
||||
#include "base/bitfield.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/base.hh"
|
||||
|
||||
@@ -42,10 +42,11 @@ from m5.defines import buildEnv
|
||||
from m5.params import *
|
||||
from m5.proxy import *
|
||||
|
||||
from m5.objects.BaseInterrupts import BaseInterrupts
|
||||
from m5.objects.ClockDomain import DerivedClockDomain
|
||||
from m5.SimObject import SimObject
|
||||
|
||||
class X86LocalApic(SimObject):
|
||||
class X86LocalApic(BaseInterrupts):
|
||||
type = 'X86LocalApic'
|
||||
cxx_class = 'X86ISA::Interrupts'
|
||||
cxx_header = 'arch/x86/interrupts.hh'
|
||||
|
||||
@@ -596,7 +596,7 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
|
||||
|
||||
|
||||
X86ISA::Interrupts::Interrupts(Params * p)
|
||||
: SimObject(p), sys(p->system), clockDomain(*p->clk_domain),
|
||||
: BaseInterrupts(p), sys(p->system), clockDomain(*p->clk_domain),
|
||||
apicTimerEvent([this]{ processApicTimerEvent(); }, name()),
|
||||
pendingSmi(false), smiVector(0),
|
||||
pendingNmi(false), nmiVector(0),
|
||||
|
||||
@@ -53,13 +53,14 @@
|
||||
#ifndef __ARCH_X86_INTERRUPTS_HH__
|
||||
#define __ARCH_X86_INTERRUPTS_HH__
|
||||
|
||||
#include "arch/x86/regs/apic.hh"
|
||||
#include "arch/generic/interrupts.hh"
|
||||
#include "arch/x86/faults.hh"
|
||||
#include "arch/x86/intmessage.hh"
|
||||
#include "arch/x86/regs/apic.hh"
|
||||
#include "base/bitfield.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "dev/x86/intdev.hh"
|
||||
#include "dev/io_device.hh"
|
||||
#include "dev/x86/intdev.hh"
|
||||
#include "params/X86LocalApic.hh"
|
||||
#include "sim/eventq.hh"
|
||||
|
||||
@@ -72,7 +73,7 @@ namespace X86ISA {
|
||||
|
||||
ApicRegIndex decodeAddr(Addr paddr);
|
||||
|
||||
class Interrupts : public SimObject
|
||||
class Interrupts : public BaseInterrupts
|
||||
{
|
||||
protected:
|
||||
System *sys;
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "arch/x86/faults.hh"
|
||||
#include "arch/x86/pagetable.hh"
|
||||
#include "arch/x86/tlb.hh"
|
||||
#include "arch/x86/vtophys.hh"
|
||||
|
||||
@@ -66,44 +66,37 @@ if buildEnv['TARGET_ISA'] == 'alpha':
|
||||
from m5.objects.AlphaTLB import AlphaDTB as ArchDTB, AlphaITB as ArchITB
|
||||
from m5.objects.AlphaInterrupts import AlphaInterrupts as ArchInterrupts
|
||||
from m5.objects.AlphaISA import AlphaISA as ArchISA
|
||||
ArchInterruptsParam = VectorParam.AlphaInterrupts
|
||||
ArchISAsParam = VectorParam.AlphaISA
|
||||
elif buildEnv['TARGET_ISA'] == 'sparc':
|
||||
from m5.objects.SparcTLB import SparcTLB as ArchDTB, SparcTLB as ArchITB
|
||||
from m5.objects.SparcInterrupts import SparcInterrupts as ArchInterrupts
|
||||
from m5.objects.SparcISA import SparcISA as ArchISA
|
||||
ArchInterruptsParam = VectorParam.SparcInterrupts
|
||||
ArchISAsParam = VectorParam.SparcISA
|
||||
elif buildEnv['TARGET_ISA'] == 'x86':
|
||||
from m5.objects.X86TLB import X86TLB as ArchDTB, X86TLB as ArchITB
|
||||
from m5.objects.X86LocalApic import X86LocalApic as ArchInterrupts
|
||||
from m5.objects.X86ISA import X86ISA as ArchISA
|
||||
ArchInterruptsParam = VectorParam.X86LocalApic
|
||||
ArchISAsParam = VectorParam.X86ISA
|
||||
elif buildEnv['TARGET_ISA'] == 'mips':
|
||||
from m5.objects.MipsTLB import MipsTLB as ArchDTB, MipsTLB as ArchITB
|
||||
from m5.objects.MipsInterrupts import MipsInterrupts as ArchInterrupts
|
||||
from m5.objects.MipsISA import MipsISA as ArchISA
|
||||
ArchInterruptsParam = VectorParam.MipsInterrupts
|
||||
ArchISAsParam = VectorParam.MipsISA
|
||||
elif buildEnv['TARGET_ISA'] == 'arm':
|
||||
from m5.objects.ArmTLB import ArmTLB as ArchDTB, ArmTLB as ArchITB
|
||||
from m5.objects.ArmTLB import ArmStage2IMMU, ArmStage2DMMU
|
||||
from m5.objects.ArmInterrupts import ArmInterrupts as ArchInterrupts
|
||||
from m5.objects.ArmISA import ArmISA as ArchISA
|
||||
ArchInterruptsParam = VectorParam.ArmInterrupts
|
||||
ArchISAsParam = VectorParam.ArmISA
|
||||
elif buildEnv['TARGET_ISA'] == 'power':
|
||||
from m5.objects.PowerTLB import PowerTLB as ArchDTB, PowerTLB as ArchITB
|
||||
from m5.objects.PowerInterrupts import PowerInterrupts as ArchInterrupts
|
||||
from m5.objects.PowerISA import PowerISA as ArchISA
|
||||
ArchInterruptsParam = VectorParam.PowerInterrupts
|
||||
ArchISAsParam = VectorParam.PowerISA
|
||||
elif buildEnv['TARGET_ISA'] == 'riscv':
|
||||
from m5.objects.RiscvTLB import RiscvTLB as ArchDTB, RiscvTLB as ArchITB
|
||||
from m5.objects.RiscvInterrupts import RiscvInterrupts as ArchInterrupts
|
||||
from m5.objects.RiscvISA import RiscvISA as ArchISA
|
||||
ArchInterruptsParam = VectorParam.RiscvInterrupts
|
||||
ArchISAsParam = VectorParam.RiscvISA
|
||||
else:
|
||||
print("Don't know what object types to use for ISA %s" %
|
||||
@@ -186,7 +179,7 @@ class BaseCPU(ClockedObject):
|
||||
dstage2_mmu = ArmStage2DMMU()
|
||||
elif buildEnv['TARGET_ISA'] == 'power':
|
||||
UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?")
|
||||
interrupts = ArchInterruptsParam([], "Interrupt Controller")
|
||||
interrupts = VectorParam.BaseInterrupts([], "Interrupt Controller")
|
||||
isa = ArchISAsParam([], "ISA instance")
|
||||
|
||||
max_insts_all_threads = Param.Counter(0,
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
#if THE_ISA == NULL_ISA
|
||||
#include "arch/null/cpu_dummy.hh"
|
||||
#else
|
||||
#include "arch/interrupts.hh"
|
||||
#include "arch/generic/interrupts.hh"
|
||||
#include "arch/isa_traits.hh"
|
||||
#include "arch/microcode_rom.hh"
|
||||
#include "base/statistics.hh"
|
||||
@@ -219,10 +219,10 @@ class BaseCPU : public ClockedObject
|
||||
TheISA::MicrocodeRom microcodeRom;
|
||||
|
||||
protected:
|
||||
std::vector<TheISA::Interrupts*> interrupts;
|
||||
std::vector<BaseInterrupts*> interrupts;
|
||||
|
||||
public:
|
||||
TheISA::Interrupts *
|
||||
BaseInterrupts *
|
||||
getInterruptController(ThreadID tid)
|
||||
{
|
||||
if (interrupts.empty())
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "cpu/kvm/vm.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/simple_thread.hh"
|
||||
#include "sim/faults.hh"
|
||||
|
||||
/** Signal to use to trigger exits from KVM */
|
||||
#define KVM_KICK_SIGNAL SIGRTMIN
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
|
||||
#include "arch/registers.hh"
|
||||
#include "arch/x86/cpuid.hh"
|
||||
#include "arch/x86/faults.hh"
|
||||
#include "arch/x86/interrupts.hh"
|
||||
#include "arch/x86/regs/msr.hh"
|
||||
#include "arch/x86/utility.hh"
|
||||
#include "cpu/kvm/base.hh"
|
||||
@@ -1185,8 +1187,10 @@ X86KvmCPU::kvmRun(Tick ticks)
|
||||
{
|
||||
struct kvm_run &kvm_run(*getKvmRunState());
|
||||
|
||||
if (interrupts[0]->checkInterruptsRaw()) {
|
||||
if (interrupts[0]->hasPendingUnmaskable()) {
|
||||
auto *lapic = dynamic_cast<X86ISA::Interrupts *>(interrupts[0]);
|
||||
|
||||
if (lapic->checkInterruptsRaw()) {
|
||||
if (lapic->hasPendingUnmaskable()) {
|
||||
DPRINTF(KvmInt,
|
||||
"Delivering unmaskable interrupt.\n");
|
||||
syncThreadContext();
|
||||
@@ -1198,7 +1202,7 @@ X86KvmCPU::kvmRun(Tick ticks)
|
||||
// the thread context and check if there are /really/
|
||||
// interrupts that should be delivered now.
|
||||
syncThreadContext();
|
||||
if (interrupts[0]->checkInterrupts(tc)) {
|
||||
if (lapic->checkInterrupts(tc)) {
|
||||
DPRINTF(KvmInt,
|
||||
"M5 has pending interrupts, delivering interrupt.\n");
|
||||
|
||||
|
||||
@@ -216,8 +216,9 @@ X86ISA::I82094AA::signalInterrupt(int line)
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < numContexts; i++) {
|
||||
Interrupts *localApic = sys->getThreadContext(i)->
|
||||
BaseInterrupts *base_int = sys->getThreadContext(i)->
|
||||
getCpuPtr()->getInterruptController(0);
|
||||
auto *localApic = dynamic_cast<Interrupts *>(base_int);
|
||||
if ((localApic->readReg(APIC_LOGICAL_DESTINATION) >> 24) &
|
||||
message.destination) {
|
||||
apics.push_back(localApic->getInitialApicId());
|
||||
|
||||
Reference in New Issue
Block a user