From: Paul Rosenfeld Date: Fri, 27 Jan 2017 21:03:17 +0000 (-0600) Subject: misc: Add support for switching multiple cores in SystemC X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c5df9308c99bd4af41b24119e2d86bde9eafdfa4;p=gem5.git misc: Add support for switching multiple cores in SystemC This patch adds a '-n' flag to the gem5 SystemC driver which allows multiple CPUs to be switched out to a new CPU. Primarily this involves appending CPU numbers to the objects searched for in the config manager if there are multiple CPUs in the system. Note that an equivalent change should be made to the util/cxx_config driver, but I wanted to get input on this first before making the same change over there Signed-off-by: Jason Lowe-Power --- 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 -- 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"); - BaseCPU &old_cpu = config_manager->getObject(from_cpu); - BaseCPU &new_cpu = config_manager->getObject(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"); + BaseCPU &old_cpu = config_manager->getObject(from_cpu_name.str()); + BaseCPU &new_cpu = config_manager->getObject(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"<