+++ /dev/null
-# Copyright (c) 2012-2014 ARM Limited
-# All rights reserved
-#
-# The license below extends only to copyright in the software and shall
-# not be construed as granting a license to any other intellectual
-# property including but not limited to intellectual property relating
-# to a hardware implementation of the functionality of the software
-# licensed hereunder. You may use the software subject to the license
-# terms below provided that you ensure that this notice is replicated
-# unmodified and in its entirety in all distributions of the software,
-# modified or unmodified, in source code or in binary form.
-#
-# 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: Andrew Bardsley
-
-ARCH = ARM
-VARIANT = opt
-
-SYSTEMC_INC = ./systemc/include
-SYSTEMC_LIB = ./systemc/lib-linux64
-
-CXXFLAGS = -I../../build/$(ARCH) -L../../build/$(ARCH)
-CXXFLAGS += -I$(SYSTEMC_INC) -L$(SYSTEMC_LIB)
-CXXFLAGS += -std=c++0x
-CXXFLAGS += -g
-LIBS = -lgem5_$(VARIANT) -lsystemc
-
-ALL = gem5.$(VARIANT).sc
-
-all: $(ALL)
-
-.cc.o:
- $(CXX) $(CXXFLAGS) -c -o $@ $<
-
-sc_gem5_control.o: sc_gem5_control.cc sc_gem5_control.hh
-sc_logger.o: sc_logger.cc sc_logger.hh
-sc_module.o: sc_module.cc sc_module.hh
-stats.o: stats.cc stats.hh
-main.o: main.cc sc_logger.hh sc_module.hh stats.hh
-
-gem5.$(VARIANT).sc: main.o stats.o \
- sc_gem5_control.o sc_logger.o sc_module.o
- $(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS)
-
-clean:
- $(RM) $(ALL)
- $(RM) *.o
- $(RM) -r m5out
+++ /dev/null
-This directory contains a demo of C++ configuration of gem5. The intention
-is to provide a mechanism to allow pre-generated config.ini files generated
-by Python-based gem5 to be reloaded in library-base versions of gem5
-embedded in other systems using C++ calls for simulation control.
-
-This directory contain a demo of hosting a C++ configured version of gem5
-onto SystemC's event loop. The hosting is achieved by replacing 'simulate'
-with a SystemC object which implements an event loop using SystemC scheduler
-mechanisms.
-
-The sc_... files here should probably be hosted in a diferent directory and
-buildable as a library.
-
-Files:
-
- main.cc -- demonstration top level
- sc_logger.{cc,hh} -- rehosting of DPRINTF onto SC_REPORT
- sc_module.{cc,hh} -- SystemC simulation loop base class
- sc_gem5_control.{cc,hh} -- Alternative extra wrapping to allow gem5
- Systems to be instantiated as single
- sc_module objects.
- stats.{cc,hh} -- Stats dumping (copied from util/cxx_config)
-
-Read main.cc for more details of the implementation and sc_... files for
-
-To build:
-
-First build gem5 as a library with cxx-config support and (optionally)
-without python. Also build a normal gem5 (cxx-config not needed, Python
-needed):
-
-> cd ../..
-> scons build/ARM/gem5.opt
-> scons --with-cxx-config --without-python build/ARM/libgem5_opt.so
-> cd util/systemc
-
-Note: For MAC / OSX this command should be used:
-> scons --with-cxx-config --without-python build/ARM/libgem5_opt.dylib
-
-Set a proper LD_LIBRARY_PATH e.g. for bash:
-> export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/path/to/gem5/build/ARM/"
-
-or for MAC / OSX:
-> export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:/path/to/gem5/build/ARM/"
-
-
-Then edit the Makefile to set the paths for SystemC, e.g:
-
- Linux:
- SYSTEMC_INC = /opt/systemc/include
- SYSTEMC_LIB = /opt/systemc/lib-linux64
-
- MAC / OSX:
- SYSTEMC_INC = /opt/systemc/include
- SYSTEMC_LIB = /opt/systemc/lib-macosx64
-
-Then run make:
-
-> make
-
-Make a config file for the C++-configured gem5 using normal gem5
-
-> ../../build/ARM/gem5.opt ../../configs/example/se.py -c \
-> ../../tests/test-progs/hello/bin/arm/linux/hello
-
-The binary 'gem5.opt.cxx' can now be used to load in the generated config
-file from the previous normal gem5 run.
-
-Try:
-
-> ./gem5.opt.cxx m5out/config.ini
-
-This should print:
-
-> Hello world!
-
-The .ini file can also be read by the Python .ini file reader example:
-
-> ../../build/ARM/gem5.opt ../../configs/example/read_ini.py m5out/config.ini
-
-If you are interested in SystemC Transaction Level Modeling (TLM2) please have
-a look into /util/tlm.
--- /dev/null
+# Copyright (c) 2012-2014 ARM Limited
+# All rights reserved
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder. You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
+# 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: Andrew Bardsley
+
+ARCH = ARM
+VARIANT = opt
+
+SYSTEMC_INC = ./systemc/include
+SYSTEMC_LIB = ./systemc/lib-linux64
+
+CXXFLAGS = -I../../../build/$(ARCH) -L../../../build/$(ARCH)
+CXXFLAGS += -I$(SYSTEMC_INC) -L$(SYSTEMC_LIB)
+CXXFLAGS += -std=c++0x
+CXXFLAGS += -g
+LIBS = -lgem5_$(VARIANT) -lsystemc
+
+ALL = gem5.$(VARIANT).sc
+
+all: $(ALL)
+
+.cc.o:
+ $(CXX) $(CXXFLAGS) -c -o $@ $<
+
+sc_gem5_control.o: sc_gem5_control.cc sc_gem5_control.hh
+sc_logger.o: sc_logger.cc sc_logger.hh
+sc_module.o: sc_module.cc sc_module.hh
+stats.o: stats.cc stats.hh
+main.o: main.cc sc_logger.hh sc_module.hh stats.hh
+
+gem5.$(VARIANT).sc: main.o stats.o \
+ sc_gem5_control.o sc_logger.o sc_module.o
+ $(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS)
+
+clean:
+ $(RM) $(ALL)
+ $(RM) *.o
+ $(RM) -r m5out
--- /dev/null
+This directory contains a demo of C++ configuration of gem5. The intention
+is to provide a mechanism to allow pre-generated config.ini files generated
+by Python-based gem5 to be reloaded in library-base versions of gem5
+embedded in other systems using C++ calls for simulation control.
+
+This directory contain a demo of hosting a C++ configured version of gem5
+onto SystemC's event loop. The hosting is achieved by replacing 'simulate'
+with a SystemC object which implements an event loop using SystemC scheduler
+mechanisms.
+
+The sc_... files here should probably be hosted in a diferent directory and
+buildable as a library.
+
+Files:
+
+ main.cc -- demonstration top level
+ sc_logger.{cc,hh} -- rehosting of DPRINTF onto SC_REPORT
+ sc_module.{cc,hh} -- SystemC simulation loop base class
+ sc_gem5_control.{cc,hh} -- Alternative extra wrapping to allow gem5
+ Systems to be instantiated as single
+ sc_module objects.
+ stats.{cc,hh} -- Stats dumping (copied from util/cxx_config)
+
+Read main.cc for more details of the implementation and sc_... files for
+
+To build:
+
+First build gem5 as a library with cxx-config support and (optionally)
+without python. Also build a normal gem5 (cxx-config not needed, Python
+needed):
+
+> cd ../../..
+> scons build/ARM/gem5.opt
+> scons --with-cxx-config --without-python build/ARM/libgem5_opt.so
+> cd util/systemc
+
+Note: For MAC / OSX this command should be used:
+> scons --with-cxx-config --without-python build/ARM/libgem5_opt.dylib
+
+Set a proper LD_LIBRARY_PATH e.g. for bash:
+> export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/path/to/gem5/build/ARM/"
+
+or for MAC / OSX:
+> export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:/path/to/gem5/build/ARM/"
+
+
+Then edit the Makefile to set the paths for SystemC, e.g:
+
+ Linux:
+ SYSTEMC_INC = /opt/systemc/include
+ SYSTEMC_LIB = /opt/systemc/lib-linux64
+
+ MAC / OSX:
+ SYSTEMC_INC = /opt/systemc/include
+ SYSTEMC_LIB = /opt/systemc/lib-macosx64
+
+Then run make:
+
+> make
+
+Make a config file for the C++-configured gem5 using normal gem5
+
+> ../../../build/ARM/gem5.opt ../../../configs/example/se.py -c \
+> ../../../tests/test-progs/hello/bin/arm/linux/hello
+
+The binary 'gem5.opt.cxx' can now be used to load in the generated config
+file from the previous normal gem5 run.
+
+Try:
+
+> ./gem5.opt.cxx m5out/config.ini
+
+This should print:
+
+> Hello world!
+
+The .ini file can also be read by the Python .ini file reader example:
+
+> ../../../build/ARM/gem5.opt ../../../configs/example/read_ini.py \
+> m5out/config.ini
+
+If you are interested in SystemC Transaction Level Modeling (TLM2) please have
+a look into /util/tlm.
--- /dev/null
+/*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * 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: Andrew Bardsley
+ * Abdul Mutaal Ahmad
+ */
+
+/**
+ * @file
+ *
+ * Example top level file for SystemC integration with C++-only
+ * instantiation.
+ *
+ * Build with something like:
+ *
+ * scons --without-python build/ARM/libgem5_opt.so
+ *
+ * g++ -std=c++0x -Ibuild/ARM -Isrc -DTRACING_ON \
+ * -o gem5cxx.opt -Lbuild/ARM -lgem5_opt \
+ * src/sim/sc_main_cxx.cc src/sim/cxx_stats.cc \
+ * src/sim/sc_module.cc src/sim/sc_logger.cc
+ */
+
+#include <cstdlib>
+#include <iostream>
+#include <sstream>
+#include <systemc>
+
+#include "base/statistics.hh"
+#include "base/str.hh"
+#include "base/trace.hh"
+#include "cpu/base.hh"
+#include "sc_logger.hh"
+#include "sc_module.hh"
+#include "sim/cxx_config_ini.hh"
+#include "sim/cxx_manager.hh"
+#include "sim/init_signals.hh"
+#include "sim/serialize.hh"
+#include "sim/simulate.hh"
+#include "sim/stat_control.hh"
+#include "sim/system.hh"
+#include "stats.hh"
+
+// Defining global string variable decalred in stats.hh
+std::string filename;
+
+void
+usage(const std::string &prog_name)
+{
+ std::cerr << "Usage: " << prog_name << (
+ " <config_file.ini> [ <option> ]\n\n"
+ "OPTIONS:\n"
+ " -p <object> <param> <value> -- set a parameter\n"
+ " -v <object> <param> <values> -- set a vector parameter from"
+ " a comma\n"
+ " separated values string\n"
+ " -d <flag> -- set a debug flag (-<flag>\n"
+ " clear a flag)\n"
+ " -s <dir> <ticks> -- save checkpoint to dir after"
+ " the given\n"
+ " number of ticks\n"
+ " -r <dir> -- restore checkpoint to dir\n"
+ " -c <from> <to> <ticks> -- switch from cpu 'from' to cpu"
+ " 'to' after\n"
+ " the given number of ticks\n"
+ " -n <#cpus> the number of cpus to switch\n"
+ " (appended to 'to' and 'from'"
+ " cpus above)\n"
+ "\n"
+ );
+
+ std::exit(EXIT_FAILURE);
+}
+
+class SimControl : public Gem5SystemC::Module
+{
+ protected:
+ int argc;
+ char **argv;
+ CxxConfigManager *config_manager;
+ Gem5SystemC::Logger logger;
+
+ bool checkpoint_restore;
+ bool checkpoint_save;
+ bool switch_cpus;
+ std::string checkpoint_dir;
+ std::string from_cpu;
+ std::string to_cpu;
+ Tick pre_run_time;
+ Tick pre_switch_time;
+ unsigned num_switch_cpus;
+
+ public:
+ SC_HAS_PROCESS(SimControl);
+
+ SimControl(sc_core::sc_module_name name, int argc_, char **argv_);
+
+ void run();
+ private:
+ /**
+ * Switch a single CPU
+ *
+ * If numTotalCpus is greater than 1, the CPU index will be appended to
+ * the object name when searching config manager for the CPU name
+ *
+ * @param The CPU number to switch
+ * @param The total number of CPUs in the system
+ */
+ void switchCpu(unsigned cpuNum, unsigned numTotalCpus);
+
+};
+
+SimControl::SimControl(sc_core::sc_module_name name,
+ int argc_, char **argv_) :
+ Gem5SystemC::Module(name),
+ argc(argc_),
+ argv(argv_)
+{
+ SC_THREAD(run);
+
+ std::string prog_name(argv[0]);
+ unsigned int arg_ptr = 1;
+
+ if (argc == 1)
+ usage(prog_name);
+
+ cxxConfigInit();
+
+ /* Pass DPRINTF messages to SystemC */
+ Trace::setDebugLogger(&logger);
+
+ /* @todo need this as an option */
+ Gem5SystemC::setTickFrequency();
+
+ /* Make a SystemC-synchronising event queue and install it as the
+ * sole top level gem5 EventQueue */
+ Gem5SystemC::Module::setupEventQueues(*this);
+
+ if (sc_core::sc_get_time_resolution() !=
+ sc_core::sc_time(1, sc_core::SC_PS))
+ {
+ fatal("Time resolution must be set to 1 ps for gem5 to work");
+ }
+
+ /* Enable keyboard interrupt, async I/O etc. */
+ initSignals();
+
+ /* Enable stats */
+ Stats::initSimStats();
+ Stats::registerHandlers(CxxConfig::statsReset, CxxConfig::statsDump);
+
+ Trace::enable();
+ setDebugFlag("Terminal");
+
+ checkpoint_restore = false;
+ checkpoint_save = false;
+ switch_cpus = false;
+ checkpoint_dir = "";
+ from_cpu = "";
+ to_cpu = "";
+ pre_run_time = 1000000;
+ pre_switch_time = 1000000;
+ num_switch_cpus = 1;
+
+ const std::string config_file(argv[arg_ptr]);
+
+ CxxConfigFileBase *conf = new CxxIniFile();
+
+ if (!conf->load(config_file.c_str()))
+ fatal("Can't open config file: %s", config_file);
+
+ arg_ptr++;
+
+ config_manager = new CxxConfigManager(*conf);
+
+ try {
+ while (arg_ptr < argc) {
+ std::string option(argv[arg_ptr]);
+ arg_ptr++;
+ unsigned num_args = argc - arg_ptr;
+
+ if (option == "-p") {
+ if (num_args < 3)
+ usage(prog_name);
+ config_manager->setParam(argv[arg_ptr], argv[arg_ptr + 1],
+ argv[arg_ptr + 2]);
+ arg_ptr += 3;
+ } else if (option == "-v") {
+ std::vector<std::string> values;
+
+ if (num_args < 3)
+ usage(prog_name);
+ tokenize(values, argv[2], ',');
+ config_manager->setParamVector(argv[arg_ptr],
+ argv[arg_ptr], values);
+ arg_ptr += 3;
+ } else if (option == "-d") {
+ if (num_args < 1)
+ usage(prog_name);
+ if (argv[arg_ptr][0] == '-')
+ clearDebugFlag(argv[arg_ptr] + 1);
+ else
+ setDebugFlag(argv[arg_ptr]);
+ arg_ptr++;
+ } else if (option == "-r") {
+ if (num_args < 1)
+ usage(prog_name);
+ checkpoint_dir = argv[arg_ptr];
+ checkpoint_restore = true;
+ arg_ptr++;
+ } else if (option == "-s") {
+ if (num_args < 2)
+ usage(prog_name);
+ checkpoint_dir = argv[arg_ptr];
+ std::istringstream(argv[arg_ptr + 1]) >> pre_run_time;
+ checkpoint_save = true;
+ arg_ptr += 2;
+ } else if (option == "-c") {
+ if (num_args < 3)
+ usage(prog_name);
+ switch_cpus = true;
+ from_cpu = argv[arg_ptr];
+ to_cpu = argv[arg_ptr + 1];
+ std::istringstream(argv[arg_ptr + 2]) >> pre_switch_time;
+ arg_ptr += 3;
+ } else if (option == "-n") {
+ if (num_args < 1)
+ usage(prog_name);
+ std::istringstream(argv[arg_ptr]) >> num_switch_cpus;
+ arg_ptr++;
+ } else {
+ usage(prog_name);
+ }
+ }
+ } catch (CxxConfigManager::Exception &e) {
+ fatal("Config problem in sim object %s: %s", e.name, e.message);
+ }
+
+ if (checkpoint_save && checkpoint_restore) {
+ fatal("Don't try to save and restore a checkpoint in the same"
+ "run");
+ }
+
+ CxxConfig::statsEnable();
+ getEventQueue(0)->dump();
+
+ try {
+ config_manager->instantiate();
+ } catch (CxxConfigManager::Exception &e) {
+ fatal("Config problem in sim object %s: %s", e.name, e.message);
+ }
+}
+
+void SimControl::run()
+{
+ EventQueue *eventq = getEventQueue(0);
+ GlobalSimLoopExitEvent *exit_event = NULL;
+
+ /* There *must* be no scheduled events yet */
+ fatal_if(!eventq->empty(), "There must be no posted events"
+ " before SimControl::run");
+
+ try {
+ if (checkpoint_restore) {
+ std::cerr << "Restoring checkpoint\n";
+
+ CheckpointIn *checkpoint = new CheckpointIn(checkpoint_dir,
+ config_manager->getSimObjectResolver());
+
+ /* Catch SystemC up with gem5 after checkpoint restore.
+ * Note that gem5 leading SystemC is always a violation of the
+ * required relationship between the two, hence this careful
+ * catchup */
+
+ DrainManager::instance().preCheckpointRestore();
+ Serializable::unserializeGlobals(*checkpoint);
+
+ Tick systemc_time = sc_core::sc_time_stamp().value();
+ if (curTick() > systemc_time) {
+ Tick wait_period = curTick() - systemc_time;
+
+ std::cerr << "Waiting for " << wait_period << "ps for"
+ " SystemC to catch up to gem5\n";
+ wait(sc_core::sc_time::from_value(wait_period));
+ }
+
+ config_manager->loadState(*checkpoint);
+ config_manager->startup();
+ config_manager->drainResume();
+
+ std::cerr << "Restored from Checkpoint\n";
+ } else {
+ config_manager->initState();
+ config_manager->startup();
+ }
+ } catch (CxxConfigManager::Exception &e) {
+ fatal("Config problem in sim object %s: %s", e.name, e.message);
+ }
+
+ fatal_if(eventq->empty(), "No events to process after system startup");
+
+ if (checkpoint_save) {
+ exit_event = simulate(pre_run_time);
+
+ unsigned int drain_count = 1;
+ do {
+ drain_count = config_manager->drain();
+
+ std::cerr << "Draining " << drain_count << '\n';
+
+ if (drain_count > 0) {
+ exit_event = simulate();
+ }
+ } while (drain_count > 0);
+
+ std::cerr << "Simulation stop at tick " << curTick()
+ << ", cause: " << exit_event->getCause() << '\n';
+
+ std::cerr << "Checkpointing\n";
+
+ /* FIXME, this should really be serialising just for
+ * config_manager rather than using serializeAll's ugly
+ * SimObject static object list */
+ Serializable::serializeAll(checkpoint_dir);
+
+ std::cerr << "Completed checkpoint\n";
+
+ config_manager->drainResume();
+ }
+
+ if (switch_cpus) {
+ exit_event = simulate(pre_switch_time);
+
+ unsigned int drain_count = 1;
+ do {
+ drain_count = config_manager->drain();
+
+ std::cerr << "Draining " << drain_count << '\n';
+
+ if (drain_count > 0) {
+ exit_event = simulate();
+ }
+ } while (drain_count > 0);
+
+ for (unsigned cpu_num = 0; cpu_num < num_switch_cpus; ++cpu_num) {
+ switchCpu(cpu_num, num_switch_cpus);
+ }
+
+ config_manager->drainResume();
+
+ }
+
+ exit_event = simulate();
+
+ std::cerr << "Exit at tick " << curTick()
+ << ", cause: " << exit_event->getCause() << '\n';
+
+ getEventQueue(0)->dump();
+
+#if TRY_CLEAN_DELETE
+ config_manager->deleteObjects();
+#endif
+}
+
+int
+sc_main(int argc, char **argv)
+{
+ SimControl sim_control("gem5", argc, argv);
+
+ filename = "m5out/stats-systemc.txt";
+
+ sc_core::sc_start();
+
+ CxxConfig::statsDump();
+
+ return EXIT_SUCCESS;
+}
+
+void
+SimControl::switchCpu(unsigned cpuNum, unsigned numTotalCpus) {
+ assert(cpuNum < numTotalCpus);
+ std::ostringstream from_cpu_name;
+ std::ostringstream to_cpu_name;
+
+ from_cpu_name << from_cpu;
+ to_cpu_name << to_cpu;
+
+ if (numTotalCpus > 1) {
+ from_cpu_name << cpuNum;
+ to_cpu_name << cpuNum;
+ }
+
+ std::cerr << "Switching CPU "<< cpuNum << "(from='" << from_cpu_name.str()
+ <<"' to '"<< to_cpu_name.str() << "')\n";
+
+ /* Assume the system is called system */
+ System &system = config_manager->getObject<System>("system");
+ BaseCPU &old_cpu = config_manager->getObject<BaseCPU>(from_cpu_name.str());
+ BaseCPU &new_cpu = config_manager->getObject<BaseCPU>(to_cpu_name.str());
+
+ old_cpu.switchOut();
+
+ // I'm not sure if this can be called before old_cpu.switchOut(). If so,
+ // it is best to just move this call before the switchCpu loop in run()
+ // where it previously was
+ if (cpuNum == 0)
+ system.setMemoryMode(Enums::timing);
+
+ new_cpu.takeOverFrom(&old_cpu);
+
+
+ std::cerr << "Switched CPU"<<cpuNum<<"\n";
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * 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: Andrew Bardsley
+ */
+
+#include <cstdlib>
+#include <iostream>
+#include <list>
+
+#include "base/statistics.hh"
+#include "sc_gem5_control.hh"
+#include "sc_logger.hh"
+#include "sc_module.hh"
+#include "sim/cxx_config_ini.hh"
+#include "sim/cxx_manager.hh"
+#include "sim/debug.hh"
+#include "sim/init_signals.hh"
+#include "sim/stat_control.hh"
+#include "stats.hh"
+
+namespace Gem5SystemC
+{
+
+/** This is the private side of Gem5Control */
+class Gem5TopLevelModule : public Gem5SystemC::Module
+{
+ friend class Gem5Control;
+
+ protected:
+ CxxConfigFileBase *config_file;
+ CxxConfigManager *root_manager;
+ Gem5SystemC::Logger logger;
+
+ /** Things to do at end_of_elaborate */
+ std::list<void (*)()> endOfElaborationFuncs;
+
+ public:
+ SC_HAS_PROCESS(Gem5TopLevelModule);
+
+ Gem5TopLevelModule(sc_core::sc_module_name name,
+ const std::string &config_filename);
+ ~Gem5TopLevelModule();
+
+ /** gem5 simulate. @todo for more interesting simulation control,
+ * this needs to be more complicated */
+ void run();
+
+ /* Register an action to happen at the end of elaboration */
+ void registerEndOfElaboration(void (*func)())
+ {
+ endOfElaborationFuncs.push_back(func);
+ }
+
+ /** SystemC startup */
+ void end_of_elaboration();
+};
+
+Gem5System::Gem5System(CxxConfigManager *manager_,
+ const std::string &system_name, const std::string &instance_name) :
+ manager(manager_),
+ systemName(system_name),
+ instanceName(instance_name)
+{
+ manager->addRenaming(CxxConfigManager::Renaming(
+ system_name, instance_name));
+}
+
+Gem5System::~Gem5System()
+{
+ delete manager;
+}
+
+void
+Gem5System::setParam(const std::string &object,
+ const std::string ¶m_name, const std::string ¶m_value)
+{
+ manager->setParam(systemName + (object != "" ? "." + object : ""),
+ param_name, param_value);
+}
+
+void
+Gem5System::setParamVector(const std::string &object,
+ const std::string ¶m_name,
+ const std::vector<std::string> ¶m_values)
+{
+ manager->setParamVector(systemName +
+ (object != "" ? "." + object : ""), param_name, param_values);
+}
+
+void
+Gem5System::instantiate()
+{
+ try {
+ /* Make a new System */
+ SimObject *obj = manager->findObject(systemName, true);
+
+ /* Add the System's objects to the list of managed
+ * objects for initialisation */
+ manager->findTraversalOrder(systemName);
+
+ /* Bound ports *must* be internal to System */
+ for (auto i = manager->objectsInOrder.begin();
+ i != manager->objectsInOrder.end();
+ ++ i)
+ {
+ manager->bindObjectPorts(*i);
+ }
+
+ /* gem5 startup sequence */
+ manager->instantiate(false);
+ manager->initState();
+ manager->startup();
+ } catch (CxxConfigManager::Exception &e) {
+ fatal("Config problem in Gem5System: %s: %s",
+ e.name, e.message);
+ }
+}
+
+Gem5Control::Gem5Control(const std::string &config_filename)
+{
+ module = new Gem5TopLevelModule("gem5", config_filename);
+}
+
+Gem5Control::~Gem5Control()
+{ }
+
+void
+Gem5Control::registerEndOfElaboration(void (*func)())
+{
+ module->registerEndOfElaboration(func);
+}
+
+void
+Gem5Control::setDebugFlag(const char *flag)
+{
+ ::setDebugFlag(flag);
+}
+
+void
+Gem5Control::clearDebugFlag(const char *flag)
+{
+ ::clearDebugFlag(flag);
+}
+
+void
+Gem5Control::setRemoteGDBPort(unsigned int port)
+{
+ ::setRemoteGDBPort(port);
+}
+
+Gem5System *
+Gem5Control::makeSystem(const std::string &system_name,
+ const std::string &instance_name)
+{
+ Gem5System *ret = new Gem5System(
+ new CxxConfigManager(*(module->config_file)),
+ system_name, instance_name);
+
+ return ret;
+}
+
+const std::string &
+Gem5Control::getVersion() const
+{
+ return version;
+}
+
+void
+Gem5Control::setVersion(const std::string &new_version)
+{
+ if (version != "")
+ fatal("Gem5Control::setVersion called for a second time");
+
+ version = new_version;
+}
+
+Gem5TopLevelModule::Gem5TopLevelModule(sc_core::sc_module_name name,
+ const std::string &config_filename) :
+ Gem5SystemC::Module(name),
+ config_file(NULL),
+ root_manager(NULL)
+{
+ SC_THREAD(run);
+
+ cxxConfigInit();
+
+ /* Pass DPRINTF messages to SystemC */
+ Trace::setDebugLogger(&logger);
+
+ /* @todo need this as an option */
+ Gem5SystemC::setTickFrequency();
+
+ /* Make a SystemC-synchronising event queue and install it as the
+ * sole top level gem5 EventQueue */
+ Gem5SystemC::Module::setupEventQueues(*this);
+
+ if (sc_core::sc_get_time_resolution() !=
+ sc_core::sc_time(1, sc_core::SC_PS))
+ {
+ fatal("Time resolution must be set to 1 ps for gem5 to work");
+ }
+
+ /* Enable keyboard interrupt, async I/O etc. */
+ initSignals();
+
+ /* Enable stats */
+ Stats::initSimStats();
+ Stats::registerHandlers(CxxConfig::statsReset, CxxConfig::statsDump);
+
+ Trace::enable();
+
+ config_file = new CxxIniFile();
+
+ if (!config_file->load(config_filename)) {
+ fatal("Gem5TopLevelModule: Can't open config file: %s",
+ config_filename);
+ }
+
+ root_manager = new CxxConfigManager(*config_file);
+
+ CxxConfig::statsEnable();
+
+ /* Make the root object */
+ try {
+ SimObject *root = root_manager->findObject("root", false);
+
+ /* Make sure we don't traverse into root's children */
+ root_manager->objectsInOrder.push_back(root);
+
+ root_manager->instantiate(false);
+ root_manager->initState();
+ root_manager->startup();
+ } catch (CxxConfigManager::Exception &e) {
+ fatal("Config problem in Gem5TopLevelModule: %s: %s",
+ e.name, e.message);
+ }
+}
+
+Gem5TopLevelModule::~Gem5TopLevelModule()
+{
+ delete config_file;
+ delete root_manager;
+}
+
+void
+Gem5TopLevelModule::run()
+{
+ GlobalSimLoopExitEvent *exit_event = NULL;
+
+ exit_event = simulate();
+
+ std::cerr << "Exit at tick " << curTick()
+ << ", cause: " << exit_event->getCause() << '\n';
+
+ getEventQueue(0)->dump();
+}
+
+void
+Gem5TopLevelModule::end_of_elaboration()
+{
+ for (auto i = endOfElaborationFuncs.begin();
+ i != endOfElaborationFuncs.end(); ++i)
+ {
+ (*i)();
+ }
+}
+
+}
+
+Gem5SystemC::Gem5Control *
+makeGem5Control(const std::string &config_filename)
+{
+ return new Gem5SystemC::Gem5Control(config_filename);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * 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: Andrew Bardsley
+ */
+
+/**
+ * @file
+ *
+ * Top level definitions for exporting gem5 across a dlopen interface.
+ *
+ * Gem5Control should be instantiated once to build the gem5 root.
+ * Systems from that root's config file can then be instantiated as
+ * Gem5System's using Gem5Control::makeSystem.
+ *
+ * Gem5Control contains a Gem5TopLevelModule which is a SystemC
+ * module providing the gem5 `simulate' function as its sole
+ * thread action.
+ */
+
+#ifndef __SIM_SC_GEM5_CONTROL_HH__
+#define __SIM_SC_GEM5_CONTROL_HH__
+
+#include <string>
+#include <vector>
+
+class CxxConfigManager;
+
+namespace Gem5SystemC
+{
+
+class Gem5TopLevelModule;
+class Gem5Control;
+
+/** Gem5System's wrap CxxConfigManager's instantiating a gem5 System
+ * object (and its children). New Gem5Systems are created by
+ * Gem5Control::makeSystem. A new system can have its parameters
+ * tweaked using setParam{,Vector} before being instantiated using
+ * Gem5System::instantiate. After instantiation, any external ports
+ * declared by the system should be visible in SystemC.
+ *
+ * It is recommended that a SystemC wrapper sc_module is declared to
+ * own each Gem5System with the call to Gem5System::instantiate being
+ * made in that wrapper's constructor
+ *
+ * Note that *every* `normal' member function in this class *must*
+ * be virtual to ensure that references to the functions go through
+ * the pointer acquired using makeSystem and not looked up as
+ * name-mangled symbols
+ *
+ * */
+class Gem5System
+{
+ private:
+ /** Config management for *just* this system's objects (notably
+ * excluding root */
+ CxxConfigManager *manager;
+
+ /** The config file prototype for the system */
+ std::string systemName;
+
+ /** The instantiated (in gem5) name of the system */
+ std::string instanceName;
+
+ public:
+ /** A constructor only used by Gem5Control */
+ Gem5System(CxxConfigManager *manager_,
+ const std::string &system_name, const std::string &instance_name);
+
+ virtual ~Gem5System();
+
+ /** Parameter setting functions callable before instantiate */
+ virtual void setParam(const std::string &object,
+ const std::string ¶m_name, const std::string ¶m_value);
+
+ virtual void setParamVector(const std::string &system_name,
+ const std::string ¶m_name,
+ const std::vector<std::string> ¶m_values);
+
+ /** Build the system's gem5 infrastructure, bind its ports (note
+ * that all ports *must* be internal to the system), init and
+ * SimObject::startup the system */
+ virtual void instantiate();
+};
+
+/** Singleton class containing gem5 simulation control.
+ *
+ * Note that *every* `normal' member function in this class *must*
+ * be virtual to ensure that references to the functions go through
+ * the pointer acquired using makeGem5Control and not looked up as
+ * name-mangled symbols
+ */
+class Gem5Control
+{
+ private:
+ /** Private SystemC module containing top level simulation control */
+ Gem5TopLevelModule *module;
+
+ /** One-time-settable version string */
+ std::string version;
+
+ public:
+ Gem5Control(const std::string &config_filename);
+
+ virtual ~Gem5Control();
+
+ /** Set/clear a gem5 debug flag */
+ virtual void setDebugFlag(const char *flag);
+ virtual void clearDebugFlag(const char *flag);
+
+ /** Choose a base port number for GDB to connect to the model
+ * (0 disables connections) */
+ virtual void setRemoteGDBPort(unsigned int port);
+
+ /* Register an action to happen at the end of elaboration */
+ virtual void registerEndOfElaboration(void (*func)());
+
+ /** Make a System from the config file description for system
+ * system_name and call it instance_name in gem5 */
+ virtual Gem5System *makeSystem(const std::string &system_name,
+ const std::string &top_instance);
+
+ /** set/get version string */
+ virtual const std::string &getVersion() const;
+ virtual void setVersion(const std::string &new_version);
+};
+
+}
+
+/** Instantiate a Gem5Control. This can be called using dlopen/dlsym
+ * to kick-start gem5 */
+extern "C" Gem5SystemC::Gem5Control *makeGem5Control(
+ const std::string &config_filename);
+
+#endif // __SIM_SC_GEM5_CONTROL_HH__
--- /dev/null
+/*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * 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: Andrew Bardsley
+ */
+
+/**
+ * @file
+ *
+ * A logger to allow SystemC to capture DPRINTF messages (and similar things)
+ * using sc_report
+ */
+
+#include <cstdlib>
+#include <cstring>
+#include <sstream>
+
+#include "sc_logger.hh"
+
+namespace Gem5SystemC
+{
+
+/** Class to act as a streambuf for std::ostream which cuts output strings
+ * into lines and offers them to a logger */
+class CuttingStreambuf : public std::streambuf
+{
+ public:
+ /** Accumulate line so far */
+ std::ostringstream line;
+
+ /** Logger to send complete lines to */
+ Trace::Logger *logger;
+
+ CuttingStreambuf(Trace::Logger *logger_) : logger(logger_)
+ { }
+
+ /** Accumulate to line up to \n and then emit */
+ int overflow(int i);
+ int sync();
+
+ /** Push a line out to the logger */
+ void outputLine();
+
+ ~CuttingStreambuf();
+};
+
+void CuttingStreambuf::outputLine()
+{
+ logger->logMessage((Tick)-1, "gem5", line.str());
+ line.clear();
+ line.str("");
+}
+
+/** This is pretty much the least efficient way of doing this, but it has the
+ * advantage of having very few corners to get wrong.
+ *
+ * A newly allocated streambuf will have no buffer to serve to its
+ * [oi]stream. It will, therefore, call overflow for every character it
+ * wants to insert into the output stream. Those characters are captured one
+ * by one here and added to this->line. */
+int
+CuttingStreambuf::overflow(int chr)
+{
+ if (chr == '\n')
+ outputLine();
+ else if (chr != EOF)
+ line << (char) chr;
+
+ /* Always succeeds */
+ return 0;
+}
+
+int
+CuttingStreambuf::sync()
+{
+ if (!line.str().empty())
+ outputLine();
+
+ /* Always succeeds */
+ return 0;
+}
+
+CuttingStreambuf::~CuttingStreambuf()
+{
+ sync();
+}
+
+Logger::Logger() :
+ cuttingStreambuf(new CuttingStreambuf(this)),
+ stream(cuttingStreambuf)
+{
+}
+
+Logger::~Logger()
+{
+ stream.flush();
+ delete cuttingStreambuf;
+}
+
+/** Log a single message as a single sc_report call */
+void
+Logger::logMessage(Tick when, const std::string &name,
+ const std::string &message)
+{
+ /* Need to chop the newline off the message */
+ std::string message_without_nl = message;
+ message_without_nl.erase(
+ message_without_nl.find_last_not_of(" \n\r") + 1);
+
+ SC_REPORT_INFO(name.c_str(), message_without_nl.c_str());
+}
+
+std::ostream &
+Logger::getOstream()
+{
+ return stream;
+}
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * 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: Andrew Bardsley
+ */
+
+/**
+ * @file
+ *
+ * A logger to allow SystemC to capture DPRINTF messages (and similar things)
+ * using sc_report
+ */
+
+#ifndef __SIM_SC_LOGGER_H__
+#define __SIM_SC_LOGGER_H__
+
+#include <systemc>
+
+#include "base/trace.hh"
+
+namespace Gem5SystemC
+{
+
+/** sc_report logging class */
+class Logger : public Trace::Logger
+{
+ protected:
+ /** Stream to offer getOstream. This will cut messages up newlines and
+ * offer them to logMessage */
+ std::streambuf *cuttingStreambuf;
+ std::ostream stream;
+
+ public:
+ Logger();
+
+ ~Logger();
+
+ /** Log a single message as a single sc_report call */
+ void logMessage(Tick when, const std::string &name,
+ const std::string &message);
+
+ std::ostream &getOstream();
+};
+
+}
+
+#endif // __SIM_SC_LOGGER_H__
--- /dev/null
+/*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
+ * Copyright (c) 2013 Mark D. Hill and David A. Wood
+ * All rights reserved.
+ *
+ * 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: Nathan Binkert
+ * Steve Reinhardt
+ * Andrew Bardsley
+ * Matthias Jung
+ * Christian Menard
+ */
+
+/**
+ * @file
+ *
+ * Defines an sc_module type to wrap a gem5 simulation. The 'evaluate'
+ * thread on that module implements the gem5 event loop.
+ *
+ * This currently only supports a single event queue and strictly
+ * cooperatively threaded SystemC threads and so there should be at
+ * most one Gem5Module instantiated in any simulation.
+ */
+
+#include "base/logging.hh"
+#include "base/pollevent.hh"
+#include "base/trace.hh"
+#include "debug/Event.hh"
+#include "sc_module.hh"
+#include "sim/async.hh"
+#include "sim/core.hh"
+#include "sim/eventq.hh"
+#include "sim/sim_exit.hh"
+#include "sim/stat_control.hh"
+
+namespace Gem5SystemC
+{
+
+/** There are assumptions throughout Gem5SystemC file that a tick is 1ps.
+ * Make this the case */
+void
+setTickFrequency()
+{
+ ::setClockFrequency(1000000000000);
+}
+
+Module::Module(sc_core::sc_module_name name) : sc_core::sc_channel(name),
+ in_simulate(false)
+{
+ SC_METHOD(eventLoop);
+ sensitive << eventLoopEnterEvent;
+ dont_initialize();
+
+ SC_METHOD(serviceExternalEvent);
+ sensitive << externalSchedulingEvent;
+ dont_initialize();
+}
+
+void
+Module::SCEventQueue::wakeup(Tick when)
+{
+ DPRINTF(Event, "waking up SCEventQueue\n");
+ /* Don't bother to use 'when' for now */
+ module.notify();
+}
+
+void
+Module::setupEventQueues(Module &module)
+{
+ fatal_if(mainEventQueue.size() != 0,
+ "Gem5SystemC::Module::setupEventQueues must be called"
+ " before any gem5 event queues are set up");
+
+ numMainEventQueues = 1;
+ mainEventQueue.push_back(new SCEventQueue("events", module));
+ curEventQueue(getEventQueue(0));
+}
+
+void
+Module::catchup()
+{
+ EventQueue *eventq = getEventQueue(0);
+ Tick systemc_time = sc_core::sc_time_stamp().value();
+ Tick gem5_time = curTick();
+
+ /* gem5 time *must* lag SystemC as SystemC is the master */
+ fatal_if(gem5_time > systemc_time, "gem5 time must lag SystemC time"
+ " gem5: %d SystemC: %d", gem5_time, systemc_time);
+
+ eventq->setCurTick(systemc_time);
+
+ if (!eventq->empty()) {
+ Tick next_event_time M5_VAR_USED = eventq->nextTick();
+
+ fatal_if(gem5_time > next_event_time,
+ "Missed an event at time %d gem5: %d, SystemC: %d",
+ next_event_time, gem5_time, systemc_time);
+ }
+}
+
+void
+Module::notify(sc_core::sc_time time_from_now)
+{
+ externalSchedulingEvent.notify(time_from_now);
+}
+
+void
+Module::serviceAsyncEvent()
+{
+ EventQueue *eventq = getEventQueue(0);
+ std::lock_guard<EventQueue> lock(*eventq);
+
+ assert(async_event);
+
+ /* Catch up gem5 time with SystemC time so that any event here won't
+ * be in the past relative to the current time */
+ Tick systemc_time = sc_core::sc_time_stamp().value();
+
+ /* Move time on to match SystemC */
+ catchup();
+
+ async_event = false;
+ if (async_statdump || async_statreset) {
+ Stats::schedStatEvent(async_statdump, async_statreset);
+ async_statdump = false;
+ async_statreset = false;
+ }
+
+ if (async_exit) {
+ async_exit = false;
+ exitSimLoop("user interrupt received");
+ }
+
+ if (async_io) {
+ async_io = false;
+ pollQueue.service();
+ }
+
+ if (async_exception)
+ fatal("received async_exception, shouldn't be possible");
+}
+
+void
+Module::serviceExternalEvent()
+{
+ EventQueue *eventq = getEventQueue(0);
+
+ if (!in_simulate && !async_event)
+ warn("Gem5SystemC external event received while not in simulate");
+
+ if (async_event)
+ serviceAsyncEvent();
+
+ if (in_simulate && !eventq->empty())
+ eventLoop();
+}
+
+void
+Module::eventLoop()
+{
+ EventQueue *eventq = getEventQueue(0);
+
+ fatal_if(!in_simulate, "Gem5SystemC event loop entered while"
+ " outside Gem5SystemC::Module::simulate");
+
+ if (async_event)
+ serviceAsyncEvent();
+
+ while (!eventq->empty()) {
+ Tick next_event_time = eventq->nextTick();
+
+ /* Move time on to match SystemC */
+ catchup();
+
+ Tick gem5_time = curTick();
+
+ /* Woken up early */
+ if (wait_exit_time > sc_core::sc_time_stamp().value()) {
+ DPRINTF(Event, "Woken up early\n");
+ wait_exit_time = sc_core::sc_time_stamp().value();
+ }
+
+ if (gem5_time < next_event_time) {
+ Tick wait_period = next_event_time - gem5_time;
+ wait_exit_time = gem5_time + wait_period;
+
+ DPRINTF(Event, "Waiting for %d ticks for next gem5 event\n",
+ wait_period);
+
+ /* The next event is scheduled in the future, wait until
+ * then or until externalSchedulingEvent */
+ eventLoopEnterEvent.notify(sc_core::sc_time::from_value(
+ sc_dt::uint64(wait_period)));
+
+ return;
+ } else if (gem5_time > next_event_time) {
+ Tick systemc_time = sc_core::sc_time_stamp().value();
+
+ /* Missed event, for some reason the above test didn't work
+ * or an event was scheduled in the past */
+ fatal("Missed an event at time %d gem5: %d, SystemC: %d",
+ next_event_time, gem5_time, systemc_time);
+ } else {
+ /* Service an event */
+ exitEvent = eventq->serviceOne();
+
+ if (exitEvent) {
+ eventLoopExitEvent.notify(sc_core::SC_ZERO_TIME);
+ return;
+ }
+ }
+ }
+
+ fatal("Ran out of events without seeing exit event");
+}
+
+GlobalSimLoopExitEvent *
+Module::simulate(Tick num_cycles)
+{
+ inform("Entering event queue @ %d. Starting simulation...", curTick());
+
+ if (num_cycles < MaxTick - curTick())
+ num_cycles = curTick() + num_cycles;
+ else /* counter would roll over or be set to MaxTick anyhow */
+ num_cycles = MaxTick;
+
+ GlobalEvent *limit_event = new GlobalSimLoopExitEvent(num_cycles,
+ "simulate() limit reached", 0, 0);
+
+ exitEvent = NULL;
+
+ /* Cancel any outstanding events */
+ eventLoopExitEvent.cancel();
+ externalSchedulingEvent.cancel();
+
+ in_simulate = true;
+ eventLoopEnterEvent.notify(sc_core::SC_ZERO_TIME);
+
+ /* Wait for event queue to exit, guarded by exitEvent just incase
+ * it already has exited and we don't want to completely rely
+ * on notify semantics */
+ if (!exitEvent)
+ wait(eventLoopExitEvent);
+
+ /* Cancel any outstanding event loop entries */
+ eventLoopEnterEvent.cancel();
+ in_simulate = false;
+
+ /* Locate the global exit event */
+ BaseGlobalEvent *global_event = exitEvent->globalEvent();
+ assert(global_event != NULL);
+
+ GlobalSimLoopExitEvent *global_exit_event =
+ dynamic_cast<GlobalSimLoopExitEvent *>(global_event);
+ assert(global_exit_event != NULL);
+
+ if (global_exit_event != limit_event) {
+ limit_event->deschedule();
+ delete limit_event;
+ }
+
+ return global_exit_event;
+}
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
+ * Copyright (c) 2013 Mark D. Hill and David A. Wood
+ * All rights reserved.
+ *
+ * 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: Nathan Binkert
+ * Steve Reinhardt
+ * Andrew Bardsley
+ * Christian Menard
+ */
+
+/**
+ * @file
+ *
+ * Defines an sc_module type to wrap a gem5 simulation. The 'evaluate'
+ * thread on that module implements the gem5 event loop.
+ *
+ * This currently only supports a single event queue and strictly
+ * cooperatively threaded SystemC threads and so there should be at
+ * most one Gem5Module instantiated in any simulation.
+ */
+
+#ifndef __SIM_SC_MODULE_HH__
+#define __SIM_SC_MODULE_HH__
+
+#include <systemc>
+
+#include "sim/eventq.hh"
+#include "sim/sim_events.hh"
+
+namespace Gem5SystemC
+{
+
+/** A SystemC module implementing the gem5 event queue. This object
+ * doesn't actually own any of the simulation SimObjects (those need
+ * to be administered separately) but it does control the event
+ * queue.
+ *
+ * The event loop here services gem5 events in order at the current time
+ * and then yielding to another SystemC thread. gem5 events are not
+ * individually scheduled in SystemC. For this reason, asynchronous events
+ * and function interaction (for example TLM) with gem5 from SystemC must
+ * notify the module so that the yielding 'wait' can be interrupted.
+ * From the point of view of another SystemC module calling into gem5,
+ * curTick can lag SystemC time, be exactly the same time but *never*
+ * lead SystemC time.
+ *
+ * This functionality is wrapped in an sc_module as its intended that
+ * the a class representing top level simulation control should be derived
+ * from this class. */
+class Module : public sc_core::sc_channel
+{
+ protected:
+ /** Event to trigger (via. ::notify) for event scheduling from
+ * outside gem5 */
+ sc_core::sc_event externalSchedulingEvent;
+
+ /** Event to trigger on exit of eventLoop */
+ sc_core::sc_event eventLoopExitEvent;
+
+ /** Event to trigger to enter eventLoop */
+ sc_core::sc_event eventLoopEnterEvent;
+
+ /** Expected exit time of last eventLoop sleep */
+ Tick wait_exit_time;
+
+ /** Are we in Module::simulate? Used to mask events when not inside
+ * the simulate loop */
+ bool in_simulate;
+
+ /** Placeholder base class for a variant event queue if this becomes
+ * useful */
+ class SCEventQueue : public EventQueue
+ {
+ protected:
+ Module &module;
+
+ public:
+ SCEventQueue(const std::string &name,
+ Module &module_) : EventQueue(name), module(module_)
+ { }
+
+ /** Signal module to wakeup */
+ void wakeup(Tick when);
+ };
+
+ /** Service any async event marked up in the globals event_... */
+ void serviceAsyncEvent();
+
+ public:
+ /** Simulate is a process */
+ SC_HAS_PROCESS(Module);
+
+ Module(sc_core::sc_module_name name);
+
+ /** Last exitEvent from eventLoop */
+ Event *exitEvent;
+
+ /** Setup global event queues. Call this before any other event queues
+ * are created */
+ static void setupEventQueues(Module &module);
+
+ /** Catch gem5 time up with SystemC */
+ void catchup();
+
+ /** Notify an externalSchedulingEvent at the given time from the
+ * current SystemC time */
+ void notify(sc_core::sc_time time_from_now = sc_core::SC_ZERO_TIME);
+
+ /** Process an event triggered by externalSchedulingEvent and also
+ * call eventLoop (to try and mop up any events at this time) if there
+ * are any scheduled events */
+ void serviceExternalEvent();
+
+ /** Process gem5 events up until an exit event or there are no events
+ * left. */
+ void eventLoop();
+
+ /** Run eventLoop up to num_cycles and return the final event */
+ GlobalSimLoopExitEvent *simulate(Tick num_cycles = MaxTick);
+};
+
+/** There are assumptions throughout Gem5SystemC file that a tick is 1ps.
+ * Make this the case */
+void setTickFrequency();
+
+}
+
+#endif // __SIM_SC_MODULE_HH__
--- /dev/null
+/*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * 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: Andrew Bardsley
+ * Matthias Jung
+ * Abdul Mutaal Ahmad
+ */
+
+/**
+ * @file
+ *
+ * C++-only configuration stats handling example
+ *
+ * Register with: Stats::registerHandlers(statsReset, statsDump)
+ */
+
+#include "base/output.hh"
+#include "base/statistics.hh"
+#include "base/stats/text.hh"
+#include "stats.hh"
+
+namespace CxxConfig
+{
+
+void statsPrepare()
+{
+ std::list<Stats::Info *> stats = Stats::statsList();
+
+ /* gather_stats -> prepare */
+ for (auto i = stats.begin(); i != stats.end(); ++i){
+ Stats::Info *stat = *i;
+ Stats::VectorInfo *vector = dynamic_cast<Stats::VectorInfo *>(stat);
+ if (vector){
+ (dynamic_cast<Stats::VectorInfo *>(*i))->prepare();
+ }
+ else {
+ (*i)->prepare();
+ }
+
+ }
+}
+
+void statsDump()
+{
+ bool desc = true;
+ Stats::Output *output = Stats::initText(filename, desc);
+
+ Stats::processDumpQueue();
+
+ std::list<Stats::Info *> stats = Stats::statsList();
+
+ statsEnable();
+ statsPrepare();
+
+ output->begin();
+ /* gather_stats -> convert_value */
+ for (auto i = stats.begin(); i != stats.end(); ++i) {
+ Stats::Info *stat = *i;
+
+ const Stats::ScalarInfo *scalar = dynamic_cast<Stats::ScalarInfo
+ *>(stat);
+ Stats::VectorInfo *vector = dynamic_cast<Stats::VectorInfo *>(stat);
+ const Stats::Vector2dInfo *vector2d = dynamic_cast<Stats::Vector2dInfo
+ *>(vector);
+ const Stats::DistInfo *dist = dynamic_cast<Stats::DistInfo *>(stat);
+ const Stats::VectorDistInfo *vectordist =
+ dynamic_cast<Stats::VectorDistInfo *>(stat);
+ const Stats::SparseHistInfo *sparse =
+ dynamic_cast<Stats::SparseHistInfo *>(stat);
+ const Stats::InfoProxy <Stats::Vector2d,Stats::Vector2dInfo> *info =
+ dynamic_cast<Stats::InfoProxy
+ <Stats::Vector2d,Stats::Vector2dInfo>*>(stat);
+
+ if (vector) {
+ const Stats::FormulaInfo *formula = dynamic_cast<Stats::FormulaInfo
+ *>(vector);
+ if (formula){
+ output->visit(*formula);
+ } else {
+ const Stats::VectorInfo *vector1 = vector;
+ output->visit(*vector1);
+ }
+ } else if (vector2d) {
+ output->visit(*vector2d);
+ } else if (info){
+ output->visit(*info);
+ } else if (vectordist){
+ output->visit(*vectordist);
+ } else if (dist) {
+ output->visit(*dist);
+ } else if (sparse) {
+ output->visit(*sparse);
+ } else if (scalar) {
+ output->visit(*scalar);
+ } else {
+ warn("Stat not dumped: %s\n", stat->name);
+ }
+ }
+ output->end();
+}
+
+void statsReset()
+{
+ std::cerr << "Stats reset\n";
+
+ Stats::processResetQueue();
+}
+
+void statsEnable()
+{
+ std::list<Stats::Info *> stats = Stats::statsList();
+
+ for (auto i = stats.begin(); i != stats.end(); ++i){
+ Stats::Info *stat = *i;
+ Stats::VectorInfo *vector = dynamic_cast<Stats::VectorInfo *>(stat);
+ if (vector){
+ (dynamic_cast<Stats::VectorInfo *>(*i))->enable();
+ }
+ else {
+ (*i)->enable();
+ }
+
+ }
+}
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * 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: Andrew Bardsley
+ * Matthias Jung
+ * Abdul Mutaal Ahmad
+ */
+
+/**
+ * @file
+ *
+ * C++-only configuration stats handling example
+ *
+ * Register with: Stats::registerHandlers(statsReset, statsDump)
+ */
+
+#ifndef __UTIL_CXX_CONFIG_STATS_H__
+#define __UTIL_CXX_CONFIG_STATS_H__
+
+extern std::string filename;
+
+namespace CxxConfig
+{
+
+void statsDump();
+void statsReset();
+void statsEnable();
+void statsPrepare();
+
+}
+
+#endif // __UTIL_CXX_CONFIG_STATS_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 ARM Limited
- * All rights reserved
- *
- * The license below extends only to copyright in the software and shall
- * not be construed as granting a license to any other intellectual
- * property including but not limited to intellectual property relating
- * to a hardware implementation of the functionality of the software
- * licensed hereunder. You may use the software subject to the license
- * terms below provided that you ensure that this notice is replicated
- * unmodified and in its entirety in all distributions of the software,
- * modified or unmodified, in source code or in binary form.
- *
- * 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: Andrew Bardsley
- * Abdul Mutaal Ahmad
- */
-
-/**
- * @file
- *
- * Example top level file for SystemC integration with C++-only
- * instantiation.
- *
- * Build with something like:
- *
- * scons --without-python build/ARM/libgem5_opt.so
- *
- * g++ -std=c++0x -Ibuild/ARM -Isrc -DTRACING_ON \
- * -o gem5cxx.opt -Lbuild/ARM -lgem5_opt \
- * src/sim/sc_main_cxx.cc src/sim/cxx_stats.cc \
- * src/sim/sc_module.cc src/sim/sc_logger.cc
- */
-
-#include <cstdlib>
-#include <iostream>
-#include <sstream>
-#include <systemc>
-
-#include "base/statistics.hh"
-#include "base/str.hh"
-#include "base/trace.hh"
-#include "cpu/base.hh"
-#include "sim/cxx_config_ini.hh"
-#include "sim/cxx_manager.hh"
-#include "sim/init_signals.hh"
-#include "sim/serialize.hh"
-#include "sim/simulate.hh"
-#include "sim/stat_control.hh"
-#include "sim/system.hh"
-#include "sc_logger.hh"
-#include "sc_module.hh"
-#include "stats.hh"
-
-// Defining global string variable decalred in stats.hh
-std::string filename;
-
-void
-usage(const std::string &prog_name)
-{
- std::cerr << "Usage: " << prog_name << (
- " <config_file.ini> [ <option> ]\n\n"
- "OPTIONS:\n"
- " -p <object> <param> <value> -- set a parameter\n"
- " -v <object> <param> <values> -- set a vector parameter from"
- " a comma\n"
- " separated values string\n"
- " -d <flag> -- set a debug flag (-<flag>\n"
- " clear a flag)\n"
- " -s <dir> <ticks> -- save checkpoint to dir after"
- " the given\n"
- " number of ticks\n"
- " -r <dir> -- restore checkpoint to dir\n"
- " -c <from> <to> <ticks> -- switch from cpu 'from' to cpu"
- " 'to' after\n"
- " the given number of ticks\n"
- " -n <#cpus> the number of cpus to switch\n"
- " (appended to 'to' and 'from'"
- " cpus above)\n"
- "\n"
- );
-
- std::exit(EXIT_FAILURE);
-}
-
-class SimControl : public Gem5SystemC::Module
-{
- protected:
- int argc;
- char **argv;
- CxxConfigManager *config_manager;
- Gem5SystemC::Logger logger;
-
- bool checkpoint_restore;
- bool checkpoint_save;
- bool switch_cpus;
- std::string checkpoint_dir;
- std::string from_cpu;
- std::string to_cpu;
- Tick pre_run_time;
- Tick pre_switch_time;
- unsigned num_switch_cpus;
-
- public:
- SC_HAS_PROCESS(SimControl);
-
- SimControl(sc_core::sc_module_name name, int argc_, char **argv_);
-
- void run();
- private:
- /**
- * Switch a single CPU
- *
- * If numTotalCpus is greater than 1, the CPU index will be appended to
- * the object name when searching config manager for the CPU name
- *
- * @param The CPU number to switch
- * @param The total number of CPUs in the system
- */
- void switchCpu(unsigned cpuNum, unsigned numTotalCpus);
-
-};
-
-SimControl::SimControl(sc_core::sc_module_name name,
- int argc_, char **argv_) :
- Gem5SystemC::Module(name),
- argc(argc_),
- argv(argv_)
-{
- SC_THREAD(run);
-
- std::string prog_name(argv[0]);
- unsigned int arg_ptr = 1;
-
- if (argc == 1)
- usage(prog_name);
-
- cxxConfigInit();
-
- /* Pass DPRINTF messages to SystemC */
- Trace::setDebugLogger(&logger);
-
- /* @todo need this as an option */
- Gem5SystemC::setTickFrequency();
-
- /* Make a SystemC-synchronising event queue and install it as the
- * sole top level gem5 EventQueue */
- Gem5SystemC::Module::setupEventQueues(*this);
-
- if (sc_core::sc_get_time_resolution() !=
- sc_core::sc_time(1, sc_core::SC_PS))
- {
- fatal("Time resolution must be set to 1 ps for gem5 to work");
- }
-
- /* Enable keyboard interrupt, async I/O etc. */
- initSignals();
-
- /* Enable stats */
- Stats::initSimStats();
- Stats::registerHandlers(CxxConfig::statsReset, CxxConfig::statsDump);
-
- Trace::enable();
- setDebugFlag("Terminal");
-
- checkpoint_restore = false;
- checkpoint_save = false;
- switch_cpus = false;
- checkpoint_dir = "";
- from_cpu = "";
- to_cpu = "";
- pre_run_time = 1000000;
- pre_switch_time = 1000000;
- num_switch_cpus = 1;
-
- const std::string config_file(argv[arg_ptr]);
-
- CxxConfigFileBase *conf = new CxxIniFile();
-
- if (!conf->load(config_file.c_str()))
- fatal("Can't open config file: %s", config_file);
-
- arg_ptr++;
-
- config_manager = new CxxConfigManager(*conf);
-
- try {
- while (arg_ptr < argc) {
- std::string option(argv[arg_ptr]);
- arg_ptr++;
- unsigned num_args = argc - arg_ptr;
-
- if (option == "-p") {
- if (num_args < 3)
- usage(prog_name);
- config_manager->setParam(argv[arg_ptr], argv[arg_ptr + 1],
- argv[arg_ptr + 2]);
- arg_ptr += 3;
- } else if (option == "-v") {
- std::vector<std::string> values;
-
- if (num_args < 3)
- usage(prog_name);
- tokenize(values, argv[2], ',');
- config_manager->setParamVector(argv[arg_ptr],
- argv[arg_ptr], values);
- arg_ptr += 3;
- } else if (option == "-d") {
- if (num_args < 1)
- usage(prog_name);
- if (argv[arg_ptr][0] == '-')
- clearDebugFlag(argv[arg_ptr] + 1);
- else
- setDebugFlag(argv[arg_ptr]);
- arg_ptr++;
- } else if (option == "-r") {
- if (num_args < 1)
- usage(prog_name);
- checkpoint_dir = argv[arg_ptr];
- checkpoint_restore = true;
- arg_ptr++;
- } else if (option == "-s") {
- if (num_args < 2)
- usage(prog_name);
- checkpoint_dir = argv[arg_ptr];
- std::istringstream(argv[arg_ptr + 1]) >> pre_run_time;
- checkpoint_save = true;
- arg_ptr += 2;
- } else if (option == "-c") {
- if (num_args < 3)
- usage(prog_name);
- switch_cpus = true;
- from_cpu = argv[arg_ptr];
- to_cpu = argv[arg_ptr + 1];
- std::istringstream(argv[arg_ptr + 2]) >> pre_switch_time;
- arg_ptr += 3;
- } else if (option == "-n") {
- if (num_args < 1)
- usage(prog_name);
- std::istringstream(argv[arg_ptr]) >> num_switch_cpus;
- arg_ptr++;
- } else {
- usage(prog_name);
- }
- }
- } catch (CxxConfigManager::Exception &e) {
- fatal("Config problem in sim object %s: %s", e.name, e.message);
- }
-
- if (checkpoint_save && checkpoint_restore) {
- fatal("Don't try to save and restore a checkpoint in the same"
- "run");
- }
-
- CxxConfig::statsEnable();
- getEventQueue(0)->dump();
-
- try {
- config_manager->instantiate();
- } catch (CxxConfigManager::Exception &e) {
- fatal("Config problem in sim object %s: %s", e.name, e.message);
- }
-}
-
-void SimControl::run()
-{
- EventQueue *eventq = getEventQueue(0);
- GlobalSimLoopExitEvent *exit_event = NULL;
-
- /* There *must* be no scheduled events yet */
- fatal_if(!eventq->empty(), "There must be no posted events"
- " before SimControl::run");
-
- try {
- if (checkpoint_restore) {
- std::cerr << "Restoring checkpoint\n";
-
- CheckpointIn *checkpoint = new CheckpointIn(checkpoint_dir,
- config_manager->getSimObjectResolver());
-
- /* Catch SystemC up with gem5 after checkpoint restore.
- * Note that gem5 leading SystemC is always a violation of the
- * required relationship between the two, hence this careful
- * catchup */
-
- DrainManager::instance().preCheckpointRestore();
- Serializable::unserializeGlobals(*checkpoint);
-
- Tick systemc_time = sc_core::sc_time_stamp().value();
- if (curTick() > systemc_time) {
- Tick wait_period = curTick() - systemc_time;
-
- std::cerr << "Waiting for " << wait_period << "ps for"
- " SystemC to catch up to gem5\n";
- wait(sc_core::sc_time::from_value(wait_period));
- }
-
- config_manager->loadState(*checkpoint);
- config_manager->startup();
- config_manager->drainResume();
-
- std::cerr << "Restored from Checkpoint\n";
- } else {
- config_manager->initState();
- config_manager->startup();
- }
- } catch (CxxConfigManager::Exception &e) {
- fatal("Config problem in sim object %s: %s", e.name, e.message);
- }
-
- fatal_if(eventq->empty(), "No events to process after system startup");
-
- if (checkpoint_save) {
- exit_event = simulate(pre_run_time);
-
- unsigned int drain_count = 1;
- do {
- drain_count = config_manager->drain();
-
- std::cerr << "Draining " << drain_count << '\n';
-
- if (drain_count > 0) {
- exit_event = simulate();
- }
- } while (drain_count > 0);
-
- std::cerr << "Simulation stop at tick " << curTick()
- << ", cause: " << exit_event->getCause() << '\n';
-
- std::cerr << "Checkpointing\n";
-
- /* FIXME, this should really be serialising just for
- * config_manager rather than using serializeAll's ugly
- * SimObject static object list */
- Serializable::serializeAll(checkpoint_dir);
-
- std::cerr << "Completed checkpoint\n";
-
- config_manager->drainResume();
- }
-
- if (switch_cpus) {
- exit_event = simulate(pre_switch_time);
-
- unsigned int drain_count = 1;
- do {
- drain_count = config_manager->drain();
-
- std::cerr << "Draining " << drain_count << '\n';
-
- if (drain_count > 0) {
- exit_event = simulate();
- }
- } while (drain_count > 0);
-
- for (unsigned cpu_num = 0; cpu_num < num_switch_cpus; ++cpu_num) {
- switchCpu(cpu_num, num_switch_cpus);
- }
-
- config_manager->drainResume();
-
- }
-
- exit_event = simulate();
-
- std::cerr << "Exit at tick " << curTick()
- << ", cause: " << exit_event->getCause() << '\n';
-
- getEventQueue(0)->dump();
-
-#if TRY_CLEAN_DELETE
- config_manager->deleteObjects();
-#endif
-}
-
-int
-sc_main(int argc, char **argv)
-{
- SimControl sim_control("gem5", argc, argv);
-
- filename = "m5out/stats-systemc.txt";
-
- sc_core::sc_start();
-
- CxxConfig::statsDump();
-
- return EXIT_SUCCESS;
-}
-
-void
-SimControl::switchCpu(unsigned cpuNum, unsigned numTotalCpus) {
- assert(cpuNum < numTotalCpus);
- std::ostringstream from_cpu_name;
- std::ostringstream to_cpu_name;
-
- from_cpu_name << from_cpu;
- to_cpu_name << to_cpu;
-
- if (numTotalCpus > 1) {
- from_cpu_name << cpuNum;
- to_cpu_name << cpuNum;
- }
-
- std::cerr << "Switching CPU "<< cpuNum << "(from='" << from_cpu_name.str()
- <<"' to '"<< to_cpu_name.str() << "')\n";
-
- /* Assume the system is called system */
- System &system = config_manager->getObject<System>("system");
- BaseCPU &old_cpu = config_manager->getObject<BaseCPU>(from_cpu_name.str());
- BaseCPU &new_cpu = config_manager->getObject<BaseCPU>(to_cpu_name.str());
-
- old_cpu.switchOut();
-
- // I'm not sure if this can be called before old_cpu.switchOut(). If so,
- // it is best to just move this call before the switchCpu loop in run()
- // where it previously was
- if (cpuNum == 0)
- system.setMemoryMode(Enums::timing);
-
- new_cpu.takeOverFrom(&old_cpu);
-
-
- std::cerr << "Switched CPU"<<cpuNum<<"\n";
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 ARM Limited
- * All rights reserved
- *
- * The license below extends only to copyright in the software and shall
- * not be construed as granting a license to any other intellectual
- * property including but not limited to intellectual property relating
- * to a hardware implementation of the functionality of the software
- * licensed hereunder. You may use the software subject to the license
- * terms below provided that you ensure that this notice is replicated
- * unmodified and in its entirety in all distributions of the software,
- * modified or unmodified, in source code or in binary form.
- *
- * 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: Andrew Bardsley
- */
-
-#include <cstdlib>
-#include <iostream>
-#include <list>
-
-#include "base/statistics.hh"
-#include "sim/cxx_config_ini.hh"
-#include "sim/cxx_manager.hh"
-#include "sim/debug.hh"
-#include "sim/init_signals.hh"
-#include "sim/stat_control.hh"
-#include "sc_gem5_control.hh"
-#include "sc_logger.hh"
-#include "sc_module.hh"
-#include "stats.hh"
-
-namespace Gem5SystemC
-{
-
-/** This is the private side of Gem5Control */
-class Gem5TopLevelModule : public Gem5SystemC::Module
-{
- friend class Gem5Control;
-
- protected:
- CxxConfigFileBase *config_file;
- CxxConfigManager *root_manager;
- Gem5SystemC::Logger logger;
-
- /** Things to do at end_of_elaborate */
- std::list<void (*)()> endOfElaborationFuncs;
-
- public:
- SC_HAS_PROCESS(Gem5TopLevelModule);
-
- Gem5TopLevelModule(sc_core::sc_module_name name,
- const std::string &config_filename);
- ~Gem5TopLevelModule();
-
- /** gem5 simulate. @todo for more interesting simulation control,
- * this needs to be more complicated */
- void run();
-
- /* Register an action to happen at the end of elaboration */
- void registerEndOfElaboration(void (*func)())
- {
- endOfElaborationFuncs.push_back(func);
- }
-
- /** SystemC startup */
- void end_of_elaboration();
-};
-
-Gem5System::Gem5System(CxxConfigManager *manager_,
- const std::string &system_name, const std::string &instance_name) :
- manager(manager_),
- systemName(system_name),
- instanceName(instance_name)
-{
- manager->addRenaming(CxxConfigManager::Renaming(
- system_name, instance_name));
-}
-
-Gem5System::~Gem5System()
-{
- delete manager;
-}
-
-void
-Gem5System::setParam(const std::string &object,
- const std::string ¶m_name, const std::string ¶m_value)
-{
- manager->setParam(systemName + (object != "" ? "." + object : ""),
- param_name, param_value);
-}
-
-void
-Gem5System::setParamVector(const std::string &object,
- const std::string ¶m_name,
- const std::vector<std::string> ¶m_values)
-{
- manager->setParamVector(systemName +
- (object != "" ? "." + object : ""), param_name, param_values);
-}
-
-void
-Gem5System::instantiate()
-{
- try {
- /* Make a new System */
- SimObject *obj = manager->findObject(systemName, true);
-
- /* Add the System's objects to the list of managed
- * objects for initialisation */
- manager->findTraversalOrder(systemName);
-
- /* Bound ports *must* be internal to System */
- for (auto i = manager->objectsInOrder.begin();
- i != manager->objectsInOrder.end();
- ++ i)
- {
- manager->bindObjectPorts(*i);
- }
-
- /* gem5 startup sequence */
- manager->instantiate(false);
- manager->initState();
- manager->startup();
- } catch (CxxConfigManager::Exception &e) {
- fatal("Config problem in Gem5System: %s: %s",
- e.name, e.message);
- }
-}
-
-Gem5Control::Gem5Control(const std::string &config_filename)
-{
- module = new Gem5TopLevelModule("gem5", config_filename);
-}
-
-Gem5Control::~Gem5Control()
-{ }
-
-void
-Gem5Control::registerEndOfElaboration(void (*func)())
-{
- module->registerEndOfElaboration(func);
-}
-
-void
-Gem5Control::setDebugFlag(const char *flag)
-{
- ::setDebugFlag(flag);
-}
-
-void
-Gem5Control::clearDebugFlag(const char *flag)
-{
- ::clearDebugFlag(flag);
-}
-
-void
-Gem5Control::setRemoteGDBPort(unsigned int port)
-{
- ::setRemoteGDBPort(port);
-}
-
-Gem5System *
-Gem5Control::makeSystem(const std::string &system_name,
- const std::string &instance_name)
-{
- Gem5System *ret = new Gem5System(
- new CxxConfigManager(*(module->config_file)),
- system_name, instance_name);
-
- return ret;
-}
-
-const std::string &
-Gem5Control::getVersion() const
-{
- return version;
-}
-
-void
-Gem5Control::setVersion(const std::string &new_version)
-{
- if (version != "")
- fatal("Gem5Control::setVersion called for a second time");
-
- version = new_version;
-}
-
-Gem5TopLevelModule::Gem5TopLevelModule(sc_core::sc_module_name name,
- const std::string &config_filename) :
- Gem5SystemC::Module(name),
- config_file(NULL),
- root_manager(NULL)
-{
- SC_THREAD(run);
-
- cxxConfigInit();
-
- /* Pass DPRINTF messages to SystemC */
- Trace::setDebugLogger(&logger);
-
- /* @todo need this as an option */
- Gem5SystemC::setTickFrequency();
-
- /* Make a SystemC-synchronising event queue and install it as the
- * sole top level gem5 EventQueue */
- Gem5SystemC::Module::setupEventQueues(*this);
-
- if (sc_core::sc_get_time_resolution() !=
- sc_core::sc_time(1, sc_core::SC_PS))
- {
- fatal("Time resolution must be set to 1 ps for gem5 to work");
- }
-
- /* Enable keyboard interrupt, async I/O etc. */
- initSignals();
-
- /* Enable stats */
- Stats::initSimStats();
- Stats::registerHandlers(CxxConfig::statsReset, CxxConfig::statsDump);
-
- Trace::enable();
-
- config_file = new CxxIniFile();
-
- if (!config_file->load(config_filename)) {
- fatal("Gem5TopLevelModule: Can't open config file: %s",
- config_filename);
- }
-
- root_manager = new CxxConfigManager(*config_file);
-
- CxxConfig::statsEnable();
-
- /* Make the root object */
- try {
- SimObject *root = root_manager->findObject("root", false);
-
- /* Make sure we don't traverse into root's children */
- root_manager->objectsInOrder.push_back(root);
-
- root_manager->instantiate(false);
- root_manager->initState();
- root_manager->startup();
- } catch (CxxConfigManager::Exception &e) {
- fatal("Config problem in Gem5TopLevelModule: %s: %s",
- e.name, e.message);
- }
-}
-
-Gem5TopLevelModule::~Gem5TopLevelModule()
-{
- delete config_file;
- delete root_manager;
-}
-
-void
-Gem5TopLevelModule::run()
-{
- GlobalSimLoopExitEvent *exit_event = NULL;
-
- exit_event = simulate();
-
- std::cerr << "Exit at tick " << curTick()
- << ", cause: " << exit_event->getCause() << '\n';
-
- getEventQueue(0)->dump();
-}
-
-void
-Gem5TopLevelModule::end_of_elaboration()
-{
- for (auto i = endOfElaborationFuncs.begin();
- i != endOfElaborationFuncs.end(); ++i)
- {
- (*i)();
- }
-}
-
-}
-
-Gem5SystemC::Gem5Control *
-makeGem5Control(const std::string &config_filename)
-{
- return new Gem5SystemC::Gem5Control(config_filename);
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2014 ARM Limited
- * All rights reserved
- *
- * The license below extends only to copyright in the software and shall
- * not be construed as granting a license to any other intellectual
- * property including but not limited to intellectual property relating
- * to a hardware implementation of the functionality of the software
- * licensed hereunder. You may use the software subject to the license
- * terms below provided that you ensure that this notice is replicated
- * unmodified and in its entirety in all distributions of the software,
- * modified or unmodified, in source code or in binary form.
- *
- * 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: Andrew Bardsley
- */
-
-/**
- * @file
- *
- * Top level definitions for exporting gem5 across a dlopen interface.
- *
- * Gem5Control should be instantiated once to build the gem5 root.
- * Systems from that root's config file can then be instantiated as
- * Gem5System's using Gem5Control::makeSystem.
- *
- * Gem5Control contains a Gem5TopLevelModule which is a SystemC
- * module providing the gem5 `simulate' function as its sole
- * thread action.
- */
-
-#ifndef __SIM_SC_GEM5_CONTROL_HH__
-#define __SIM_SC_GEM5_CONTROL_HH__
-
-#include <string>
-#include <vector>
-
-class CxxConfigManager;
-
-namespace Gem5SystemC
-{
-
-class Gem5TopLevelModule;
-class Gem5Control;
-
-/** Gem5System's wrap CxxConfigManager's instantiating a gem5 System
- * object (and its children). New Gem5Systems are created by
- * Gem5Control::makeSystem. A new system can have its parameters
- * tweaked using setParam{,Vector} before being instantiated using
- * Gem5System::instantiate. After instantiation, any external ports
- * declared by the system should be visible in SystemC.
- *
- * It is recommended that a SystemC wrapper sc_module is declared to
- * own each Gem5System with the call to Gem5System::instantiate being
- * made in that wrapper's constructor
- *
- * Note that *every* `normal' member function in this class *must*
- * be virtual to ensure that references to the functions go through
- * the pointer acquired using makeSystem and not looked up as
- * name-mangled symbols
- *
- * */
-class Gem5System
-{
- private:
- /** Config management for *just* this system's objects (notably
- * excluding root */
- CxxConfigManager *manager;
-
- /** The config file prototype for the system */
- std::string systemName;
-
- /** The instantiated (in gem5) name of the system */
- std::string instanceName;
-
- public:
- /** A constructor only used by Gem5Control */
- Gem5System(CxxConfigManager *manager_,
- const std::string &system_name, const std::string &instance_name);
-
- virtual ~Gem5System();
-
- /** Parameter setting functions callable before instantiate */
- virtual void setParam(const std::string &object,
- const std::string ¶m_name, const std::string ¶m_value);
-
- virtual void setParamVector(const std::string &system_name,
- const std::string ¶m_name,
- const std::vector<std::string> ¶m_values);
-
- /** Build the system's gem5 infrastructure, bind its ports (note
- * that all ports *must* be internal to the system), init and
- * SimObject::startup the system */
- virtual void instantiate();
-};
-
-/** Singleton class containing gem5 simulation control.
- *
- * Note that *every* `normal' member function in this class *must*
- * be virtual to ensure that references to the functions go through
- * the pointer acquired using makeGem5Control and not looked up as
- * name-mangled symbols
- */
-class Gem5Control
-{
- private:
- /** Private SystemC module containing top level simulation control */
- Gem5TopLevelModule *module;
-
- /** One-time-settable version string */
- std::string version;
-
- public:
- Gem5Control(const std::string &config_filename);
-
- virtual ~Gem5Control();
-
- /** Set/clear a gem5 debug flag */
- virtual void setDebugFlag(const char *flag);
- virtual void clearDebugFlag(const char *flag);
-
- /** Choose a base port number for GDB to connect to the model
- * (0 disables connections) */
- virtual void setRemoteGDBPort(unsigned int port);
-
- /* Register an action to happen at the end of elaboration */
- virtual void registerEndOfElaboration(void (*func)());
-
- /** Make a System from the config file description for system
- * system_name and call it instance_name in gem5 */
- virtual Gem5System *makeSystem(const std::string &system_name,
- const std::string &top_instance);
-
- /** set/get version string */
- virtual const std::string &getVersion() const;
- virtual void setVersion(const std::string &new_version);
-};
-
-}
-
-/** Instantiate a Gem5Control. This can be called using dlopen/dlsym
- * to kick-start gem5 */
-extern "C" Gem5SystemC::Gem5Control *makeGem5Control(
- const std::string &config_filename);
-
-#endif // __SIM_SC_GEM5_CONTROL_HH__
+++ /dev/null
-/*
- * Copyright (c) 2014 ARM Limited
- * All rights reserved
- *
- * The license below extends only to copyright in the software and shall
- * not be construed as granting a license to any other intellectual
- * property including but not limited to intellectual property relating
- * to a hardware implementation of the functionality of the software
- * licensed hereunder. You may use the software subject to the license
- * terms below provided that you ensure that this notice is replicated
- * unmodified and in its entirety in all distributions of the software,
- * modified or unmodified, in source code or in binary form.
- *
- * 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: Andrew Bardsley
- */
-
-/**
- * @file
- *
- * A logger to allow SystemC to capture DPRINTF messages (and similar things)
- * using sc_report
- */
-
-#include <cstdlib>
-#include <cstring>
-#include <sstream>
-
-#include "sc_logger.hh"
-
-namespace Gem5SystemC
-{
-
-/** Class to act as a streambuf for std::ostream which cuts output strings
- * into lines and offers them to a logger */
-class CuttingStreambuf : public std::streambuf
-{
- public:
- /** Accumulate line so far */
- std::ostringstream line;
-
- /** Logger to send complete lines to */
- Trace::Logger *logger;
-
- CuttingStreambuf(Trace::Logger *logger_) : logger(logger_)
- { }
-
- /** Accumulate to line up to \n and then emit */
- int overflow(int i);
- int sync();
-
- /** Push a line out to the logger */
- void outputLine();
-
- ~CuttingStreambuf();
-};
-
-void CuttingStreambuf::outputLine()
-{
- logger->logMessage((Tick)-1, "gem5", line.str());
- line.clear();
- line.str("");
-}
-
-/** This is pretty much the least efficient way of doing this, but it has the
- * advantage of having very few corners to get wrong.
- *
- * A newly allocated streambuf will have no buffer to serve to its
- * [oi]stream. It will, therefore, call overflow for every character it
- * wants to insert into the output stream. Those characters are captured one
- * by one here and added to this->line. */
-int
-CuttingStreambuf::overflow(int chr)
-{
- if (chr == '\n')
- outputLine();
- else if (chr != EOF)
- line << (char) chr;
-
- /* Always succeeds */
- return 0;
-}
-
-int
-CuttingStreambuf::sync()
-{
- if (!line.str().empty())
- outputLine();
-
- /* Always succeeds */
- return 0;
-}
-
-CuttingStreambuf::~CuttingStreambuf()
-{
- sync();
-}
-
-Logger::Logger() :
- cuttingStreambuf(new CuttingStreambuf(this)),
- stream(cuttingStreambuf)
-{
-}
-
-Logger::~Logger()
-{
- stream.flush();
- delete cuttingStreambuf;
-}
-
-/** Log a single message as a single sc_report call */
-void
-Logger::logMessage(Tick when, const std::string &name,
- const std::string &message)
-{
- /* Need to chop the newline off the message */
- std::string message_without_nl = message;
- message_without_nl.erase(
- message_without_nl.find_last_not_of(" \n\r") + 1);
-
- SC_REPORT_INFO(name.c_str(), message_without_nl.c_str());
-}
-
-std::ostream &
-Logger::getOstream()
-{
- return stream;
-}
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 ARM Limited
- * All rights reserved
- *
- * The license below extends only to copyright in the software and shall
- * not be construed as granting a license to any other intellectual
- * property including but not limited to intellectual property relating
- * to a hardware implementation of the functionality of the software
- * licensed hereunder. You may use the software subject to the license
- * terms below provided that you ensure that this notice is replicated
- * unmodified and in its entirety in all distributions of the software,
- * modified or unmodified, in source code or in binary form.
- *
- * 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: Andrew Bardsley
- */
-
-/**
- * @file
- *
- * A logger to allow SystemC to capture DPRINTF messages (and similar things)
- * using sc_report
- */
-
-#ifndef __SIM_SC_LOGGER_H__
-#define __SIM_SC_LOGGER_H__
-
-#include <systemc>
-
-#include "base/trace.hh"
-
-namespace Gem5SystemC
-{
-
-/** sc_report logging class */
-class Logger : public Trace::Logger
-{
- protected:
- /** Stream to offer getOstream. This will cut messages up newlines and
- * offer them to logMessage */
- std::streambuf *cuttingStreambuf;
- std::ostream stream;
-
- public:
- Logger();
-
- ~Logger();
-
- /** Log a single message as a single sc_report call */
- void logMessage(Tick when, const std::string &name,
- const std::string &message);
-
- std::ostream &getOstream();
-};
-
-}
-
-#endif // __SIM_SC_LOGGER_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 ARM Limited
- * All rights reserved
- *
- * The license below extends only to copyright in the software and shall
- * not be construed as granting a license to any other intellectual
- * property including but not limited to intellectual property relating
- * to a hardware implementation of the functionality of the software
- * licensed hereunder. You may use the software subject to the license
- * terms below provided that you ensure that this notice is replicated
- * unmodified and in its entirety in all distributions of the software,
- * modified or unmodified, in source code or in binary form.
- *
- * Copyright (c) 2006 The Regents of The University of Michigan
- * Copyright (c) 2013 Advanced Micro Devices, Inc.
- * Copyright (c) 2013 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * 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: Nathan Binkert
- * Steve Reinhardt
- * Andrew Bardsley
- * Matthias Jung
- * Christian Menard
- */
-
-/**
- * @file
- *
- * Defines an sc_module type to wrap a gem5 simulation. The 'evaluate'
- * thread on that module implements the gem5 event loop.
- *
- * This currently only supports a single event queue and strictly
- * cooperatively threaded SystemC threads and so there should be at
- * most one Gem5Module instantiated in any simulation.
- */
-
-#include "base/logging.hh"
-#include "base/pollevent.hh"
-#include "base/trace.hh"
-#include "debug/Event.hh"
-#include "sc_module.hh"
-#include "sim/async.hh"
-#include "sim/core.hh"
-#include "sim/eventq.hh"
-#include "sim/sim_exit.hh"
-#include "sim/stat_control.hh"
-
-namespace Gem5SystemC
-{
-
-/** There are assumptions throughout Gem5SystemC file that a tick is 1ps.
- * Make this the case */
-void
-setTickFrequency()
-{
- ::setClockFrequency(1000000000000);
-}
-
-Module::Module(sc_core::sc_module_name name) : sc_core::sc_channel(name),
- in_simulate(false)
-{
- SC_METHOD(eventLoop);
- sensitive << eventLoopEnterEvent;
- dont_initialize();
-
- SC_METHOD(serviceExternalEvent);
- sensitive << externalSchedulingEvent;
- dont_initialize();
-}
-
-void
-Module::SCEventQueue::wakeup(Tick when)
-{
- DPRINTF(Event, "waking up SCEventQueue\n");
- /* Don't bother to use 'when' for now */
- module.notify();
-}
-
-void
-Module::setupEventQueues(Module &module)
-{
- fatal_if(mainEventQueue.size() != 0,
- "Gem5SystemC::Module::setupEventQueues must be called"
- " before any gem5 event queues are set up");
-
- numMainEventQueues = 1;
- mainEventQueue.push_back(new SCEventQueue("events", module));
- curEventQueue(getEventQueue(0));
-}
-
-void
-Module::catchup()
-{
- EventQueue *eventq = getEventQueue(0);
- Tick systemc_time = sc_core::sc_time_stamp().value();
- Tick gem5_time = curTick();
-
- /* gem5 time *must* lag SystemC as SystemC is the master */
- fatal_if(gem5_time > systemc_time, "gem5 time must lag SystemC time"
- " gem5: %d SystemC: %d", gem5_time, systemc_time);
-
- eventq->setCurTick(systemc_time);
-
- if (!eventq->empty()) {
- Tick next_event_time M5_VAR_USED = eventq->nextTick();
-
- fatal_if(gem5_time > next_event_time,
- "Missed an event at time %d gem5: %d, SystemC: %d",
- next_event_time, gem5_time, systemc_time);
- }
-}
-
-void
-Module::notify(sc_core::sc_time time_from_now)
-{
- externalSchedulingEvent.notify(time_from_now);
-}
-
-void
-Module::serviceAsyncEvent()
-{
- EventQueue *eventq = getEventQueue(0);
- std::lock_guard<EventQueue> lock(*eventq);
-
- assert(async_event);
-
- /* Catch up gem5 time with SystemC time so that any event here won't
- * be in the past relative to the current time */
- Tick systemc_time = sc_core::sc_time_stamp().value();
-
- /* Move time on to match SystemC */
- catchup();
-
- async_event = false;
- if (async_statdump || async_statreset) {
- Stats::schedStatEvent(async_statdump, async_statreset);
- async_statdump = false;
- async_statreset = false;
- }
-
- if (async_exit) {
- async_exit = false;
- exitSimLoop("user interrupt received");
- }
-
- if (async_io) {
- async_io = false;
- pollQueue.service();
- }
-
- if (async_exception)
- fatal("received async_exception, shouldn't be possible");
-}
-
-void
-Module::serviceExternalEvent()
-{
- EventQueue *eventq = getEventQueue(0);
-
- if (!in_simulate && !async_event)
- warn("Gem5SystemC external event received while not in simulate");
-
- if (async_event)
- serviceAsyncEvent();
-
- if (in_simulate && !eventq->empty())
- eventLoop();
-}
-
-void
-Module::eventLoop()
-{
- EventQueue *eventq = getEventQueue(0);
-
- fatal_if(!in_simulate, "Gem5SystemC event loop entered while"
- " outside Gem5SystemC::Module::simulate");
-
- if (async_event)
- serviceAsyncEvent();
-
- while (!eventq->empty()) {
- Tick next_event_time = eventq->nextTick();
-
- /* Move time on to match SystemC */
- catchup();
-
- Tick gem5_time = curTick();
-
- /* Woken up early */
- if (wait_exit_time > sc_core::sc_time_stamp().value()) {
- DPRINTF(Event, "Woken up early\n");
- wait_exit_time = sc_core::sc_time_stamp().value();
- }
-
- if (gem5_time < next_event_time) {
- Tick wait_period = next_event_time - gem5_time;
- wait_exit_time = gem5_time + wait_period;
-
- DPRINTF(Event, "Waiting for %d ticks for next gem5 event\n",
- wait_period);
-
- /* The next event is scheduled in the future, wait until
- * then or until externalSchedulingEvent */
- eventLoopEnterEvent.notify(sc_core::sc_time::from_value(
- sc_dt::uint64(wait_period)));
-
- return;
- } else if (gem5_time > next_event_time) {
- Tick systemc_time = sc_core::sc_time_stamp().value();
-
- /* Missed event, for some reason the above test didn't work
- * or an event was scheduled in the past */
- fatal("Missed an event at time %d gem5: %d, SystemC: %d",
- next_event_time, gem5_time, systemc_time);
- } else {
- /* Service an event */
- exitEvent = eventq->serviceOne();
-
- if (exitEvent) {
- eventLoopExitEvent.notify(sc_core::SC_ZERO_TIME);
- return;
- }
- }
- }
-
- fatal("Ran out of events without seeing exit event");
-}
-
-GlobalSimLoopExitEvent *
-Module::simulate(Tick num_cycles)
-{
- inform("Entering event queue @ %d. Starting simulation...", curTick());
-
- if (num_cycles < MaxTick - curTick())
- num_cycles = curTick() + num_cycles;
- else /* counter would roll over or be set to MaxTick anyhow */
- num_cycles = MaxTick;
-
- GlobalEvent *limit_event = new GlobalSimLoopExitEvent(num_cycles,
- "simulate() limit reached", 0, 0);
-
- exitEvent = NULL;
-
- /* Cancel any outstanding events */
- eventLoopExitEvent.cancel();
- externalSchedulingEvent.cancel();
-
- in_simulate = true;
- eventLoopEnterEvent.notify(sc_core::SC_ZERO_TIME);
-
- /* Wait for event queue to exit, guarded by exitEvent just incase
- * it already has exited and we don't want to completely rely
- * on notify semantics */
- if (!exitEvent)
- wait(eventLoopExitEvent);
-
- /* Cancel any outstanding event loop entries */
- eventLoopEnterEvent.cancel();
- in_simulate = false;
-
- /* Locate the global exit event */
- BaseGlobalEvent *global_event = exitEvent->globalEvent();
- assert(global_event != NULL);
-
- GlobalSimLoopExitEvent *global_exit_event =
- dynamic_cast<GlobalSimLoopExitEvent *>(global_event);
- assert(global_exit_event != NULL);
-
- if (global_exit_event != limit_event) {
- limit_event->deschedule();
- delete limit_event;
- }
-
- return global_exit_event;
-}
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 ARM Limited
- * All rights reserved
- *
- * The license below extends only to copyright in the software and shall
- * not be construed as granting a license to any other intellectual
- * property including but not limited to intellectual property relating
- * to a hardware implementation of the functionality of the software
- * licensed hereunder. You may use the software subject to the license
- * terms below provided that you ensure that this notice is replicated
- * unmodified and in its entirety in all distributions of the software,
- * modified or unmodified, in source code or in binary form.
- *
- * Copyright (c) 2006 The Regents of The University of Michigan
- * Copyright (c) 2013 Advanced Micro Devices, Inc.
- * Copyright (c) 2013 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * 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: Nathan Binkert
- * Steve Reinhardt
- * Andrew Bardsley
- * Christian Menard
- */
-
-/**
- * @file
- *
- * Defines an sc_module type to wrap a gem5 simulation. The 'evaluate'
- * thread on that module implements the gem5 event loop.
- *
- * This currently only supports a single event queue and strictly
- * cooperatively threaded SystemC threads and so there should be at
- * most one Gem5Module instantiated in any simulation.
- */
-
-#ifndef __SIM_SC_MODULE_HH__
-#define __SIM_SC_MODULE_HH__
-
-#include <systemc>
-
-#include "sim/eventq.hh"
-#include "sim/sim_events.hh"
-
-namespace Gem5SystemC
-{
-
-/** A SystemC module implementing the gem5 event queue. This object
- * doesn't actually own any of the simulation SimObjects (those need
- * to be administered separately) but it does control the event
- * queue.
- *
- * The event loop here services gem5 events in order at the current time
- * and then yielding to another SystemC thread. gem5 events are not
- * individually scheduled in SystemC. For this reason, asynchronous events
- * and function interaction (for example TLM) with gem5 from SystemC must
- * notify the module so that the yielding 'wait' can be interrupted.
- * From the point of view of another SystemC module calling into gem5,
- * curTick can lag SystemC time, be exactly the same time but *never*
- * lead SystemC time.
- *
- * This functionality is wrapped in an sc_module as its intended that
- * the a class representing top level simulation control should be derived
- * from this class. */
-class Module : public sc_core::sc_channel
-{
- protected:
- /** Event to trigger (via. ::notify) for event scheduling from
- * outside gem5 */
- sc_core::sc_event externalSchedulingEvent;
-
- /** Event to trigger on exit of eventLoop */
- sc_core::sc_event eventLoopExitEvent;
-
- /** Event to trigger to enter eventLoop */
- sc_core::sc_event eventLoopEnterEvent;
-
- /** Expected exit time of last eventLoop sleep */
- Tick wait_exit_time;
-
- /** Are we in Module::simulate? Used to mask events when not inside
- * the simulate loop */
- bool in_simulate;
-
- /** Placeholder base class for a variant event queue if this becomes
- * useful */
- class SCEventQueue : public EventQueue
- {
- protected:
- Module &module;
-
- public:
- SCEventQueue(const std::string &name,
- Module &module_) : EventQueue(name), module(module_)
- { }
-
- /** Signal module to wakeup */
- void wakeup(Tick when);
- };
-
- /** Service any async event marked up in the globals event_... */
- void serviceAsyncEvent();
-
- public:
- /** Simulate is a process */
- SC_HAS_PROCESS(Module);
-
- Module(sc_core::sc_module_name name);
-
- /** Last exitEvent from eventLoop */
- Event *exitEvent;
-
- /** Setup global event queues. Call this before any other event queues
- * are created */
- static void setupEventQueues(Module &module);
-
- /** Catch gem5 time up with SystemC */
- void catchup();
-
- /** Notify an externalSchedulingEvent at the given time from the
- * current SystemC time */
- void notify(sc_core::sc_time time_from_now = sc_core::SC_ZERO_TIME);
-
- /** Process an event triggered by externalSchedulingEvent and also
- * call eventLoop (to try and mop up any events at this time) if there
- * are any scheduled events */
- void serviceExternalEvent();
-
- /** Process gem5 events up until an exit event or there are no events
- * left. */
- void eventLoop();
-
- /** Run eventLoop up to num_cycles and return the final event */
- GlobalSimLoopExitEvent *simulate(Tick num_cycles = MaxTick);
-};
-
-/** There are assumptions throughout Gem5SystemC file that a tick is 1ps.
- * Make this the case */
-void setTickFrequency();
-
-}
-
-#endif // __SIM_SC_MODULE_HH__
+++ /dev/null
-/*
- * Copyright (c) 2014 ARM Limited
- * All rights reserved
- *
- * The license below extends only to copyright in the software and shall
- * not be construed as granting a license to any other intellectual
- * property including but not limited to intellectual property relating
- * to a hardware implementation of the functionality of the software
- * licensed hereunder. You may use the software subject to the license
- * terms below provided that you ensure that this notice is replicated
- * unmodified and in its entirety in all distributions of the software,
- * modified or unmodified, in source code or in binary form.
- *
- * 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: Andrew Bardsley
- * Matthias Jung
- * Abdul Mutaal Ahmad
- */
-
-/**
- * @file
- *
- * C++-only configuration stats handling example
- *
- * Register with: Stats::registerHandlers(statsReset, statsDump)
- */
-
-#include "base/output.hh"
-#include "base/statistics.hh"
-#include "base/stats/text.hh"
-#include "stats.hh"
-
-namespace CxxConfig
-{
-
-void statsPrepare()
-{
- std::list<Stats::Info *> stats = Stats::statsList();
-
- /* gather_stats -> prepare */
- for (auto i = stats.begin(); i != stats.end(); ++i){
- Stats::Info *stat = *i;
- Stats::VectorInfo *vector = dynamic_cast<Stats::VectorInfo *>(stat);
- if (vector){
- (dynamic_cast<Stats::VectorInfo *>(*i))->prepare();
- }
- else {
- (*i)->prepare();
- }
-
- }
-}
-
-void statsDump()
-{
- bool desc = true;
- Stats::Output *output = Stats::initText(filename, desc);
-
- Stats::processDumpQueue();
-
- std::list<Stats::Info *> stats = Stats::statsList();
-
- statsEnable();
- statsPrepare();
-
- output->begin();
- /* gather_stats -> convert_value */
- for (auto i = stats.begin(); i != stats.end(); ++i) {
- Stats::Info *stat = *i;
-
- const Stats::ScalarInfo *scalar = dynamic_cast<Stats::ScalarInfo
- *>(stat);
- Stats::VectorInfo *vector = dynamic_cast<Stats::VectorInfo *>(stat);
- const Stats::Vector2dInfo *vector2d = dynamic_cast<Stats::Vector2dInfo
- *>(vector);
- const Stats::DistInfo *dist = dynamic_cast<Stats::DistInfo *>(stat);
- const Stats::VectorDistInfo *vectordist =
- dynamic_cast<Stats::VectorDistInfo *>(stat);
- const Stats::SparseHistInfo *sparse =
- dynamic_cast<Stats::SparseHistInfo *>(stat);
- const Stats::InfoProxy <Stats::Vector2d,Stats::Vector2dInfo> *info =
- dynamic_cast<Stats::InfoProxy
- <Stats::Vector2d,Stats::Vector2dInfo>*>(stat);
-
- if (vector) {
- const Stats::FormulaInfo *formula = dynamic_cast<Stats::FormulaInfo
- *>(vector);
- if (formula){
- output->visit(*formula);
- } else {
- const Stats::VectorInfo *vector1 = vector;
- output->visit(*vector1);
- }
- } else if (vector2d) {
- output->visit(*vector2d);
- } else if (info){
- output->visit(*info);
- } else if (vectordist){
- output->visit(*vectordist);
- } else if (dist) {
- output->visit(*dist);
- } else if (sparse) {
- output->visit(*sparse);
- } else if (scalar) {
- output->visit(*scalar);
- } else {
- warn("Stat not dumped: %s\n", stat->name);
- }
- }
- output->end();
-}
-
-void statsReset()
-{
- std::cerr << "Stats reset\n";
-
- Stats::processResetQueue();
-}
-
-void statsEnable()
-{
- std::list<Stats::Info *> stats = Stats::statsList();
-
- for (auto i = stats.begin(); i != stats.end(); ++i){
- Stats::Info *stat = *i;
- Stats::VectorInfo *vector = dynamic_cast<Stats::VectorInfo *>(stat);
- if (vector){
- (dynamic_cast<Stats::VectorInfo *>(*i))->enable();
- }
- else {
- (*i)->enable();
- }
-
- }
-}
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 ARM Limited
- * All rights reserved
- *
- * The license below extends only to copyright in the software and shall
- * not be construed as granting a license to any other intellectual
- * property including but not limited to intellectual property relating
- * to a hardware implementation of the functionality of the software
- * licensed hereunder. You may use the software subject to the license
- * terms below provided that you ensure that this notice is replicated
- * unmodified and in its entirety in all distributions of the software,
- * modified or unmodified, in source code or in binary form.
- *
- * 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: Andrew Bardsley
- * Matthias Jung
- * Abdul Mutaal Ahmad
- */
-
-/**
- * @file
- *
- * C++-only configuration stats handling example
- *
- * Register with: Stats::registerHandlers(statsReset, statsDump)
- */
-
-#ifndef __UTIL_CXX_CONFIG_STATS_H__
-#define __UTIL_CXX_CONFIG_STATS_H__
-
-extern std::string filename;
-
-namespace CxxConfig
-{
-
-void statsDump();
-void statsReset();
-void statsEnable();
-void statsPrepare();
-
-}
-
-#endif // __UTIL_CXX_CONFIG_STATS_H__