2 * Copyright (c) 2014 ARM Limited
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.
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.
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.
37 * Authors: Andrew Bardsley
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"
58 /** This is the private side of Gem5Control */
59 class Gem5TopLevelModule
: public Gem5SystemC::Module
61 friend class Gem5Control
;
64 CxxConfigFileBase
*config_file
;
65 CxxConfigManager
*root_manager
;
66 Gem5SystemC::Logger logger
;
68 /** Things to do at end_of_elaborate */
69 std::list
<void (*)()> endOfElaborationFuncs
;
72 SC_HAS_PROCESS(Gem5TopLevelModule
);
74 Gem5TopLevelModule(sc_core::sc_module_name name
,
75 const std::string
&config_filename
);
76 ~Gem5TopLevelModule();
78 /** gem5 simulate. @todo for more interesting simulation control,
79 * this needs to be more complicated */
82 /* Register an action to happen at the end of elaboration */
83 void registerEndOfElaboration(void (*func
)())
85 endOfElaborationFuncs
.push_back(func
);
88 /** SystemC startup */
89 void end_of_elaboration();
92 Gem5System::Gem5System(CxxConfigManager
*manager_
,
93 const std::string
&system_name
, const std::string
&instance_name
) :
95 systemName(system_name
),
96 instanceName(instance_name
)
98 manager
->addRenaming(CxxConfigManager::Renaming(
99 system_name
, instance_name
));
102 Gem5System::~Gem5System()
108 Gem5System::setParam(const std::string
&object
,
109 const std::string
¶m_name
, const std::string
¶m_value
)
111 manager
->setParam(systemName
+ (object
!= "" ? "." + object
: ""),
112 param_name
, param_value
);
116 Gem5System::setParamVector(const std::string
&object
,
117 const std::string
¶m_name
,
118 const std::vector
<std::string
> ¶m_values
)
120 manager
->setParamVector(systemName
+
121 (object
!= "" ? "." + object
: ""), param_name
, param_values
);
125 Gem5System::instantiate()
128 /* Make a new System */
129 SimObject
*obj
= manager
->findObject(systemName
, true);
131 /* Add the System's objects to the list of managed
132 * objects for initialisation */
133 manager
->findTraversalOrder(systemName
);
135 /* Bound ports *must* be internal to System */
136 for (auto i
= manager
->objectsInOrder
.begin();
137 i
!= manager
->objectsInOrder
.end();
140 manager
->bindObjectPorts(*i
);
143 /* gem5 startup sequence */
144 manager
->instantiate(false);
145 manager
->initState();
147 } catch (CxxConfigManager::Exception
&e
) {
148 fatal("Config problem in Gem5System: %s: %s",
153 Gem5Control::Gem5Control(const std::string
&config_filename
)
155 module
= new Gem5TopLevelModule("gem5", config_filename
);
158 Gem5Control::~Gem5Control()
162 Gem5Control::registerEndOfElaboration(void (*func
)())
164 module
->registerEndOfElaboration(func
);
168 Gem5Control::setDebugFlag(const char *flag
)
170 ::setDebugFlag(flag
);
174 Gem5Control::clearDebugFlag(const char *flag
)
176 ::clearDebugFlag(flag
);
180 Gem5Control::setRemoteGDBPort(unsigned int port
)
182 ::setRemoteGDBPort(port
);
186 Gem5Control::makeSystem(const std::string
&system_name
,
187 const std::string
&instance_name
)
189 Gem5System
*ret
= new Gem5System(
190 new CxxConfigManager(*(module
->config_file
)),
191 system_name
, instance_name
);
197 Gem5Control::getVersion() const
203 Gem5Control::setVersion(const std::string
&new_version
)
206 fatal("Gem5Control::setVersion called for a second time");
208 version
= new_version
;
211 Gem5TopLevelModule::Gem5TopLevelModule(sc_core::sc_module_name name
,
212 const std::string
&config_filename
) :
213 Gem5SystemC::Module(name
),
221 /* Pass DPRINTF messages to SystemC */
222 Trace::setDebugLogger(&logger
);
224 /* @todo need this as an option */
225 Gem5SystemC::setTickFrequency();
227 /* Make a SystemC-synchronising event queue and install it as the
228 * sole top level gem5 EventQueue */
229 Gem5SystemC::Module::setupEventQueues(*this);
231 if (sc_core::sc_get_time_resolution() !=
232 sc_core::sc_time(1, sc_core::SC_PS
))
234 fatal("Time resolution must be set to 1 ps for gem5 to work");
237 /* Enable keyboard interrupt, async I/O etc. */
241 Stats::initSimStats();
242 Stats::registerHandlers(CxxConfig::statsReset
, CxxConfig::statsDump
);
246 config_file
= new CxxIniFile();
248 if (!config_file
->load(config_filename
)) {
249 fatal("Gem5TopLevelModule: Can't open config file: %s",
253 root_manager
= new CxxConfigManager(*config_file
);
255 CxxConfig::statsEnable();
257 /* Make the root object */
259 SimObject
*root
= root_manager
->findObject("root", false);
261 /* Make sure we don't traverse into root's children */
262 root_manager
->objectsInOrder
.push_back(root
);
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",
273 Gem5TopLevelModule::~Gem5TopLevelModule()
280 Gem5TopLevelModule::run()
282 GlobalSimLoopExitEvent
*exit_event
= NULL
;
284 exit_event
= simulate();
286 std::cerr
<< "Exit at tick " << curTick()
287 << ", cause: " << exit_event
->getCause() << '\n';
289 getEventQueue(0)->dump();
293 Gem5TopLevelModule::end_of_elaboration()
295 for (auto i
= endOfElaborationFuncs
.begin();
296 i
!= endOfElaborationFuncs
.end(); ++i
)
304 Gem5SystemC::Gem5Control
*
305 makeGem5Control(const std::string
&config_filename
)
307 return new Gem5SystemC::Gem5Control(config_filename
);