pseudo_inst.cc revision 2235
12SN/A/* 21762SN/A * Copyright (c) 2003-2006 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292665Ssaidi@eecs.umich.edu#include <errno.h> 302665Ssaidi@eecs.umich.edu#include <fcntl.h> 312SN/A#include <unistd.h> 322SN/A#include <cstdio> 332SN/A 342SN/A#include <string> 352SN/A 362655Sstever@eecs.umich.edu#include "sim/pseudo_inst.hh" 372655Sstever@eecs.umich.edu#include "arch/vtophys.hh" 382SN/A#include "cpu/base.hh" 392SN/A#include "cpu/sampler/sampler.hh" 401399SN/A#include "cpu/exec_context.hh" 411396SN/A#include "kern/kernel_stats.hh" 422SN/A#include "sim/param.hh" 432SN/A#include "sim/serialize.hh" 442667Sstever@eecs.umich.edu#include "sim/sim_exit.hh" 452SN/A#include "sim/stat_control.hh" 461310SN/A#include "sim/stats.hh" 472SN/A#include "sim/system.hh" 482SN/A#include "sim/debug.hh" 492SN/A#include "sim/vptr.hh" 502667Sstever@eecs.umich.edu 5156SN/Ausing namespace std; 52146SN/A 531388SN/Aextern Sampler *SampCPU; 5456SN/A 5556SN/Ausing namespace Stats; 561311SN/Ausing namespace TheISA; 57400SN/A 581717SN/Anamespace AlphaPseudo 591717SN/A{ 60146SN/A bool doStatisticsInsts; 61146SN/A bool doCheckpointInsts; 62146SN/A bool doQuiesce; 63146SN/A 6456SN/A void 6556SN/A arm(ExecContext *xc) 6656SN/A { 67695SN/A xc->getCpuPtr()->kernelStats->arm(); 68695SN/A } 691696SN/A 702SN/A void 712SN/A quiesce(ExecContext *xc) 722SN/A { 732SN/A if (!doQuiesce) 742SN/A return; 752SN/A 76329SN/A xc->suspend(); 772SN/A xc->getCpuPtr()->kernelStats->quiesce(); 782SN/A } 792SN/A 802SN/A void 812SN/A quiesceNs(ExecContext *xc, uint64_t ns) 822SN/A { 832SN/A if (!doQuiesce || ns == 0) 842SN/A return; 852SN/A 862SN/A Event *quiesceEvent = xc->getQuiesceEvent(); 872SN/A 882SN/A if (quiesceEvent->scheduled()) 89329SN/A quiesceEvent->reschedule(curTick + Clock::Int::ns * ns); 90329SN/A else 91329SN/A quiesceEvent->schedule(curTick + Clock::Int::ns * ns); 92329SN/A 93329SN/A xc->suspend(); 94329SN/A xc->getCpuPtr()->kernelStats->quiesce(); 95329SN/A } 962SN/A 972SN/A void 982SN/A quiesceCycles(ExecContext *xc, uint64_t cycles) 992SN/A { 1002SN/A if (!doQuiesce || cycles == 0) 1012SN/A return; 1022SN/A 1032SN/A Event *quiesceEvent = xc->getQuiesceEvent(); 104764SN/A 105764SN/A if (quiesceEvent->scheduled()) 106764SN/A quiesceEvent->reschedule(curTick + 107764SN/A xc->getCpuPtr()->cycles(cycles)); 108764SN/A else 109764SN/A quiesceEvent->schedule(curTick + 110764SN/A xc->getCpuPtr()->cycles(cycles)); 111764SN/A 112764SN/A xc->suspend(); 113764SN/A xc->getCpuPtr()->kernelStats->quiesce(); 114764SN/A } 115764SN/A 1162SN/A uint64_t 1172667Sstever@eecs.umich.edu quiesceTime(ExecContext *xc) 1182667Sstever@eecs.umich.edu { 1192667Sstever@eecs.umich.edu return (xc->readLastActivate() - xc->readLastSuspend()) / Clock::Int::ns; 1202667Sstever@eecs.umich.edu } 1212667Sstever@eecs.umich.edu 1222667Sstever@eecs.umich.edu void 1231388SN/A ivlb(ExecContext *xc) 1242667Sstever@eecs.umich.edu { 1252SN/A xc->getCpuPtr()->kernelStats->ivlb(); 1262667Sstever@eecs.umich.edu } 1272SN/A 1282667Sstever@eecs.umich.edu void 1292667Sstever@eecs.umich.edu ivle(ExecContext *xc) 1302667Sstever@eecs.umich.edu { 1312667Sstever@eecs.umich.edu } 1322667Sstever@eecs.umich.edu 1332SN/A void 1342667Sstever@eecs.umich.edu m5exit_old(ExecContext *xc) 1352667Sstever@eecs.umich.edu { 1362667Sstever@eecs.umich.edu SimExit(curTick, "m5_exit_old instruction encountered"); 1372SN/A } 1382667Sstever@eecs.umich.edu 1392667Sstever@eecs.umich.edu void 1402667Sstever@eecs.umich.edu m5exit(ExecContext *xc, Tick delay) 1412SN/A { 1422SN/A Tick when = curTick + delay * Clock::Int::ns; 1432667Sstever@eecs.umich.edu SimExit(when, "m5_exit instruction encountered"); 1442SN/A } 1452SN/A 1462SN/A void 1472SN/A resetstats(ExecContext *xc, Tick delay, Tick period) 1482667Sstever@eecs.umich.edu { 1492SN/A if (!doStatisticsInsts) 1502SN/A return; 1512SN/A 152329SN/A 153329SN/A Tick when = curTick + delay * Clock::Int::ns; 154329SN/A Tick repeat = period * Clock::Int::ns; 155764SN/A 1562SN/A using namespace Stats; 1572655Sstever@eecs.umich.edu SetupEvent(Reset, when, repeat); 1582667Sstever@eecs.umich.edu } 1592667Sstever@eecs.umich.edu 1602667Sstever@eecs.umich.edu void 1612667Sstever@eecs.umich.edu dumpstats(ExecContext *xc, Tick delay, Tick period) 1622667Sstever@eecs.umich.edu { 1632667Sstever@eecs.umich.edu if (!doStatisticsInsts) 1642667Sstever@eecs.umich.edu return; 1652667Sstever@eecs.umich.edu 1662667Sstever@eecs.umich.edu 1672667Sstever@eecs.umich.edu Tick when = curTick + delay * Clock::Int::ns; 1682667Sstever@eecs.umich.edu Tick repeat = period * Clock::Int::ns; 1692667Sstever@eecs.umich.edu 1702667Sstever@eecs.umich.edu using namespace Stats; 1712667Sstever@eecs.umich.edu SetupEvent(Dump, when, repeat); 1722667Sstever@eecs.umich.edu } 1732667Sstever@eecs.umich.edu 1742667Sstever@eecs.umich.edu void 1752667Sstever@eecs.umich.edu addsymbol(ExecContext *xc, Addr addr, Addr symbolAddr) 1762667Sstever@eecs.umich.edu { 1772667Sstever@eecs.umich.edu char symb[100]; 1782667Sstever@eecs.umich.edu CopyString(xc, symb, symbolAddr, 100); 1792667Sstever@eecs.umich.edu std::string symbol(symb); 1802667Sstever@eecs.umich.edu 1812667Sstever@eecs.umich.edu DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 1822667Sstever@eecs.umich.edu 1832667Sstever@eecs.umich.edu xc->getSystemPtr()->kernelSymtab->insert(addr,symbol); 1842667Sstever@eecs.umich.edu } 1852667Sstever@eecs.umich.edu 1862667Sstever@eecs.umich.edu void 1872667Sstever@eecs.umich.edu dumpresetstats(ExecContext *xc, Tick delay, Tick period) 1882667Sstever@eecs.umich.edu { 1892667Sstever@eecs.umich.edu if (!doStatisticsInsts) 1902667Sstever@eecs.umich.edu return; 1912667Sstever@eecs.umich.edu 1922667Sstever@eecs.umich.edu 1932667Sstever@eecs.umich.edu Tick when = curTick + delay * Clock::Int::ns; 1942667Sstever@eecs.umich.edu Tick repeat = period * Clock::Int::ns; 1952667Sstever@eecs.umich.edu 1962667Sstever@eecs.umich.edu using namespace Stats; 1972667Sstever@eecs.umich.edu SetupEvent(Dump|Reset, when, repeat); 1982667Sstever@eecs.umich.edu } 1992667Sstever@eecs.umich.edu 2002667Sstever@eecs.umich.edu void 2012667Sstever@eecs.umich.edu m5checkpoint(ExecContext *xc, Tick delay, Tick period) 2022667Sstever@eecs.umich.edu { 2032667Sstever@eecs.umich.edu if (!doCheckpointInsts) 2042667Sstever@eecs.umich.edu return; 2052667Sstever@eecs.umich.edu 2062667Sstever@eecs.umich.edu 2072667Sstever@eecs.umich.edu Tick when = curTick + delay * Clock::Int::ns; 2082667Sstever@eecs.umich.edu Tick repeat = period * Clock::Int::ns; 2092667Sstever@eecs.umich.edu 2102667Sstever@eecs.umich.edu Checkpoint::setup(when, repeat); 2112655Sstever@eecs.umich.edu } 2122655Sstever@eecs.umich.edu 2131311SN/A uint64_t 2142667Sstever@eecs.umich.edu readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset) 2152667Sstever@eecs.umich.edu { 2161703SN/A const string &file = xc->getCpuPtr()->system->params()->readfile; 2172667Sstever@eecs.umich.edu if (file.empty()) { 2182667Sstever@eecs.umich.edu return ULL(0); 2192667Sstever@eecs.umich.edu } 2202667Sstever@eecs.umich.edu 2212667Sstever@eecs.umich.edu uint64_t result = 0; 2222667Sstever@eecs.umich.edu 2232667Sstever@eecs.umich.edu int fd = ::open(file.c_str(), O_RDONLY, 0); 2242667Sstever@eecs.umich.edu if (fd < 0) 2251703SN/A panic("could not open file %s\n", file); 2262667Sstever@eecs.umich.edu 2272667Sstever@eecs.umich.edu if (::lseek(fd, offset, SEEK_SET) < 0) 2282667Sstever@eecs.umich.edu panic("could not seek: %s", strerror(errno)); 2292667Sstever@eecs.umich.edu 2302667Sstever@eecs.umich.edu char *buf = new char[len]; 2312SN/A char *p = buf; 2322667Sstever@eecs.umich.edu while (len > 0) { 2332667Sstever@eecs.umich.edu int bytes = ::read(fd, p, len); 2342667Sstever@eecs.umich.edu if (bytes <= 0) 2352667Sstever@eecs.umich.edu break; 2362667Sstever@eecs.umich.edu 2372667Sstever@eecs.umich.edu p += bytes; 2382667Sstever@eecs.umich.edu result += bytes; 2392667Sstever@eecs.umich.edu len -= bytes; 2402667Sstever@eecs.umich.edu } 2412667Sstever@eecs.umich.edu 2422667Sstever@eecs.umich.edu close(fd); 2432667Sstever@eecs.umich.edu CopyIn(xc, vaddr, buf, result); 2442667Sstever@eecs.umich.edu delete [] buf; 2452667Sstever@eecs.umich.edu return result; 2462667Sstever@eecs.umich.edu } 2472667Sstever@eecs.umich.edu 2482667Sstever@eecs.umich.edu class Context : public ParamContext 2492667Sstever@eecs.umich.edu { 2502655Sstever@eecs.umich.edu public: 2512667Sstever@eecs.umich.edu Context(const string §ion) : ParamContext(section) {} 2521388SN/A void checkParams(); 2532667Sstever@eecs.umich.edu }; 2542667Sstever@eecs.umich.edu 2552667Sstever@eecs.umich.edu Context context("pseudo_inst"); 2562667Sstever@eecs.umich.edu 2572667Sstever@eecs.umich.edu Param<bool> __quiesce(&context, "quiesce", 2582667Sstever@eecs.umich.edu "enable quiesce instructions", 2592655Sstever@eecs.umich.edu true); 2601388SN/A Param<bool> __statistics(&context, "statistics", 2612SN/A "enable statistics pseudo instructions", 2621388SN/A true); 2632655Sstever@eecs.umich.edu Param<bool> __checkpoint(&context, "checkpoint", 2642SN/A "enable checkpoint pseudo instructions", 2651388SN/A true); 2661388SN/A 2672SN/A void 2681310SN/A Context::checkParams() 2691388SN/A { 2701310SN/A doQuiesce = __quiesce; 2711310SN/A doStatisticsInsts = __statistics; 2721310SN/A doCheckpointInsts = __checkpoint; 2731388SN/A } 2741388SN/A 2751388SN/A void debugbreak(ExecContext *xc) 2761388SN/A { 2772667Sstever@eecs.umich.edu debug_break(); 2781104SN/A } 2792SN/A 2802499SN/A void switchcpu(ExecContext *xc) 2812499SN/A { 2822499SN/A if (SampCPU) 2832499SN/A SampCPU->switchCPUs(); 2841127SN/A } 2851127SN/A} 2861127SN/A