misc: Documentation Update
[gem5.git] / util / systemc / sc_gem5_control.cc
1 /*
2 * Copyright (c) 2014 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Andrew Bardsley
38 */
39
40 #include <cstdlib>
41 #include <iostream>
42 #include <list>
43
44 #include "base/statistics.hh"
45 #include "sim/cxx_config_ini.hh"
46 #include "sim/cxx_manager.hh"
47 #include "sim/debug.hh"
48 #include "sim/init_signals.hh"
49 #include "sim/stat_control.hh"
50 #include "sc_gem5_control.hh"
51 #include "sc_logger.hh"
52 #include "sc_module.hh"
53 #include "stats.hh"
54
55 namespace Gem5SystemC
56 {
57
58 /** This is the private side of Gem5Control */
59 class Gem5TopLevelModule : public Gem5SystemC::Module
60 {
61 friend class Gem5Control;
62
63 protected:
64 CxxConfigFileBase *config_file;
65 CxxConfigManager *root_manager;
66 Gem5SystemC::Logger logger;
67
68 /** Things to do at end_of_elaborate */
69 std::list<void (*)()> endOfElaborationFuncs;
70
71 public:
72 SC_HAS_PROCESS(Gem5TopLevelModule);
73
74 Gem5TopLevelModule(sc_core::sc_module_name name,
75 const std::string &config_filename);
76 ~Gem5TopLevelModule();
77
78 /** gem5 simulate. @todo for more interesting simulation control,
79 * this needs to be more complicated */
80 void run();
81
82 /* Register an action to happen at the end of elaboration */
83 void registerEndOfElaboration(void (*func)())
84 {
85 endOfElaborationFuncs.push_back(func);
86 }
87
88 /** SystemC startup */
89 void end_of_elaboration();
90 };
91
92 Gem5System::Gem5System(CxxConfigManager *manager_,
93 const std::string &system_name, const std::string &instance_name) :
94 manager(manager_),
95 systemName(system_name),
96 instanceName(instance_name)
97 {
98 manager->addRenaming(CxxConfigManager::Renaming(
99 system_name, instance_name));
100 }
101
102 Gem5System::~Gem5System()
103 {
104 delete manager;
105 }
106
107 void
108 Gem5System::setParam(const std::string &object,
109 const std::string &param_name, const std::string &param_value)
110 {
111 manager->setParam(systemName + (object != "" ? "." + object : ""),
112 param_name, param_value);
113 }
114
115 void
116 Gem5System::setParamVector(const std::string &object,
117 const std::string &param_name,
118 const std::vector<std::string> &param_values)
119 {
120 manager->setParamVector(systemName +
121 (object != "" ? "." + object : ""), param_name, param_values);
122 }
123
124 void
125 Gem5System::instantiate()
126 {
127 try {
128 /* Make a new System */
129 SimObject *obj = manager->findObject(systemName, true);
130
131 /* Add the System's objects to the list of managed
132 * objects for initialisation */
133 manager->findTraversalOrder(systemName);
134
135 /* Bound ports *must* be internal to System */
136 for (auto i = manager->objectsInOrder.begin();
137 i != manager->objectsInOrder.end();
138 ++ i)
139 {
140 manager->bindObjectPorts(*i);
141 }
142
143 /* gem5 startup sequence */
144 manager->instantiate(false);
145 manager->initState();
146 manager->startup();
147 } catch (CxxConfigManager::Exception &e) {
148 fatal("Config problem in Gem5System: %s: %s",
149 e.name, e.message);
150 }
151 }
152
153 Gem5Control::Gem5Control(const std::string &config_filename)
154 {
155 module = new Gem5TopLevelModule("gem5", config_filename);
156 }
157
158 Gem5Control::~Gem5Control()
159 { }
160
161 void
162 Gem5Control::registerEndOfElaboration(void (*func)())
163 {
164 module->registerEndOfElaboration(func);
165 }
166
167 void
168 Gem5Control::setDebugFlag(const char *flag)
169 {
170 ::setDebugFlag(flag);
171 }
172
173 void
174 Gem5Control::clearDebugFlag(const char *flag)
175 {
176 ::clearDebugFlag(flag);
177 }
178
179 void
180 Gem5Control::setRemoteGDBPort(unsigned int port)
181 {
182 ::setRemoteGDBPort(port);
183 }
184
185 Gem5System *
186 Gem5Control::makeSystem(const std::string &system_name,
187 const std::string &instance_name)
188 {
189 Gem5System *ret = new Gem5System(
190 new CxxConfigManager(*(module->config_file)),
191 system_name, instance_name);
192
193 return ret;
194 }
195
196 const std::string &
197 Gem5Control::getVersion() const
198 {
199 return version;
200 }
201
202 void
203 Gem5Control::setVersion(const std::string &new_version)
204 {
205 if (version != "")
206 fatal("Gem5Control::setVersion called for a second time");
207
208 version = new_version;
209 }
210
211 Gem5TopLevelModule::Gem5TopLevelModule(sc_core::sc_module_name name,
212 const std::string &config_filename) :
213 Gem5SystemC::Module(name),
214 config_file(NULL),
215 root_manager(NULL)
216 {
217 SC_THREAD(run);
218
219 cxxConfigInit();
220
221 /* Pass DPRINTF messages to SystemC */
222 Trace::setDebugLogger(&logger);
223
224 /* @todo need this as an option */
225 Gem5SystemC::setTickFrequency();
226
227 /* Make a SystemC-synchronising event queue and install it as the
228 * sole top level gem5 EventQueue */
229 Gem5SystemC::Module::setupEventQueues(*this);
230
231 if (sc_core::sc_get_time_resolution() !=
232 sc_core::sc_time(1, sc_core::SC_PS))
233 {
234 fatal("Time resolution must be set to 1 ps for gem5 to work");
235 }
236
237 /* Enable keyboard interrupt, async I/O etc. */
238 initSignals();
239
240 /* Enable stats */
241 Stats::initSimStats();
242 Stats::registerHandlers(CxxConfig::statsReset, CxxConfig::statsDump);
243
244 Trace::enable();
245
246 config_file = new CxxIniFile();
247
248 if (!config_file->load(config_filename)) {
249 fatal("Gem5TopLevelModule: Can't open config file: %s",
250 config_filename);
251 }
252
253 root_manager = new CxxConfigManager(*config_file);
254
255 CxxConfig::statsEnable();
256
257 /* Make the root object */
258 try {
259 SimObject *root = root_manager->findObject("root", false);
260
261 /* Make sure we don't traverse into root's children */
262 root_manager->objectsInOrder.push_back(root);
263
264 root_manager->instantiate(false);
265 root_manager->initState();
266 root_manager->startup();
267 } catch (CxxConfigManager::Exception &e) {
268 fatal("Config problem in Gem5TopLevelModule: %s: %s",
269 e.name, e.message);
270 }
271 }
272
273 Gem5TopLevelModule::~Gem5TopLevelModule()
274 {
275 delete config_file;
276 delete root_manager;
277 }
278
279 void
280 Gem5TopLevelModule::run()
281 {
282 GlobalSimLoopExitEvent *exit_event = NULL;
283
284 exit_event = simulate();
285
286 std::cerr << "Exit at tick " << curTick()
287 << ", cause: " << exit_event->getCause() << '\n';
288
289 getEventQueue(0)->dump();
290 }
291
292 void
293 Gem5TopLevelModule::end_of_elaboration()
294 {
295 for (auto i = endOfElaborationFuncs.begin();
296 i != endOfElaborationFuncs.end(); ++i)
297 {
298 (*i)();
299 }
300 }
301
302 }
303
304 Gem5SystemC::Gem5Control *
305 makeGem5Control(const std::string &config_filename)
306 {
307 return new Gem5SystemC::Gem5Control(config_filename);
308 }
309