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_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
|
||||
BoolVariable('USE_CHECKER', 'Use checker for detailed CPU models', False),
|
||||
BoolVariable('CP_ANNOTATE', 'Enable critical path annotation capability', False),
|
||||
)
|
||||
|
||||
nonsticky_vars.AddVariables(
|
||||
|
@ -699,7 +700,7 @@ nonsticky_vars.AddVariables(
|
|||
env.ExportVariables = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \
|
||||
'USE_MYSQL', 'NO_FAST_ALLOC', 'FAST_ALLOC_DEBUG', \
|
||||
'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({{
|
||||
panic("M5 panic instruction called at pc=%#x.", xc->readPC());
|
||||
}}, IsNonSpeculative);
|
||||
0x55: m5reserved1({{
|
||||
warn("M5 reserved opcode ignored");
|
||||
#define CPANN(lbl) CPA::cpa()->lbl(xc->tcBase())
|
||||
0x55: decode RA {
|
||||
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({{
|
||||
warn("M5 reserved opcode ignored");
|
||||
}}, IsNonSpeculative);
|
||||
|
|
|
@ -68,6 +68,7 @@ using namespace AlphaISA;
|
|||
output exec {{
|
||||
#include <math.h>
|
||||
|
||||
#include "base/cp_annotate.hh"
|
||||
#include "sim/pseudo_inst.hh"
|
||||
#include "arch/alpha/ipr.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('*')
|
||||
|
||||
Source('annotate.cc')
|
||||
if env['CP_ANNOTATE']:
|
||||
SimObject('CPA.py')
|
||||
Source('cp_annotate.cc')
|
||||
Source('atomicio.cc')
|
||||
Source('bigint.cc')
|
||||
Source('circlebuf.cc')
|
||||
|
@ -82,6 +84,8 @@ if env['USE_MYSQL']:
|
|||
Source('stats/mysql.cc')
|
||||
|
||||
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('GDBExtra', "Dump extra information on reads and writes")
|
||||
TraceFlag('GDBMisc', "Breakpoints, traps, watchpoints, etc.")
|
||||
|
@ -96,3 +100,6 @@ CompoundFlag('GDBAll',
|
|||
[ 'GDBMisc', 'GDBAcc', 'GDBRead', 'GDBWrite', 'GDBSend', 'GDBRecv',
|
||||
'GDBExtra' ],
|
||||
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()));
|
||||
}
|
||||
};
|
||||
|
||||
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 <map>
|
||||
#include <string>
|
||||
|
||||
#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
|
||||
# normal users don't need them
|
||||
from params import ParamDesc, VectorParamDesc, isNullPointer, SimObjVector
|
||||
from proxy import *
|
||||
|
||||
noDot = False
|
||||
try:
|
||||
|
@ -667,7 +668,7 @@ class SimObject(object):
|
|||
match_obj = self._values[pname]
|
||||
if found_obj != None and found_obj != match_obj:
|
||||
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
|
||||
return found_obj, found_obj != None
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
|
||||
#include "arch/kernel_stats.hh"
|
||||
#include "arch/vtophys.hh"
|
||||
#include "base/annotate.hh"
|
||||
#include "base/debug.hh"
|
||||
#include "cpu/base.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);
|
||||
|
||||
tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
|
||||
debugSymbolTable->insert(addr,symbol);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue