cp_annotate.hh revision 11168:f98eb2da15a4
16657Snate@binkert.org/*
26657Snate@binkert.org * Copyright (c) 2014 ARM Limited
36657Snate@binkert.org * All rights reserved.
46657Snate@binkert.org *
56657Snate@binkert.org * The license below extends only to copyright in the software and shall
66657Snate@binkert.org * not be construed as granting a license to any other intellectual
76657Snate@binkert.org * property including but not limited to intellectual property relating
86657Snate@binkert.org * to a hardware implementation of the functionality of the software
96657Snate@binkert.org * licensed hereunder.  You may use the software subject to the license
106657Snate@binkert.org * terms below provided that you ensure that this notice is replicated
116657Snate@binkert.org * unmodified and in its entirety in all distributions of the software,
126657Snate@binkert.org * modified or unmodified, in source code or in binary form.
136657Snate@binkert.org *
146657Snate@binkert.org * Copyright (c) 2006-2009 The Regents of The University of Michigan
156657Snate@binkert.org * All rights reserved.
166657Snate@binkert.org *
176657Snate@binkert.org * Redistribution and use in source and binary forms, with or without
186657Snate@binkert.org * modification, are permitted provided that the following conditions are
196657Snate@binkert.org * met: redistributions of source code must retain the above copyright
206657Snate@binkert.org * notice, this list of conditions and the following disclaimer;
216657Snate@binkert.org * redistributions in binary form must reproduce the above copyright
226657Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
236657Snate@binkert.org * documentation and/or other materials provided with the distribution;
246657Snate@binkert.org * neither the name of the copyright holders nor the names of its
256657Snate@binkert.org * contributors may be used to endorse or promote products derived from
266657Snate@binkert.org * this software without specific prior written permission.
276657Snate@binkert.org *
286999Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
296657Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
306657Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
316657Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
326657Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
338189SLisa.Hsu@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
346657Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
359499Snilay@cs.wisc.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
369499Snilay@cs.wisc.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
379364Snilay@cs.wisc.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
387055Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
396882SBrad.Beckmann@amd.com *
406882SBrad.Beckmann@amd.com * Authors: Ali Saidi
418191SLisa.Hsu@amd.com */
426882SBrad.Beckmann@amd.com
436882SBrad.Beckmann@amd.com#ifndef __BASE__CP_ANNOTATE_HH__
449102SNuwan.Jayasena@amd.com#define __BASE__CP_ANNOTATE_HH__
459366Snilay@cs.wisc.edu
469499Snilay@cs.wisc.edu#include <list>
479499Snilay@cs.wisc.edu#include <map>
489499Snilay@cs.wisc.edu#include <memory>
496882SBrad.Beckmann@amd.com#include <string>
506657Snate@binkert.org#include <unordered_map>
516657Snate@binkert.org#include <vector>
526657Snate@binkert.org
536657Snate@binkert.org#include "base/loader/symtab.hh"
546657Snate@binkert.org#include "base/trace.hh"
559366Snilay@cs.wisc.edu#include "base/types.hh"
567839Snilay@cs.wisc.edu#include "debug/AnnotateQ.hh"
576657Snate@binkert.org#include "config/cp_annotate.hh"
586882SBrad.Beckmann@amd.com#include "config/the_isa.hh"
596882SBrad.Beckmann@amd.com#include "sim/serialize.hh"
606882SBrad.Beckmann@amd.com#include "sim/system.hh"
616882SBrad.Beckmann@amd.com
626882SBrad.Beckmann@amd.com#if CP_ANNOTATE
636882SBrad.Beckmann@amd.com#include "params/CPA.hh"
646657Snate@binkert.org#endif
659366Snilay@cs.wisc.edu
669366Snilay@cs.wisc.educlass System;
676657Snate@binkert.orgclass ThreadContext;
686657Snate@binkert.org
696657Snate@binkert.org
706657Snate@binkert.org#if !CP_ANNOTATE
719104Shestness@cs.utexas.educlass CPA
726657Snate@binkert.org{
736657Snate@binkert.org  public:
746657Snate@binkert.org    enum flags {
756657Snate@binkert.org        FL_NONE     = 0x00,
767839Snilay@cs.wisc.edu        FL_HW       = 0x01,
777839Snilay@cs.wisc.edu        FL_BAD      = 0x02,
789366Snilay@cs.wisc.edu        FL_QOPP     = 0x04,
796657Snate@binkert.org        FL_WAIT     = 0x08,
806657Snate@binkert.org        FL_LINK     = 0x10,
816657Snate@binkert.org        FL_RESET    = 0x20
826657Snate@binkert.org    };
836657Snate@binkert.org
846657Snate@binkert.org    static CPA *cpa()                                        { return NULL; }
856657Snate@binkert.org    static bool available()                                 { return false; }
866657Snate@binkert.org    bool enabled()                                          { return false; }
876657Snate@binkert.org    void swSmBegin(ThreadContext *tc)                             { return; }
886657Snate@binkert.org    void swSmEnd(ThreadContext *tc)                               { return; }
896657Snate@binkert.org    void swExplictBegin(ThreadContext *tc)                        { return; }
906657Snate@binkert.org    void swAutoBegin(ThreadContext *tc, Addr next_pc)             { return; }
916657Snate@binkert.org    void swEnd(ThreadContext *tc)                                 { return; }
926657Snate@binkert.org    void swQ(ThreadContext *tc)                                   { return; }
936657Snate@binkert.org    void swDq(ThreadContext *tc)                                  { return; }
946657Snate@binkert.org    void swPq(ThreadContext *tc)                                  { return; }
956657Snate@binkert.org    void swRq(ThreadContext *tc)                                  { return; }
966657Snate@binkert.org    void swWf(ThreadContext *tc)                                  { return; }
976657Snate@binkert.org    void swWe(ThreadContext *tc)                                  { return; }
986779SBrad.Beckmann@amd.com    void swSq(ThreadContext *tc)                                  { return; }
996657Snate@binkert.org    void swAq(ThreadContext *tc)                                  { return; }
1006657Snate@binkert.org    void swLink(ThreadContext *tc)                                { return; }
1016657Snate@binkert.org    void swIdentify(ThreadContext *tc)                            { return; }
1026657Snate@binkert.org    uint64_t swGetId(ThreadContext *tc)                         { return 0; }
1036657Snate@binkert.org    void swSyscallLink(ThreadContext *tc)                         { return; }
1046657Snate@binkert.org    void hwBegin(flags f, System *sys, uint64_t frame, std::string sm,
1056657Snate@binkert.org                 std::string st)                                  { return; }
1066657Snate@binkert.org    void hwQ(flags f, System *sys, uint64_t frame, std::string sm,
1076657Snate@binkert.org             std::string q, uint64_t qid, System *q_sys = NULL,
1089104Shestness@cs.utexas.edu             int32_t count = 1)                                   { return; }
1099104Shestness@cs.utexas.edu    void hwDq(flags f, System *sys, uint64_t frame, std::string sm,
1109104Shestness@cs.utexas.edu              std::string q, uint64_t qid, System *q_sys = NULL,
1119104Shestness@cs.utexas.edu              int32_t count = 1)                                  { return; }
1126657Snate@binkert.org    void hwPq(flags f, System *sys, uint64_t frame, std::string sm,
1136657Snate@binkert.org              std::string q, uint64_t qid, System *q_sys = NULL,
1146657Snate@binkert.org              int32_t count = 1)                                  { return; }
1156657Snate@binkert.org    void hwRq(flags f, System *sys, uint64_t frame, std::string sm,
1166657Snate@binkert.org              std::string q, uint64_t qid, System *q_sys = NULL,
1176657Snate@binkert.org              int32_t count = 1)                                  { return; }
1186657Snate@binkert.org    void hwWf(flags f, System *sys, uint64_t frame, std::string sm,
1196657Snate@binkert.org              std::string q, uint64_t qid, System *q_sys = NULL,
1206657Snate@binkert.org              int32_t count = 1)                                  { return; }
1216657Snate@binkert.org    void hwWe(flags f, System *sys, uint64_t frame, std::string sm,
1226657Snate@binkert.org              std::string q, uint64_t qid, System *q_sys = NULL,
1236657Snate@binkert.org              int32_t count = 1)                                  { return; }
1246657Snate@binkert.org};
1256657Snate@binkert.org#else
1266657Snate@binkert.org
1277839Snilay@cs.wisc.edu/**
1287839Snilay@cs.wisc.edu * Provide a hash function for the CPI Id type
1297839Snilay@cs.wisc.edu */
1307839Snilay@cs.wisc.edunamespace std {
1317839Snilay@cs.wisc.edutemplate <>
1327839Snilay@cs.wisc.edustruct hash<std::pair<std::string, uint64_t> >
1337839Snilay@cs.wisc.edu{
1347839Snilay@cs.wisc.edu
1357839Snilay@cs.wisc.edu    size_t
1367839Snilay@cs.wisc.edu    operator()(const std::pair<std::string, uint64_t>& x) const
1377839Snilay@cs.wisc.edu    {
1387839Snilay@cs.wisc.edu        return hash<std::string>()(x.first);
1397839Snilay@cs.wisc.edu    }
1407839Snilay@cs.wisc.edu
1417839Snilay@cs.wisc.edu};
1426657Snate@binkert.org}
1436657Snate@binkert.org
1446657Snate@binkert.orgclass CPA : SimObject
1456657Snate@binkert.org{
1466657Snate@binkert.org  public:
1476657Snate@binkert.org    typedef CPAParams Params;
1486657Snate@binkert.org
1496657Snate@binkert.org    /** The known operations that are written to the annotation output file. */
1506657Snate@binkert.org    enum ops {
1516657Snate@binkert.org        OP_BEGIN           = 0x01,
1526657Snate@binkert.org        OP_WAIT_EMPTY      = 0x02,
1536657Snate@binkert.org        OP_WAIT_FULL       = 0x03,
1546657Snate@binkert.org        OP_QUEUE           = 0x04,
1556657Snate@binkert.org        OP_DEQUEUE         = 0x05,
1566657Snate@binkert.org        OP_SIZE_QUEUE      = 0x08,
1576657Snate@binkert.org        OP_PEEK            = 0x09,
1586657Snate@binkert.org        OP_LINK            = 0x0A,
1596657Snate@binkert.org        OP_IDENT           = 0x0B,
1606657Snate@binkert.org        OP_RESERVE         = 0x0C
1616657Snate@binkert.org    };
1626657Snate@binkert.org
1636657Snate@binkert.org    /** Flags for the various options.*/
1646657Snate@binkert.org    enum flags {
1656657Snate@binkert.org        /* no flags */
1666657Snate@binkert.org        FL_NONE     = 0x00,
1676657Snate@binkert.org        /* operation was done on hardware */
1686657Snate@binkert.org        FL_HW       = 0x01,
1696657Snate@binkert.org        /* operation should cause a warning when encountered */
1706657Snate@binkert.org        FL_BAD      = 0x02,
1716657Snate@binkert.org        /* Queue like a stack, not a queue */
1729219Spower.jg@gmail.com        FL_QOPP     = 0x04,
1736877Ssteve.reinhardt@amd.com        /* Mark HW state as waiting for some non-resource constraint
1746657Snate@binkert.org         * (e.g. wait because SM only starts after 10 items are queued) */
1759219Spower.jg@gmail.com        FL_WAIT     = 0x08,
1766657Snate@binkert.org        /* operation is linking to another state machine */
1779219Spower.jg@gmail.com        FL_LINK     = 0x10,
1786657Snate@binkert.org        /* queue should be completely cleared/reset before executing this
1796657Snate@binkert.org         * operation */
1807542SBrad.Beckmann@amd.com        FL_RESET    = 0x20
1817542SBrad.Beckmann@amd.com    };
1826657Snate@binkert.org
1836877Ssteve.reinhardt@amd.com
1846999Snate@binkert.org
1856877Ssteve.reinhardt@amd.com  protected:
1866877Ssteve.reinhardt@amd.com    const Params *
1876877Ssteve.reinhardt@amd.com        params() const
1886877Ssteve.reinhardt@amd.com        {
1896877Ssteve.reinhardt@amd.com            return dynamic_cast<const Params *>(_params);
1906877Ssteve.reinhardt@amd.com        }
1916877Ssteve.reinhardt@amd.com
1926877Ssteve.reinhardt@amd.com    /* struct that is written to the annotation output file */
1936877Ssteve.reinhardt@amd.com    struct AnnotateData : public Serializable {
1946877Ssteve.reinhardt@amd.com
1959338SAndreas.Sandberg@arm.com        Tick time;
1966877Ssteve.reinhardt@amd.com        uint32_t data;
1976877Ssteve.reinhardt@amd.com        uint32_t orig_data;
1986877Ssteve.reinhardt@amd.com        uint16_t sm;
1996877Ssteve.reinhardt@amd.com        uint16_t stq;
2006877Ssteve.reinhardt@amd.com        uint8_t  op;
2016877Ssteve.reinhardt@amd.com        uint8_t  flag;
2026882SBrad.Beckmann@amd.com        uint8_t  cpu;
2036882SBrad.Beckmann@amd.com        bool dump;
2046882SBrad.Beckmann@amd.com
2056882SBrad.Beckmann@amd.com        void serialize(CheckpointOut &cp) const override;
2066882SBrad.Beckmann@amd.com        void unserialize(CheckpointIn &cp) override;
2076882SBrad.Beckmann@amd.com    };
2086882SBrad.Beckmann@amd.com
2096877Ssteve.reinhardt@amd.com    typedef std::shared_ptr<AnnotateData> AnnDataPtr;
2106877Ssteve.reinhardt@amd.com
2116877Ssteve.reinhardt@amd.com    /* header for the annotation file */
2126877Ssteve.reinhardt@amd.com    struct AnnotateHeader {
2136657Snate@binkert.org        uint64_t version;
2146657Snate@binkert.org        uint64_t num_recs;
2156999Snate@binkert.org        uint64_t key_off;
2166657Snate@binkert.org        uint64_t idx_off;
2176657Snate@binkert.org        uint32_t key_len;
2186657Snate@binkert.org        uint32_t idx_len;
2196657Snate@binkert.org    };
2206657Snate@binkert.org
2216657Snate@binkert.org    AnnotateHeader ah;
2227007Snate@binkert.org
2236657Snate@binkert.org    std::vector<uint64_t> annotateIdx;
2246657Snate@binkert.org
2256657Snate@binkert.org    // number of state machines encountered in the simulation
2266657Snate@binkert.org    int numSm;
2276657Snate@binkert.org    // number of states encountered in the simulation
2287007Snate@binkert.org    int numSmt;
2297007Snate@binkert.org    // number of states/queues for a given state machine/system respectively
2306657Snate@binkert.org    std::vector<int> numSt, numQ;
2317002Snate@binkert.org    // number of systems in the simulation
2327002Snate@binkert.org    int numSys;
2337002Snate@binkert.org    // number of queues in the state machine
2347002Snate@binkert.org    int numQs;
2358229Snate@binkert.org    // maximum connection id assigned so far
2368229Snate@binkert.org    uint64_t conId;
2376657Snate@binkert.org
2386657Snate@binkert.org    // Convert state strings into state ids
2398229Snate@binkert.org    typedef std::unordered_map<std::string, int> SCache;
2408229Snate@binkert.org    typedef std::vector<SCache> StCache;
2418229Snate@binkert.org
2428229Snate@binkert.org    // Convert sm and queue name,id into queue id
2436657Snate@binkert.org    typedef std::pair<std::string, uint64_t> Id;
2446657Snate@binkert.org    typedef std::unordered_map<Id, int> IdHCache;
2456657Snate@binkert.org    typedef std::vector<IdHCache> IdCache;
2466657Snate@binkert.org
2476793SBrad.Beckmann@amd.com    // Hold mapping of sm and queues to output python
2486657Snate@binkert.org    typedef std::vector<std::pair<int, Id> > IdMap;
2496657Snate@binkert.org
2506657Snate@binkert.org    // System pointer to name,id
2516657Snate@binkert.org    typedef std::map<System*, std::pair<std::string, int> > NameCache;
2526657Snate@binkert.org
2537002Snate@binkert.org    // array of systems each of which is a stack of running sm
2546657Snate@binkert.org    typedef std::pair<int, uint64_t> StackId;
2557007Snate@binkert.org    typedef std::map<StackId, std::vector<int> > SmStack;
2567007Snate@binkert.org
2579271Snilay@cs.wisc.edu    // map of each context and if it's currently in explict state mode
2586877Ssteve.reinhardt@amd.com    // states are not automatically updated until it leaves
2596877Ssteve.reinhardt@amd.com    typedef std::map<StackId, bool> SwExpl;
2606657Snate@binkert.org
2616877Ssteve.reinhardt@amd.com    typedef std::map<int,int> IMap;
2626657Snate@binkert.org    // List of annotate records have not been written/completed yet
2636657Snate@binkert.org    typedef std::list<AnnDataPtr> AnnotateList;
2647002Snate@binkert.org
2657002Snate@binkert.org    // Maintain link state information
2667567SBrad.Beckmann@amd.com    typedef std::map<int, int> LinkMap;
2677567SBrad.Beckmann@amd.com
2687922SBrad.Beckmann@amd.com    // SC Links
2696881SBrad.Beckmann@amd.com    typedef std::unordered_map<Id, AnnDataPtr> ScHCache;
2707002Snate@binkert.org    typedef std::vector<ScHCache> ScCache;
2716657Snate@binkert.org
2727002Snate@binkert.org
2736902SBrad.Beckmann@amd.com    AnnotateList data;
2746863Sdrh5@cs.wisc.edu
2756863Sdrh5@cs.wisc.edu    // vector indexed by queueid to find current number of elements and bytes
2768683Snilay@cs.wisc.edu    std::vector<int> qSize;
2778683Snilay@cs.wisc.edu    std::vector<int32_t> qBytes;
2787007Snate@binkert.org
2799302Snilay@cs.wisc.edu
2809302Snilay@cs.wisc.edu    // Turn state machine string into state machine id (small int)
2819302Snilay@cs.wisc.edu    // Used for outputting key to convert id back into string
2826657Snate@binkert.org    SCache smtCache;
2836657Snate@binkert.org    // Turn state machine id, state name into state id (small int)
2846657Snate@binkert.org    StCache stCache;
2856657Snate@binkert.org    // turn system, queue, and queue identify into qid (small int)
2866657Snate@binkert.org    // turn system, state, and context into state machine id (small int)
2876657Snate@binkert.org    IdCache qCache, smCache;
2886882SBrad.Beckmann@amd.com    //Link state machines accross system calls
2896882SBrad.Beckmann@amd.com    ScCache scLinks;
2906882SBrad.Beckmann@amd.com    // System pointer to name,id
2916882SBrad.Beckmann@amd.com    NameCache nameCache;
2926657Snate@binkert.org    // Stack of state machines currently nested (should unwind correctly)
2936657Snate@binkert.org    SmStack smStack;
2947007Snate@binkert.org    // Map of currently outstanding links
2957839Snilay@cs.wisc.edu    LinkMap lnMap;
2967839Snilay@cs.wisc.edu    // If the state machine is currently exculding automatic changes
2977839Snilay@cs.wisc.edu    SwExpl swExpl;
2987839Snilay@cs.wisc.edu    // Last state that a given state machine was in
2997839Snilay@cs.wisc.edu    IMap lastState;
3007839Snilay@cs.wisc.edu    // Hold mapping of sm and queues to output python
3017839Snilay@cs.wisc.edu    IdMap smMap, qMap;
3027839Snilay@cs.wisc.edu    // Items still in queue, used for sanity checking
3037839Snilay@cs.wisc.edu    std::vector<AnnotateList> qData;
3047839Snilay@cs.wisc.edu
3057839Snilay@cs.wisc.edu    void doDq(System *sys, int flags, int cpu, int sm, std::string q, int qi,
3067839Snilay@cs.wisc.edu            int count);
3077007Snate@binkert.org    void doQ(System *sys, int flags, int cpu, int sm, std::string q, int qi,
3087007Snate@binkert.org            int count);
3097007Snate@binkert.org
3107007Snate@binkert.org    void doSwSmEnd(System *sys, int cpuid, std::string sm, uint64_t frame);
3117007Snate@binkert.org
3127839Snilay@cs.wisc.edu    // Turn a system id, state machine string, state machine id into a small int
3137839Snilay@cs.wisc.edu    // for annotation output
3147839Snilay@cs.wisc.edu    int
3157839Snilay@cs.wisc.edu    getSm(int sysi, std::string si, uint64_t id)
3167839Snilay@cs.wisc.edu    {
3177839Snilay@cs.wisc.edu        int smi;
3187839Snilay@cs.wisc.edu        Id smid = Id(si, id);
3197839Snilay@cs.wisc.edu
3207839Snilay@cs.wisc.edu        smi = smCache[sysi-1][smid];
3217839Snilay@cs.wisc.edu        if (smi == 0) {
3227839Snilay@cs.wisc.edu            smCache[sysi-1][smid] = smi = ++numSm;
3237839Snilay@cs.wisc.edu            assert(smi < 65535);
3247007Snate@binkert.org            smMap.push_back(std::make_pair(sysi, smid));
3257007Snate@binkert.org        }
3267542SBrad.Beckmann@amd.com        return smi;
3277542SBrad.Beckmann@amd.com    }
3286657Snate@binkert.org
3297007Snate@binkert.org    // Turn a state machine string, state string into a small int
3306657Snate@binkert.org    // for annotation output
3316657Snate@binkert.org    int
3326657Snate@binkert.org    getSt(std::string sm, std::string s)
3336657Snate@binkert.org    {
3346657Snate@binkert.org        int sti, smi;
3356657Snate@binkert.org
3366657Snate@binkert.org        smi = smtCache[sm];
3376657Snate@binkert.org        if (smi == 0)
3387839Snilay@cs.wisc.edu           smi = smtCache[sm] = ++numSmt;
3397839Snilay@cs.wisc.edu
3407839Snilay@cs.wisc.edu        while (stCache.size() < smi) {
3417839Snilay@cs.wisc.edu            //stCache.resize(sm);
3427839Snilay@cs.wisc.edu            stCache.push_back(SCache());
3437839Snilay@cs.wisc.edu            numSt.push_back(0);
3447839Snilay@cs.wisc.edu        }
3457839Snilay@cs.wisc.edu        //assert(stCache.size() == sm);
3467839Snilay@cs.wisc.edu        //assert(numSt.size() == sm);
3477839Snilay@cs.wisc.edu        sti = stCache[smi-1][s];
3487839Snilay@cs.wisc.edu        if (sti == 0)
3497839Snilay@cs.wisc.edu            stCache[smi-1][s] = sti = ++numSt[smi-1];
3507839Snilay@cs.wisc.edu        return sti;
3517839Snilay@cs.wisc.edu    }
3527839Snilay@cs.wisc.edu
3537839Snilay@cs.wisc.edu    // Turn state machine pointer into a smal int for annotation output
3546657Snate@binkert.org    int
3556657Snate@binkert.org    getSys(System *s)
3566657Snate@binkert.org    {
3576657Snate@binkert.org        NameCache::iterator i = nameCache.find(s);
3587839Snilay@cs.wisc.edu        if (i == nameCache.end()) {
3597839Snilay@cs.wisc.edu            nameCache[s] = std::make_pair(s->name(), ++numSys);
3607839Snilay@cs.wisc.edu            i = nameCache.find(s);
3617839Snilay@cs.wisc.edu            // might need to put smstackid into map here, but perhaps not
3627839Snilay@cs.wisc.edu            //smStack.push_back(std::vector<int>());
3637839Snilay@cs.wisc.edu            //swExpl.push_back(false);
3647839Snilay@cs.wisc.edu            numQ.push_back(0);
3657839Snilay@cs.wisc.edu            qCache.push_back(IdHCache());
3667839Snilay@cs.wisc.edu            smCache.push_back(IdHCache());
3677839Snilay@cs.wisc.edu            scLinks.push_back(ScHCache());
3687839Snilay@cs.wisc.edu        }
3697839Snilay@cs.wisc.edu        return i->second.second;
3707839Snilay@cs.wisc.edu    }
3717839Snilay@cs.wisc.edu
3727839Snilay@cs.wisc.edu    // Turn queue name, and queue context into small int for
3737839Snilay@cs.wisc.edu    // annotation output
3746657Snate@binkert.org    int
3756657Snate@binkert.org    getQ(int sys, std::string q, uint64_t id)
3766657Snate@binkert.org    {
3776657Snate@binkert.org        int qi;
3787007Snate@binkert.org        Id qid = Id(q, id);
3796657Snate@binkert.org
3806657Snate@binkert.org        qi = qCache[sys-1][qid];
3819273Snilay@cs.wisc.edu        if (qi == 0) {
3826657Snate@binkert.org            qi = qCache[sys-1][qid] = ++numQs;
3836657Snate@binkert.org            assert(qi < 65535);
3846657Snate@binkert.org            qSize.push_back(0);
3856657Snate@binkert.org            qBytes.push_back(0);
3866657Snate@binkert.org            qData.push_back(AnnotateList());
3876657Snate@binkert.org            numQ[sys-1]++;
3886657Snate@binkert.org            qMap.push_back(std::make_pair(sys, qid));
3897007Snate@binkert.org        }
3906657Snate@binkert.org        return qi;
3916657Snate@binkert.org    }
3929219Spower.jg@gmail.com
3936657Snate@binkert.org    void swBegin(System *sys, int cpuid, std::string st, uint64_t frame,
3946657Snate@binkert.org            bool expl = false, int flags = FL_NONE);
3956999Snate@binkert.org
3966657Snate@binkert.org    AnnDataPtr add(int t, int f, int c, int sm, int stq, int32_t data=0);
3976657Snate@binkert.org
3986657Snate@binkert.org    std::ostream *osbin;
3996657Snate@binkert.org
4007007Snate@binkert.org    bool _enabled;
4016657Snate@binkert.org
4026657Snate@binkert.org    /** Only allow one CPA object in a system. It doesn't make sense to have
4036657Snate@binkert.org     * more that one per simulation because if a part of the system was
4046657Snate@binkert.org     * important it would have annotations and queues, and with more than one
4056657Snate@binkert.org     * object none of the sanity checking for queues will work. */
4068946Sandreas.hansson@arm.com    static bool exists;
4078946Sandreas.hansson@arm.com    static CPA *_cpa;
4088946Sandreas.hansson@arm.com
4097832Snate@binkert.org
4107002Snate@binkert.org    std::map<std::string, SymbolTable*> userApp;
4117002Snate@binkert.org
4127002Snate@binkert.org  public:
4138641Snate@binkert.org    static CPA *cpa() { return _cpa; }
4147056Snate@binkert.org    void swSmBegin(ThreadContext *tc);
4158232Snate@binkert.org    void swSmEnd(ThreadContext *tc);
4168232Snate@binkert.org    void swExplictBegin(ThreadContext *tc);
4176657Snate@binkert.org    void swAutoBegin(ThreadContext *tc, Addr next_pc);
4188229Snate@binkert.org    void swEnd(ThreadContext *tc);
4196657Snate@binkert.org    void swQ(ThreadContext *tc);
4206657Snate@binkert.org    void swDq(ThreadContext *tc);
4217056Snate@binkert.org    void swPq(ThreadContext *tc);
4226657Snate@binkert.org    void swRq(ThreadContext *tc);
4239219Spower.jg@gmail.com    void swWf(ThreadContext *tc);
4249219Spower.jg@gmail.com    void swWe(ThreadContext *tc);
4259219Spower.jg@gmail.com    void swSq(ThreadContext *tc);
4269219Spower.jg@gmail.com    void swAq(ThreadContext *tc);
4279219Spower.jg@gmail.com    void swLink(ThreadContext *tc);
4287002Snate@binkert.org    void swIdentify(ThreadContext *tc);
4297002Snate@binkert.org    uint64_t swGetId(ThreadContext *tc);
4306657Snate@binkert.org    void swSyscallLink(ThreadContext *tc);
4316657Snate@binkert.org
4326657Snate@binkert.org    inline void hwBegin(flags f, System *sys, uint64_t frame, std::string sm,
4336657Snate@binkert.org            std::string st)
4346657Snate@binkert.org    {
4356793SBrad.Beckmann@amd.com        if (!enabled())
4366657Snate@binkert.org            return;
4376657Snate@binkert.org
4386657Snate@binkert.org        int sysi = getSys(sys);
4396657Snate@binkert.org        int smi = getSm(sysi, sm, frame);
4406877Ssteve.reinhardt@amd.com        add(OP_BEGIN, FL_HW | f, 0, smi, getSt(sm, st));
4416877Ssteve.reinhardt@amd.com        if (f & FL_BAD)
4426877Ssteve.reinhardt@amd.com            warn("BAD state encountered: at cycle %d: %s\n", curTick(), st);
4436877Ssteve.reinhardt@amd.com    }
4446877Ssteve.reinhardt@amd.com
4456877Ssteve.reinhardt@amd.com    inline void hwQ(flags f, System *sys, uint64_t frame, std::string sm,
4466657Snate@binkert.org            std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
4477542SBrad.Beckmann@amd.com    {
4486657Snate@binkert.org        if (!enabled())
4497007Snate@binkert.org            return;
4506657Snate@binkert.org
4516657Snate@binkert.org        int sysi = getSys(sys);
4527007Snate@binkert.org        int qi = getQ(q_sys ?  getSys(q_sys) : sysi, q, qid);
4536657Snate@binkert.org        DPRINTFS(AnnotateQ, sys,
4546877Ssteve.reinhardt@amd.com                "hwQ: %s[%#x] cur size %d %d bytes: %d adding: %d\n",
4556877Ssteve.reinhardt@amd.com                q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
4566657Snate@binkert.org        doQ(sys, FL_HW | f, 0, getSm(sysi, sm, frame), q, qi, count);
4578532SLisa.Hsu@amd.com
4586657Snate@binkert.org    }
4597567SBrad.Beckmann@amd.com
4607567SBrad.Beckmann@amd.com    inline void hwDq(flags f, System *sys, uint64_t frame, std::string sm,
4617567SBrad.Beckmann@amd.com            std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
4627567SBrad.Beckmann@amd.com    {
4637567SBrad.Beckmann@amd.com        if (!enabled())
4647567SBrad.Beckmann@amd.com            return;
4656657Snate@binkert.org
4666882SBrad.Beckmann@amd.com        int sysi = getSys(sys);
4676882SBrad.Beckmann@amd.com        int qi = getQ(q_sys ?  getSys(q_sys) : sysi, q, qid);
4686882SBrad.Beckmann@amd.com        DPRINTFS(AnnotateQ, sys,
4696882SBrad.Beckmann@amd.com                "hwDQ: %s[%#x] cur size %d %d bytes: %d removing: %d\n",
4706882SBrad.Beckmann@amd.com                q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
4716882SBrad.Beckmann@amd.com        doDq(sys, FL_HW | f, 0, getSm(sysi,sm, frame), q, qi, count);
4726882SBrad.Beckmann@amd.com    }
4738189SLisa.Hsu@amd.com
4748189SLisa.Hsu@amd.com    inline void hwPq(flags f, System *sys, uint64_t frame, std::string sm,
4756877Ssteve.reinhardt@amd.com            std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
4768189SLisa.Hsu@amd.com    {
4778189SLisa.Hsu@amd.com        if (!enabled())
4788189SLisa.Hsu@amd.com            return;
4798189SLisa.Hsu@amd.com
4806882SBrad.Beckmann@amd.com        int sysi = getSys(sys);
4816882SBrad.Beckmann@amd.com        int qi = getQ(q_sys ?  getSys(q_sys) : sysi, q, qid);
4826882SBrad.Beckmann@amd.com        DPRINTFS(AnnotateQ, sys,
4836882SBrad.Beckmann@amd.com                "hwPQ: %s[%#x] cur size %d %d bytes: %d peeking: %d\n",
4846882SBrad.Beckmann@amd.com                q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
4856882SBrad.Beckmann@amd.com        add(OP_PEEK, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
4866882SBrad.Beckmann@amd.com    }
4876882SBrad.Beckmann@amd.com
4886882SBrad.Beckmann@amd.com    inline void hwRq(flags f, System *sys, uint64_t frame, std::string sm,
4896882SBrad.Beckmann@amd.com            std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
4908189SLisa.Hsu@amd.com    {
4916882SBrad.Beckmann@amd.com        if (!enabled())
4926882SBrad.Beckmann@amd.com            return;
4936882SBrad.Beckmann@amd.com
4948189SLisa.Hsu@amd.com        int sysi = getSys(sys);
4958189SLisa.Hsu@amd.com        int qi = getQ(q_sys ?  getSys(q_sys) : sysi, q, qid);
4968189SLisa.Hsu@amd.com        DPRINTFS(AnnotateQ, sys,
4978189SLisa.Hsu@amd.com                "hwRQ: %s[%#x] cur size %d %d bytes: %d reserving: %d\n",
4988938SLisa.Hsu@amd.com                q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
4998938SLisa.Hsu@amd.com        add(OP_RESERVE, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
5008938SLisa.Hsu@amd.com    }
5018938SLisa.Hsu@amd.com
5028938SLisa.Hsu@amd.com    inline void hwWf(flags f, System *sys, uint64_t frame, std::string sm,
5038938SLisa.Hsu@amd.com            std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
5048938SLisa.Hsu@amd.com    {
5056888SBrad.Beckmann@amd.com        if (!enabled())
5066888SBrad.Beckmann@amd.com            return;
5076888SBrad.Beckmann@amd.com
5086888SBrad.Beckmann@amd.com        int sysi = getSys(sys);
5096888SBrad.Beckmann@amd.com        int qi = getQ(q_sys ?  getSys(q_sys) : sysi, q, qid);
5108189SLisa.Hsu@amd.com        add(OP_WAIT_FULL, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
5116888SBrad.Beckmann@amd.com    }
5126888SBrad.Beckmann@amd.com
5136657Snate@binkert.org    inline void hwWe(flags f, System *sys, uint64_t frame, std::string sm,
5146888SBrad.Beckmann@amd.com            std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
5156888SBrad.Beckmann@amd.com    {
5166888SBrad.Beckmann@amd.com        if (!enabled())
5176888SBrad.Beckmann@amd.com            return;
5186657Snate@binkert.org
5196657Snate@binkert.org        int sysi = getSys(sys);
5206657Snate@binkert.org        int qi = getQ(q_sys ?  getSys(q_sys) : sysi, q, qid);
5216657Snate@binkert.org        add(OP_WAIT_EMPTY, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
5226657Snate@binkert.org    }
5236657Snate@binkert.org
5246657Snate@binkert.org  public:
5256657Snate@binkert.org    CPA(Params *p);
5266657Snate@binkert.org    void startup();
5277007Snate@binkert.org
5287007Snate@binkert.org    uint64_t getFrame(ThreadContext *tc);
5296657Snate@binkert.org
5307007Snate@binkert.org    static bool available()  { return true; }
5317007Snate@binkert.org
5329465Snilay@cs.wisc.edu    bool
5339465Snilay@cs.wisc.edu    enabled()
5347007Snate@binkert.org    {
5356657Snate@binkert.org        if (!this)
5366657Snate@binkert.org            return false;
5376657Snate@binkert.org        return _enabled;
5387007Snate@binkert.org    }
5397542SBrad.Beckmann@amd.com
5407542SBrad.Beckmann@amd.com    void dump(bool all);
5417007Snate@binkert.org    void dumpKey();
5426657Snate@binkert.org
5436657Snate@binkert.org    void serialize(CheckpointOut &cp) const override;
5446657Snate@binkert.org    void unserialize(CheckpointIn &cp) override;
5456657Snate@binkert.org};
5466657Snate@binkert.org#endif // !CP_ANNOTATE
5476657Snate@binkert.org
5486657Snate@binkert.org#endif //__BASE__CP_ANNOTATE_HH__
5496657Snate@binkert.org
5506657Snate@binkert.org