fastmodel: Make CortexA76x1's interrupts use gem5's mechanisms.

This makes it easier to wire up CPUs to the interrupt controller, and
makes things more modular.

Change-Id: I8d3ab26e4bb588b8efb198ed145d0f58b7ee04cb
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21049
Reviewed-by: Chun-Chen TK Hsu <chunchenhsu@google.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Gabe Black
2019-08-28 15:16:05 -07:00
parent d241429e60
commit 8329f4bb65
7 changed files with 90 additions and 156 deletions

View File

@@ -31,10 +31,10 @@ from m5.SimObject import SimObject
from m5.objects.ArmInterrupts import ArmInterrupts
from m5.objects.ArmISA import ArmISA
from m5.objects.FastModel import AmbaInitiatorSocket, AmbaTargetSocket
from m5.objects.FastModel import ScMasterPort
from m5.objects.FastModelArch import FastModelArmCPU
from m5.objects.FastModelGIC import Gicv3CommsInitiatorSocket
from m5.objects.FastModelGIC import Gicv3CommsTargetSocket
from m5.objects.Gic import ArmPPI
from m5.objects.SystemC import SystemC_ScModule
class FastModelCortexA76x1(SystemC_ScModule):
@@ -53,18 +53,26 @@ class FastModelCortexA76x1(SystemC_ScModule):
isa = [ ArmISA() ],
)
cnthpirq = Param.ArmInterruptPin(ArmPPI(num=10),
"EL2 physical timer event")
cnthvirq = Param.ArmInterruptPin(ArmPPI(num=12), "EL2 virtual timer event")
cntpsirq = Param.ArmInterruptPin(ArmPPI(num=13),
"EL1 Secure physical timer event")
cntvirq = Param.ArmInterruptPin(ArmPPI(num=11), "Virtual timer event")
commirq = Param.ArmInterruptPin(ArmPPI(num=6),
"Interrupt signal from debug communications channel")
ctidbgirq = Param.ArmInterruptPin(ArmPPI(num=8),
"Cross Trigger Interface (CTI) interrupt trigger output")
pmuirq = Param.ArmInterruptPin(ArmPPI(num=7),
"Interrupt from performance monitoring unit")
vcpumntirq = Param.ArmInterruptPin(ArmPPI(num=9),
"Interrupt signal for virtual CPU maintenance IRQ")
cntpnsirq = Param.ArmInterruptPin(ArmPPI(num=14),
"Non-secure physical timer event")
amba = AmbaInitiatorSocket(64, 'AMBA initiator socket')
redistributor_m = Gicv3CommsInitiatorSocket('GIC communication initiator')
redistributor_s = Gicv3CommsTargetSocket('GIC communication target')
cnthpirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool")
cnthvirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool")
cntpsirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool")
cntvirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool")
commirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool")
ctidbgirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool")
pmuirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool")
vcpumntirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool")
cntpnsirq = ScMasterPort("Master port for CPU-to-GIC signal", "bool")
# These parameters are described in "Fast Models Reference Manual" section
# 3.4.19, "ARMCortexA7x1CT".

View File

@@ -29,8 +29,10 @@
#include "arch/arm/fastmodel/CortexA76x1/cortex_a76x1.hh"
#include "arch/arm/fastmodel/arm/cpu.hh"
#include "arch/arm/fastmodel/iris/cpu.hh"
#include "base/logging.hh"
#include "dev/arm/base_gic.hh"
#include "params/FastModelCortexA76x1.hh"
#include "sim/core.hh"
#include "systemc/tlm_bridge/gem5_to_tlm.hh"
@@ -45,24 +47,25 @@ CortexA76x1::clockChangeHandler()
}
CortexA76x1::CortexA76x1(const sc_core::sc_module_name &mod_name,
const FastModelCortexA76x1Params &params)
const FastModelCortexA76x1Params &p)
: scx_evs_CortexA76x1(mod_name),
amba(scx_evs_CortexA76x1::amba, params.name + ".amba", -1),
redistributorM(redistributor_m, params.name + ".redistributor_m", -1),
redistributorS(redistributor_s, params.name + ".redistributor_s", -1),
cnthpirqWrapper(cnthpirq, params.name + ".cnthpirq", -1),
cnthvirqWrapper(cnthvirq, params.name + ".cnthvirq", -1),
cntpsirqWrapper(cntpsirq, params.name + ".cntpsirq", -1),
cntvirqWrapper(cntvirq, params.name + ".cntvirq", -1),
commirqWrapper(commirq, params.name + ".commirq", -1),
ctidbgirqWrapper(ctidbgirq, params.name + ".ctidbgirq", -1),
pmuirqWrapper(pmuirq, params.name + ".pmuirq", -1),
vcpumntirqWrapper(vcpumntirq, params.name + ".vcpumntirq", -1),
cntpnsirqWrapper(cntpnsirq, params.name + ".cntpnsirq", -1),
amba(scx_evs_CortexA76x1::amba, p.name + ".amba", -1),
redistributorM(redistributor_m, p.name + ".redistributor_m", -1),
redistributorS(redistributor_s, p.name + ".redistributor_s", -1),
cnthpirq("cnthpirq"),
cnthvirq("cnthvirq"),
cntpsirq("cntpsirq"),
cntvirq("cntvirq"),
commirq("commirq"),
ctidbgirq("ctidbgirq"),
pmuirq("pmuirq"),
vcpumntirq("vcpumntirq"),
cntpnsirq("cntpnsirq"),
clockChanged(Iris::ClockEventName.c_str()),
clockPeriod(Iris::PeriodAttributeName.c_str()),
gem5Cpu(Iris::Gem5CpuAttributeName.c_str()),
sendFunctional(Iris::SendFunctionalAttributeName.c_str())
sendFunctional(Iris::SendFunctionalAttributeName.c_str()),
params(p)
{
clockRateControl.bind(clock_rate_s);
@@ -206,6 +209,16 @@ CortexA76x1::CortexA76x1(const sc_core::sc_module_name &mod_name,
sendFunctional.value = [this](PacketPtr pkt) { sendFunc(pkt); };
add_attribute(sendFunctional);
scx_evs_CortexA76x1::cnthpirq.bind(cnthpirq.signal_in);
scx_evs_CortexA76x1::cnthvirq.bind(cnthvirq.signal_in);
scx_evs_CortexA76x1::cntpsirq.bind(cntpsirq.signal_in);
scx_evs_CortexA76x1::cntvirq.bind(cntvirq.signal_in);
scx_evs_CortexA76x1::commirq.bind(commirq.signal_in);
scx_evs_CortexA76x1::ctidbgirq.bind(ctidbgirq.signal_in);
scx_evs_CortexA76x1::pmuirq.bind(pmuirq.signal_in);
scx_evs_CortexA76x1::vcpumntirq.bind(vcpumntirq.signal_in);
scx_evs_CortexA76x1::cntpnsirq.bind(cntpnsirq.signal_in);
}
void
@@ -217,6 +230,35 @@ CortexA76x1::sendFunc(PacketPtr pkt)
trans->release();
}
void
CortexA76x1::before_end_of_elaboration()
{
scx_evs_CortexA76x1::before_end_of_elaboration();
auto *gem5_cpu = gem5Cpu.value;
auto set_on_change = [gem5_cpu](SignalReceiver &recv,
ArmInterruptPinGen *gen,
int ctx_num)
{
auto *pin = gen->get(gem5_cpu->getContext(ctx_num));
auto handler = [pin](bool status)
{
status ? pin->raise() : pin->clear();
};
recv.onChange(handler);
};
set_on_change(cnthpirq, params.cnthpirq, 0);
set_on_change(cnthvirq, params.cnthvirq, 0);
set_on_change(cntpsirq, params.cntpsirq, 0);
set_on_change(cntvirq, params.cntvirq, 0);
set_on_change(commirq, params.commirq, 0);
set_on_change(ctidbgirq, params.ctidbgirq, 0);
set_on_change(pmuirq, params.pmuirq, 0);
set_on_change(vcpumntirq, params.vcpumntirq, 0);
set_on_change(cntpnsirq, params.cntpnsirq, 0);
}
Port &
CortexA76x1::gem5_getPort(const std::string &if_name, int idx)
{
@@ -226,24 +268,6 @@ CortexA76x1::gem5_getPort(const std::string &if_name, int idx)
return redistributorM;
else if (if_name == "redistributor_s")
return redistributorS;
else if (if_name == "cnthpirq")
return cnthpirqWrapper;
else if (if_name == "cnthvirq")
return cnthvirqWrapper;
else if (if_name == "cntpsirq")
return cntpsirqWrapper;
else if (if_name == "cntvirq")
return cntvirqWrapper;
else if (if_name == "commirq")
return commirqWrapper;
else if (if_name == "ctidbgirq")
return ctidbgirqWrapper;
else if (if_name == "pmuirq")
return pmuirqWrapper;
else if (if_name == "vcpumntirq")
return vcpumntirqWrapper;
else if (if_name == "cntpnsirq")
return cntpnsirqWrapper;
else
return scx_evs_CortexA76x1::gem5_getPort(if_name, idx);
}

View File

@@ -30,24 +30,17 @@
#ifndef __ARCH_ARM_FASTMODEL_CORTEXA76X1_CORETEX_A76X1_HH__
#define __ARCH_ARM_FASTMODEL_CORTEXA76X1_CORETEX_A76X1_HH__
#include <type_traits>
#include "arch/arm/fastmodel/amba_ports.hh"
#include "arch/arm/fastmodel/common/signal_receiver.hh"
#include "arch/arm/fastmodel/protocol/exported_clock_rate_control.hh"
#include "mem/port_proxy.hh"
#include "params/FastModelCortexA76x1.hh"
#include "scx_evs_CortexA76x1.h"
#include "systemc/ext/core/sc_event.hh"
#include "systemc/ext/core/sc_module.hh"
#include "systemc/sc_port_wrapper.hh"
class BaseCPU;
// This macro is to get the type IF of a sc_export<IF> variable x. It relies on
// the fact that the "operator->()" function returns the "IF*" type and
// std::decay to remove cv-qualifiers and reference.
#define IFACE_TYPE(x) std::decay<decltype(*(x).operator->())>::type
namespace FastModel
{
@@ -67,15 +60,15 @@ class CortexA76x1 : public scx_evs_CortexA76x1
ClockRateControlInitiatorSocket clockRateControl;
sc_gem5::ScPortWrapper<IFACE_TYPE(cnthpirq)> cnthpirqWrapper;
sc_gem5::ScPortWrapper<IFACE_TYPE(cnthvirq)> cnthvirqWrapper;
sc_gem5::ScPortWrapper<IFACE_TYPE(cntpsirq)> cntpsirqWrapper;
sc_gem5::ScPortWrapper<IFACE_TYPE(cntvirq)> cntvirqWrapper;
sc_gem5::ScPortWrapper<IFACE_TYPE(commirq)> commirqWrapper;
sc_gem5::ScPortWrapper<IFACE_TYPE(ctidbgirq)> ctidbgirqWrapper;
sc_gem5::ScPortWrapper<IFACE_TYPE(pmuirq)> pmuirqWrapper;
sc_gem5::ScPortWrapper<IFACE_TYPE(vcpumntirq)> vcpumntirqWrapper;
sc_gem5::ScPortWrapper<IFACE_TYPE(cntpnsirq)> cntpnsirqWrapper;
SignalReceiver cnthpirq;
SignalReceiver cnthvirq;
SignalReceiver cntpsirq;
SignalReceiver cntvirq;
SignalReceiver commirq;
SignalReceiver ctidbgirq;
SignalReceiver pmuirq;
SignalReceiver vcpumntirq;
SignalReceiver cntpnsirq;
sc_core::sc_event clockChanged;
sc_core::sc_attribute<Tick> clockPeriod;
@@ -86,12 +79,16 @@ class CortexA76x1 : public scx_evs_CortexA76x1
void clockChangeHandler();
const FastModelCortexA76x1Params &params;
public:
CortexA76x1(const sc_core::sc_module_name &mod_name,
const FastModelCortexA76x1Params &params);
const FastModelCortexA76x1Params &p);
Port &gem5_getPort(const std::string &if_name, int idx=-1) override;
void before_end_of_elaboration() override;
void
end_of_elaboration() override
{

View File

@@ -29,7 +29,6 @@ from m5.params import *
from m5.SimObject import SimObject
from m5.objects.FastModel import AmbaInitiatorSocket, AmbaTargetSocket
from m5.objects.FastModel import ScSlavePort
from m5.objects.Gic import BaseGic
from m5.objects.SystemC import SystemC_ScModule
@@ -460,13 +459,3 @@ class FastModelGIC(BaseGic):
redistributor_m = Gicv3CommsInitiatorSocket('GIC communication initiator')
redistributor_s = Gicv3CommsTargetSocket('GIC communication target')
cnthpirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool")
cnthvirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool")
cntpsirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool")
cntvirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool")
commirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool")
ctidbgirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool")
pmuirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool")
vcpumntirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool")
cntpnsirq = ScSlavePort("Slave port for CPU-to-GIC signal", "bool")

View File

@@ -43,17 +43,6 @@ component GIC
gic_gic2pv : GICv3CommsPVBus();
gic_pv2amba : PVBus2AMBAPV();
gic_amba2pv : AMBAPV2PVBus();
// Adapters for CPU-to-GIC signals
cnthpirqBridge : AMBAPVSignal2SGSignal();
cnthvirqBridge : AMBAPVSignal2SGSignal();
cntpnsirqBridge : AMBAPVSignal2SGSignal();
cntpsirqBridge : AMBAPVSignal2SGSignal();
cntvirqBridge : AMBAPVSignal2SGSignal();
commirqBridge : AMBAPVSignal2SGSignal();
ctidbgirqBridge : AMBAPVSignal2SGSignal();
pmuirqBridge : AMBAPVSignal2SGSignal();
vcpumntirqBridge : AMBAPVSignal2SGSignal();
}
connection
@@ -330,26 +319,6 @@ component GIC
self.ppi_255 => gic.ppi_in_255;
self.spi => gic.spi_in;
// Connections from CPU
self.cnthpirq => cnthpirqBridge.amba_pv_signal_s;
cnthpirqBridge.sg_signal_m => gic.ppi_in_0[10];
self.cnthvirq => cnthvirqBridge.amba_pv_signal_s;
cnthvirqBridge.sg_signal_m => gic.ppi_in_0[12];
self.cntpnsirq => cntpnsirqBridge.amba_pv_signal_s;
cntpnsirqBridge.sg_signal_m => gic.ppi_in_0[14];
self.cntpsirq => cntpsirqBridge.amba_pv_signal_s;
cntpsirqBridge.sg_signal_m => gic.ppi_in_0[13];
self.cntvirq => cntvirqBridge.amba_pv_signal_s;
cntvirqBridge.sg_signal_m => gic.ppi_in_0[11];
self.commirq => commirqBridge.amba_pv_signal_s;
commirqBridge.sg_signal_m => gic.ppi_in_0[6];
self.ctidbgirq => ctidbgirqBridge.amba_pv_signal_s;
ctidbgirqBridge.sg_signal_m => gic.ppi_in_0[8];
self.pmuirq => pmuirqBridge.amba_pv_signal_s;
pmuirqBridge.sg_signal_m => gic.ppi_in_0[7];
self.vcpumntirq => vcpumntirqBridge.amba_pv_signal_s;
vcpumntirqBridge.sg_signal_m => gic.ppi_in_0[9];
}
properties
@@ -439,17 +408,6 @@ component GIC
}
}
// CPU-side connections
slave port<AMBAPVSignal> cnthpirq;
slave port<AMBAPVSignal> cnthvirq;
slave port<AMBAPVSignal> cntpnsirq;
slave port<AMBAPVSignal> cntpsirq;
slave port<AMBAPVSignal> cntvirq;
slave port<AMBAPVSignal> commirq;
slave port<AMBAPVSignal> ctidbgirq;
slave port<AMBAPVSignal> pmuirq;
slave port<AMBAPVSignal> vcpumntirq;
internal slave port<Signal> spi[988];
internal slave port<Signal> ppi_0[16];

View File

@@ -37,16 +37,7 @@ namespace FastModel
{
SCGIC::SCGIC(const SCFastModelGICParams &params,
sc_core::sc_module_name _name) : scx_evs_GIC(_name),
cnthpirqWrapper(cnthpirq, params.name + ".cnthpirq", -1),
cnthvirqWrapper(cnthvirq, params.name + ".cnthvirq", -1),
cntpnsirqWrapper(cntpnsirq, params.name + ".cntpnsirq", -1),
cntpsirqWrapper(cntpsirq, params.name + ".cntpsirq", -1),
cntvirqWrapper(cntvirq, params.name + ".cntvirq", -1),
commirqWrapper(commirq, params.name + ".commirq", -1),
ctidbgirqWrapper(ctidbgirq, params.name + ".ctidbgirq", -1),
pmuirqWrapper(pmuirq, params.name + ".pmuirq", -1),
vcpumntirqWrapper(vcpumntirq, params.name + ".vcpumntirq", -1)
sc_core::sc_module_name _name) : scx_evs_GIC(_name)
{
signalInterrupt.bind(signal_interrupt);
@@ -289,24 +280,6 @@ GIC::getPort(const std::string &if_name, PortID idx)
return redistributorM;
else if (if_name == "redistributor_s")
return redistributorS;
else if (if_name == "cnthpirq")
return scGIC->cnthpirqWrapper;
else if (if_name == "cnthvirq")
return scGIC->cnthvirqWrapper;
else if (if_name == "cntpnsirq")
return scGIC->cntpnsirqWrapper;
else if (if_name == "cntpsirq")
return scGIC->cntpsirqWrapper;
else if (if_name == "cntvirq")
return scGIC->cntvirqWrapper;
else if (if_name == "commirq")
return scGIC->commirqWrapper;
else if (if_name == "ctidbgirq")
return scGIC->ctidbgirqWrapper;
else if (if_name == "pmuirq")
return scGIC->pmuirqWrapper;
else if (if_name == "vcpumntirq")
return scGIC->vcpumntirqWrapper;
else
return BaseGic::getPort(if_name, idx);
}

View File

@@ -40,11 +40,6 @@
#include "systemc/ext/core/sc_module_name.hh"
#include "systemc/sc_port_wrapper.hh"
// This macro is to get the type IF of a sc_export<IF> variable x. It relies on
// the fact that the "operator->()" function returns the "IF*" type and
// std::decay to remove cv-qualifiers and reference.
#define IFACE_TYPE(x) std::decay<decltype(*(x).operator->())>::type
namespace FastModel
{
@@ -60,16 +55,6 @@ class SCGIC : public scx_evs_GIC
SignalInterruptInitiatorSocket signalInterrupt;
sc_gem5::ScInterfaceWrapper<IFACE_TYPE(cnthpirq)> cnthpirqWrapper;
sc_gem5::ScInterfaceWrapper<IFACE_TYPE(cnthvirq)> cnthvirqWrapper;
sc_gem5::ScInterfaceWrapper<IFACE_TYPE(cntpnsirq)> cntpnsirqWrapper;
sc_gem5::ScInterfaceWrapper<IFACE_TYPE(cntpsirq)> cntpsirqWrapper;
sc_gem5::ScInterfaceWrapper<IFACE_TYPE(cntvirq)> cntvirqWrapper;
sc_gem5::ScInterfaceWrapper<IFACE_TYPE(commirq)> commirqWrapper;
sc_gem5::ScInterfaceWrapper<IFACE_TYPE(ctidbgirq)> ctidbgirqWrapper;
sc_gem5::ScInterfaceWrapper<IFACE_TYPE(pmuirq)> pmuirqWrapper;
sc_gem5::ScInterfaceWrapper<IFACE_TYPE(vcpumntirq)> vcpumntirqWrapper;
void
end_of_elaboration() override
{