gem5/src/mem/ruby/common/Debug.cc
Nilay Vaish 658849d101 ruby: Converted old ruby debug calls to M5 debug calls
This patch developed by Nilay Vaish converts all the old GEMS-style ruby
debug calls to the appropriate M5 debug calls.
2010-12-01 11:30:04 -08:00

338 lines
8.3 KiB
C++

/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <fstream>
#include <stdarg.h>
#include "base/misc.hh"
#include "mem/ruby/common/Debug.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
using namespace std;
class Debug;
extern Debug* g_debug_ptr;
ostream *debug_cout_ptr;
bool Debug::m_protocol_trace = false;
struct DebugComponentData
{
const char *desc;
const char ch;
};
// component character list
DebugComponentData debugComponents[] =
{
{"System", 's' },
{"Node", 'N' },
{"Queue", 'q' },
{"Event Queue", 'e' },
{"Network", 'n' },
{"Sequencer", 'S' },
{"Tester", 't' },
{"Generated", 'g' },
{"SLICC", 'l' },
{"Network Queues", 'Q' },
{"Time", 'T' },
{"Network Internals", 'i' },
{"Store Buffer", 'b' },
{"Cache", 'c' },
{"Predictor", 'p' },
{"Memory", 'M' },
};
extern "C" void changeDebugVerbosity(VerbosityLevel vb);
extern "C" void changeDebugFilter(int filter);
void
changeDebugVerbosity(VerbosityLevel vb)
{
g_debug_ptr->setVerbosity(vb);
}
void
changeDebugFilter(int filter)
{
g_debug_ptr->setFilter(filter);
}
Debug::Debug(const Params *p)
: SimObject(p)
{
clearFilter();
debug_cout_ptr = &cout;
setFilterString(p->filter_string.c_str());
setVerbosityString(p->verbosity_string.c_str());
setDebugOutputFile(p->output_filename.c_str());
m_starting_cycle = p->start_time;
m_protocol_trace = p->protocol_trace;
g_debug_ptr = this;
}
Debug::~Debug()
{
}
void
Debug::printVerbosity(ostream& out) const
{
switch (getVerbosity()) {
case No_Verb:
out << "verbosity = No_Verb" << endl;
break;
case Low_Verb:
out << "verbosity = Low_Verb" << endl;
break;
case Med_Verb:
out << "verbosity = Med_Verb" << endl;
break;
case High_Verb:
out << "verbosity = High_Verb" << endl;
break;
default:
out << "verbosity = unknown" << endl;
}
}
bool
Debug::validDebug(int module, PriorityLevel priority)
{
int local_module = (1 << module);
if (m_filter & local_module) {
if (g_eventQueue_ptr == NULL ||
g_eventQueue_ptr->getTime() >= m_starting_cycle) {
switch (m_verbosityLevel) {
case No_Verb:
return false;
case Low_Verb:
return (priority == HighPrio);
case Med_Verb:
return (priority == HighPrio || priority == MedPrio);
case High_Verb:
return true;
}
}
}
return false;
}
void
Debug::setDebugTime(Time t)
{
m_starting_cycle = t;
}
void
Debug::setVerbosity(VerbosityLevel vb)
{
m_verbosityLevel = vb;
}
void
Debug::setFilter(int filter)
{
m_filter = filter;
}
bool
Debug::setVerbosityString(const char *verb_str)
{
string verb = verb_str ? verb_str : "";
if (verb == "none") {
setVerbosity(No_Verb);
} else if (verb == "low") {
setVerbosity(Low_Verb);
} else if (verb == "med") {
setVerbosity(Med_Verb);
} else if (verb == "high") {
setVerbosity(High_Verb);
} else {
cerr << "Error: unrecognized verbosity (use none, low, med, high): "
<< verb << endl;
return true; // error
}
return false; // no error
}
bool
Debug::checkFilter(char ch)
{
for (int i = 0; i < NUMBER_OF_COMPS; i++) {
// Look at all components to find a character match
if (debugComponents[i].ch == ch) {
// We found a match - return no error
return false; // no error
}
}
return true; // error
}
bool
Debug::checkFilterString(const char *filter_str)
{
if (filter_str == NULL) {
cerr << "Error: unrecognized component filter: NULL" << endl;
return true; // error
}
// check for default filter ("none") before reporting RUBY_DEBUG error
if (string(filter_str) == "none") {
return false; // no error
}
if (string(filter_str) == "all") {
return false; // no error
}
// scan string checking each character
for (unsigned int i = 0; i < strlen(filter_str); i++) {
bool unrecognized = checkFilter(filter_str[i]);
if (unrecognized == true) {
return true; // error
}
}
return false; // no error
}
bool
Debug::setFilterString(const char *filter_str)
{
if (checkFilterString(filter_str)) {
return true; // error
}
if (string(filter_str) == "all" ) {
allFilter();
} else if (string(filter_str) == "none") {
clearFilter();
} else {
// scan string adding to bit mask for each component which is present
for (unsigned int i = 0; i < strlen(filter_str); i++) {
bool error = addFilter( filter_str[i] );
if (error) {
return true; // error
}
}
}
return false; // no error
}
bool
Debug::addFilter(char ch)
{
for (int i = 0; i < NUMBER_OF_COMPS; i++) {
// Look at all components to find a character match
if (debugComponents[i].ch == ch) {
// We found a match - update the filter bit mask
cout << " Debug: Adding to filter: '" << ch << "' ("
<< debugComponents[i].desc << ")" << endl;
m_filter |= (1 << i);
return false; // no error
}
}
// We didn't find the character
cerr << "Error: unrecognized component filter: " << ch << endl;
usageInstructions();
return true; // error
}
void
Debug::clearFilter()
{
m_filter = 0;
}
void Debug::allFilter()
{
m_filter = ~0;
}
void
Debug::usageInstructions(void)
{
cerr << "Debug components: " << endl;
for (int i = 0; i < NUMBER_OF_COMPS; i++) {
cerr << " " << debugComponents[i].ch << ": "
<< debugComponents[i].desc << endl;
}
}
void
Debug::print(ostream& out) const
{
out << "[Debug]" << endl;
}
void
Debug::setDebugOutputFile (const char *filename)
{
if (filename == NULL || !strcmp(filename, "none")) {
debug_cout_ptr = &cout;
return;
}
if (m_fout.is_open()) {
m_fout.close();
}
m_fout.open(filename, ios::out);
if (!m_fout.is_open()) {
cerr << "setDebugOutputFile: can't open file " << filename << endl;
} else {
debug_cout_ptr = &m_fout;
}
}
void
Debug::closeDebugOutputFile ()
{
if (m_fout.is_open()) {
m_fout.close ();
debug_cout_ptr = &cout;
}
}
void
Debug::debugMsg( const char *fmt, ...)
{
va_list args;
// you could check validDebug() here before printing the message
va_start(args, fmt);
vfprintf(stdout, fmt, args);
va_end(args);
}
Debug *
RubyDebugParams::create()
{
return new Debug(this);
}