pseudo_inst.cc revision 8806
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 *
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
518777Sgblack@eecs.umich.edu#include "arch/kernel_stats.hh"
522170SN/A#include "arch/vtophys.hh"
535882Snate@binkert.org#include "base/debug.hh"
546658Snate@binkert.org#include "config/the_isa.hh"
551717SN/A#include "cpu/base.hh"
568229Snate@binkert.org#include "cpu/quiesce_event.hh"
572680Sktlim@umich.edu#include "cpu/thread_context.hh"
588232Snate@binkert.org#include "debug/Loader.hh"
598232Snate@binkert.org#include "debug/Quiesce.hh"
608232Snate@binkert.org#include "debug/WorkItems.hh"
615529Snate@binkert.org#include "params/BaseCPU.hh"
628784Sgblack@eecs.umich.edu#include "sim/full_system.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"
702080SN/A#include "sim/vptr.hh"
71298SN/A
72299SN/Ausing namespace std;
731052SN/A
74729SN/Ausing namespace Stats;
752107SN/Ausing namespace TheISA;
76298SN/A
775504Snate@binkert.orgnamespace PseudoInst {
785504Snate@binkert.org
798784Sgblack@eecs.umich.edustatic inline void
808784Sgblack@eecs.umich.edupanicFsOnlyPseudoInst(const char *name)
818784Sgblack@eecs.umich.edu{
828784Sgblack@eecs.umich.edu    panic("Pseudo inst \"%s\" is only available in Full System mode.");
838784Sgblack@eecs.umich.edu}
845780Ssteve.reinhardt@amd.com
855504Snate@binkert.orgvoid
865504Snate@binkert.orgarm(ThreadContext *tc)
87298SN/A{
888806Sgblack@eecs.umich.edu    if (!FullSystem)
898784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("arm");
908806Sgblack@eecs.umich.edu
918806Sgblack@eecs.umich.edu    if (tc->getKernelStats())
928806Sgblack@eecs.umich.edu        tc->getKernelStats()->arm();
935504Snate@binkert.org}
945504Snate@binkert.org
955504Snate@binkert.orgvoid
965504Snate@binkert.orgquiesce(ThreadContext *tc)
975504Snate@binkert.org{
988806Sgblack@eecs.umich.edu    if (!FullSystem)
998806Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("quiesce");
1005504Snate@binkert.org
1018806Sgblack@eecs.umich.edu    if (!tc->getCpuPtr()->params()->do_quiesce)
1028806Sgblack@eecs.umich.edu        return;
1035504Snate@binkert.org
1048806Sgblack@eecs.umich.edu    DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name());
1058806Sgblack@eecs.umich.edu
1068806Sgblack@eecs.umich.edu    tc->suspend();
1078806Sgblack@eecs.umich.edu    if (tc->getKernelStats())
1088806Sgblack@eecs.umich.edu        tc->getKernelStats()->quiesce();
1095504Snate@binkert.org}
1105504Snate@binkert.org
1115504Snate@binkert.orgvoid
1128142SAli.Saidi@ARM.comquiesceSkip(ThreadContext *tc)
1138142SAli.Saidi@ARM.com{
1148806Sgblack@eecs.umich.edu    if (!FullSystem)
1158806Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("quiesceSkip");
1168142SAli.Saidi@ARM.com
1178806Sgblack@eecs.umich.edu    BaseCPU *cpu = tc->getCpuPtr();
1188142SAli.Saidi@ARM.com
1198806Sgblack@eecs.umich.edu    if (!cpu->params()->do_quiesce)
1208806Sgblack@eecs.umich.edu        return;
1218142SAli.Saidi@ARM.com
1228806Sgblack@eecs.umich.edu    EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1238142SAli.Saidi@ARM.com
1248806Sgblack@eecs.umich.edu    Tick resume = curTick() + 1;
1258142SAli.Saidi@ARM.com
1268806Sgblack@eecs.umich.edu    cpu->reschedule(quiesceEvent, resume, true);
1278142SAli.Saidi@ARM.com
1288806Sgblack@eecs.umich.edu    DPRINTF(Quiesce, "%s: quiesceSkip() until %d\n",
1298806Sgblack@eecs.umich.edu            cpu->name(), resume);
1308806Sgblack@eecs.umich.edu
1318806Sgblack@eecs.umich.edu    tc->suspend();
1328806Sgblack@eecs.umich.edu    if (tc->getKernelStats())
1338806Sgblack@eecs.umich.edu        tc->getKernelStats()->quiesce();
1348142SAli.Saidi@ARM.com}
1358142SAli.Saidi@ARM.com
1368142SAli.Saidi@ARM.comvoid
1375504Snate@binkert.orgquiesceNs(ThreadContext *tc, uint64_t ns)
1385504Snate@binkert.org{
1398806Sgblack@eecs.umich.edu    if (!FullSystem)
1408806Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("quiesceNs");
1417819Ssteve.reinhardt@amd.com
1428806Sgblack@eecs.umich.edu    BaseCPU *cpu = tc->getCpuPtr();
1435504Snate@binkert.org
1448806Sgblack@eecs.umich.edu    if (!cpu->params()->do_quiesce || ns == 0)
1458806Sgblack@eecs.umich.edu        return;
1465504Snate@binkert.org
1478806Sgblack@eecs.umich.edu    EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1485504Snate@binkert.org
1498806Sgblack@eecs.umich.edu    Tick resume = curTick() + SimClock::Int::ns * ns;
1505504Snate@binkert.org
1518806Sgblack@eecs.umich.edu    cpu->reschedule(quiesceEvent, resume, true);
1525504Snate@binkert.org
1538806Sgblack@eecs.umich.edu    DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
1548806Sgblack@eecs.umich.edu            cpu->name(), ns, resume);
1558806Sgblack@eecs.umich.edu
1568806Sgblack@eecs.umich.edu    tc->suspend();
1578806Sgblack@eecs.umich.edu    if (tc->getKernelStats())
1588806Sgblack@eecs.umich.edu        tc->getKernelStats()->quiesce();
1595504Snate@binkert.org}
1605504Snate@binkert.org
1615504Snate@binkert.orgvoid
1625504Snate@binkert.orgquiesceCycles(ThreadContext *tc, uint64_t cycles)
1635504Snate@binkert.org{
1648806Sgblack@eecs.umich.edu    if (!FullSystem)
1658806Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("quiesceCycles");
1667819Ssteve.reinhardt@amd.com
1678806Sgblack@eecs.umich.edu    BaseCPU *cpu = tc->getCpuPtr();
1685504Snate@binkert.org
1698806Sgblack@eecs.umich.edu    if (!cpu->params()->do_quiesce || cycles == 0)
1708806Sgblack@eecs.umich.edu        return;
1715504Snate@binkert.org
1728806Sgblack@eecs.umich.edu    EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1735504Snate@binkert.org
1748806Sgblack@eecs.umich.edu    Tick resume = curTick() + cpu->ticks(cycles);
1755504Snate@binkert.org
1768806Sgblack@eecs.umich.edu    cpu->reschedule(quiesceEvent, resume, true);
1775504Snate@binkert.org
1788806Sgblack@eecs.umich.edu    DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
1798806Sgblack@eecs.umich.edu            cpu->name(), cycles, resume);
1808806Sgblack@eecs.umich.edu
1818806Sgblack@eecs.umich.edu    tc->suspend();
1828806Sgblack@eecs.umich.edu    if (tc->getKernelStats())
1838806Sgblack@eecs.umich.edu        tc->getKernelStats()->quiesce();
1845504Snate@binkert.org}
1855504Snate@binkert.org
1865504Snate@binkert.orguint64_t
1875504Snate@binkert.orgquiesceTime(ThreadContext *tc)
1885504Snate@binkert.org{
1898806Sgblack@eecs.umich.edu    if (!FullSystem) {
1908784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("quiesceTime");
1918784Sgblack@eecs.umich.edu        return 0;
1928784Sgblack@eecs.umich.edu    }
1938806Sgblack@eecs.umich.edu
1948806Sgblack@eecs.umich.edu    return (tc->readLastActivate() - tc->readLastSuspend()) /
1958806Sgblack@eecs.umich.edu        SimClock::Int::ns;
1965504Snate@binkert.org}
1975504Snate@binkert.org
1985741Snate@binkert.orguint64_t
1995741Snate@binkert.orgrpns(ThreadContext *tc)
2005741Snate@binkert.org{
2017823Ssteve.reinhardt@amd.com    return curTick() / SimClock::Int::ns;
2025741Snate@binkert.org}
2035741Snate@binkert.org
2045504Snate@binkert.orgvoid
2055808Snate@binkert.orgwakeCPU(ThreadContext *tc, uint64_t cpuid)
2065808Snate@binkert.org{
2075808Snate@binkert.org    System *sys = tc->getSystemPtr();
2085808Snate@binkert.org    ThreadContext *other_tc = sys->threadContexts[cpuid];
2095808Snate@binkert.org    if (other_tc->status() == ThreadContext::Suspended)
2105808Snate@binkert.org        other_tc->activate();
2115808Snate@binkert.org}
2125808Snate@binkert.org
2135808Snate@binkert.orgvoid
2145504Snate@binkert.orgm5exit(ThreadContext *tc, Tick delay)
2155504Snate@binkert.org{
2167823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
2177819Ssteve.reinhardt@amd.com    exitSimLoop("m5_exit instruction encountered", 0, when);
2185504Snate@binkert.org}
2195504Snate@binkert.org
2205504Snate@binkert.orgvoid
2215504Snate@binkert.orgloadsymbol(ThreadContext *tc)
2225504Snate@binkert.org{
2238806Sgblack@eecs.umich.edu    if (!FullSystem)
2248806Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("loadsymbol");
2258784Sgblack@eecs.umich.edu
2268806Sgblack@eecs.umich.edu    const string &filename = tc->getCpuPtr()->system->params()->symbolfile;
2278806Sgblack@eecs.umich.edu    if (filename.empty()) {
2288806Sgblack@eecs.umich.edu        return;
2298806Sgblack@eecs.umich.edu    }
2308784Sgblack@eecs.umich.edu
2318806Sgblack@eecs.umich.edu    std::string buffer;
2328806Sgblack@eecs.umich.edu    ifstream file(filename.c_str());
2338784Sgblack@eecs.umich.edu
2348806Sgblack@eecs.umich.edu    if (!file)
2358806Sgblack@eecs.umich.edu        fatal("file error: Can't open symbol table file %s\n", filename);
2368784Sgblack@eecs.umich.edu
2378806Sgblack@eecs.umich.edu    while (!file.eof()) {
2388806Sgblack@eecs.umich.edu        getline(file, buffer);
2398784Sgblack@eecs.umich.edu
2408806Sgblack@eecs.umich.edu        if (buffer.empty())
2418806Sgblack@eecs.umich.edu            continue;
2428784Sgblack@eecs.umich.edu
2438806Sgblack@eecs.umich.edu        string::size_type idx = buffer.find(' ');
2448806Sgblack@eecs.umich.edu        if (idx == string::npos)
2458806Sgblack@eecs.umich.edu            continue;
2468784Sgblack@eecs.umich.edu
2478806Sgblack@eecs.umich.edu        string address = "0x" + buffer.substr(0, idx);
2488806Sgblack@eecs.umich.edu        eat_white(address);
2498806Sgblack@eecs.umich.edu        if (address.empty())
2508806Sgblack@eecs.umich.edu            continue;
2518784Sgblack@eecs.umich.edu
2528806Sgblack@eecs.umich.edu        // Skip over letter and space
2538806Sgblack@eecs.umich.edu        string symbol = buffer.substr(idx + 3);
2548806Sgblack@eecs.umich.edu        eat_white(symbol);
2558806Sgblack@eecs.umich.edu        if (symbol.empty())
2568806Sgblack@eecs.umich.edu            continue;
2578784Sgblack@eecs.umich.edu
2588806Sgblack@eecs.umich.edu        Addr addr;
2598806Sgblack@eecs.umich.edu        if (!to_number(address, addr))
2608806Sgblack@eecs.umich.edu            continue;
2618784Sgblack@eecs.umich.edu
2628806Sgblack@eecs.umich.edu        if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol))
2638806Sgblack@eecs.umich.edu            continue;
2648784Sgblack@eecs.umich.edu
2658806Sgblack@eecs.umich.edu
2668806Sgblack@eecs.umich.edu        DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
267711SN/A    }
2688806Sgblack@eecs.umich.edu    file.close();
2695504Snate@binkert.org}
2705504Snate@binkert.org
2715504Snate@binkert.orgvoid
2725780Ssteve.reinhardt@amd.comaddsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
2735780Ssteve.reinhardt@amd.com{
2748806Sgblack@eecs.umich.edu    if (!FullSystem)
2758806Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("addSymbol");
2765780Ssteve.reinhardt@amd.com
2778806Sgblack@eecs.umich.edu    char symb[100];
2788806Sgblack@eecs.umich.edu    CopyStringOut(tc, symb, symbolAddr, 100);
2798806Sgblack@eecs.umich.edu    std::string symbol(symb);
2805780Ssteve.reinhardt@amd.com
2818806Sgblack@eecs.umich.edu    DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
2828806Sgblack@eecs.umich.edu
2838806Sgblack@eecs.umich.edu    tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
2848806Sgblack@eecs.umich.edu    debugSymbolTable->insert(addr,symbol);
2855780Ssteve.reinhardt@amd.com}
2865780Ssteve.reinhardt@amd.com
2878555Sgblack@eecs.umich.eduuint64_t
2888555Sgblack@eecs.umich.eduinitParam(ThreadContext *tc)
2898555Sgblack@eecs.umich.edu{
2908806Sgblack@eecs.umich.edu    if (!FullSystem) {
2918784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("initParam");
2928784Sgblack@eecs.umich.edu        return 0;
2938784Sgblack@eecs.umich.edu    }
2948806Sgblack@eecs.umich.edu
2958806Sgblack@eecs.umich.edu    return tc->getCpuPtr()->system->init_param;
2968555Sgblack@eecs.umich.edu}
2978555Sgblack@eecs.umich.edu
2985780Ssteve.reinhardt@amd.com
2995780Ssteve.reinhardt@amd.comvoid
3005504Snate@binkert.orgresetstats(ThreadContext *tc, Tick delay, Tick period)
3015504Snate@binkert.org{
3025529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_statistics_insts)
3035504Snate@binkert.org        return;
3045504Snate@binkert.org
3055504Snate@binkert.org
3067823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
3077064Snate@binkert.org    Tick repeat = period * SimClock::Int::ns;
3085504Snate@binkert.org
3097822Ssteve.reinhardt@amd.com    Stats::schedStatEvent(false, true, when, repeat);
3105504Snate@binkert.org}
3115504Snate@binkert.org
3125504Snate@binkert.orgvoid
3135504Snate@binkert.orgdumpstats(ThreadContext *tc, Tick delay, Tick period)
3145504Snate@binkert.org{
3155529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_statistics_insts)
3165504Snate@binkert.org        return;
3175504Snate@binkert.org
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
3227822Ssteve.reinhardt@amd.com    Stats::schedStatEvent(true, false, when, repeat);
3235504Snate@binkert.org}
3245504Snate@binkert.org
3255504Snate@binkert.orgvoid
3265504Snate@binkert.orgdumpresetstats(ThreadContext *tc, Tick delay, Tick period)
3275504Snate@binkert.org{
3285529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_statistics_insts)
3295504Snate@binkert.org        return;
3305504Snate@binkert.org
3315504Snate@binkert.org
3327823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
3337064Snate@binkert.org    Tick repeat = period * SimClock::Int::ns;
3345504Snate@binkert.org
3357822Ssteve.reinhardt@amd.com    Stats::schedStatEvent(true, true, when, repeat);
3365504Snate@binkert.org}
3375504Snate@binkert.org
3385504Snate@binkert.orgvoid
3395504Snate@binkert.orgm5checkpoint(ThreadContext *tc, Tick delay, Tick period)
3405504Snate@binkert.org{
3415529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_checkpoint_insts)
3425504Snate@binkert.org        return;
3435504Snate@binkert.org
3447823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
3457064Snate@binkert.org    Tick repeat = period * SimClock::Int::ns;
3465504Snate@binkert.org
3477819Ssteve.reinhardt@amd.com    exitSimLoop("checkpoint", 0, when, repeat);
3485504Snate@binkert.org}
3495504Snate@binkert.org
3505504Snate@binkert.orguint64_t
3515504Snate@binkert.orgreadfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset)
3525504Snate@binkert.org{
3538806Sgblack@eecs.umich.edu    if (!FullSystem) {
3548784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("readfile");
3558784Sgblack@eecs.umich.edu        return 0;
356310SN/A    }
3578806Sgblack@eecs.umich.edu
3588806Sgblack@eecs.umich.edu    const string &file = tc->getSystemPtr()->params()->readfile;
3598806Sgblack@eecs.umich.edu    if (file.empty()) {
3608806Sgblack@eecs.umich.edu        return ULL(0);
3618806Sgblack@eecs.umich.edu    }
3628806Sgblack@eecs.umich.edu
3638806Sgblack@eecs.umich.edu    uint64_t result = 0;
3648806Sgblack@eecs.umich.edu
3658806Sgblack@eecs.umich.edu    int fd = ::open(file.c_str(), O_RDONLY, 0);
3668806Sgblack@eecs.umich.edu    if (fd < 0)
3678806Sgblack@eecs.umich.edu        panic("could not open file %s\n", file);
3688806Sgblack@eecs.umich.edu
3698806Sgblack@eecs.umich.edu    if (::lseek(fd, offset, SEEK_SET) < 0)
3708806Sgblack@eecs.umich.edu        panic("could not seek: %s", strerror(errno));
3718806Sgblack@eecs.umich.edu
3728806Sgblack@eecs.umich.edu    char *buf = new char[len];
3738806Sgblack@eecs.umich.edu    char *p = buf;
3748806Sgblack@eecs.umich.edu    while (len > 0) {
3758806Sgblack@eecs.umich.edu        int bytes = ::read(fd, p, len);
3768806Sgblack@eecs.umich.edu        if (bytes <= 0)
3778806Sgblack@eecs.umich.edu            break;
3788806Sgblack@eecs.umich.edu
3798806Sgblack@eecs.umich.edu        p += bytes;
3808806Sgblack@eecs.umich.edu        result += bytes;
3818806Sgblack@eecs.umich.edu        len -= bytes;
3828806Sgblack@eecs.umich.edu    }
3838806Sgblack@eecs.umich.edu
3848806Sgblack@eecs.umich.edu    close(fd);
3858806Sgblack@eecs.umich.edu    CopyIn(tc, vaddr, buf, result);
3868806Sgblack@eecs.umich.edu    delete [] buf;
3878806Sgblack@eecs.umich.edu    return result;
3885504Snate@binkert.org}
3892188SN/A
3905504Snate@binkert.orgvoid
3915504Snate@binkert.orgdebugbreak(ThreadContext *tc)
3925504Snate@binkert.org{
3938231Snate@binkert.org    Debug::breakpoint();
3945504Snate@binkert.org}
3952235SN/A
3965504Snate@binkert.orgvoid
3975504Snate@binkert.orgswitchcpu(ThreadContext *tc)
3985504Snate@binkert.org{
3995504Snate@binkert.org    exitSimLoop("switchcpu");
4005504Snate@binkert.org}
4013368Sstever@eecs.umich.edu
4027914SBrad.Beckmann@amd.com//
4037914SBrad.Beckmann@amd.com// This function is executed when annotated work items begin.  Depending on
4047914SBrad.Beckmann@amd.com// what the user specified at the command line, the simulation may exit and/or
4057914SBrad.Beckmann@amd.com// take a checkpoint when a certain work item begins.
4067914SBrad.Beckmann@amd.com//
4077914SBrad.Beckmann@amd.comvoid
4087914SBrad.Beckmann@amd.comworkbegin(ThreadContext *tc, uint64_t workid, uint64_t threadid)
4097914SBrad.Beckmann@amd.com{
4107914SBrad.Beckmann@amd.com    tc->getCpuPtr()->workItemBegin();
4117914SBrad.Beckmann@amd.com    System *sys = tc->getSystemPtr();
4128580Ssteve.reinhardt@amd.com    const System::Params *params = sys->params();
4138666SPrakash.Ramrakhyani@arm.com    sys->workItemBegin(threadid, workid);
4147914SBrad.Beckmann@amd.com
4157914SBrad.Beckmann@amd.com    DPRINTF(WorkItems, "Work Begin workid: %d, threadid %d\n", workid,
4167914SBrad.Beckmann@amd.com            threadid);
4177914SBrad.Beckmann@amd.com
4187914SBrad.Beckmann@amd.com    //
4197914SBrad.Beckmann@amd.com    // If specified, determine if this is the specific work item the user
4207914SBrad.Beckmann@amd.com    // identified
4217914SBrad.Beckmann@amd.com    //
4228580Ssteve.reinhardt@amd.com    if (params->work_item_id == -1 || params->work_item_id == workid) {
4237914SBrad.Beckmann@amd.com
4247914SBrad.Beckmann@amd.com        uint64_t systemWorkBeginCount = sys->incWorkItemsBegin();
4257914SBrad.Beckmann@amd.com        int cpuId = tc->getCpuPtr()->cpuId();
4267914SBrad.Beckmann@amd.com
4278580Ssteve.reinhardt@amd.com        if (params->work_cpus_ckpt_count != 0 &&
4288580Ssteve.reinhardt@amd.com            sys->markWorkItem(cpuId) >= params->work_cpus_ckpt_count) {
4297914SBrad.Beckmann@amd.com            //
4307914SBrad.Beckmann@amd.com            // If active cpus equals checkpoint count, create checkpoint
4317914SBrad.Beckmann@amd.com            //
4328580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
4337914SBrad.Beckmann@amd.com        }
4347914SBrad.Beckmann@amd.com
4358580Ssteve.reinhardt@amd.com        if (systemWorkBeginCount == params->work_begin_ckpt_count) {
4367914SBrad.Beckmann@amd.com            //
4377914SBrad.Beckmann@amd.com            // Note: the string specified as the cause of the exit event must
4387914SBrad.Beckmann@amd.com            // exactly equal "checkpoint" inorder to create a checkpoint
4397914SBrad.Beckmann@amd.com            //
4408580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
4417914SBrad.Beckmann@amd.com        }
4427914SBrad.Beckmann@amd.com
4438580Ssteve.reinhardt@amd.com        if (systemWorkBeginCount == params->work_begin_exit_count) {
4447914SBrad.Beckmann@amd.com            //
4457914SBrad.Beckmann@amd.com            // If a certain number of work items started, exit simulation
4467914SBrad.Beckmann@amd.com            //
4478580Ssteve.reinhardt@amd.com            exitSimLoop("work started count reach");
4487914SBrad.Beckmann@amd.com        }
4497914SBrad.Beckmann@amd.com
4508580Ssteve.reinhardt@amd.com        if (cpuId == params->work_begin_cpu_id_exit) {
4517914SBrad.Beckmann@amd.com            //
4528580Ssteve.reinhardt@amd.com            // If work started on the cpu id specified, exit simulation
4537914SBrad.Beckmann@amd.com            //
4548580Ssteve.reinhardt@amd.com            exitSimLoop("work started on specific cpu");
4557914SBrad.Beckmann@amd.com        }
4567914SBrad.Beckmann@amd.com    }
4577914SBrad.Beckmann@amd.com}
4587914SBrad.Beckmann@amd.com
4597914SBrad.Beckmann@amd.com//
4607914SBrad.Beckmann@amd.com// This function is executed when annotated work items end.  Depending on
4617914SBrad.Beckmann@amd.com// what the user specified at the command line, the simulation may exit and/or
4627914SBrad.Beckmann@amd.com// take a checkpoint when a certain work item ends.
4637914SBrad.Beckmann@amd.com//
4647914SBrad.Beckmann@amd.comvoid
4657914SBrad.Beckmann@amd.comworkend(ThreadContext *tc, uint64_t workid, uint64_t threadid)
4667914SBrad.Beckmann@amd.com{
4677914SBrad.Beckmann@amd.com    tc->getCpuPtr()->workItemEnd();
4687914SBrad.Beckmann@amd.com    System *sys = tc->getSystemPtr();
4698580Ssteve.reinhardt@amd.com    const System::Params *params = sys->params();
4708666SPrakash.Ramrakhyani@arm.com    sys->workItemEnd(threadid, workid);
4717914SBrad.Beckmann@amd.com
4727914SBrad.Beckmann@amd.com    DPRINTF(WorkItems, "Work End workid: %d, threadid %d\n", workid, threadid);
4737914SBrad.Beckmann@amd.com
4747914SBrad.Beckmann@amd.com    //
4757914SBrad.Beckmann@amd.com    // If specified, determine if this is the specific work item the user
4767914SBrad.Beckmann@amd.com    // identified
4777914SBrad.Beckmann@amd.com    //
4788580Ssteve.reinhardt@amd.com    if (params->work_item_id == -1 || params->work_item_id == workid) {
4797914SBrad.Beckmann@amd.com
4807914SBrad.Beckmann@amd.com        uint64_t systemWorkEndCount = sys->incWorkItemsEnd();
4817914SBrad.Beckmann@amd.com        int cpuId = tc->getCpuPtr()->cpuId();
4827914SBrad.Beckmann@amd.com
4838580Ssteve.reinhardt@amd.com        if (params->work_cpus_ckpt_count != 0 &&
4848580Ssteve.reinhardt@amd.com            sys->markWorkItem(cpuId) >= params->work_cpus_ckpt_count) {
4857914SBrad.Beckmann@amd.com            //
4867914SBrad.Beckmann@amd.com            // If active cpus equals checkpoint count, create checkpoint
4877914SBrad.Beckmann@amd.com            //
4888580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
4897914SBrad.Beckmann@amd.com        }
4907914SBrad.Beckmann@amd.com
4918580Ssteve.reinhardt@amd.com        if (params->work_end_ckpt_count != 0 &&
4928580Ssteve.reinhardt@amd.com            systemWorkEndCount == params->work_end_ckpt_count) {
4937914SBrad.Beckmann@amd.com            //
4947914SBrad.Beckmann@amd.com            // If total work items completed equals checkpoint count, create
4957914SBrad.Beckmann@amd.com            // checkpoint
4967914SBrad.Beckmann@amd.com            //
4978580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
4987914SBrad.Beckmann@amd.com        }
4997914SBrad.Beckmann@amd.com
5008580Ssteve.reinhardt@amd.com        if (params->work_end_exit_count != 0 &&
5018580Ssteve.reinhardt@amd.com            systemWorkEndCount == params->work_end_exit_count) {
5027914SBrad.Beckmann@amd.com            //
5037914SBrad.Beckmann@amd.com            // If total work items completed equals exit count, exit simulation
5047914SBrad.Beckmann@amd.com            //
5058580Ssteve.reinhardt@amd.com            exitSimLoop("work items exit count reached");
5067914SBrad.Beckmann@amd.com        }
5077914SBrad.Beckmann@amd.com    }
5087914SBrad.Beckmann@amd.com}
5097914SBrad.Beckmann@amd.com
5107811Ssteve.reinhardt@amd.com} // namespace PseudoInst
511