pseudo_inst.cc revision 8229
1298SN/A/*
28142SAli.Saidi@ARM.com * Copyright (c) 2010 ARM Limited
38142SAli.Saidi@ARM.com * All rights reserved
48142SAli.Saidi@ARM.com *
58142SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall
68142SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual
78142SAli.Saidi@ARM.com * property including but not limited to intellectual property relating
88142SAli.Saidi@ARM.com * to a hardware implementation of the functionality of the software
98142SAli.Saidi@ARM.com * licensed hereunder.  You may use the software subject to the license
108142SAli.Saidi@ARM.com * terms below provided that you ensure that this notice is replicated
118142SAli.Saidi@ARM.com * unmodified and in its entirety in all distributions of the software,
128142SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form.
138142SAli.Saidi@ARM.com *
142188SN/A * Copyright (c) 2003-2006 The Regents of The University of Michigan
15298SN/A * All rights reserved.
16298SN/A *
17298SN/A * Redistribution and use in source and binary forms, with or without
18298SN/A * modification, are permitted provided that the following conditions are
19298SN/A * met: redistributions of source code must retain the above copyright
20298SN/A * notice, this list of conditions and the following disclaimer;
21298SN/A * redistributions in binary form must reproduce the above copyright
22298SN/A * notice, this list of conditions and the following disclaimer in the
23298SN/A * documentation and/or other materials provided with the distribution;
24298SN/A * neither the name of the copyright holders nor the names of its
25298SN/A * contributors may be used to endorse or promote products derived from
26298SN/A * this software without specific prior written permission.
27298SN/A *
28298SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29298SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30298SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31298SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32298SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33298SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34298SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35298SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36298SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37298SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38298SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392665Ssaidi@eecs.umich.edu *
402665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
41298SN/A */
42298SN/A
43954SN/A#include <fcntl.h>
44956SN/A#include <unistd.h>
45956SN/A
468229Snate@binkert.org#include <cerrno>
474078Sbinkertn@umich.edu#include <fstream>
48299SN/A#include <string>
49299SN/A
502170SN/A#include "arch/vtophys.hh"
515882Snate@binkert.org#include "base/debug.hh"
526658Snate@binkert.org#include "config/full_system.hh"
536658Snate@binkert.org#include "config/the_isa.hh"
541717SN/A#include "cpu/base.hh"
558229Snate@binkert.org#include "cpu/quiesce_event.hh"
562680Sktlim@umich.edu#include "cpu/thread_context.hh"
575529Snate@binkert.org#include "params/BaseCPU.hh"
583565Sgblack@eecs.umich.edu#include "sim/pseudo_inst.hh"
59298SN/A#include "sim/serialize.hh"
605606Snate@binkert.org#include "sim/sim_events.hh"
61298SN/A#include "sim/sim_exit.hh"
62695SN/A#include "sim/stat_control.hh"
63695SN/A#include "sim/stats.hh"
64954SN/A#include "sim/system.hh"
656118Snate@binkert.org
665780Ssteve.reinhardt@amd.com#if FULL_SYSTEM
676118Snate@binkert.org#include "arch/kernel_stats.hh"
682080SN/A#include "sim/vptr.hh"
695780Ssteve.reinhardt@amd.com#endif
70298SN/A
71299SN/Ausing namespace std;
721052SN/A
73729SN/Ausing namespace Stats;
742107SN/Ausing namespace TheISA;
75298SN/A
765504Snate@binkert.orgnamespace PseudoInst {
775504Snate@binkert.org
785780Ssteve.reinhardt@amd.com#if FULL_SYSTEM
795780Ssteve.reinhardt@amd.com
805504Snate@binkert.orgvoid
815504Snate@binkert.orgarm(ThreadContext *tc)
82298SN/A{
835504Snate@binkert.org    if (tc->getKernelStats())
845504Snate@binkert.org        tc->getKernelStats()->arm();
855504Snate@binkert.org}
865504Snate@binkert.org
875504Snate@binkert.orgvoid
885504Snate@binkert.orgquiesce(ThreadContext *tc)
895504Snate@binkert.org{
905529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_quiesce)
915504Snate@binkert.org        return;
925504Snate@binkert.org
935504Snate@binkert.org    DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name());
945504Snate@binkert.org
955504Snate@binkert.org    tc->suspend();
965504Snate@binkert.org    if (tc->getKernelStats())
975504Snate@binkert.org        tc->getKernelStats()->quiesce();
985504Snate@binkert.org}
995504Snate@binkert.org
1005504Snate@binkert.orgvoid
1018142SAli.Saidi@ARM.comquiesceSkip(ThreadContext *tc)
1028142SAli.Saidi@ARM.com{
1038142SAli.Saidi@ARM.com    BaseCPU *cpu = tc->getCpuPtr();
1048142SAli.Saidi@ARM.com
1058142SAli.Saidi@ARM.com    if (!cpu->params()->do_quiesce)
1068142SAli.Saidi@ARM.com        return;
1078142SAli.Saidi@ARM.com
1088142SAli.Saidi@ARM.com    EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1098142SAli.Saidi@ARM.com
1108142SAli.Saidi@ARM.com    Tick resume = curTick() + 1;
1118142SAli.Saidi@ARM.com
1128142SAli.Saidi@ARM.com    cpu->reschedule(quiesceEvent, resume, true);
1138142SAli.Saidi@ARM.com
1148142SAli.Saidi@ARM.com    DPRINTF(Quiesce, "%s: quiesceSkip() until %d\n",
1158142SAli.Saidi@ARM.com            cpu->name(), resume);
1168142SAli.Saidi@ARM.com
1178142SAli.Saidi@ARM.com    tc->suspend();
1188142SAli.Saidi@ARM.com    if (tc->getKernelStats())
1198142SAli.Saidi@ARM.com        tc->getKernelStats()->quiesce();
1208142SAli.Saidi@ARM.com}
1218142SAli.Saidi@ARM.com
1228142SAli.Saidi@ARM.comvoid
1235504Snate@binkert.orgquiesceNs(ThreadContext *tc, uint64_t ns)
1245504Snate@binkert.org{
1257819Ssteve.reinhardt@amd.com    BaseCPU *cpu = tc->getCpuPtr();
1267819Ssteve.reinhardt@amd.com
1277819Ssteve.reinhardt@amd.com    if (!cpu->params()->do_quiesce || ns == 0)
1285504Snate@binkert.org        return;
1295504Snate@binkert.org
1305504Snate@binkert.org    EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1315504Snate@binkert.org
1327823Ssteve.reinhardt@amd.com    Tick resume = curTick() + SimClock::Int::ns * ns;
1335504Snate@binkert.org
1347819Ssteve.reinhardt@amd.com    cpu->reschedule(quiesceEvent, resume, true);
1355504Snate@binkert.org
1365504Snate@binkert.org    DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
1377819Ssteve.reinhardt@amd.com            cpu->name(), ns, resume);
1385504Snate@binkert.org
1395504Snate@binkert.org    tc->suspend();
1405504Snate@binkert.org    if (tc->getKernelStats())
1415504Snate@binkert.org        tc->getKernelStats()->quiesce();
1425504Snate@binkert.org}
1435504Snate@binkert.org
1445504Snate@binkert.orgvoid
1455504Snate@binkert.orgquiesceCycles(ThreadContext *tc, uint64_t cycles)
1465504Snate@binkert.org{
1477819Ssteve.reinhardt@amd.com    BaseCPU *cpu = tc->getCpuPtr();
1487819Ssteve.reinhardt@amd.com
1497819Ssteve.reinhardt@amd.com    if (!cpu->params()->do_quiesce || cycles == 0)
1505504Snate@binkert.org        return;
1515504Snate@binkert.org
1525504Snate@binkert.org    EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1535504Snate@binkert.org
1547823Ssteve.reinhardt@amd.com    Tick resume = curTick() + cpu->ticks(cycles);
1555504Snate@binkert.org
1567819Ssteve.reinhardt@amd.com    cpu->reschedule(quiesceEvent, resume, true);
1575504Snate@binkert.org
1585504Snate@binkert.org    DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
1597819Ssteve.reinhardt@amd.com            cpu->name(), cycles, resume);
1605504Snate@binkert.org
1615504Snate@binkert.org    tc->suspend();
1625504Snate@binkert.org    if (tc->getKernelStats())
1635504Snate@binkert.org        tc->getKernelStats()->quiesce();
1645504Snate@binkert.org}
1655504Snate@binkert.org
1665504Snate@binkert.orguint64_t
1675504Snate@binkert.orgquiesceTime(ThreadContext *tc)
1685504Snate@binkert.org{
1697064Snate@binkert.org    return (tc->readLastActivate() - tc->readLastSuspend()) /
1707064Snate@binkert.org        SimClock::Int::ns;
1715504Snate@binkert.org}
1725504Snate@binkert.org
1735780Ssteve.reinhardt@amd.com#endif
1745780Ssteve.reinhardt@amd.com
1755741Snate@binkert.orguint64_t
1765741Snate@binkert.orgrpns(ThreadContext *tc)
1775741Snate@binkert.org{
1787823Ssteve.reinhardt@amd.com    return curTick() / SimClock::Int::ns;
1795741Snate@binkert.org}
1805741Snate@binkert.org
1815504Snate@binkert.orgvoid
1825808Snate@binkert.orgwakeCPU(ThreadContext *tc, uint64_t cpuid)
1835808Snate@binkert.org{
1845808Snate@binkert.org    System *sys = tc->getSystemPtr();
1855808Snate@binkert.org    ThreadContext *other_tc = sys->threadContexts[cpuid];
1865808Snate@binkert.org    if (other_tc->status() == ThreadContext::Suspended)
1875808Snate@binkert.org        other_tc->activate();
1885808Snate@binkert.org}
1895808Snate@binkert.org
1905808Snate@binkert.orgvoid
1915504Snate@binkert.orgm5exit(ThreadContext *tc, Tick delay)
1925504Snate@binkert.org{
1937823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
1947819Ssteve.reinhardt@amd.com    exitSimLoop("m5_exit instruction encountered", 0, when);
1955504Snate@binkert.org}
1965504Snate@binkert.org
1975780Ssteve.reinhardt@amd.com#if FULL_SYSTEM
1985780Ssteve.reinhardt@amd.com
1995504Snate@binkert.orgvoid
2005504Snate@binkert.orgloadsymbol(ThreadContext *tc)
2015504Snate@binkert.org{
2025504Snate@binkert.org    const string &filename = tc->getCpuPtr()->system->params()->symbolfile;
2035504Snate@binkert.org    if (filename.empty()) {
2045504Snate@binkert.org        return;
205711SN/A    }
206711SN/A
2075504Snate@binkert.org    std::string buffer;
2085504Snate@binkert.org    ifstream file(filename.c_str());
209310SN/A
2105504Snate@binkert.org    if (!file)
2115504Snate@binkert.org        fatal("file error: Can't open symbol table file %s\n", filename);
2123373Sstever@eecs.umich.edu
2135504Snate@binkert.org    while (!file.eof()) {
2145504Snate@binkert.org        getline(file, buffer);
2155504Snate@binkert.org
2165504Snate@binkert.org        if (buffer.empty())
2175504Snate@binkert.org            continue;
2185504Snate@binkert.org
2196227Snate@binkert.org        string::size_type idx = buffer.find(' ');
2205504Snate@binkert.org        if (idx == string::npos)
2215504Snate@binkert.org            continue;
2225504Snate@binkert.org
2235504Snate@binkert.org        string address = "0x" + buffer.substr(0, idx);
2245504Snate@binkert.org        eat_white(address);
2255504Snate@binkert.org        if (address.empty())
2265504Snate@binkert.org            continue;
2275504Snate@binkert.org
2285504Snate@binkert.org        // Skip over letter and space
2295504Snate@binkert.org        string symbol = buffer.substr(idx + 3);
2305504Snate@binkert.org        eat_white(symbol);
2315504Snate@binkert.org        if (symbol.empty())
2325504Snate@binkert.org            continue;
2335504Snate@binkert.org
2345504Snate@binkert.org        Addr addr;
2355504Snate@binkert.org        if (!to_number(address, addr))
2365504Snate@binkert.org            continue;
2375504Snate@binkert.org
2385504Snate@binkert.org        if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol))
2395504Snate@binkert.org            continue;
2405504Snate@binkert.org
2415504Snate@binkert.org
2425504Snate@binkert.org        DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
2435504Snate@binkert.org    }
2445504Snate@binkert.org    file.close();
2455504Snate@binkert.org}
2465504Snate@binkert.org
2475504Snate@binkert.orgvoid
2485780Ssteve.reinhardt@amd.comaddsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
2495780Ssteve.reinhardt@amd.com{
2505780Ssteve.reinhardt@amd.com    char symb[100];
2515780Ssteve.reinhardt@amd.com    CopyStringOut(tc, symb, symbolAddr, 100);
2525780Ssteve.reinhardt@amd.com    std::string symbol(symb);
2535780Ssteve.reinhardt@amd.com
2545780Ssteve.reinhardt@amd.com    DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
2555780Ssteve.reinhardt@amd.com
2565780Ssteve.reinhardt@amd.com    tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
2575952Ssaidi@eecs.umich.edu    debugSymbolTable->insert(addr,symbol);
2585780Ssteve.reinhardt@amd.com}
2595780Ssteve.reinhardt@amd.com
2605780Ssteve.reinhardt@amd.com#endif
2615780Ssteve.reinhardt@amd.com
2625780Ssteve.reinhardt@amd.com
2635780Ssteve.reinhardt@amd.comvoid
2645504Snate@binkert.orgresetstats(ThreadContext *tc, Tick delay, Tick period)
2655504Snate@binkert.org{
2665529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_statistics_insts)
2675504Snate@binkert.org        return;
2685504Snate@binkert.org
2695504Snate@binkert.org
2707823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
2717064Snate@binkert.org    Tick repeat = period * SimClock::Int::ns;
2725504Snate@binkert.org
2737822Ssteve.reinhardt@amd.com    Stats::schedStatEvent(false, true, when, repeat);
2745504Snate@binkert.org}
2755504Snate@binkert.org
2765504Snate@binkert.orgvoid
2775504Snate@binkert.orgdumpstats(ThreadContext *tc, Tick delay, Tick period)
2785504Snate@binkert.org{
2795529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_statistics_insts)
2805504Snate@binkert.org        return;
2815504Snate@binkert.org
2825504Snate@binkert.org
2837823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
2847064Snate@binkert.org    Tick repeat = period * SimClock::Int::ns;
2855504Snate@binkert.org
2867822Ssteve.reinhardt@amd.com    Stats::schedStatEvent(true, false, when, repeat);
2875504Snate@binkert.org}
2885504Snate@binkert.org
2895504Snate@binkert.orgvoid
2905504Snate@binkert.orgdumpresetstats(ThreadContext *tc, Tick delay, Tick period)
2915504Snate@binkert.org{
2925529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_statistics_insts)
2935504Snate@binkert.org        return;
2945504Snate@binkert.org
2955504Snate@binkert.org
2967823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
2977064Snate@binkert.org    Tick repeat = period * SimClock::Int::ns;
2985504Snate@binkert.org
2997822Ssteve.reinhardt@amd.com    Stats::schedStatEvent(true, true, when, repeat);
3005504Snate@binkert.org}
3015504Snate@binkert.org
3025504Snate@binkert.orgvoid
3035504Snate@binkert.orgm5checkpoint(ThreadContext *tc, Tick delay, Tick period)
3045504Snate@binkert.org{
3055529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_checkpoint_insts)
3065504Snate@binkert.org        return;
3075504Snate@binkert.org
3087823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
3097064Snate@binkert.org    Tick repeat = period * SimClock::Int::ns;
3105504Snate@binkert.org
3117819Ssteve.reinhardt@amd.com    exitSimLoop("checkpoint", 0, when, repeat);
3125504Snate@binkert.org}
3135504Snate@binkert.org
3145780Ssteve.reinhardt@amd.com#if FULL_SYSTEM
3155780Ssteve.reinhardt@amd.com
3165504Snate@binkert.orguint64_t
3175504Snate@binkert.orgreadfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset)
3185504Snate@binkert.org{
3195504Snate@binkert.org    const string &file = tc->getSystemPtr()->params()->readfile;
3205504Snate@binkert.org    if (file.empty()) {
3215504Snate@binkert.org        return ULL(0);
322310SN/A    }
323299SN/A
3245504Snate@binkert.org    uint64_t result = 0;
3252188SN/A
3265504Snate@binkert.org    int fd = ::open(file.c_str(), O_RDONLY, 0);
3275504Snate@binkert.org    if (fd < 0)
3285504Snate@binkert.org        panic("could not open file %s\n", file);
3292235SN/A
3305504Snate@binkert.org    if (::lseek(fd, offset, SEEK_SET) < 0)
3315504Snate@binkert.org        panic("could not seek: %s", strerror(errno));
3323368Sstever@eecs.umich.edu
3335504Snate@binkert.org    char *buf = new char[len];
3345504Snate@binkert.org    char *p = buf;
3355504Snate@binkert.org    while (len > 0) {
3365504Snate@binkert.org        int bytes = ::read(fd, p, len);
3375504Snate@binkert.org        if (bytes <= 0)
3385504Snate@binkert.org            break;
3393368Sstever@eecs.umich.edu
3405504Snate@binkert.org        p += bytes;
3415504Snate@binkert.org        result += bytes;
3425504Snate@binkert.org        len -= bytes;
3432188SN/A    }
3442188SN/A
3455504Snate@binkert.org    close(fd);
3465504Snate@binkert.org    CopyIn(tc, vaddr, buf, result);
3475504Snate@binkert.org    delete [] buf;
3485504Snate@binkert.org    return result;
3495504Snate@binkert.org}
3502188SN/A
3515780Ssteve.reinhardt@amd.com#endif
3525780Ssteve.reinhardt@amd.com
3535504Snate@binkert.orgvoid
3545504Snate@binkert.orgdebugbreak(ThreadContext *tc)
3555504Snate@binkert.org{
3565504Snate@binkert.org    debug_break();
3575504Snate@binkert.org}
3582235SN/A
3595504Snate@binkert.orgvoid
3605504Snate@binkert.orgswitchcpu(ThreadContext *tc)
3615504Snate@binkert.org{
3625504Snate@binkert.org    exitSimLoop("switchcpu");
3635504Snate@binkert.org}
3643368Sstever@eecs.umich.edu
3657914SBrad.Beckmann@amd.com//
3667914SBrad.Beckmann@amd.com// This function is executed when annotated work items begin.  Depending on
3677914SBrad.Beckmann@amd.com// what the user specified at the command line, the simulation may exit and/or
3687914SBrad.Beckmann@amd.com// take a checkpoint when a certain work item begins.
3697914SBrad.Beckmann@amd.com//
3707914SBrad.Beckmann@amd.comvoid
3717914SBrad.Beckmann@amd.comworkbegin(ThreadContext *tc, uint64_t workid, uint64_t threadid)
3727914SBrad.Beckmann@amd.com{
3737914SBrad.Beckmann@amd.com    tc->getCpuPtr()->workItemBegin();
3747914SBrad.Beckmann@amd.com    System *sys = tc->getSystemPtr();
3757914SBrad.Beckmann@amd.com
3767914SBrad.Beckmann@amd.com    DPRINTF(WorkItems, "Work Begin workid: %d, threadid %d\n", workid,
3777914SBrad.Beckmann@amd.com            threadid);
3787914SBrad.Beckmann@amd.com
3797914SBrad.Beckmann@amd.com    //
3807914SBrad.Beckmann@amd.com    // If specified, determine if this is the specific work item the user
3817914SBrad.Beckmann@amd.com    // identified
3827914SBrad.Beckmann@amd.com    //
3837914SBrad.Beckmann@amd.com    if (sys->params()->work_item_id == -1 ||
3847914SBrad.Beckmann@amd.com        sys->params()->work_item_id == workid) {
3857914SBrad.Beckmann@amd.com
3867914SBrad.Beckmann@amd.com        uint64_t systemWorkBeginCount = sys->incWorkItemsBegin();
3877914SBrad.Beckmann@amd.com        int cpuId = tc->getCpuPtr()->cpuId();
3887914SBrad.Beckmann@amd.com
3897914SBrad.Beckmann@amd.com        if (sys->params()->work_cpus_ckpt_count != 0 &&
3907914SBrad.Beckmann@amd.com            sys->markWorkItem(cpuId) >= sys->params()->work_cpus_ckpt_count) {
3917914SBrad.Beckmann@amd.com            //
3927914SBrad.Beckmann@amd.com            // If active cpus equals checkpoint count, create checkpoint
3937914SBrad.Beckmann@amd.com            //
3947914SBrad.Beckmann@amd.com            Event *event = new SimLoopExitEvent("checkpoint", 0);
3957914SBrad.Beckmann@amd.com            mainEventQueue.schedule(event, curTick());
3967914SBrad.Beckmann@amd.com        }
3977914SBrad.Beckmann@amd.com
3987914SBrad.Beckmann@amd.com        if (systemWorkBeginCount == sys->params()->work_begin_ckpt_count) {
3997914SBrad.Beckmann@amd.com            //
4007914SBrad.Beckmann@amd.com            // Note: the string specified as the cause of the exit event must
4017914SBrad.Beckmann@amd.com            // exactly equal "checkpoint" inorder to create a checkpoint
4027914SBrad.Beckmann@amd.com            //
4037914SBrad.Beckmann@amd.com            Event *event = new SimLoopExitEvent("checkpoint", 0);
4047914SBrad.Beckmann@amd.com            mainEventQueue.schedule(event, curTick());
4057914SBrad.Beckmann@amd.com        }
4067914SBrad.Beckmann@amd.com
4077914SBrad.Beckmann@amd.com        if (systemWorkBeginCount == sys->params()->work_begin_exit_count) {
4087914SBrad.Beckmann@amd.com            //
4097914SBrad.Beckmann@amd.com            // If a certain number of work items started, exit simulation
4107914SBrad.Beckmann@amd.com            //
4117914SBrad.Beckmann@amd.com            Event *event = new SimLoopExitEvent("work started count reach", 0);
4127914SBrad.Beckmann@amd.com            mainEventQueue.schedule(event, curTick());
4137914SBrad.Beckmann@amd.com        }
4147914SBrad.Beckmann@amd.com
4157914SBrad.Beckmann@amd.com        if (tc->getCpuPtr()->cpuId() == sys->params()->work_begin_cpu_id_exit) {
4167914SBrad.Beckmann@amd.com            //
4177914SBrad.Beckmann@amd.com            // If work started on the specific cpu id specified, exit simulation
4187914SBrad.Beckmann@amd.com            //
4197914SBrad.Beckmann@amd.com            Event *event = new SimLoopExitEvent("work started on specific cpu",
4207914SBrad.Beckmann@amd.com                                                0);
4217914SBrad.Beckmann@amd.com
4227914SBrad.Beckmann@amd.com            mainEventQueue.schedule(event, curTick() + 1);
4237914SBrad.Beckmann@amd.com        }
4247914SBrad.Beckmann@amd.com    }
4257914SBrad.Beckmann@amd.com}
4267914SBrad.Beckmann@amd.com
4277914SBrad.Beckmann@amd.com//
4287914SBrad.Beckmann@amd.com// This function is executed when annotated work items end.  Depending on
4297914SBrad.Beckmann@amd.com// what the user specified at the command line, the simulation may exit and/or
4307914SBrad.Beckmann@amd.com// take a checkpoint when a certain work item ends.
4317914SBrad.Beckmann@amd.com//
4327914SBrad.Beckmann@amd.comvoid
4337914SBrad.Beckmann@amd.comworkend(ThreadContext *tc, uint64_t workid, uint64_t threadid)
4347914SBrad.Beckmann@amd.com{
4357914SBrad.Beckmann@amd.com    tc->getCpuPtr()->workItemEnd();
4367914SBrad.Beckmann@amd.com    System *sys = tc->getSystemPtr();
4377914SBrad.Beckmann@amd.com
4387914SBrad.Beckmann@amd.com    DPRINTF(WorkItems, "Work End workid: %d, threadid %d\n", workid, threadid);
4397914SBrad.Beckmann@amd.com
4407914SBrad.Beckmann@amd.com    //
4417914SBrad.Beckmann@amd.com    // If specified, determine if this is the specific work item the user
4427914SBrad.Beckmann@amd.com    // identified
4437914SBrad.Beckmann@amd.com    //
4447914SBrad.Beckmann@amd.com    if (sys->params()->work_item_id == -1 ||
4457914SBrad.Beckmann@amd.com        sys->params()->work_item_id == workid) {
4467914SBrad.Beckmann@amd.com
4477914SBrad.Beckmann@amd.com        uint64_t systemWorkEndCount = sys->incWorkItemsEnd();
4487914SBrad.Beckmann@amd.com        int cpuId = tc->getCpuPtr()->cpuId();
4497914SBrad.Beckmann@amd.com
4507914SBrad.Beckmann@amd.com        if (sys->params()->work_cpus_ckpt_count != 0 &&
4517914SBrad.Beckmann@amd.com            sys->markWorkItem(cpuId) >= sys->params()->work_cpus_ckpt_count) {
4527914SBrad.Beckmann@amd.com            //
4537914SBrad.Beckmann@amd.com            // If active cpus equals checkpoint count, create checkpoint
4547914SBrad.Beckmann@amd.com            //
4557914SBrad.Beckmann@amd.com            Event *event = new SimLoopExitEvent("checkpoint", 0);
4567914SBrad.Beckmann@amd.com            mainEventQueue.schedule(event, curTick());
4577914SBrad.Beckmann@amd.com        }
4587914SBrad.Beckmann@amd.com
4597914SBrad.Beckmann@amd.com        if (sys->params()->work_end_ckpt_count != 0 &&
4607914SBrad.Beckmann@amd.com            systemWorkEndCount == sys->params()->work_end_ckpt_count) {
4617914SBrad.Beckmann@amd.com            //
4627914SBrad.Beckmann@amd.com            // If total work items completed equals checkpoint count, create
4637914SBrad.Beckmann@amd.com            // checkpoint
4647914SBrad.Beckmann@amd.com            //
4657914SBrad.Beckmann@amd.com            Event *event = new SimLoopExitEvent("checkpoint", 0);
4667914SBrad.Beckmann@amd.com            mainEventQueue.schedule(event, curTick());
4677914SBrad.Beckmann@amd.com        }
4687914SBrad.Beckmann@amd.com
4697914SBrad.Beckmann@amd.com        if (sys->params()->work_end_exit_count != 0 &&
4707914SBrad.Beckmann@amd.com            systemWorkEndCount == sys->params()->work_end_exit_count) {
4717914SBrad.Beckmann@amd.com            //
4727914SBrad.Beckmann@amd.com            // If total work items completed equals exit count, exit simulation
4737914SBrad.Beckmann@amd.com            //
4747914SBrad.Beckmann@amd.com            Event *event = new SimLoopExitEvent("work items exit count reached",
4757914SBrad.Beckmann@amd.com                                                0);
4767914SBrad.Beckmann@amd.com
4777914SBrad.Beckmann@amd.com            mainEventQueue.schedule(event, curTick());
4787914SBrad.Beckmann@amd.com        }
4797914SBrad.Beckmann@amd.com    }
4807914SBrad.Beckmann@amd.com}
4817914SBrad.Beckmann@amd.com
4827811Ssteve.reinhardt@amd.com} // namespace PseudoInst
483