ruby: get rid of gems_common/util.hh and .cc and use stuff in src/base
[gem5.git] / src / mem / ruby / common / Debug.cc
1 /*
2 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <fstream>
30 #include <stdarg.h>
31
32 #include "base/misc.hh"
33 #include "mem/ruby/common/Debug.hh"
34 #include "mem/ruby/common/Global.hh"
35 #include "mem/ruby/eventqueue/RubyEventQueue.hh"
36
37 using namespace std;
38
39 class Debug;
40 extern Debug* g_debug_ptr;
41 ostream *debug_cout_ptr;
42
43 bool Debug::m_protocol_trace = false;
44 struct DebugComponentData
45 {
46 const char *desc;
47 const char ch;
48 };
49
50 // component character list
51 DebugComponentData debugComponents[] =
52 {
53 {"System", 's' },
54 {"Node", 'N' },
55 {"Queue", 'q' },
56 {"Event Queue", 'e' },
57 {"Network", 'n' },
58 {"Sequencer", 'S' },
59 {"Tester", 't' },
60 {"Generated", 'g' },
61 {"SLICC", 'l' },
62 {"Network Queues", 'Q' },
63 {"Time", 'T' },
64 {"Network Internals", 'i' },
65 {"Store Buffer", 'b' },
66 {"Cache", 'c' },
67 {"Predictor", 'p' },
68 {"Allocator", 'a' },
69 {"Memory", 'M' },
70 };
71
72 extern "C" void changeDebugVerbosity(VerbosityLevel vb);
73 extern "C" void changeDebugFilter(int filter);
74
75 void
76 changeDebugVerbosity(VerbosityLevel vb)
77 {
78 g_debug_ptr->setVerbosity(vb);
79 }
80
81 void
82 changeDebugFilter(int filter)
83 {
84 g_debug_ptr->setFilter(filter);
85 }
86
87 Debug::Debug(const Params *p)
88 : SimObject(p)
89 {
90 clearFilter();
91 debug_cout_ptr = &cout;
92
93 setFilterString(p->filter_string.c_str());
94 setVerbosityString(p->verbosity_string.c_str());
95 setDebugOutputFile(p->output_filename.c_str());
96 m_starting_cycle = p->start_time;
97 m_protocol_trace = p->protocol_trace;
98 g_debug_ptr = this;
99 }
100
101 Debug::~Debug()
102 {
103 }
104
105 void
106 Debug::printVerbosity(ostream& out) const
107 {
108 switch (getVerbosity()) {
109 case No_Verb:
110 out << "verbosity = No_Verb" << endl;
111 break;
112 case Low_Verb:
113 out << "verbosity = Low_Verb" << endl;
114 break;
115 case Med_Verb:
116 out << "verbosity = Med_Verb" << endl;
117 break;
118 case High_Verb:
119 out << "verbosity = High_Verb" << endl;
120 break;
121 default:
122 out << "verbosity = unknown" << endl;
123 }
124 }
125
126 bool
127 Debug::validDebug(int module, PriorityLevel priority)
128 {
129 int local_module = (1 << module);
130 if (m_filter & local_module) {
131 if (g_eventQueue_ptr == NULL ||
132 g_eventQueue_ptr->getTime() >= m_starting_cycle) {
133 switch (m_verbosityLevel) {
134 case No_Verb:
135 return false;
136 case Low_Verb:
137 return (priority == HighPrio);
138 case Med_Verb:
139 return (priority == HighPrio || priority == MedPrio);
140 case High_Verb:
141 return true;
142 }
143 }
144 }
145 return false;
146 }
147
148 void
149 Debug::setDebugTime(Time t)
150 {
151 m_starting_cycle = t;
152 }
153
154 void
155 Debug::setVerbosity(VerbosityLevel vb)
156 {
157 m_verbosityLevel = vb;
158 }
159
160 void
161 Debug::setFilter(int filter)
162 {
163 m_filter = filter;
164 }
165
166 bool
167 Debug::setVerbosityString(const char *verb_str)
168 {
169 string verb = verb_str ? verb_str : "";
170 if (verb == "none") {
171 setVerbosity(No_Verb);
172 } else if (verb == "low") {
173 setVerbosity(Low_Verb);
174 } else if (verb == "med") {
175 setVerbosity(Med_Verb);
176 } else if (verb == "high") {
177 setVerbosity(High_Verb);
178 } else {
179 cerr << "Error: unrecognized verbosity (use none, low, med, high): "
180 << verb << endl;
181 return true; // error
182 }
183 return false; // no error
184 }
185
186 bool
187 Debug::checkFilter(char ch)
188 {
189 for (int i = 0; i < NUMBER_OF_COMPS; i++) {
190 // Look at all components to find a character match
191 if (debugComponents[i].ch == ch) {
192 // We found a match - return no error
193 return false; // no error
194 }
195 }
196 return true; // error
197 }
198
199 bool
200 Debug::checkFilterString(const char *filter_str)
201 {
202 if (filter_str == NULL) {
203 cerr << "Error: unrecognized component filter: NULL" << endl;
204 return true; // error
205 }
206
207 // check for default filter ("none") before reporting RUBY_DEBUG error
208 if (string(filter_str) == "none") {
209 return false; // no error
210 }
211
212 if (RUBY_DEBUG == false) {
213 cerr << "Error: User specified set of debug components, but the "
214 << "RUBY_DEBUG compile-time flag is false." << endl
215 << "Solution: Re-compile with RUBY_DEBUG set to true." << endl;
216 return true; // error
217 }
218
219 if (string(filter_str) == "all") {
220 return false; // no error
221 }
222
223 // scan string checking each character
224 for (unsigned int i = 0; i < strlen(filter_str); i++) {
225 bool unrecognized = checkFilter(filter_str[i]);
226 if (unrecognized == true) {
227 return true; // error
228 }
229 }
230 return false; // no error
231 }
232
233 bool
234 Debug::setFilterString(const char *filter_str)
235 {
236 if (checkFilterString(filter_str)) {
237 return true; // error
238 }
239
240 if (string(filter_str) == "all" ) {
241 allFilter();
242 } else if (string(filter_str) == "none") {
243 clearFilter();
244 } else {
245 // scan string adding to bit mask for each component which is present
246 for (unsigned int i = 0; i < strlen(filter_str); i++) {
247 bool error = addFilter( filter_str[i] );
248 if (error) {
249 return true; // error
250 }
251 }
252 }
253 return false; // no error
254 }
255
256 bool
257 Debug::addFilter(char ch)
258 {
259 for (int i = 0; i < NUMBER_OF_COMPS; i++) {
260 // Look at all components to find a character match
261 if (debugComponents[i].ch == ch) {
262 // We found a match - update the filter bit mask
263 cout << " Debug: Adding to filter: '" << ch << "' ("
264 << debugComponents[i].desc << ")" << endl;
265 m_filter |= (1 << i);
266 return false; // no error
267 }
268 }
269
270 // We didn't find the character
271 cerr << "Error: unrecognized component filter: " << ch << endl;
272 usageInstructions();
273 return true; // error
274 }
275
276 void
277 Debug::clearFilter()
278 {
279 m_filter = 0;
280 }
281
282 void Debug::allFilter()
283 {
284 m_filter = ~0;
285 }
286
287 void
288 Debug::usageInstructions(void)
289 {
290 cerr << "Debug components: " << endl;
291 for (int i = 0; i < NUMBER_OF_COMPS; i++) {
292 cerr << " " << debugComponents[i].ch << ": "
293 << debugComponents[i].desc << endl;
294 }
295 }
296
297 void
298 Debug::print(ostream& out) const
299 {
300 out << "[Debug]" << endl;
301 }
302
303 void
304 Debug::setDebugOutputFile (const char *filename)
305 {
306 if (filename == NULL || !strcmp(filename, "none")) {
307 debug_cout_ptr = &cout;
308 return;
309 }
310
311 if (m_fout.is_open()) {
312 m_fout.close();
313 }
314 m_fout.open(filename, ios::out);
315 if (!m_fout.is_open()) {
316 cerr << "setDebugOutputFile: can't open file " << filename << endl;
317 } else {
318 debug_cout_ptr = &m_fout;
319 }
320 }
321
322 void
323 Debug::closeDebugOutputFile ()
324 {
325 if (m_fout.is_open()) {
326 m_fout.close ();
327 debug_cout_ptr = &cout;
328 }
329 }
330
331 void
332 Debug::debugMsg( const char *fmt, ...)
333 {
334 va_list args;
335
336 // you could check validDebug() here before printing the message
337 va_start(args, fmt);
338 vfprintf(stdout, fmt, args);
339 va_end(args);
340 }
341
342 Debug *
343 RubyDebugParams::create()
344 {
345 return new Debug(this);
346 }