2009-02-27 01:29:17 +01:00
|
|
|
/*
|
|
|
|
* 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 <list>
|
|
|
|
#include <map>
|
2011-04-15 19:44:06 +02:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2009-05-17 23:34:52 +02:00
|
|
|
|
|
|
|
#include "base/loader/symtab.hh"
|
2011-04-15 19:44:06 +02:00
|
|
|
#include "base/hashmap.hh"
|
2009-02-27 01:29:17 +01:00
|
|
|
#include "base/trace.hh"
|
2009-05-17 23:34:52 +02:00
|
|
|
#include "base/types.hh"
|
|
|
|
#include "config/cp_annotate.hh"
|
2009-09-23 17:34:21 +02:00
|
|
|
#include "config/the_isa.hh"
|
2009-05-17 23:34:52 +02:00
|
|
|
#include "sim/serialize.hh"
|
|
|
|
#include "sim/system.hh"
|
|
|
|
|
2009-02-27 01:29:17 +01:00
|
|
|
#if CP_ANNOTATE
|
|
|
|
#include "params/CPA.hh"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
class System;
|
|
|
|
class ThreadContext;
|
|
|
|
|
|
|
|
|
|
|
|
#if !CP_ANNOTATE
|
2009-03-07 23:30:52 +01:00
|
|
|
class CPA
|
2009-02-27 01:29:17 +01:00
|
|
|
{
|
|
|
|
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)
|
2011-01-08 06:50:29 +01:00
|
|
|
warn("BAD state encountered: at cycle %d: %s\n", curTick(), st);
|
2009-02-27 01:29:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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__
|
|
|
|
|