ruby: Import ruby and slicc from GEMS
[gem5.git] / src / mem / ruby / init.cc
1
2 /*
3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /*
31 * init.C
32 *
33 * Description: See init.h
34 *
35 * $Id$
36 *
37 */
38
39 #include "Global.hh"
40 #include "EventQueue.hh"
41 #include "System.hh"
42 #include "Debug.hh"
43 #include "Profiler.hh"
44 #include "Tester.hh"
45 #include "OpalInterface.hh"
46 #include "init.hh"
47 #include "interface.hh"
48
49 #ifdef CONTIGUOUS_ADDRESSES
50 #include "ContiguousAddressTranslator.hh"
51
52 /* Declared in interface.C */
53 extern ContiguousAddressTranslator * g_p_ca_translator;
54
55 #endif // #ifdef CONTIGUOUS_ADDRESSES
56
57 using namespace std;
58 #include <string>
59 #include <map>
60 #include <stdlib.h>
61
62 // Maurice
63 // extern "C" {
64 // #include "simics/api.hh"
65 // };
66
67 #include "FakeSimicsDataTypes.hh"
68
69 #include "confio.hh"
70 #include "initvar.hh"
71
72 // A generated file containing the default parameters in string form
73 // The defaults are stored in the variable global_default_param
74 #include "default_param.hh"
75
76 attr_value_t ruby_session_get( void *id, void *obj,
77 attr_value_t *idx ) {
78 attr_value_t ret;
79
80 // all session attributes default to return invalid
81 ret.kind = Sim_Val_Invalid;
82 return ret;
83 }
84
85 set_error_t ruby_session_set( void *id, void *obj,
86 attr_value_t *val, attr_value_t *idx ) {
87 const char *command = (const char *) id;
88 // Add new ruby commands to this function
89
90 #if 0 // Eventually add these commands back in
91 if (!strcmp(command, "dump-stats" ) ) {
92 char* filename = (char*) val->u.string;
93 if(strcmp(filename, "")){
94 ruby_dump_stats(filename);
95 } else {
96 ruby_dump_stats(NULL);
97 }
98 return Sim_Set_Ok;
99 } else if (!strcmp(command, "dump-short-stats" ) ) {
100 char* filename = (char*) val->u.string;
101 if(strcmp(filename, "")){
102 ruby_dump_short_stats(filename);
103 } else {
104 ruby_dump_short_stats(NULL);
105 }
106 return Sim_Set_Ok;
107 } else if (!strcmp(command, "periodic-stats-file" ) ) {
108 char* filename = (char*) val->u.string;
109 ruby_set_periodic_stats_file(filename);
110 return Sim_Set_Ok;
111 } else if (!strcmp(command, "periodic-stats-interval" ) ) {
112 int interval = val->u.integer;
113 ruby_set_periodic_stats_interval(interval);
114 return Sim_Set_Ok;
115 } else if (!strcmp(command, "clear-stats" ) ) {
116 ruby_clear_stats();
117 return Sim_Set_Ok;
118 } else if (!strcmp(command, "debug-verb" ) ) {
119 char* new_verbosity = (char*) val->u.string;
120 ruby_change_debug_verbosity(new_verbosity);
121 return Sim_Set_Ok;
122 } else if (!strcmp(command, "debug-filter" ) ) {
123 char* new_debug_filter = (char*) val->u.string;
124 ruby_change_debug_filter(new_debug_filter);
125 return Sim_Set_Ok;
126 } else if (!strcmp(command, "debug-output-file" ) ) {
127 char* new_filename = (char*) val->u.string;
128 ruby_set_debug_output_file(new_filename);
129 return Sim_Set_Ok;
130 } else if (!strcmp(command, "debug-start-time" ) ) {
131 char* new_start_time = (char*) val->u.string;
132 ruby_set_debug_start_time(new_start_time);
133 return Sim_Set_Ok;
134 } else if (!strcmp(command, "load-caches" ) ) {
135 char* filename = (char*) val->u.string;
136 ruby_load_caches(filename);
137 return Sim_Set_Ok;
138 } else if (!strcmp(command, "save-caches" ) ) {
139 char* filename = (char*) val->u.string;
140 ruby_save_caches(filename);
141 return Sim_Set_Ok;
142 } else if (!strcmp(command, "dump-cache" ) ) {
143 int cpuNumber = val->u.integer;
144 ruby_dump_cache(cpuNumber);
145 return Sim_Set_Ok;
146 } else if (!strcmp(command, "dump-cache-data" ) ) {
147 int cpuNumber = val->u.list.vector[0].u.integer;
148 char *filename = (char*) val->u.list.vector[1].u.string;
149 ruby_dump_cache_data( cpuNumber, filename );
150 return Sim_Set_Ok;
151 } else if (!strcmp(command, "tracer-output-file" ) ) {
152 char* new_filename = (char*) val->u.string;
153 ruby_set_tracer_output_file(new_filename);
154 return Sim_Set_Ok;
155 } else if (!strcmp(command, "xact-visualizer-file" ) ) {
156 char* new_filename = (char*) val->u.string;
157 ruby_xact_visualizer_file(new_filename);
158 return Sim_Set_Ok;
159 }
160 fprintf( stderr, "error: unrecognized command: %s\n", command );
161 #endif
162 return Sim_Set_Illegal_Value;
163 }
164
165 static initvar_t *ruby_initvar_obj = NULL;
166
167 //***************************************************************************
168 static void init_generate_values( void )
169 {
170 /* update generated values, based on input configuration */
171 }
172
173 //***************************************************************************
174 void init_variables( void )
175 {
176 // allocate the "variable initialization" package
177 ruby_initvar_obj = new initvar_t( "ruby", "../../../ruby/",
178 global_default_param,
179 &init_simulator,
180 &init_generate_values,
181 &ruby_session_get,
182 &ruby_session_set );
183 }
184
185 void init_simulator()
186 {
187 // Set things to NULL to make sure we don't de-reference them
188 // without a seg. fault.
189 g_system_ptr = NULL;
190 g_debug_ptr = NULL;
191 g_eventQueue_ptr = NULL;
192
193 cout << "Ruby Timing Mode" << endl;
194 #ifndef MULTIFACET_NO_OPT_WARN
195 cerr << "Warning: optimizations not enabled." << endl;
196 #endif
197
198 if (g_SIMICS) {
199 // LUKE - if we don't set the default SMT threads in condor scripts,
200 // set it now
201 if(g_NUM_SMT_THREADS == 0){
202 g_NUM_SMT_THREADS = 1;
203 }
204 if(g_NUM_PROCESSORS == 0){
205 //only set to default if value not set in condor scripts
206 // Account for SMT systems also
207 g_NUM_PROCESSORS = SIMICS_number_processors()/g_NUM_SMT_THREADS;
208 }
209 }
210
211 RubyConfig::init();
212
213 g_debug_ptr = new Debug( DEBUG_FILTER_STRING,
214 DEBUG_VERBOSITY_STRING,
215 DEBUG_START_TIME,
216 DEBUG_OUTPUT_FILENAME );
217
218 cout << "Creating event queue..." << endl;
219 g_eventQueue_ptr = new EventQueue;
220 cout << "Creating event queue done" << endl;
221
222 cout << "Creating system..." << endl;
223 cout << " Processors: " << RubyConfig::numberOfProcessors() << endl;
224
225 g_system_ptr = new System;
226 cout << "Creating system done" << endl;
227
228 // if opal is loaded, its static interface object (inst) will be non-null,
229 // and the opal object needs to be notified that ruby is now loaded.
230 // "1" indicates a load and should be replaced with an enumerated type.
231 if (OpalInterface::inst != NULL) {
232 OpalInterface::inst->notify( 1 );
233 }
234
235 #ifdef CONTIGUOUS_ADDRESSES
236 if(g_SIMICS) {
237 cout << "Establishing Contiguous Address Space Mappings..." << flush;
238 g_p_ca_translator = new ContiguousAddressTranslator();
239 assert(g_p_ca_translator!=NULL);
240 if(g_p_ca_translator->AddressesAreContiguous()) {
241 cout << "Physical Memory Addresses are already contiguous." << endl;
242 delete g_p_ca_translator;
243 g_p_ca_translator = NULL;
244 } else {
245 cout << "Done." << endl;
246 }
247 } else {
248 g_p_ca_translator = NULL;
249 }
250 #endif // #ifdef CONTIGUOUS_ADDRESSES
251
252 cout << "Ruby initialization complete" << endl;
253 }
254
255 void init_opal_interface( mf_ruby_api_t *api )
256 {
257 OpalInterface::installInterface( api );
258 }
259
260 int init_use_snoop()
261 {
262 if (g_SIMICS) {
263 // The "snoop interface" defined by simics allows ruby to see store
264 // data values (from simics). If DATA_BLOCK is defined, we are tracking
265 // data, so we need to install the snoop interface.
266 return ((DATA_BLOCK == true) || (XACT_MEMORY));
267 } else {
268 return (0);
269 }
270 }
271
272 void destroy_simulator()
273 {
274 cout << "Deleting system..." << endl;
275 delete g_system_ptr;
276 cout << "Deleting system done" << endl;
277
278 cout << "Deleting event queue..." << endl;
279 delete g_eventQueue_ptr;
280 cout << "Deleting event queue done" << endl;
281
282 delete g_debug_ptr;
283 }
284
285 /*-------------------------------------------------------------------------+
286 | DG: These are the external load and unload hooks that will be called by |
287 | M5 in phase 1 integration, and possibly afterwards, too. |
288 +-------------------------------------------------------------------------*/
289
290 extern "C"
291 int OnLoadRuby() {
292 init_variables();
293 return 0;
294 }
295
296 extern "C"
297 int OnInitRuby() {
298 init_simulator();
299 return 0;
300 }
301
302 extern "C"
303 int OnUnloadRuby() {
304 destroy_simulator();
305 return 0;
306 }
307