summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/systemc/main.cc72
1 files changed, 61 insertions, 11 deletions
diff --git a/util/systemc/main.cc b/util/systemc/main.cc
index c9fbd48a0..cbbdd7229 100644
--- a/util/systemc/main.cc
+++ b/util/systemc/main.cc
@@ -96,6 +96,9 @@ usage(const std::string &prog_name)
" -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"
);
@@ -118,6 +121,7 @@ class SimControl : public Gem5SystemC::Module
std::string to_cpu;
Tick pre_run_time;
Tick pre_switch_time;
+ unsigned num_switch_cpus;
public:
SC_HAS_PROCESS(SimControl);
@@ -125,6 +129,18 @@ class SimControl : public Gem5SystemC::Module
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,
@@ -177,6 +193,7 @@ SimControl::SimControl(sc_core::sc_module_name name,
to_cpu = "";
pre_run_time = 1000000;
pre_switch_time = 1000000;
+ num_switch_cpus = 1;
const std::string config_file(argv[arg_ptr]);
@@ -239,6 +256,11 @@ SimControl::SimControl(sc_core::sc_module_name name,
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);
}
@@ -342,13 +364,6 @@ void SimControl::run()
if (switch_cpus) {
exit_event = simulate(pre_switch_time);
- std::cerr << "Switching CPU\n";
-
- /* Assume the system is called system */
- System &system = config_manager->getObject<System>("system");
- BaseCPU &old_cpu = config_manager->getObject<BaseCPU>(from_cpu);
- BaseCPU &new_cpu = config_manager->getObject<BaseCPU>(to_cpu);
-
unsigned int drain_count = 1;
do {
drain_count = config_manager->drain();
@@ -360,13 +375,12 @@ void SimControl::run()
}
} while (drain_count > 0);
- old_cpu.switchOut();
- system.setMemoryMode(Enums::timing);
+ for (unsigned cpu_num = 0; cpu_num < num_switch_cpus; ++cpu_num) {
+ switchCpu(cpu_num, num_switch_cpus);
+ }
- new_cpu.takeOverFrom(&old_cpu);
config_manager->drainResume();
- std::cerr << "Switched CPU\n";
}
exit_event = simulate();
@@ -394,3 +408,39 @@ sc_main(int argc, char **argv)
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";
+}