blob: 720f1ccf8984bc7f111f5eeb47f2458252a89d4d [file] [log] [blame]
/*
* Copyright 2020 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.
*/
#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"
#include "systemc/tlm_bridge/gem5_to_tlm.hh"
namespace gem5
{
GEM5_DEPRECATED_NAMESPACE(FastModel, fastmodel);
namespace fastmodel
{
template <class Types>
void
ScxEvsCortexR52<Types>::setClkPeriod(Tick clk_period)
{
clockRateControl->set_mul_div(sim_clock::as_int::s, clk_period);
}
template <class Types>
void
ScxEvsCortexR52<Types>::setSysCounterFrq(uint64_t sys_counter_frq)
{
panic("Not implemented for R52.");
}
template <class Types>
void
ScxEvsCortexR52<Types>::setCluster(SimObject *cluster)
{
gem5CpuCluster = dynamic_cast<CortexR52Cluster *>(cluster);
panic_if(!gem5CpuCluster, "Cluster should be of type CortexR52Cluster");
}
template <class Types>
void
ScxEvsCortexR52<Types>::setResetAddr(int core, Addr addr, bool secure)
{
this->corePins[core]->cfgvectable.set_state(0, addr);
}
template <class Types>
ScxEvsCortexR52<Types>::CorePins::CorePins(Evs *_evs, int _cpu) :
name(csprintf("%s.cpu%s", _evs->name(), _cpu)),
evs(_evs), cpu(_cpu),
llpp(evs->llpp[cpu], name + ".llpp", -1),
flash(evs->flash[cpu], name + ".flash", -1),
amba(evs->amba[cpu], name + ".amba", -1),
core_reset(name + ".core_reset", 0),
poweron_reset(name + ".poweron_reset", 0),
halt(name + ".halt", 0),
cfgvectable((name + "cfgvectable").c_str())
{
for (int i = 0; i < Evs::PpiCount; i++) {
ppis.emplace_back(
new CoreInt(csprintf("%s.ppi[%d]", name, i), i, this));
}
core_reset.signal_out.bind(evs->core_reset[cpu]);
poweron_reset.signal_out.bind(evs->poweron_reset[cpu]);
halt.signal_out.bind(evs->halt[cpu]);
cfgvectable.bind(evs->cfgvectable[cpu]);
}
template <class Types>
ScxEvsCortexR52<Types>::ScxEvsCortexR52(
const sc_core::sc_module_name &mod_name, const Params &p) :
Base(mod_name),
params(p),
ext_slave(Base::ext_slave, p.name + ".ext_slave", -1),
top_reset(p.name + ".top_reset", 0)
{
for (int i = 0; i < CoreCount; i++)
corePins.emplace_back(new CorePins(this, i));
for (int i = 0; i < SpiCount; i++) {
spis.emplace_back(
new ClstrInt(csprintf("%s.spi[%d]", name(), i), i, this));
}
top_reset.signal_out.bind(Base::top_reset);
clockRateControl.bind(this->clock_rate_s);
signalInterrupt.bind(this->signal_interrupt);
}
template <class Types>
void
ScxEvsCortexR52<Types>::sendFunc(PacketPtr pkt)
{
auto *trans = sc_gem5::packet2payload(pkt);
panic_if(Base::amba[0]->transport_dbg(*trans) != trans->get_data_length(),
"Didn't send entire functional packet!");
trans->release();
}
template <class Types>
Port &
ScxEvsCortexR52<Types>::gem5_getPort(const std::string &if_name, int idx)
{
if (if_name == "llpp") {
return this->corePins.at(idx)->llpp;
} else if (if_name == "flash") {
return this->corePins.at(idx)->flash;
} else if (if_name == "amba") {
return this->corePins.at(idx)->amba;
} else if (if_name == "core_reset") {
return this->corePins.at(idx)->core_reset;
} else if (if_name == "poweron_reset") {
return this->corePins.at(idx)->poweron_reset;
} else if (if_name == "halt") {
return this->corePins.at(idx)->halt;
} else if (if_name == "ext_slave") {
return this->ext_slave;
} else if (if_name == "top_reset") {
return this->top_reset;
} else if (if_name == "spi") {
return *this->spis.at(idx);
} else if (if_name.substr(0, 3) == "ppi") {
int cpu;
try {
cpu = std::stoi(if_name.substr(4));
} catch (const std::invalid_argument &a) {
panic("Couldn't find CPU number in %s.", if_name);
}
return *this->corePins.at(cpu)->ppis.at(idx);
} else {
return Base::gem5_getPort(if_name, idx);
}
}
template class ScxEvsCortexR52<ScxEvsCortexR52x1Types>;
template class ScxEvsCortexR52<ScxEvsCortexR52x2Types>;
template class ScxEvsCortexR52<ScxEvsCortexR52x3Types>;
template class ScxEvsCortexR52<ScxEvsCortexR52x4Types>;
} // namespace fastmodel
} // namespace gem5