cp_annotate.hh revision 5952:c1ee8282291d
111482Sandreas.sandberg@arm.com/* 211482Sandreas.sandberg@arm.com * Copyright (c) 2006-2009 The Regents of The University of Michigan 311482Sandreas.sandberg@arm.com * All rights reserved. 411482Sandreas.sandberg@arm.com * 511482Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 611482Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 711482Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 811482Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 911482Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1011482Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 1111482Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 1211482Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 1311482Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 1411482Sandreas.sandberg@arm.com * this software without specific prior written permission. 1511482Sandreas.sandberg@arm.com * 1611482Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711482Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811482Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911482Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011482Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111482Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211482Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311482Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411482Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511482Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611482Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711482Sandreas.sandberg@arm.com * 2811482Sandreas.sandberg@arm.com * Authors: Ali Saidi 2911482Sandreas.sandberg@arm.com */ 3011482Sandreas.sandberg@arm.com 3111482Sandreas.sandberg@arm.com#ifndef __BASE__CP_ANNOTATE_HH__ 3211482Sandreas.sandberg@arm.com#define __BASE__CP_ANNOTATE_HH__ 3311482Sandreas.sandberg@arm.com 3411482Sandreas.sandberg@arm.com#include "base/loader/symtab.hh" 3511482Sandreas.sandberg@arm.com#include "config/cp_annotate.hh" 3611482Sandreas.sandberg@arm.com#include "sim/host.hh" 3711482Sandreas.sandberg@arm.com#include "sim/serialize.hh" 3811482Sandreas.sandberg@arm.com#include "sim/startup.hh" 3911482Sandreas.sandberg@arm.com#include "sim/system.hh" 4011482Sandreas.sandberg@arm.com 4111482Sandreas.sandberg@arm.com#include <string> 4211482Sandreas.sandberg@arm.com#include <list> 4311482Sandreas.sandberg@arm.com#include <vector> 4411482Sandreas.sandberg@arm.com#include <map> 4511482Sandreas.sandberg@arm.com#include "base/hashmap.hh" 4611482Sandreas.sandberg@arm.com#include "base/trace.hh" 4711482Sandreas.sandberg@arm.com#if CP_ANNOTATE 4811482Sandreas.sandberg@arm.com#include "params/CPA.hh" 4911482Sandreas.sandberg@arm.com#endif 5011482Sandreas.sandberg@arm.com 5111482Sandreas.sandberg@arm.comclass System; 5211482Sandreas.sandberg@arm.comclass ThreadContext; 5311482Sandreas.sandberg@arm.com 5411482Sandreas.sandberg@arm.com 5511482Sandreas.sandberg@arm.com#if !CP_ANNOTATE 5611482Sandreas.sandberg@arm.comclass CPA : SimObject 5711482Sandreas.sandberg@arm.com{ 5811482Sandreas.sandberg@arm.com public: 5911482Sandreas.sandberg@arm.com enum flags { 6011482Sandreas.sandberg@arm.com FL_NONE = 0x00, 6111482Sandreas.sandberg@arm.com FL_HW = 0x01, 6211482Sandreas.sandberg@arm.com FL_BAD = 0x02, 6311482Sandreas.sandberg@arm.com FL_QOPP = 0x04, 6411482Sandreas.sandberg@arm.com FL_WAIT = 0x08, 6511482Sandreas.sandberg@arm.com FL_LINK = 0x10, 6611482Sandreas.sandberg@arm.com FL_RESET = 0x20 6711482Sandreas.sandberg@arm.com }; 6811482Sandreas.sandberg@arm.com 6911482Sandreas.sandberg@arm.com static CPA *cpa() { return NULL; } 7011482Sandreas.sandberg@arm.com static bool available() { return false; } 7111482Sandreas.sandberg@arm.com bool enabled() { return false; } 7211482Sandreas.sandberg@arm.com void swSmBegin(ThreadContext *tc) { return; } 7311482Sandreas.sandberg@arm.com void swSmEnd(ThreadContext *tc) { return; } 7411482Sandreas.sandberg@arm.com void swExplictBegin(ThreadContext *tc) { return; } 7511482Sandreas.sandberg@arm.com void swAutoBegin(ThreadContext *tc, Addr next_pc) { return; } 7611482Sandreas.sandberg@arm.com void swEnd(ThreadContext *tc) { return; } 7711482Sandreas.sandberg@arm.com void swQ(ThreadContext *tc) { return; } 7811482Sandreas.sandberg@arm.com void swDq(ThreadContext *tc) { return; } 7911482Sandreas.sandberg@arm.com void swPq(ThreadContext *tc) { return; } 8011482Sandreas.sandberg@arm.com void swRq(ThreadContext *tc) { return; } 8111482Sandreas.sandberg@arm.com void swWf(ThreadContext *tc) { return; } 8211482Sandreas.sandberg@arm.com void swWe(ThreadContext *tc) { return; } 8311482Sandreas.sandberg@arm.com void swSq(ThreadContext *tc) { return; } 8411482Sandreas.sandberg@arm.com void swAq(ThreadContext *tc) { return; } 8511482Sandreas.sandberg@arm.com void swLink(ThreadContext *tc) { return; } 8611482Sandreas.sandberg@arm.com void swIdentify(ThreadContext *tc) { return; } 8711482Sandreas.sandberg@arm.com uint64_t swGetId(ThreadContext *tc) { return 0; } 8811482Sandreas.sandberg@arm.com void swSyscallLink(ThreadContext *tc) { return; } 8911482Sandreas.sandberg@arm.com void hwBegin(flags f, System *sys, uint64_t frame, std::string sm, 9011482Sandreas.sandberg@arm.com std::string st) { return; } 9111482Sandreas.sandberg@arm.com void hwQ(flags f, System *sys, uint64_t frame, std::string sm, 9211482Sandreas.sandberg@arm.com std::string q, uint64_t qid, System *q_sys = NULL, 9311482Sandreas.sandberg@arm.com int32_t count = 1) { return; } 9411482Sandreas.sandberg@arm.com void hwDq(flags f, System *sys, uint64_t frame, std::string sm, 9511482Sandreas.sandberg@arm.com std::string q, uint64_t qid, System *q_sys = NULL, 9611482Sandreas.sandberg@arm.com int32_t count = 1) { return; } 9711482Sandreas.sandberg@arm.com void hwPq(flags f, System *sys, uint64_t frame, std::string sm, 9811482Sandreas.sandberg@arm.com std::string q, uint64_t qid, System *q_sys = NULL, 9911482Sandreas.sandberg@arm.com int32_t count = 1) { return; } 10011482Sandreas.sandberg@arm.com void hwRq(flags f, System *sys, uint64_t frame, std::string sm, 10111482Sandreas.sandberg@arm.com std::string q, uint64_t qid, System *q_sys = NULL, 10211482Sandreas.sandberg@arm.com int32_t count = 1) { return; } 10311482Sandreas.sandberg@arm.com void hwWf(flags f, System *sys, uint64_t frame, std::string sm, 10411482Sandreas.sandberg@arm.com std::string q, uint64_t qid, System *q_sys = NULL, 10511482Sandreas.sandberg@arm.com int32_t count = 1) { return; } 10611482Sandreas.sandberg@arm.com void hwWe(flags f, System *sys, uint64_t frame, std::string sm, 10711482Sandreas.sandberg@arm.com std::string q, uint64_t qid, System *q_sys = NULL, 10811482Sandreas.sandberg@arm.com int32_t count = 1) { return; } 10911482Sandreas.sandberg@arm.com}; 11011482Sandreas.sandberg@arm.com#else 11111482Sandreas.sandberg@arm.comclass CPA : SimObject 11211482Sandreas.sandberg@arm.com{ 11311482Sandreas.sandberg@arm.com public: 11411482Sandreas.sandberg@arm.com typedef CPAParams Params; 11511482Sandreas.sandberg@arm.com 11611482Sandreas.sandberg@arm.com /** The known operations that are written to the annotation output file. */ 11711482Sandreas.sandberg@arm.com enum ops { 11811482Sandreas.sandberg@arm.com OP_BEGIN = 0x01, 11911482Sandreas.sandberg@arm.com OP_WAIT_EMPTY = 0x02, 12011482Sandreas.sandberg@arm.com OP_WAIT_FULL = 0x03, 12111482Sandreas.sandberg@arm.com OP_QUEUE = 0x04, 12211482Sandreas.sandberg@arm.com OP_DEQUEUE = 0x05, 12311482Sandreas.sandberg@arm.com OP_SIZE_QUEUE = 0x08, 12411482Sandreas.sandberg@arm.com OP_PEEK = 0x09, 12511482Sandreas.sandberg@arm.com OP_LINK = 0x0A, 12611482Sandreas.sandberg@arm.com OP_IDENT = 0x0B, 12711482Sandreas.sandberg@arm.com OP_RESERVE = 0x0C 12811482Sandreas.sandberg@arm.com }; 12911482Sandreas.sandberg@arm.com 13011482Sandreas.sandberg@arm.com /** Flags for the various options.*/ 13111482Sandreas.sandberg@arm.com enum flags { 13211482Sandreas.sandberg@arm.com /* no flags */ 13311482Sandreas.sandberg@arm.com FL_NONE = 0x00, 13411482Sandreas.sandberg@arm.com /* operation was done on hardware */ 13511482Sandreas.sandberg@arm.com FL_HW = 0x01, 13611482Sandreas.sandberg@arm.com /* operation should cause a warning when encountered */ 13711482Sandreas.sandberg@arm.com FL_BAD = 0x02, 13811482Sandreas.sandberg@arm.com /* Queue like a stack, not a queue */ 13911482Sandreas.sandberg@arm.com FL_QOPP = 0x04, 14011482Sandreas.sandberg@arm.com /* Mark HW state as waiting for some non-resource constraint 14111482Sandreas.sandberg@arm.com * (e.g. wait because SM only starts after 10 items are queued) */ 14211482Sandreas.sandberg@arm.com FL_WAIT = 0x08, 14311482Sandreas.sandberg@arm.com /* operation is linking to another state machine */ 14411482Sandreas.sandberg@arm.com FL_LINK = 0x10, 14511482Sandreas.sandberg@arm.com /* queue should be completely cleared/reset before executing this 14611482Sandreas.sandberg@arm.com * operation */ 14711482Sandreas.sandberg@arm.com FL_RESET = 0x20 14811482Sandreas.sandberg@arm.com }; 14911482Sandreas.sandberg@arm.com 15011482Sandreas.sandberg@arm.com 15111482Sandreas.sandberg@arm.com 15211482Sandreas.sandberg@arm.com protected: 15311482Sandreas.sandberg@arm.com const Params * 15411482Sandreas.sandberg@arm.com params() const 15511482Sandreas.sandberg@arm.com { 15611482Sandreas.sandberg@arm.com return dynamic_cast<const Params *>(_params); 15711482Sandreas.sandberg@arm.com } 15811482Sandreas.sandberg@arm.com 15911482Sandreas.sandberg@arm.com /* struct that is written to the annotation output file */ 16011482Sandreas.sandberg@arm.com struct AnnotateData : public RefCounted { 16111482Sandreas.sandberg@arm.com 16211482Sandreas.sandberg@arm.com Tick time; 16311482Sandreas.sandberg@arm.com uint32_t data; 16411482Sandreas.sandberg@arm.com uint32_t orig_data; 16511482Sandreas.sandberg@arm.com uint16_t sm; 16611482Sandreas.sandberg@arm.com uint16_t stq; 16711482Sandreas.sandberg@arm.com uint8_t op; 16811482Sandreas.sandberg@arm.com uint8_t flag; 16911482Sandreas.sandberg@arm.com uint8_t cpu; 17011482Sandreas.sandberg@arm.com bool dump; 17111482Sandreas.sandberg@arm.com 17211482Sandreas.sandberg@arm.com void serialize(std::ostream &os); 17311482Sandreas.sandberg@arm.com void unserialize(Checkpoint *cp, const std::string §ion); 17411482Sandreas.sandberg@arm.com 17511482Sandreas.sandberg@arm.com }; 17611482Sandreas.sandberg@arm.com 17711482Sandreas.sandberg@arm.com typedef RefCountingPtr<AnnotateData> AnnDataPtr; 17811482Sandreas.sandberg@arm.com 17911482Sandreas.sandberg@arm.com /* header for the annotation file */ 18011482Sandreas.sandberg@arm.com struct AnnotateHeader { 18111482Sandreas.sandberg@arm.com uint64_t version; 18211482Sandreas.sandberg@arm.com uint64_t num_recs; 18311482Sandreas.sandberg@arm.com uint64_t key_off; 18411482Sandreas.sandberg@arm.com uint64_t idx_off; 18511482Sandreas.sandberg@arm.com uint32_t key_len; 18611482Sandreas.sandberg@arm.com uint32_t idx_len; 18711482Sandreas.sandberg@arm.com }; 18811482Sandreas.sandberg@arm.com 18911482Sandreas.sandberg@arm.com AnnotateHeader ah; 19011482Sandreas.sandberg@arm.com 19111482Sandreas.sandberg@arm.com std::vector<uint64_t> annotateIdx; 19211482Sandreas.sandberg@arm.com 19311482Sandreas.sandberg@arm.com // number of state machines encountered in the simulation 19411482Sandreas.sandberg@arm.com int numSm; 19511482Sandreas.sandberg@arm.com // number of states encountered in the simulation 19611482Sandreas.sandberg@arm.com int numSmt; 19711482Sandreas.sandberg@arm.com // number of states/queues for a given state machine/system respectively 19811482Sandreas.sandberg@arm.com std::vector<int> numSt, numQ; 19911482Sandreas.sandberg@arm.com // number of systems in the simulation 20011482Sandreas.sandberg@arm.com int numSys; 20111482Sandreas.sandberg@arm.com // number of queues in the state machine 20211482Sandreas.sandberg@arm.com int numQs; 20311482Sandreas.sandberg@arm.com // maximum connection id assigned so far 20411482Sandreas.sandberg@arm.com uint64_t conId; 20511482Sandreas.sandberg@arm.com 20611482Sandreas.sandberg@arm.com // Convert state strings into state ids 20711482Sandreas.sandberg@arm.com typedef m5::hash_map<std::string, int> SCache; 20811482Sandreas.sandberg@arm.com typedef std::vector<SCache> StCache; 20911482Sandreas.sandberg@arm.com 21011482Sandreas.sandberg@arm.com // Convert sm and queue name,id into queue id 21111482Sandreas.sandberg@arm.com typedef std::pair<std::string, uint64_t> Id; 21211482Sandreas.sandberg@arm.com typedef m5::hash_map<Id, int> IdHCache; 21311482Sandreas.sandberg@arm.com typedef std::vector<IdHCache> IdCache; 21411482Sandreas.sandberg@arm.com 21511482Sandreas.sandberg@arm.com // Hold mapping of sm and queues to output python 21611482Sandreas.sandberg@arm.com typedef std::vector<std::pair<int, Id> > IdMap; 21711482Sandreas.sandberg@arm.com 21811482Sandreas.sandberg@arm.com // System pointer to name,id 21911482Sandreas.sandberg@arm.com typedef std::map<System*, std::pair<std::string, int> > NameCache; 22011482Sandreas.sandberg@arm.com 22111482Sandreas.sandberg@arm.com // array of systems each of which is a stack of running sm 22211482Sandreas.sandberg@arm.com typedef std::pair<int, uint64_t> StackId; 22311482Sandreas.sandberg@arm.com typedef std::map<StackId, std::vector<int> > SmStack; 22411482Sandreas.sandberg@arm.com 22511482Sandreas.sandberg@arm.com // map of each context and if it's currently in explict state mode 22611482Sandreas.sandberg@arm.com // states are not automatically updated until it leaves 22711482Sandreas.sandberg@arm.com typedef std::map<StackId, bool> SwExpl; 22811482Sandreas.sandberg@arm.com 22911482Sandreas.sandberg@arm.com typedef std::map<int,int> IMap; 23011482Sandreas.sandberg@arm.com // List of annotate records have not been written/completed yet 23111482Sandreas.sandberg@arm.com typedef std::list<AnnDataPtr> AnnotateList; 23211482Sandreas.sandberg@arm.com 23311482Sandreas.sandberg@arm.com // Maintain link state information 23411482Sandreas.sandberg@arm.com typedef std::map<int, int> LinkMap; 23511482Sandreas.sandberg@arm.com 23611482Sandreas.sandberg@arm.com // SC Links 23711482Sandreas.sandberg@arm.com typedef m5::hash_map<Id, AnnDataPtr> ScHCache; 23811482Sandreas.sandberg@arm.com typedef std::vector<ScHCache> ScCache; 23911482Sandreas.sandberg@arm.com 24011482Sandreas.sandberg@arm.com 24111482Sandreas.sandberg@arm.com AnnotateList data; 24211482Sandreas.sandberg@arm.com 24311482Sandreas.sandberg@arm.com // vector indexed by queueid to find current number of elements and bytes 24411482Sandreas.sandberg@arm.com std::vector<int> qSize; 24511482Sandreas.sandberg@arm.com std::vector<int32_t> qBytes; 24611482Sandreas.sandberg@arm.com 24711482Sandreas.sandberg@arm.com 24811482Sandreas.sandberg@arm.com // Turn state machine string into state machine id (small int) 24911482Sandreas.sandberg@arm.com // Used for outputting key to convert id back into string 25011482Sandreas.sandberg@arm.com SCache smtCache; 25111482Sandreas.sandberg@arm.com // Turn state machine id, state name into state id (small int) 25211482Sandreas.sandberg@arm.com StCache stCache; 25311482Sandreas.sandberg@arm.com // turn system, queue, and queue identify into qid (small int) 25411482Sandreas.sandberg@arm.com // turn system, state, and context into state machine id (small int) 25511482Sandreas.sandberg@arm.com IdCache qCache, smCache; 25611482Sandreas.sandberg@arm.com //Link state machines accross system calls 25711482Sandreas.sandberg@arm.com ScCache scLinks; 25811482Sandreas.sandberg@arm.com // System pointer to name,id 25911482Sandreas.sandberg@arm.com NameCache nameCache; 26011482Sandreas.sandberg@arm.com // Stack of state machines currently nested (should unwind correctly) 26111482Sandreas.sandberg@arm.com SmStack smStack; 26211482Sandreas.sandberg@arm.com // Map of currently outstanding links 26311482Sandreas.sandberg@arm.com LinkMap lnMap; 26411482Sandreas.sandberg@arm.com // If the state machine is currently exculding automatic changes 26511482Sandreas.sandberg@arm.com SwExpl swExpl; 26611482Sandreas.sandberg@arm.com // Last state that a given state machine was in 26711482Sandreas.sandberg@arm.com IMap lastState; 26811482Sandreas.sandberg@arm.com // Hold mapping of sm and queues to output python 26911482Sandreas.sandberg@arm.com IdMap smMap, qMap; 27011482Sandreas.sandberg@arm.com // Items still in queue, used for sanity checking 27111482Sandreas.sandberg@arm.com std::vector<AnnotateList> qData; 27211482Sandreas.sandberg@arm.com 27311482Sandreas.sandberg@arm.com void doDq(System *sys, int flags, int cpu, int sm, std::string q, int qi, 27411482Sandreas.sandberg@arm.com int count); 27511482Sandreas.sandberg@arm.com void doQ(System *sys, int flags, int cpu, int sm, std::string q, int qi, 27611482Sandreas.sandberg@arm.com int count); 27711482Sandreas.sandberg@arm.com 27811482Sandreas.sandberg@arm.com void doSwSmEnd(System *sys, int cpuid, std::string sm, uint64_t frame); 27911482Sandreas.sandberg@arm.com 28011482Sandreas.sandberg@arm.com // Turn a system id, state machine string, state machine id into a small int 28111482Sandreas.sandberg@arm.com // for annotation output 28211482Sandreas.sandberg@arm.com int 28311482Sandreas.sandberg@arm.com getSm(int sysi, std::string si, uint64_t id) 28411482Sandreas.sandberg@arm.com { 28511482Sandreas.sandberg@arm.com int smi; 28611482Sandreas.sandberg@arm.com Id smid = Id(si, id); 28711482Sandreas.sandberg@arm.com 28811482Sandreas.sandberg@arm.com smi = smCache[sysi-1][smid]; 28911482Sandreas.sandberg@arm.com if (smi == 0) { 29011482Sandreas.sandberg@arm.com smCache[sysi-1][smid] = smi = ++numSm; 29111482Sandreas.sandberg@arm.com assert(smi < 65535); 29211482Sandreas.sandberg@arm.com smMap.push_back(std::make_pair<int, Id>(sysi, smid)); 29311482Sandreas.sandberg@arm.com } 29411482Sandreas.sandberg@arm.com return smi; 29511482Sandreas.sandberg@arm.com } 29611482Sandreas.sandberg@arm.com 29711482Sandreas.sandberg@arm.com // Turn a state machine string, state string into a small int 29811482Sandreas.sandberg@arm.com // for annotation output 29911482Sandreas.sandberg@arm.com int 30011482Sandreas.sandberg@arm.com getSt(std::string sm, std::string s) 30111482Sandreas.sandberg@arm.com { 30211482Sandreas.sandberg@arm.com int sti, smi; 30311482Sandreas.sandberg@arm.com 30411482Sandreas.sandberg@arm.com smi = smtCache[sm]; 30511482Sandreas.sandberg@arm.com if (smi == 0) 30611482Sandreas.sandberg@arm.com smi = smtCache[sm] = ++numSmt; 30711482Sandreas.sandberg@arm.com 30811482Sandreas.sandberg@arm.com while (stCache.size() < smi) { 30911482Sandreas.sandberg@arm.com //stCache.resize(sm); 31011482Sandreas.sandberg@arm.com stCache.push_back(SCache()); 31111482Sandreas.sandberg@arm.com numSt.push_back(0); 31211482Sandreas.sandberg@arm.com } 31311482Sandreas.sandberg@arm.com //assert(stCache.size() == sm); 31411482Sandreas.sandberg@arm.com //assert(numSt.size() == sm); 31511482Sandreas.sandberg@arm.com sti = stCache[smi-1][s]; 31611482Sandreas.sandberg@arm.com if (sti == 0) 31711482Sandreas.sandberg@arm.com stCache[smi-1][s] = sti = ++numSt[smi-1]; 31811482Sandreas.sandberg@arm.com return sti; 31911482Sandreas.sandberg@arm.com } 32011482Sandreas.sandberg@arm.com 32111482Sandreas.sandberg@arm.com // Turn state machine pointer into a smal int for annotation output 32211482Sandreas.sandberg@arm.com int 32311482Sandreas.sandberg@arm.com getSys(System *s) 32411482Sandreas.sandberg@arm.com { 32511482Sandreas.sandberg@arm.com NameCache::iterator i = nameCache.find(s); 32611482Sandreas.sandberg@arm.com if (i == nameCache.end()) { 32711482Sandreas.sandberg@arm.com nameCache[s] = std::make_pair<std::string,int>(s->name(), ++numSys); 32811482Sandreas.sandberg@arm.com i = nameCache.find(s); 32911482Sandreas.sandberg@arm.com // might need to put smstackid into map here, but perhaps not 33011482Sandreas.sandberg@arm.com //smStack.push_back(std::vector<int>()); 33111482Sandreas.sandberg@arm.com //swExpl.push_back(false); 33211482Sandreas.sandberg@arm.com numQ.push_back(0); 33311482Sandreas.sandberg@arm.com qCache.push_back(IdHCache()); 33411482Sandreas.sandberg@arm.com smCache.push_back(IdHCache()); 33511482Sandreas.sandberg@arm.com scLinks.push_back(ScHCache()); 33611482Sandreas.sandberg@arm.com } 33711482Sandreas.sandberg@arm.com return i->second.second; 33811482Sandreas.sandberg@arm.com } 33911482Sandreas.sandberg@arm.com 34011482Sandreas.sandberg@arm.com // Turn queue name, and queue context into small int for 34111482Sandreas.sandberg@arm.com // annotation output 34211482Sandreas.sandberg@arm.com int 34311482Sandreas.sandberg@arm.com getQ(int sys, std::string q, uint64_t id) 344 { 345 int qi; 346 Id qid = Id(q, id); 347 348 qi = qCache[sys-1][qid]; 349 if (qi == 0) { 350 qi = qCache[sys-1][qid] = ++numQs; 351 assert(qi < 65535); 352 qSize.push_back(0); 353 qBytes.push_back(0); 354 qData.push_back(AnnotateList()); 355 numQ[sys-1]++; 356 qMap.push_back(std::make_pair<int, Id>(sys, qid)); 357 } 358 return qi; 359 } 360 361 void swBegin(System *sys, int cpuid, std::string st, uint64_t frame, 362 bool expl = false, int flags = FL_NONE); 363 364 AnnDataPtr add(int t, int f, int c, int sm, int stq, int32_t data=0); 365 366 std::ostream *osbin; 367 368 bool _enabled; 369 370 /** Only allow one CPA object in a system. It doesn't make sense to have 371 * more that one per simulation because if a part of the system was 372 * important it would have annotations and queues, and with more than one 373 * object none of the sanity checking for queues will work. */ 374 static bool exists; 375 static CPA *_cpa; 376 377 378 std::map<std::string, SymbolTable*> userApp; 379 380 public: 381 static CPA *cpa() { return _cpa; } 382 void swSmBegin(ThreadContext *tc); 383 void swSmEnd(ThreadContext *tc); 384 void swExplictBegin(ThreadContext *tc); 385 void swAutoBegin(ThreadContext *tc, Addr next_pc); 386 void swEnd(ThreadContext *tc); 387 void swQ(ThreadContext *tc); 388 void swDq(ThreadContext *tc); 389 void swPq(ThreadContext *tc); 390 void swRq(ThreadContext *tc); 391 void swWf(ThreadContext *tc); 392 void swWe(ThreadContext *tc); 393 void swSq(ThreadContext *tc); 394 void swAq(ThreadContext *tc); 395 void swLink(ThreadContext *tc); 396 void swIdentify(ThreadContext *tc); 397 uint64_t swGetId(ThreadContext *tc); 398 void swSyscallLink(ThreadContext *tc); 399 400 inline void hwBegin(flags f, System *sys, uint64_t frame, std::string sm, 401 std::string st) 402 { 403 if (!enabled()) 404 return; 405 406 int sysi = getSys(sys); 407 int smi = getSm(sysi, sm, frame); 408 add(OP_BEGIN, FL_HW | f, 0, smi, getSt(sm, st)); 409 if (f & FL_BAD) 410 warn("BAD state encountered: at cycle %d: %s\n", curTick, st); 411 } 412 413 inline void hwQ(flags f, System *sys, uint64_t frame, std::string sm, 414 std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1) 415 { 416 if (!enabled()) 417 return; 418 419 int sysi = getSys(sys); 420 int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid); 421 DPRINTFS(AnnotateQ, sys, 422 "hwQ: %s[%#x] cur size %d %d bytes: %d adding: %d\n", 423 q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count); 424 doQ(sys, FL_HW | f, 0, getSm(sysi, sm, frame), q, qi, count); 425 426 } 427 428 inline void hwDq(flags f, System *sys, uint64_t frame, std::string sm, 429 std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1) 430 { 431 if (!enabled()) 432 return; 433 434 int sysi = getSys(sys); 435 int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid); 436 DPRINTFS(AnnotateQ, sys, 437 "hwDQ: %s[%#x] cur size %d %d bytes: %d removing: %d\n", 438 q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count); 439 doDq(sys, FL_HW | f, 0, getSm(sysi,sm, frame), q, qi, count); 440 } 441 442 inline void hwPq(flags f, System *sys, uint64_t frame, std::string sm, 443 std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1) 444 { 445 if (!enabled()) 446 return; 447 448 int sysi = getSys(sys); 449 int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid); 450 DPRINTFS(AnnotateQ, sys, 451 "hwPQ: %s[%#x] cur size %d %d bytes: %d peeking: %d\n", 452 q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count); 453 add(OP_PEEK, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count); 454 } 455 456 inline void hwRq(flags f, System *sys, uint64_t frame, std::string sm, 457 std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1) 458 { 459 if (!enabled()) 460 return; 461 462 int sysi = getSys(sys); 463 int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid); 464 DPRINTFS(AnnotateQ, sys, 465 "hwRQ: %s[%#x] cur size %d %d bytes: %d reserving: %d\n", 466 q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count); 467 add(OP_RESERVE, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count); 468 } 469 470 inline void hwWf(flags f, System *sys, uint64_t frame, std::string sm, 471 std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1) 472 { 473 if (!enabled()) 474 return; 475 476 int sysi = getSys(sys); 477 int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid); 478 add(OP_WAIT_FULL, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count); 479 } 480 481 inline void hwWe(flags f, System *sys, uint64_t frame, std::string sm, 482 std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1) 483 { 484 if (!enabled()) 485 return; 486 487 int sysi = getSys(sys); 488 int qi = getQ(q_sys ? getSys(q_sys) : sysi, q, qid); 489 add(OP_WAIT_EMPTY, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count); 490 } 491 492 public: 493 CPA(Params *p); 494 void startup(); 495 496 // This code is ISA specific and will need to be changed 497 // if the annotation code is used for something other than Alpha 498 inline uint64_t getFrame(ThreadContext *tc) 499 { return (tc->readMiscRegNoEffect(TheISA::IPR_PALtemp23) & 500 ~ULL(0x3FFF)); } 501 502 static bool available() { return true; } 503 504 bool 505 enabled() 506 { 507 if (!this) 508 return false; 509 return _enabled; 510 } 511 512 void dump(bool all); 513 void dumpKey(); 514 515 void serialize(std::ostream &os); 516 void unserialize(Checkpoint *cp, const std::string §ion); 517 518}; 519#endif // !CP_ANNOTATE 520 521#endif //__BASE__CP_ANNOTATE_HH__ 522 523