cp_annotate.hh revision 5952:c1ee8282291d
12SN/A/* 211274Sshingarov@labware.com * Copyright (c) 2006-2009 The Regents of The University of Michigan 310595Sgabeblack@google.com * All rights reserved. 41762SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272SN/A * 282SN/A * Authors: Ali Saidi 292665Ssaidi@eecs.umich.edu */ 302665Ssaidi@eecs.umich.edu 3111274Sshingarov@labware.com#ifndef __BASE__CP_ANNOTATE_HH__ 322SN/A#define __BASE__CP_ANNOTATE_HH__ 332SN/A 342SN/A#include "base/loader/symtab.hh" 352SN/A#include "config/cp_annotate.hh" 362SN/A#include "sim/host.hh" 373960Sgblack@eecs.umich.edu#include "sim/serialize.hh" 3877SN/A#include "sim/startup.hh" 3912031Sgabeblack@google.com#include "sim/system.hh" 408229Snate@binkert.org 4112031Sgabeblack@google.com#include <string> 428229Snate@binkert.org#include <list> 432986Sgblack@eecs.umich.edu#include <vector> 4410595Sgabeblack@google.com#include <map> 4556SN/A#include "base/hashmap.hh" 4656SN/A#include "base/trace.hh" 478229Snate@binkert.org#if CP_ANNOTATE 482SN/A#include "params/CPA.hh" 492SN/A#endif 502680Sktlim@umich.edu 512SN/Aclass System; 5212449Sgabeblack@google.comclass ThreadContext; 5312449Sgabeblack@google.com 543536Sgblack@eecs.umich.edu 5512449Sgabeblack@google.com#if !CP_ANNOTATE 5612449Sgabeblack@google.comclass CPA : SimObject 5712449Sgabeblack@google.com{ 5812449Sgabeblack@google.com public: 5912449Sgabeblack@google.com enum flags { 6012449Sgabeblack@google.com FL_NONE = 0x00, 6112449Sgabeblack@google.com FL_HW = 0x01, 6212449Sgabeblack@google.com FL_BAD = 0x02, 632SN/A FL_QOPP = 0x04, 6412031Sgabeblack@google.com FL_WAIT = 0x08, 6512031Sgabeblack@google.com FL_LINK = 0x10, 6612449Sgabeblack@google.com FL_RESET = 0x20 6712449Sgabeblack@google.com }; 6812449Sgabeblack@google.com 6912449Sgabeblack@google.com static CPA *cpa() { return NULL; } 7012449Sgabeblack@google.com static bool available() { return false; } 7112449Sgabeblack@google.com bool enabled() { return false; } 7212031Sgabeblack@google.com void swSmBegin(ThreadContext *tc) { return; } 7312449Sgabeblack@google.com void swSmEnd(ThreadContext *tc) { return; } 7412449Sgabeblack@google.com void swExplictBegin(ThreadContext *tc) { return; } 7512449Sgabeblack@google.com void swAutoBegin(ThreadContext *tc, Addr next_pc) { return; } 7612449Sgabeblack@google.com void swEnd(ThreadContext *tc) { return; } 7712449Sgabeblack@google.com void swQ(ThreadContext *tc) { return; } 7812031Sgabeblack@google.com void swDq(ThreadContext *tc) { return; } 7912449Sgabeblack@google.com void swPq(ThreadContext *tc) { return; } 8012449Sgabeblack@google.com void swRq(ThreadContext *tc) { return; } 8112449Sgabeblack@google.com void swWf(ThreadContext *tc) { return; } 8212449Sgabeblack@google.com void swWe(ThreadContext *tc) { return; } 8312449Sgabeblack@google.com void swSq(ThreadContext *tc) { return; } 8412449Sgabeblack@google.com void swAq(ThreadContext *tc) { return; } 8512449Sgabeblack@google.com void swLink(ThreadContext *tc) { return; } 8612449Sgabeblack@google.com void swIdentify(ThreadContext *tc) { return; } 8712449Sgabeblack@google.com uint64_t swGetId(ThreadContext *tc) { return 0; } 8812449Sgabeblack@google.com void swSyscallLink(ThreadContext *tc) { return; } 8912449Sgabeblack@google.com void hwBegin(flags f, System *sys, uint64_t frame, std::string sm, 9012449Sgabeblack@google.com std::string st) { return; } 9112449Sgabeblack@google.com void hwQ(flags f, System *sys, uint64_t frame, std::string sm, 9212449Sgabeblack@google.com std::string q, uint64_t qid, System *q_sys = NULL, 9312449Sgabeblack@google.com int32_t count = 1) { return; } 9412449Sgabeblack@google.com void hwDq(flags f, System *sys, uint64_t frame, std::string sm, 9512449Sgabeblack@google.com std::string q, uint64_t qid, System *q_sys = NULL, 9612449Sgabeblack@google.com int32_t count = 1) { return; } 9712449Sgabeblack@google.com void hwPq(flags f, System *sys, uint64_t frame, std::string sm, 9812449Sgabeblack@google.com std::string q, uint64_t qid, System *q_sys = NULL, 9912031Sgabeblack@google.com int32_t count = 1) { return; } 10012449Sgabeblack@google.com void hwRq(flags f, System *sys, uint64_t frame, std::string sm, 10112449Sgabeblack@google.com std::string q, uint64_t qid, System *q_sys = NULL, 10212449Sgabeblack@google.com int32_t count = 1) { return; } 10312449Sgabeblack@google.com void hwWf(flags f, System *sys, uint64_t frame, std::string sm, 10412449Sgabeblack@google.com std::string q, uint64_t qid, System *q_sys = NULL, 1053536Sgblack@eecs.umich.edu int32_t count = 1) { return; } 1063536Sgblack@eecs.umich.edu void hwWe(flags f, System *sys, uint64_t frame, std::string sm, 1073536Sgblack@eecs.umich.edu std::string q, uint64_t qid, System *q_sys = NULL, 1083536Sgblack@eecs.umich.edu int32_t count = 1) { return; } 10912449Sgabeblack@google.com}; 11012449Sgabeblack@google.com#else 11112449Sgabeblack@google.comclass CPA : SimObject 11212449Sgabeblack@google.com{ 11312449Sgabeblack@google.com public: 11412449Sgabeblack@google.com typedef CPAParams Params; 11512449Sgabeblack@google.com 11612449Sgabeblack@google.com /** The known operations that are written to the annotation output file. */ 11712449Sgabeblack@google.com enum ops { 11812449Sgabeblack@google.com OP_BEGIN = 0x01, 11912449Sgabeblack@google.com OP_WAIT_EMPTY = 0x02, 12012449Sgabeblack@google.com OP_WAIT_FULL = 0x03, 12112449Sgabeblack@google.com OP_QUEUE = 0x04, 12212449Sgabeblack@google.com OP_DEQUEUE = 0x05, 12312449Sgabeblack@google.com OP_SIZE_QUEUE = 0x08, 12412449Sgabeblack@google.com OP_PEEK = 0x09, 12512449Sgabeblack@google.com OP_LINK = 0x0A, 12612449Sgabeblack@google.com OP_IDENT = 0x0B, 12712449Sgabeblack@google.com OP_RESERVE = 0x0C 12812449Sgabeblack@google.com }; 12912449Sgabeblack@google.com 13012449Sgabeblack@google.com /** Flags for the various options.*/ 13112449Sgabeblack@google.com enum flags { 13212449Sgabeblack@google.com /* no flags */ 13312449Sgabeblack@google.com FL_NONE = 0x00, 1341910SN/A /* operation was done on hardware */ 13512449Sgabeblack@google.com FL_HW = 0x01, 13612449Sgabeblack@google.com /* operation should cause a warning when encountered */ 13712449Sgabeblack@google.com FL_BAD = 0x02, 13812449Sgabeblack@google.com /* Queue like a stack, not a queue */ 13912449Sgabeblack@google.com FL_QOPP = 0x04, 1401910SN/A /* Mark HW state as waiting for some non-resource constraint 14112449Sgabeblack@google.com * (e.g. wait because SM only starts after 10 items are queued) */ 14212449Sgabeblack@google.com FL_WAIT = 0x08, 14312031Sgabeblack@google.com /* operation is linking to another state machine */ 14412449Sgabeblack@google.com FL_LINK = 0x10, 14512449Sgabeblack@google.com /* queue should be completely cleared/reset before executing this 14612449Sgabeblack@google.com * operation */ 14712449Sgabeblack@google.com FL_RESET = 0x20 14812449Sgabeblack@google.com }; 14912449Sgabeblack@google.com 15012031Sgabeblack@google.com 15112449Sgabeblack@google.com 15212449Sgabeblack@google.com protected: 15312031Sgabeblack@google.com const Params * 15412449Sgabeblack@google.com params() const 15512449Sgabeblack@google.com { 15612449Sgabeblack@google.com return dynamic_cast<const Params *>(_params); 15712449Sgabeblack@google.com } 15812449Sgabeblack@google.com 15912449Sgabeblack@google.com /* struct that is written to the annotation output file */ 16012449Sgabeblack@google.com struct AnnotateData : public RefCounted { 16112449Sgabeblack@google.com 16212449Sgabeblack@google.com Tick time; 16312449Sgabeblack@google.com uint32_t data; 16412449Sgabeblack@google.com uint32_t orig_data; 16512449Sgabeblack@google.com uint16_t sm; 16612449Sgabeblack@google.com uint16_t stq; 16712449Sgabeblack@google.com uint8_t op; 16812449Sgabeblack@google.com uint8_t flag; 16912449Sgabeblack@google.com uint8_t cpu; 17012449Sgabeblack@google.com bool dump; 17112449Sgabeblack@google.com 17212449Sgabeblack@google.com void serialize(std::ostream &os); 17312449Sgabeblack@google.com void unserialize(Checkpoint *cp, const std::string §ion); 17413470Sciro.santilli@arm.com 17512449Sgabeblack@google.com }; 17612449Sgabeblack@google.com 17712449Sgabeblack@google.com typedef RefCountingPtr<AnnotateData> AnnDataPtr; 17812449Sgabeblack@google.com 17912449Sgabeblack@google.com /* header for the annotation file */ 18012449Sgabeblack@google.com struct AnnotateHeader { 18112449Sgabeblack@google.com uint64_t version; 18212449Sgabeblack@google.com uint64_t num_recs; 18312449Sgabeblack@google.com uint64_t key_off; 18412449Sgabeblack@google.com uint64_t idx_off; 18512449Sgabeblack@google.com uint32_t key_len; 18612449Sgabeblack@google.com uint32_t idx_len; 18712449Sgabeblack@google.com }; 18812449Sgabeblack@google.com 18912031Sgabeblack@google.com AnnotateHeader ah; 19012449Sgabeblack@google.com 19112449Sgabeblack@google.com std::vector<uint64_t> annotateIdx; 19212449Sgabeblack@google.com 19312449Sgabeblack@google.com // number of state machines encountered in the simulation 19412449Sgabeblack@google.com int numSm; 19512449Sgabeblack@google.com // number of states encountered in the simulation 19612031Sgabeblack@google.com int numSmt; 19712449Sgabeblack@google.com // number of states/queues for a given state machine/system respectively 19812449Sgabeblack@google.com std::vector<int> numSt, numQ; 19912449Sgabeblack@google.com // number of systems in the simulation 20012449Sgabeblack@google.com int numSys; 20112449Sgabeblack@google.com // number of queues in the state machine 20212449Sgabeblack@google.com int numQs; 20312449Sgabeblack@google.com // maximum connection id assigned so far 20412449Sgabeblack@google.com uint64_t conId; 20512449Sgabeblack@google.com 20612449Sgabeblack@google.com // Convert state strings into state ids 20712449Sgabeblack@google.com typedef m5::hash_map<std::string, int> SCache; 20812449Sgabeblack@google.com typedef std::vector<SCache> StCache; 20912449Sgabeblack@google.com 21012449Sgabeblack@google.com // Convert sm and queue name,id into queue id 21112449Sgabeblack@google.com typedef std::pair<std::string, uint64_t> Id; 21212449Sgabeblack@google.com typedef m5::hash_map<Id, int> IdHCache; 21312449Sgabeblack@google.com typedef std::vector<IdHCache> IdCache; 21412449Sgabeblack@google.com 21512449Sgabeblack@google.com // Hold mapping of sm and queues to output python 21612449Sgabeblack@google.com typedef std::vector<std::pair<int, Id> > IdMap; 21712449Sgabeblack@google.com 21812449Sgabeblack@google.com // System pointer to name,id 21912449Sgabeblack@google.com typedef std::map<System*, std::pair<std::string, int> > NameCache; 22012449Sgabeblack@google.com 22112449Sgabeblack@google.com // array of systems each of which is a stack of running sm 22212449Sgabeblack@google.com typedef std::pair<int, uint64_t> StackId; 22312449Sgabeblack@google.com typedef std::map<StackId, std::vector<int> > SmStack; 22412449Sgabeblack@google.com 22512449Sgabeblack@google.com // map of each context and if it's currently in explict state mode 22612449Sgabeblack@google.com // states are not automatically updated until it leaves 22712449Sgabeblack@google.com typedef std::map<StackId, bool> SwExpl; 22812449Sgabeblack@google.com 22912449Sgabeblack@google.com typedef std::map<int,int> IMap; 23012449Sgabeblack@google.com // List of annotate records have not been written/completed yet 23112449Sgabeblack@google.com typedef std::list<AnnDataPtr> AnnotateList; 23212449Sgabeblack@google.com 23312449Sgabeblack@google.com // Maintain link state information 23412449Sgabeblack@google.com typedef std::map<int, int> LinkMap; 23512449Sgabeblack@google.com 23612449Sgabeblack@google.com // SC Links 23712449Sgabeblack@google.com typedef m5::hash_map<Id, AnnDataPtr> ScHCache; 23812449Sgabeblack@google.com typedef std::vector<ScHCache> ScCache; 23912449Sgabeblack@google.com 24012449Sgabeblack@google.com 24112449Sgabeblack@google.com AnnotateList data; 24212449Sgabeblack@google.com 24312449Sgabeblack@google.com // vector indexed by queueid to find current number of elements and bytes 24412449Sgabeblack@google.com std::vector<int> qSize; 24512449Sgabeblack@google.com std::vector<int32_t> qBytes; 24612449Sgabeblack@google.com 24712449Sgabeblack@google.com 24812449Sgabeblack@google.com // Turn state machine string into state machine id (small int) 24912449Sgabeblack@google.com // Used for outputting key to convert id back into string 25012449Sgabeblack@google.com SCache smtCache; 25112449Sgabeblack@google.com // Turn state machine id, state name into state id (small int) 25212449Sgabeblack@google.com StCache stCache; 25312449Sgabeblack@google.com // turn system, queue, and queue identify into qid (small int) 25412031Sgabeblack@google.com // turn system, state, and context into state machine id (small int) 25512031Sgabeblack@google.com IdCache qCache, smCache; 25612031Sgabeblack@google.com //Link state machines accross system calls 25712031Sgabeblack@google.com ScCache scLinks; 25812031Sgabeblack@google.com // System pointer to name,id 25912031Sgabeblack@google.com NameCache nameCache; 26012031Sgabeblack@google.com // Stack of state machines currently nested (should unwind correctly) 26112031Sgabeblack@google.com SmStack smStack; 26212031Sgabeblack@google.com // Map of currently outstanding links 26312031Sgabeblack@google.com LinkMap lnMap; 26412031Sgabeblack@google.com // If the state machine is currently exculding automatic changes 26512031Sgabeblack@google.com SwExpl swExpl; 26612031Sgabeblack@google.com // Last state that a given state machine was in 26712031Sgabeblack@google.com IMap lastState; 26812031Sgabeblack@google.com // Hold mapping of sm and queues to output python 26912031Sgabeblack@google.com IdMap smMap, qMap; 27012031Sgabeblack@google.com // Items still in queue, used for sanity checking 27112031Sgabeblack@google.com std::vector<AnnotateList> qData; 27212031Sgabeblack@google.com 27312031Sgabeblack@google.com void doDq(System *sys, int flags, int cpu, int sm, std::string q, int qi, 2743536Sgblack@eecs.umich.edu int count); 2752SN/A void doQ(System *sys, int flags, int cpu, int sm, std::string q, int qi, 27612449Sgabeblack@google.com int count); 27712449Sgabeblack@google.com 2782SN/A void doSwSmEnd(System *sys, int cpuid, std::string sm, uint64_t frame); 27912449Sgabeblack@google.com 28012449Sgabeblack@google.com // Turn a system id, state machine string, state machine id into a small int 2812SN/A // for annotation output 28211274Sshingarov@labware.com int 2832SN/A getSm(int sysi, std::string si, uint64_t id) 2843536Sgblack@eecs.umich.edu { 2852SN/A int smi; 2862SN/A Id smid = Id(si, id); 2872SN/A 2882SN/A smi = smCache[sysi-1][smid]; 2893536Sgblack@eecs.umich.edu if (smi == 0) { 2902SN/A smCache[sysi-1][smid] = smi = ++numSm; 2912SN/A assert(smi < 65535); 2922SN/A smMap.push_back(std::make_pair<int, Id>(sysi, smid)); 2932SN/A } 2942SN/A return smi; 2952SN/A } 2962SN/A 2972SN/A // Turn a state machine string, state string into a small int 2983536Sgblack@eecs.umich.edu // for annotation output 2992SN/A int 30012449Sgabeblack@google.com getSt(std::string sm, std::string s) 30112449Sgabeblack@google.com { 3022SN/A int sti, smi; 3032SN/A 304 smi = smtCache[sm]; 305 if (smi == 0) 306 smi = smtCache[sm] = ++numSmt; 307 308 while (stCache.size() < smi) { 309 //stCache.resize(sm); 310 stCache.push_back(SCache()); 311 numSt.push_back(0); 312 } 313 //assert(stCache.size() == sm); 314 //assert(numSt.size() == sm); 315 sti = stCache[smi-1][s]; 316 if (sti == 0) 317 stCache[smi-1][s] = sti = ++numSt[smi-1]; 318 return sti; 319 } 320 321 // Turn state machine pointer into a smal int for annotation output 322 int 323 getSys(System *s) 324 { 325 NameCache::iterator i = nameCache.find(s); 326 if (i == nameCache.end()) { 327 nameCache[s] = std::make_pair<std::string,int>(s->name(), ++numSys); 328 i = nameCache.find(s); 329 // might need to put smstackid into map here, but perhaps not 330 //smStack.push_back(std::vector<int>()); 331 //swExpl.push_back(false); 332 numQ.push_back(0); 333 qCache.push_back(IdHCache()); 334 smCache.push_back(IdHCache()); 335 scLinks.push_back(ScHCache()); 336 } 337 return i->second.second; 338 } 339 340 // Turn queue name, and queue context into small int for 341 // annotation output 342 int 343 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