pseudo_inst.cc revision 9457
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
518777Sgblack@eecs.umich.edu#include "arch/kernel_stats.hh"
522170SN/A#include "arch/vtophys.hh"
535882Snate@binkert.org#include "base/debug.hh"
548734Sdam.sunwoo@arm.com#include "base/output.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{
898806Sgblack@eecs.umich.edu    if (!FullSystem)
908784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("arm");
918806Sgblack@eecs.umich.edu
925504Snate@binkert.org    if (tc->getKernelStats())
935504Snate@binkert.org        tc->getKernelStats()->arm();
945504Snate@binkert.org}
955504Snate@binkert.org
965504Snate@binkert.orgvoid
975504Snate@binkert.orgquiesce(ThreadContext *tc)
985504Snate@binkert.org{
998806Sgblack@eecs.umich.edu    if (!FullSystem)
1008806Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("quiesce");
1018666SPrakash.Ramrakhyani@arm.com
1025529Snate@binkert.org    if (!tc->getCpuPtr()->params()->do_quiesce)
1035504Snate@binkert.org        return;
1045504Snate@binkert.org
1055504Snate@binkert.org    DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name());
1065504Snate@binkert.org
1075504Snate@binkert.org    tc->suspend();
1085504Snate@binkert.org    if (tc->getKernelStats())
1095504Snate@binkert.org        tc->getKernelStats()->quiesce();
1105504Snate@binkert.org}
1115504Snate@binkert.org
1125504Snate@binkert.orgvoid
1138142SAli.Saidi@ARM.comquiesceSkip(ThreadContext *tc)
1148142SAli.Saidi@ARM.com{
1158806Sgblack@eecs.umich.edu    if (!FullSystem)
1168806Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("quiesceSkip");
1178666SPrakash.Ramrakhyani@arm.com
1188142SAli.Saidi@ARM.com    BaseCPU *cpu = tc->getCpuPtr();
1198142SAli.Saidi@ARM.com
1208142SAli.Saidi@ARM.com    if (!cpu->params()->do_quiesce)
1218142SAli.Saidi@ARM.com        return;
1228142SAli.Saidi@ARM.com
1238142SAli.Saidi@ARM.com    EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1248142SAli.Saidi@ARM.com
1258142SAli.Saidi@ARM.com    Tick resume = curTick() + 1;
1268142SAli.Saidi@ARM.com
1278142SAli.Saidi@ARM.com    cpu->reschedule(quiesceEvent, resume, true);
1288142SAli.Saidi@ARM.com
1298142SAli.Saidi@ARM.com    DPRINTF(Quiesce, "%s: quiesceSkip() until %d\n",
1308142SAli.Saidi@ARM.com            cpu->name(), resume);
1318142SAli.Saidi@ARM.com
1328142SAli.Saidi@ARM.com    tc->suspend();
1338142SAli.Saidi@ARM.com    if (tc->getKernelStats())
1348142SAli.Saidi@ARM.com        tc->getKernelStats()->quiesce();
1358142SAli.Saidi@ARM.com}
1368142SAli.Saidi@ARM.com
1378142SAli.Saidi@ARM.comvoid
1385504Snate@binkert.orgquiesceNs(ThreadContext *tc, uint64_t ns)
1395504Snate@binkert.org{
1408806Sgblack@eecs.umich.edu    if (!FullSystem)
1418806Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("quiesceNs");
1428666SPrakash.Ramrakhyani@arm.com
1437819Ssteve.reinhardt@amd.com    BaseCPU *cpu = tc->getCpuPtr();
1447819Ssteve.reinhardt@amd.com
1457819Ssteve.reinhardt@amd.com    if (!cpu->params()->do_quiesce || ns == 0)
1465504Snate@binkert.org        return;
1475504Snate@binkert.org
1485504Snate@binkert.org    EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1495504Snate@binkert.org
1507823Ssteve.reinhardt@amd.com    Tick resume = curTick() + SimClock::Int::ns * ns;
1515504Snate@binkert.org
1527819Ssteve.reinhardt@amd.com    cpu->reschedule(quiesceEvent, resume, true);
1535504Snate@binkert.org
1545504Snate@binkert.org    DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
1557819Ssteve.reinhardt@amd.com            cpu->name(), ns, resume);
1565504Snate@binkert.org
1575504Snate@binkert.org    tc->suspend();
1585504Snate@binkert.org    if (tc->getKernelStats())
1595504Snate@binkert.org        tc->getKernelStats()->quiesce();
1605504Snate@binkert.org}
1615504Snate@binkert.org
1625504Snate@binkert.orgvoid
1635504Snate@binkert.orgquiesceCycles(ThreadContext *tc, uint64_t cycles)
1645504Snate@binkert.org{
1658806Sgblack@eecs.umich.edu    if (!FullSystem)
1668806Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("quiesceCycles");
1678666SPrakash.Ramrakhyani@arm.com
1687819Ssteve.reinhardt@amd.com    BaseCPU *cpu = tc->getCpuPtr();
1697819Ssteve.reinhardt@amd.com
1707819Ssteve.reinhardt@amd.com    if (!cpu->params()->do_quiesce || cycles == 0)
1715504Snate@binkert.org        return;
1725504Snate@binkert.org
1735504Snate@binkert.org    EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1745504Snate@binkert.org
1759180Sandreas.hansson@arm.com    Tick resume = cpu->clockEdge(Cycles(cycles));
1765504Snate@binkert.org
1777819Ssteve.reinhardt@amd.com    cpu->reschedule(quiesceEvent, resume, true);
1785504Snate@binkert.org
1795504Snate@binkert.org    DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
1807819Ssteve.reinhardt@amd.com            cpu->name(), cycles, resume);
1815504Snate@binkert.org
1825504Snate@binkert.org    tc->suspend();
1835504Snate@binkert.org    if (tc->getKernelStats())
1845504Snate@binkert.org        tc->getKernelStats()->quiesce();
1855504Snate@binkert.org}
1865504Snate@binkert.org
1875504Snate@binkert.orguint64_t
1885504Snate@binkert.orgquiesceTime(ThreadContext *tc)
1895504Snate@binkert.org{
1908806Sgblack@eecs.umich.edu    if (!FullSystem) {
1918784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("quiesceTime");
1928784Sgblack@eecs.umich.edu        return 0;
1938784Sgblack@eecs.umich.edu    }
1948806Sgblack@eecs.umich.edu
1957064Snate@binkert.org    return (tc->readLastActivate() - tc->readLastSuspend()) /
1967064Snate@binkert.org        SimClock::Int::ns;
1975504Snate@binkert.org}
1985504Snate@binkert.org
1995741Snate@binkert.orguint64_t
2005741Snate@binkert.orgrpns(ThreadContext *tc)
2015741Snate@binkert.org{
2027823Ssteve.reinhardt@amd.com    return curTick() / SimClock::Int::ns;
2035741Snate@binkert.org}
2045741Snate@binkert.org
2055504Snate@binkert.orgvoid
2065808Snate@binkert.orgwakeCPU(ThreadContext *tc, uint64_t cpuid)
2075808Snate@binkert.org{
2085808Snate@binkert.org    System *sys = tc->getSystemPtr();
2095808Snate@binkert.org    ThreadContext *other_tc = sys->threadContexts[cpuid];
2105808Snate@binkert.org    if (other_tc->status() == ThreadContext::Suspended)
2115808Snate@binkert.org        other_tc->activate();
2125808Snate@binkert.org}
2135808Snate@binkert.org
2145808Snate@binkert.orgvoid
2155504Snate@binkert.orgm5exit(ThreadContext *tc, Tick delay)
2165504Snate@binkert.org{
2177823Ssteve.reinhardt@amd.com    Tick when = curTick() + delay * SimClock::Int::ns;
2187819Ssteve.reinhardt@amd.com    exitSimLoop("m5_exit instruction encountered", 0, when);
2195504Snate@binkert.org}
2205504Snate@binkert.org
2215504Snate@binkert.orgvoid
2229457Svilanova@ac.upc.edum5fail(ThreadContext *tc, Tick delay, uint64_t code)
2239457Svilanova@ac.upc.edu{
2249457Svilanova@ac.upc.edu    Tick when = curTick() + delay * SimClock::Int::ns;
2259457Svilanova@ac.upc.edu    exitSimLoop("m5_fail instruction encountered", code, when);
2269457Svilanova@ac.upc.edu}
2279457Svilanova@ac.upc.edu
2289457Svilanova@ac.upc.eduvoid
2295504Snate@binkert.orgloadsymbol(ThreadContext *tc)
2305504Snate@binkert.org{
2318806Sgblack@eecs.umich.edu    if (!FullSystem)
2328806Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("loadsymbol");
2338784Sgblack@eecs.umich.edu
2345504Snate@binkert.org    const string &filename = tc->getCpuPtr()->system->params()->symbolfile;
2355504Snate@binkert.org    if (filename.empty()) {
2365504Snate@binkert.org        return;
237711SN/A    }
238711SN/A
2395504Snate@binkert.org    std::string buffer;
2405504Snate@binkert.org    ifstream file(filename.c_str());
241310SN/A
2425504Snate@binkert.org    if (!file)
2435504Snate@binkert.org        fatal("file error: Can't open symbol table file %s\n", filename);
2443373Sstever@eecs.umich.edu
2455504Snate@binkert.org    while (!file.eof()) {
2465504Snate@binkert.org        getline(file, buffer);
2475504Snate@binkert.org
2485504Snate@binkert.org        if (buffer.empty())
2495504Snate@binkert.org            continue;
2505504Snate@binkert.org
2516227Snate@binkert.org        string::size_type idx = buffer.find(' ');
2525504Snate@binkert.org        if (idx == string::npos)
2535504Snate@binkert.org            continue;
2545504Snate@binkert.org
2555504Snate@binkert.org        string address = "0x" + buffer.substr(0, idx);
2565504Snate@binkert.org        eat_white(address);
2575504Snate@binkert.org        if (address.empty())
2585504Snate@binkert.org            continue;
2595504Snate@binkert.org
2605504Snate@binkert.org        // Skip over letter and space
2615504Snate@binkert.org        string symbol = buffer.substr(idx + 3);
2625504Snate@binkert.org        eat_white(symbol);
2635504Snate@binkert.org        if (symbol.empty())
2645504Snate@binkert.org            continue;
2655504Snate@binkert.org
2665504Snate@binkert.org        Addr addr;
2675504Snate@binkert.org        if (!to_number(address, addr))
2685504Snate@binkert.org            continue;
2695504Snate@binkert.org
2705504Snate@binkert.org        if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol))
2715504Snate@binkert.org            continue;
2725504Snate@binkert.org
2735504Snate@binkert.org
2745504Snate@binkert.org        DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
2755504Snate@binkert.org    }
2765504Snate@binkert.org    file.close();
2775504Snate@binkert.org}
2785504Snate@binkert.org
2795504Snate@binkert.orgvoid
2805780Ssteve.reinhardt@amd.comaddsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
2815780Ssteve.reinhardt@amd.com{
2828806Sgblack@eecs.umich.edu    if (!FullSystem)
2838806Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("addSymbol");
2848666SPrakash.Ramrakhyani@arm.com
2855780Ssteve.reinhardt@amd.com    char symb[100];
2865780Ssteve.reinhardt@amd.com    CopyStringOut(tc, symb, symbolAddr, 100);
2875780Ssteve.reinhardt@amd.com    std::string symbol(symb);
2885780Ssteve.reinhardt@amd.com
2895780Ssteve.reinhardt@amd.com    DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
2905780Ssteve.reinhardt@amd.com
2915780Ssteve.reinhardt@amd.com    tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
2925952Ssaidi@eecs.umich.edu    debugSymbolTable->insert(addr,symbol);
2935780Ssteve.reinhardt@amd.com}
2945780Ssteve.reinhardt@amd.com
2958555Sgblack@eecs.umich.eduuint64_t
2968555Sgblack@eecs.umich.eduinitParam(ThreadContext *tc)
2978555Sgblack@eecs.umich.edu{
2988806Sgblack@eecs.umich.edu    if (!FullSystem) {
2998784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("initParam");
3008784Sgblack@eecs.umich.edu        return 0;
3018784Sgblack@eecs.umich.edu    }
3028806Sgblack@eecs.umich.edu
3038555Sgblack@eecs.umich.edu    return tc->getCpuPtr()->system->init_param;
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{
3618806Sgblack@eecs.umich.edu    if (!FullSystem) {
3628784Sgblack@eecs.umich.edu        panicFsOnlyPseudoInst("readfile");
3638784Sgblack@eecs.umich.edu        return 0;
3648666SPrakash.Ramrakhyani@arm.com    }
3658806Sgblack@eecs.umich.edu
3665504Snate@binkert.org    const string &file = tc->getSystemPtr()->params()->readfile;
3675504Snate@binkert.org    if (file.empty()) {
3685504Snate@binkert.org        return ULL(0);
369310SN/A    }
370299SN/A
3715504Snate@binkert.org    uint64_t result = 0;
3722188SN/A
3735504Snate@binkert.org    int fd = ::open(file.c_str(), O_RDONLY, 0);
3745504Snate@binkert.org    if (fd < 0)
3755504Snate@binkert.org        panic("could not open file %s\n", file);
3762235SN/A
3775504Snate@binkert.org    if (::lseek(fd, offset, SEEK_SET) < 0)
3785504Snate@binkert.org        panic("could not seek: %s", strerror(errno));
3793368Sstever@eecs.umich.edu
3805504Snate@binkert.org    char *buf = new char[len];
3815504Snate@binkert.org    char *p = buf;
3825504Snate@binkert.org    while (len > 0) {
3835504Snate@binkert.org        int bytes = ::read(fd, p, len);
3845504Snate@binkert.org        if (bytes <= 0)
3855504Snate@binkert.org            break;
3863368Sstever@eecs.umich.edu
3875504Snate@binkert.org        p += bytes;
3885504Snate@binkert.org        result += bytes;
3895504Snate@binkert.org        len -= bytes;
3902188SN/A    }
3912188SN/A
3925504Snate@binkert.org    close(fd);
3935504Snate@binkert.org    CopyIn(tc, vaddr, buf, result);
3945504Snate@binkert.org    delete [] buf;
3955504Snate@binkert.org    return result;
3965504Snate@binkert.org}
3972188SN/A
3988734Sdam.sunwoo@arm.comuint64_t
3998734Sdam.sunwoo@arm.comwritefile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset,
4008734Sdam.sunwoo@arm.com            Addr filename_addr)
4018734Sdam.sunwoo@arm.com{
4028734Sdam.sunwoo@arm.com    ostream *os;
4038734Sdam.sunwoo@arm.com
4048734Sdam.sunwoo@arm.com    // copy out target filename
4058734Sdam.sunwoo@arm.com    char fn[100];
4068734Sdam.sunwoo@arm.com    std::string filename;
4078734Sdam.sunwoo@arm.com    CopyStringOut(tc, fn, filename_addr, 100);
4088734Sdam.sunwoo@arm.com    filename = std::string(fn);
4098734Sdam.sunwoo@arm.com
4108734Sdam.sunwoo@arm.com    if (offset == 0) {
4118734Sdam.sunwoo@arm.com        // create a new file (truncate)
4128734Sdam.sunwoo@arm.com        os = simout.create(filename, true);
4138734Sdam.sunwoo@arm.com    } else {
4148734Sdam.sunwoo@arm.com        // do not truncate file if offset is non-zero
4158734Sdam.sunwoo@arm.com        // (ios::in flag is required as well to keep the existing data
4168734Sdam.sunwoo@arm.com        //  intact, otherwise existing data will be zeroed out.)
4178734Sdam.sunwoo@arm.com        os = simout.openFile(simout.directory() + filename,
4188734Sdam.sunwoo@arm.com                            ios::in | ios::out | ios::binary);
4198734Sdam.sunwoo@arm.com    }
4208734Sdam.sunwoo@arm.com    if (!os)
4218734Sdam.sunwoo@arm.com        panic("could not open file %s\n", filename);
4228734Sdam.sunwoo@arm.com
4238734Sdam.sunwoo@arm.com    // seek to offset
4248734Sdam.sunwoo@arm.com    os->seekp(offset);
4258734Sdam.sunwoo@arm.com
4268734Sdam.sunwoo@arm.com    // copy out data and write to file
4278734Sdam.sunwoo@arm.com    char *buf = new char[len];
4288734Sdam.sunwoo@arm.com    CopyOut(tc, buf, vaddr, len);
4298734Sdam.sunwoo@arm.com    os->write(buf, len);
4308734Sdam.sunwoo@arm.com    if (os->fail() || os->bad())
4318734Sdam.sunwoo@arm.com        panic("Error while doing writefile!\n");
4328734Sdam.sunwoo@arm.com
4338734Sdam.sunwoo@arm.com    simout.close(os);
4348734Sdam.sunwoo@arm.com
4358734Sdam.sunwoo@arm.com    delete [] buf;
4368734Sdam.sunwoo@arm.com
4378734Sdam.sunwoo@arm.com    return len;
4388734Sdam.sunwoo@arm.com}
4398734Sdam.sunwoo@arm.com
4405504Snate@binkert.orgvoid
4415504Snate@binkert.orgdebugbreak(ThreadContext *tc)
4425504Snate@binkert.org{
4438231Snate@binkert.org    Debug::breakpoint();
4445504Snate@binkert.org}
4452235SN/A
4465504Snate@binkert.orgvoid
4475504Snate@binkert.orgswitchcpu(ThreadContext *tc)
4485504Snate@binkert.org{
4495504Snate@binkert.org    exitSimLoop("switchcpu");
4505504Snate@binkert.org}
4513368Sstever@eecs.umich.edu
4527914SBrad.Beckmann@amd.com//
4537914SBrad.Beckmann@amd.com// This function is executed when annotated work items begin.  Depending on
4547914SBrad.Beckmann@amd.com// what the user specified at the command line, the simulation may exit and/or
4557914SBrad.Beckmann@amd.com// take a checkpoint when a certain work item begins.
4567914SBrad.Beckmann@amd.com//
4577914SBrad.Beckmann@amd.comvoid
4587914SBrad.Beckmann@amd.comworkbegin(ThreadContext *tc, uint64_t workid, uint64_t threadid)
4597914SBrad.Beckmann@amd.com{
4607914SBrad.Beckmann@amd.com    tc->getCpuPtr()->workItemBegin();
4617914SBrad.Beckmann@amd.com    System *sys = tc->getSystemPtr();
4628580Ssteve.reinhardt@amd.com    const System::Params *params = sys->params();
4638666SPrakash.Ramrakhyani@arm.com    sys->workItemBegin(threadid, workid);
4647914SBrad.Beckmann@amd.com
4657914SBrad.Beckmann@amd.com    DPRINTF(WorkItems, "Work Begin workid: %d, threadid %d\n", workid,
4667914SBrad.Beckmann@amd.com            threadid);
4677914SBrad.Beckmann@amd.com
4687914SBrad.Beckmann@amd.com    //
4697914SBrad.Beckmann@amd.com    // If specified, determine if this is the specific work item the user
4707914SBrad.Beckmann@amd.com    // identified
4717914SBrad.Beckmann@amd.com    //
4728580Ssteve.reinhardt@amd.com    if (params->work_item_id == -1 || params->work_item_id == workid) {
4737914SBrad.Beckmann@amd.com
4747914SBrad.Beckmann@amd.com        uint64_t systemWorkBeginCount = sys->incWorkItemsBegin();
4757914SBrad.Beckmann@amd.com        int cpuId = tc->getCpuPtr()->cpuId();
4767914SBrad.Beckmann@amd.com
4778580Ssteve.reinhardt@amd.com        if (params->work_cpus_ckpt_count != 0 &&
4788580Ssteve.reinhardt@amd.com            sys->markWorkItem(cpuId) >= params->work_cpus_ckpt_count) {
4797914SBrad.Beckmann@amd.com            //
4807914SBrad.Beckmann@amd.com            // If active cpus equals checkpoint count, create checkpoint
4817914SBrad.Beckmann@amd.com            //
4828580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
4837914SBrad.Beckmann@amd.com        }
4847914SBrad.Beckmann@amd.com
4858580Ssteve.reinhardt@amd.com        if (systemWorkBeginCount == params->work_begin_ckpt_count) {
4867914SBrad.Beckmann@amd.com            //
4877914SBrad.Beckmann@amd.com            // Note: the string specified as the cause of the exit event must
4887914SBrad.Beckmann@amd.com            // exactly equal "checkpoint" inorder to create a checkpoint
4897914SBrad.Beckmann@amd.com            //
4908580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
4917914SBrad.Beckmann@amd.com        }
4927914SBrad.Beckmann@amd.com
4938580Ssteve.reinhardt@amd.com        if (systemWorkBeginCount == params->work_begin_exit_count) {
4947914SBrad.Beckmann@amd.com            //
4957914SBrad.Beckmann@amd.com            // If a certain number of work items started, exit simulation
4967914SBrad.Beckmann@amd.com            //
4978580Ssteve.reinhardt@amd.com            exitSimLoop("work started count reach");
4987914SBrad.Beckmann@amd.com        }
4997914SBrad.Beckmann@amd.com
5008580Ssteve.reinhardt@amd.com        if (cpuId == params->work_begin_cpu_id_exit) {
5017914SBrad.Beckmann@amd.com            //
5028580Ssteve.reinhardt@amd.com            // If work started on the cpu id specified, exit simulation
5037914SBrad.Beckmann@amd.com            //
5048580Ssteve.reinhardt@amd.com            exitSimLoop("work started on specific cpu");
5057914SBrad.Beckmann@amd.com        }
5067914SBrad.Beckmann@amd.com    }
5077914SBrad.Beckmann@amd.com}
5087914SBrad.Beckmann@amd.com
5097914SBrad.Beckmann@amd.com//
5107914SBrad.Beckmann@amd.com// This function is executed when annotated work items end.  Depending on
5117914SBrad.Beckmann@amd.com// what the user specified at the command line, the simulation may exit and/or
5127914SBrad.Beckmann@amd.com// take a checkpoint when a certain work item ends.
5137914SBrad.Beckmann@amd.com//
5147914SBrad.Beckmann@amd.comvoid
5157914SBrad.Beckmann@amd.comworkend(ThreadContext *tc, uint64_t workid, uint64_t threadid)
5167914SBrad.Beckmann@amd.com{
5177914SBrad.Beckmann@amd.com    tc->getCpuPtr()->workItemEnd();
5187914SBrad.Beckmann@amd.com    System *sys = tc->getSystemPtr();
5198580Ssteve.reinhardt@amd.com    const System::Params *params = sys->params();
5208666SPrakash.Ramrakhyani@arm.com    sys->workItemEnd(threadid, workid);
5217914SBrad.Beckmann@amd.com
5227914SBrad.Beckmann@amd.com    DPRINTF(WorkItems, "Work End workid: %d, threadid %d\n", workid, threadid);
5237914SBrad.Beckmann@amd.com
5247914SBrad.Beckmann@amd.com    //
5257914SBrad.Beckmann@amd.com    // If specified, determine if this is the specific work item the user
5267914SBrad.Beckmann@amd.com    // identified
5277914SBrad.Beckmann@amd.com    //
5288580Ssteve.reinhardt@amd.com    if (params->work_item_id == -1 || params->work_item_id == workid) {
5297914SBrad.Beckmann@amd.com
5307914SBrad.Beckmann@amd.com        uint64_t systemWorkEndCount = sys->incWorkItemsEnd();
5317914SBrad.Beckmann@amd.com        int cpuId = tc->getCpuPtr()->cpuId();
5327914SBrad.Beckmann@amd.com
5338580Ssteve.reinhardt@amd.com        if (params->work_cpus_ckpt_count != 0 &&
5348580Ssteve.reinhardt@amd.com            sys->markWorkItem(cpuId) >= params->work_cpus_ckpt_count) {
5357914SBrad.Beckmann@amd.com            //
5367914SBrad.Beckmann@amd.com            // If active cpus equals checkpoint count, create checkpoint
5377914SBrad.Beckmann@amd.com            //
5388580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
5397914SBrad.Beckmann@amd.com        }
5407914SBrad.Beckmann@amd.com
5418580Ssteve.reinhardt@amd.com        if (params->work_end_ckpt_count != 0 &&
5428580Ssteve.reinhardt@amd.com            systemWorkEndCount == params->work_end_ckpt_count) {
5437914SBrad.Beckmann@amd.com            //
5447914SBrad.Beckmann@amd.com            // If total work items completed equals checkpoint count, create
5457914SBrad.Beckmann@amd.com            // checkpoint
5467914SBrad.Beckmann@amd.com            //
5478580Ssteve.reinhardt@amd.com            exitSimLoop("checkpoint");
5487914SBrad.Beckmann@amd.com        }
5497914SBrad.Beckmann@amd.com
5508580Ssteve.reinhardt@amd.com        if (params->work_end_exit_count != 0 &&
5518580Ssteve.reinhardt@amd.com            systemWorkEndCount == params->work_end_exit_count) {
5527914SBrad.Beckmann@amd.com            //
5537914SBrad.Beckmann@amd.com            // If total work items completed equals exit count, exit simulation
5547914SBrad.Beckmann@amd.com            //
5558580Ssteve.reinhardt@amd.com            exitSimLoop("work items exit count reached");
5567914SBrad.Beckmann@amd.com        }
5577914SBrad.Beckmann@amd.com    }
5587914SBrad.Beckmann@amd.com}
5597914SBrad.Beckmann@amd.com
5607811Ssteve.reinhardt@amd.com} // namespace PseudoInst
561