cp_annotate.cc revision 10377
12221SN/A/*
22221SN/A * Copyright (c) 2006-2009 The Regents of The University of Michigan
32221SN/A * All rights reserved.
42221SN/A *
52221SN/A * Redistribution and use in source and binary forms, with or without
62221SN/A * modification, are permitted provided that the following conditions are
72221SN/A * met: redistributions of source code must retain the above copyright
82221SN/A * notice, this list of conditions and the following disclaimer;
92221SN/A * redistributions in binary form must reproduce the above copyright
102221SN/A * notice, this list of conditions and the following disclaimer in the
112221SN/A * documentation and/or other materials provided with the distribution;
122221SN/A * neither the name of the copyright holders nor the names of its
132221SN/A * contributors may be used to endorse or promote products derived from
142221SN/A * this software without specific prior written permission.
152221SN/A *
162221SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172221SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182221SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192221SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202221SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212221SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222221SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232221SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242221SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252221SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262221SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Ali Saidi
292665Ssaidi@eecs.umich.edu */
302221SN/A
312221SN/A#include "arch/generic/linux/threadinfo.hh"
323415Sgblack@eecs.umich.edu#include "arch/utility.hh"
333415Sgblack@eecs.umich.edu#include "base/loader/object_file.hh"
342223SN/A#include "base/callback.hh"
353415Sgblack@eecs.umich.edu#include "base/cp_annotate.hh"
363578Sgblack@eecs.umich.edu#include "base/output.hh"
373415Sgblack@eecs.umich.edu#include "base/trace.hh"
383415Sgblack@eecs.umich.edu#include "config/the_isa.hh"
393523Sgblack@eecs.umich.edu#include "cpu/thread_context.hh"
403415Sgblack@eecs.umich.edu#include "debug/Annotate.hh"
412680Sktlim@umich.edu#include "debug/AnnotateVerbose.hh"
422800Ssaidi@eecs.umich.edu#include "sim/arguments.hh"
433523Sgblack@eecs.umich.edu#include "sim/core.hh"
443415Sgblack@eecs.umich.edu#include "sim/sim_exit.hh"
452800Ssaidi@eecs.umich.edu#include "sim/system.hh"
462800Ssaidi@eecs.umich.edu
472221SN/Astruct CPAIgnoreSymbol
483415Sgblack@eecs.umich.edu{
493415Sgblack@eecs.umich.edu    const char *symbol;
502223SN/A    size_t len;
512221SN/A};
522221SN/A#define CPA_IGNORE_SYMBOL(sym) { #sym, sizeof(#sym) }
533573Sgblack@eecs.umich.edu
543576Sgblack@eecs.umich.eduCPAIgnoreSymbol ignoreSymbols[] = {
553576Sgblack@eecs.umich.edu    CPA_IGNORE_SYMBOL("m5a_"),
562221SN/A    CPA_IGNORE_SYMBOL("ret_from_sys_call"),
573573Sgblack@eecs.umich.edu    CPA_IGNORE_SYMBOL("ret_from_reschedule"),
583576Sgblack@eecs.umich.edu    CPA_IGNORE_SYMBOL("_spin_"),
593576Sgblack@eecs.umich.edu    CPA_IGNORE_SYMBOL("local_bh_"),
602221SN/A    CPA_IGNORE_SYMBOL("restore_all"),
613573Sgblack@eecs.umich.edu    CPA_IGNORE_SYMBOL("Call_Pal_"),
623576Sgblack@eecs.umich.edu    CPA_IGNORE_SYMBOL("pal_post_interrupt"),
633576Sgblack@eecs.umich.edu    CPA_IGNORE_SYMBOL("rti_to_"),
642221SN/A    CPA_IGNORE_SYMBOL("sys_int_2"),
653573Sgblack@eecs.umich.edu    CPA_IGNORE_SYMBOL("sys_interrupt"),
663576Sgblack@eecs.umich.edu    CPA_IGNORE_SYMBOL("normal_int"),
673576Sgblack@eecs.umich.edu    CPA_IGNORE_SYMBOL("TRAP_INTERRUPT_10_"),
682221SN/A    CPA_IGNORE_SYMBOL("Trap_Interrupt"),
693573Sgblack@eecs.umich.edu    CPA_IGNORE_SYMBOL("do_entInt"),
703576Sgblack@eecs.umich.edu    CPA_IGNORE_SYMBOL("__do_softirq"),
713576Sgblack@eecs.umich.edu    CPA_IGNORE_SYMBOL("_end"),
722221SN/A    CPA_IGNORE_SYMBOL("entInt"),
733573Sgblack@eecs.umich.edu    CPA_IGNORE_SYMBOL("entSys"),
743576Sgblack@eecs.umich.edu    {0,0}
753576Sgblack@eecs.umich.edu};
762221SN/A#undef CPA_IGNORE_SYMBOL
773573Sgblack@eecs.umich.edu
783576Sgblack@eecs.umich.eduusing namespace std;
793576Sgblack@eecs.umich.eduusing namespace TheISA;
803576Sgblack@eecs.umich.edu
813576Sgblack@eecs.umich.edubool CPA::exists;
823576Sgblack@eecs.umich.eduCPA *CPA::_cpa;
833576Sgblack@eecs.umich.edu
843576Sgblack@eecs.umich.educlass AnnotateDumpCallback : public Callback
852221SN/A{
863573Sgblack@eecs.umich.edu
873576Sgblack@eecs.umich.edu  private:
883576Sgblack@eecs.umich.edu    CPA *cpa;
892221SN/A  public:
903573Sgblack@eecs.umich.edu    virtual void process();
913576Sgblack@eecs.umich.edu    AnnotateDumpCallback(CPA *_cpa)
923576Sgblack@eecs.umich.edu        : cpa(_cpa)
932221SN/A    {}
943573Sgblack@eecs.umich.edu};
953576Sgblack@eecs.umich.edu
963576Sgblack@eecs.umich.eduvoid
973576Sgblack@eecs.umich.eduAnnotateDumpCallback::process()
983576Sgblack@eecs.umich.edu{
993576Sgblack@eecs.umich.edu    cpa->dump(true);
1003576Sgblack@eecs.umich.edu    cpa->dumpKey();
1013576Sgblack@eecs.umich.edu}
1023576Sgblack@eecs.umich.edu
1033576Sgblack@eecs.umich.edu
1043576Sgblack@eecs.umich.eduCPA::CPA(Params *p)
1053576Sgblack@eecs.umich.edu    : SimObject(p), numSm(0), numSmt(0), numSys(0), numQs(0), conId(0)
1063576Sgblack@eecs.umich.edu{
1072221SN/A    if (exists)
1083573Sgblack@eecs.umich.edu        fatal("Multiple annotation objects found in system");
1093576Sgblack@eecs.umich.edu    exists = true;
1103576Sgblack@eecs.umich.edu
1112221SN/A    _enabled = p->enabled;
1123573Sgblack@eecs.umich.edu    _cpa = this;
1133576Sgblack@eecs.umich.edu
1143576Sgblack@eecs.umich.edu    vector<string>::iterator i;
1152221SN/A    i = p->user_apps.begin();
1163573Sgblack@eecs.umich.edu
1173576Sgblack@eecs.umich.edu    while (i != p->user_apps.end()) {
1183576Sgblack@eecs.umich.edu        ObjectFile *of = createObjectFile(*i);
1192221SN/A        string sf;
1203573Sgblack@eecs.umich.edu        if (!of)
1213576Sgblack@eecs.umich.edu            fatal("Couldn't load symbols from file: %s\n", *i);
1223576Sgblack@eecs.umich.edu        sf = *i;
1232221SN/A        sf.erase(0, sf.rfind('/') + 1);;
1243573Sgblack@eecs.umich.edu        DPRINTFN("file %s short: %s\n", *i, sf);
1253576Sgblack@eecs.umich.edu        userApp[sf] = new SymbolTable;
1263576Sgblack@eecs.umich.edu        bool result1 = of->loadGlobalSymbols(userApp[sf]);
1272221SN/A        bool result2 = of->loadLocalSymbols(userApp[sf]);
1283573Sgblack@eecs.umich.edu        if (!result1 || !result2)
1293576Sgblack@eecs.umich.edu            panic("blah");
1303576Sgblack@eecs.umich.edu        assert(result1 && result2);
1312223SN/A        i++;
1323573Sgblack@eecs.umich.edu    }
1333576Sgblack@eecs.umich.edu}
1343576Sgblack@eecs.umich.edu
1352223SN/Avoid
1363573Sgblack@eecs.umich.eduCPA::startup()
1373576Sgblack@eecs.umich.edu{
1383576Sgblack@eecs.umich.edu    osbin = simout.create("annotate.bin", true);
1392223SN/A    // MAGIC version number 'M''5''A'N' + version/capabilities
1403573Sgblack@eecs.umich.edu    ah.version = 0x4D35414E00000101ULL;
1413576Sgblack@eecs.umich.edu    ah.num_recs = 0;
1423576Sgblack@eecs.umich.edu    ah.key_off = 0;
1432223SN/A    osbin->write((char*)&ah, sizeof(AnnotateHeader));
1443573Sgblack@eecs.umich.edu
1453576Sgblack@eecs.umich.edu    registerExitCallback(new AnnotateDumpCallback(this));
1463576Sgblack@eecs.umich.edu}
1473576Sgblack@eecs.umich.edu
1483576Sgblack@eecs.umich.eduuint64_t
1493576Sgblack@eecs.umich.eduCPA::getFrame(ThreadContext *tc)
1503576Sgblack@eecs.umich.edu{
1513576Sgblack@eecs.umich.edu    // This code is ISA specific and will need to be changed
1522223SN/A    // if the annotation code is used for something other than Alpha
1533573Sgblack@eecs.umich.edu    return (tc->readMiscRegNoEffect(TheISA::IPR_PALtemp23) &
1543576Sgblack@eecs.umich.edu            ~ULL(0x3FFF));
1553576Sgblack@eecs.umich.edu
1562223SN/A}
1573573Sgblack@eecs.umich.edu
1583576Sgblack@eecs.umich.eduvoid
1593576Sgblack@eecs.umich.eduCPA::swSmBegin(ThreadContext *tc)
1602223SN/A{
1613573Sgblack@eecs.umich.edu    if (!enabled())
1623576Sgblack@eecs.umich.edu        return;
1633576Sgblack@eecs.umich.edu
1642223SN/A    Arguments args(tc);
1653573Sgblack@eecs.umich.edu    std::string st;
1663576Sgblack@eecs.umich.edu    Addr junk;
1673576Sgblack@eecs.umich.edu    char sm[50];
1682223SN/A    if (!TheISA::inUserMode(tc))
1693573Sgblack@eecs.umich.edu        debugSymbolTable->findNearestSymbol(
1703576Sgblack@eecs.umich.edu            tc->readIntReg(ReturnAddressReg), st, junk);
1713576Sgblack@eecs.umich.edu
1722223SN/A    CopyStringOut(tc, sm, args[0], 50);
1733573Sgblack@eecs.umich.edu    System *sys = tc->getSystemPtr();
1743576Sgblack@eecs.umich.edu    StringWrap name(sys->name());
1753576Sgblack@eecs.umich.edu
1762223SN/A    if (!sm[0])
1773573Sgblack@eecs.umich.edu        warn("Got null SM at tick %d\n", curTick());
1783576Sgblack@eecs.umich.edu
1793576Sgblack@eecs.umich.edu    int sysi = getSys(sys);
1802223SN/A    int smi = getSm(sysi, sm, args[1]);
1813573Sgblack@eecs.umich.edu    DPRINTF(Annotate,  "Starting machine: %s(%d) sysi: %d id: %#x\n", sm,
1823576Sgblack@eecs.umich.edu            smi, sysi, args[1]);
1833576Sgblack@eecs.umich.edu    DPRINTF(Annotate, "smMap[%d] = %d, %s, %#x\n", smi,
1842223SN/A            smMap[smi-1].first, smMap[smi-1].second.first,
1853573Sgblack@eecs.umich.edu            smMap[smi-1].second.second);
1863576Sgblack@eecs.umich.edu
1873576Sgblack@eecs.umich.edu    uint64_t frame = getFrame(tc);
1882223SN/A    StackId sid = StackId(sysi, frame);
1893573Sgblack@eecs.umich.edu
1903576Sgblack@eecs.umich.edu    // check if we need to link to the previous state machine
1913576Sgblack@eecs.umich.edu    int flags = args[2];
1922223SN/A    if (flags & FL_LINK) {
1933576Sgblack@eecs.umich.edu        if (smStack[sid].size()) {
1943576Sgblack@eecs.umich.edu            int prev_smi = smStack[sid].back();
1953576Sgblack@eecs.umich.edu            DPRINTF(Annotate, "Linking from %d to state machine %s(%d) [%#x]\n",
1963576Sgblack@eecs.umich.edu                    prev_smi, sm, smi, args[1]);
1972527SN/A
1983573Sgblack@eecs.umich.edu            if (lnMap[smi])
1993576Sgblack@eecs.umich.edu                DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
2003890Ssaidi@eecs.umich.edu                        smi, lnMap[smi]);
2012223SN/A            assert(lnMap[smi] == 0);
2023573Sgblack@eecs.umich.edu            lnMap[smi] =  prev_smi;
2033576Sgblack@eecs.umich.edu
2043576Sgblack@eecs.umich.edu            add(OP_LINK, FL_NONE, tc->contextId(), prev_smi, smi);
2052223SN/A        } else {
2063573Sgblack@eecs.umich.edu            DPRINTF(Annotate, "Not Linking to state machine %s(%d) [%#x]\n",
2073576Sgblack@eecs.umich.edu                    sm, smi, args[1]);
2083576Sgblack@eecs.umich.edu        }
2092223SN/A    }
2103573Sgblack@eecs.umich.edu
2114103Ssaidi@eecs.umich.edu
2124103Ssaidi@eecs.umich.edu    smStack[sid].push_back(smi);
2134103Ssaidi@eecs.umich.edu
2144103Ssaidi@eecs.umich.edu    DPRINTF(Annotate, "Stack Now (%#X):\n", frame);
2153576Sgblack@eecs.umich.edu    for (int x = smStack[sid].size()-1; x >= 0; x--)
2163576Sgblack@eecs.umich.edu        DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
2172223SN/A
2183573Sgblack@eecs.umich.edu    // reset the sw state exculsion to false
2193576Sgblack@eecs.umich.edu    if (swExpl[sid])
2203576Sgblack@eecs.umich.edu        swExpl[sid] = false;
2212223SN/A
2223573Sgblack@eecs.umich.edu
2233576Sgblack@eecs.umich.edu    Id id = Id(sm, frame);
2243576Sgblack@eecs.umich.edu    if (scLinks[sysi-1][id]) {
2253576Sgblack@eecs.umich.edu        AnnDataPtr an = scLinks[sysi-1][id];
2263576Sgblack@eecs.umich.edu        scLinks[sysi-1].erase(id);
2273576Sgblack@eecs.umich.edu        an->stq = smi;
2283576Sgblack@eecs.umich.edu        an->dump = true;
2293576Sgblack@eecs.umich.edu        DPRINTF(Annotate,
2303576Sgblack@eecs.umich.edu                "Found prev unknown linking from %d to state machine %s(%d)\n",
2313576Sgblack@eecs.umich.edu                an->sm, sm, smi);
2323576Sgblack@eecs.umich.edu
2333576Sgblack@eecs.umich.edu        if (lnMap[smi])
2343576Sgblack@eecs.umich.edu            DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
2353576Sgblack@eecs.umich.edu                    smi, lnMap[smi]);
2363576Sgblack@eecs.umich.edu        assert(lnMap[smi] == 0);
2373576Sgblack@eecs.umich.edu        lnMap[smi] =  an->sm;
2383576Sgblack@eecs.umich.edu    }
2393576Sgblack@eecs.umich.edu
2403576Sgblack@eecs.umich.edu    // add a new begin ifwe have that info
2413576Sgblack@eecs.umich.edu    if (st != "") {
2423576Sgblack@eecs.umich.edu        DPRINTF(Annotate, "st: %s smi: %d stCache.size %d\n", st,
2433576Sgblack@eecs.umich.edu                smi, stCache.size());
2443576Sgblack@eecs.umich.edu        int sti = getSt(sm, st);
2453576Sgblack@eecs.umich.edu        lastState[smi] = sti;
2463576Sgblack@eecs.umich.edu        add(OP_BEGIN, FL_NONE, tc->contextId(), smi, sti);
2473893Shsul@eecs.umich.edu    }
2483576Sgblack@eecs.umich.edu}
2493576Sgblack@eecs.umich.edu
2503576Sgblack@eecs.umich.eduvoid
2513576Sgblack@eecs.umich.eduCPA::swSmEnd(ThreadContext *tc)
2523576Sgblack@eecs.umich.edu{
2533576Sgblack@eecs.umich.edu    if (!enabled())
2543576Sgblack@eecs.umich.edu        return;
2553576Sgblack@eecs.umich.edu
2563576Sgblack@eecs.umich.edu    Arguments args(tc);
2573576Sgblack@eecs.umich.edu    char sm[50];
2583576Sgblack@eecs.umich.edu    CopyStringOut(tc, sm, args[0], 50);
2593576Sgblack@eecs.umich.edu    System *sys = tc->getSystemPtr();
2603576Sgblack@eecs.umich.edu    doSwSmEnd(sys, tc->contextId(), sm, getFrame(tc));
2613576Sgblack@eecs.umich.edu}
2623576Sgblack@eecs.umich.edu
2633576Sgblack@eecs.umich.eduvoid
2643576Sgblack@eecs.umich.eduCPA::doSwSmEnd(System *sys, int cpuid, string sm, uint64_t frame)
2653576Sgblack@eecs.umich.edu{
2663576Sgblack@eecs.umich.edu    int sysi = getSys(sys);
2673576Sgblack@eecs.umich.edu    StackId sid = StackId(sysi, frame);
2683576Sgblack@eecs.umich.edu
2692223SN/A
2703415Sgblack@eecs.umich.edu    // reset the sw state exculsion to false
2713578Sgblack@eecs.umich.edu    if (swExpl[sid])
2723578Sgblack@eecs.umich.edu        swExpl[sid] = false;
2733415Sgblack@eecs.umich.edu
2743415Sgblack@eecs.umich.edu
2753578Sgblack@eecs.umich.edu    int smib = smStack[sid].back();
2763415Sgblack@eecs.umich.edu    StringWrap name(sys->name());
2773578Sgblack@eecs.umich.edu    DPRINTF(Annotate, "Ending machine: %s[%d, %#x] (%d?)\n", sm, sysi,
2783578Sgblack@eecs.umich.edu            frame, smib);
2794172Ssaidi@eecs.umich.edu
2803578Sgblack@eecs.umich.edu    if (!smStack[sid].size() || smMap[smib-1].second.first != sm) {
2813578Sgblack@eecs.umich.edu        DPRINTF(Annotate, "State Machine not unwinding correctly. sid: %d, %#x"
2823578Sgblack@eecs.umich.edu                " top of stack: %s Current Stack:\n",
2833578Sgblack@eecs.umich.edu                sysi, frame, smMap[smib-1].second.first);
2844172Ssaidi@eecs.umich.edu        for (int x = smStack[sid].size()-1; x >= 0; x--)
2853746Sgblack@eecs.umich.edu            DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
2863746Sgblack@eecs.umich.edu        DPRINTF(Annotate, "Ending machine: %s; end stack: %s\n", sm,
2874172Ssaidi@eecs.umich.edu                smMap[smib-1].second.first);
2883746Sgblack@eecs.umich.edu
2894172Ssaidi@eecs.umich.edu        warn("State machine stack not unwinding correctly at %d\n", curTick());
2903578Sgblack@eecs.umich.edu    } else {
2913578Sgblack@eecs.umich.edu        DPRINTF(Annotate,
2923578Sgblack@eecs.umich.edu                "State machine ending:%s sysi:%d id:%#x back:%d getSm:%d\n",
2933578Sgblack@eecs.umich.edu                sm, sysi, smMap[smib-1].second.second, smStack[sid].back(),
2943578Sgblack@eecs.umich.edu                getSm(sysi, sm, smMap[smib-1].second.second));
2953578Sgblack@eecs.umich.edu        assert(getSm(sysi, sm, smMap[smib-1].second.second) ==
2963578Sgblack@eecs.umich.edu                smStack[sid].back());
2973578Sgblack@eecs.umich.edu
2983578Sgblack@eecs.umich.edu        int smi = smStack[sid].back();
2994172Ssaidi@eecs.umich.edu        smStack[sid].pop_back();
3004172Ssaidi@eecs.umich.edu
3014172Ssaidi@eecs.umich.edu        if (lnMap[smi]) {
3024172Ssaidi@eecs.umich.edu            DPRINTF(Annotate, "Linking %d back to %d\n", smi, lnMap[smi]);
3034172Ssaidi@eecs.umich.edu            add(OP_LINK, FL_NONE, cpuid, smi, lnMap[smi]);
3043761Sgblack@eecs.umich.edu            lnMap.erase(smi);
3054172Ssaidi@eecs.umich.edu        }
3064172Ssaidi@eecs.umich.edu
3074172Ssaidi@eecs.umich.edu        if (smStack[sid].size()) {
3084172Ssaidi@eecs.umich.edu            add(OP_BEGIN, FL_NONE, cpuid, smi, lastState[smi]);
3094172Ssaidi@eecs.umich.edu        }
3103578Sgblack@eecs.umich.edu
3113578Sgblack@eecs.umich.edu        DPRINTF(Annotate, "Stack Now:\n");
3123578Sgblack@eecs.umich.edu        for (int x = smStack[sid].size()-1; x >= 0; x--)
3133578Sgblack@eecs.umich.edu            DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
3143578Sgblack@eecs.umich.edu    }
3153928Ssaidi@eecs.umich.edu}
3163928Ssaidi@eecs.umich.edu
3173928Ssaidi@eecs.umich.edu
3183928Ssaidi@eecs.umich.eduvoid
3193928Ssaidi@eecs.umich.eduCPA::swExplictBegin(ThreadContext *tc)
3203578Sgblack@eecs.umich.edu{
3213578Sgblack@eecs.umich.edu    if (!enabled())
3223578Sgblack@eecs.umich.edu        return;
3233578Sgblack@eecs.umich.edu
3243578Sgblack@eecs.umich.edu    Arguments args(tc);
3253578Sgblack@eecs.umich.edu    char st[50];
3263578Sgblack@eecs.umich.edu    CopyStringOut(tc, st, args[1], 50);
3273578Sgblack@eecs.umich.edu
3283578Sgblack@eecs.umich.edu    StringWrap name(tc->getSystemPtr()->name());
3293578Sgblack@eecs.umich.edu    DPRINTF(Annotate, "Explict begin of state %s\n", st);
3303578Sgblack@eecs.umich.edu    uint32_t flags = args[0];
3313578Sgblack@eecs.umich.edu    if (flags & FL_BAD)
3324172Ssaidi@eecs.umich.edu        warn("BAD state encountered: at cycle %d: %s\n", curTick(), st);
3333578Sgblack@eecs.umich.edu    swBegin(tc->getSystemPtr(), tc->contextId(), st, getFrame(tc), true, args[0]);
3343578Sgblack@eecs.umich.edu}
3354172Ssaidi@eecs.umich.edu
3363578Sgblack@eecs.umich.eduvoid
3374172Ssaidi@eecs.umich.eduCPA::swAutoBegin(ThreadContext *tc, Addr next_pc)
3383578Sgblack@eecs.umich.edu{
3393578Sgblack@eecs.umich.edu    if (!enabled())
3404172Ssaidi@eecs.umich.edu        return;
3413578Sgblack@eecs.umich.edu
3423578Sgblack@eecs.umich.edu    string sym;
3434172Ssaidi@eecs.umich.edu    Addr sym_addr = 0;
3443578Sgblack@eecs.umich.edu
3453578Sgblack@eecs.umich.edu    if (!TheISA::inUserMode(tc)) {
3464172Ssaidi@eecs.umich.edu        debugSymbolTable->findNearestSymbol(next_pc, sym, sym_addr);
3473578Sgblack@eecs.umich.edu    } else {
3483926Ssaidi@eecs.umich.edu        Linux::ThreadInfo ti(tc);
3493926Ssaidi@eecs.umich.edu        string app = ti.curTaskName();
3504172Ssaidi@eecs.umich.edu        if (userApp.count(app))
3513578Sgblack@eecs.umich.edu            userApp[app]->findNearestSymbol(next_pc, sym, sym_addr);
3523578Sgblack@eecs.umich.edu    }
3533578Sgblack@eecs.umich.edu
3543578Sgblack@eecs.umich.edu    if (sym_addr)
3553578Sgblack@eecs.umich.edu        swBegin(tc->getSystemPtr(), tc->contextId(), sym, getFrame(tc));
3563578Sgblack@eecs.umich.edu}
3573578Sgblack@eecs.umich.edu
3583578Sgblack@eecs.umich.eduvoid
3593578Sgblack@eecs.umich.eduCPA::swBegin(System *sys, int cpuid, std::string st, uint64_t frame, bool expl,
3604172Ssaidi@eecs.umich.edu        int flags)
3613578Sgblack@eecs.umich.edu{
3623578Sgblack@eecs.umich.edu    int x = 0;
3633578Sgblack@eecs.umich.edu    int len;
3643578Sgblack@eecs.umich.edu    while (ignoreSymbols[x].len)
3653578Sgblack@eecs.umich.edu    {
3663578Sgblack@eecs.umich.edu        len = ignoreSymbols[x].len;
3673578Sgblack@eecs.umich.edu        if (!st.compare(0,len, ignoreSymbols[x].symbol, len))
3683578Sgblack@eecs.umich.edu            return;
3693578Sgblack@eecs.umich.edu        x++;
3703578Sgblack@eecs.umich.edu    }
3713578Sgblack@eecs.umich.edu
3723578Sgblack@eecs.umich.edu    int sysi = getSys(sys);
3733578Sgblack@eecs.umich.edu    StackId sid = StackId(sysi, frame);
3743578Sgblack@eecs.umich.edu    // if expl is true suspend symbol table based states
3754172Ssaidi@eecs.umich.edu    if (!smStack[sid].size())
3763578Sgblack@eecs.umich.edu        return;
3773578Sgblack@eecs.umich.edu    if (!expl && swExpl[sid])
3783578Sgblack@eecs.umich.edu        return;
3793578Sgblack@eecs.umich.edu    if (expl)
3803578Sgblack@eecs.umich.edu        swExpl[sid] = true;
3813578Sgblack@eecs.umich.edu    DPRINTFS(AnnotateVerbose, sys, "SwBegin: %s sysi: %d\n", st, sysi);
3823578Sgblack@eecs.umich.edu    int smi = smStack[sid].back();
3833578Sgblack@eecs.umich.edu    int sti = getSt(smMap[smi-1].second.first, st);
3843578Sgblack@eecs.umich.edu    if (lastState[smi] != sti) {
3853578Sgblack@eecs.umich.edu        lastState[smi] = sti;
3864172Ssaidi@eecs.umich.edu        add(OP_BEGIN, flags, cpuid, smi, sti);
3874172Ssaidi@eecs.umich.edu    }
3884172Ssaidi@eecs.umich.edu}
3894172Ssaidi@eecs.umich.edu
3904172Ssaidi@eecs.umich.eduvoid
3913761Sgblack@eecs.umich.eduCPA::swEnd(ThreadContext *tc)
3924172Ssaidi@eecs.umich.edu{
3934172Ssaidi@eecs.umich.edu    if (!enabled())
3944172Ssaidi@eecs.umich.edu        return;
3953761Sgblack@eecs.umich.edu
3964172Ssaidi@eecs.umich.edu    std::string st;
3973578Sgblack@eecs.umich.edu    Addr junk;
3983578Sgblack@eecs.umich.edu    if (!TheISA::inUserMode(tc))
3993415Sgblack@eecs.umich.edu        debugSymbolTable->findNearestSymbol(
4003928Ssaidi@eecs.umich.edu            tc->readIntReg(ReturnAddressReg), st, junk);
4013928Ssaidi@eecs.umich.edu    System *sys = tc->getSystemPtr();
4023928Ssaidi@eecs.umich.edu    StringWrap name(sys->name());
4033928Ssaidi@eecs.umich.edu
4043928Ssaidi@eecs.umich.edu    int sysi = getSys(sys);
4053415Sgblack@eecs.umich.edu    StackId sid = StackId(sysi, getFrame(tc));
4063415Sgblack@eecs.umich.edu    if (!smStack[sid].size()) {
4074172Ssaidi@eecs.umich.edu        DPRINTF(Annotate, "Explict end of State: %s IGNORED\n",  st);
4083415Sgblack@eecs.umich.edu        return;
4093415Sgblack@eecs.umich.edu    }
4103415Sgblack@eecs.umich.edu    DPRINTF(Annotate, "Explict end of State: %s\n",  st);
4113415Sgblack@eecs.umich.edu    // return back to symbol table based states
4123415Sgblack@eecs.umich.edu    swExpl[sid] = false;
4133415Sgblack@eecs.umich.edu    int smi = smStack[sid].back();
4143415Sgblack@eecs.umich.edu    if (st != "") {
4153415Sgblack@eecs.umich.edu        int sti = getSt(smMap[smi-1].second.first, st);
4163415Sgblack@eecs.umich.edu        lastState[smi] = sti;
4173415Sgblack@eecs.umich.edu        add(OP_BEGIN, FL_NONE, tc->contextId(), smi, sti);
4183415Sgblack@eecs.umich.edu    }
4193415Sgblack@eecs.umich.edu}
4203415Sgblack@eecs.umich.edu
4213415Sgblack@eecs.umich.eduvoid
4223415Sgblack@eecs.umich.eduCPA::swQ(ThreadContext *tc)
4234172Ssaidi@eecs.umich.edu{
4243415Sgblack@eecs.umich.edu    if (!enabled())
4253415Sgblack@eecs.umich.edu        return;
4264172Ssaidi@eecs.umich.edu
4273415Sgblack@eecs.umich.edu    char q[50];
4284172Ssaidi@eecs.umich.edu    Arguments args(tc);
4293415Sgblack@eecs.umich.edu    uint64_t id = args[0];
4303415Sgblack@eecs.umich.edu    CopyStringOut(tc, q, args[1], 50);
4314172Ssaidi@eecs.umich.edu    int32_t count = args[2];
4323415Sgblack@eecs.umich.edu    System *sys = tc->getSystemPtr();
4333415Sgblack@eecs.umich.edu
4344172Ssaidi@eecs.umich.edu    int sysi = getSys(sys);
4353415Sgblack@eecs.umich.edu    StackId sid = StackId(sysi, getFrame(tc));
4363415Sgblack@eecs.umich.edu    if (!smStack[sid].size())
4373893Shsul@eecs.umich.edu        return;
4384172Ssaidi@eecs.umich.edu    int smi = smStack[sid].back();
4393415Sgblack@eecs.umich.edu    if (swExpl[sid])
4404172Ssaidi@eecs.umich.edu        swExpl[sid] = false;
4413415Sgblack@eecs.umich.edu    int qi = getQ(sysi, q, id);
4423415Sgblack@eecs.umich.edu    if (count == 0) {
4433926Ssaidi@eecs.umich.edu        //warn("Tried to queue 0 bytes in %s, ignoring\n", q);
4443926Ssaidi@eecs.umich.edu        return;
4453926Ssaidi@eecs.umich.edu    }
4463415Sgblack@eecs.umich.edu    DPRINTFS(AnnotateQ, sys,
4473415Sgblack@eecs.umich.edu            "swQ: %s[%#x] cur size %d %d bytes: %d adding: %d\n",
4483415Sgblack@eecs.umich.edu            q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
4493893Shsul@eecs.umich.edu    doQ(sys, FL_NONE, tc->contextId(), smi, q, qi, count);
4503415Sgblack@eecs.umich.edu}
4513926Ssaidi@eecs.umich.edu
4523926Ssaidi@eecs.umich.eduvoid
4533926Ssaidi@eecs.umich.eduCPA::swDq(ThreadContext *tc)
4543926Ssaidi@eecs.umich.edu{
4553926Ssaidi@eecs.umich.edu    if (!enabled())
4563415Sgblack@eecs.umich.edu        return;
4574172Ssaidi@eecs.umich.edu
4583926Ssaidi@eecs.umich.edu    char q[50];
4593926Ssaidi@eecs.umich.edu    Arguments args(tc);
4603926Ssaidi@eecs.umich.edu    uint64_t id = args[0];
4613415Sgblack@eecs.umich.edu    CopyStringOut(tc, q, args[1], 50);
4624172Ssaidi@eecs.umich.edu    int32_t count = args[2];
4633926Ssaidi@eecs.umich.edu    System *sys = tc->getSystemPtr();
4643415Sgblack@eecs.umich.edu
4653415Sgblack@eecs.umich.edu    int sysi = getSys(sys);
4663893Shsul@eecs.umich.edu    StackId sid = StackId(sysi, getFrame(tc));
4673415Sgblack@eecs.umich.edu    if (!smStack[sid].size())
4683893Shsul@eecs.umich.edu        return;
4693415Sgblack@eecs.umich.edu    int smi = smStack[sid].back();
4703893Shsul@eecs.umich.edu    int qi = getQ(sysi, q, id);
4713415Sgblack@eecs.umich.edu    if (swExpl[sid])
4723415Sgblack@eecs.umich.edu        swExpl[sid] = false;
4733415Sgblack@eecs.umich.edu    DPRINTFS(AnnotateQ, sys,
4743420Sgblack@eecs.umich.edu            "swDq: %s[%#x] cur size %d %d bytes: %d removing: %d\n",
4753893Shsul@eecs.umich.edu            q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
4763415Sgblack@eecs.umich.edu    assert(count != 0);
4773415Sgblack@eecs.umich.edu
4784172Ssaidi@eecs.umich.edu    doDq(sys, FL_NONE, tc->contextId(), smi, q, qi, count);
4793415Sgblack@eecs.umich.edu}
4803415Sgblack@eecs.umich.edu
4813415Sgblack@eecs.umich.eduvoid
4823595Sgblack@eecs.umich.eduCPA::swPq(ThreadContext *tc)
4833578Sgblack@eecs.umich.edu{
4843585Sgblack@eecs.umich.edu    if (!enabled())
4853603Ssaidi@eecs.umich.edu        return;
4863595Sgblack@eecs.umich.edu
4873578Sgblack@eecs.umich.edu    char q[50];
4883578Sgblack@eecs.umich.edu    Arguments args(tc);
4893578Sgblack@eecs.umich.edu    uint64_t id = args[0];
4903585Sgblack@eecs.umich.edu    CopyStringOut(tc, q, args[1], 50);
4913578Sgblack@eecs.umich.edu    System *sys = tc->getSystemPtr();
4924172Ssaidi@eecs.umich.edu    int32_t count = args[2];
4933578Sgblack@eecs.umich.edu
4943578Sgblack@eecs.umich.edu    int sysi = getSys(sys);
4953578Sgblack@eecs.umich.edu    StackId sid = StackId(sysi, getFrame(tc));
4963578Sgblack@eecs.umich.edu    if (!smStack[sid].size())
4973585Sgblack@eecs.umich.edu        return;
4983578Sgblack@eecs.umich.edu    int smi = smStack[sid].back();
4994172Ssaidi@eecs.umich.edu    int qi = getQ(sysi, q, id);
5003578Sgblack@eecs.umich.edu    if (swExpl[sid])
5013578Sgblack@eecs.umich.edu        swExpl[sid] = false;
5023578Sgblack@eecs.umich.edu    DPRINTFS(AnnotateQ, sys,
5033578Sgblack@eecs.umich.edu            "swPq: %s [%#x] cur size %d %d bytes: %d peeking: %d\n",
5043578Sgblack@eecs.umich.edu            q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
5053578Sgblack@eecs.umich.edu
5062221SN/A    assert(count != 0);
5072221SN/A    if (qBytes[qi-1] < count) {
5083573Sgblack@eecs.umich.edu        dump(true);
5092221SN/A        dumpKey();
5103825Ssaidi@eecs.umich.edu        fatal("Queue %s peeking with not enough bytes available in queue!\n", q);
5112680Sktlim@umich.edu    }
5122223SN/A
5132221SN/A    add(OP_PEEK, FL_NONE, tc->contextId(), smi, qi, count);
5143578Sgblack@eecs.umich.edu}
5153578Sgblack@eecs.umich.edu
5164172Ssaidi@eecs.umich.eduvoid
5174172Ssaidi@eecs.umich.eduCPA::swRq(ThreadContext *tc)
5184172Ssaidi@eecs.umich.edu{
5194172Ssaidi@eecs.umich.edu    if (!enabled())
5203578Sgblack@eecs.umich.edu        return;
5213578Sgblack@eecs.umich.edu
5223578Sgblack@eecs.umich.edu    char q[50];
5233578Sgblack@eecs.umich.edu    Arguments args(tc);
5243893Shsul@eecs.umich.edu    uint64_t id = args[0];
5253746Sgblack@eecs.umich.edu    CopyStringOut(tc, q, args[1], 50);
5263893Shsul@eecs.umich.edu    System *sys = tc->getSystemPtr();
5273578Sgblack@eecs.umich.edu    int32_t count = args[2];
5283578Sgblack@eecs.umich.edu
5293746Sgblack@eecs.umich.edu    int sysi = getSys(sys);
5303578Sgblack@eecs.umich.edu    StackId sid = StackId(sysi, getFrame(tc));
5313578Sgblack@eecs.umich.edu    if (!smStack[sid].size())
5323578Sgblack@eecs.umich.edu        return;
5333893Shsul@eecs.umich.edu    int smi = smStack[sid].back();
5343595Sgblack@eecs.umich.edu    int qi = getQ(sysi, q, id);
5353893Shsul@eecs.umich.edu    if (swExpl[sid])
5363746Sgblack@eecs.umich.edu        swExpl[sid] = false;
5373746Sgblack@eecs.umich.edu    DPRINTFS(AnnotateQ, sys,
5383578Sgblack@eecs.umich.edu            "swRq: %s [%#x] cur size %d %d bytes: %d reserve: %d\n",
5393893Shsul@eecs.umich.edu            q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
5403825Ssaidi@eecs.umich.edu
5413578Sgblack@eecs.umich.edu    assert(count != 0);
5423578Sgblack@eecs.umich.edu
5433578Sgblack@eecs.umich.edu    add(OP_RESERVE, FL_NONE, tc->contextId(), smi, qi, count);
5443893Shsul@eecs.umich.edu}
5453578Sgblack@eecs.umich.edu
5463578Sgblack@eecs.umich.edu
5473585Sgblack@eecs.umich.eduvoid
5483893Shsul@eecs.umich.eduCPA::swWf(ThreadContext *tc)
5493826Ssaidi@eecs.umich.edu{
5503578Sgblack@eecs.umich.edu    if (!enabled())
5513585Sgblack@eecs.umich.edu        return;
5523826Ssaidi@eecs.umich.edu
5533578Sgblack@eecs.umich.edu    char q[50];
5543893Shsul@eecs.umich.edu    Arguments args(tc);
5553578Sgblack@eecs.umich.edu    uint64_t id = args[0];
5563578Sgblack@eecs.umich.edu    CopyStringOut(tc, q, args[1], 50);
5573578Sgblack@eecs.umich.edu    System *sys = tc->getSystemPtr();
5583578Sgblack@eecs.umich.edu    int32_t count = args[3];
5593578Sgblack@eecs.umich.edu
5603420Sgblack@eecs.umich.edu    int sysi = getSys(sys);
5612221SN/A    StackId sid = StackId(sysi, getFrame(tc));
5623523Sgblack@eecs.umich.edu    if (!smStack[sid].size())
5633523Sgblack@eecs.umich.edu        return;
5643523Sgblack@eecs.umich.edu    int smi = smStack[sid].back();
5653523Sgblack@eecs.umich.edu    int qi = getQ(sysi, q, id);
5663523Sgblack@eecs.umich.edu    add(OP_WAIT_FULL, FL_NONE, tc->contextId(), smi, qi, count);
5673595Sgblack@eecs.umich.edu
5684172Ssaidi@eecs.umich.edu    if (!!args[2]) {
5694172Ssaidi@eecs.umich.edu        char sm[50];
5704172Ssaidi@eecs.umich.edu        CopyStringOut(tc, sm, args[2], 50);
5713595Sgblack@eecs.umich.edu        doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
5723746Sgblack@eecs.umich.edu    }
5734172Ssaidi@eecs.umich.edu}
5743595Sgblack@eecs.umich.edu
5753595Sgblack@eecs.umich.eduvoid
5764172Ssaidi@eecs.umich.eduCPA::swWe(ThreadContext *tc)
5773628Sgblack@eecs.umich.edu{
5783628Sgblack@eecs.umich.edu    if (!enabled())
5793628Sgblack@eecs.umich.edu        return;
5803628Sgblack@eecs.umich.edu
5813628Sgblack@eecs.umich.edu    char q[50];
5823628Sgblack@eecs.umich.edu    Arguments args(tc);
5833628Sgblack@eecs.umich.edu    uint64_t id = args[0];
5843628Sgblack@eecs.umich.edu    CopyStringOut(tc, q, args[1], 50);
5854172Ssaidi@eecs.umich.edu    System *sys = tc->getSystemPtr();
5863595Sgblack@eecs.umich.edu    int32_t count = args[3];
5873595Sgblack@eecs.umich.edu
5884172Ssaidi@eecs.umich.edu    int sysi = getSys(sys);
5893595Sgblack@eecs.umich.edu    StackId sid = StackId(sysi, getFrame(tc));
5903746Sgblack@eecs.umich.edu    if (!smStack[sid].size())
5913746Sgblack@eecs.umich.edu        return;
5923746Sgblack@eecs.umich.edu    int smi = smStack[sid].back();
5933746Sgblack@eecs.umich.edu    int qi = getQ(sysi, q, id);
5943595Sgblack@eecs.umich.edu    add(OP_WAIT_EMPTY, FL_NONE, tc->contextId(), smi, qi, count);
5953595Sgblack@eecs.umich.edu
5963595Sgblack@eecs.umich.edu    if (!!args[2]) {
5973595Sgblack@eecs.umich.edu        char sm[50];
5983595Sgblack@eecs.umich.edu        CopyStringOut(tc, sm, args[2], 50);
5993595Sgblack@eecs.umich.edu        doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
6003595Sgblack@eecs.umich.edu    }
6013595Sgblack@eecs.umich.edu}
6023523Sgblack@eecs.umich.edu
6033595Sgblack@eecs.umich.eduvoid
6043595Sgblack@eecs.umich.eduCPA::swSq(ThreadContext *tc)
6053595Sgblack@eecs.umich.edu{
6064172Ssaidi@eecs.umich.edu    if (!enabled())
6073595Sgblack@eecs.umich.edu        return;
6083523Sgblack@eecs.umich.edu
6093523Sgblack@eecs.umich.edu    char q[50];
6103523Sgblack@eecs.umich.edu    Arguments args(tc);
6113523Sgblack@eecs.umich.edu    uint64_t id = args[0];
6123523Sgblack@eecs.umich.edu    CopyStringOut(tc, q, args[1], 50);
6133523Sgblack@eecs.umich.edu    System *sys = tc->getSystemPtr();
6143523Sgblack@eecs.umich.edu    StringWrap name(sys->name());
6153523Sgblack@eecs.umich.edu    int32_t size = args[2];
6163523Sgblack@eecs.umich.edu    int flags = args[3];
6173523Sgblack@eecs.umich.edu
6183523Sgblack@eecs.umich.edu    int sysi = getSys(sys);
6192221SN/A    StackId sid = StackId(sysi, getFrame(tc));
6202221SN/A    if (!smStack[sid].size())
6213578Sgblack@eecs.umich.edu        return;
6222612SN/A    int smi = smStack[sid].back();
6234997Sgblack@eecs.umich.edu    int qi = getQ(sysi, q, id);
6244997Sgblack@eecs.umich.edu    DPRINTF(AnnotateQ, "swSq: %s [%#x] cur size: %d bytes: %d, new size: %d\n",
6254997Sgblack@eecs.umich.edu             q, id, qSize[qi-1], qBytes[qi-1], size);
6265184Sgblack@eecs.umich.edu
6275184Sgblack@eecs.umich.edu    if (FL_RESET & flags) {
6284997Sgblack@eecs.umich.edu        DPRINTF(AnnotateQ, "Resetting Queue %s\n", q);
6294997Sgblack@eecs.umich.edu        add(OP_SIZE_QUEUE, FL_NONE, tc->contextId(), smi, qi, 0);
6304997Sgblack@eecs.umich.edu        qData[qi-1].clear();
6314997Sgblack@eecs.umich.edu        qSize[qi-1] = 0;
6324997Sgblack@eecs.umich.edu        qBytes[qi-1] = 0;
6335184Sgblack@eecs.umich.edu    }
6344997Sgblack@eecs.umich.edu
6354997Sgblack@eecs.umich.edu    if (qBytes[qi-1] < size)
6364997Sgblack@eecs.umich.edu        doQ(sys, FL_NONE, tc->contextId(), smi, q, qi, size - qBytes[qi-1]);
6374997Sgblack@eecs.umich.edu    else if (qBytes[qi-1] > size) {
6384997Sgblack@eecs.umich.edu        DPRINTF(AnnotateQ, "removing for resize of queue %s\n", q);
6394997Sgblack@eecs.umich.edu        add(OP_SIZE_QUEUE, FL_NONE, tc->contextId(), smi, qi, size);
6405184Sgblack@eecs.umich.edu        if (size <= 0) {
6415184Sgblack@eecs.umich.edu            qData[qi-1].clear();
6424997Sgblack@eecs.umich.edu            qSize[qi-1] = 0;
6434997Sgblack@eecs.umich.edu            qBytes[qi-1] = 0;
6445184Sgblack@eecs.umich.edu            return;
6454997Sgblack@eecs.umich.edu        }
6464997Sgblack@eecs.umich.edu        int need = qBytes[qi-1] - size;
6474997Sgblack@eecs.umich.edu        qBytes[qi-1] = size;
6484997Sgblack@eecs.umich.edu        while (need > 0) {
6494997Sgblack@eecs.umich.edu            int32_t tail_bytes = qData[qi-1].back()->data;
6504997Sgblack@eecs.umich.edu            if (qSize[qi-1] <= 0 || qBytes[qi-1] < 0) {
6515184Sgblack@eecs.umich.edu                dump(true);
6524997Sgblack@eecs.umich.edu                dumpKey();
6534997Sgblack@eecs.umich.edu                fatal("Queue %s had inconsistancy when doing size queue!\n", q);
6544997Sgblack@eecs.umich.edu            }
6553415Sgblack@eecs.umich.edu            if (tail_bytes > need) {
6563415Sgblack@eecs.umich.edu                qData[qi-1].back()->data -= need;
6573578Sgblack@eecs.umich.edu                need = 0;
6583415Sgblack@eecs.umich.edu            } else if (tail_bytes == need) {
6593415Sgblack@eecs.umich.edu                qData[qi-1].pop_back();
6603415Sgblack@eecs.umich.edu                qSize[qi-1]--;
6613578Sgblack@eecs.umich.edu                need = 0;
6623415Sgblack@eecs.umich.edu            } else {
6633415Sgblack@eecs.umich.edu                qData[qi-1].pop_back();
6643415Sgblack@eecs.umich.edu                qSize[qi-1]--;
6653415Sgblack@eecs.umich.edu                need -= tail_bytes;
6663415Sgblack@eecs.umich.edu            }
6673415Sgblack@eecs.umich.edu        }
6683415Sgblack@eecs.umich.edu    }
6693415Sgblack@eecs.umich.edu}
6703415Sgblack@eecs.umich.edu
6713415Sgblack@eecs.umich.eduvoid
6723415Sgblack@eecs.umich.eduCPA::swAq(ThreadContext *tc)
6733415Sgblack@eecs.umich.edu{
6743578Sgblack@eecs.umich.edu    if (!enabled())
6753415Sgblack@eecs.umich.edu        return;
6763415Sgblack@eecs.umich.edu
6773415Sgblack@eecs.umich.edu    char q[50];
6783578Sgblack@eecs.umich.edu    Arguments args(tc);
6793415Sgblack@eecs.umich.edu    uint64_t id = args[0];
6803415Sgblack@eecs.umich.edu    CopyStringOut(tc, q, args[1], 50);
6813415Sgblack@eecs.umich.edu    System *sys = tc->getSystemPtr();
6823578Sgblack@eecs.umich.edu    StringWrap name(sys->name());
6833415Sgblack@eecs.umich.edu    int32_t size = args[2];
6843415Sgblack@eecs.umich.edu
6853415Sgblack@eecs.umich.edu    int sysi = getSys(sys);
6863415Sgblack@eecs.umich.edu    int qi = getQ(sysi, q, id);
6873415Sgblack@eecs.umich.edu    if (qBytes[qi-1] != size) {
6883415Sgblack@eecs.umich.edu        DPRINTF(AnnotateQ, "Queue %s [%#x] has inconsintant size\n", q, id);
6894111Sgblack@eecs.umich.edu        //dump(true);
6904111Sgblack@eecs.umich.edu        //dumpKey();
6914111Sgblack@eecs.umich.edu        std::list<AnnDataPtr>::iterator ai = qData[qi-1].begin();
6924111Sgblack@eecs.umich.edu        int x = 0;
6934111Sgblack@eecs.umich.edu        while (ai != qData[qi-1].end()) {
6944111Sgblack@eecs.umich.edu            DPRINTF(AnnotateQ, "--Element %d size %d\n", x, (*ai)->data);
6954111Sgblack@eecs.umich.edu            ai++;
6964111Sgblack@eecs.umich.edu            x++;
6974111Sgblack@eecs.umich.edu        }
6984111Sgblack@eecs.umich.edu
6994111Sgblack@eecs.umich.edu        warn("%d: Queue Assert: SW said there should be %d byte(s) in %s,"
7004111Sgblack@eecs.umich.edu                "however there are %d byte(s)\n",
7014111Sgblack@eecs.umich.edu            curTick(), size, q, qBytes[qi-1]);
7024111Sgblack@eecs.umich.edu        DPRINTF(AnnotateQ, "%d: Queue Assert: SW said there should be %d"
7034111Sgblack@eecs.umich.edu                " byte(s) in %s, however there are %d byte(s)\n",
7044111Sgblack@eecs.umich.edu            curTick(), size, q, qBytes[qi-1]);
7054111Sgblack@eecs.umich.edu    }
7064111Sgblack@eecs.umich.edu}
7074111Sgblack@eecs.umich.edu
7084111Sgblack@eecs.umich.eduvoid
7092221SN/ACPA::swLink(ThreadContext *tc)
7102221SN/A{
7112223SN/A    if (!enabled())
7122221SN/A        return;
713
714    char lsm[50];
715    Arguments args(tc);
716    CopyStringOut(tc, lsm, args[0], 50);
717    System *sys = tc->getSystemPtr();
718    StringWrap name(sys->name());
719
720    int sysi = getSys(sys);
721    StackId sid = StackId(sysi, getFrame(tc));
722    if (!smStack[sid].size())
723        return;
724    int smi = smStack[sid].back();
725    int lsmi = getSm(sysi, lsm, args[1]);
726
727    DPRINTF(Annotate, "Linking from %d to state machine %s(%d) [%#x]\n",
728            smi, lsm, lsmi, args[1]);
729
730    if (lnMap[lsmi])
731        DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
732                lsmi, lnMap[lsmi]);
733    assert(lnMap[lsmi] == 0);
734    lnMap[lsmi] =  smi;
735
736    add(OP_LINK, FL_NONE, tc->contextId(), smi, lsmi);
737
738    if (!!args[2]) {
739        char sm[50];
740        CopyStringOut(tc, sm, args[2], 50);
741        doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
742    }
743}
744
745void
746CPA::swIdentify(ThreadContext *tc)
747{
748    if (!enabled())
749        return;
750
751    Arguments args(tc);
752    int sysi = getSys(tc->getSystemPtr());
753    StackId sid = StackId(sysi, getFrame(tc));
754    if (!smStack[sid].size())
755        return;
756    int smi = smStack[sid].back();
757
758    DPRINTFS(Annotate, tc->getSystemPtr(), "swIdentify: id %#X\n", args[0]);
759
760    add(OP_IDENT, FL_NONE, tc->contextId(), smi, 0, args[0]);
761}
762
763uint64_t
764CPA::swGetId(ThreadContext *tc)
765{
766    if (!enabled())
767        return 0;
768
769    uint64_t id = ++conId;
770    int sysi = getSys(tc->getSystemPtr());
771    StackId sid = StackId(sysi, getFrame(tc));
772    if (!smStack[sid].size())
773        panic("swGetId called without a state machine stack!");
774    int smi = smStack[sid].back();
775
776    DPRINTFS(Annotate, tc->getSystemPtr(), "swGetId: id %#X\n", id);
777
778    add(OP_IDENT, FL_NONE, tc->contextId(), smi, 0, id);
779    return id;
780}
781
782
783void
784CPA::swSyscallLink(ThreadContext  *tc)
785{
786    if (!enabled())
787        return;
788
789    char lsm[50];
790    Arguments args(tc);
791    CopyStringOut(tc, lsm, args[0], 50);
792    System *sys = tc->getSystemPtr();
793    StringWrap name(sys->name());
794    int sysi = getSys(sys);
795
796    Id id = Id(lsm, getFrame(tc));
797    StackId sid = StackId(sysi, getFrame(tc));
798
799    if (!smStack[sid].size())
800        return;
801
802    int smi = smStack[sid].back();
803
804    DPRINTF(Annotate, "Linking from %d to state machine %s(UNKNOWN)\n",
805            smi, lsm);
806
807    if (scLinks[sysi-1][id])
808        DPRINTF(Annotate,
809                "scLinks already contains entry for system %d %s[%x] of %d\n",
810                sysi, lsm, getFrame(tc), scLinks[sysi-1][id]);
811    assert(scLinks[sysi-1][id] == 0);
812    scLinks[sysi-1][id] = add(OP_LINK, FL_NONE, tc->contextId(), smi, 0xFFFF);
813    scLinks[sysi-1][id]->dump = false;
814
815    if (!!args[1]) {
816        char sm[50];
817        CopyStringOut(tc, sm, args[1], 50);
818        doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
819    }
820}
821
822CPA::AnnDataPtr
823CPA::add(int t, int f, int c, int sm, int stq, int32_t d)
824{
825    AnnDataPtr an = new AnnotateData;
826    an->time = curTick();
827    an->data = d;
828    an->orig_data = d;
829    an->op = t;
830    an->flag = f;
831    an->sm = sm;
832    an->stq = stq;
833    an->cpu = c;
834    an->dump = true;
835
836    data.push_back(an);
837
838    DPRINTF(AnnotateVerbose, "Annotate: op: %d flags: 0x%x sm: %d state: %d time: %d, data: %d\n",
839            an->op, an->flag, an->sm, an->stq, an->time, an->data);
840
841    // Don't dump Links because we might be setting no-dump on it
842    if (an->op != OP_LINK)
843        dump(false);
844
845    return an;
846}
847
848void
849CPA::dumpKey()
850{
851    std::streampos curpos = osbin->tellp();
852    ah.key_off = curpos;
853
854    // Output the various state machines and their corresponding states
855    *osbin << "# Automatically generated state machine descriptor file" << endl;
856
857    *osbin << "sms = {}" << endl << endl;
858    vector<string> state_machines;
859    state_machines.resize(numSmt+1);
860
861    // State machines, id -> states
862    SCache::iterator i = smtCache.begin();
863    while (i != smtCache.end()) {
864        state_machines[i->second] = i->first;
865        i++;
866    }
867
868    for (int x = 1; x < state_machines.size(); x++) {
869        vector<string> states;
870        states.resize(numSt[x-1]+1);
871        assert(x-1 < stCache.size());
872        SCache::iterator i = stCache[x-1].begin();
873        while (i != stCache[x-1].end()) {
874            states[i->second] = i->first;
875            i++;
876        }
877        *osbin << "sms[\"" << state_machines[x] << "\"] = [\"NULL\"";
878        for (int y = 1; y < states.size(); y++)
879            *osbin << ", \"" << states[y] << "\"";
880        *osbin << "]" << endl;
881    }
882
883    *osbin << endl << endl << endl;
884
885    // state machine number -> system, name, id
886    *osbin << "smNum = [\"NULL\"";
887    for (int x = 0; x < smMap.size(); x++)
888        *osbin << ", (" << smMap[x].first << ", \"" << smMap[x].second.first <<
889            "\", " << smMap[x].second.second << ")";
890    *osbin << "]" << endl;
891
892    *osbin << endl << endl << endl;
893
894    // Output the systems
895    vector<string> systems;
896    systems.resize(numSys+1);
897    NameCache::iterator i2 = nameCache.begin();
898    while (i2 != nameCache.end()) {
899        systems[i2->second.second] = i2->second.first;
900        i2++;
901    }
902
903    *osbin << "sysNum = [\"NULL\"";
904    for (int x = 1; x < systems.size(); x++) {
905        *osbin << ", \"" << systems[x] << "\"";
906    }
907    *osbin << "]" << endl;
908
909    // queue number -> system, qname, qid
910    *osbin << "queues = [\"NULL\"";
911    for (int x = 0; x < qMap.size(); x++)
912        *osbin << ", (" << qMap[x].first << ", \"" << qMap[x].second.first <<
913            "\", " << qMap[x].second.second << ")";
914    *osbin << "]" << endl;
915
916    *osbin << "smComb = [s for s in [(i,r) for i in xrange(1,len(sysNum)) "
917           << "for r in xrange (1,len(smNum))]]" << endl;
918    ah.key_len = osbin->tellp() - curpos;
919
920    // output index
921    curpos = osbin->tellp();
922    ah.idx_off = curpos;
923
924    for (int x = 0; x < annotateIdx.size(); x++)
925        osbin->write((char*)&annotateIdx[x], sizeof(uint64_t));
926    ah.idx_len = osbin->tellp() - curpos;
927
928    osbin->seekp(0);
929    osbin->write((char*)&ah, sizeof(AnnotateHeader));
930    osbin->flush();
931
932}
933
934void
935CPA::dump(bool all)
936{
937
938    list<AnnDataPtr>::iterator i;
939
940    i = data.begin();
941
942    if (i == data.end())
943        return;
944
945    // Dump the data every
946    if (!all && data.size() < 10000)
947        return;
948
949    DPRINTF(Annotate, "Writing %d\n", data.size());
950    while (i != data.end()) {
951        AnnDataPtr an = *i;
952
953        // If we can't dump this record, hold here
954        if (!an->dump && !all)
955            break;
956
957        ah.num_recs++;
958        if (ah.num_recs % 100000 == 0)
959            annotateIdx.push_back(osbin->tellp());
960
961
962        osbin->write((char*)&(an->time), sizeof(an->time));
963        osbin->write((char*)&(an->orig_data), sizeof(an->orig_data));
964        osbin->write((char*)&(an->sm), sizeof(an->sm));
965        osbin->write((char*)&(an->stq), sizeof(an->stq));
966        osbin->write((char*)&(an->op), sizeof(an->op));
967        osbin->write((char*)&(an->flag), sizeof(an->flag));
968        osbin->write((char*)&(an->cpu), sizeof(an->cpu));
969        i++;
970    }
971    if (data.begin() != i)
972        data.erase(data.begin(), i);
973
974    if (all)
975        osbin->flush();
976}
977
978void
979CPA::doQ(System *sys, int flags, int cpuid, int sm,
980              string q, int qi, int count)
981{
982    qSize[qi-1]++;
983    qBytes[qi-1] += count;
984    if (qSize[qi-1] > 2501 || qBytes[qi-1] > 2000000000)
985        warn("Queue %s is %d elements/%d bytes, "
986                "maybe things aren't being removed?\n",
987                q, qSize[qi-1], qBytes[qi-1]);
988    if (flags & FL_QOPP)
989        qData[qi-1].push_front(add(OP_QUEUE, flags, cpuid, sm, qi, count));
990    else
991        qData[qi-1].push_back(add(OP_QUEUE, flags, cpuid, sm, qi, count));
992    DPRINTFS(AnnotateQ, sys, "Queing in queue %s size now %d/%d\n",
993            q, qSize[qi-1], qBytes[qi-1]);
994    assert(qSize[qi-1] >= 0);
995    assert(qBytes[qi-1] >= 0);
996}
997
998
999void
1000CPA::doDq(System *sys, int flags, int cpuid, int sm,
1001               string q, int qi, int count)
1002{
1003
1004    StringWrap name(sys->name());
1005    if (count == -1) {
1006        add(OP_DEQUEUE, flags, cpuid, sm, qi, count);
1007        qData[qi-1].clear();
1008        qSize[qi-1] = 0;
1009        qBytes[qi-1] = 0;
1010        DPRINTF(AnnotateQ, "Dequeing all data in queue %s size now %d/%d\n",
1011                q, qSize[qi-1], qBytes[qi-1]);
1012        return;
1013    }
1014
1015    assert(count > 0);
1016    if (qSize[qi-1] <= 0 || qBytes[qi-1] <= 0 || !qData[qi-1].size()) {
1017        dump(true);
1018        dumpKey();
1019        fatal("Queue %s dequing with no data available in queue!\n",
1020                q);
1021    }
1022    assert(qSize[qi-1] >= 0);
1023    assert(qBytes[qi-1] >= 0);
1024    assert(qData[qi-1].size());
1025
1026    int32_t need = count;
1027    qBytes[qi-1] -= count;
1028    if (qBytes[qi-1] < 0) {
1029        dump(true);
1030        dumpKey();
1031        fatal("Queue %s dequing with no bytes available in queue!\n",
1032                q);
1033    }
1034
1035    while (need > 0) {
1036        int32_t head_bytes = qData[qi-1].front()->data;
1037        if (qSize[qi-1] <= 0 || qBytes[qi-1] < 0) {
1038            dump(true);
1039            dumpKey();
1040            fatal("Queue %s dequing with nothing in queue!\n",
1041                q);
1042        }
1043
1044        if (head_bytes > need) {
1045            qData[qi-1].front()->data -= need;
1046            need = 0;
1047        } else if (head_bytes == need) {
1048            qData[qi-1].pop_front();
1049            qSize[qi-1]--;
1050            need = 0;
1051        } else {
1052            qData[qi-1].pop_front();
1053            qSize[qi-1]--;
1054            need -= head_bytes;
1055        }
1056    }
1057
1058    add(OP_DEQUEUE, flags, cpuid, sm, qi, count);
1059    DPRINTF(AnnotateQ, "Dequeing in queue %s size now %d/%d\n",
1060            q, qSize[qi-1], qBytes[qi-1]);
1061}
1062
1063
1064
1065void
1066CPA::serialize(std::ostream &os)
1067{
1068
1069    SERIALIZE_SCALAR(numSm);
1070    SERIALIZE_SCALAR(numSmt);
1071    arrayParamOut(os, "numSt", numSt);
1072    arrayParamOut(os, "numQ", numQ);
1073    SERIALIZE_SCALAR(numSys);
1074    SERIALIZE_SCALAR(numQs);
1075    SERIALIZE_SCALAR(conId);
1076    arrayParamOut(os, "qSize", qSize);
1077    arrayParamOut(os, "qSize", qSize);
1078    arrayParamOut(os, "qBytes", qBytes);
1079
1080    std::list<AnnDataPtr>::iterator ai;
1081
1082    SCache::iterator i;
1083    int x = 0, y = 0;
1084
1085    // smtCache (SCache)
1086    x = 0;
1087    y = 0;
1088    i = smtCache.begin();
1089    while (i != smtCache.end()) {
1090        paramOut(os, csprintf("smtCache%d.str", x), i->first);
1091        paramOut(os, csprintf("smtCache%d.int", x), i->second);
1092        x++; i++;
1093    }
1094
1095    // stCache  (StCache)
1096    for (x = 0; x < stCache.size(); x++) {
1097        i = stCache[x].begin();
1098        y = 0;
1099        while (i != stCache[x].end()) {
1100            paramOut(os, csprintf("stCache%d_%d.str", x, y), i->first);
1101            paramOut(os, csprintf("stCache%d_%d.int", x, y), i->second);
1102            y++; i++;
1103        }
1104    }
1105
1106    // qCache (IdCache)
1107    IdHCache::iterator idi;
1108    for (x = 0; x < qCache.size(); x++) {
1109        idi = qCache[x].begin();
1110        y = 0;
1111        while (idi != qCache[x].end()) {
1112            paramOut(os, csprintf("qCache%d_%d.str", x, y), idi->first.first);
1113            paramOut(os, csprintf("qCache%d_%d.id", x, y), idi->first.second);
1114            paramOut(os, csprintf("qCache%d_%d.int", x, y), idi->second);
1115            y++; idi++;
1116        }
1117    }
1118
1119    // smCache (IdCache)
1120    for (x = 0; x < smCache.size(); x++) {
1121        idi = smCache[x].begin();
1122        y = 0;
1123        paramOut(os, csprintf("smCache%d", x), smCache[x].size());
1124        while (idi != smCache[x].end()) {
1125            paramOut(os, csprintf("smCache%d_%d.str", x, y), idi->first.first);
1126            paramOut(os, csprintf("smCache%d_%d.id", x, y), idi->first.second);
1127            paramOut(os, csprintf("smCache%d_%d.int", x, y), idi->second);
1128            y++; idi++;
1129        }
1130    }
1131
1132    // scLinks (ScCache) -- data not serialize
1133
1134
1135    // namecache (NameCache)
1136    NameCache::iterator ni;
1137
1138    ni = nameCache.begin();
1139    x = 0;
1140    while (ni != nameCache.end()) {
1141        paramOut(os, csprintf("nameCache%d.name", x), ni->first->name());
1142        paramOut(os, csprintf("nameCache%d.str", x), ni->second.first);
1143        paramOut(os, csprintf("nameCache%d.int", x), ni->second.second);
1144        x++; ni++;
1145    }
1146
1147    // smStack (SmStack)
1148    SmStack::iterator si;
1149    si = smStack.begin();
1150    x = 0;
1151    paramOut(os, "smStackIdCount", smStack.size());
1152    while (si != smStack.end()) {
1153        paramOut(os, csprintf("smStackId%d.sys", x), si->first.first);
1154        paramOut(os, csprintf("smStackId%d.frame", x), si->first.second);
1155        paramOut(os, csprintf("smStackId%d.count", x), si->second.size());
1156        for (y = 0; y < si->second.size(); y++)
1157            paramOut(os, csprintf("smStackId%d_%d", x, y), si->second[y]);
1158        x++; si++;
1159    }
1160
1161    // lnMap (LinkMap)
1162    x = 0;
1163    LinkMap::iterator li;
1164    li = lnMap.begin();
1165    paramOut(os, "lnMapSize", lnMap.size());
1166    while (li != lnMap.end()) {
1167        paramOut(os, csprintf("lnMap%d.smi", x), li->first);
1168        paramOut(os, csprintf("lnMap%d.lsmi", x), li->second);
1169        x++; li++;
1170    }
1171
1172    // swExpl (vector)
1173    SwExpl::iterator swexpli;
1174    swexpli = swExpl.begin();
1175    x = 0;
1176    paramOut(os, "swExplCount", swExpl.size());
1177    while (swexpli != swExpl.end()) {
1178        paramOut(os, csprintf("swExpl%d.sys", x), swexpli->first.first);
1179        paramOut(os, csprintf("swExpl%d.frame", x), swexpli->first.second);
1180        paramOut(os, csprintf("swExpl%d.swexpl", x), swexpli->second);
1181        x++; swexpli++;
1182    }
1183
1184    // lastState (IMap)
1185    x = 0;
1186    IMap::iterator ii;
1187    ii = lastState.begin();
1188    paramOut(os, "lastStateSize", lastState.size());
1189    while (ii != lastState.end()) {
1190        paramOut(os, csprintf("lastState%d.smi", x), ii->first);
1191        paramOut(os, csprintf("lastState%d.sti", x), ii->second);
1192        x++; ii++;
1193    }
1194
1195    // smMap (IdMap)
1196    for (x = 0; x < smMap.size(); x++) {
1197        paramOut(os, csprintf("smMap%d.sys", x), smMap[x].first);
1198        paramOut(os, csprintf("smMap%d.smname", x), smMap[x].second.first);
1199        paramOut(os, csprintf("smMap%d.id", x), smMap[x].second.second);
1200    }
1201
1202    // qMap (IdMap)
1203    for (x = 0; x < qMap.size(); x++) {
1204        paramOut(os, csprintf("qMap%d.sys", x), qMap[x].first);
1205        paramOut(os, csprintf("qMap%d.qname", x), qMap[x].second.first);
1206        paramOut(os, csprintf("qMap%d.id", x), qMap[x].second.second);
1207    }
1208
1209    // qData (vector<AnnotateList>)
1210    for(x = 0; x < qData.size(); x++) {
1211        if (!qData[x].size())
1212            continue;
1213        y = 0;
1214        ai = qData[x].begin();
1215        while (ai != qData[x].end()) {
1216            nameOut(os, csprintf("%s.Q%d_%d", name(), x, y));
1217            (*ai)->serialize(os);
1218            ai++;
1219            y++;
1220        }
1221    }
1222}
1223
1224void
1225CPA::unserialize(Checkpoint *cp, const std::string &section)
1226{
1227    UNSERIALIZE_SCALAR(numSm);
1228    UNSERIALIZE_SCALAR(numSmt);
1229    arrayParamIn(cp, section, "numSt", numSt);
1230    arrayParamIn(cp, section, "numQ", numQ);
1231    UNSERIALIZE_SCALAR(numSys);
1232    UNSERIALIZE_SCALAR(numQs);
1233    UNSERIALIZE_SCALAR(conId);
1234    arrayParamIn(cp, section, "qSize", qSize);
1235    arrayParamIn(cp, section, "qBytes", qBytes);
1236
1237
1238    // smtCache (SCache
1239    string str;
1240    int smi;
1241    for (int x = 0;  x < numSmt; x++) {
1242        paramIn(cp, section, csprintf("smtCache%d.str", x), str);
1243        paramIn(cp, section, csprintf("smtCache%d.int", x), smi);
1244        smtCache[str] = smi;
1245    }
1246
1247    // stCache  (StCache)
1248    stCache.resize(numSmt);
1249    for (int x = 0;  x < numSmt; x++) {
1250        for (int y = 0; y < numSt[x]; y++) {
1251            paramIn(cp, section, csprintf("stCache%d_%d.str", x,y), str);
1252            paramIn(cp, section, csprintf("stCache%d_%d.int", x,y), smi);
1253            stCache[x][str] = smi;
1254        }
1255    }
1256
1257    // qCache (IdCache)
1258    uint64_t id;
1259    qCache.resize(numSys);
1260    for (int x = 0;  x < numSys; x++) {
1261        for (int y = 0; y < numQ[x]; y++) {
1262            paramIn(cp, section, csprintf("qCache%d_%d.str", x,y), str);
1263            paramIn(cp, section, csprintf("qCache%d_%d.id", x,y), id);
1264            paramIn(cp, section, csprintf("qCache%d_%d.int", x,y), smi);
1265            qCache[x][Id(str,id)] = smi;
1266        }
1267    }
1268
1269    // smCache (IdCache)
1270    smCache.resize(numSys);
1271    for (int x = 0;  x < numSys; x++) {
1272        int size;
1273        paramIn(cp, section, csprintf("smCache%d", x), size);
1274        for (int y = 0; y < size; y++) {
1275            paramIn(cp, section, csprintf("smCache%d_%d.str", x,y), str);
1276            paramIn(cp, section, csprintf("smCache%d_%d.id", x,y), id);
1277            paramIn(cp, section, csprintf("smCache%d_%d.int", x,y), smi);
1278            smCache[x][Id(str,id)] = smi;
1279        }
1280    }
1281
1282    // scLinks (ScCache) -- data not serialized, just creating one per sys
1283    for (int x = 0; x < numSys; x++)
1284        scLinks.push_back(ScHCache());
1285
1286    // nameCache (NameCache)
1287    for (int x = 0; x < numSys; x++) {
1288        System *sys;
1289        SimObject *sptr;
1290        string str;
1291        int sysi;
1292
1293        objParamIn(cp, section, csprintf("nameCache%d.name", x), sptr);
1294        sys = dynamic_cast<System*>(sptr);
1295
1296        paramIn(cp, section, csprintf("nameCache%d.str", x), str);
1297        paramIn(cp, section, csprintf("nameCache%d.int", x), sysi);
1298        nameCache[sys] = std::make_pair(str, sysi);
1299    }
1300
1301    //smStack (SmStack)
1302    int smStack_size;
1303    paramIn(cp, section, "smStackIdCount", smStack_size);
1304    for (int x = 0; x < smStack_size; x++) {
1305        int sysi;
1306        uint64_t frame;
1307        int count;
1308        paramIn(cp, section, csprintf("smStackId%d.sys", x), sysi);
1309        paramIn(cp, section, csprintf("smStackId%d.frame", x), frame);
1310        paramIn(cp, section, csprintf("smStackId%d.count", x), count);
1311        StackId sid = StackId(sysi, frame);
1312        for (int y = 0; y < count; y++) {
1313            paramIn(cp, section, csprintf("smStackId%d_%d", x, y), smi);
1314            smStack[sid].push_back(smi);
1315        }
1316    }
1317
1318    // lnMap (LinkMap)
1319    int lsmi;
1320    int lnMap_size;
1321    paramIn(cp, section, "lnMapSize", lnMap_size);
1322    for (int x = 0;  x < lnMap_size; x++) {
1323        paramIn(cp, section, csprintf("lnMap%d.smi", x), smi);
1324        paramIn(cp, section, csprintf("lnMap%d.lsmi", x), lsmi);
1325        lnMap[smi] = lsmi;
1326    }
1327
1328    // swExpl (vector)
1329    int swExpl_size;
1330    paramIn(cp, section, "swExplCount", swExpl_size);
1331    for (int x = 0; x < swExpl_size; x++) {
1332        int sysi;
1333        uint64_t frame;
1334        bool b;
1335        paramIn(cp, section, csprintf("swExpl%d.sys", x), sysi);
1336        paramIn(cp, section, csprintf("swExpl%d.frame", x), frame);
1337        paramIn(cp, section, csprintf("swExpl%d.swexpl", x), b);
1338        StackId sid = StackId(sysi, frame);
1339        swExpl[sid] = b;
1340    }
1341
1342    // lastState (IMap)
1343    int sti;
1344    int lastState_size;
1345    paramIn(cp, section, "lastStateSize", lastState_size);
1346    for (int x = 0;  x < lastState_size; x++) {
1347        paramIn(cp, section, csprintf("lastState%d.smi", x), smi);
1348        paramIn(cp, section, csprintf("lastState%d.sti", x), sti);
1349        lastState[smi] = sti;
1350    }
1351
1352
1353    //smMap (IdMap)
1354    smMap.resize(numSm);
1355    for (int x = 0; x < smMap.size(); x++) {
1356        paramIn(cp, section, csprintf("smMap%d.sys", x), smMap[x].first);
1357        paramIn(cp, section, csprintf("smMap%d.smname", x), smMap[x].second.first);
1358        paramIn(cp, section, csprintf("smMap%d.id", x), smMap[x].second.second);
1359    }
1360
1361    //qMap (IdMap)
1362    qMap.resize(numQs);
1363    for (int x = 0; x < qMap.size(); x++) {
1364        paramIn(cp, section, csprintf("qMap%d.sys", x), qMap[x].first);
1365        paramIn(cp, section, csprintf("qMap%d.qname", x), qMap[x].second.first);
1366        paramIn(cp, section, csprintf("qMap%d.id", x), qMap[x].second.second);
1367    }
1368
1369
1370    // qData (vector<AnnotateList>)
1371    qData.resize(qSize.size());
1372    for (int x = 0; x < qSize.size(); x++) {
1373        if (!qSize[x])
1374            continue;
1375        for (int y = 0; y < qSize[x]; y++) {
1376            AnnDataPtr a = new AnnotateData;
1377            a->unserialize(cp, csprintf("%s.Q%d_%d", section, x, y));
1378            data.push_back(a);
1379            qData[x].push_back(a);
1380        }
1381    }
1382}
1383
1384void
1385CPA::AnnotateData::serialize(std::ostream &os)
1386{
1387    SERIALIZE_SCALAR(time);
1388    SERIALIZE_SCALAR(data);
1389    SERIALIZE_SCALAR(sm);
1390    SERIALIZE_SCALAR(stq);
1391    SERIALIZE_SCALAR(op);
1392    SERIALIZE_SCALAR(flag);
1393    SERIALIZE_SCALAR(cpu);
1394}
1395
1396void
1397CPA::AnnotateData::unserialize(Checkpoint *cp, const std::string &section)
1398{
1399    UNSERIALIZE_SCALAR(time);
1400    UNSERIALIZE_SCALAR(data);
1401    orig_data = data;
1402    UNSERIALIZE_SCALAR(sm);
1403    UNSERIALIZE_SCALAR(stq);
1404    UNSERIALIZE_SCALAR(op);
1405    UNSERIALIZE_SCALAR(flag);
1406    UNSERIALIZE_SCALAR(cpu);
1407    dump = true;
1408}
1409
1410CPA*
1411CPAParams::create()
1412{
1413    return new CPA(this);
1414}
1415
1416