pseudo_inst.cc revision 8666
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 2010 ARM Limited 311308Santhony.gutierrez@amd.com * All rights reserved 411308Santhony.gutierrez@amd.com * 511308Santhony.gutierrez@amd.com * The license below extends only to copyright in the software and shall 611308Santhony.gutierrez@amd.com * not be construed as granting a license to any other intellectual 711308Santhony.gutierrez@amd.com * property including but not limited to intellectual property relating 811308Santhony.gutierrez@amd.com * to a hardware implementation of the functionality of the software 911308Santhony.gutierrez@amd.com * licensed hereunder. You may use the software subject to the license 1011308Santhony.gutierrez@amd.com * terms below provided that you ensure that this notice is replicated 1111308Santhony.gutierrez@amd.com * unmodified and in its entirety in all distributions of the software, 1211308Santhony.gutierrez@amd.com * modified or unmodified, in source code or in binary form. 1311308Santhony.gutierrez@amd.com * 1411308Santhony.gutierrez@amd.com * Copyright (c) 2011 Advanced Micro Devices, Inc. 1511308Santhony.gutierrez@amd.com * Copyright (c) 2003-2006 The Regents of The University of Michigan 1611308Santhony.gutierrez@amd.com * All rights reserved. 1711308Santhony.gutierrez@amd.com * 1811308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without 1911308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are 2011308Santhony.gutierrez@amd.com * met: redistributions of source code must retain the above copyright 2111308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer; 2211308Santhony.gutierrez@amd.com * redistributions in binary form must reproduce the above copyright 2311308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer in the 2411308Santhony.gutierrez@amd.com * documentation and/or other materials provided with the distribution; 2511308Santhony.gutierrez@amd.com * neither the name of the copyright holders nor the names of its 2611308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from 2711308Santhony.gutierrez@amd.com * this software without specific prior written permission. 2811308Santhony.gutierrez@amd.com * 2911308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3011308Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3111308Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3211308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3311308Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3411308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3511308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3611308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3711308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3811308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3911308Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4011308Santhony.gutierrez@amd.com * 4111308Santhony.gutierrez@amd.com * Authors: Nathan Binkert 4211308Santhony.gutierrez@amd.com */ 4311308Santhony.gutierrez@amd.com 4411308Santhony.gutierrez@amd.com#include <fcntl.h> 4511308Santhony.gutierrez@amd.com#include <unistd.h> 4611308Santhony.gutierrez@amd.com 4711308Santhony.gutierrez@amd.com#include <cerrno> 4811308Santhony.gutierrez@amd.com#include <fstream> 4911308Santhony.gutierrez@amd.com#include <string> 5011308Santhony.gutierrez@amd.com 5111308Santhony.gutierrez@amd.com#include "arch/vtophys.hh" 5211308Santhony.gutierrez@amd.com#include "base/debug.hh" 5311308Santhony.gutierrez@amd.com#include "config/full_system.hh" 5411308Santhony.gutierrez@amd.com#include "config/the_isa.hh" 5511308Santhony.gutierrez@amd.com#include "cpu/base.hh" 5611308Santhony.gutierrez@amd.com#include "cpu/quiesce_event.hh" 5711308Santhony.gutierrez@amd.com#include "cpu/thread_context.hh" 5811308Santhony.gutierrez@amd.com#include "debug/Loader.hh" 5911308Santhony.gutierrez@amd.com#include "debug/Quiesce.hh" 6011308Santhony.gutierrez@amd.com#include "debug/WorkItems.hh" 6111308Santhony.gutierrez@amd.com#include "params/BaseCPU.hh" 6211308Santhony.gutierrez@amd.com#include "sim/pseudo_inst.hh" 6311308Santhony.gutierrez@amd.com#include "sim/serialize.hh" 6411308Santhony.gutierrez@amd.com#include "sim/sim_events.hh" 6511308Santhony.gutierrez@amd.com#include "sim/sim_exit.hh" 6611308Santhony.gutierrez@amd.com#include "sim/stat_control.hh" 6711308Santhony.gutierrez@amd.com#include "sim/stats.hh" 6811308Santhony.gutierrez@amd.com#include "sim/system.hh" 6911308Santhony.gutierrez@amd.com 7011308Santhony.gutierrez@amd.com#if FULL_SYSTEM 7111308Santhony.gutierrez@amd.com#include "arch/kernel_stats.hh" 7211308Santhony.gutierrez@amd.com#include "sim/vptr.hh" 7311308Santhony.gutierrez@amd.com#endif 7411308Santhony.gutierrez@amd.com 7511308Santhony.gutierrez@amd.comusing namespace std; 7611308Santhony.gutierrez@amd.com 7711308Santhony.gutierrez@amd.comusing namespace Stats; 7811308Santhony.gutierrez@amd.comusing namespace TheISA; 7911308Santhony.gutierrez@amd.com 8011308Santhony.gutierrez@amd.comnamespace PseudoInst { 8111308Santhony.gutierrez@amd.com 8211308Santhony.gutierrez@amd.com#if FULL_SYSTEM 8311308Santhony.gutierrez@amd.com 8411308Santhony.gutierrez@amd.comvoid 8511308Santhony.gutierrez@amd.comarm(ThreadContext *tc) 8611308Santhony.gutierrez@amd.com{ 8711308Santhony.gutierrez@amd.com if (tc->getKernelStats()) 8811308Santhony.gutierrez@amd.com tc->getKernelStats()->arm(); 8911308Santhony.gutierrez@amd.com} 9011308Santhony.gutierrez@amd.com 9111308Santhony.gutierrez@amd.comvoid 9211308Santhony.gutierrez@amd.comquiesce(ThreadContext *tc) 9311308Santhony.gutierrez@amd.com{ 9411308Santhony.gutierrez@amd.com if (!tc->getCpuPtr()->params()->do_quiesce) 9511308Santhony.gutierrez@amd.com return; 9611308Santhony.gutierrez@amd.com 9711308Santhony.gutierrez@amd.com DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name()); 9811308Santhony.gutierrez@amd.com 9911308Santhony.gutierrez@amd.com tc->suspend(); 10011308Santhony.gutierrez@amd.com if (tc->getKernelStats()) 10111308Santhony.gutierrez@amd.com tc->getKernelStats()->quiesce(); 10211308Santhony.gutierrez@amd.com} 10311308Santhony.gutierrez@amd.com 10411308Santhony.gutierrez@amd.comvoid 10511308Santhony.gutierrez@amd.comquiesceSkip(ThreadContext *tc) 10611308Santhony.gutierrez@amd.com{ 10711308Santhony.gutierrez@amd.com BaseCPU *cpu = tc->getCpuPtr(); 10811308Santhony.gutierrez@amd.com 10911308Santhony.gutierrez@amd.com if (!cpu->params()->do_quiesce) 11011308Santhony.gutierrez@amd.com return; 11111308Santhony.gutierrez@amd.com 11211308Santhony.gutierrez@amd.com EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 11311308Santhony.gutierrez@amd.com 11411308Santhony.gutierrez@amd.com Tick resume = curTick() + 1; 11511308Santhony.gutierrez@amd.com 11611308Santhony.gutierrez@amd.com cpu->reschedule(quiesceEvent, resume, true); 11711308Santhony.gutierrez@amd.com 11811308Santhony.gutierrez@amd.com DPRINTF(Quiesce, "%s: quiesceSkip() until %d\n", 11911308Santhony.gutierrez@amd.com cpu->name(), resume); 12011308Santhony.gutierrez@amd.com 12111308Santhony.gutierrez@amd.com tc->suspend(); 12211308Santhony.gutierrez@amd.com if (tc->getKernelStats()) 12311308Santhony.gutierrez@amd.com tc->getKernelStats()->quiesce(); 12411308Santhony.gutierrez@amd.com} 12511308Santhony.gutierrez@amd.com 12611308Santhony.gutierrez@amd.comvoid 12711308Santhony.gutierrez@amd.comquiesceNs(ThreadContext *tc, uint64_t ns) 12811308Santhony.gutierrez@amd.com{ 12911308Santhony.gutierrez@amd.com BaseCPU *cpu = tc->getCpuPtr(); 13011308Santhony.gutierrez@amd.com 13111308Santhony.gutierrez@amd.com if (!cpu->params()->do_quiesce || ns == 0) 13211308Santhony.gutierrez@amd.com return; 13311308Santhony.gutierrez@amd.com 13411308Santhony.gutierrez@amd.com EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 13511308Santhony.gutierrez@amd.com 13611308Santhony.gutierrez@amd.com Tick resume = curTick() + SimClock::Int::ns * ns; 13711308Santhony.gutierrez@amd.com 13811308Santhony.gutierrez@amd.com cpu->reschedule(quiesceEvent, resume, true); 13911308Santhony.gutierrez@amd.com 14011308Santhony.gutierrez@amd.com DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n", 14111308Santhony.gutierrez@amd.com cpu->name(), ns, resume); 14211308Santhony.gutierrez@amd.com 14311308Santhony.gutierrez@amd.com tc->suspend(); 14411308Santhony.gutierrez@amd.com if (tc->getKernelStats()) 14511308Santhony.gutierrez@amd.com tc->getKernelStats()->quiesce(); 14611308Santhony.gutierrez@amd.com} 14711308Santhony.gutierrez@amd.com 14811308Santhony.gutierrez@amd.comvoid 14911308Santhony.gutierrez@amd.comquiesceCycles(ThreadContext *tc, uint64_t cycles) 15011308Santhony.gutierrez@amd.com{ 15111308Santhony.gutierrez@amd.com BaseCPU *cpu = tc->getCpuPtr(); 15211308Santhony.gutierrez@amd.com 15311308Santhony.gutierrez@amd.com if (!cpu->params()->do_quiesce || cycles == 0) 15411308Santhony.gutierrez@amd.com return; 15511308Santhony.gutierrez@amd.com 15611308Santhony.gutierrez@amd.com EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 15711308Santhony.gutierrez@amd.com 15811308Santhony.gutierrez@amd.com Tick resume = curTick() + cpu->ticks(cycles); 15911308Santhony.gutierrez@amd.com 16011308Santhony.gutierrez@amd.com cpu->reschedule(quiesceEvent, resume, true); 16111308Santhony.gutierrez@amd.com 16211308Santhony.gutierrez@amd.com DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n", 16311308Santhony.gutierrez@amd.com cpu->name(), cycles, resume); 16411308Santhony.gutierrez@amd.com 16511308Santhony.gutierrez@amd.com tc->suspend(); 16611308Santhony.gutierrez@amd.com if (tc->getKernelStats()) 16711308Santhony.gutierrez@amd.com tc->getKernelStats()->quiesce(); 16811308Santhony.gutierrez@amd.com} 16911308Santhony.gutierrez@amd.com 17011308Santhony.gutierrez@amd.comuint64_t 17111308Santhony.gutierrez@amd.comquiesceTime(ThreadContext *tc) 17211308Santhony.gutierrez@amd.com{ 17311308Santhony.gutierrez@amd.com return (tc->readLastActivate() - tc->readLastSuspend()) / 17411308Santhony.gutierrez@amd.com SimClock::Int::ns; 17511308Santhony.gutierrez@amd.com} 17611308Santhony.gutierrez@amd.com 17711308Santhony.gutierrez@amd.com#endif 17811308Santhony.gutierrez@amd.com 17911308Santhony.gutierrez@amd.comuint64_t 18011308Santhony.gutierrez@amd.comrpns(ThreadContext *tc) 18111308Santhony.gutierrez@amd.com{ 18211308Santhony.gutierrez@amd.com return curTick() / SimClock::Int::ns; 18311308Santhony.gutierrez@amd.com} 18411308Santhony.gutierrez@amd.com 18511308Santhony.gutierrez@amd.comvoid 18611308Santhony.gutierrez@amd.comwakeCPU(ThreadContext *tc, uint64_t cpuid) 18711308Santhony.gutierrez@amd.com{ 18811308Santhony.gutierrez@amd.com System *sys = tc->getSystemPtr(); 18911308Santhony.gutierrez@amd.com ThreadContext *other_tc = sys->threadContexts[cpuid]; 19011308Santhony.gutierrez@amd.com if (other_tc->status() == ThreadContext::Suspended) 19111308Santhony.gutierrez@amd.com other_tc->activate(); 19211308Santhony.gutierrez@amd.com} 19311308Santhony.gutierrez@amd.com 19411308Santhony.gutierrez@amd.comvoid 19511308Santhony.gutierrez@amd.comm5exit(ThreadContext *tc, Tick delay) 19611308Santhony.gutierrez@amd.com{ 19711308Santhony.gutierrez@amd.com Tick when = curTick() + delay * SimClock::Int::ns; 19811308Santhony.gutierrez@amd.com exitSimLoop("m5_exit instruction encountered", 0, when); 19911308Santhony.gutierrez@amd.com} 20011308Santhony.gutierrez@amd.com 20111308Santhony.gutierrez@amd.com#if FULL_SYSTEM 20211308Santhony.gutierrez@amd.com 20311308Santhony.gutierrez@amd.comvoid 20411308Santhony.gutierrez@amd.comloadsymbol(ThreadContext *tc) 20511308Santhony.gutierrez@amd.com{ 20611308Santhony.gutierrez@amd.com const string &filename = tc->getCpuPtr()->system->params()->symbolfile; 20711308Santhony.gutierrez@amd.com if (filename.empty()) { 20811308Santhony.gutierrez@amd.com return; 20911308Santhony.gutierrez@amd.com } 21011308Santhony.gutierrez@amd.com 21111308Santhony.gutierrez@amd.com std::string buffer; 21211308Santhony.gutierrez@amd.com ifstream file(filename.c_str()); 21311308Santhony.gutierrez@amd.com 21411308Santhony.gutierrez@amd.com if (!file) 21511308Santhony.gutierrez@amd.com fatal("file error: Can't open symbol table file %s\n", filename); 21611308Santhony.gutierrez@amd.com 21711308Santhony.gutierrez@amd.com while (!file.eof()) { 21811308Santhony.gutierrez@amd.com getline(file, buffer); 21911308Santhony.gutierrez@amd.com 22011308Santhony.gutierrez@amd.com if (buffer.empty()) 22111308Santhony.gutierrez@amd.com continue; 22211308Santhony.gutierrez@amd.com 22311308Santhony.gutierrez@amd.com string::size_type idx = buffer.find(' '); 22411308Santhony.gutierrez@amd.com if (idx == string::npos) 22511308Santhony.gutierrez@amd.com continue; 22611308Santhony.gutierrez@amd.com 22711308Santhony.gutierrez@amd.com string address = "0x" + buffer.substr(0, idx); 22811308Santhony.gutierrez@amd.com eat_white(address); 22911308Santhony.gutierrez@amd.com if (address.empty()) 23011308Santhony.gutierrez@amd.com continue; 23111308Santhony.gutierrez@amd.com 23211308Santhony.gutierrez@amd.com // Skip over letter and space 23311308Santhony.gutierrez@amd.com string symbol = buffer.substr(idx + 3); 23411308Santhony.gutierrez@amd.com eat_white(symbol); 23511308Santhony.gutierrez@amd.com if (symbol.empty()) 23611308Santhony.gutierrez@amd.com continue; 23711308Santhony.gutierrez@amd.com 23811308Santhony.gutierrez@amd.com Addr addr; 23911308Santhony.gutierrez@amd.com if (!to_number(address, addr)) 24011308Santhony.gutierrez@amd.com continue; 24111308Santhony.gutierrez@amd.com 24211308Santhony.gutierrez@amd.com if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) 24311308Santhony.gutierrez@amd.com continue; 24411308Santhony.gutierrez@amd.com 24511308Santhony.gutierrez@amd.com 24611308Santhony.gutierrez@amd.com DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 24711308Santhony.gutierrez@amd.com } 24811308Santhony.gutierrez@amd.com file.close(); 24911308Santhony.gutierrez@amd.com} 25011308Santhony.gutierrez@amd.com 25111308Santhony.gutierrez@amd.comvoid 25211308Santhony.gutierrez@amd.comaddsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) 25311308Santhony.gutierrez@amd.com{ 25411308Santhony.gutierrez@amd.com char symb[100]; 25511308Santhony.gutierrez@amd.com CopyStringOut(tc, symb, symbolAddr, 100); 25611308Santhony.gutierrez@amd.com std::string symbol(symb); 25711308Santhony.gutierrez@amd.com 25811308Santhony.gutierrez@amd.com DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 25911308Santhony.gutierrez@amd.com 26011308Santhony.gutierrez@amd.com tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); 26111308Santhony.gutierrez@amd.com debugSymbolTable->insert(addr,symbol); 26211308Santhony.gutierrez@amd.com} 26311308Santhony.gutierrez@amd.com 26411308Santhony.gutierrez@amd.comuint64_t 26511308Santhony.gutierrez@amd.cominitParam(ThreadContext *tc) 26611308Santhony.gutierrez@amd.com{ 26711308Santhony.gutierrez@amd.com return tc->getCpuPtr()->system->init_param; 26811308Santhony.gutierrez@amd.com} 26911308Santhony.gutierrez@amd.com 27011308Santhony.gutierrez@amd.com#endif 27111308Santhony.gutierrez@amd.com 27211308Santhony.gutierrez@amd.com 27311308Santhony.gutierrez@amd.comvoid 27411308Santhony.gutierrez@amd.comresetstats(ThreadContext *tc, Tick delay, Tick period) 27511308Santhony.gutierrez@amd.com{ 27611308Santhony.gutierrez@amd.com if (!tc->getCpuPtr()->params()->do_statistics_insts) 27711308Santhony.gutierrez@amd.com return; 27811308Santhony.gutierrez@amd.com 27911308Santhony.gutierrez@amd.com 28011308Santhony.gutierrez@amd.com Tick when = curTick() + delay * SimClock::Int::ns; 28111308Santhony.gutierrez@amd.com Tick repeat = period * SimClock::Int::ns; 28211308Santhony.gutierrez@amd.com 28311308Santhony.gutierrez@amd.com Stats::schedStatEvent(false, true, when, repeat); 28411308Santhony.gutierrez@amd.com} 28511308Santhony.gutierrez@amd.com 28611308Santhony.gutierrez@amd.comvoid 28711308Santhony.gutierrez@amd.comdumpstats(ThreadContext *tc, Tick delay, Tick period) 28811308Santhony.gutierrez@amd.com{ 28911308Santhony.gutierrez@amd.com if (!tc->getCpuPtr()->params()->do_statistics_insts) 29011308Santhony.gutierrez@amd.com return; 29111308Santhony.gutierrez@amd.com 29211308Santhony.gutierrez@amd.com 29311308Santhony.gutierrez@amd.com Tick when = curTick() + delay * SimClock::Int::ns; 294 Tick repeat = period * SimClock::Int::ns; 295 296 Stats::schedStatEvent(true, false, when, repeat); 297} 298 299void 300dumpresetstats(ThreadContext *tc, Tick delay, Tick period) 301{ 302 if (!tc->getCpuPtr()->params()->do_statistics_insts) 303 return; 304 305 306 Tick when = curTick() + delay * SimClock::Int::ns; 307 Tick repeat = period * SimClock::Int::ns; 308 309 Stats::schedStatEvent(true, true, when, repeat); 310} 311 312void 313m5checkpoint(ThreadContext *tc, Tick delay, Tick period) 314{ 315 if (!tc->getCpuPtr()->params()->do_checkpoint_insts) 316 return; 317 318 Tick when = curTick() + delay * SimClock::Int::ns; 319 Tick repeat = period * SimClock::Int::ns; 320 321 exitSimLoop("checkpoint", 0, when, repeat); 322} 323 324#if FULL_SYSTEM 325 326uint64_t 327readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) 328{ 329 const string &file = tc->getSystemPtr()->params()->readfile; 330 if (file.empty()) { 331 return ULL(0); 332 } 333 334 uint64_t result = 0; 335 336 int fd = ::open(file.c_str(), O_RDONLY, 0); 337 if (fd < 0) 338 panic("could not open file %s\n", file); 339 340 if (::lseek(fd, offset, SEEK_SET) < 0) 341 panic("could not seek: %s", strerror(errno)); 342 343 char *buf = new char[len]; 344 char *p = buf; 345 while (len > 0) { 346 int bytes = ::read(fd, p, len); 347 if (bytes <= 0) 348 break; 349 350 p += bytes; 351 result += bytes; 352 len -= bytes; 353 } 354 355 close(fd); 356 CopyIn(tc, vaddr, buf, result); 357 delete [] buf; 358 return result; 359} 360 361#endif 362 363void 364debugbreak(ThreadContext *tc) 365{ 366 Debug::breakpoint(); 367} 368 369void 370switchcpu(ThreadContext *tc) 371{ 372 exitSimLoop("switchcpu"); 373} 374 375// 376// This function is executed when annotated work items begin. Depending on 377// what the user specified at the command line, the simulation may exit and/or 378// take a checkpoint when a certain work item begins. 379// 380void 381workbegin(ThreadContext *tc, uint64_t workid, uint64_t threadid) 382{ 383 tc->getCpuPtr()->workItemBegin(); 384 System *sys = tc->getSystemPtr(); 385 const System::Params *params = sys->params(); 386 sys->workItemBegin(threadid, workid); 387 388 DPRINTF(WorkItems, "Work Begin workid: %d, threadid %d\n", workid, 389 threadid); 390 391 // 392 // If specified, determine if this is the specific work item the user 393 // identified 394 // 395 if (params->work_item_id == -1 || params->work_item_id == workid) { 396 397 uint64_t systemWorkBeginCount = sys->incWorkItemsBegin(); 398 int cpuId = tc->getCpuPtr()->cpuId(); 399 400 if (params->work_cpus_ckpt_count != 0 && 401 sys->markWorkItem(cpuId) >= params->work_cpus_ckpt_count) { 402 // 403 // If active cpus equals checkpoint count, create checkpoint 404 // 405 exitSimLoop("checkpoint"); 406 } 407 408 if (systemWorkBeginCount == params->work_begin_ckpt_count) { 409 // 410 // Note: the string specified as the cause of the exit event must 411 // exactly equal "checkpoint" inorder to create a checkpoint 412 // 413 exitSimLoop("checkpoint"); 414 } 415 416 if (systemWorkBeginCount == params->work_begin_exit_count) { 417 // 418 // If a certain number of work items started, exit simulation 419 // 420 exitSimLoop("work started count reach"); 421 } 422 423 if (cpuId == params->work_begin_cpu_id_exit) { 424 // 425 // If work started on the cpu id specified, exit simulation 426 // 427 exitSimLoop("work started on specific cpu"); 428 } 429 } 430} 431 432// 433// This function is executed when annotated work items end. Depending on 434// what the user specified at the command line, the simulation may exit and/or 435// take a checkpoint when a certain work item ends. 436// 437void 438workend(ThreadContext *tc, uint64_t workid, uint64_t threadid) 439{ 440 tc->getCpuPtr()->workItemEnd(); 441 System *sys = tc->getSystemPtr(); 442 const System::Params *params = sys->params(); 443 sys->workItemEnd(threadid, workid); 444 445 DPRINTF(WorkItems, "Work End workid: %d, threadid %d\n", workid, threadid); 446 447 // 448 // If specified, determine if this is the specific work item the user 449 // identified 450 // 451 if (params->work_item_id == -1 || params->work_item_id == workid) { 452 453 uint64_t systemWorkEndCount = sys->incWorkItemsEnd(); 454 int cpuId = tc->getCpuPtr()->cpuId(); 455 456 if (params->work_cpus_ckpt_count != 0 && 457 sys->markWorkItem(cpuId) >= params->work_cpus_ckpt_count) { 458 // 459 // If active cpus equals checkpoint count, create checkpoint 460 // 461 exitSimLoop("checkpoint"); 462 } 463 464 if (params->work_end_ckpt_count != 0 && 465 systemWorkEndCount == params->work_end_ckpt_count) { 466 // 467 // If total work items completed equals checkpoint count, create 468 // checkpoint 469 // 470 exitSimLoop("checkpoint"); 471 } 472 473 if (params->work_end_exit_count != 0 && 474 systemWorkEndCount == params->work_end_exit_count) { 475 // 476 // If total work items completed equals exit count, exit simulation 477 // 478 exitSimLoop("work items exit count reached"); 479 } 480 } 481} 482 483} // namespace PseudoInst 484