base.cc revision 3126:756092c6383c
1955SN/A/* 2955SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 310841Sandreas.sandberg@arm.com * All rights reserved. 49812Sandreas.hansson@arm.com * 59812Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 69812Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 79812Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 89812Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 99812Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 109812Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 119812Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 129812Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 139812Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 149812Sandreas.hansson@arm.com * this software without specific prior written permission. 157816Ssteve.reinhardt@amd.com * 165871Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171762SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27955SN/A * 28955SN/A * Authors: Steve Reinhardt 29955SN/A * Nathan Binkert 30955SN/A */ 31955SN/A 32955SN/A#include <iostream> 33955SN/A#include <string> 34955SN/A#include <sstream> 35955SN/A 36955SN/A#include "base/cprintf.hh" 37955SN/A#include "base/loader/symtab.hh" 38955SN/A#include "base/misc.hh" 39955SN/A#include "base/output.hh" 40955SN/A#include "cpu/base.hh" 41955SN/A#include "cpu/cpuevent.hh" 422665Ssaidi@eecs.umich.edu#include "cpu/thread_context.hh" 432665Ssaidi@eecs.umich.edu#include "cpu/profile.hh" 445863Snate@binkert.org#include "sim/param.hh" 45955SN/A#include "sim/process.hh" 46955SN/A#include "sim/sim_events.hh" 47955SN/A#include "sim/system.hh" 48955SN/A 49955SN/A#include "base/trace.hh" 508878Ssteve.reinhardt@amd.com 512632Sstever@eecs.umich.edu// Hack 528878Ssteve.reinhardt@amd.com#include "sim/stat_control.hh" 532632Sstever@eecs.umich.edu 54955SN/Ausing namespace std; 558878Ssteve.reinhardt@amd.com 562632Sstever@eecs.umich.eduvector<BaseCPU *> BaseCPU::cpuList; 572761Sstever@eecs.umich.edu 582632Sstever@eecs.umich.edu// This variable reflects the max number of threads in any CPU. Be 592632Sstever@eecs.umich.edu// careful to only use it once all the CPUs that you care about have 602632Sstever@eecs.umich.edu// been initialized 612761Sstever@eecs.umich.eduint maxThreadsPerCPU = 1; 622761Sstever@eecs.umich.edu 632761Sstever@eecs.umich.eduCPUProgressEvent::CPUProgressEvent(EventQueue *q, Tick ival, 648878Ssteve.reinhardt@amd.com BaseCPU *_cpu) 658878Ssteve.reinhardt@amd.com : Event(q, Event::Stat_Event_Pri), interval(ival), 662761Sstever@eecs.umich.edu lastNumInst(0), cpu(_cpu) 672761Sstever@eecs.umich.edu{ 682761Sstever@eecs.umich.edu if (interval) 692761Sstever@eecs.umich.edu schedule(curTick + interval); 702761Sstever@eecs.umich.edu} 718878Ssteve.reinhardt@amd.com 728878Ssteve.reinhardt@amd.comvoid 732632Sstever@eecs.umich.eduCPUProgressEvent::process() 742632Sstever@eecs.umich.edu{ 758878Ssteve.reinhardt@amd.com Counter temp = cpu->totalInstructions(); 768878Ssteve.reinhardt@amd.com#ifndef NDEBUG 772632Sstever@eecs.umich.edu double ipc = double(temp - lastNumInst) / (interval / cpu->cycles(1)); 78955SN/A 79955SN/A DPRINTFN("%s progress event, instructions committed: %lli, IPC: %0.8d\n", 80955SN/A cpu->name(), temp - lastNumInst, ipc); 815863Snate@binkert.org ipc = 0.0; 825863Snate@binkert.org#else 835863Snate@binkert.org cprintf("%lli: %s progress event, instructions committed: %lli\n", 845863Snate@binkert.org curTick, cpu->name(), temp - lastNumInst); 855863Snate@binkert.org#endif 865863Snate@binkert.org lastNumInst = temp; 875863Snate@binkert.org schedule(curTick + interval); 885863Snate@binkert.org} 895863Snate@binkert.org 905863Snate@binkert.orgconst char * 915863Snate@binkert.orgCPUProgressEvent::description() 928878Ssteve.reinhardt@amd.com{ 935863Snate@binkert.org return "CPU Progress event"; 945863Snate@binkert.org} 955863Snate@binkert.org 969812Sandreas.hansson@arm.com#if FULL_SYSTEM 979812Sandreas.hansson@arm.comBaseCPU::BaseCPU(Params *p) 985863Snate@binkert.org : MemObject(p->name), clock(p->clock), checkInterrupts(true), 999812Sandreas.hansson@arm.com params(p), number_of_threads(p->numberOfThreads), system(p->system) 1005863Snate@binkert.org#else 1015863Snate@binkert.orgBaseCPU::BaseCPU(Params *p) 1025863Snate@binkert.org : MemObject(p->name), clock(p->clock), params(p), 1039812Sandreas.hansson@arm.com number_of_threads(p->numberOfThreads), system(p->system) 1049812Sandreas.hansson@arm.com#endif 1055863Snate@binkert.org{ 1065863Snate@binkert.org// currentTick = curTick; 1078878Ssteve.reinhardt@amd.com DPRINTF(FullCPU, "BaseCPU: Creating object, mem address %#x.\n", this); 1085863Snate@binkert.org 1095863Snate@binkert.org // add self to global list of CPUs 1105863Snate@binkert.org cpuList.push_back(this); 1116654Snate@binkert.org 11210196SCurtis.Dunham@arm.com DPRINTF(FullCPU, "BaseCPU: CPU added to cpuList, mem address %#x.\n", 113955SN/A this); 1145396Ssaidi@eecs.umich.edu 1155863Snate@binkert.org if (number_of_threads > maxThreadsPerCPU) 1165863Snate@binkert.org maxThreadsPerCPU = number_of_threads; 1174202Sbinkertn@umich.edu 1185863Snate@binkert.org // allocate per-thread instruction-based event queues 1195863Snate@binkert.org comInstEventQueue = new EventQueue *[number_of_threads]; 1205863Snate@binkert.org for (int i = 0; i < number_of_threads; ++i) 1215863Snate@binkert.org comInstEventQueue[i] = new EventQueue("instruction-based event queue"); 122955SN/A 1236654Snate@binkert.org // 1245273Sstever@gmail.com // set up instruction-count-based termination events, if any 1255871Snate@binkert.org // 1265273Sstever@gmail.com if (p->max_insts_any_thread != 0) 1276655Snate@binkert.org for (int i = 0; i < number_of_threads; ++i) 1288878Ssteve.reinhardt@amd.com new SimLoopExitEvent(comInstEventQueue[i], p->max_insts_any_thread, 1296655Snate@binkert.org "a thread reached the max instruction count"); 1306655Snate@binkert.org 1319219Spower.jg@gmail.com if (p->max_insts_all_threads != 0) { 1326655Snate@binkert.org // allocate & initialize shared downcounter: each event will 1335871Snate@binkert.org // decrement this when triggered; simulation will terminate 1346654Snate@binkert.org // when counter reaches 0 1358947Sandreas.hansson@arm.com int *counter = new int; 1365396Ssaidi@eecs.umich.edu *counter = number_of_threads; 1378120Sgblack@eecs.umich.edu for (int i = 0; i < number_of_threads; ++i) 1388120Sgblack@eecs.umich.edu new CountedExitEvent(comInstEventQueue[i], 1398120Sgblack@eecs.umich.edu "all threads reached the max instruction count", 1408120Sgblack@eecs.umich.edu p->max_insts_all_threads, *counter); 1418120Sgblack@eecs.umich.edu } 1428120Sgblack@eecs.umich.edu 1438120Sgblack@eecs.umich.edu // allocate per-thread load-based event queues 1448120Sgblack@eecs.umich.edu comLoadEventQueue = new EventQueue *[number_of_threads]; 1458879Ssteve.reinhardt@amd.com for (int i = 0; i < number_of_threads; ++i) 1468879Ssteve.reinhardt@amd.com comLoadEventQueue[i] = new EventQueue("load-based event queue"); 1478879Ssteve.reinhardt@amd.com 1488879Ssteve.reinhardt@amd.com // 1498879Ssteve.reinhardt@amd.com // set up instruction-count-based termination events, if any 1508879Ssteve.reinhardt@amd.com // 1518879Ssteve.reinhardt@amd.com if (p->max_loads_any_thread != 0) 1528879Ssteve.reinhardt@amd.com for (int i = 0; i < number_of_threads; ++i) 1538879Ssteve.reinhardt@amd.com new SimLoopExitEvent(comLoadEventQueue[i], p->max_loads_any_thread, 1548879Ssteve.reinhardt@amd.com "a thread reached the max load count"); 1558879Ssteve.reinhardt@amd.com 1568879Ssteve.reinhardt@amd.com if (p->max_loads_all_threads != 0) { 1578879Ssteve.reinhardt@amd.com // allocate & initialize shared downcounter: each event will 1588120Sgblack@eecs.umich.edu // decrement this when triggered; simulation will terminate 1598120Sgblack@eecs.umich.edu // when counter reaches 0 1608120Sgblack@eecs.umich.edu int *counter = new int; 1618120Sgblack@eecs.umich.edu *counter = number_of_threads; 1628120Sgblack@eecs.umich.edu for (int i = 0; i < number_of_threads; ++i) 1638120Sgblack@eecs.umich.edu new CountedExitEvent(comLoadEventQueue[i], 1648120Sgblack@eecs.umich.edu "all threads reached the max load count", 1658120Sgblack@eecs.umich.edu p->max_loads_all_threads, *counter); 1668120Sgblack@eecs.umich.edu } 1678120Sgblack@eecs.umich.edu 1688120Sgblack@eecs.umich.edu#if FULL_SYSTEM 1698120Sgblack@eecs.umich.edu memset(interrupts, 0, sizeof(interrupts)); 1708120Sgblack@eecs.umich.edu intstatus = 0; 1718120Sgblack@eecs.umich.edu#endif 1728879Ssteve.reinhardt@amd.com 1738879Ssteve.reinhardt@amd.com functionTracingEnabled = false; 1748879Ssteve.reinhardt@amd.com if (p->functionTrace) { 1758879Ssteve.reinhardt@amd.com functionTraceStream = simout.find(csprintf("ftrace.%s", name())); 17610458Sandreas.hansson@arm.com currentFunctionStart = currentFunctionEnd = 0; 17710458Sandreas.hansson@arm.com functionEntryTick = p->functionTraceStart; 17810458Sandreas.hansson@arm.com 1798879Ssteve.reinhardt@amd.com if (p->functionTraceStart == 0) { 1808879Ssteve.reinhardt@amd.com functionTracingEnabled = true; 1818879Ssteve.reinhardt@amd.com } else { 1828879Ssteve.reinhardt@amd.com Event *e = 1839227Sandreas.hansson@arm.com new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this, 1849227Sandreas.hansson@arm.com true); 1858879Ssteve.reinhardt@amd.com e->schedule(p->functionTraceStart); 1868879Ssteve.reinhardt@amd.com } 1878879Ssteve.reinhardt@amd.com } 1888879Ssteve.reinhardt@amd.com#if FULL_SYSTEM 18910453SAndrew.Bardsley@arm.com profileEvent = NULL; 19010453SAndrew.Bardsley@arm.com if (params->profile) 19110453SAndrew.Bardsley@arm.com profileEvent = new ProfileEvent(this, params->profile); 19210456SCurtis.Dunham@arm.com#endif 19310456SCurtis.Dunham@arm.com} 19410456SCurtis.Dunham@arm.com 19510457Sandreas.hansson@arm.comBaseCPU::Params::Params() 19610457Sandreas.hansson@arm.com{ 1978120Sgblack@eecs.umich.edu#if FULL_SYSTEM 1988947Sandreas.hansson@arm.com profile = false; 1997816Ssteve.reinhardt@amd.com#endif 2005871Snate@binkert.org checker = NULL; 2015871Snate@binkert.org} 2026121Snate@binkert.org 2035871Snate@binkert.orgvoid 2045871Snate@binkert.orgBaseCPU::enableFunctionTrace() 2059926Sstan.czerniawski@arm.com{ 2069926Sstan.czerniawski@arm.com functionTracingEnabled = true; 2079119Sandreas.hansson@arm.com} 20810068Sandreas.hansson@arm.com 20910068Sandreas.hansson@arm.comBaseCPU::~BaseCPU() 210955SN/A{ 2119416SAndreas.Sandberg@ARM.com} 21211212Sjoseph.gross@amd.com 21311212Sjoseph.gross@amd.comvoid 21411212Sjoseph.gross@amd.comBaseCPU::init() 21511212Sjoseph.gross@amd.com{ 21611212Sjoseph.gross@amd.com if (!params->deferRegistration) 2179416SAndreas.Sandberg@ARM.com registerThreadContexts(); 2189416SAndreas.Sandberg@ARM.com} 2195871Snate@binkert.org 22010584Sandreas.hansson@arm.comvoid 2219416SAndreas.Sandberg@ARM.comBaseCPU::startup() 2229416SAndreas.Sandberg@ARM.com{ 2235871Snate@binkert.org#if FULL_SYSTEM 224955SN/A if (!params->deferRegistration && profileEvent) 22510671Sandreas.hansson@arm.com profileEvent->schedule(curTick); 22610671Sandreas.hansson@arm.com#endif 22710671Sandreas.hansson@arm.com 22810671Sandreas.hansson@arm.com if (params->progress_interval) { 2298881Smarc.orr@gmail.com new CPUProgressEvent(&mainEventQueue, params->progress_interval, 2306121Snate@binkert.org this); 2316121Snate@binkert.org } 2321533SN/A} 2339239Sandreas.hansson@arm.com 2349239Sandreas.hansson@arm.com 2359239Sandreas.hansson@arm.comvoid 2369239Sandreas.hansson@arm.comBaseCPU::regStats() 2379239Sandreas.hansson@arm.com{ 2389239Sandreas.hansson@arm.com using namespace Stats; 2399239Sandreas.hansson@arm.com 2409239Sandreas.hansson@arm.com numCycles 2419239Sandreas.hansson@arm.com .name(name() + ".numCycles") 2429239Sandreas.hansson@arm.com .desc("number of cpu cycles simulated") 2439239Sandreas.hansson@arm.com ; 2449239Sandreas.hansson@arm.com 2456655Snate@binkert.org int size = threadContexts.size(); 2466655Snate@binkert.org if (size > 1) { 2476655Snate@binkert.org for (int i = 0; i < size; ++i) { 2486655Snate@binkert.org stringstream namestr; 2495871Snate@binkert.org ccprintf(namestr, "%s.ctx%d", name(), i); 2505871Snate@binkert.org threadContexts[i]->regStats(namestr.str()); 2515863Snate@binkert.org } 2525871Snate@binkert.org } else if (size == 1) 2538878Ssteve.reinhardt@amd.com threadContexts[0]->regStats(name()); 2545871Snate@binkert.org 2555871Snate@binkert.org#if FULL_SYSTEM 2565871Snate@binkert.org#endif 2575863Snate@binkert.org} 2586121Snate@binkert.org 2595863Snate@binkert.org 2605871Snate@binkert.orgvoid 2618336Ssteve.reinhardt@amd.comBaseCPU::registerThreadContexts() 2628336Ssteve.reinhardt@amd.com{ 2638336Ssteve.reinhardt@amd.com for (int i = 0; i < threadContexts.size(); ++i) { 2648336Ssteve.reinhardt@amd.com ThreadContext *tc = threadContexts[i]; 2654678Snate@binkert.org 2668336Ssteve.reinhardt@amd.com#if FULL_SYSTEM 2678336Ssteve.reinhardt@amd.com int id = params->cpu_id; 2688336Ssteve.reinhardt@amd.com if (id != -1) 2694678Snate@binkert.org id += i; 2704678Snate@binkert.org 2714678Snate@binkert.org tc->setCpuId(system->registerThreadContext(tc, id)); 2724678Snate@binkert.org#else 2737827Snate@binkert.org tc->setCpuId(tc->getProcessPtr()->registerThreadContext(tc)); 2747827Snate@binkert.org#endif 2758336Ssteve.reinhardt@amd.com } 2764678Snate@binkert.org} 2778336Ssteve.reinhardt@amd.com 2788336Ssteve.reinhardt@amd.com 2798336Ssteve.reinhardt@amd.comvoid 2808336Ssteve.reinhardt@amd.comBaseCPU::switchOut() 2818336Ssteve.reinhardt@amd.com{ 2828336Ssteve.reinhardt@amd.com// panic("This CPU doesn't support sampling!"); 2835871Snate@binkert.org#if FULL_SYSTEM 2845871Snate@binkert.org if (profileEvent && profileEvent->scheduled()) 2858336Ssteve.reinhardt@amd.com profileEvent->deschedule(); 2868336Ssteve.reinhardt@amd.com#endif 2878336Ssteve.reinhardt@amd.com} 2888336Ssteve.reinhardt@amd.com 2898336Ssteve.reinhardt@amd.comvoid 2905871Snate@binkert.orgBaseCPU::takeOverFrom(BaseCPU *oldCPU) 2918336Ssteve.reinhardt@amd.com{ 2928336Ssteve.reinhardt@amd.com assert(threadContexts.size() == oldCPU->threadContexts.size()); 2938336Ssteve.reinhardt@amd.com 2948336Ssteve.reinhardt@amd.com for (int i = 0; i < threadContexts.size(); ++i) { 2958336Ssteve.reinhardt@amd.com ThreadContext *newTC = threadContexts[i]; 2964678Snate@binkert.org ThreadContext *oldTC = oldCPU->threadContexts[i]; 2975871Snate@binkert.org 2984678Snate@binkert.org newTC->takeOverFrom(oldTC); 2998336Ssteve.reinhardt@amd.com 3008336Ssteve.reinhardt@amd.com CpuEvent::replaceThreadContext(oldTC, newTC); 3018336Ssteve.reinhardt@amd.com 3028336Ssteve.reinhardt@amd.com assert(newTC->readCpuId() == oldTC->readCpuId()); 3038336Ssteve.reinhardt@amd.com#if FULL_SYSTEM 3048336Ssteve.reinhardt@amd.com system->replaceThreadContext(newTC, newTC->readCpuId()); 3058336Ssteve.reinhardt@amd.com#else 3068336Ssteve.reinhardt@amd.com assert(newTC->getProcessPtr() == oldTC->getProcessPtr()); 3078336Ssteve.reinhardt@amd.com newTC->getProcessPtr()->replaceThreadContext(newTC, newTC->readCpuId()); 3088336Ssteve.reinhardt@amd.com#endif 3098336Ssteve.reinhardt@amd.com 3108336Ssteve.reinhardt@amd.com// TheISA::compareXCs(oldXC, newXC); 3118336Ssteve.reinhardt@amd.com } 3128336Ssteve.reinhardt@amd.com 3138336Ssteve.reinhardt@amd.com#if FULL_SYSTEM 3148336Ssteve.reinhardt@amd.com for (int i = 0; i < TheISA::NumInterruptLevels; ++i) 3158336Ssteve.reinhardt@amd.com interrupts[i] = oldCPU->interrupts[i]; 3165871Snate@binkert.org intstatus = oldCPU->intstatus; 3176121Snate@binkert.org checkInterrupts = oldCPU->checkInterrupts; 318955SN/A 319955SN/A for (int i = 0; i < threadContexts.size(); ++i) 3202632Sstever@eecs.umich.edu threadContexts[i]->profileClear(); 3212632Sstever@eecs.umich.edu 322955SN/A // The Sampler must take care of this! 323955SN/A// if (profileEvent) 324955SN/A// profileEvent->schedule(curTick); 325955SN/A#endif 3268878Ssteve.reinhardt@amd.com} 327955SN/A 3282632Sstever@eecs.umich.edu 3292632Sstever@eecs.umich.edu#if FULL_SYSTEM 3302632Sstever@eecs.umich.eduBaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, int _interval) 3312632Sstever@eecs.umich.edu : Event(&mainEventQueue), cpu(_cpu), interval(_interval) 3322632Sstever@eecs.umich.edu{ } 3332632Sstever@eecs.umich.edu 3342632Sstever@eecs.umich.eduvoid 3358268Ssteve.reinhardt@amd.comBaseCPU::ProfileEvent::process() 3368268Ssteve.reinhardt@amd.com{ 3378268Ssteve.reinhardt@amd.com for (int i = 0, size = cpu->threadContexts.size(); i < size; ++i) { 3388268Ssteve.reinhardt@amd.com ThreadContext *tc = cpu->threadContexts[i]; 3398268Ssteve.reinhardt@amd.com tc->profileSample(); 3408268Ssteve.reinhardt@amd.com } 3418268Ssteve.reinhardt@amd.com 3422632Sstever@eecs.umich.edu schedule(curTick + interval); 3432632Sstever@eecs.umich.edu} 3442632Sstever@eecs.umich.edu 3452632Sstever@eecs.umich.eduvoid 3468268Ssteve.reinhardt@amd.comBaseCPU::post_interrupt(int int_num, int index) 3472632Sstever@eecs.umich.edu{ 3488268Ssteve.reinhardt@amd.com DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); 3498268Ssteve.reinhardt@amd.com 3508268Ssteve.reinhardt@amd.com if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) 3518268Ssteve.reinhardt@amd.com panic("int_num out of bounds\n"); 3523718Sstever@eecs.umich.edu 3532634Sstever@eecs.umich.edu if (index < 0 || index >= sizeof(uint64_t) * 8) 3542634Sstever@eecs.umich.edu panic("int_num out of bounds\n"); 3555863Snate@binkert.org 3562638Sstever@eecs.umich.edu checkInterrupts = true; 3578268Ssteve.reinhardt@amd.com interrupts[int_num] |= 1 << index; 3582632Sstever@eecs.umich.edu intstatus |= (ULL(1) << int_num); 3592632Sstever@eecs.umich.edu} 3602632Sstever@eecs.umich.edu 3612632Sstever@eecs.umich.eduvoid 3622632Sstever@eecs.umich.eduBaseCPU::clear_interrupt(int int_num, int index) 3631858SN/A{ 3643716Sstever@eecs.umich.edu DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); 3652638Sstever@eecs.umich.edu 3662638Sstever@eecs.umich.edu if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) 3672638Sstever@eecs.umich.edu panic("int_num out of bounds\n"); 3682638Sstever@eecs.umich.edu 3692638Sstever@eecs.umich.edu if (index < 0 || index >= sizeof(uint64_t) * 8) 3702638Sstever@eecs.umich.edu panic("int_num out of bounds\n"); 3712638Sstever@eecs.umich.edu 3725863Snate@binkert.org interrupts[int_num] &= ~(1 << index); 3735863Snate@binkert.org if (interrupts[int_num] == 0) 3745863Snate@binkert.org intstatus &= ~(ULL(1) << int_num); 375955SN/A} 3765341Sstever@gmail.com 3775341Sstever@gmail.comvoid 3785863Snate@binkert.orgBaseCPU::clear_interrupts() 3797756SAli.Saidi@ARM.com{ 3805341Sstever@gmail.com DPRINTF(Interrupt, "Interrupts all cleared\n"); 3816121Snate@binkert.org 3824494Ssaidi@eecs.umich.edu memset(interrupts, 0, sizeof(interrupts)); 3836121Snate@binkert.org intstatus = 0; 3841105SN/A} 3852667Sstever@eecs.umich.edu 3862667Sstever@eecs.umich.edu 3872667Sstever@eecs.umich.eduvoid 3882667Sstever@eecs.umich.eduBaseCPU::serialize(std::ostream &os) 3896121Snate@binkert.org{ 3902667Sstever@eecs.umich.edu SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); 3915341Sstever@gmail.com SERIALIZE_SCALAR(intstatus); 3925863Snate@binkert.org} 3935341Sstever@gmail.com 3945341Sstever@gmail.comvoid 3955341Sstever@gmail.comBaseCPU::unserialize(Checkpoint *cp, const std::string §ion) 3968120Sgblack@eecs.umich.edu{ 3975341Sstever@gmail.com UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); 3988120Sgblack@eecs.umich.edu UNSERIALIZE_SCALAR(intstatus); 3995341Sstever@gmail.com} 4008120Sgblack@eecs.umich.edu 4016121Snate@binkert.org#endif // FULL_SYSTEM 4026121Snate@binkert.org 4038980Ssteve.reinhardt@amd.comvoid 4049396Sandreas.hansson@arm.comBaseCPU::traceFunctionsInternal(Addr pc) 4055397Ssaidi@eecs.umich.edu{ 4065397Ssaidi@eecs.umich.edu if (!debugSymbolTable) 4077727SAli.Saidi@ARM.com return; 4088268Ssteve.reinhardt@amd.com 4096168Snate@binkert.org // if pc enters different function, print new function symbol and 4105341Sstever@gmail.com // update saved range. Otherwise do nothing. 4118120Sgblack@eecs.umich.edu if (pc < currentFunctionStart || pc >= currentFunctionEnd) { 4128120Sgblack@eecs.umich.edu string sym_str; 4138120Sgblack@eecs.umich.edu bool found = debugSymbolTable->findNearestSymbol(pc, sym_str, 4146814Sgblack@eecs.umich.edu currentFunctionStart, 4155863Snate@binkert.org currentFunctionEnd); 4168120Sgblack@eecs.umich.edu 4175341Sstever@gmail.com if (!found) { 4185863Snate@binkert.org // no symbol found: use addr as label 4198268Ssteve.reinhardt@amd.com sym_str = csprintf("0x%x", pc); 4206121Snate@binkert.org currentFunctionStart = pc; 4216121Snate@binkert.org currentFunctionEnd = pc + 1; 4228268Ssteve.reinhardt@amd.com } 4235742Snate@binkert.org 4245742Snate@binkert.org ccprintf(*functionTraceStream, " (%d)\n%d: %s", 4255341Sstever@gmail.com curTick - functionEntryTick, curTick, sym_str); 4265742Snate@binkert.org functionEntryTick = curTick; 4275742Snate@binkert.org } 4285341Sstever@gmail.com} 4296017Snate@binkert.org 4306121Snate@binkert.org 4316017Snate@binkert.orgDEFINE_SIM_OBJECT_CLASS_NAME("BaseCPU", BaseCPU) 4327816Ssteve.reinhardt@amd.com