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):
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".
#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"
}
CortexA76x1::CortexA76x1(const sc_core::sc_module_name &mod_name,
- const FastModelCortexA76x1Params ¶ms)
+ 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);
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
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)
{
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);
}
#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
{
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;
void clockChangeHandler();
+ const FastModelCortexA76x1Params ¶ms;
+
public:
CortexA76x1(const sc_core::sc_module_name &mod_name,
- const FastModelCortexA76x1Params ¶ms);
+ 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
{
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
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")
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
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
}
}
- // 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];
{
SCGIC::SCGIC(const SCFastModelGICParams ¶ms,
- 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);
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);
}
#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
{
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
{