pseudo_inst.cc revision 5504
11060SN/A/*
29814Sandreas.hansson@arm.com * Copyright (c) 2003-2006 The Regents of The University of Michigan
39920Syasuko.eckert@amd.com * All rights reserved.
47944SGiacomo.Gabrielli@arm.com *
57944SGiacomo.Gabrielli@arm.com * Redistribution and use in source and binary forms, with or without
67944SGiacomo.Gabrielli@arm.com * modification, are permitted provided that the following conditions are
77944SGiacomo.Gabrielli@arm.com * met: redistributions of source code must retain the above copyright
87944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer;
97944SGiacomo.Gabrielli@arm.com * redistributions in binary form must reproduce the above copyright
107944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer in the
117944SGiacomo.Gabrielli@arm.com * documentation and/or other materials provided with the distribution;
127944SGiacomo.Gabrielli@arm.com * neither the name of the copyright holders nor the names of its
137944SGiacomo.Gabrielli@arm.com * contributors may be used to endorse or promote products derived from
147944SGiacomo.Gabrielli@arm.com * this software without specific prior written permission.
152702Sktlim@umich.edu *
166973Stjones1@inf.ed.ac.uk * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171060SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181060SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191060SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201060SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211060SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221060SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231060SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241060SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251060SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261060SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271060SN/A *
281060SN/A * Authors: Nathan Binkert
291060SN/A */
301060SN/A
311060SN/A#include <errno.h>
321060SN/A#include <fcntl.h>
331060SN/A#include <unistd.h>
341060SN/A
351060SN/A#include <fstream>
361060SN/A#include <string>
371060SN/A
381060SN/A#include "arch/vtophys.hh"
391060SN/A#include "base/annotate.hh"
401060SN/A#include "cpu/base.hh"
412665Ssaidi@eecs.umich.edu#include "cpu/thread_context.hh"
422665Ssaidi@eecs.umich.edu#include "cpu/quiesce_event.hh"
436973Stjones1@inf.ed.ac.uk#include "arch/kernel_stats.hh"
441060SN/A#include "sim/pseudo_inst.hh"
451060SN/A#include "sim/serialize.hh"
461464SN/A#include "sim/sim_exit.hh"
471464SN/A#include "sim/stat_control.hh"
481060SN/A#include "sim/stats.hh"
492731Sktlim@umich.edu#include "sim/system.hh"
502292SN/A#include "sim/debug.hh"
511464SN/A#include "sim/vptr.hh"
528733Sgeoffrey.blake@arm.com
531060SN/Ausing namespace std;
5410687SAndreas.Sandberg@ARM.com
557720Sgblack@eecs.umich.eduusing namespace Stats;
561060SN/Ausing namespace TheISA;
576658Snate@binkert.org
588887Sgeoffrey.blake@arm.comnamespace PseudoInst {
593770Sgblack@eecs.umich.edu
6010319SAndreas.Sandberg@ARM.comvoid
611464SN/Aarm(ThreadContext *tc)
621464SN/A{
632669Sktlim@umich.edu    if (tc->getKernelStats())
641060SN/A        tc->getKernelStats()->arm();
656973Stjones1@inf.ed.ac.uk}
662669Sktlim@umich.edu
677678Sgblack@eecs.umich.eduvoid
682292SN/Aquiesce(ThreadContext *tc)
691060SN/A{
701060SN/A    if (!tc->getCpuPtr()->params->do_quiesce)
711060SN/A        return;
721060SN/A
731060SN/A    DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name());
741060SN/A
751060SN/A    tc->suspend();
7610319SAndreas.Sandberg@ARM.com    if (tc->getKernelStats())
771060SN/A        tc->getKernelStats()->quiesce();
781060SN/A}
791060SN/A
802733Sktlim@umich.eduvoid
812733Sktlim@umich.eduquiesceNs(ThreadContext *tc, uint64_t ns)
821060SN/A{
832292SN/A    if (!tc->getCpuPtr()->params->do_quiesce || ns == 0)
842107SN/A        return;
851060SN/A
862292SN/A    EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
872292SN/A
888486Sgblack@eecs.umich.edu    Tick resume = curTick + Clock::Int::ns * ns;
892292SN/A
902292SN/A    quiesceEvent->reschedule(resume, true);
912292SN/A
922292SN/A    DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
931060SN/A            tc->getCpuPtr()->name(), ns, resume);
945543Ssaidi@eecs.umich.edu
958902Sandreas.hansson@arm.com    tc->suspend();
961060SN/A    if (tc->getKernelStats())
971060SN/A        tc->getKernelStats()->quiesce();
989046SAli.Saidi@ARM.com}
999046SAli.Saidi@ARM.com
1009046SAli.Saidi@ARM.comvoid
1019046SAli.Saidi@ARM.comquiesceCycles(ThreadContext *tc, uint64_t cycles)
1029046SAli.Saidi@ARM.com{
1039046SAli.Saidi@ARM.com    if (!tc->getCpuPtr()->params->do_quiesce || cycles == 0)
1049046SAli.Saidi@ARM.com        return;
1059046SAli.Saidi@ARM.com
1069046SAli.Saidi@ARM.com    EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1079046SAli.Saidi@ARM.com
1089046SAli.Saidi@ARM.com    Tick resume = curTick + tc->getCpuPtr()->ticks(cycles);
1099046SAli.Saidi@ARM.com
1109046SAli.Saidi@ARM.com    quiesceEvent->reschedule(resume, true);
1119046SAli.Saidi@ARM.com
1129046SAli.Saidi@ARM.com    DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
1139046SAli.Saidi@ARM.com            tc->getCpuPtr()->name(), cycles, resume);
1149046SAli.Saidi@ARM.com
1159046SAli.Saidi@ARM.com    tc->suspend();
1169046SAli.Saidi@ARM.com    if (tc->getKernelStats())
1179046SAli.Saidi@ARM.com        tc->getKernelStats()->quiesce();
1189046SAli.Saidi@ARM.com}
1199046SAli.Saidi@ARM.com
1209046SAli.Saidi@ARM.comuint64_t
1219046SAli.Saidi@ARM.comquiesceTime(ThreadContext *tc)
1229046SAli.Saidi@ARM.com{
1239046SAli.Saidi@ARM.com    return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns;
1249046SAli.Saidi@ARM.com}
1259046SAli.Saidi@ARM.com
1269046SAli.Saidi@ARM.comvoid
1279046SAli.Saidi@ARM.comm5exit_old(ThreadContext *tc)
1289046SAli.Saidi@ARM.com{
1299046SAli.Saidi@ARM.com    exitSimLoop("m5_exit_old instruction encountered");
1309046SAli.Saidi@ARM.com}
1319046SAli.Saidi@ARM.com
1329046SAli.Saidi@ARM.comvoid
1339046SAli.Saidi@ARM.comm5exit(ThreadContext *tc, Tick delay)
1349046SAli.Saidi@ARM.com{
1359046SAli.Saidi@ARM.com    Tick when = curTick + delay * Clock::Int::ns;
1369046SAli.Saidi@ARM.com    schedExitSimLoop("m5_exit instruction encountered", when);
1379046SAli.Saidi@ARM.com}
1389046SAli.Saidi@ARM.com
1399046SAli.Saidi@ARM.comvoid
1409046SAli.Saidi@ARM.comloadsymbol(ThreadContext *tc)
1419046SAli.Saidi@ARM.com{
1429046SAli.Saidi@ARM.com    const string &filename = tc->getCpuPtr()->system->params()->symbolfile;
1439046SAli.Saidi@ARM.com    if (filename.empty()) {
1449046SAli.Saidi@ARM.com        return;
1459046SAli.Saidi@ARM.com    }
1469046SAli.Saidi@ARM.com
1479046SAli.Saidi@ARM.com    std::string buffer;
1489046SAli.Saidi@ARM.com    ifstream file(filename.c_str());
1499046SAli.Saidi@ARM.com
1509046SAli.Saidi@ARM.com    if (!file)
1519046SAli.Saidi@ARM.com        fatal("file error: Can't open symbol table file %s\n", filename);
1529046SAli.Saidi@ARM.com
1539046SAli.Saidi@ARM.com    while (!file.eof()) {
1549046SAli.Saidi@ARM.com        getline(file, buffer);
1559046SAli.Saidi@ARM.com
1569046SAli.Saidi@ARM.com        if (buffer.empty())
1572292SN/A            continue;
15810417Sandreas.hansson@arm.com
1599046SAli.Saidi@ARM.com        int idx = buffer.find(' ');
1609046SAli.Saidi@ARM.com        if (idx == string::npos)
1619046SAli.Saidi@ARM.com            continue;
1629046SAli.Saidi@ARM.com
16310030SAli.Saidi@ARM.com        string address = "0x" + buffer.substr(0, idx);
16410030SAli.Saidi@ARM.com        eat_white(address);
1659046SAli.Saidi@ARM.com        if (address.empty())
1669046SAli.Saidi@ARM.com            continue;
1679046SAli.Saidi@ARM.com
1689046SAli.Saidi@ARM.com        // Skip over letter and space
1699046SAli.Saidi@ARM.com        string symbol = buffer.substr(idx + 3);
1709046SAli.Saidi@ARM.com        eat_white(symbol);
1719046SAli.Saidi@ARM.com        if (symbol.empty())
1729046SAli.Saidi@ARM.com            continue;
1739046SAli.Saidi@ARM.com
1749046SAli.Saidi@ARM.com        Addr addr;
1759046SAli.Saidi@ARM.com        if (!to_number(address, addr))
1769046SAli.Saidi@ARM.com            continue;
1779046SAli.Saidi@ARM.com
1789046SAli.Saidi@ARM.com        if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol))
1799046SAli.Saidi@ARM.com            continue;
1809046SAli.Saidi@ARM.com
1819046SAli.Saidi@ARM.com
1829046SAli.Saidi@ARM.com        DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
1839046SAli.Saidi@ARM.com    }
1849046SAli.Saidi@ARM.com    file.close();
1859046SAli.Saidi@ARM.com}
1869046SAli.Saidi@ARM.com
1879046SAli.Saidi@ARM.comvoid
1889046SAli.Saidi@ARM.comresetstats(ThreadContext *tc, Tick delay, Tick period)
1899046SAli.Saidi@ARM.com{
1909046SAli.Saidi@ARM.com    if (!tc->getCpuPtr()->params->do_statistics_insts)
1919046SAli.Saidi@ARM.com        return;
1929046SAli.Saidi@ARM.com
1939046SAli.Saidi@ARM.com
1949046SAli.Saidi@ARM.com    Tick when = curTick + delay * Clock::Int::ns;
1959046SAli.Saidi@ARM.com    Tick repeat = period * Clock::Int::ns;
1969046SAli.Saidi@ARM.com
1979046SAli.Saidi@ARM.com    Stats::StatEvent(false, true, when, repeat);
1989046SAli.Saidi@ARM.com}
1999046SAli.Saidi@ARM.com
2009046SAli.Saidi@ARM.comvoid
2019046SAli.Saidi@ARM.comdumpstats(ThreadContext *tc, Tick delay, Tick period)
2029046SAli.Saidi@ARM.com{
2039046SAli.Saidi@ARM.com    if (!tc->getCpuPtr()->params->do_statistics_insts)
2049046SAli.Saidi@ARM.com        return;
2059046SAli.Saidi@ARM.com
20610417Sandreas.hansson@arm.com
2071060SN/A    Tick when = curTick + delay * Clock::Int::ns;
2089046SAli.Saidi@ARM.com    Tick repeat = period * Clock::Int::ns;
2099046SAli.Saidi@ARM.com
2109046SAli.Saidi@ARM.com    Stats::StatEvent(true, false, when, repeat);
2119046SAli.Saidi@ARM.com}
2129046SAli.Saidi@ARM.com
2139046SAli.Saidi@ARM.comvoid
2149046SAli.Saidi@ARM.comaddsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
2159046SAli.Saidi@ARM.com{
2169046SAli.Saidi@ARM.com    char symb[100];
2179046SAli.Saidi@ARM.com    CopyStringOut(tc, symb, symbolAddr, 100);
2189046SAli.Saidi@ARM.com    std::string symbol(symb);
2199046SAli.Saidi@ARM.com
2209046SAli.Saidi@ARM.com    DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
2219046SAli.Saidi@ARM.com
2229046SAli.Saidi@ARM.com    tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
2239046SAli.Saidi@ARM.com}
2249046SAli.Saidi@ARM.com
2259046SAli.Saidi@ARM.comvoid
2269046SAli.Saidi@ARM.comanBegin(ThreadContext *tc, uint64_t cur)
2279046SAli.Saidi@ARM.com{
2289046SAli.Saidi@ARM.com    Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur &
2299046SAli.Saidi@ARM.com                              0xFFFFFFFF, 0,0);
2309046SAli.Saidi@ARM.com}
2319046SAli.Saidi@ARM.com
2329046SAli.Saidi@ARM.comvoid
2339046SAli.Saidi@ARM.comanWait(ThreadContext *tc, uint64_t cur, uint64_t wait)
2349046SAli.Saidi@ARM.com{
2359046SAli.Saidi@ARM.com    Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur &
2369046SAli.Saidi@ARM.com                              0xFFFFFFFF, wait >> 32, wait & 0xFFFFFFFF);
2379046SAli.Saidi@ARM.com}
2389046SAli.Saidi@ARM.com
2399046SAli.Saidi@ARM.com
2409046SAli.Saidi@ARM.comvoid
2419046SAli.Saidi@ARM.comdumpresetstats(ThreadContext *tc, Tick delay, Tick period)
2429046SAli.Saidi@ARM.com{
2439046SAli.Saidi@ARM.com    if (!tc->getCpuPtr()->params->do_statistics_insts)
2449046SAli.Saidi@ARM.com        return;
2459046SAli.Saidi@ARM.com
2469046SAli.Saidi@ARM.com
2479046SAli.Saidi@ARM.com    Tick when = curTick + delay * Clock::Int::ns;
2489046SAli.Saidi@ARM.com    Tick repeat = period * Clock::Int::ns;
2499046SAli.Saidi@ARM.com
2509046SAli.Saidi@ARM.com    Stats::StatEvent(true, true, when, repeat);
2519046SAli.Saidi@ARM.com}
2529046SAli.Saidi@ARM.com
2539046SAli.Saidi@ARM.comvoid
2549046SAli.Saidi@ARM.comm5checkpoint(ThreadContext *tc, Tick delay, Tick period)
2559046SAli.Saidi@ARM.com{
2569046SAli.Saidi@ARM.com    if (!tc->getCpuPtr()->params->do_checkpoint_insts)
2579046SAli.Saidi@ARM.com        return;
2589046SAli.Saidi@ARM.com
2599046SAli.Saidi@ARM.com    Tick when = curTick + delay * Clock::Int::ns;
2609046SAli.Saidi@ARM.com    Tick repeat = period * Clock::Int::ns;
2619046SAli.Saidi@ARM.com
2629046SAli.Saidi@ARM.com    schedExitSimLoop("checkpoint", when, repeat);
2639046SAli.Saidi@ARM.com}
2649046SAli.Saidi@ARM.com
2659046SAli.Saidi@ARM.comuint64_t
2669046SAli.Saidi@ARM.comreadfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset)
2679046SAli.Saidi@ARM.com{
2689046SAli.Saidi@ARM.com    const string &file = tc->getSystemPtr()->params()->readfile;
2699046SAli.Saidi@ARM.com    if (file.empty()) {
2709046SAli.Saidi@ARM.com        return ULL(0);
2719046SAli.Saidi@ARM.com    }
2729046SAli.Saidi@ARM.com
2739046SAli.Saidi@ARM.com    uint64_t result = 0;
2749046SAli.Saidi@ARM.com
2759046SAli.Saidi@ARM.com    int fd = ::open(file.c_str(), O_RDONLY, 0);
2769046SAli.Saidi@ARM.com    if (fd < 0)
2779046SAli.Saidi@ARM.com        panic("could not open file %s\n", file);
2789046SAli.Saidi@ARM.com
2799046SAli.Saidi@ARM.com    if (::lseek(fd, offset, SEEK_SET) < 0)
2809046SAli.Saidi@ARM.com        panic("could not seek: %s", strerror(errno));
2819046SAli.Saidi@ARM.com
2829046SAli.Saidi@ARM.com    char *buf = new char[len];
2839046SAli.Saidi@ARM.com    char *p = buf;
2849046SAli.Saidi@ARM.com    while (len > 0) {
2859046SAli.Saidi@ARM.com        int bytes = ::read(fd, p, len);
2869046SAli.Saidi@ARM.com        if (bytes <= 0)
2879046SAli.Saidi@ARM.com            break;
2889046SAli.Saidi@ARM.com
2899046SAli.Saidi@ARM.com        p += bytes;
2909046SAli.Saidi@ARM.com        result += bytes;
2911060SN/A        len -= bytes;
2921060SN/A    }
2931060SN/A
2941060SN/A    close(fd);
2951060SN/A    CopyIn(tc, vaddr, buf, result);
2961060SN/A    delete [] buf;
2975358Sgblack@eecs.umich.edu    return result;
2985358Sgblack@eecs.umich.edu}
2995358Sgblack@eecs.umich.edu
3005358Sgblack@eecs.umich.eduvoid
3015358Sgblack@eecs.umich.edudebugbreak(ThreadContext *tc)
3025358Sgblack@eecs.umich.edu{
3035358Sgblack@eecs.umich.edu    debug_break();
3045358Sgblack@eecs.umich.edu}
3055358Sgblack@eecs.umich.edu
3065358Sgblack@eecs.umich.eduvoid
3075358Sgblack@eecs.umich.eduswitchcpu(ThreadContext *tc)
3085358Sgblack@eecs.umich.edu{
3095358Sgblack@eecs.umich.edu    exitSimLoop("switchcpu");
3108444Sgblack@eecs.umich.edu}
3117520Sgblack@eecs.umich.edu
3128444Sgblack@eecs.umich.edu/* namespace PseudoInst */ }
3138444Sgblack@eecs.umich.edu