cp_annotate.hh revision 6214:1ec0ec8933ae
1298SN/A/* 22188SN/A * Copyright (c) 2006-2009 The Regents of The University of Michigan 3298SN/A * All rights reserved. 4298SN/A * 5298SN/A * Redistribution and use in source and binary forms, with or without 6298SN/A * modification, are permitted provided that the following conditions are 7298SN/A * met: redistributions of source code must retain the above copyright 8298SN/A * notice, this list of conditions and the following disclaimer; 9298SN/A * redistributions in binary form must reproduce the above copyright 10298SN/A * notice, this list of conditions and the following disclaimer in the 11298SN/A * documentation and/or other materials provided with the distribution; 12298SN/A * neither the name of the copyright holders nor the names of its 13298SN/A * contributors may be used to endorse or promote products derived from 14298SN/A * this software without specific prior written permission. 15298SN/A * 16298SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17298SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18298SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19298SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20298SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21298SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22298SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23298SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24298SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25298SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26298SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Ali Saidi 29298SN/A */ 30298SN/A 311642SN/A#ifndef __BASE__CP_ANNOTATE_HH__ 32954SN/A#define __BASE__CP_ANNOTATE_HH__ 33956SN/A 34956SN/A#include "base/loader/symtab.hh" 354078Sbinkertn@umich.edu#include "config/cp_annotate.hh" 36299SN/A#include "base/types.hh" 37299SN/A#include "sim/serialize.hh" 385529Snate@binkert.org#include "sim/startup.hh" 392170SN/A#include "sim/system.hh" 405882Snate@binkert.org 411717SN/A#include <string> 422680Sktlim@umich.edu#include <list> 432313SN/A#include <vector> 445529Snate@binkert.org#include <map> 453565Sgblack@eecs.umich.edu#include "base/hashmap.hh" 46298SN/A#include "base/trace.hh" 475606Snate@binkert.org#if CP_ANNOTATE 48298SN/A#include "params/CPA.hh" 49695SN/A#endif 50695SN/A 51954SN/Aclass System; 525780Ssteve.reinhardt@amd.comclass ThreadContext; 532080SN/A 545780Ssteve.reinhardt@amd.com 55298SN/A#if !CP_ANNOTATE 56299SN/Aclass CPA 571052SN/A{ 58729SN/A public: 592107SN/A enum flags { 60298SN/A FL_NONE = 0x00, 615504Snate@binkert.org FL_HW = 0x01, 625504Snate@binkert.org FL_BAD = 0x02, 635780Ssteve.reinhardt@amd.com FL_QOPP = 0x04, 645780Ssteve.reinhardt@amd.com FL_WAIT = 0x08, 655504Snate@binkert.org FL_LINK = 0x10, 665504Snate@binkert.org FL_RESET = 0x20 67298SN/A }; 685504Snate@binkert.org 695504Snate@binkert.org static CPA *cpa() { return NULL; } 705504Snate@binkert.org static bool available() { return false; } 715504Snate@binkert.org bool enabled() { return false; } 725504Snate@binkert.org void swSmBegin(ThreadContext *tc) { return; } 735504Snate@binkert.org void swSmEnd(ThreadContext *tc) { return; } 745504Snate@binkert.org void swExplictBegin(ThreadContext *tc) { return; } 755529Snate@binkert.org void swAutoBegin(ThreadContext *tc, Addr next_pc) { return; } 765504Snate@binkert.org void swEnd(ThreadContext *tc) { return; } 775504Snate@binkert.org void swQ(ThreadContext *tc) { return; } 785504Snate@binkert.org void swDq(ThreadContext *tc) { return; } 795504Snate@binkert.org void swPq(ThreadContext *tc) { return; } 805504Snate@binkert.org void swRq(ThreadContext *tc) { return; } 815504Snate@binkert.org void swWf(ThreadContext *tc) { return; } 825504Snate@binkert.org void swWe(ThreadContext *tc) { return; } 835504Snate@binkert.org void swSq(ThreadContext *tc) { return; } 845504Snate@binkert.org void swAq(ThreadContext *tc) { return; } 855504Snate@binkert.org void swLink(ThreadContext *tc) { return; } 865504Snate@binkert.org void swIdentify(ThreadContext *tc) { return; } 875504Snate@binkert.org uint64_t swGetId(ThreadContext *tc) { return 0; } 885529Snate@binkert.org void swSyscallLink(ThreadContext *tc) { return; } 895504Snate@binkert.org void hwBegin(flags f, System *sys, uint64_t frame, std::string sm, 905504Snate@binkert.org std::string st) { return; } 915504Snate@binkert.org void hwQ(flags f, System *sys, uint64_t frame, std::string sm, 925504Snate@binkert.org std::string q, uint64_t qid, System *q_sys = NULL, 935504Snate@binkert.org int32_t count = 1) { return; } 945504Snate@binkert.org void hwDq(flags f, System *sys, uint64_t frame, std::string sm, 955606Snate@binkert.org std::string q, uint64_t qid, System *q_sys = NULL, 965504Snate@binkert.org int32_t count = 1) { return; } 975504Snate@binkert.org void hwPq(flags f, System *sys, uint64_t frame, std::string sm, 985504Snate@binkert.org std::string q, uint64_t qid, System *q_sys = NULL, 995504Snate@binkert.org int32_t count = 1) { return; } 1005504Snate@binkert.org void hwRq(flags f, System *sys, uint64_t frame, std::string sm, 1015504Snate@binkert.org std::string q, uint64_t qid, System *q_sys = NULL, 1025504Snate@binkert.org int32_t count = 1) { return; } 1035504Snate@binkert.org void hwWf(flags f, System *sys, uint64_t frame, std::string sm, 1045504Snate@binkert.org std::string q, uint64_t qid, System *q_sys = NULL, 1055504Snate@binkert.org int32_t count = 1) { return; } 1065504Snate@binkert.org void hwWe(flags f, System *sys, uint64_t frame, std::string sm, 1075504Snate@binkert.org std::string q, uint64_t qid, System *q_sys = NULL, 1085529Snate@binkert.org int32_t count = 1) { return; } 1095504Snate@binkert.org}; 1105504Snate@binkert.org#else 1115504Snate@binkert.orgclass CPA : SimObject 1125504Snate@binkert.org{ 1135504Snate@binkert.org public: 1145504Snate@binkert.org typedef CPAParams Params; 1155606Snate@binkert.org 1165504Snate@binkert.org /** The known operations that are written to the annotation output file. */ 1175504Snate@binkert.org enum ops { 1185504Snate@binkert.org OP_BEGIN = 0x01, 1195504Snate@binkert.org OP_WAIT_EMPTY = 0x02, 1205504Snate@binkert.org OP_WAIT_FULL = 0x03, 1215504Snate@binkert.org OP_QUEUE = 0x04, 1225504Snate@binkert.org OP_DEQUEUE = 0x05, 1235504Snate@binkert.org OP_SIZE_QUEUE = 0x08, 1245504Snate@binkert.org OP_PEEK = 0x09, 1255504Snate@binkert.org OP_LINK = 0x0A, 1265504Snate@binkert.org OP_IDENT = 0x0B, 1275504Snate@binkert.org OP_RESERVE = 0x0C 1285504Snate@binkert.org }; 1295504Snate@binkert.org 1305504Snate@binkert.org /** Flags for the various options.*/ 1315780Ssteve.reinhardt@amd.com enum flags { 1325780Ssteve.reinhardt@amd.com /* no flags */ 1335741Snate@binkert.org FL_NONE = 0x00, 1345741Snate@binkert.org /* operation was done on hardware */ 1355741Snate@binkert.org FL_HW = 0x01, 1365741Snate@binkert.org /* operation should cause a warning when encountered */ 1375741Snate@binkert.org FL_BAD = 0x02, 1385741Snate@binkert.org /* Queue like a stack, not a queue */ 1395504Snate@binkert.org FL_QOPP = 0x04, 1405808Snate@binkert.org /* Mark HW state as waiting for some non-resource constraint 1415808Snate@binkert.org * (e.g. wait because SM only starts after 10 items are queued) */ 1425808Snate@binkert.org FL_WAIT = 0x08, 1435808Snate@binkert.org /* operation is linking to another state machine */ 1445808Snate@binkert.org FL_LINK = 0x10, 1455808Snate@binkert.org /* queue should be completely cleared/reset before executing this 1465808Snate@binkert.org * operation */ 1475808Snate@binkert.org FL_RESET = 0x20 1485808Snate@binkert.org }; 1495504Snate@binkert.org 1505504Snate@binkert.org 1515504Snate@binkert.org 1525606Snate@binkert.org protected: 1535606Snate@binkert.org const Params * 1545504Snate@binkert.org params() const 1555504Snate@binkert.org { 1565780Ssteve.reinhardt@amd.com return dynamic_cast<const Params *>(_params); 1575780Ssteve.reinhardt@amd.com } 1585504Snate@binkert.org 1595504Snate@binkert.org /* struct that is written to the annotation output file */ 1605504Snate@binkert.org struct AnnotateData : public RefCounted { 1615504Snate@binkert.org 1625504Snate@binkert.org Tick time; 1635504Snate@binkert.org uint32_t data; 164711SN/A uint32_t orig_data; 165711SN/A uint16_t sm; 1665504Snate@binkert.org uint16_t stq; 1675504Snate@binkert.org uint8_t op; 168310SN/A uint8_t flag; 1695504Snate@binkert.org uint8_t cpu; 1705504Snate@binkert.org bool dump; 1713373Sstever@eecs.umich.edu 1725504Snate@binkert.org void serialize(std::ostream &os); 1735504Snate@binkert.org void unserialize(Checkpoint *cp, const std::string §ion); 1745504Snate@binkert.org 1755504Snate@binkert.org }; 1765504Snate@binkert.org 1775504Snate@binkert.org typedef RefCountingPtr<AnnotateData> AnnDataPtr; 1785504Snate@binkert.org 1795504Snate@binkert.org /* header for the annotation file */ 1805504Snate@binkert.org struct AnnotateHeader { 1815504Snate@binkert.org uint64_t version; 1825504Snate@binkert.org uint64_t num_recs; 1835504Snate@binkert.org uint64_t key_off; 1845504Snate@binkert.org uint64_t idx_off; 1855504Snate@binkert.org uint32_t key_len; 1865504Snate@binkert.org uint32_t idx_len; 1875504Snate@binkert.org }; 1885504Snate@binkert.org 1895504Snate@binkert.org AnnotateHeader ah; 1905504Snate@binkert.org 1915504Snate@binkert.org std::vector<uint64_t> annotateIdx; 1925504Snate@binkert.org 1935504Snate@binkert.org // number of state machines encountered in the simulation 1945504Snate@binkert.org int numSm; 1955504Snate@binkert.org // number of states encountered in the simulation 1965504Snate@binkert.org int numSmt; 1975504Snate@binkert.org // number of states/queues for a given state machine/system respectively 1985504Snate@binkert.org std::vector<int> numSt, numQ; 1995504Snate@binkert.org // number of systems in the simulation 2005504Snate@binkert.org int numSys; 2015504Snate@binkert.org // number of queues in the state machine 2025504Snate@binkert.org int numQs; 2035504Snate@binkert.org // maximum connection id assigned so far 2045504Snate@binkert.org uint64_t conId; 2055504Snate@binkert.org 2065504Snate@binkert.org // Convert state strings into state ids 2075780Ssteve.reinhardt@amd.com typedef m5::hash_map<std::string, int> SCache; 2085780Ssteve.reinhardt@amd.com typedef std::vector<SCache> StCache; 2095780Ssteve.reinhardt@amd.com 2105780Ssteve.reinhardt@amd.com // Convert sm and queue name,id into queue id 2115780Ssteve.reinhardt@amd.com typedef std::pair<std::string, uint64_t> Id; 2125780Ssteve.reinhardt@amd.com typedef m5::hash_map<Id, int> IdHCache; 2135780Ssteve.reinhardt@amd.com typedef std::vector<IdHCache> IdCache; 2145780Ssteve.reinhardt@amd.com 2155780Ssteve.reinhardt@amd.com // Hold mapping of sm and queues to output python 2165952Ssaidi@eecs.umich.edu typedef std::vector<std::pair<int, Id> > IdMap; 2175780Ssteve.reinhardt@amd.com 2185780Ssteve.reinhardt@amd.com // System pointer to name,id 2195780Ssteve.reinhardt@amd.com typedef std::map<System*, std::pair<std::string, int> > NameCache; 2205780Ssteve.reinhardt@amd.com 2215780Ssteve.reinhardt@amd.com // array of systems each of which is a stack of running sm 2225780Ssteve.reinhardt@amd.com typedef std::pair<int, uint64_t> StackId; 2235504Snate@binkert.org typedef std::map<StackId, std::vector<int> > SmStack; 2245504Snate@binkert.org 2255529Snate@binkert.org // map of each context and if it's currently in explict state mode 2265504Snate@binkert.org // states are not automatically updated until it leaves 2275504Snate@binkert.org typedef std::map<StackId, bool> SwExpl; 2285504Snate@binkert.org 2295504Snate@binkert.org typedef std::map<int,int> IMap; 2305504Snate@binkert.org // List of annotate records have not been written/completed yet 2315504Snate@binkert.org typedef std::list<AnnDataPtr> AnnotateList; 2325504Snate@binkert.org 2335504Snate@binkert.org // Maintain link state information 2345504Snate@binkert.org typedef std::map<int, int> LinkMap; 2355504Snate@binkert.org 2365504Snate@binkert.org // SC Links 2375504Snate@binkert.org typedef m5::hash_map<Id, AnnDataPtr> ScHCache; 2385529Snate@binkert.org typedef std::vector<ScHCache> ScCache; 2395504Snate@binkert.org 2405504Snate@binkert.org 2415504Snate@binkert.org AnnotateList data; 2425504Snate@binkert.org 2435504Snate@binkert.org // vector indexed by queueid to find current number of elements and bytes 2445504Snate@binkert.org std::vector<int> qSize; 2455504Snate@binkert.org std::vector<int32_t> qBytes; 2465504Snate@binkert.org 2475504Snate@binkert.org 2485504Snate@binkert.org // Turn state machine string into state machine id (small int) 2495504Snate@binkert.org // Used for outputting key to convert id back into string 2505504Snate@binkert.org SCache smtCache; 2515529Snate@binkert.org // Turn state machine id, state name into state id (small int) 2525504Snate@binkert.org StCache stCache; 2535504Snate@binkert.org // turn system, queue, and queue identify into qid (small int) 2545504Snate@binkert.org // turn system, state, and context into state machine id (small int) 2555504Snate@binkert.org IdCache qCache, smCache; 2565504Snate@binkert.org //Link state machines accross system calls 2575504Snate@binkert.org ScCache scLinks; 2585504Snate@binkert.org // System pointer to name,id 2595504Snate@binkert.org NameCache nameCache; 2605504Snate@binkert.org // Stack of state machines currently nested (should unwind correctly) 2615504Snate@binkert.org SmStack smStack; 2625504Snate@binkert.org // Map of currently outstanding links 2635504Snate@binkert.org LinkMap lnMap; 2645529Snate@binkert.org // If the state machine is currently exculding automatic changes 2655504Snate@binkert.org SwExpl swExpl; 2665504Snate@binkert.org // Last state that a given state machine was in 2675504Snate@binkert.org IMap lastState; 2685504Snate@binkert.org // Hold mapping of sm and queues to output python 2695504Snate@binkert.org IdMap smMap, qMap; 2705606Snate@binkert.org // Items still in queue, used for sanity checking 2715606Snate@binkert.org std::vector<AnnotateList> qData; 2725504Snate@binkert.org 2735504Snate@binkert.org void doDq(System *sys, int flags, int cpu, int sm, std::string q, int qi, 2745780Ssteve.reinhardt@amd.com int count); 2755780Ssteve.reinhardt@amd.com void doQ(System *sys, int flags, int cpu, int sm, std::string q, int qi, 2765504Snate@binkert.org int count); 2775504Snate@binkert.org 2785504Snate@binkert.org void doSwSmEnd(System *sys, int cpuid, std::string sm, uint64_t frame); 2795504Snate@binkert.org 2805504Snate@binkert.org // Turn a system id, state machine string, state machine id into a small int 2815504Snate@binkert.org // for annotation output 282310SN/A int 283299SN/A getSm(int sysi, std::string si, uint64_t id) 2845504Snate@binkert.org { 2852188SN/A int smi; 2865504Snate@binkert.org Id smid = Id(si, id); 2875504Snate@binkert.org 2885504Snate@binkert.org smi = smCache[sysi-1][smid]; 2892235SN/A if (smi == 0) { 2905504Snate@binkert.org smCache[sysi-1][smid] = smi = ++numSm; 2915504Snate@binkert.org assert(smi < 65535); 2923368Sstever@eecs.umich.edu smMap.push_back(std::make_pair<int, Id>(sysi, smid)); 2935504Snate@binkert.org } 2945504Snate@binkert.org return smi; 2955504Snate@binkert.org } 2965504Snate@binkert.org 2975504Snate@binkert.org // Turn a state machine string, state string into a small int 2985504Snate@binkert.org // for annotation output 2993368Sstever@eecs.umich.edu int 3005504Snate@binkert.org getSt(std::string sm, std::string s) 3015504Snate@binkert.org { 3025504Snate@binkert.org int sti, smi; 3032188SN/A 3042188SN/A smi = smtCache[sm]; 3055504Snate@binkert.org if (smi == 0) 3065504Snate@binkert.org smi = smtCache[sm] = ++numSmt; 3075504Snate@binkert.org 3085504Snate@binkert.org while (stCache.size() < smi) { 3095504Snate@binkert.org //stCache.resize(sm); 3102188SN/A stCache.push_back(SCache()); 3115780Ssteve.reinhardt@amd.com numSt.push_back(0); 3125780Ssteve.reinhardt@amd.com } 3135504Snate@binkert.org //assert(stCache.size() == sm); 3145504Snate@binkert.org //assert(numSt.size() == sm); 3155504Snate@binkert.org sti = stCache[smi-1][s]; 3165504Snate@binkert.org if (sti == 0) 3175504Snate@binkert.org stCache[smi-1][s] = sti = ++numSt[smi-1]; 3182235SN/A return sti; 3195504Snate@binkert.org } 3205504Snate@binkert.org 3215504Snate@binkert.org // Turn state machine pointer into a smal int for annotation output 3225504Snate@binkert.org int 3235504Snate@binkert.org getSys(System *s) 3243368Sstever@eecs.umich.edu { 3255504Snate@binkert.org 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