pseudo_inst.cc revision 8734
1298SN/A/*
28734Sdam.sunwoo@arm.com * Copyright (c) 2010-2011 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 *
148580Ssteve.reinhardt@amd.com * Copyright (c) 2011 Advanced Micro Devices, Inc.
152188SN/A * Copyright (c) 2003-2006 The Regents of The University of Michigan
16298SN/A * All rights reserved.
17298SN/A *
18298SN/A * Redistribution and use in source and binary forms, with or without
19298SN/A * modification, are permitted provided that the following conditions are
20298SN/A * met: redistributions of source code must retain the above copyright
21298SN/A * notice, this list of conditions and the following disclaimer;
22298SN/A * redistributions in binary form must reproduce the above copyright
23298SN/A * notice, this list of conditions and the following disclaimer in the
24298SN/A * documentation and/or other materials provided with the distribution;
25298SN/A * neither the name of the copyright holders nor the names of its
26298SN/A * contributors may be used to endorse or promote products derived from
27298SN/A * this software without specific prior written permission.
28298SN/A *
29298SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30298SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31298SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32298SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33298SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34298SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35298SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36298SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37298SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38298SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39298SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402665Ssaidi@eecs.umich.edu *
412665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
42298SN/A */
43298SN/A
44954SN/A#include <fcntl.h>
45956SN/A#include <unistd.h>
46956SN/A
478229Snate@binkert.org#include <cerrno>
484078Sbinkertn@umich.edu#include <fstream>
49299SN/A#include <string>
50299SN/A
512170SN/A#include "arch/vtophys.hh"
525882Snate@binkert.org#include "base/debug.hh"
538734Sdam.sunwoo@arm.com#include "base/output.hh"
546658Snate@binkert.org#include "config/full_system.hh"
556658Snate@binkert.org#include "config/the_isa.hh"
561717SN/A#include "cpu/base.hh"
578229Snate@binkert.org#include "cpu/quiesce_event.hh"
582680Sktlim@umich.edu#include "cpu/thread_context.hh"
598232Snate@binkert.org#include "debug/Loader.hh"
608232Snate@binkert.org#include "debug/Quiesce.hh"
618232Snate@binkert.org#include "debug/WorkItems.hh"
625529Snate@binkert.org#include "params/BaseCPU.hh"
633565Sgblack@eecs.umich.edu#include "sim/pseudo_inst.hh"
64298SN/A#include "sim/serialize.hh"
655606Snate@binkert.org#include "sim/sim_events.hh"
66298SN/A#include "sim/sim_exit.hh"
67695SN/A#include "sim/stat_control.hh"
68695SN/A#include "sim/stats.hh"
69954SN/A#include "sim/system.hh"
706118Snate@binkert.org
715780Ssteve.reinhardt@amd.com#if FULL_SYSTEM
726118Snate@binkert.org#include "arch/kernel_stats.hh"
732080SN/A#include "sim/vptr.hh"
745780Ssteve.reinhardt@amd.com#endif
75298SN/A
76299SN/Ausing namespace std;
771052SN/A
78729SN/Ausing namespace Stats;
792107SN/Ausing namespace TheISA;
80298SN/A
815504Snate@binkert.orgnamespace PseudoInst {
825504Snate@binkert.org
835780Ssteve.reinhardt@amd.com#if FULL_SYSTEM
845780Ssteve.reinhardt@amd.com
855504Snate@binkert.orgvoid
865504Snate@binkert.orgarm(ThreadContext *tc)
87298SN/A{
885504Snate@binkert.org    if (tc->getKernelStats())
895504Snate@binkert.org        tc->getKernelStats()->arm();
905504Snate@binkert.org}
915504Snate@binkert.org
925504Snate@binkert.orgvoid
935504Snate@binkert.orgquiesce(ThreadContext *tc)
945504Snate@binkert.org{
955529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_quiesce)
965504Snate@binkert.org        return;
975504Snate@binkert.org
985504Snate@binkert.org    DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name());
995504Snate@binkert.org
1005504Snate@binkert.org    tc->suspend();
1015504Snate@binkert.org    if (tc->getKernelStats())
1025504Snate@binkert.org        tc->getKernelStats()->quiesce();
1035504Snate@binkert.org}
1045504Snate@binkert.org
1055504Snate@binkert.orgvoid
1068142SAli.Saidi@ARM.comquiesceSkip(ThreadContext *tc)
1078142SAli.Saidi@ARM.com{
1088142SAli.Saidi@ARM.com    BaseCPU *cpu = tc->getCpuPtr();
1098142SAli.Saidi@ARM.com
1108142SAli.Saidi@ARM.com    if (!cpu->params()->do_quiesce)
1118142SAli.Saidi@ARM.com        return;
1128142SAli.Saidi@ARM.com
1138142SAli.Saidi@ARM.com    EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1148142SAli.Saidi@ARM.com
1158142SAli.Saidi@ARM.com    Tick resume = curTick() + 1;
1168142SAli.Saidi@ARM.com
1178142SAli.Saidi@ARM.com    cpu->reschedule(quiesceEvent, resume, true);
1188142SAli.Saidi@ARM.com
1198142SAli.Saidi@ARM.com    DPRINTF(Quiesce, "%s: quiesceSkip() until %d\n",
1208142SAli.Saidi@ARM.com            cpu->name(), resume);
1218142SAli.Saidi@ARM.com
1228142SAli.Saidi@ARM.com    tc->suspend();
1238142SAli.Saidi@ARM.com    if (tc->getKernelStats())
1248142SAli.Saidi@ARM.com        tc->getKernelStats()->quiesce();
1258142SAli.Saidi@ARM.com}
1268142SAli.Saidi@ARM.com
1278142SAli.Saidi@ARM.comvoid
1285504Snate@binkert.orgquiesceNs(ThreadContext *tc, uint64_t ns)
1295504Snate@binkert.org{
1307819Ssteve.reinhardt@amd.com    BaseCPU *cpu = tc->getCpuPtr();
1317819Ssteve.reinhardt@amd.com
1327819Ssteve.reinhardt@amd.com    if (!cpu->params()->do_quiesce || ns == 0)
1335504Snate@binkert.org        return;
1345504Snate@binkert.org
1355504Snate@binkert.org    EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1365504Snate@binkert.org
1377823Ssteve.reinhardt@amd.com    Tick resume = curTick() + SimClock::Int::ns * ns;
1385504Snate@binkert.org
1397819Ssteve.reinhardt@amd.com    cpu->reschedule(quiesceEvent, resume, true);
1405504Snate@binkert.org
1415504Snate@binkert.org    DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
1427819Ssteve.reinhardt@amd.com            cpu->name(), ns, resume);
1435504Snate@binkert.org
1445504Snate@binkert.org    tc->suspend();
1455504Snate@binkert.org    if (tc->getKernelStats())
1465504Snate@binkert.org        tc->getKernelStats()->quiesce();
1475504Snate@binkert.org}
1485504Snate@binkert.org
1495504Snate@binkert.orgvoid
1505504Snate@binkert.orgquiesceCycles(ThreadContext *tc, uint64_t cycles)
1515504Snate@binkert.org{
1527819Ssteve.reinhardt@amd.com    BaseCPU *cpu = tc->getCpuPtr();
1537819Ssteve.reinhardt@amd.com
1547819Ssteve.reinhardt@amd.com    if (!cpu->params()->do_quiesce || cycles == 0)
1555504Snate@binkert.org        return;
1565504Snate@binkert.org
1575504Snate@binkert.org    EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1585504Snate@binkert.org
1597823Ssteve.reinhardt@amd.com    Tick resume = curTick() + cpu->ticks(cycles);
1605504Snate@binkert.org
1617819Ssteve.reinhardt@amd.com    cpu->reschedule(quiesceEvent, resume, true);
1625504Snate@binkert.org
1635504Snate@binkert.org    DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
1647819Ssteve.reinhardt@amd.com            cpu->name(), cycles, resume);
1655504Snate@binkert.org
1665504Snate@binkert.org    tc->suspend();
1675504Snate@binkert.org    if (tc->getKernelStats())
1685504Snate@binkert.org        tc->getKernelStats()->quiesce();
1695504Snate@binkert.org}
1705504Snate@binkert.org
1715504Snate@binkert.orguint64_t
1725504Snate@binkert.orgquiesceTime(ThreadContext *tc)
1735504Snate@binkert.org{
1747064Snate@binkert.org    return (tc->readLastActivate() - tc->readLastSuspend()) /
1757064Snate@binkert.org        SimClock::Int::ns;
1765504Snate@binkert.org}
1775504Snate@binkert.org
1785780Ssteve.reinhardt@amd.com#endif
1795780Ssteve.reinhardt@amd.com
1805741Snate@binkert.orguint64_t
1815741Snate@binkert.orgrpns(ThreadContext *tc)
1825741Snate@binkert.org{
1837823Ssteve.reinhardt@amd.com    return curTick() / SimClock::Int::ns;
1845741Snate@binkert.org}
1855741Snate@binkert.org
1865504Snate@binkert.orgvoid
1875808Snate@binkert.orgwakeCPU(ThreadContext *tc, uint64_t cpuid)
1885808Snate@binkert.org{
1895808Snate@binkert.org    System *sys = tc->getSystemPtr();
1905808Snate@binkert.org    ThreadContext *other_tc = sys->threadContexts[cpuid];
1915808Snate@binkert.org    if (other_tc->status() == ThreadContext::Suspended)
1925808Snate@binkert.org        other_tc->activate();
1935808Snate@binkert.org}
1945808Snate@binkert.org
1955808Snate@binkert.orgvoid
1965504Snate@binkert.orgm5exit(ThreadContext *tc, Tick delay)
1975504Snate@binkert.org{
1987823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
1997819Ssteve.reinhardt@amd.com    exitSimLoop("m5_exit instruction encountered", 0, when);
2005504Snate@binkert.org}
2015504Snate@binkert.org
2025780Ssteve.reinhardt@amd.com#if FULL_SYSTEM
2035780Ssteve.reinhardt@amd.com
2045504Snate@binkert.orgvoid
2055504Snate@binkert.orgloadsymbol(ThreadContext *tc)
2065504Snate@binkert.org{
2075504Snate@binkert.org    const string &filename = tc->getCpuPtr()->system->params()->symbolfile;
2085504Snate@binkert.org    if (filename.empty()) {
2095504Snate@binkert.org        return;
210711SN/A    }
211711SN/A
2125504Snate@binkert.org    std::string buffer;
2135504Snate@binkert.org    ifstream file(filename.c_str());
214310SN/A
2155504Snate@binkert.org    if (!file)
2165504Snate@binkert.org        fatal("file error: Can't open symbol table file %s\n", filename);
2173373Sstever@eecs.umich.edu
2185504Snate@binkert.org    while (!file.eof()) {
2195504Snate@binkert.org        getline(file, buffer);
2205504Snate@binkert.org
2215504Snate@binkert.org        if (buffer.empty())
2225504Snate@binkert.org            continue;
2235504Snate@binkert.org
2246227Snate@binkert.org        string::size_type idx = buffer.find(' ');
2255504Snate@binkert.org        if (idx == string::npos)
2265504Snate@binkert.org            continue;
2275504Snate@binkert.org
2285504Snate@binkert.org        string address = "0x" + buffer.substr(0, idx);
2295504Snate@binkert.org        eat_white(address);
2305504Snate@binkert.org        if (address.empty())
2315504Snate@binkert.org            continue;
2325504Snate@binkert.org
2335504Snate@binkert.org        // Skip over letter and space
2345504Snate@binkert.org        string symbol = buffer.substr(idx + 3);
2355504Snate@binkert.org        eat_white(symbol);
2365504Snate@binkert.org        if (symbol.empty())
2375504Snate@binkert.org            continue;
2385504Snate@binkert.org
2395504Snate@binkert.org        Addr addr;
2405504Snate@binkert.org        if (!to_number(address, addr))
2415504Snate@binkert.org            continue;
2425504Snate@binkert.org
2435504Snate@binkert.org        if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol))
2445504Snate@binkert.org            continue;
2455504Snate@binkert.org
2465504Snate@binkert.org
2475504Snate@binkert.org        DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
2485504Snate@binkert.org    }
2495504Snate@binkert.org    file.close();
2505504Snate@binkert.org}
2515504Snate@binkert.org
2525504Snate@binkert.orgvoid
2535780Ssteve.reinhardt@amd.comaddsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
2545780Ssteve.reinhardt@amd.com{
2555780Ssteve.reinhardt@amd.com    char symb[100];
2565780Ssteve.reinhardt@amd.com    CopyStringOut(tc, symb, symbolAddr, 100);
2575780Ssteve.reinhardt@amd.com    std::string symbol(symb);
2585780Ssteve.reinhardt@amd.com
2595780Ssteve.reinhardt@amd.com    DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
2605780Ssteve.reinhardt@amd.com
2615780Ssteve.reinhardt@amd.com    tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
2625952Ssaidi@eecs.umich.edu    debugSymbolTable->insert(addr,symbol);
2635780Ssteve.reinhardt@amd.com}
2645780Ssteve.reinhardt@amd.com
2658555Sgblack@eecs.umich.eduuint64_t
2668555Sgblack@eecs.umich.eduinitParam(ThreadContext *tc)
2678555Sgblack@eecs.umich.edu{
2688555Sgblack@eecs.umich.edu    return tc->getCpuPtr()->system->init_param;
2698555Sgblack@eecs.umich.edu}
2708555Sgblack@eecs.umich.edu
2715780Ssteve.reinhardt@amd.com#endif
2725780Ssteve.reinhardt@amd.com
2735780Ssteve.reinhardt@amd.com
2745780Ssteve.reinhardt@amd.comvoid
2755504Snate@binkert.orgresetstats(ThreadContext *tc, Tick delay, Tick period)
2765504Snate@binkert.org{
2775529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_statistics_insts)
2785504Snate@binkert.org        return;
2795504Snate@binkert.org
2805504Snate@binkert.org
2817823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
2827064Snate@binkert.org    Tick repeat = period * SimClock::Int::ns;
2835504Snate@binkert.org
2847822Ssteve.reinhardt@amd.com    Stats::schedStatEvent(false, true, when, repeat);
2855504Snate@binkert.org}
2865504Snate@binkert.org
2875504Snate@binkert.orgvoid
2885504Snate@binkert.orgdumpstats(ThreadContext *tc, Tick delay, Tick period)
2895504Snate@binkert.org{
2905529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_statistics_insts)
2915504Snate@binkert.org        return;
2925504Snate@binkert.org
2935504Snate@binkert.org
2947823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
2957064Snate@binkert.org    Tick repeat = period * SimClock::Int::ns;
2965504Snate@binkert.org
2977822Ssteve.reinhardt@amd.com    Stats::schedStatEvent(true, false, when, repeat);
2985504Snate@binkert.org}
2995504Snate@binkert.org
3005504Snate@binkert.orgvoid
3015504Snate@binkert.orgdumpresetstats(ThreadContext *tc, Tick delay, Tick period)
3025504Snate@binkert.org{
3035529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_statistics_insts)
3045504Snate@binkert.org        return;
3055504Snate@binkert.org
3065504Snate@binkert.org
3077823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
3087064Snate@binkert.org    Tick repeat = period * SimClock::Int::ns;
3095504Snate@binkert.org
3107822Ssteve.reinhardt@amd.com    Stats::schedStatEvent(true, true, when, repeat);
3115504Snate@binkert.org}
3125504Snate@binkert.org
3135504Snate@binkert.orgvoid
3145504Snate@binkert.orgm5checkpoint(ThreadContext *tc, Tick delay, Tick period)
3155504Snate@binkert.org{
3165529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_checkpoint_insts)
3175504Snate@binkert.org        return;
3185504Snate@binkert.org
3197823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
3207064Snate@binkert.org    Tick repeat = period * SimClock::Int::ns;
3215504Snate@binkert.org
3227819Ssteve.reinhardt@amd.com    exitSimLoop("checkpoint", 0, when, repeat);
3235504Snate@binkert.org}
3245504Snate@binkert.org
3255780Ssteve.reinhardt@amd.com#if FULL_SYSTEM
3265780Ssteve.reinhardt@amd.com
3275504Snate@binkert.orguint64_t
3285504Snate@binkert.orgreadfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset)
3295504Snate@binkert.org{
3305504Snate@binkert.org    const string &file = tc->getSystemPtr()->params()->readfile;
3315504Snate@binkert.org    if (file.empty()) {
3325504Snate@binkert.org        return ULL(0);
333310SN/A    }
334299SN/A
3355504Snate@binkert.org    uint64_t result = 0;
3362188SN/A
3375504Snate@binkert.org    int fd = ::open(file.c_str(), O_RDONLY, 0);
3385504Snate@binkert.org    if (fd < 0)
3395504Snate@binkert.org        panic("could not open file %s\n", file);
3402235SN/A
3415504Snate@binkert.org    if (::lseek(fd, offset, SEEK_SET) < 0)
3425504Snate@binkert.org        panic("could not seek: %s", strerror(errno));
3433368Sstever@eecs.umich.edu
3445504Snate@binkert.org    char *buf = new char[len];
3455504Snate@binkert.org    char *p = buf;
3465504Snate@binkert.org    while (len > 0) {
3475504Snate@binkert.org        int bytes = ::read(fd, p, len);
3485504Snate@binkert.org        if (bytes <= 0)
3495504Snate@binkert.org            break;
3503368Sstever@eecs.umich.edu
3515504Snate@binkert.org        p += bytes;
3525504Snate@binkert.org        result += bytes;
3535504Snate@binkert.org        len -= bytes;
3542188SN/A    }
3552188SN/A
3565504Snate@binkert.org    close(fd);
3575504Snate@binkert.org    CopyIn(tc, vaddr, buf, result);
3585504Snate@binkert.org    delete [] buf;
3595504Snate@binkert.org    return result;
3605504Snate@binkert.org}
3612188SN/A
3628734Sdam.sunwoo@arm.comuint64_t
3638734Sdam.sunwoo@arm.comwritefile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset,
3648734Sdam.sunwoo@arm.com            Addr filename_addr)
3658734Sdam.sunwoo@arm.com{
3668734Sdam.sunwoo@arm.com    ostream *os;
3678734Sdam.sunwoo@arm.com
3688734Sdam.sunwoo@arm.com    // copy out target filename
3698734Sdam.sunwoo@arm.com    char fn[100];
3708734Sdam.sunwoo@arm.com    std::string filename;
3718734Sdam.sunwoo@arm.com    CopyStringOut(tc, fn, filename_addr, 100);
3728734Sdam.sunwoo@arm.com    filename = std::string(fn);
3738734Sdam.sunwoo@arm.com
3748734Sdam.sunwoo@arm.com    if (offset == 0) {
3758734Sdam.sunwoo@arm.com        // create a new file (truncate)
3768734Sdam.sunwoo@arm.com        os = simout.create(filename, true);
3778734Sdam.sunwoo@arm.com    } else {
3788734Sdam.sunwoo@arm.com        // do not truncate file if offset is non-zero
3798734Sdam.sunwoo@arm.com        // (ios::in flag is required as well to keep the existing data
3808734Sdam.sunwoo@arm.com        //  intact, otherwise existing data will be zeroed out.)
3818734Sdam.sunwoo@arm.com        os = simout.openFile(simout.directory() + filename,
3828734Sdam.sunwoo@arm.com                            ios::in | ios::out | ios::binary);
3838734Sdam.sunwoo@arm.com    }
3848734Sdam.sunwoo@arm.com    if (!os)
3858734Sdam.sunwoo@arm.com        panic("could not open file %s\n", filename);
3868734Sdam.sunwoo@arm.com
3878734Sdam.sunwoo@arm.com    // seek to offset
3888734Sdam.sunwoo@arm.com    os->seekp(offset);
3898734Sdam.sunwoo@arm.com
3908734Sdam.sunwoo@arm.com    // copy out data and write to file
3918734Sdam.sunwoo@arm.com    char *buf = new char[len];
3928734Sdam.sunwoo@arm.com    CopyOut(tc, buf, vaddr, len);
3938734Sdam.sunwoo@arm.com    os->write(buf, len);
3948734Sdam.sunwoo@arm.com    if (os->fail() || os->bad())
3958734Sdam.sunwoo@arm.com        panic("Error while doing writefile!\n");
3968734Sdam.sunwoo@arm.com
3978734Sdam.sunwoo@arm.com    simout.close(os);
3988734Sdam.sunwoo@arm.com
3998734Sdam.sunwoo@arm.com    delete [] buf;
4008734Sdam.sunwoo@arm.com
4018734Sdam.sunwoo@arm.com    return len;
4028734Sdam.sunwoo@arm.com}
4038734Sdam.sunwoo@arm.com
4045780Ssteve.reinhardt@amd.com#endif
4055780Ssteve.reinhardt@amd.com
4065504Snate@binkert.orgvoid
4075504Snate@binkert.orgdebugbreak(ThreadContext *tc)
4085504Snate@binkert.org{
4098231Snate@binkert.org    Debug::breakpoint();
4105504Snate@binkert.org}
4112235SN/A
4125504Snate@binkert.orgvoid
4135504Snate@binkert.orgswitchcpu(ThreadContext *tc)
4145504Snate@binkert.org{
4155504Snate@binkert.org    exitSimLoop("switchcpu");
4165504Snate@binkert.org}
4173368Sstever@eecs.umich.edu
4187914SBrad.Beckmann@amd.com//
4197914SBrad.Beckmann@amd.com// This function is executed when annotated work items begin.  Depending on
4207914SBrad.Beckmann@amd.com// what the user specified at the command line, the simulation may exit and/or
4217914SBrad.Beckmann@amd.com// take a checkpoint when a certain work item begins.
4227914SBrad.Beckmann@amd.com//
4237914SBrad.Beckmann@amd.comvoid
4247914SBrad.Beckmann@amd.comworkbegin(ThreadContext *tc, uint64_t workid, uint64_t threadid)
4257914SBrad.Beckmann@amd.com{
4267914SBrad.Beckmann@amd.com    tc->getCpuPtr()->workItemBegin();
4277914SBrad.Beckmann@amd.com    System *sys = tc->getSystemPtr();
4288580Ssteve.reinhardt@amd.com    const System::Params *params = sys->params();
4298666SPrakash.Ramrakhyani@arm.com    sys->workItemBegin(threadid, workid);
4307914SBrad.Beckmann@amd.com
4317914SBrad.Beckmann@amd.com    DPRINTF(WorkItems, "Work Begin workid: %d, threadid %d\n", workid,
4327914SBrad.Beckmann@amd.com            threadid);
4337914SBrad.Beckmann@amd.com
4347914SBrad.Beckmann@amd.com    //
4357914SBrad.Beckmann@amd.com    // If specified, determine if this is the specific work item the user
4367914SBrad.Beckmann@amd.com    // identified
4377914SBrad.Beckmann@amd.com    //
4388580Ssteve.reinhardt@amd.com    if (params->work_item_id == -1 || params->work_item_id == workid) {
4397914SBrad.Beckmann@amd.com
4407914SBrad.Beckmann@amd.com        uint64_t systemWorkBeginCount = sys->incWorkItemsBegin();
4417914SBrad.Beckmann@amd.com        int cpuId = tc->getCpuPtr()->cpuId();
4427914SBrad.Beckmann@amd.com
4438580Ssteve.reinhardt@amd.com        if (params->work_cpus_ckpt_count != 0 &&
4448580Ssteve.reinhardt@amd.com            sys->markWorkItem(cpuId) >= params->work_cpus_ckpt_count) {
4457914SBrad.Beckmann@amd.com            //
4467914SBrad.Beckmann@amd.com            // If active cpus equals checkpoint count, create checkpoint
4477914SBrad.Beckmann@amd.com            //
4488580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
4497914SBrad.Beckmann@amd.com        }
4507914SBrad.Beckmann@amd.com
4518580Ssteve.reinhardt@amd.com        if (systemWorkBeginCount == params->work_begin_ckpt_count) {
4527914SBrad.Beckmann@amd.com            //
4537914SBrad.Beckmann@amd.com            // Note: the string specified as the cause of the exit event must
4547914SBrad.Beckmann@amd.com            // exactly equal "checkpoint" inorder to create a checkpoint
4557914SBrad.Beckmann@amd.com            //
4568580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
4577914SBrad.Beckmann@amd.com        }
4587914SBrad.Beckmann@amd.com
4598580Ssteve.reinhardt@amd.com        if (systemWorkBeginCount == params->work_begin_exit_count) {
4607914SBrad.Beckmann@amd.com            //
4617914SBrad.Beckmann@amd.com            // If a certain number of work items started, exit simulation
4627914SBrad.Beckmann@amd.com            //
4638580Ssteve.reinhardt@amd.com            exitSimLoop("work started count reach");
4647914SBrad.Beckmann@amd.com        }
4657914SBrad.Beckmann@amd.com
4668580Ssteve.reinhardt@amd.com        if (cpuId == params->work_begin_cpu_id_exit) {
4677914SBrad.Beckmann@amd.com            //
4688580Ssteve.reinhardt@amd.com            // If work started on the cpu id specified, exit simulation
4697914SBrad.Beckmann@amd.com            //
4708580Ssteve.reinhardt@amd.com            exitSimLoop("work started on specific cpu");
4717914SBrad.Beckmann@amd.com        }
4727914SBrad.Beckmann@amd.com    }
4737914SBrad.Beckmann@amd.com}
4747914SBrad.Beckmann@amd.com
4757914SBrad.Beckmann@amd.com//
4767914SBrad.Beckmann@amd.com// This function is executed when annotated work items end.  Depending on
4777914SBrad.Beckmann@amd.com// what the user specified at the command line, the simulation may exit and/or
4787914SBrad.Beckmann@amd.com// take a checkpoint when a certain work item ends.
4797914SBrad.Beckmann@amd.com//
4807914SBrad.Beckmann@amd.comvoid
4817914SBrad.Beckmann@amd.comworkend(ThreadContext *tc, uint64_t workid, uint64_t threadid)
4827914SBrad.Beckmann@amd.com{
4837914SBrad.Beckmann@amd.com    tc->getCpuPtr()->workItemEnd();
4847914SBrad.Beckmann@amd.com    System *sys = tc->getSystemPtr();
4858580Ssteve.reinhardt@amd.com    const System::Params *params = sys->params();
4868666SPrakash.Ramrakhyani@arm.com    sys->workItemEnd(threadid, workid);
4877914SBrad.Beckmann@amd.com
4887914SBrad.Beckmann@amd.com    DPRINTF(WorkItems, "Work End workid: %d, threadid %d\n", workid, threadid);
4897914SBrad.Beckmann@amd.com
4907914SBrad.Beckmann@amd.com    //
4917914SBrad.Beckmann@amd.com    // If specified, determine if this is the specific work item the user
4927914SBrad.Beckmann@amd.com    // identified
4937914SBrad.Beckmann@amd.com    //
4948580Ssteve.reinhardt@amd.com    if (params->work_item_id == -1 || params->work_item_id == workid) {
4957914SBrad.Beckmann@amd.com
4967914SBrad.Beckmann@amd.com        uint64_t systemWorkEndCount = sys->incWorkItemsEnd();
4977914SBrad.Beckmann@amd.com        int cpuId = tc->getCpuPtr()->cpuId();
4987914SBrad.Beckmann@amd.com
4998580Ssteve.reinhardt@amd.com        if (params->work_cpus_ckpt_count != 0 &&
5008580Ssteve.reinhardt@amd.com            sys->markWorkItem(cpuId) >= params->work_cpus_ckpt_count) {
5017914SBrad.Beckmann@amd.com            //
5027914SBrad.Beckmann@amd.com            // If active cpus equals checkpoint count, create checkpoint
5037914SBrad.Beckmann@amd.com            //
5048580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
5057914SBrad.Beckmann@amd.com        }
5067914SBrad.Beckmann@amd.com
5078580Ssteve.reinhardt@amd.com        if (params->work_end_ckpt_count != 0 &&
5088580Ssteve.reinhardt@amd.com            systemWorkEndCount == params->work_end_ckpt_count) {
5097914SBrad.Beckmann@amd.com            //
5107914SBrad.Beckmann@amd.com            // If total work items completed equals checkpoint count, create
5117914SBrad.Beckmann@amd.com            // checkpoint
5127914SBrad.Beckmann@amd.com            //
5138580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
5147914SBrad.Beckmann@amd.com        }
5157914SBrad.Beckmann@amd.com
5168580Ssteve.reinhardt@amd.com        if (params->work_end_exit_count != 0 &&
5178580Ssteve.reinhardt@amd.com            systemWorkEndCount == params->work_end_exit_count) {
5187914SBrad.Beckmann@amd.com            //
5197914SBrad.Beckmann@amd.com            // If total work items completed equals exit count, exit simulation
5207914SBrad.Beckmann@amd.com            //
5218580Ssteve.reinhardt@amd.com            exitSimLoop("work items exit count reached");
5227914SBrad.Beckmann@amd.com        }
5237914SBrad.Beckmann@amd.com    }
5247914SBrad.Beckmann@amd.com}
5257914SBrad.Beckmann@amd.com
5267811Ssteve.reinhardt@amd.com} // namespace PseudoInst
527