base.cc revision 2
13569Sgblack@eecs.umich.edu/* 23569Sgblack@eecs.umich.edu * Copyright (c) 2003 The Regents of The University of Michigan 33569Sgblack@eecs.umich.edu * All rights reserved. 43569Sgblack@eecs.umich.edu * 53569Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 63569Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 73569Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 83569Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 93569Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 103569Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 113569Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 123569Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 133569Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 143569Sgblack@eecs.umich.edu * this software without specific prior written permission. 153569Sgblack@eecs.umich.edu * 163569Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173569Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183569Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193569Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203569Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213569Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223569Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233569Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243569Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253569Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263569Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273569Sgblack@eecs.umich.edu */ 283804Ssaidi@eecs.umich.edu 293569Sgblack@eecs.umich.edu#include <iostream> 303569Sgblack@eecs.umich.edu#include <iomanip> 313918Ssaidi@eecs.umich.edu#include <list> 323918Ssaidi@eecs.umich.edu#include <sstream> 333804Ssaidi@eecs.umich.edu#include <string> 343811Ssaidi@eecs.umich.edu 353569Sgblack@eecs.umich.edu#include <stdio.h> 363824Ssaidi@eecs.umich.edu#include <stdlib.h> 373811Ssaidi@eecs.umich.edu#include <math.h> 383811Ssaidi@eecs.umich.edu 393823Ssaidi@eecs.umich.edu#include "host.hh" 403823Ssaidi@eecs.umich.edu#include "cprintf.hh" 413823Ssaidi@eecs.umich.edu#include "misc.hh" 423569Sgblack@eecs.umich.edu#include "stats.hh" 434103Ssaidi@eecs.umich.edu#include "smt.hh" 443569Sgblack@eecs.umich.edu 453804Ssaidi@eecs.umich.edu#include "annotation.hh" 463804Ssaidi@eecs.umich.edu#include "exec_context.hh" 474088Sbinkertn@umich.edu#include "base_cpu.hh" 483569Sgblack@eecs.umich.edu#include "debug.hh" 493804Ssaidi@eecs.umich.edu#include "simple_cpu.hh" 503881Ssaidi@eecs.umich.edu#include "inifile.hh" 513881Ssaidi@eecs.umich.edu#include "mem_interface.hh" 523804Ssaidi@eecs.umich.edu#include "base_mem.hh" 533804Ssaidi@eecs.umich.edu#include "static_inst.hh" 543804Ssaidi@eecs.umich.edu 553804Ssaidi@eecs.umich.edu#ifdef FULL_SYSTEM 563569Sgblack@eecs.umich.edu#include "memory_control.hh" 573804Ssaidi@eecs.umich.edu#include "physical_memory.hh" 583918Ssaidi@eecs.umich.edu#include "alpha_memory.hh" 593881Ssaidi@eecs.umich.edu#include "system.hh" 603881Ssaidi@eecs.umich.edu#else // !FULL_SYSTEM 613881Ssaidi@eecs.umich.edu#include "functional_memory.hh" 623804Ssaidi@eecs.umich.edu#include "prog.hh" 633569Sgblack@eecs.umich.edu#include "eio.hh" 643804Ssaidi@eecs.umich.edu#endif // FULL_SYSTEM 653804Ssaidi@eecs.umich.edu 663804Ssaidi@eecs.umich.edu#include "exetrace.hh" 673804Ssaidi@eecs.umich.edu#include "trace.hh" 683881Ssaidi@eecs.umich.edu#include "sim_events.hh" 693804Ssaidi@eecs.umich.edu#include "pollevent.hh" 703804Ssaidi@eecs.umich.edu#include "sim_object.hh" 713804Ssaidi@eecs.umich.edu#include "sim_stats.hh" 723804Ssaidi@eecs.umich.edu 733804Ssaidi@eecs.umich.edu#include "range.hh" 743804Ssaidi@eecs.umich.edu#include "symtab.hh" 753804Ssaidi@eecs.umich.edu 763569Sgblack@eecs.umich.edu#ifdef FULL_SYSTEM 773569Sgblack@eecs.umich.edu#include "vtophys.hh" 783804Ssaidi@eecs.umich.edu#include "pciareg.h" 793804Ssaidi@eecs.umich.edu#include "remote_gdb.hh" 803826Ssaidi@eecs.umich.edu#include "alpha_access.h" 813804Ssaidi@eecs.umich.edu#endif 823569Sgblack@eecs.umich.edu 833569Sgblack@eecs.umich.edu 843804Ssaidi@eecs.umich.eduusing namespace std; 853826Ssaidi@eecs.umich.edu 863907Ssaidi@eecs.umich.eduSimpleCPU::CacheCompletionEvent::CacheCompletionEvent(SimpleCPU *_cpu) 873826Ssaidi@eecs.umich.edu : Event(&mainEventQueue), 883811Ssaidi@eecs.umich.edu cpu(_cpu) 893836Ssaidi@eecs.umich.edu{ 903915Ssaidi@eecs.umich.edu} 913907Ssaidi@eecs.umich.edu 923881Ssaidi@eecs.umich.eduvoid SimpleCPU::CacheCompletionEvent::process() 933881Ssaidi@eecs.umich.edu{ 943881Ssaidi@eecs.umich.edu cpu->processCacheCompletion(); 953881Ssaidi@eecs.umich.edu} 963907Ssaidi@eecs.umich.edu 973881Ssaidi@eecs.umich.educonst char * 983881Ssaidi@eecs.umich.eduSimpleCPU::CacheCompletionEvent::description() 993881Ssaidi@eecs.umich.edu{ 1003881Ssaidi@eecs.umich.edu return "cache completion event"; 1013881Ssaidi@eecs.umich.edu} 1023907Ssaidi@eecs.umich.edu 1033907Ssaidi@eecs.umich.edu#ifdef FULL_SYSTEM 1043907Ssaidi@eecs.umich.eduSimpleCPU::SimpleCPU(const string &_name, 1053907Ssaidi@eecs.umich.edu System *_system, 1063907Ssaidi@eecs.umich.edu Counter max_insts_any_thread, 1073907Ssaidi@eecs.umich.edu Counter max_insts_all_threads, 1083907Ssaidi@eecs.umich.edu AlphaItb *itb, AlphaDtb *dtb, 1093907Ssaidi@eecs.umich.edu FunctionalMemory *mem, 1103907Ssaidi@eecs.umich.edu MemInterface *icache_interface, 1113907Ssaidi@eecs.umich.edu MemInterface *dcache_interface, 1123907Ssaidi@eecs.umich.edu int cpu_id, Tick freq) 1133907Ssaidi@eecs.umich.edu : BaseCPU(_name, /* number_of_threads */ 1, 1143907Ssaidi@eecs.umich.edu max_insts_any_thread, max_insts_all_threads, 1153907Ssaidi@eecs.umich.edu _system, cpu_id, freq), 1163907Ssaidi@eecs.umich.edu#else 1173907Ssaidi@eecs.umich.eduSimpleCPU::SimpleCPU(const string &_name, Process *_process, 1183907Ssaidi@eecs.umich.edu Counter max_insts_any_thread, 1193907Ssaidi@eecs.umich.edu Counter max_insts_all_threads, 1203907Ssaidi@eecs.umich.edu MemInterface *icache_interface, 1213907Ssaidi@eecs.umich.edu MemInterface *dcache_interface) 1223907Ssaidi@eecs.umich.edu : BaseCPU(_name, /* number_of_threads */ 1, 1233907Ssaidi@eecs.umich.edu max_insts_any_thread, max_insts_all_threads), 1243907Ssaidi@eecs.umich.edu#endif 1253881Ssaidi@eecs.umich.edu tickEvent(this), xc(NULL), cacheCompletionEvent(this) 1263881Ssaidi@eecs.umich.edu{ 1273881Ssaidi@eecs.umich.edu#ifdef FULL_SYSTEM 1283881Ssaidi@eecs.umich.edu xc = new ExecContext(this, 0, system, itb, dtb, mem, cpu_id); 1293881Ssaidi@eecs.umich.edu 1303881Ssaidi@eecs.umich.edu _status = Running; 1313881Ssaidi@eecs.umich.edu if (cpu_id != 0) { 1323881Ssaidi@eecs.umich.edu 1333881Ssaidi@eecs.umich.edu xc->setStatus(ExecContext::Unallocated); 1343881Ssaidi@eecs.umich.edu 1353881Ssaidi@eecs.umich.edu //Open a GDB debug session on port (7000 + the cpu_id) 1363881Ssaidi@eecs.umich.edu (new GDBListener(new RemoteGDB(system, xc), 7000 + cpu_id))->listen(); 1373907Ssaidi@eecs.umich.edu 1383811Ssaidi@eecs.umich.edu AlphaISA::init(system->physmem, &xc->regs); 1393826Ssaidi@eecs.umich.edu 1403826Ssaidi@eecs.umich.edu fault = Reset_Fault; 1413826Ssaidi@eecs.umich.edu 1423826Ssaidi@eecs.umich.edu IntReg *ipr = xc->regs.ipr; 1433881Ssaidi@eecs.umich.edu ipr[TheISA::IPR_MCSR] = 0x6; 1443881Ssaidi@eecs.umich.edu 1453881Ssaidi@eecs.umich.edu AlphaISA::swap_palshadow(&xc->regs, true); 1463881Ssaidi@eecs.umich.edu 1473881Ssaidi@eecs.umich.edu xc->regs.pc = 1483881Ssaidi@eecs.umich.edu ipr[TheISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault]; 1493881Ssaidi@eecs.umich.edu xc->regs.npc = xc->regs.pc + sizeof(MachInst); 1503881Ssaidi@eecs.umich.edu 1513881Ssaidi@eecs.umich.edu _status = Idle; 1523881Ssaidi@eecs.umich.edu } 1533881Ssaidi@eecs.umich.edu else { 1543881Ssaidi@eecs.umich.edu system->initBootContext(xc); 1553881Ssaidi@eecs.umich.edu 1563881Ssaidi@eecs.umich.edu // Reset the system 1573881Ssaidi@eecs.umich.edu // 1583826Ssaidi@eecs.umich.edu AlphaISA::init(system->physmem, &xc->regs); 1593826Ssaidi@eecs.umich.edu 1603826Ssaidi@eecs.umich.edu fault = Reset_Fault; 1613826Ssaidi@eecs.umich.edu 1623826Ssaidi@eecs.umich.edu IntReg *ipr = xc->regs.ipr; 1633881Ssaidi@eecs.umich.edu ipr[TheISA::IPR_MCSR] = 0x6; 1643569Sgblack@eecs.umich.edu 1653569Sgblack@eecs.umich.edu AlphaISA::swap_palshadow(&xc->regs, true); 1663881Ssaidi@eecs.umich.edu 1673804Ssaidi@eecs.umich.edu xc->regs.pc = ipr[TheISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault]; 1683881Ssaidi@eecs.umich.edu xc->regs.npc = xc->regs.pc + sizeof(MachInst); 1693826Ssaidi@eecs.umich.edu 1703881Ssaidi@eecs.umich.edu _status = Running; 1713881Ssaidi@eecs.umich.edu tickEvent.schedule(0); 1723881Ssaidi@eecs.umich.edu } 1733907Ssaidi@eecs.umich.edu 1743907Ssaidi@eecs.umich.edu#else 1753929Ssaidi@eecs.umich.edu xc = new ExecContext(this, /* thread_num */ 0, _process, /* asid */ 0); 1763929Ssaidi@eecs.umich.edu fault = No_Fault; 1773907Ssaidi@eecs.umich.edu if (xc->status() == ExecContext::Active) { 1783907Ssaidi@eecs.umich.edu _status = Running; 1793804Ssaidi@eecs.umich.edu tickEvent.schedule(0); 1803804Ssaidi@eecs.umich.edu } else 1813881Ssaidi@eecs.umich.edu _status = Idle; 1823804Ssaidi@eecs.umich.edu#endif // !FULL_SYSTEM 1833804Ssaidi@eecs.umich.edu 1843804Ssaidi@eecs.umich.edu icacheInterface = icache_interface; 1853804Ssaidi@eecs.umich.edu dcacheInterface = dcache_interface; 1863804Ssaidi@eecs.umich.edu 1873804Ssaidi@eecs.umich.edu memReq = new MemReq(); 1883804Ssaidi@eecs.umich.edu memReq->xc = xc; 1893569Sgblack@eecs.umich.edu memReq->asid = 0; 1903569Sgblack@eecs.umich.edu 1913569Sgblack@eecs.umich.edu numInst = 0; 1923863Ssaidi@eecs.umich.edu last_idle = 0; 1933863Ssaidi@eecs.umich.edu lastIcacheStall = 0; 1943804Ssaidi@eecs.umich.edu lastDcacheStall = 0; 1953804Ssaidi@eecs.umich.edu 1963804Ssaidi@eecs.umich.edu contexts.push_back(xc); 1973804Ssaidi@eecs.umich.edu} 1983804Ssaidi@eecs.umich.edu 1993804Ssaidi@eecs.umich.eduSimpleCPU::~SimpleCPU() 2003804Ssaidi@eecs.umich.edu{ 2013804Ssaidi@eecs.umich.edu} 2023804Ssaidi@eecs.umich.edu 2033569Sgblack@eecs.umich.eduvoid 2043804Ssaidi@eecs.umich.eduSimpleCPU::regStats() 2053804Ssaidi@eecs.umich.edu{ 2063804Ssaidi@eecs.umich.edu BaseCPU::regStats(); 2074070Ssaidi@eecs.umich.edu 2084070Ssaidi@eecs.umich.edu numInsts 2093804Ssaidi@eecs.umich.edu .name(name() + ".num_insts") 2103804Ssaidi@eecs.umich.edu .desc("Number of instructions executed") 2113804Ssaidi@eecs.umich.edu ; 2123804Ssaidi@eecs.umich.edu 2133804Ssaidi@eecs.umich.edu numMemRefs 2143811Ssaidi@eecs.umich.edu .name(name() + ".num_refs") 2153811Ssaidi@eecs.umich.edu .desc("Number of memory references") 2163804Ssaidi@eecs.umich.edu ; 2173804Ssaidi@eecs.umich.edu 2183863Ssaidi@eecs.umich.edu idleCycles 2193804Ssaidi@eecs.umich.edu .name(name() + ".idle_cycles") 2203804Ssaidi@eecs.umich.edu .desc("Number of idle cycles") 2213804Ssaidi@eecs.umich.edu ; 2223804Ssaidi@eecs.umich.edu 2233804Ssaidi@eecs.umich.edu idleFraction 2243804Ssaidi@eecs.umich.edu .name(name() + ".idle_fraction") 2253804Ssaidi@eecs.umich.edu .desc("Percentage of idle cycles") 2263811Ssaidi@eecs.umich.edu ; 2273804Ssaidi@eecs.umich.edu 2283804Ssaidi@eecs.umich.edu icacheStallCycles 2293804Ssaidi@eecs.umich.edu .name(name() + ".icache_stall_cycles") 2303804Ssaidi@eecs.umich.edu .desc("ICache total stall cycles") 2313804Ssaidi@eecs.umich.edu .prereq(icacheStallCycles) 2323826Ssaidi@eecs.umich.edu ; 2333826Ssaidi@eecs.umich.edu 2344070Ssaidi@eecs.umich.edu dcacheStallCycles 2354070Ssaidi@eecs.umich.edu .name(name() + ".dcache_stall_cycles") 2364070Ssaidi@eecs.umich.edu .desc("DCache total stall cycles") 2374070Ssaidi@eecs.umich.edu .prereq(dcacheStallCycles) 2383804Ssaidi@eecs.umich.edu ; 2393804Ssaidi@eecs.umich.edu 2403804Ssaidi@eecs.umich.edu idleFraction = idleCycles / simTicks; 2413804Ssaidi@eecs.umich.edu 2423804Ssaidi@eecs.umich.edu numInsts = Statistics::scalar(numInst); 2433804Ssaidi@eecs.umich.edu simInsts += numInsts; 2443804Ssaidi@eecs.umich.edu} 2453804Ssaidi@eecs.umich.edu 2463804Ssaidi@eecs.umich.eduvoid 2473804Ssaidi@eecs.umich.eduSimpleCPU::serialize() 2483804Ssaidi@eecs.umich.edu{ 2493804Ssaidi@eecs.umich.edu nameOut(); 2503826Ssaidi@eecs.umich.edu 2513826Ssaidi@eecs.umich.edu#ifdef FULL_SYSTEM 2523826Ssaidi@eecs.umich.edu#if 0 2533863Ssaidi@eecs.umich.edu // do we need this anymore?? egh 2543826Ssaidi@eecs.umich.edu childOut("itb", xc->itb); 2553826Ssaidi@eecs.umich.edu childOut("dtb", xc->dtb); 2563826Ssaidi@eecs.umich.edu childOut("physmem", physmem); 2573826Ssaidi@eecs.umich.edu#endif 2583826Ssaidi@eecs.umich.edu#endif 2593826Ssaidi@eecs.umich.edu 2603826Ssaidi@eecs.umich.edu for (int i = 0; i < NumIntRegs; i++) { 2613826Ssaidi@eecs.umich.edu stringstream buf; 2623826Ssaidi@eecs.umich.edu ccprintf(buf, "R%02d", i); 2633804Ssaidi@eecs.umich.edu paramOut(buf.str(), xc->regs.intRegFile[i]); 2643804Ssaidi@eecs.umich.edu } 2653804Ssaidi@eecs.umich.edu for (int i = 0; i < NumFloatRegs; i++) { 2663804Ssaidi@eecs.umich.edu stringstream buf; 2673804Ssaidi@eecs.umich.edu ccprintf(buf, "F%02d", i); 2683804Ssaidi@eecs.umich.edu paramOut(buf.str(), xc->regs.floatRegFile.d[i]); 2693804Ssaidi@eecs.umich.edu } 2703863Ssaidi@eecs.umich.edu // CPUTraitsType::serializeSpecialRegs(getProxy(), xc->regs); 2713863Ssaidi@eecs.umich.edu} 2723863Ssaidi@eecs.umich.edu 2733836Ssaidi@eecs.umich.eduvoid 2743836Ssaidi@eecs.umich.eduSimpleCPU::unserialize(IniFile &db, const string &category, ConfigNode *node) 2753804Ssaidi@eecs.umich.edu{ 2763804Ssaidi@eecs.umich.edu string data; 2773863Ssaidi@eecs.umich.edu 2783804Ssaidi@eecs.umich.edu for (int i = 0; i < NumIntRegs; i++) { 2793804Ssaidi@eecs.umich.edu stringstream buf; 2803804Ssaidi@eecs.umich.edu ccprintf(buf, "R%02d", i); 2813804Ssaidi@eecs.umich.edu db.findDefault(category, buf.str(), data); 2823804Ssaidi@eecs.umich.edu to_number(data,xc->regs.intRegFile[i]); 2833804Ssaidi@eecs.umich.edu } 2843804Ssaidi@eecs.umich.edu for (int i = 0; i < NumFloatRegs; i++) { 2853863Ssaidi@eecs.umich.edu stringstream buf; 2863804Ssaidi@eecs.umich.edu ccprintf(buf, "F%02d", i); 2873804Ssaidi@eecs.umich.edu db.findDefault(category, buf.str(), data); 2883804Ssaidi@eecs.umich.edu xc->regs.floatRegFile.d[i] = strtod(data.c_str(),NULL); 2893804Ssaidi@eecs.umich.edu } 2903804Ssaidi@eecs.umich.edu 2913881Ssaidi@eecs.umich.edu // Read in Special registers 2923804Ssaidi@eecs.umich.edu 2933804Ssaidi@eecs.umich.edu // CPUTraitsType::unserializeSpecialRegs(db,category,node,xc->regs); 2943804Ssaidi@eecs.umich.edu} 2953804Ssaidi@eecs.umich.edu 2963804Ssaidi@eecs.umich.eduvoid 2973804Ssaidi@eecs.umich.educhange_thread_state(int thread_number, int activate, int priority) 2983804Ssaidi@eecs.umich.edu{ 2993804Ssaidi@eecs.umich.edu} 3003863Ssaidi@eecs.umich.edu 3013863Ssaidi@eecs.umich.edu// precise architected memory state accessor macros 3023836Ssaidi@eecs.umich.edutemplate <class T> 3033804Ssaidi@eecs.umich.eduFault 3043804Ssaidi@eecs.umich.eduSimpleCPU::read(Addr addr, T& data, unsigned flags) 3053804Ssaidi@eecs.umich.edu{ 3063881Ssaidi@eecs.umich.edu memReq->reset(addr, sizeof(T), flags); 3073881Ssaidi@eecs.umich.edu 3083881Ssaidi@eecs.umich.edu // translate to physical address 3093804Ssaidi@eecs.umich.edu Fault fault = xc->translateDataReadReq(memReq); 3103804Ssaidi@eecs.umich.edu 3113804Ssaidi@eecs.umich.edu // do functional access 3123804Ssaidi@eecs.umich.edu if (fault == No_Fault) 3133804Ssaidi@eecs.umich.edu fault = xc->read(memReq, data); 3143804Ssaidi@eecs.umich.edu 3153804Ssaidi@eecs.umich.edu if (traceData) { 3163804Ssaidi@eecs.umich.edu traceData->setAddr(addr); 3173804Ssaidi@eecs.umich.edu if (fault == No_Fault) 3183804Ssaidi@eecs.umich.edu traceData->setData(data); 3193804Ssaidi@eecs.umich.edu } 3203804Ssaidi@eecs.umich.edu 3213804Ssaidi@eecs.umich.edu // if we have a cache, do cache access too 3223804Ssaidi@eecs.umich.edu if (fault == No_Fault && dcacheInterface) { 3233863Ssaidi@eecs.umich.edu memReq->cmd = Read; 3243836Ssaidi@eecs.umich.edu memReq->completionEvent = NULL; 3253804Ssaidi@eecs.umich.edu memReq->time = curTick; 3263804Ssaidi@eecs.umich.edu memReq->flags &= ~UNCACHEABLE; 3273881Ssaidi@eecs.umich.edu MemAccessResult result = dcacheInterface->access(memReq); 3283881Ssaidi@eecs.umich.edu 3293881Ssaidi@eecs.umich.edu // Ugly hack to get an event scheduled *only* if the access is 3303804Ssaidi@eecs.umich.edu // a miss. We really should add first-class support for this 3313804Ssaidi@eecs.umich.edu // at some point. 3323804Ssaidi@eecs.umich.edu if (result != MA_HIT && dcacheInterface->doEvents) { 3333804Ssaidi@eecs.umich.edu memReq->completionEvent = &cacheCompletionEvent; 3343804Ssaidi@eecs.umich.edu setStatus(DcacheMissStall); 3353804Ssaidi@eecs.umich.edu } 3363804Ssaidi@eecs.umich.edu } 3373804Ssaidi@eecs.umich.edu 3383804Ssaidi@eecs.umich.edu return fault; 3393804Ssaidi@eecs.umich.edu} 3403804Ssaidi@eecs.umich.edu 3413804Ssaidi@eecs.umich.edu#ifndef DOXYGEN_SHOULD_SKIP_THIS 3423804Ssaidi@eecs.umich.edu 3433804Ssaidi@eecs.umich.edutemplate 3443836Ssaidi@eecs.umich.eduFault 3453836Ssaidi@eecs.umich.eduSimpleCPU::read(Addr addr, uint64_t& data, unsigned flags); 3463881Ssaidi@eecs.umich.edu 3473907Ssaidi@eecs.umich.edutemplate 3483804Ssaidi@eecs.umich.eduFault 3493881Ssaidi@eecs.umich.eduSimpleCPU::read(Addr addr, uint32_t& data, unsigned flags); 3503881Ssaidi@eecs.umich.edu 3513804Ssaidi@eecs.umich.edutemplate 3523907Ssaidi@eecs.umich.eduFault 3533804Ssaidi@eecs.umich.eduSimpleCPU::read(Addr addr, uint16_t& data, unsigned flags); 3543804Ssaidi@eecs.umich.edu 3553804Ssaidi@eecs.umich.edutemplate 3563804Ssaidi@eecs.umich.eduFault 3573804Ssaidi@eecs.umich.eduSimpleCPU::read(Addr addr, uint8_t& data, unsigned flags); 3583804Ssaidi@eecs.umich.edu 3593881Ssaidi@eecs.umich.edu#endif //DOXYGEN_SHOULD_SKIP_THIS 3603881Ssaidi@eecs.umich.edu 3613881Ssaidi@eecs.umich.edutemplate<> 3623804Ssaidi@eecs.umich.eduFault 3633881Ssaidi@eecs.umich.eduSimpleCPU::read(Addr addr, double& data, unsigned flags) 3643881Ssaidi@eecs.umich.edu{ 3653881Ssaidi@eecs.umich.edu return read(addr, *(uint64_t*)&data, flags); 3663881Ssaidi@eecs.umich.edu} 3673804Ssaidi@eecs.umich.edu 3683804Ssaidi@eecs.umich.edutemplate<> 3693804Ssaidi@eecs.umich.eduFault 3703804Ssaidi@eecs.umich.eduSimpleCPU::read(Addr addr, float& data, unsigned flags) 3713804Ssaidi@eecs.umich.edu{ 3723804Ssaidi@eecs.umich.edu return read(addr, *(uint32_t*)&data, flags); 3733881Ssaidi@eecs.umich.edu} 3743881Ssaidi@eecs.umich.edu 3753804Ssaidi@eecs.umich.edu 3763881Ssaidi@eecs.umich.edutemplate<> 3773881Ssaidi@eecs.umich.eduFault 3783881Ssaidi@eecs.umich.eduSimpleCPU::read(Addr addr, int32_t& data, unsigned flags) 3793804Ssaidi@eecs.umich.edu{ 3803804Ssaidi@eecs.umich.edu return read(addr, (uint32_t&)data, flags); 3813804Ssaidi@eecs.umich.edu} 3823804Ssaidi@eecs.umich.edu 3833804Ssaidi@eecs.umich.edu 3843804Ssaidi@eecs.umich.edutemplate <class T> 3853804Ssaidi@eecs.umich.eduFault 3863804Ssaidi@eecs.umich.eduSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) 3873804Ssaidi@eecs.umich.edu{ 3883804Ssaidi@eecs.umich.edu if (traceData) { 3893804Ssaidi@eecs.umich.edu traceData->setAddr(addr); 3903804Ssaidi@eecs.umich.edu traceData->setData(data); 3913804Ssaidi@eecs.umich.edu } 3923804Ssaidi@eecs.umich.edu 3933804Ssaidi@eecs.umich.edu memReq->reset(addr, sizeof(T), flags); 3943804Ssaidi@eecs.umich.edu 3953804Ssaidi@eecs.umich.edu // translate to physical address 3963804Ssaidi@eecs.umich.edu Fault fault = xc->translateDataWriteReq(memReq); 3973804Ssaidi@eecs.umich.edu 3983804Ssaidi@eecs.umich.edu // do functional access 3994172Ssaidi@eecs.umich.edu if (fault == No_Fault) 4003804Ssaidi@eecs.umich.edu fault = xc->write(memReq, data); 4013804Ssaidi@eecs.umich.edu 4023804Ssaidi@eecs.umich.edu if (fault == No_Fault && dcacheInterface) { 4033804Ssaidi@eecs.umich.edu memReq->cmd = Write; 4043804Ssaidi@eecs.umich.edu memReq->data = (uint8_t *)&data; 4053804Ssaidi@eecs.umich.edu memReq->completionEvent = NULL; 4063804Ssaidi@eecs.umich.edu memReq->time = curTick; 4073804Ssaidi@eecs.umich.edu memReq->flags &= ~UNCACHEABLE; 4083804Ssaidi@eecs.umich.edu MemAccessResult result = dcacheInterface->access(memReq); 4093804Ssaidi@eecs.umich.edu 4103804Ssaidi@eecs.umich.edu // Ugly hack to get an event scheduled *only* if the access is 4113804Ssaidi@eecs.umich.edu // a miss. We really should add first-class support for this 4123804Ssaidi@eecs.umich.edu // at some point. 4134172Ssaidi@eecs.umich.edu if (result != MA_HIT && dcacheInterface->doEvents) { 4143804Ssaidi@eecs.umich.edu memReq->completionEvent = &cacheCompletionEvent; 4153804Ssaidi@eecs.umich.edu setStatus(DcacheMissStall); 4163826Ssaidi@eecs.umich.edu } 4173826Ssaidi@eecs.umich.edu } 4183826Ssaidi@eecs.umich.edu 4193916Ssaidi@eecs.umich.edu if (res && (fault == No_Fault)) 4203916Ssaidi@eecs.umich.edu *res = memReq->result; 4213916Ssaidi@eecs.umich.edu 4224172Ssaidi@eecs.umich.edu return fault; 4233826Ssaidi@eecs.umich.edu} 4243804Ssaidi@eecs.umich.edu 4253804Ssaidi@eecs.umich.edu 4263804Ssaidi@eecs.umich.edu#ifndef DOXYGEN_SHOULD_SKIP_THIS 4273804Ssaidi@eecs.umich.edutemplate 4283804Ssaidi@eecs.umich.eduFault 4293811Ssaidi@eecs.umich.eduSimpleCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res); 4303811Ssaidi@eecs.umich.edu 4313804Ssaidi@eecs.umich.edutemplate 4323804Ssaidi@eecs.umich.eduFault 4333804Ssaidi@eecs.umich.eduSimpleCPU::write(uint32_t data, Addr addr, unsigned flags, uint64_t *res); 4343804Ssaidi@eecs.umich.edu 4353826Ssaidi@eecs.umich.edutemplate 4363826Ssaidi@eecs.umich.eduFault 4373826Ssaidi@eecs.umich.eduSimpleCPU::write(uint16_t data, Addr addr, unsigned flags, uint64_t *res); 4383826Ssaidi@eecs.umich.edu 4393826Ssaidi@eecs.umich.edutemplate 4403826Ssaidi@eecs.umich.eduFault 4413804Ssaidi@eecs.umich.eduSimpleCPU::write(uint8_t data, Addr addr, unsigned flags, uint64_t *res); 4423804Ssaidi@eecs.umich.edu 4433804Ssaidi@eecs.umich.edu#endif //DOXYGEN_SHOULD_SKIP_THIS 4443811Ssaidi@eecs.umich.edu 4453811Ssaidi@eecs.umich.edutemplate<> 4463804Ssaidi@eecs.umich.eduFault 4474172Ssaidi@eecs.umich.eduSimpleCPU::write(double data, Addr addr, unsigned flags, uint64_t *res) 4483804Ssaidi@eecs.umich.edu{ 4493804Ssaidi@eecs.umich.edu return write(*(uint64_t*)&data, addr, flags, res); 4503836Ssaidi@eecs.umich.edu} 4513826Ssaidi@eecs.umich.edu 4523826Ssaidi@eecs.umich.edutemplate<> 4533826Ssaidi@eecs.umich.eduFault 4543826Ssaidi@eecs.umich.eduSimpleCPU::write(float data, Addr addr, unsigned flags, uint64_t *res) 4553826Ssaidi@eecs.umich.edu{ 4563826Ssaidi@eecs.umich.edu return write(*(uint32_t*)&data, addr, flags, res); 4573804Ssaidi@eecs.umich.edu} 4583804Ssaidi@eecs.umich.edu 4593804Ssaidi@eecs.umich.edu 4603804Ssaidi@eecs.umich.edutemplate<> 4614172Ssaidi@eecs.umich.eduFault 4623833Ssaidi@eecs.umich.eduSimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res) 4633836Ssaidi@eecs.umich.edu{ 4643836Ssaidi@eecs.umich.edu return write((uint32_t)data, addr, flags, res); 4653836Ssaidi@eecs.umich.edu} 4663836Ssaidi@eecs.umich.edu 4673836Ssaidi@eecs.umich.edu 4683836Ssaidi@eecs.umich.edu#ifdef FULL_SYSTEM 4693836Ssaidi@eecs.umich.eduAddr 4703836Ssaidi@eecs.umich.eduSimpleCPU::dbg_vtophys(Addr addr) 4713836Ssaidi@eecs.umich.edu{ 4723836Ssaidi@eecs.umich.edu return vtophys(xc, addr); 4733836Ssaidi@eecs.umich.edu} 4743836Ssaidi@eecs.umich.edu#endif // FULL_SYSTEM 4753836Ssaidi@eecs.umich.edu 4763836Ssaidi@eecs.umich.eduTick save_cycle = 0; 4773836Ssaidi@eecs.umich.edu 4783836Ssaidi@eecs.umich.edu 4793836Ssaidi@eecs.umich.eduvoid 4803836Ssaidi@eecs.umich.eduSimpleCPU::processCacheCompletion() 4813836Ssaidi@eecs.umich.edu{ 4823836Ssaidi@eecs.umich.edu switch (status()) { 4833836Ssaidi@eecs.umich.edu case IcacheMissStall: 4843836Ssaidi@eecs.umich.edu icacheStallCycles += curTick - lastIcacheStall; 4853836Ssaidi@eecs.umich.edu setStatus(IcacheMissComplete); 4863833Ssaidi@eecs.umich.edu break; 4873833Ssaidi@eecs.umich.edu case DcacheMissStall: 4883833Ssaidi@eecs.umich.edu dcacheStallCycles += curTick - lastDcacheStall; 4893833Ssaidi@eecs.umich.edu setStatus(Running); 4903833Ssaidi@eecs.umich.edu break; 4913833Ssaidi@eecs.umich.edu default: 4923833Ssaidi@eecs.umich.edu panic("SimpleCPU::processCacheCompletion: bad state"); 4933833Ssaidi@eecs.umich.edu break; 4943833Ssaidi@eecs.umich.edu } 4953804Ssaidi@eecs.umich.edu} 4963804Ssaidi@eecs.umich.edu 4973804Ssaidi@eecs.umich.edu#ifdef FULL_SYSTEM 4983804Ssaidi@eecs.umich.eduvoid 4993804Ssaidi@eecs.umich.eduSimpleCPU::post_interrupt(int int_num, int index) 5003833Ssaidi@eecs.umich.edu{ 5013833Ssaidi@eecs.umich.edu BaseCPU::post_interrupt(int_num, index); 5023811Ssaidi@eecs.umich.edu 5033804Ssaidi@eecs.umich.edu if (xc->status() == ExecContext::Suspended) { 5043804Ssaidi@eecs.umich.edu DPRINTF(IPI,"Suspended Processor awoke\n"); 5053804Ssaidi@eecs.umich.edu xc->setStatus(ExecContext::Active); 5063804Ssaidi@eecs.umich.edu Annotate::Resume(xc); 5073804Ssaidi@eecs.umich.edu } 5083804Ssaidi@eecs.umich.edu} 5093804Ssaidi@eecs.umich.edu#endif // FULL_SYSTEM 5103833Ssaidi@eecs.umich.edu 5113804Ssaidi@eecs.umich.edu/* start simulation, program loaded, processor precise state initialized */ 5123804Ssaidi@eecs.umich.eduvoid 5133833Ssaidi@eecs.umich.eduSimpleCPU::tick() 5143836Ssaidi@eecs.umich.edu{ 5153836Ssaidi@eecs.umich.edu traceData = NULL; 5163836Ssaidi@eecs.umich.edu 5173836Ssaidi@eecs.umich.edu#ifdef FULL_SYSTEM 5183804Ssaidi@eecs.umich.edu if (fault == No_Fault && AlphaISA::check_interrupts && 5193804Ssaidi@eecs.umich.edu xc->cpu->check_interrupts() && 5203804Ssaidi@eecs.umich.edu !PC_PAL(xc->regs.pc) && 5213836Ssaidi@eecs.umich.edu status() != IcacheMissComplete) { 5223836Ssaidi@eecs.umich.edu int ipl = 0; 5233804Ssaidi@eecs.umich.edu int summary = 0; 5243804Ssaidi@eecs.umich.edu AlphaISA::check_interrupts = 0; 5253804Ssaidi@eecs.umich.edu IntReg *ipr = xc->regs.ipr; 5263804Ssaidi@eecs.umich.edu 5273804Ssaidi@eecs.umich.edu if (xc->regs.ipr[TheISA::IPR_SIRR]) { 5283804Ssaidi@eecs.umich.edu for (int i = TheISA::INTLEVEL_SOFTWARE_MIN; 5293804Ssaidi@eecs.umich.edu i < TheISA::INTLEVEL_SOFTWARE_MAX; i++) { 5303804Ssaidi@eecs.umich.edu if (ipr[TheISA::IPR_SIRR] & (ULL(1) << i)) { 5313804Ssaidi@eecs.umich.edu // See table 4-19 of 21164 hardware reference 5323804Ssaidi@eecs.umich.edu ipl = (i - TheISA::INTLEVEL_SOFTWARE_MIN) + 1; 5333804Ssaidi@eecs.umich.edu summary |= (ULL(1) << i); 5343804Ssaidi@eecs.umich.edu } 5353833Ssaidi@eecs.umich.edu } 5363836Ssaidi@eecs.umich.edu } 5373804Ssaidi@eecs.umich.edu 5383804Ssaidi@eecs.umich.edu uint64_t interrupts = xc->cpu->intr_status(); 5393804Ssaidi@eecs.umich.edu for(int i = TheISA::INTLEVEL_EXTERNAL_MIN; 5403804Ssaidi@eecs.umich.edu i < TheISA::INTLEVEL_EXTERNAL_MAX; i++) { 5413804Ssaidi@eecs.umich.edu if (interrupts & (ULL(1) << i)) { 5423804Ssaidi@eecs.umich.edu // See table 4-19 of 21164 hardware reference 5433804Ssaidi@eecs.umich.edu ipl = i; 5443916Ssaidi@eecs.umich.edu summary |= (ULL(1) << i); 5453804Ssaidi@eecs.umich.edu } 5463804Ssaidi@eecs.umich.edu } 5473804Ssaidi@eecs.umich.edu 5483804Ssaidi@eecs.umich.edu if (ipr[TheISA::IPR_ASTRR]) 5493804Ssaidi@eecs.umich.edu panic("asynchronous traps not implemented\n"); 5503804Ssaidi@eecs.umich.edu 5513804Ssaidi@eecs.umich.edu if (ipl && ipl > xc->regs.ipr[TheISA::IPR_IPLR]) { 5523804Ssaidi@eecs.umich.edu ipr[TheISA::IPR_ISR] = summary; 5533928Ssaidi@eecs.umich.edu ipr[TheISA::IPR_INTID] = ipl; 5543804Ssaidi@eecs.umich.edu xc->ev5_trap(Interrupt_Fault); 5553804Ssaidi@eecs.umich.edu 5563804Ssaidi@eecs.umich.edu DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", 5573804Ssaidi@eecs.umich.edu ipr[TheISA::IPR_IPLR], ipl, summary); 5583836Ssaidi@eecs.umich.edu } 5593836Ssaidi@eecs.umich.edu } 5603836Ssaidi@eecs.umich.edu#endif 5613836Ssaidi@eecs.umich.edu 5623836Ssaidi@eecs.umich.edu // maintain $r0 semantics 5633826Ssaidi@eecs.umich.edu xc->regs.intRegFile[ZeroReg] = 0; 5643836Ssaidi@eecs.umich.edu#ifdef TARGET_ALPHA 5653836Ssaidi@eecs.umich.edu xc->regs.floatRegFile.d[ZeroReg] = 0.0; 5663804Ssaidi@eecs.umich.edu#endif // TARGET_ALPHA 5673804Ssaidi@eecs.umich.edu 5683804Ssaidi@eecs.umich.edu if (status() == IcacheMissComplete) { 5693804Ssaidi@eecs.umich.edu // We've already fetched an instruction and were stalled on an 5703804Ssaidi@eecs.umich.edu // I-cache miss. No need to fetch it again. 5713804Ssaidi@eecs.umich.edu 5723804Ssaidi@eecs.umich.edu setStatus(Running); 5733804Ssaidi@eecs.umich.edu } 5743804Ssaidi@eecs.umich.edu else { 5754172Ssaidi@eecs.umich.edu // Try to fetch an instruction 5763836Ssaidi@eecs.umich.edu 5773836Ssaidi@eecs.umich.edu // set up memory request for instruction fetch 5783836Ssaidi@eecs.umich.edu#ifdef FULL_SYSTEM 5793836Ssaidi@eecs.umich.edu#define IFETCH_FLAGS(pc) ((pc) & 1) ? PHYSICAL : 0 5803836Ssaidi@eecs.umich.edu#else 5813836Ssaidi@eecs.umich.edu#define IFETCH_FLAGS(pc) 0 5823833Ssaidi@eecs.umich.edu#endif 5833836Ssaidi@eecs.umich.edu 5843836Ssaidi@eecs.umich.edu memReq->cmd = Read; 5853836Ssaidi@eecs.umich.edu memReq->reset(xc->regs.pc & ~3, sizeof(uint32_t), 5863929Ssaidi@eecs.umich.edu IFETCH_FLAGS(xc->regs.pc)); 5873929Ssaidi@eecs.umich.edu 5883929Ssaidi@eecs.umich.edu fault = xc->translateInstReq(memReq); 5893836Ssaidi@eecs.umich.edu 5903836Ssaidi@eecs.umich.edu if (fault == No_Fault) 5913836Ssaidi@eecs.umich.edu fault = xc->mem->read(memReq, inst); 5923836Ssaidi@eecs.umich.edu 5933836Ssaidi@eecs.umich.edu if (icacheInterface && fault == No_Fault) { 5943836Ssaidi@eecs.umich.edu memReq->completionEvent = NULL; 5953836Ssaidi@eecs.umich.edu 5963836Ssaidi@eecs.umich.edu memReq->time = curTick; 5973836Ssaidi@eecs.umich.edu memReq->flags &= ~UNCACHEABLE; 5983836Ssaidi@eecs.umich.edu MemAccessResult result = icacheInterface->access(memReq); 5994090Ssaidi@eecs.umich.edu 6004090Ssaidi@eecs.umich.edu // Ugly hack to get an event scheduled *only* if the access is 6014090Ssaidi@eecs.umich.edu // a miss. We really should add first-class support for this 6024090Ssaidi@eecs.umich.edu // at some point. 6034090Ssaidi@eecs.umich.edu if (result != MA_HIT && icacheInterface->doEvents) { 6044090Ssaidi@eecs.umich.edu memReq->completionEvent = &cacheCompletionEvent; 6054090Ssaidi@eecs.umich.edu setStatus(IcacheMissStall); 6064090Ssaidi@eecs.umich.edu return; 6074090Ssaidi@eecs.umich.edu } 6084090Ssaidi@eecs.umich.edu } 6094090Ssaidi@eecs.umich.edu } 6104090Ssaidi@eecs.umich.edu 6114090Ssaidi@eecs.umich.edu // If we've got a valid instruction (i.e., no fault on instruction 6124090Ssaidi@eecs.umich.edu // fetch), then execute it. 6134090Ssaidi@eecs.umich.edu if (fault == No_Fault) { 6144090Ssaidi@eecs.umich.edu 6154090Ssaidi@eecs.umich.edu // keep an instruction count 6164090Ssaidi@eecs.umich.edu numInst++; 6174090Ssaidi@eecs.umich.edu 6184090Ssaidi@eecs.umich.edu // check for instruction-count-based events 6194090Ssaidi@eecs.umich.edu comInsnEventQueue[0]->serviceEvents(numInst); 6204090Ssaidi@eecs.umich.edu 6214090Ssaidi@eecs.umich.edu // decode the instruction 6224090Ssaidi@eecs.umich.edu StaticInstPtr<TheISA> si(inst); 6234090Ssaidi@eecs.umich.edu 6244090Ssaidi@eecs.umich.edu traceData = Trace::getInstRecord(curTick, xc, this, si, 6254090Ssaidi@eecs.umich.edu xc->regs.pc); 6264090Ssaidi@eecs.umich.edu 6274090Ssaidi@eecs.umich.edu#ifdef FULL_SYSTEM 6284090Ssaidi@eecs.umich.edu xc->regs.opcode = (inst >> 26) & 0x3f; 6293836Ssaidi@eecs.umich.edu xc->regs.ra = (inst >> 21) & 0x1f; 6303833Ssaidi@eecs.umich.edu#endif // FULL_SYSTEM 6313833Ssaidi@eecs.umich.edu 6323833Ssaidi@eecs.umich.edu xc->func_exe_insn++; 6333833Ssaidi@eecs.umich.edu 6343833Ssaidi@eecs.umich.edu fault = si->execute(this, xc, traceData); 6353833Ssaidi@eecs.umich.edu 6363833Ssaidi@eecs.umich.edu if (si->isMemRef()) { 6373833Ssaidi@eecs.umich.edu numMemRefs++; 6383916Ssaidi@eecs.umich.edu } 6393833Ssaidi@eecs.umich.edu 6403804Ssaidi@eecs.umich.edu if (traceData) 6413832Ssaidi@eecs.umich.edu traceData->finalize(); 6423832Ssaidi@eecs.umich.edu 6433804Ssaidi@eecs.umich.edu } // if (fault == No_Fault) 6443804Ssaidi@eecs.umich.edu 6453804Ssaidi@eecs.umich.edu if (fault != No_Fault) { 6463833Ssaidi@eecs.umich.edu#ifdef FULL_SYSTEM 6473833Ssaidi@eecs.umich.edu xc->ev5_trap(fault); 6483804Ssaidi@eecs.umich.edu#else // !FULL_SYSTEM 6493804Ssaidi@eecs.umich.edu fatal("fault (%d) detected @ PC 0x%08p", fault, xc->regs.pc); 6503804Ssaidi@eecs.umich.edu#endif // FULL_SYSTEM 6513804Ssaidi@eecs.umich.edu } 6523804Ssaidi@eecs.umich.edu else { 6533804Ssaidi@eecs.umich.edu // go to the next instruction 6543804Ssaidi@eecs.umich.edu xc->regs.pc = xc->regs.npc; 6553804Ssaidi@eecs.umich.edu xc->regs.npc += sizeof(MachInst); 6563804Ssaidi@eecs.umich.edu } 6573833Ssaidi@eecs.umich.edu 6583804Ssaidi@eecs.umich.edu#ifdef FULL_SYSTEM 6593910Ssaidi@eecs.umich.edu Addr oldpc; 6603804Ssaidi@eecs.umich.edu do { 6613910Ssaidi@eecs.umich.edu oldpc = xc->regs.pc; 6623804Ssaidi@eecs.umich.edu system->pcEventQueue.service(xc); 6633804Ssaidi@eecs.umich.edu } while (oldpc != xc->regs.pc); 6643804Ssaidi@eecs.umich.edu#endif 6653804Ssaidi@eecs.umich.edu 6663910Ssaidi@eecs.umich.edu assert(status() == Running || 6673910Ssaidi@eecs.umich.edu status() == Idle || 6683804Ssaidi@eecs.umich.edu status() == DcacheMissStall); 6693804Ssaidi@eecs.umich.edu 6703804Ssaidi@eecs.umich.edu if (status() == Running && !tickEvent.scheduled()) 6713804Ssaidi@eecs.umich.edu tickEvent.schedule(curTick + 1); 6723910Ssaidi@eecs.umich.edu} 6733910Ssaidi@eecs.umich.edu 6743910Ssaidi@eecs.umich.edu 6753910Ssaidi@eecs.umich.edu//////////////////////////////////////////////////////////////////////// 6763910Ssaidi@eecs.umich.edu// 6773910Ssaidi@eecs.umich.edu// SimpleCPU Simulation Object 6783910Ssaidi@eecs.umich.edu// 6793910Ssaidi@eecs.umich.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU) 6803910Ssaidi@eecs.umich.edu 6813910Ssaidi@eecs.umich.edu Param<Counter> max_insts_any_thread; 6823910Ssaidi@eecs.umich.edu Param<Counter> max_insts_all_threads; 6833910Ssaidi@eecs.umich.edu 6843910Ssaidi@eecs.umich.edu#ifdef FULL_SYSTEM 6853902Ssaidi@eecs.umich.edu SimObjectParam<AlphaItb *> itb; 6863804Ssaidi@eecs.umich.edu SimObjectParam<AlphaDtb *> dtb; 6873926Ssaidi@eecs.umich.edu SimObjectParam<FunctionalMemory *> mem; 6883804Ssaidi@eecs.umich.edu SimObjectParam<System *> system; 6893804Ssaidi@eecs.umich.edu Param<int> cpu_id; 6903804Ssaidi@eecs.umich.edu Param<int> mult; 6913804Ssaidi@eecs.umich.edu#else 6923856Ssaidi@eecs.umich.edu SimObjectParam<Process *> workload; 6933804Ssaidi@eecs.umich.edu#endif // FULL_SYSTEM 6943804Ssaidi@eecs.umich.edu 6954103Ssaidi@eecs.umich.edu SimObjectParam<BaseMem *> icache; 6964191Ssaidi@eecs.umich.edu SimObjectParam<BaseMem *> dcache; 6974191Ssaidi@eecs.umich.edu 6984191Ssaidi@eecs.umich.eduEND_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU) 6993824Ssaidi@eecs.umich.edu 7004103Ssaidi@eecs.umich.eduBEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU) 7013804Ssaidi@eecs.umich.edu 7023804Ssaidi@eecs.umich.edu INIT_PARAM_DFLT(max_insts_any_thread, 7033804Ssaidi@eecs.umich.edu "terminate when any thread reaches this insn count", 7043804Ssaidi@eecs.umich.edu 0), 7053824Ssaidi@eecs.umich.edu INIT_PARAM_DFLT(max_insts_all_threads, 7063824Ssaidi@eecs.umich.edu "terminate when all threads have reached this insn count", 7073825Ssaidi@eecs.umich.edu 0), 7083825Ssaidi@eecs.umich.edu 7093823Ssaidi@eecs.umich.edu#ifdef FULL_SYSTEM 7103926Ssaidi@eecs.umich.edu INIT_PARAM(itb, "Instruction TLB"), 7114010Ssaidi@eecs.umich.edu INIT_PARAM(dtb, "Data TLB"), 7123823Ssaidi@eecs.umich.edu INIT_PARAM(mem, "memory"), 7133804Ssaidi@eecs.umich.edu INIT_PARAM(system, "system object"), 7143804Ssaidi@eecs.umich.edu INIT_PARAM_DFLT(cpu_id, "CPU identification number", 0), 7153826Ssaidi@eecs.umich.edu INIT_PARAM_DFLT(mult, "system clock multiplier", 1), 7163826Ssaidi@eecs.umich.edu#else 7173826Ssaidi@eecs.umich.edu INIT_PARAM(workload, "processes to run"), 7183826Ssaidi@eecs.umich.edu#endif // FULL_SYSTEM 7193826Ssaidi@eecs.umich.edu 7203826Ssaidi@eecs.umich.edu INIT_PARAM_DFLT(icache, "L1 instruction cache object", NULL), 7213826Ssaidi@eecs.umich.edu INIT_PARAM_DFLT(dcache, "L1 data cache object", NULL) 7223826Ssaidi@eecs.umich.edu 7233826Ssaidi@eecs.umich.eduEND_INIT_SIM_OBJECT_PARAMS(SimpleCPU) 7243826Ssaidi@eecs.umich.edu 7253826Ssaidi@eecs.umich.edu 7263826Ssaidi@eecs.umich.eduCREATE_SIM_OBJECT(SimpleCPU) 7273826Ssaidi@eecs.umich.edu{ 7283826Ssaidi@eecs.umich.edu#ifdef FULL_SYSTEM 7293826Ssaidi@eecs.umich.edu if (mult != 1) 7303910Ssaidi@eecs.umich.edu panic("processor clock multiplier must be 1\n"); 7313804Ssaidi@eecs.umich.edu 7323804Ssaidi@eecs.umich.edu return new SimpleCPU(getInstanceName(), system, 7333804Ssaidi@eecs.umich.edu max_insts_any_thread, max_insts_all_threads, 7343804Ssaidi@eecs.umich.edu itb, dtb, mem, 7353804Ssaidi@eecs.umich.edu (icache) ? icache->getInterface() : NULL, 7363836Ssaidi@eecs.umich.edu (dcache) ? dcache->getInterface() : NULL, 7373804Ssaidi@eecs.umich.edu cpu_id, ticksPerSecond * mult); 7383804Ssaidi@eecs.umich.edu#else 7393804Ssaidi@eecs.umich.edu 7403836Ssaidi@eecs.umich.edu return new SimpleCPU(getInstanceName(), workload, 7413804Ssaidi@eecs.umich.edu max_insts_any_thread, max_insts_all_threads, 7423804Ssaidi@eecs.umich.edu icache->getInterface(), dcache->getInterface()); 7433916Ssaidi@eecs.umich.edu 7443811Ssaidi@eecs.umich.edu#endif // FULL_SYSTEM 7453804Ssaidi@eecs.umich.edu} 7463804Ssaidi@eecs.umich.edu 7473804Ssaidi@eecs.umich.eduREGISTER_SIM_OBJECT("SimpleCPU", SimpleCPU) 7483804Ssaidi@eecs.umich.edu