pseudo_inst.cc revision 8784
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/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"
638784Sgblack@eecs.umich.edu#include "sim/full_system.hh"
643565Sgblack@eecs.umich.edu#include "sim/pseudo_inst.hh"
65298SN/A#include "sim/serialize.hh"
665606Snate@binkert.org#include "sim/sim_events.hh"
67298SN/A#include "sim/sim_exit.hh"
68695SN/A#include "sim/stat_control.hh"
69695SN/A#include "sim/stats.hh"
70954SN/A#include "sim/system.hh"
712080SN/A#include "sim/vptr.hh"
72298SN/A
73299SN/Ausing namespace std;
741052SN/A
75729SN/Ausing namespace Stats;
762107SN/Ausing namespace TheISA;
77298SN/A
785504Snate@binkert.orgnamespace PseudoInst {
795504Snate@binkert.org
808784Sgblack@eecs.umich.edustatic inline void
818784Sgblack@eecs.umich.edupanicFsOnlyPseudoInst(const char *name)
828784Sgblack@eecs.umich.edu{
838784Sgblack@eecs.umich.edu    panic("Pseudo inst \"%s\" is only available in Full System mode.");
848784Sgblack@eecs.umich.edu}
855780Ssteve.reinhardt@amd.com
865504Snate@binkert.orgvoid
875504Snate@binkert.orgarm(ThreadContext *tc)
88298SN/A{
898784Sgblack@eecs.umich.edu    if (FullSystem) {
908784Sgblack@eecs.umich.edu        if (tc->getKernelStats())
918784Sgblack@eecs.umich.edu            tc->getKernelStats()->arm();
928784Sgblack@eecs.umich.edu    } else {
938784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("arm");
948784Sgblack@eecs.umich.edu    }
955504Snate@binkert.org}
965504Snate@binkert.org
975504Snate@binkert.orgvoid
985504Snate@binkert.orgquiesce(ThreadContext *tc)
995504Snate@binkert.org{
1008784Sgblack@eecs.umich.edu    if (FullSystem) {
1018784Sgblack@eecs.umich.edu        if (!tc->getCpuPtr()->params()->do_quiesce)
1028784Sgblack@eecs.umich.edu            return;
1035504Snate@binkert.org
1048784Sgblack@eecs.umich.edu        DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name());
1055504Snate@binkert.org
1068784Sgblack@eecs.umich.edu        tc->suspend();
1078784Sgblack@eecs.umich.edu        if (tc->getKernelStats())
1088784Sgblack@eecs.umich.edu            tc->getKernelStats()->quiesce();
1098784Sgblack@eecs.umich.edu    } else {
1108784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("quiesce");
1118784Sgblack@eecs.umich.edu    }
1125504Snate@binkert.org}
1135504Snate@binkert.org
1145504Snate@binkert.orgvoid
1158142SAli.Saidi@ARM.comquiesceSkip(ThreadContext *tc)
1168142SAli.Saidi@ARM.com{
1178784Sgblack@eecs.umich.edu    if (FullSystem) {
1188784Sgblack@eecs.umich.edu        BaseCPU *cpu = tc->getCpuPtr();
1198142SAli.Saidi@ARM.com
1208784Sgblack@eecs.umich.edu        if (!cpu->params()->do_quiesce)
1218784Sgblack@eecs.umich.edu            return;
1228142SAli.Saidi@ARM.com
1238784Sgblack@eecs.umich.edu        EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1248142SAli.Saidi@ARM.com
1258784Sgblack@eecs.umich.edu        Tick resume = curTick() + 1;
1268142SAli.Saidi@ARM.com
1278784Sgblack@eecs.umich.edu        cpu->reschedule(quiesceEvent, resume, true);
1288142SAli.Saidi@ARM.com
1298784Sgblack@eecs.umich.edu        DPRINTF(Quiesce, "%s: quiesceSkip() until %d\n",
1308784Sgblack@eecs.umich.edu                cpu->name(), resume);
1318142SAli.Saidi@ARM.com
1328784Sgblack@eecs.umich.edu        tc->suspend();
1338784Sgblack@eecs.umich.edu        if (tc->getKernelStats())
1348784Sgblack@eecs.umich.edu            tc->getKernelStats()->quiesce();
1358784Sgblack@eecs.umich.edu    } else {
1368784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("quiesceSkip");
1378784Sgblack@eecs.umich.edu    }
1388142SAli.Saidi@ARM.com}
1398142SAli.Saidi@ARM.com
1408142SAli.Saidi@ARM.comvoid
1415504Snate@binkert.orgquiesceNs(ThreadContext *tc, uint64_t ns)
1425504Snate@binkert.org{
1438784Sgblack@eecs.umich.edu    if (FullSystem) {
1448784Sgblack@eecs.umich.edu        BaseCPU *cpu = tc->getCpuPtr();
1457819Ssteve.reinhardt@amd.com
1468784Sgblack@eecs.umich.edu        if (!cpu->params()->do_quiesce || ns == 0)
1478784Sgblack@eecs.umich.edu            return;
1485504Snate@binkert.org
1498784Sgblack@eecs.umich.edu        EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1505504Snate@binkert.org
1518784Sgblack@eecs.umich.edu        Tick resume = curTick() + SimClock::Int::ns * ns;
1525504Snate@binkert.org
1538784Sgblack@eecs.umich.edu        cpu->reschedule(quiesceEvent, resume, true);
1545504Snate@binkert.org
1558784Sgblack@eecs.umich.edu        DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
1568784Sgblack@eecs.umich.edu                cpu->name(), ns, resume);
1575504Snate@binkert.org
1588784Sgblack@eecs.umich.edu        tc->suspend();
1598784Sgblack@eecs.umich.edu        if (tc->getKernelStats())
1608784Sgblack@eecs.umich.edu            tc->getKernelStats()->quiesce();
1618784Sgblack@eecs.umich.edu    } else {
1628784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("quiesceNs");
1638784Sgblack@eecs.umich.edu    }
1645504Snate@binkert.org}
1655504Snate@binkert.org
1665504Snate@binkert.orgvoid
1675504Snate@binkert.orgquiesceCycles(ThreadContext *tc, uint64_t cycles)
1685504Snate@binkert.org{
1698784Sgblack@eecs.umich.edu    if (FullSystem) {
1708784Sgblack@eecs.umich.edu        BaseCPU *cpu = tc->getCpuPtr();
1717819Ssteve.reinhardt@amd.com
1728784Sgblack@eecs.umich.edu        if (!cpu->params()->do_quiesce || cycles == 0)
1738784Sgblack@eecs.umich.edu            return;
1745504Snate@binkert.org
1758784Sgblack@eecs.umich.edu        EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1765504Snate@binkert.org
1778784Sgblack@eecs.umich.edu        Tick resume = curTick() + cpu->ticks(cycles);
1785504Snate@binkert.org
1798784Sgblack@eecs.umich.edu        cpu->reschedule(quiesceEvent, resume, true);
1805504Snate@binkert.org
1818784Sgblack@eecs.umich.edu        DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
1828784Sgblack@eecs.umich.edu                cpu->name(), cycles, resume);
1835504Snate@binkert.org
1848784Sgblack@eecs.umich.edu        tc->suspend();
1858784Sgblack@eecs.umich.edu        if (tc->getKernelStats())
1868784Sgblack@eecs.umich.edu            tc->getKernelStats()->quiesce();
1878784Sgblack@eecs.umich.edu    } else {
1888784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("quiesceCycles");
1898784Sgblack@eecs.umich.edu    }
1905504Snate@binkert.org}
1915504Snate@binkert.org
1925504Snate@binkert.orguint64_t
1935504Snate@binkert.orgquiesceTime(ThreadContext *tc)
1945504Snate@binkert.org{
1958784Sgblack@eecs.umich.edu    if (FullSystem) {
1968784Sgblack@eecs.umich.edu        return (tc->readLastActivate() - tc->readLastSuspend()) /
1978784Sgblack@eecs.umich.edu            SimClock::Int::ns;
1988784Sgblack@eecs.umich.edu    } else {
1998784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("quiesceTime");
2008784Sgblack@eecs.umich.edu        return 0;
2018784Sgblack@eecs.umich.edu    }
2025504Snate@binkert.org}
2035504Snate@binkert.org
2045741Snate@binkert.orguint64_t
2055741Snate@binkert.orgrpns(ThreadContext *tc)
2065741Snate@binkert.org{
2077823Ssteve.reinhardt@amd.com    return curTick() / SimClock::Int::ns;
2085741Snate@binkert.org}
2095741Snate@binkert.org
2105504Snate@binkert.orgvoid
2115808Snate@binkert.orgwakeCPU(ThreadContext *tc, uint64_t cpuid)
2125808Snate@binkert.org{
2135808Snate@binkert.org    System *sys = tc->getSystemPtr();
2145808Snate@binkert.org    ThreadContext *other_tc = sys->threadContexts[cpuid];
2155808Snate@binkert.org    if (other_tc->status() == ThreadContext::Suspended)
2165808Snate@binkert.org        other_tc->activate();
2175808Snate@binkert.org}
2185808Snate@binkert.org
2195808Snate@binkert.orgvoid
2205504Snate@binkert.orgm5exit(ThreadContext *tc, Tick delay)
2215504Snate@binkert.org{
2227823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
2237819Ssteve.reinhardt@amd.com    exitSimLoop("m5_exit instruction encountered", 0, when);
2245504Snate@binkert.org}
2255504Snate@binkert.org
2265504Snate@binkert.orgvoid
2275504Snate@binkert.orgloadsymbol(ThreadContext *tc)
2285504Snate@binkert.org{
2298784Sgblack@eecs.umich.edu    if (FullSystem) {
2308784Sgblack@eecs.umich.edu        const string &filename = tc->getCpuPtr()->system->params()->symbolfile;
2318784Sgblack@eecs.umich.edu        if (filename.empty()) {
2328784Sgblack@eecs.umich.edu            return;
2338784Sgblack@eecs.umich.edu        }
2348784Sgblack@eecs.umich.edu
2358784Sgblack@eecs.umich.edu        std::string buffer;
2368784Sgblack@eecs.umich.edu        ifstream file(filename.c_str());
2378784Sgblack@eecs.umich.edu
2388784Sgblack@eecs.umich.edu        if (!file)
2398784Sgblack@eecs.umich.edu            fatal("file error: Can't open symbol table file %s\n", filename);
2408784Sgblack@eecs.umich.edu
2418784Sgblack@eecs.umich.edu        while (!file.eof()) {
2428784Sgblack@eecs.umich.edu            getline(file, buffer);
2438784Sgblack@eecs.umich.edu
2448784Sgblack@eecs.umich.edu            if (buffer.empty())
2458784Sgblack@eecs.umich.edu                continue;
2468784Sgblack@eecs.umich.edu
2478784Sgblack@eecs.umich.edu            string::size_type idx = buffer.find(' ');
2488784Sgblack@eecs.umich.edu            if (idx == string::npos)
2498784Sgblack@eecs.umich.edu                continue;
2508784Sgblack@eecs.umich.edu
2518784Sgblack@eecs.umich.edu            string address = "0x" + buffer.substr(0, idx);
2528784Sgblack@eecs.umich.edu            eat_white(address);
2538784Sgblack@eecs.umich.edu            if (address.empty())
2548784Sgblack@eecs.umich.edu                continue;
2558784Sgblack@eecs.umich.edu
2568784Sgblack@eecs.umich.edu            // Skip over letter and space
2578784Sgblack@eecs.umich.edu            string symbol = buffer.substr(idx + 3);
2588784Sgblack@eecs.umich.edu            eat_white(symbol);
2598784Sgblack@eecs.umich.edu            if (symbol.empty())
2608784Sgblack@eecs.umich.edu                continue;
2618784Sgblack@eecs.umich.edu
2628784Sgblack@eecs.umich.edu            Addr addr;
2638784Sgblack@eecs.umich.edu            if (!to_number(address, addr))
2648784Sgblack@eecs.umich.edu                continue;
2658784Sgblack@eecs.umich.edu
2668784Sgblack@eecs.umich.edu            if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol))
2678784Sgblack@eecs.umich.edu                continue;
2688784Sgblack@eecs.umich.edu
2698784Sgblack@eecs.umich.edu
2708784Sgblack@eecs.umich.edu            DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
2718784Sgblack@eecs.umich.edu        }
2728784Sgblack@eecs.umich.edu        file.close();
2738784Sgblack@eecs.umich.edu    } else {
2748784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("loadsymbol");
275711SN/A    }
2765504Snate@binkert.org}
2775504Snate@binkert.org
2785504Snate@binkert.orgvoid
2795780Ssteve.reinhardt@amd.comaddsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
2805780Ssteve.reinhardt@amd.com{
2818784Sgblack@eecs.umich.edu    if (FullSystem) {
2828784Sgblack@eecs.umich.edu        char symb[100];
2838784Sgblack@eecs.umich.edu        CopyStringOut(tc, symb, symbolAddr, 100);
2848784Sgblack@eecs.umich.edu        std::string symbol(symb);
2855780Ssteve.reinhardt@amd.com
2868784Sgblack@eecs.umich.edu        DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
2875780Ssteve.reinhardt@amd.com
2888784Sgblack@eecs.umich.edu        tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
2898784Sgblack@eecs.umich.edu        debugSymbolTable->insert(addr,symbol);
2908784Sgblack@eecs.umich.edu    } else {
2918784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("addSymbol");
2928784Sgblack@eecs.umich.edu    }
2935780Ssteve.reinhardt@amd.com}
2945780Ssteve.reinhardt@amd.com
2958555Sgblack@eecs.umich.eduuint64_t
2968555Sgblack@eecs.umich.eduinitParam(ThreadContext *tc)
2978555Sgblack@eecs.umich.edu{
2988784Sgblack@eecs.umich.edu    if (FullSystem) {
2998784Sgblack@eecs.umich.edu        return tc->getCpuPtr()->system->init_param;
3008784Sgblack@eecs.umich.edu    } else {
3018784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("initParam");
3028784Sgblack@eecs.umich.edu        return 0;
3038784Sgblack@eecs.umich.edu    }
3048555Sgblack@eecs.umich.edu}
3058555Sgblack@eecs.umich.edu
3065780Ssteve.reinhardt@amd.com
3075780Ssteve.reinhardt@amd.comvoid
3085504Snate@binkert.orgresetstats(ThreadContext *tc, Tick delay, Tick period)
3095504Snate@binkert.org{
3105529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_statistics_insts)
3115504Snate@binkert.org        return;
3125504Snate@binkert.org
3135504Snate@binkert.org
3147823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
3157064Snate@binkert.org    Tick repeat = period * SimClock::Int::ns;
3165504Snate@binkert.org
3177822Ssteve.reinhardt@amd.com    Stats::schedStatEvent(false, true, when, repeat);
3185504Snate@binkert.org}
3195504Snate@binkert.org
3205504Snate@binkert.orgvoid
3215504Snate@binkert.orgdumpstats(ThreadContext *tc, Tick delay, Tick period)
3225504Snate@binkert.org{
3235529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_statistics_insts)
3245504Snate@binkert.org        return;
3255504Snate@binkert.org
3265504Snate@binkert.org
3277823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
3287064Snate@binkert.org    Tick repeat = period * SimClock::Int::ns;
3295504Snate@binkert.org
3307822Ssteve.reinhardt@amd.com    Stats::schedStatEvent(true, false, when, repeat);
3315504Snate@binkert.org}
3325504Snate@binkert.org
3335504Snate@binkert.orgvoid
3345504Snate@binkert.orgdumpresetstats(ThreadContext *tc, Tick delay, Tick period)
3355504Snate@binkert.org{
3365529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_statistics_insts)
3375504Snate@binkert.org        return;
3385504Snate@binkert.org
3395504Snate@binkert.org
3407823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
3417064Snate@binkert.org    Tick repeat = period * SimClock::Int::ns;
3425504Snate@binkert.org
3437822Ssteve.reinhardt@amd.com    Stats::schedStatEvent(true, true, when, repeat);
3445504Snate@binkert.org}
3455504Snate@binkert.org
3465504Snate@binkert.orgvoid
3475504Snate@binkert.orgm5checkpoint(ThreadContext *tc, Tick delay, Tick period)
3485504Snate@binkert.org{
3495529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_checkpoint_insts)
3505504Snate@binkert.org        return;
3515504Snate@binkert.org
3527823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
3537064Snate@binkert.org    Tick repeat = period * SimClock::Int::ns;
3545504Snate@binkert.org
3557819Ssteve.reinhardt@amd.com    exitSimLoop("checkpoint", 0, when, repeat);
3565504Snate@binkert.org}
3575504Snate@binkert.org
3585504Snate@binkert.orguint64_t
3595504Snate@binkert.orgreadfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset)
3605504Snate@binkert.org{
3618784Sgblack@eecs.umich.edu    if (FullSystem) {
3628784Sgblack@eecs.umich.edu        const string &file = tc->getSystemPtr()->params()->readfile;
3638784Sgblack@eecs.umich.edu        if (file.empty()) {
3648784Sgblack@eecs.umich.edu            return ULL(0);
3658784Sgblack@eecs.umich.edu        }
3668784Sgblack@eecs.umich.edu
3678784Sgblack@eecs.umich.edu        uint64_t result = 0;
3688784Sgblack@eecs.umich.edu
3698784Sgblack@eecs.umich.edu        int fd = ::open(file.c_str(), O_RDONLY, 0);
3708784Sgblack@eecs.umich.edu        if (fd < 0)
3718784Sgblack@eecs.umich.edu            panic("could not open file %s\n", file);
3728784Sgblack@eecs.umich.edu
3738784Sgblack@eecs.umich.edu        if (::lseek(fd, offset, SEEK_SET) < 0)
3748784Sgblack@eecs.umich.edu            panic("could not seek: %s", strerror(errno));
3758784Sgblack@eecs.umich.edu
3768784Sgblack@eecs.umich.edu        char *buf = new char[len];
3778784Sgblack@eecs.umich.edu        char *p = buf;
3788784Sgblack@eecs.umich.edu        while (len > 0) {
3798784Sgblack@eecs.umich.edu            int bytes = ::read(fd, p, len);
3808784Sgblack@eecs.umich.edu            if (bytes <= 0)
3818784Sgblack@eecs.umich.edu                break;
3828784Sgblack@eecs.umich.edu
3838784Sgblack@eecs.umich.edu            p += bytes;
3848784Sgblack@eecs.umich.edu            result += bytes;
3858784Sgblack@eecs.umich.edu            len -= bytes;
3868784Sgblack@eecs.umich.edu        }
3878784Sgblack@eecs.umich.edu
3888784Sgblack@eecs.umich.edu        close(fd);
3898784Sgblack@eecs.umich.edu        CopyIn(tc, vaddr, buf, result);
3908784Sgblack@eecs.umich.edu        delete [] buf;
3918784Sgblack@eecs.umich.edu        return result;
3928784Sgblack@eecs.umich.edu    } else {
3938784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("readfile");
3948784Sgblack@eecs.umich.edu        return 0;
395310SN/A    }
3965504Snate@binkert.org}
3972188SN/A
3985504Snate@binkert.orgvoid
3995504Snate@binkert.orgdebugbreak(ThreadContext *tc)
4005504Snate@binkert.org{
4018231Snate@binkert.org    Debug::breakpoint();
4025504Snate@binkert.org}
4032235SN/A
4045504Snate@binkert.orgvoid
4055504Snate@binkert.orgswitchcpu(ThreadContext *tc)
4065504Snate@binkert.org{
4075504Snate@binkert.org    exitSimLoop("switchcpu");
4085504Snate@binkert.org}
4093368Sstever@eecs.umich.edu
4107914SBrad.Beckmann@amd.com//
4117914SBrad.Beckmann@amd.com// This function is executed when annotated work items begin.  Depending on
4127914SBrad.Beckmann@amd.com// what the user specified at the command line, the simulation may exit and/or
4137914SBrad.Beckmann@amd.com// take a checkpoint when a certain work item begins.
4147914SBrad.Beckmann@amd.com//
4157914SBrad.Beckmann@amd.comvoid
4167914SBrad.Beckmann@amd.comworkbegin(ThreadContext *tc, uint64_t workid, uint64_t threadid)
4177914SBrad.Beckmann@amd.com{
4187914SBrad.Beckmann@amd.com    tc->getCpuPtr()->workItemBegin();
4197914SBrad.Beckmann@amd.com    System *sys = tc->getSystemPtr();
4208580Ssteve.reinhardt@amd.com    const System::Params *params = sys->params();
4217914SBrad.Beckmann@amd.com
4227914SBrad.Beckmann@amd.com    DPRINTF(WorkItems, "Work Begin workid: %d, threadid %d\n", workid,
4237914SBrad.Beckmann@amd.com            threadid);
4247914SBrad.Beckmann@amd.com
4257914SBrad.Beckmann@amd.com    //
4267914SBrad.Beckmann@amd.com    // If specified, determine if this is the specific work item the user
4277914SBrad.Beckmann@amd.com    // identified
4287914SBrad.Beckmann@amd.com    //
4298580Ssteve.reinhardt@amd.com    if (params->work_item_id == -1 || params->work_item_id == workid) {
4307914SBrad.Beckmann@amd.com
4317914SBrad.Beckmann@amd.com        uint64_t systemWorkBeginCount = sys->incWorkItemsBegin();
4327914SBrad.Beckmann@amd.com        int cpuId = tc->getCpuPtr()->cpuId();
4337914SBrad.Beckmann@amd.com
4348580Ssteve.reinhardt@amd.com        if (params->work_cpus_ckpt_count != 0 &&
4358580Ssteve.reinhardt@amd.com            sys->markWorkItem(cpuId) >= params->work_cpus_ckpt_count) {
4367914SBrad.Beckmann@amd.com            //
4377914SBrad.Beckmann@amd.com            // If active cpus equals checkpoint count, create checkpoint
4387914SBrad.Beckmann@amd.com            //
4398580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
4407914SBrad.Beckmann@amd.com        }
4417914SBrad.Beckmann@amd.com
4428580Ssteve.reinhardt@amd.com        if (systemWorkBeginCount == params->work_begin_ckpt_count) {
4437914SBrad.Beckmann@amd.com            //
4447914SBrad.Beckmann@amd.com            // Note: the string specified as the cause of the exit event must
4457914SBrad.Beckmann@amd.com            // exactly equal "checkpoint" inorder to create a checkpoint
4467914SBrad.Beckmann@amd.com            //
4478580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
4487914SBrad.Beckmann@amd.com        }
4497914SBrad.Beckmann@amd.com
4508580Ssteve.reinhardt@amd.com        if (systemWorkBeginCount == params->work_begin_exit_count) {
4517914SBrad.Beckmann@amd.com            //
4527914SBrad.Beckmann@amd.com            // If a certain number of work items started, exit simulation
4537914SBrad.Beckmann@amd.com            //
4548580Ssteve.reinhardt@amd.com            exitSimLoop("work started count reach");
4557914SBrad.Beckmann@amd.com        }
4567914SBrad.Beckmann@amd.com
4578580Ssteve.reinhardt@amd.com        if (cpuId == params->work_begin_cpu_id_exit) {
4587914SBrad.Beckmann@amd.com            //
4598580Ssteve.reinhardt@amd.com            // If work started on the cpu id specified, exit simulation
4607914SBrad.Beckmann@amd.com            //
4618580Ssteve.reinhardt@amd.com            exitSimLoop("work started on specific cpu");
4627914SBrad.Beckmann@amd.com        }
4637914SBrad.Beckmann@amd.com    }
4647914SBrad.Beckmann@amd.com}
4657914SBrad.Beckmann@amd.com
4667914SBrad.Beckmann@amd.com//
4677914SBrad.Beckmann@amd.com// This function is executed when annotated work items end.  Depending on
4687914SBrad.Beckmann@amd.com// what the user specified at the command line, the simulation may exit and/or
4697914SBrad.Beckmann@amd.com// take a checkpoint when a certain work item ends.
4707914SBrad.Beckmann@amd.com//
4717914SBrad.Beckmann@amd.comvoid
4727914SBrad.Beckmann@amd.comworkend(ThreadContext *tc, uint64_t workid, uint64_t threadid)
4737914SBrad.Beckmann@amd.com{
4747914SBrad.Beckmann@amd.com    tc->getCpuPtr()->workItemEnd();
4757914SBrad.Beckmann@amd.com    System *sys = tc->getSystemPtr();
4768580Ssteve.reinhardt@amd.com    const System::Params *params = sys->params();
4777914SBrad.Beckmann@amd.com
4787914SBrad.Beckmann@amd.com    DPRINTF(WorkItems, "Work End workid: %d, threadid %d\n", workid, threadid);
4797914SBrad.Beckmann@amd.com
4807914SBrad.Beckmann@amd.com    //
4817914SBrad.Beckmann@amd.com    // If specified, determine if this is the specific work item the user
4827914SBrad.Beckmann@amd.com    // identified
4837914SBrad.Beckmann@amd.com    //
4848580Ssteve.reinhardt@amd.com    if (params->work_item_id == -1 || params->work_item_id == workid) {
4857914SBrad.Beckmann@amd.com
4867914SBrad.Beckmann@amd.com        uint64_t systemWorkEndCount = sys->incWorkItemsEnd();
4877914SBrad.Beckmann@amd.com        int cpuId = tc->getCpuPtr()->cpuId();
4887914SBrad.Beckmann@amd.com
4898580Ssteve.reinhardt@amd.com        if (params->work_cpus_ckpt_count != 0 &&
4908580Ssteve.reinhardt@amd.com            sys->markWorkItem(cpuId) >= params->work_cpus_ckpt_count) {
4917914SBrad.Beckmann@amd.com            //
4927914SBrad.Beckmann@amd.com            // If active cpus equals checkpoint count, create checkpoint
4937914SBrad.Beckmann@amd.com            //
4948580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
4957914SBrad.Beckmann@amd.com        }
4967914SBrad.Beckmann@amd.com
4978580Ssteve.reinhardt@amd.com        if (params->work_end_ckpt_count != 0 &&
4988580Ssteve.reinhardt@amd.com            systemWorkEndCount == params->work_end_ckpt_count) {
4997914SBrad.Beckmann@amd.com            //
5007914SBrad.Beckmann@amd.com            // If total work items completed equals checkpoint count, create
5017914SBrad.Beckmann@amd.com            // checkpoint
5027914SBrad.Beckmann@amd.com            //
5038580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
5047914SBrad.Beckmann@amd.com        }
5057914SBrad.Beckmann@amd.com
5068580Ssteve.reinhardt@amd.com        if (params->work_end_exit_count != 0 &&
5078580Ssteve.reinhardt@amd.com            systemWorkEndCount == params->work_end_exit_count) {
5087914SBrad.Beckmann@amd.com            //
5097914SBrad.Beckmann@amd.com            // If total work items completed equals exit count, exit simulation
5107914SBrad.Beckmann@amd.com            //
5118580Ssteve.reinhardt@amd.com            exitSimLoop("work items exit count reached");
5127914SBrad.Beckmann@amd.com        }
5137914SBrad.Beckmann@amd.com    }
5147914SBrad.Beckmann@amd.com}
5157914SBrad.Beckmann@amd.com
5167811Ssteve.reinhardt@amd.com} // namespace PseudoInst
517