From 16c1986fe2733de923a2e14ef3056d2f736d5c39 Mon Sep 17 00:00:00 2001 From: Earl Ou Date: Mon, 1 Feb 2021 09:41:33 +0800 Subject: [PATCH] fastmodel: create base class for EVS CPU Previously we use attribute and event for communication between gem5 SimObject to systemC fastmodel sc_module. Creating a base class allows us to perform casting once and get all the interface required. Also, instead of warning on attribute not found, we should make simulator panic if the sc_module does not provide the interface we need. Change-Id: I91e1036cb792d556dfc4010e7a0f138b1519b079 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40277 Reviewed-by: Gabe Black Maintainer: Gabe Black Tested-by: kokoro --- .../arm/fastmodel/CortexA76/cortex_a76.cc | 13 ++--- src/arch/arm/fastmodel/CortexA76/evs.cc | 49 ++++++++----------- src/arch/arm/fastmodel/CortexA76/evs.hh | 18 +++---- .../arm/fastmodel/CortexR52/cortex_r52.cc | 13 ++--- src/arch/arm/fastmodel/CortexR52/evs.cc | 26 +++++----- src/arch/arm/fastmodel/CortexR52/evs.hh | 18 +++---- src/arch/arm/fastmodel/iris/cpu.cc | 25 +--------- src/arch/arm/fastmodel/iris/cpu.hh | 41 +++++----------- 8 files changed, 70 insertions(+), 133 deletions(-) diff --git a/src/arch/arm/fastmodel/CortexA76/cortex_a76.cc b/src/arch/arm/fastmodel/CortexA76/cortex_a76.cc index d2b96764e..1decdf97c 100644 --- a/src/arch/arm/fastmodel/CortexA76/cortex_a76.cc +++ b/src/arch/arm/fastmodel/CortexA76/cortex_a76.cc @@ -104,16 +104,9 @@ CortexA76Cluster::CortexA76Cluster(const Params &p) : for (int i = 0; i < p.cores.size(); i++) p.cores[i]->setCluster(this, i); - sc_core::sc_attr_base *base; - - base = evs->get_attribute(Iris::Gem5CpuClusterAttributeName); - auto *gem5_cluster_attr = - dynamic_cast *>(base); - panic_if(base && !gem5_cluster_attr, - "The EVS gem5 CPU cluster attribute was not of type " - "sc_attribute."); - if (gem5_cluster_attr) - gem5_cluster_attr->value = this; + Iris::BaseCpuEvs *e = dynamic_cast(evs); + panic_if(!e, "EVS should be of type Iris::BaseCpuEvs"); + e->setCluster(this); set_evs_param("core.BROADCASTATOMIC", p.BROADCASTATOMIC); set_evs_param("core.BROADCASTCACHEMAINT", p.BROADCASTCACHEMAINT); diff --git a/src/arch/arm/fastmodel/CortexA76/evs.cc b/src/arch/arm/fastmodel/CortexA76/evs.cc index 360a5dd49..29d8877f6 100644 --- a/src/arch/arm/fastmodel/CortexA76/evs.cc +++ b/src/arch/arm/fastmodel/CortexA76/evs.cc @@ -39,19 +39,23 @@ namespace FastModel template void -ScxEvsCortexA76::clockChangeHandler() +ScxEvsCortexA76::setClkPeriod(Tick clk_period) { - clockRateControl->set_mul_div(SimClock::Int::s, clockPeriod.value); + clockRateControl->set_mul_div(SimClock::Int::s, clk_period); +} + +template +void +ScxEvsCortexA76::setCluster(SimObject *cluster) +{ + gem5CpuCluster = dynamic_cast(cluster); + panic_if(!gem5CpuCluster, "Cluster should be of type CortexA76Cluster"); } template ScxEvsCortexA76::ScxEvsCortexA76( const sc_core::sc_module_name &mod_name, const Params &p) : Base(mod_name), amba(Base::amba, p.name + ".amba", -1), - clockChanged(Iris::ClockEventName.c_str()), - clockPeriod(Iris::PeriodAttributeName.c_str()), - gem5CpuCluster(Iris::Gem5CpuClusterAttributeName.c_str()), - sendFunctional(Iris::SendFunctionalAttributeName.c_str()), params(p) { for (int i = 0; i < CoreCount; i++) { @@ -82,15 +86,6 @@ ScxEvsCortexA76::ScxEvsCortexA76( } clockRateControl.bind(this->clock_rate_s); - - this->add_attribute(gem5CpuCluster); - this->add_attribute(clockPeriod); - SC_METHOD(clockChangeHandler); - this->dont_initialize(); - this->sensitive << clockChanged; - - sendFunctional.value = [this](PacketPtr pkt) { sendFunc(pkt); }; - this->add_attribute(sendFunctional); } template @@ -109,12 +104,10 @@ ScxEvsCortexA76::before_end_of_elaboration() { Base::before_end_of_elaboration(); - auto *cluster = gem5CpuCluster.value; - - auto set_on_change = [cluster]( + auto set_on_change = [this]( SignalReceiver &recv, ArmInterruptPinGen *gen, int num) { - auto *pin = gen->get(cluster->getCore(num)->getContext(0)); + auto *pin = gen->get(gem5CpuCluster->getCore(num)->getContext(0)); auto handler = [pin](bool status) { status ? pin->raise() : pin->clear(); @@ -123,15 +116,15 @@ ScxEvsCortexA76::before_end_of_elaboration() }; for (int i = 0; i < CoreCount; i++) { - set_on_change(*cnthpirq[i], cluster->params().cnthpirq, i); - set_on_change(*cnthvirq[i], cluster->params().cnthvirq, i); - set_on_change(*cntpsirq[i], cluster->params().cntpsirq, i); - set_on_change(*cntvirq[i], cluster->params().cntvirq, i); - set_on_change(*commirq[i], cluster->params().commirq, i); - set_on_change(*ctidbgirq[i], cluster->params().ctidbgirq, i); - set_on_change(*pmuirq[i], cluster->params().pmuirq, i); - set_on_change(*vcpumntirq[i], cluster->params().vcpumntirq, i); - set_on_change(*cntpnsirq[i], cluster->params().cntpnsirq, i); + set_on_change(*cnthpirq[i], gem5CpuCluster->params().cnthpirq, i); + set_on_change(*cnthvirq[i], gem5CpuCluster->params().cnthvirq, i); + set_on_change(*cntpsirq[i], gem5CpuCluster->params().cntpsirq, i); + set_on_change(*cntvirq[i], gem5CpuCluster->params().cntvirq, i); + set_on_change(*commirq[i], gem5CpuCluster->params().commirq, i); + set_on_change(*ctidbgirq[i], gem5CpuCluster->params().ctidbgirq, i); + set_on_change(*pmuirq[i], gem5CpuCluster->params().pmuirq, i); + set_on_change(*vcpumntirq[i], gem5CpuCluster->params().vcpumntirq, i); + set_on_change(*cntpnsirq[i], gem5CpuCluster->params().cntpnsirq, i); } } diff --git a/src/arch/arm/fastmodel/CortexA76/evs.hh b/src/arch/arm/fastmodel/CortexA76/evs.hh index e57bdd763..fa12ff821 100644 --- a/src/arch/arm/fastmodel/CortexA76/evs.hh +++ b/src/arch/arm/fastmodel/CortexA76/evs.hh @@ -32,6 +32,7 @@ #include "arch/arm/fastmodel/amba_ports.hh" #include "arch/arm/fastmodel/common/signal_receiver.hh" +#include "arch/arm/fastmodel/iris/cpu.hh" #include "arch/arm/fastmodel/protocol/exported_clock_rate_control.hh" #include "mem/port_proxy.hh" #include "params/FastModelScxEvsCortexA76x1.hh" @@ -52,7 +53,7 @@ namespace FastModel class CortexA76Cluster; template -class ScxEvsCortexA76 : public Types::Base +class ScxEvsCortexA76 : public Types::Base, public Iris::BaseCpuEvs { private: static const int CoreCount = Types::CoreCount; @@ -81,14 +82,7 @@ class ScxEvsCortexA76 : public Types::Base std::vector> vcpumntirq; std::vector> cntpnsirq; - sc_core::sc_event clockChanged; - sc_core::sc_attribute clockPeriod; - sc_core::sc_attribute gem5CpuCluster; - sc_core::sc_attribute sendFunctional; - - void sendFunc(PacketPtr pkt); - - void clockChangeHandler(); + CortexA76Cluster *gem5CpuCluster; const Params ¶ms; @@ -106,6 +100,12 @@ class ScxEvsCortexA76 : public Types::Base Base::start_of_simulation(); } void start_of_simulation() override {} + + void sendFunc(PacketPtr pkt) override; + + void setClkPeriod(Tick clk_period) override; + + void setCluster(SimObject *cluster) override; }; struct ScxEvsCortexA76x1Types diff --git a/src/arch/arm/fastmodel/CortexR52/cortex_r52.cc b/src/arch/arm/fastmodel/CortexR52/cortex_r52.cc index 18bb33d48..3a8ac3dc1 100644 --- a/src/arch/arm/fastmodel/CortexR52/cortex_r52.cc +++ b/src/arch/arm/fastmodel/CortexR52/cortex_r52.cc @@ -99,16 +99,9 @@ CortexR52Cluster::CortexR52Cluster(const Params &p) : for (int i = 0; i < p.cores.size(); i++) p.cores[i]->setCluster(this, i); - sc_core::sc_attr_base *base; - - base = evs->get_attribute(Iris::Gem5CpuClusterAttributeName); - auto *gem5_cluster_attr = - dynamic_cast *>(base); - panic_if(base && !gem5_cluster_attr, - "The EVS gem5 CPU cluster attribute was not of type " - "sc_attribute."); - if (gem5_cluster_attr) - gem5_cluster_attr->value = this; + Iris::BaseCpuEvs *e = dynamic_cast(evs); + panic_if(!e, "EVS should be of type Iris::BaseCpuEvs"); + e->setCluster(this); set_evs_param("core.CLUSTER_ID", params().CLUSTER_ID); set_evs_param("core.DBGROMADDR", params().DBGROMADDR); diff --git a/src/arch/arm/fastmodel/CortexR52/evs.cc b/src/arch/arm/fastmodel/CortexR52/evs.cc index 50ac670f6..cd84aa62e 100644 --- a/src/arch/arm/fastmodel/CortexR52/evs.cc +++ b/src/arch/arm/fastmodel/CortexR52/evs.cc @@ -27,6 +27,7 @@ #include "arch/arm/fastmodel/CortexR52/evs.hh" +#include "arch/arm/fastmodel/CortexR52/cortex_r52.hh" #include "arch/arm/fastmodel/iris/cpu.hh" #include "base/logging.hh" #include "sim/core.hh" @@ -37,9 +38,17 @@ namespace FastModel template void -ScxEvsCortexR52::clockChangeHandler() +ScxEvsCortexR52::setClkPeriod(Tick clk_period) { - clockRateControl->set_mul_div(SimClock::Int::s, clockPeriod.value); + clockRateControl->set_mul_div(SimClock::Int::s, clk_period); +} + +template +void +ScxEvsCortexR52::setCluster(SimObject *cluster) +{ + gem5CpuCluster = dynamic_cast(cluster); + panic_if(!gem5CpuCluster, "Cluster should be of type CortexR52Cluster"); } template @@ -61,10 +70,6 @@ template ScxEvsCortexR52::ScxEvsCortexR52( const sc_core::sc_module_name &mod_name, const Params &p) : Base(mod_name), - clockChanged(Iris::ClockEventName.c_str()), - clockPeriod(Iris::PeriodAttributeName.c_str()), - gem5CpuCluster(Iris::Gem5CpuClusterAttributeName.c_str()), - sendFunctional(Iris::SendFunctionalAttributeName.c_str()), params(p) { for (int i = 0; i < CoreCount; i++) @@ -77,15 +82,6 @@ ScxEvsCortexR52::ScxEvsCortexR52( clockRateControl.bind(this->clock_rate_s); signalInterrupt.bind(this->signal_interrupt); - - this->add_attribute(gem5CpuCluster); - this->add_attribute(clockPeriod); - SC_METHOD(clockChangeHandler); - this->dont_initialize(); - this->sensitive << clockChanged; - - sendFunctional.value = [this](PacketPtr pkt) { sendFunc(pkt); }; - this->add_attribute(sendFunctional); } template diff --git a/src/arch/arm/fastmodel/CortexR52/evs.hh b/src/arch/arm/fastmodel/CortexR52/evs.hh index 3f663020a..e03a32200 100644 --- a/src/arch/arm/fastmodel/CortexR52/evs.hh +++ b/src/arch/arm/fastmodel/CortexR52/evs.hh @@ -32,6 +32,7 @@ #include "arch/arm/fastmodel/amba_ports.hh" #include "arch/arm/fastmodel/common/signal_receiver.hh" +#include "arch/arm/fastmodel/iris/cpu.hh" #include "arch/arm/fastmodel/protocol/exported_clock_rate_control.hh" #include "arch/arm/fastmodel/protocol/signal_interrupt.hh" #include "dev/intpin.hh" @@ -54,7 +55,7 @@ namespace FastModel class CortexR52Cluster; template -class ScxEvsCortexR52 : public Types::Base +class ScxEvsCortexR52 : public Types::Base, public Iris::BaseCpuEvs { private: static const int CoreCount = Types::CoreCount; @@ -105,14 +106,7 @@ class ScxEvsCortexR52 : public Types::Base std::vector> spis; - sc_core::sc_event clockChanged; - sc_core::sc_attribute clockPeriod; - sc_core::sc_attribute gem5CpuCluster; - sc_core::sc_attribute sendFunctional; - - void sendFunc(PacketPtr pkt); - - void clockChangeHandler(); + CortexR52Cluster *gem5CpuCluster; const Params ¶ms; @@ -141,6 +135,12 @@ class ScxEvsCortexR52 : public Types::Base Base::start_of_simulation(); } void start_of_simulation() override {} + + void sendFunc(PacketPtr pkt) override; + + void setClkPeriod(Tick clk_period) override; + + void setCluster(SimObject *cluster) override; }; struct ScxEvsCortexR52x1Types diff --git a/src/arch/arm/fastmodel/iris/cpu.cc b/src/arch/arm/fastmodel/iris/cpu.cc index cf93c8cd5..a155deaf4 100644 --- a/src/arch/arm/fastmodel/iris/cpu.cc +++ b/src/arch/arm/fastmodel/iris/cpu.cc @@ -36,30 +36,9 @@ namespace Iris BaseCPU::BaseCPU(const BaseCPUParams ¶ms, sc_core::sc_module *_evs) : ::BaseCPU::BaseCPU(params), evs(_evs), - clockEvent(nullptr), periodAttribute(nullptr) + evs_base_cpu(dynamic_cast(_evs)) { - sc_core::sc_attr_base *base; - - const auto &event_vec = evs->get_child_events(); - auto event_it = std::find_if(event_vec.begin(), event_vec.end(), - [](const sc_core::sc_event *e) -> bool { - return e->basename() == ClockEventName; }); - if (event_it != event_vec.end()) - clockEvent = *event_it; - - base = evs->get_attribute(PeriodAttributeName); - periodAttribute = dynamic_cast *>(base); - panic_if(base && !periodAttribute, - "The EVS clock period attribute is not of type " - "sc_attribute."); - - base = evs->get_attribute(SendFunctionalAttributeName); - sendFunctional = - dynamic_cast *>( - base); - panic_if(base && !sendFunctional, - "The EVS send functional attribute is not of type " - "sc_attribute."); + panic_if(!evs_base_cpu, "EVS should be of type BaseCpuEvs"); // Make sure fast model knows we're using debugging mechanisms to control // the simulation, and it shouldn't shut down if simulation time stops diff --git a/src/arch/arm/fastmodel/iris/cpu.hh b/src/arch/arm/fastmodel/iris/cpu.hh index 277258a2f..c5dd19f24 100644 --- a/src/arch/arm/fastmodel/iris/cpu.hh +++ b/src/arch/arm/fastmodel/iris/cpu.hh @@ -38,18 +38,14 @@ namespace Iris { -// The name of the event that should be notified when the CPU subsystem needs -// to adjust it's clock. -static const std::string ClockEventName = "gem5_clock_period_event"; -// The name of the attribute the subsystem should create which can be set to -// the desired clock period, in gem5's Ticks. -static const std::string PeriodAttributeName = "gem5_clock_period_attribute"; -// The name of the attribute the subsystem should create which will be set to -// a pointer to its corresponding gem5 CPU. -static const std::string Gem5CpuClusterAttributeName = "gem5_cpu_cluster"; -// The name of the attribute the subsystem should create to hold the -// sendFunctional delegate for port proxies. -static const std::string SendFunctionalAttributeName = "gem5_send_functional"; +// The base interface of the EVS used by gem5 BaseCPU below. +class BaseCpuEvs +{ + public: + virtual void sendFunc(PacketPtr pkt) = 0; + virtual void setClkPeriod(Tick clk_period) = 0; + virtual void setCluster(SimObject *cluster) = 0; +}; // This CPU class adds some mechanisms which help attach the gem5 and fast // model CPUs to each other. It acts as a base class for the gem5 CPU, and @@ -87,32 +83,19 @@ class BaseCPU : public ::BaseCPU PortProxy::SendFunctionalFunc getSendFunctional() override { - if (sendFunctional) - return sendFunctional->value; - return ::BaseCPU::getSendFunctional(); + return [this] (PacketPtr pkt) { evs_base_cpu->sendFunc(pkt); }; } protected: sc_core::sc_module *evs; - - private: - sc_core::sc_event *clockEvent; - sc_core::sc_attribute *periodAttribute; - sc_core::sc_attribute *sendFunctional; + // Hold casted pointer to *evs. + Iris::BaseCpuEvs *evs_base_cpu; protected: void clockPeriodUpdated() override { - if (!clockEvent || !periodAttribute) { - warn("Unable to notify EVS of clock change, missing:"); - warn_if(!clockEvent, " Clock change event"); - warn_if(!periodAttribute, " Clock period attribute"); - return; - } - - periodAttribute->value = clockPeriod(); - clockEvent->notify(); + evs_base_cpu->setClkPeriod(clockPeriod()); } void init() override; -- 2.30.2