CPA: Add new object for gathering critical path annotations.
This commit is contained in:
parent
d5ef9ee06b
commit
6fd4bc34a1
13 changed files with 2015 additions and 202 deletions
|
@ -689,6 +689,7 @@ sticky_vars.AddVariables(
|
||||||
BoolVariable('USE_MYSQL', 'Use MySQL for stats output', have_mysql),
|
BoolVariable('USE_MYSQL', 'Use MySQL for stats output', have_mysql),
|
||||||
BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
|
BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
|
||||||
BoolVariable('USE_CHECKER', 'Use checker for detailed CPU models', False),
|
BoolVariable('USE_CHECKER', 'Use checker for detailed CPU models', False),
|
||||||
|
BoolVariable('CP_ANNOTATE', 'Enable critical path annotation capability', False),
|
||||||
)
|
)
|
||||||
|
|
||||||
nonsticky_vars.AddVariables(
|
nonsticky_vars.AddVariables(
|
||||||
|
@ -699,7 +700,7 @@ nonsticky_vars.AddVariables(
|
||||||
env.ExportVariables = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \
|
env.ExportVariables = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \
|
||||||
'USE_MYSQL', 'NO_FAST_ALLOC', 'FAST_ALLOC_DEBUG', \
|
'USE_MYSQL', 'NO_FAST_ALLOC', 'FAST_ALLOC_DEBUG', \
|
||||||
'FAST_ALLOC_STATS', 'SS_COMPATIBLE_FP', \
|
'FAST_ALLOC_STATS', 'SS_COMPATIBLE_FP', \
|
||||||
'USE_CHECKER', 'TARGET_ISA']
|
'USE_CHECKER', 'TARGET_ISA', 'CP_ANNOTATE']
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
#
|
#
|
||||||
|
|
|
@ -870,9 +870,62 @@ decode OPCODE default Unknown::unknown() {
|
||||||
0x54: m5panic({{
|
0x54: m5panic({{
|
||||||
panic("M5 panic instruction called at pc=%#x.", xc->readPC());
|
panic("M5 panic instruction called at pc=%#x.", xc->readPC());
|
||||||
}}, IsNonSpeculative);
|
}}, IsNonSpeculative);
|
||||||
0x55: m5reserved1({{
|
#define CPANN(lbl) CPA::cpa()->lbl(xc->tcBase())
|
||||||
warn("M5 reserved opcode ignored");
|
0x55: decode RA {
|
||||||
}}, IsNonSpeculative);
|
0x00: m5a_old({{
|
||||||
|
panic("Deprecated M5 annotate instruction executed at pc=%#x\n",
|
||||||
|
xc->readPC());
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x01: m5a_bsm({{
|
||||||
|
CPANN(swSmBegin);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x02: m5a_esm({{
|
||||||
|
CPANN(swSmEnd);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x03: m5a_begin({{
|
||||||
|
CPANN(swExplictBegin);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x04: m5a_end({{
|
||||||
|
CPANN(swEnd);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x06: m5a_q({{
|
||||||
|
CPANN(swQ);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x07: m5a_dq({{
|
||||||
|
CPANN(swDq);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x08: m5a_wf({{
|
||||||
|
CPANN(swWf);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x09: m5a_we({{
|
||||||
|
CPANN(swWe);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x0C: m5a_sq({{
|
||||||
|
CPANN(swSq);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x0D: m5a_aq({{
|
||||||
|
CPANN(swAq);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x0E: m5a_pq({{
|
||||||
|
CPANN(swPq);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x0F: m5a_l({{
|
||||||
|
CPANN(swLink);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x10: m5a_identify({{
|
||||||
|
CPANN(swIdentify);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x11: m5a_getid({{
|
||||||
|
R0 = CPANN(swGetId);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x13: m5a_scl({{
|
||||||
|
CPANN(swSyscallLink);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
0x14: m5a_rq({{
|
||||||
|
CPANN(swRq);
|
||||||
|
}}, IsNonSpeculative);
|
||||||
|
} // M5 Annotate Operations
|
||||||
|
#undef CPANN
|
||||||
0x56: m5reserved2({{
|
0x56: m5reserved2({{
|
||||||
warn("M5 reserved opcode ignored");
|
warn("M5 reserved opcode ignored");
|
||||||
}}, IsNonSpeculative);
|
}}, IsNonSpeculative);
|
||||||
|
|
|
@ -68,6 +68,7 @@ using namespace AlphaISA;
|
||||||
output exec {{
|
output exec {{
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "base/cp_annotate.hh"
|
||||||
#include "sim/pseudo_inst.hh"
|
#include "sim/pseudo_inst.hh"
|
||||||
#include "arch/alpha/ipr.hh"
|
#include "arch/alpha/ipr.hh"
|
||||||
#include "base/fenv.hh"
|
#include "base/fenv.hh"
|
||||||
|
|
8
src/base/CPA.py
Normal file
8
src/base/CPA.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
from m5.SimObject import SimObject
|
||||||
|
from m5.params import *
|
||||||
|
|
||||||
|
class CPA(SimObject):
|
||||||
|
type = 'CPA'
|
||||||
|
|
||||||
|
enabled = Param.Bool(False, "Is Annotation enabled?")
|
||||||
|
user_apps = VectorParam.String([], "List of apps to get symbols for")
|
|
@ -30,7 +30,9 @@
|
||||||
|
|
||||||
Import('*')
|
Import('*')
|
||||||
|
|
||||||
Source('annotate.cc')
|
if env['CP_ANNOTATE']:
|
||||||
|
SimObject('CPA.py')
|
||||||
|
Source('cp_annotate.cc')
|
||||||
Source('atomicio.cc')
|
Source('atomicio.cc')
|
||||||
Source('bigint.cc')
|
Source('bigint.cc')
|
||||||
Source('circlebuf.cc')
|
Source('circlebuf.cc')
|
||||||
|
@ -82,6 +84,8 @@ if env['USE_MYSQL']:
|
||||||
Source('stats/mysql.cc')
|
Source('stats/mysql.cc')
|
||||||
|
|
||||||
TraceFlag('Annotate', "State machine annotation debugging")
|
TraceFlag('Annotate', "State machine annotation debugging")
|
||||||
|
TraceFlag('AnnotateQ', "State machine annotation queue debugging")
|
||||||
|
TraceFlag('AnnotateVerbose', "Dump all state machine annotation details")
|
||||||
TraceFlag('GDBAcc', "Remote debugger accesses")
|
TraceFlag('GDBAcc', "Remote debugger accesses")
|
||||||
TraceFlag('GDBExtra', "Dump extra information on reads and writes")
|
TraceFlag('GDBExtra', "Dump extra information on reads and writes")
|
||||||
TraceFlag('GDBMisc', "Breakpoints, traps, watchpoints, etc.")
|
TraceFlag('GDBMisc', "Breakpoints, traps, watchpoints, etc.")
|
||||||
|
@ -96,3 +100,6 @@ CompoundFlag('GDBAll',
|
||||||
[ 'GDBMisc', 'GDBAcc', 'GDBRead', 'GDBWrite', 'GDBSend', 'GDBRecv',
|
[ 'GDBMisc', 'GDBAcc', 'GDBRead', 'GDBWrite', 'GDBSend', 'GDBRecv',
|
||||||
'GDBExtra' ],
|
'GDBExtra' ],
|
||||||
desc="All Remote debugging flags")
|
desc="All Remote debugging flags")
|
||||||
|
CompoundFlag('AnnotateAll', ['Annotate', 'AnnotateQ', 'AnnotateVerbose'],
|
||||||
|
desc="All Annotation flags")
|
||||||
|
|
||||||
|
|
|
@ -1,122 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2006 The Regents of The University of Michigan
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Authors: Ali Saidi
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "base/annotate.hh"
|
|
||||||
#include "base/callback.hh"
|
|
||||||
#include "base/output.hh"
|
|
||||||
#include "base/trace.hh"
|
|
||||||
#include "sim/core.hh"
|
|
||||||
#include "sim/sim_exit.hh"
|
|
||||||
#include "sim/system.hh"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AnnotateDumpCallback : public Callback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void process();
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
AnnotateDumpCallback::process()
|
|
||||||
{
|
|
||||||
Annotate::annotations.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Annotate {
|
|
||||||
|
|
||||||
|
|
||||||
Annotate annotations;
|
|
||||||
|
|
||||||
Annotate::Annotate()
|
|
||||||
{
|
|
||||||
registerExitCallback(new AnnotateDumpCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Annotate::add(System *sys, Addr stack, uint32_t sm, uint32_t st,
|
|
||||||
uint32_t wm, uint32_t ws)
|
|
||||||
{
|
|
||||||
AnnotateData *an;
|
|
||||||
|
|
||||||
an = new AnnotateData;
|
|
||||||
an->time = curTick;
|
|
||||||
|
|
||||||
std::map<System*, std::string>::iterator i = nameCache.find(sys);
|
|
||||||
if (i == nameCache.end()) {
|
|
||||||
nameCache[sys] = sys->name();
|
|
||||||
}
|
|
||||||
|
|
||||||
an->system = nameCache[sys];
|
|
||||||
an->stack = stack;
|
|
||||||
an->stateMachine = sm;
|
|
||||||
an->curState = st;
|
|
||||||
an->waitMachine = wm;
|
|
||||||
an->waitState = ws;
|
|
||||||
|
|
||||||
data.push_back(an);
|
|
||||||
if (an->waitMachine)
|
|
||||||
DPRINTF(Annotate, "Annotating: %s(%#llX) %d:%d waiting on %d:%d\n",
|
|
||||||
an->system, an->stack, an->stateMachine, an->curState,
|
|
||||||
an->waitMachine, an->waitState);
|
|
||||||
else
|
|
||||||
DPRINTF(Annotate, "Annotating: %s(%#llX) %d:%d beginning\n", an->system,
|
|
||||||
an->stack, an->stateMachine, an->curState);
|
|
||||||
|
|
||||||
DPRINTF(Annotate, "Now %d events on list\n", data.size());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Annotate::dump()
|
|
||||||
{
|
|
||||||
|
|
||||||
std::list<AnnotateData*>::iterator i;
|
|
||||||
|
|
||||||
i = data.begin();
|
|
||||||
|
|
||||||
if (i == data.end())
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::ostream *os = simout.create("annotate.dat");
|
|
||||||
|
|
||||||
AnnotateData *an;
|
|
||||||
|
|
||||||
while (i != data.end()) {
|
|
||||||
DPRINTF(Annotate, "Writing\n", data.size());
|
|
||||||
an = *i;
|
|
||||||
ccprintf(*os, "%d %s(%#llX) %d %d %d %d\n", an->time, an->system,
|
|
||||||
an->stack, an->stateMachine, an->curState, an->waitMachine,
|
|
||||||
an->waitState);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} //namespace Annotate
|
|
|
@ -1,73 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2006 The Regents of The University of Michigan
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Authors: Ali Saidi
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __BASE__ANNOTATE_HH__
|
|
||||||
#define __BASE__ANNOTATE_HH__
|
|
||||||
|
|
||||||
#include "sim/host.hh"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <list>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
|
|
||||||
class System;
|
|
||||||
|
|
||||||
namespace Annotate {
|
|
||||||
|
|
||||||
|
|
||||||
class Annotate {
|
|
||||||
|
|
||||||
protected:
|
|
||||||
struct AnnotateData {
|
|
||||||
Tick time;
|
|
||||||
std::string system;
|
|
||||||
Addr stack;
|
|
||||||
uint32_t stateMachine;
|
|
||||||
uint32_t curState;
|
|
||||||
uint32_t waitMachine;
|
|
||||||
uint32_t waitState;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::list<AnnotateData*> data;
|
|
||||||
std::map<System*, std::string> nameCache;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Annotate();
|
|
||||||
void add(System *sys, Addr stack, uint32_t sm, uint32_t st, uint32_t
|
|
||||||
wm, uint32_t ws);
|
|
||||||
void dump();
|
|
||||||
};
|
|
||||||
|
|
||||||
extern Annotate annotations;
|
|
||||||
} //namespace Annotate
|
|
||||||
|
|
||||||
#endif //__BASE__ANNOTATE_HH__
|
|
||||||
|
|
1404
src/base/cp_annotate.cc
Normal file
1404
src/base/cp_annotate.cc
Normal file
File diff suppressed because it is too large
Load diff
522
src/base/cp_annotate.hh
Normal file
522
src/base/cp_annotate.hh
Normal file
|
@ -0,0 +1,522 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2009 The Regents of The University of Michigan
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Authors: Ali Saidi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __BASE__CP_ANNOTATE_HH__
|
||||||
|
#define __BASE__CP_ANNOTATE_HH__
|
||||||
|
|
||||||
|
#include "base/loader/symtab.hh"
|
||||||
|
#include "config/cp_annotate.hh"
|
||||||
|
#include "sim/host.hh"
|
||||||
|
#include "sim/serialize.hh"
|
||||||
|
#include "sim/startup.hh"
|
||||||
|
#include "sim/system.hh"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include "base/hashmap.hh"
|
||||||
|
#include "base/trace.hh"
|
||||||
|
#if CP_ANNOTATE
|
||||||
|
#include "params/CPA.hh"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class System;
|
||||||
|
class ThreadContext;
|
||||||
|
|
||||||
|
|
||||||
|
#if !CP_ANNOTATE
|
||||||
|
class CPA : SimObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum flags {
|
||||||
|
FL_NONE = 0x00,
|
||||||
|
FL_HW = 0x01,
|
||||||
|
FL_BAD = 0x02,
|
||||||
|
FL_QOPP = 0x04,
|
||||||
|
FL_WAIT = 0x08,
|
||||||
|
FL_LINK = 0x10,
|
||||||
|
FL_RESET = 0x20
|
||||||
|
};
|
||||||
|
|
||||||
|
static CPA *cpa() { return NULL; }
|
||||||
|
static bool available() { return false; }
|
||||||
|
bool enabled() { return false; }
|
||||||
|
void swSmBegin(ThreadContext *tc) { return; }
|
||||||
|
void swSmEnd(ThreadContext *tc) { return; }
|
||||||
|
void swExplictBegin(ThreadContext *tc) { return; }
|
||||||
|
void swAutoBegin(ThreadContext *tc, Addr next_pc) { return; }
|
||||||
|
void swEnd(ThreadContext *tc) { return; }
|
||||||
|
void swQ(ThreadContext *tc) { return; }
|
||||||
|
void swDq(ThreadContext *tc) { return; }
|
||||||
|
void swPq(ThreadContext *tc) { return; }
|
||||||
|
void swRq(ThreadContext *tc) { return; }
|
||||||
|
void swWf(ThreadContext *tc) { return; }
|
||||||
|
void swWe(ThreadContext *tc) { return; }
|
||||||
|
void swSq(ThreadContext *tc) { return; }
|
||||||
|
void swAq(ThreadContext *tc) { return; }
|
||||||
|
void swLink(ThreadContext *tc) { return; }
|
||||||
|
void swIdentify(ThreadContext *tc) { return; }
|
||||||
|
uint64_t swGetId(ThreadContext *tc) { return 0; }
|
||||||
|
void swSyscallLink(ThreadContext *tc) { return; }
|
||||||
|
void hwBegin(flags f, System *sys, uint64_t frame, std::string sm,
|
||||||
|
std::string st) { return; }
|
||||||
|
void hwQ(flags f, System *sys, uint64_t frame, std::string sm,
|
||||||
|
std::string q, uint64_t qid, System *q_sys = NULL,
|
||||||
|
int32_t count = 1) { return; }
|
||||||
|
void hwDq(flags f, System *sys, uint64_t frame, std::string sm,
|
||||||
|
std::string q, uint64_t qid, System *q_sys = NULL,
|
||||||
|
int32_t count = 1) { return; }
|
||||||
|
void hwPq(flags f, System *sys, uint64_t frame, std::string sm,
|
||||||
|
std::string q, uint64_t qid, System *q_sys = NULL,
|
||||||
|
int32_t count = 1) { return; }
|
||||||
|
void hwRq(flags f, System *sys, uint64_t frame, std::string sm,
|
||||||
|
std::string q, uint64_t qid, System *q_sys = NULL,
|
||||||
|
int32_t count = 1) { return; }
|
||||||
|
void hwWf(flags f, System *sys, uint64_t frame, std::string sm,
|
||||||
|
std::string q, uint64_t qid, System *q_sys = NULL,
|
||||||
|
int32_t count = 1) { return; }
|
||||||
|
void hwWe(flags f, System *sys, uint64_t frame, std::string sm,
|
||||||
|
std::string q, uint64_t qid, System *q_sys = NULL,
|
||||||
|
int32_t count = 1) { return; }
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
class CPA : SimObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef CPAParams Params;
|
||||||
|
|
||||||
|
/** The known operations that are written to the annotation output file. */
|
||||||
|
enum ops {
|
||||||
|
OP_BEGIN = 0x01,
|
||||||
|
OP_WAIT_EMPTY = 0x02,
|
||||||
|
OP_WAIT_FULL = 0x03,
|
||||||
|
OP_QUEUE = 0x04,
|
||||||
|
OP_DEQUEUE = 0x05,
|
||||||
|
OP_SIZE_QUEUE = 0x08,
|
||||||
|
OP_PEEK = 0x09,
|
||||||
|
OP_LINK = 0x0A,
|
||||||
|
OP_IDENT = 0x0B,
|
||||||
|
OP_RESERVE = 0x0C
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Flags for the various options.*/
|
||||||
|
enum flags {
|
||||||
|
/* no flags */
|
||||||
|
FL_NONE = 0x00,
|
||||||
|
/* operation was done on hardware */
|
||||||
|
FL_HW = 0x01,
|
||||||
|
/* operation should cause a warning when encountered */
|
||||||
|
FL_BAD = 0x02,
|
||||||
|
/* Queue like a stack, not a queue */
|
||||||
|
FL_QOPP = 0x04,
|
||||||
|
/* Mark HW state as waiting for some non-resource constraint
|
||||||
|
* (e.g. wait because SM only starts after 10 items are queued) */
|
||||||
|
FL_WAIT = 0x08,
|
||||||
|
/* operation is linking to another state machine */
|
||||||
|
FL_LINK = 0x10,
|
||||||
|
/* queue should be completely cleared/reset before executing this
|
||||||
|
* operation */
|
||||||
|
FL_RESET = 0x20
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const Params *
|
||||||
|
params() const
|
||||||
|
{
|
||||||
|
return dynamic_cast<const Params *>(_params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* struct that is written to the annotation output file */
|
||||||
|
struct AnnotateData : public RefCounted {
|
||||||
|
|
||||||
|
Tick time;
|
||||||
|
uint32_t data;
|
||||||
|
uint32_t orig_data;
|
||||||
|
uint16_t sm;
|
||||||
|
uint16_t stq;
|
||||||
|
uint8_t op;
|
||||||
|
uint8_t flag;
|
||||||
|
uint8_t cpu;
|
||||||
|
bool dump;
|
||||||
|
|
||||||
|
void serialize(std::ostream &os);
|
||||||
|
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef RefCountingPtr<AnnotateData> AnnDataPtr;
|
||||||
|
|
||||||
|
/* header for the annotation file */
|
||||||
|
struct AnnotateHeader {
|
||||||
|
uint64_t version;
|
||||||
|
uint64_t num_recs;
|
||||||
|
uint64_t key_off;
|
||||||
|
uint64_t idx_off;
|
||||||
|
uint32_t key_len;
|
||||||
|
uint32_t idx_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
AnnotateHeader ah;
|
||||||
|
|
||||||
|
std::vector<uint64_t> annotateIdx;
|
||||||
|
|
||||||
|
// number of state machines encountered in the simulation
|
||||||
|
int numSm;
|
||||||
|
// number of states encountered in the simulation
|
||||||
|
int numSmt;
|
||||||
|
// number of states/queues for a given state machine/system respectively
|
||||||
|
std::vector<int> numSt, numQ;
|
||||||
|
// number of systems in the simulation
|
||||||
|
int numSys;
|
||||||
|
// number of queues in the state machine
|
||||||
|
int numQs;
|
||||||
|
// maximum connection id assigned so far
|
||||||
|
uint64_t conId;
|
||||||
|
|
||||||
|
// Convert state strings into state ids
|
||||||
|
typedef m5::hash_map<std::string, int> SCache;
|
||||||
|
typedef std::vector<SCache> StCache;
|
||||||
|
|
||||||
|
// Convert sm and queue name,id into queue id
|
||||||
|
typedef std::pair<std::string, uint64_t> Id;
|
||||||
|
typedef m5::hash_map<Id, int> IdHCache;
|
||||||
|
typedef std::vector<IdHCache> IdCache;
|
||||||
|
|
||||||
|
// Hold mapping of sm and queues to output python
|
||||||
|
typedef std::vector<std::pair<int, Id> > IdMap;
|
||||||
|
|
||||||
|
// System pointer to name,id
|
||||||
|
typedef std::map<System*, std::pair<std::string, int> > NameCache;
|
||||||
|
|
||||||
|
// array of systems each of which is a stack of running sm
|
||||||
|
typedef std::pair<int, uint64_t> StackId;
|
||||||
|
typedef std::map<StackId, std::vector<int> > SmStack;
|
||||||
|
|
||||||
|
// map of each context and if it's currently in explict state mode
|
||||||
|
// states are not automatically updated until it leaves
|
||||||
|
typedef std::map<StackId, bool> SwExpl;
|
||||||
|
|
||||||
|
typedef std::map<int,int> IMap;
|
||||||
|
// List of annotate records have not been written/completed yet
|
||||||
|
typedef std::list<AnnDataPtr> AnnotateList;
|
||||||
|
|
||||||
|
// Maintain link state information
|
||||||
|
typedef std::map<int, int> LinkMap;
|
||||||
|
|
||||||
|
// SC Links
|
||||||
|
typedef m5::hash_map<Id, AnnDataPtr> ScHCache;
|
||||||
|
typedef std::vector<ScHCache> ScCache;
|
||||||
|
|
||||||
|
|
||||||
|
AnnotateList data;
|
||||||
|
|
||||||
|
// vector indexed by queueid to find current number of elements and bytes
|
||||||
|
std::vector<int> qSize;
|
||||||
|
std::vector<int32_t> qBytes;
|
||||||
|
|
||||||
|
|
||||||
|
// Turn state machine string into state machine id (small int)
|
||||||
|
// Used for outputting key to convert id back into string
|
||||||
|
SCache smtCache;
|
||||||
|
// Turn state machine id, state name into state id (small int)
|
||||||
|
StCache stCache;
|
||||||
|
// turn system, queue, and queue identify into qid (small int)
|
||||||
|
// turn system, state, and context into state machine id (small int)
|
||||||
|
IdCache qCache, smCache;
|
||||||
|
//Link state machines accross system calls
|
||||||
|
ScCache scLinks;
|
||||||
|
// System pointer to name,id
|
||||||
|
NameCache nameCache;
|
||||||
|
// Stack of state machines currently nested (should unwind correctly)
|
||||||
|
SmStack smStack;
|
||||||
|
// Map of currently outstanding links
|
||||||
|
LinkMap lnMap;
|
||||||
|
// If the state machine is currently exculding automatic changes
|
||||||
|
SwExpl swExpl;
|
||||||
|
// Last state that a given state machine was in
|
||||||
|
IMap lastState;
|
||||||
|
// Hold mapping of sm and queues to output python
|
||||||
|
IdMap smMap, qMap;
|
||||||
|
// Items still in queue, used for sanity checking
|
||||||
|
std::vector<AnnotateList> qData;
|
||||||
|
|
||||||
|
void doDq(System *sys, int flags, int cpu, int sm, std::string q, int qi,
|
||||||
|
int count);
|
||||||
|
void doQ(System *sys, int flags, int cpu, int sm, std::string q, int qi,
|
||||||
|
int count);
|
||||||
|
|
||||||
|
void doSwSmEnd(System *sys, int cpuid, std::string sm, uint64_t frame);
|
||||||
|
|
||||||
|
// Turn a system id, state machine string, state machine id into a small int
|
||||||
|
// for annotation output
|
||||||
|
int
|
||||||
|
getSm(int sysi, std::string si, uint64_t id)
|
||||||
|
{
|
||||||
|
int smi;
|
||||||
|
Id smid = Id(si, id);
|
||||||
|
|
||||||
|
smi = smCache[sysi-1][smid];
|
||||||
|
if (smi == 0) {
|
||||||
|
smCache[sysi-1][smid] = smi = ++numSm;
|
||||||
|
assert(smi < 65535);
|
||||||
|
smMap.push_back(std::make_pair<int, Id>(sysi, smid));
|
||||||
|
}
|
||||||
|
return smi;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn a state machine string, state string into a small int
|
||||||
|
// for annotation output
|
||||||
|
int
|
||||||
|
getSt(std::string sm, std::string s)
|
||||||
|
{
|
||||||
|
int sti, smi;
|
||||||
|
|
||||||
|
smi = smtCache[sm];
|
||||||
|
if (smi == 0)
|
||||||
|
smi = smtCache[sm] = ++numSmt;
|
||||||
|
|
||||||
|
while (stCache.size() < smi) {
|
||||||
|
//stCache.resize(sm);
|
||||||
|
stCache.push_back(SCache());
|
||||||
|
numSt.push_back(0);
|
||||||
|
}
|
||||||
|
//assert(stCache.size() == sm);
|
||||||
|
//assert(numSt.size() == sm);
|
||||||
|
sti = stCache[smi-1][s];
|
||||||
|
if (sti == 0)
|
||||||
|
stCache[smi-1][s] = sti = ++numSt[smi-1];
|
||||||
|
return sti;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn state machine pointer into a smal int for annotation output
|
||||||
|
int
|
||||||
|
getSys(System *s)
|
||||||
|
{
|
||||||
|
NameCache::iterator i = nameCache.find(s);
|
||||||
|
if (i == nameCache.end()) {
|
||||||
|
nameCache[s] = std::make_pair<std::string,int>(s->name(), ++numSys);
|
||||||
|
i = nameCache.find(s);
|
||||||
|
// might need to put smstackid into map here, but perhaps not
|
||||||
|
//smStack.push_back(std::vector<int>());
|
||||||
|
//swExpl.push_back(false);
|
||||||
|
numQ.push_back(0);
|
||||||
|
qCache.push_back(IdHCache());
|
||||||
|
smCache.push_back(IdHCache());
|
||||||
|
scLinks.push_back(ScHCache());
|
||||||
|
}
|
||||||
|
return i->second.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn queue name, and queue context into small int for
|
||||||
|
// annotation output
|
||||||
|
int
|
||||||
|
getQ(int sys, std::string q, uint64_t id)
|
||||||
|
{
|
||||||
|
int qi;
|
||||||
|
Id qid = Id(q, id);
|
||||||
|
|
||||||
|
qi = qCache[sys-1][qid];
|
||||||
|
if (qi == 0) {
|
||||||
|
qi = qCache[sys-1][qid] = ++numQs;
|
||||||
|
assert(qi < 65535);
|
||||||
|
qSize.push_back(0);
|
||||||
|
qBytes.push_back(0);
|
||||||
|
qData.push_back(AnnotateList());
|
||||||
|
numQ[sys-1]++;
|
||||||
|
qMap.push_back(std::make_pair<int, Id>(sys, qid));
|
||||||
|
}
|
||||||
|
return qi;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swBegin(System *sys, int cpuid, std::string st, uint64_t frame,
|
||||||
|
bool expl = false, int flags = FL_NONE);
|
||||||
|
|
||||||
|
AnnDataPtr add(int t, int f, int c, int sm, int stq, int32_t data=0);
|
||||||
|
|
||||||
|
std::ostream *osbin;
|
||||||
|
|
||||||
|
bool _enabled;
|
||||||
|
|
||||||
|
/** Only allow one CPA object in a system. It doesn't make sense to have
|
||||||
|
* more that one per simulation because if a part of the system was
|
||||||
|
* important it would have annotations and queues, and with more than one
|
||||||
|
* object none of the sanity checking for queues will work. */
|
||||||
|
static bool exists;
|
||||||
|
static CPA *_cpa;
|
||||||
|
|
||||||
|
|
||||||
|
std::map<std::string, SymbolTable*> userApp;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static CPA *cpa() { return _cpa; }
|
||||||
|
void swSmBegin(ThreadContext *tc);
|
||||||
|
void swSmEnd(ThreadContext *tc);
|
||||||
|
void swExplictBegin(ThreadContext *tc);
|
||||||
|
void swAutoBegin(ThreadContext *tc, Addr next_pc);
|
||||||
|
void swEnd(ThreadContext *tc);
|
||||||
|
void swQ(ThreadContext *tc);
|
||||||
|
void swDq(ThreadContext *tc);
|
||||||
|
void swPq(ThreadContext *tc);
|
||||||
|
void swRq(ThreadContext *tc);
|
||||||
|
void swWf(ThreadContext *tc);
|
||||||
|
void swWe(ThreadContext *tc);
|
||||||
|
void swSq(ThreadContext *tc);
|
||||||
|
void swAq(ThreadContext *tc);
|
||||||
|
void swLink(ThreadContext *tc);
|
||||||
|
void swIdentify(ThreadContext *tc);
|
||||||
|
uint64_t swGetId(ThreadContext *tc);
|
||||||
|
void swSyscallLink(ThreadContext *tc);
|
||||||
|
|
||||||
|
inline void hwBegin(flags f, System *sys, uint64_t frame, std::string sm,
|
||||||
|
std::string st)
|
||||||
|
{
|
||||||
|
if (!enabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int sysi = getSys(sys);
|
||||||
|
int smi = getSm(sysi, sm, frame);
|
||||||
|
add(OP_BEGIN, FL_HW | f, 0, smi, getSt(sm, st));
|
||||||
|
if (f & FL_BAD)
|
||||||
|
warn("BAD state encountered: at cycle %d: %s\n", curTick, st);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void hwQ(flags f, System *sys, uint64_t frame, std::string sm,
|
||||||
|
std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
|
||||||
|
{
|
||||||
|
if (!enabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int sysi = getSys(sys);
|
||||||
|
int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid);
|
||||||
|
DPRINTFS(AnnotateQ, sys,
|
||||||
|
"hwQ: %s[%#x] cur size %d %d bytes: %d adding: %d\n",
|
||||||
|
q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
|
||||||
|
doQ(sys, FL_HW | f, 0, getSm(sysi, sm, frame), q, qi, count);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void hwDq(flags f, System *sys, uint64_t frame, std::string sm,
|
||||||
|
std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
|
||||||
|
{
|
||||||
|
if (!enabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int sysi = getSys(sys);
|
||||||
|
int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid);
|
||||||
|
DPRINTFS(AnnotateQ, sys,
|
||||||
|
"hwDQ: %s[%#x] cur size %d %d bytes: %d removing: %d\n",
|
||||||
|
q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
|
||||||
|
doDq(sys, FL_HW | f, 0, getSm(sysi,sm, frame), q, qi, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void hwPq(flags f, System *sys, uint64_t frame, std::string sm,
|
||||||
|
std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
|
||||||
|
{
|
||||||
|
if (!enabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int sysi = getSys(sys);
|
||||||
|
int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid);
|
||||||
|
DPRINTFS(AnnotateQ, sys,
|
||||||
|
"hwPQ: %s[%#x] cur size %d %d bytes: %d peeking: %d\n",
|
||||||
|
q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
|
||||||
|
add(OP_PEEK, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void hwRq(flags f, System *sys, uint64_t frame, std::string sm,
|
||||||
|
std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
|
||||||
|
{
|
||||||
|
if (!enabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int sysi = getSys(sys);
|
||||||
|
int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid);
|
||||||
|
DPRINTFS(AnnotateQ, sys,
|
||||||
|
"hwRQ: %s[%#x] cur size %d %d bytes: %d reserving: %d\n",
|
||||||
|
q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
|
||||||
|
add(OP_RESERVE, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void hwWf(flags f, System *sys, uint64_t frame, std::string sm,
|
||||||
|
std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
|
||||||
|
{
|
||||||
|
if (!enabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int sysi = getSys(sys);
|
||||||
|
int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid);
|
||||||
|
add(OP_WAIT_FULL, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void hwWe(flags f, System *sys, uint64_t frame, std::string sm,
|
||||||
|
std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
|
||||||
|
{
|
||||||
|
if (!enabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int sysi = getSys(sys);
|
||||||
|
int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid);
|
||||||
|
add(OP_WAIT_EMPTY, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
CPA(Params *p);
|
||||||
|
void startup();
|
||||||
|
|
||||||
|
// This code is ISA specific and will need to be changed
|
||||||
|
// if the annotation code is used for something other than Alpha
|
||||||
|
inline uint64_t getFrame(ThreadContext *tc)
|
||||||
|
{ return (tc->readMiscRegNoEffect(TheISA::IPR_PALtemp23) &
|
||||||
|
~ULL(0x3FFF)); }
|
||||||
|
|
||||||
|
static bool available() { return true; }
|
||||||
|
|
||||||
|
bool
|
||||||
|
enabled()
|
||||||
|
{
|
||||||
|
if (!this)
|
||||||
|
return false;
|
||||||
|
return _enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump(bool all);
|
||||||
|
void dumpKey();
|
||||||
|
|
||||||
|
void serialize(std::ostream &os);
|
||||||
|
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif // !CP_ANNOTATE
|
||||||
|
|
||||||
|
#endif //__BASE__CP_ANNOTATE_HH__
|
||||||
|
|
|
@ -81,6 +81,16 @@ namespace __hash_namespace {
|
||||||
return(__stl_hash_string(s.c_str()));
|
return(__stl_hash_string(s.c_str()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<std::pair<std::string, uint64_t> > {
|
||||||
|
size_t operator() (std::pair<std::string, uint64_t> r) const {
|
||||||
|
return (__stl_hash_string(r.first.c_str())) ^ r.second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "sim/host.hh" // for Addr
|
#include "sim/host.hh" // for Addr
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ from params import *
|
||||||
# There are a few things we need that aren't in params.__all__ since
|
# There are a few things we need that aren't in params.__all__ since
|
||||||
# normal users don't need them
|
# normal users don't need them
|
||||||
from params import ParamDesc, VectorParamDesc, isNullPointer, SimObjVector
|
from params import ParamDesc, VectorParamDesc, isNullPointer, SimObjVector
|
||||||
|
from proxy import *
|
||||||
|
|
||||||
noDot = False
|
noDot = False
|
||||||
try:
|
try:
|
||||||
|
@ -667,7 +668,7 @@ class SimObject(object):
|
||||||
match_obj = self._values[pname]
|
match_obj = self._values[pname]
|
||||||
if found_obj != None and found_obj != match_obj:
|
if found_obj != None and found_obj != match_obj:
|
||||||
raise AttributeError, \
|
raise AttributeError, \
|
||||||
'parent.any matched more than one: %s' % obj.path
|
'parent.any matched more than one: %s and %s' % (found_obj.path, match_obj.path)
|
||||||
found_obj = match_obj
|
found_obj = match_obj
|
||||||
return found_obj, found_obj != None
|
return found_obj, found_obj != None
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
|
|
||||||
#include "arch/kernel_stats.hh"
|
#include "arch/kernel_stats.hh"
|
||||||
#include "arch/vtophys.hh"
|
#include "arch/vtophys.hh"
|
||||||
#include "base/annotate.hh"
|
|
||||||
#include "base/debug.hh"
|
#include "base/debug.hh"
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
|
@ -214,6 +213,7 @@ addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
|
||||||
DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
|
DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
|
||||||
|
|
||||||
tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
|
tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
|
||||||
|
debugSymbolTable->insert(addr,symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue