base.cc revision 595
12SN/A/*
28922Swilliam.wang@arm.com * Copyright (c) 2003 The Regents of The University of Michigan
38707Sandreas.hansson@arm.com * All rights reserved.
48707Sandreas.hansson@arm.com *
58707Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68707Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
78707Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
88707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
98707Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
108707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
118707Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
128707Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
138707Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
141762SN/A * this software without specific prior written permission.
157897Shestness@cs.utexas.edu *
169983Sstever@gmail.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
179983Sstever@gmail.com * "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.
272SN/A */
282SN/A
292SN/A#include <cmath>
302SN/A#include <cstdio>
312SN/A#include <cstdlib>
322SN/A#include <iostream>
332SN/A#include <iomanip>
342SN/A#include <list>
352SN/A#include <sstream>
362SN/A#include <string>
372SN/A
382SN/A#include "base/cprintf.hh"
392SN/A#include "base/inifile.hh"
402SN/A#include "base/loader/symtab.hh"
412SN/A#include "base/misc.hh"
422665Ssaidi@eecs.umich.edu#include "base/pollevent.hh"
432665Ssaidi@eecs.umich.edu#include "base/range.hh"
442665Ssaidi@eecs.umich.edu#include "base/trace.hh"
457897Shestness@cs.utexas.edu#include "cpu/base_cpu.hh"
462SN/A#include "cpu/exec_context.hh"
472SN/A#include "cpu/exetrace.hh"
481388SN/A#include "cpu/full_cpu/smt.hh"
498229Snate@binkert.org#include "cpu/simple_cpu/simple_cpu.hh"
502SN/A#include "cpu/static_inst.hh"
512SN/A#include "mem/base_mem.hh"
527781SAli.Saidi@ARM.com#include "mem/mem_interface.hh"
538229Snate@binkert.org#include "sim/annotation.hh"
541191SN/A#include "sim/builder.hh"
551191SN/A#include "sim/debug.hh"
561388SN/A#include "sim/host.hh"
575529Snate@binkert.org#include "sim/sim_events.hh"
5810529Smorr@cs.wisc.edu#include "sim/sim_object.hh"
591717SN/A#include "sim/sim_stats.hh"
602651Ssaidi@eecs.umich.edu
618229Snate@binkert.org#ifdef FULL_SYSTEM
622680Sktlim@umich.edu#include "base/remote_gdb.hh"
6310529Smorr@cs.wisc.edu#include "dev/alpha_access.h"
648232Snate@binkert.org#include "dev/pciareg.h"
6510529Smorr@cs.wisc.edu#include "mem/functional_mem/memory_control.hh"
665529Snate@binkert.org#include "mem/functional_mem/physical_memory.hh"
678779Sgblack@eecs.umich.edu#include "sim/system.hh"
682190SN/A#include "targetarch/alpha_memory.hh"
6956SN/A#include "targetarch/vtophys.hh"
708229Snate@binkert.org#else // !FULL_SYSTEM
712190SN/A#include "eio/eio.hh"
722SN/A#include "mem/functional_mem/functional_memory.hh"
732359SN/A#endif // FULL_SYSTEM
742359SN/A
752359SN/Ausing namespace std;
762SN/A
772SN/ASimpleCPU::TickEvent::TickEvent(SimpleCPU *c)
782SN/A    : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c)
792SN/A{
802SN/A}
812SN/A
822SN/Avoid
832SN/ASimpleCPU::TickEvent::process()
842SN/A{
855606Snate@binkert.org    cpu->tick();
866144Sksewell@umich.edu}
876144Sksewell@umich.edu
883126Sktlim@umich.educonst char *
896144Sksewell@umich.eduSimpleCPU::TickEvent::description()
907823Ssteve.reinhardt@amd.com{
913126Sktlim@umich.edu    return "SimpleCPU tick event";
923126Sktlim@umich.edu}
932356SN/A
942356SN/A
952356SN/ASimpleCPU::CacheCompletionEvent::CacheCompletionEvent(SimpleCPU *_cpu)
968834Satgutier@umich.edu    : Event(&mainEventQueue),
972356SN/A      cpu(_cpu)
989179Sandreas.hansson@arm.com{
992367SN/A}
1006144Sksewell@umich.edu
1016144Sksewell@umich.eduvoid SimpleCPU::CacheCompletionEvent::process()
1026144Sksewell@umich.edu{
1032356SN/A    cpu->processCacheCompletion();
1042367SN/A}
1056144Sksewell@umich.edu
1067823Ssteve.reinhardt@amd.comconst char *
1076144Sksewell@umich.eduSimpleCPU::CacheCompletionEvent::description()
1082367SN/A{
1092356SN/A    return "SimpleCPU cache completion event";
1106144Sksewell@umich.edu}
1116144Sksewell@umich.edu
1127823Ssteve.reinhardt@amd.com#ifdef FULL_SYSTEM
1132356SN/ASimpleCPU::SimpleCPU(const string &_name,
1142356SN/A                     System *_system,
1152356SN/A                     Counter max_insts_any_thread,
1165336Shines@cs.fsu.edu                     Counter max_insts_all_threads,
1172356SN/A                     Counter max_loads_any_thread,
1184873Sstever@eecs.umich.edu                     Counter max_loads_all_threads,
1192356SN/A                     AlphaItb *itb, AlphaDtb *dtb,
1202356SN/A                     FunctionalMemory *mem,
1218876Sandreas.hansson@arm.com                     MemInterface *icache_interface,
12210190Sakash.bagdia@arm.com                     MemInterface *dcache_interface,
1238832SAli.Saidi@ARM.com                     bool _def_reg, Tick freq)
1248832SAli.Saidi@ARM.com    : BaseCPU(_name, /* number_of_threads */ 1,
1259332Sdam.sunwoo@arm.com              max_insts_any_thread, max_insts_all_threads,
1269814Sandreas.hansson@arm.com              max_loads_any_thread, max_loads_all_threads,
1279220Shestness@cs.wisc.edu              _system, freq),
12810529Smorr@cs.wisc.edu#else
12910537Sandreas.hansson@arm.comSimpleCPU::SimpleCPU(const string &_name, Process *_process,
13010537Sandreas.hansson@arm.com                     Counter max_insts_any_thread,
13110529Smorr@cs.wisc.edu                     Counter max_insts_all_threads,
1322SN/A                     Counter max_loads_any_thread,
1335712Shsul@eecs.umich.edu                     Counter max_loads_all_threads,
1345712Shsul@eecs.umich.edu                     MemInterface *icache_interface,
1355712Shsul@eecs.umich.edu                     MemInterface *dcache_interface,
1365712Shsul@eecs.umich.edu                     bool _def_reg)
1375712Shsul@eecs.umich.edu    : BaseCPU(_name, /* number_of_threads */ 1,
1382SN/A              max_insts_any_thread, max_insts_all_threads,
1392SN/A              max_loads_any_thread, max_loads_all_threads),
1402SN/A#endif
14110190Sakash.bagdia@arm.com      tickEvent(this), xc(NULL), defer_registration(_def_reg),
14210190Sakash.bagdia@arm.com      cacheCompletionEvent(this)
1435712Shsul@eecs.umich.edu{
1446221Snate@binkert.org    _status = Idle;
1456221Snate@binkert.org#ifdef FULL_SYSTEM
1462SN/A    xc = new ExecContext(this, 0, system, itb, dtb, mem);
1472SN/A
1486221Snate@binkert.org    // initialize CPU, including PC
1496221Snate@binkert.org    TheISA::initCPU(&xc->regs);
1506221Snate@binkert.org#else
1516221Snate@binkert.org    xc = new ExecContext(this, /* thread_num */ 0, _process, /* asid */ 0);
1522SN/A#endif // !FULL_SYSTEM
1532SN/A
1542SN/A    icacheInterface = icache_interface;
1552SN/A    dcacheInterface = dcache_interface;
1565606Snate@binkert.org
1575606Snate@binkert.org    memReq = new MemReq();
1589749Sandreas@sandberg.pp.se    memReq->xc = xc;
1599749Sandreas@sandberg.pp.se    memReq->asid = 0;
1605606Snate@binkert.org    memReq->data = new uint8_t[64];
1612SN/A
1629647Sdam.sunwoo@arm.com    numInst = 0;
1639647Sdam.sunwoo@arm.com    startNumInst = 0;
1649647Sdam.sunwoo@arm.com    numLoad = 0;
1659647Sdam.sunwoo@arm.com    startNumLoad = 0;
1669647Sdam.sunwoo@arm.com    lastIcacheStall = 0;
1679647Sdam.sunwoo@arm.com    lastDcacheStall = 0;
1689749Sandreas@sandberg.pp.se
1699749Sandreas@sandberg.pp.se    execContexts.push_back(xc);
1709647Sdam.sunwoo@arm.com}
1719647Sdam.sunwoo@arm.com
1721400SN/ASimpleCPU::~SimpleCPU()
1735606Snate@binkert.org{
1745606Snate@binkert.org}
1752SN/A
1762SN/Avoid SimpleCPU::init()
1772SN/A{
1782SN/A    if (!defer_registration) {
1796221Snate@binkert.org        this->registerExecContexts();
1806221Snate@binkert.org    }
1815606Snate@binkert.org}
1826670Shsul@eecs.umich.edu
1835606Snate@binkert.orgvoid
1842SN/ASimpleCPU::switchOut()
1852SN/A{
186124SN/A    _status = SwitchedOut;
1876221Snate@binkert.org    if (tickEvent.scheduled())
1886221Snate@binkert.org        tickEvent.squash();
1896221Snate@binkert.org}
190124SN/A
191124SN/A
192124SN/Avoid
193124SN/ASimpleCPU::takeOverFrom(BaseCPU *oldCPU)
1945606Snate@binkert.org{
1955606Snate@binkert.org    BaseCPU::takeOverFrom(oldCPU);
1969749Sandreas@sandberg.pp.se
1979749Sandreas@sandberg.pp.se    assert(!tickEvent.scheduled());
1985606Snate@binkert.org
199124SN/A    // if any of this CPU's ExecContexts are active, mark the CPU as
2001400SN/A    // running and schedule its tick event.
2015606Snate@binkert.org    for (int i = 0; i < execContexts.size(); ++i) {
202124SN/A        ExecContext *xc = execContexts[i];
203124SN/A        if (xc->status() == ExecContext::Active && _status != Running) {
204124SN/A            _status = Running;
205124SN/A            tickEvent.schedule(curTick);
2066221Snate@binkert.org        }
2076221Snate@binkert.org    }
2085606Snate@binkert.org
2096221Snate@binkert.org    oldCPU->switchOut();
2105606Snate@binkert.org}
211124SN/A
212124SN/A
2131191SN/Avoid
2145529Snate@binkert.orgSimpleCPU::activateContext(int thread_num, int delay)
2158634Schris.emmons@arm.com{
2168634Schris.emmons@arm.com    assert(thread_num == 0);
2178634Schris.emmons@arm.com    assert(xc);
2188634Schris.emmons@arm.com
2198634Schris.emmons@arm.com    assert(_status == Idle);
2201191SN/A    notIdleFraction++;
2215529Snate@binkert.org    scheduleTickEvent(delay);
2221191SN/A    _status = Running;
2235529Snate@binkert.org}
2241191SN/A
2251191SN/A
2265606Snate@binkert.orgvoid
2275606Snate@binkert.orgSimpleCPU::suspendContext(int thread_num)
2285606Snate@binkert.org{
2291191SN/A    assert(thread_num == 0);
2301191SN/A    assert(xc);
2318876Sandreas.hansson@arm.com
2328876Sandreas.hansson@arm.com    assert(_status == Running);
2338876Sandreas.hansson@arm.com    notIdleFraction--;
2349433SAndreas.Sandberg@ARM.com    unscheduleTickEvent();
2358876Sandreas.hansson@arm.com    _status = Idle;
2368876Sandreas.hansson@arm.com}
2378876Sandreas.hansson@arm.com
2388876Sandreas.hansson@arm.com
2398876Sandreas.hansson@arm.comvoid
2408876Sandreas.hansson@arm.comSimpleCPU::deallocateContext(int thread_num)
2418876Sandreas.hansson@arm.com{
2425810Sgblack@eecs.umich.edu    // for now, these are equivalent
2438779Sgblack@eecs.umich.edu    suspendContext(thread_num);
2448779Sgblack@eecs.umich.edu}
2458779Sgblack@eecs.umich.edu
2468779Sgblack@eecs.umich.edu
2475529Snate@binkert.orgvoid
2489384SAndreas.Sandberg@arm.comSimpleCPU::haltContext(int thread_num)
2499384SAndreas.Sandberg@arm.com{
2509384SAndreas.Sandberg@arm.com    // for now, these are equivalent
2519384SAndreas.Sandberg@arm.com    suspendContext(thread_num);
2529384SAndreas.Sandberg@arm.com}
2531917SN/A
2541191SN/A
2551191SN/Avoid
2561191SN/ASimpleCPU::regStats()
2571191SN/A{
2581191SN/A    using namespace Statistics;
2591191SN/A
2601191SN/A    BaseCPU::regStats();
2611191SN/A
2621191SN/A    numInsts
2639086Sandreas.hansson@arm.com        .name(name() + ".num_insts")
2649086Sandreas.hansson@arm.com        .desc("Number of instructions executed")
2659086Sandreas.hansson@arm.com        ;
2661191SN/A
2671191SN/A    numMemRefs
2681129SN/A        .name(name() + ".num_refs")
26910529Smorr@cs.wisc.edu        .desc("Number of memory references")
27010529Smorr@cs.wisc.edu        ;
27110529Smorr@cs.wisc.edu
27210529Smorr@cs.wisc.edu    idleFraction
27310529Smorr@cs.wisc.edu        .name(name() + ".idle_fraction")
27410529Smorr@cs.wisc.edu        .desc("Percentage of idle cycles")
27510529Smorr@cs.wisc.edu        ;
27610529Smorr@cs.wisc.edu
27710529Smorr@cs.wisc.edu    icacheStallCycles
27810529Smorr@cs.wisc.edu        .name(name() + ".icache_stall_cycles")
27910529Smorr@cs.wisc.edu        .desc("ICache total stall cycles")
28010529Smorr@cs.wisc.edu        .prereq(icacheStallCycles)
28110529Smorr@cs.wisc.edu        ;
28210529Smorr@cs.wisc.edu
28310529Smorr@cs.wisc.edu    dcacheStallCycles
28410529Smorr@cs.wisc.edu        .name(name() + ".dcache_stall_cycles")
28510529Smorr@cs.wisc.edu        .desc("DCache total stall cycles")
28610529Smorr@cs.wisc.edu        .prereq(dcacheStallCycles)
28710529Smorr@cs.wisc.edu        ;
28810529Smorr@cs.wisc.edu
28910529Smorr@cs.wisc.edu    idleFraction = constant(1.0) - notIdleFraction;
29010529Smorr@cs.wisc.edu    numInsts = Statistics::scalar(numInst) - Statistics::scalar(startNumInst);
29110529Smorr@cs.wisc.edu    simInsts += numInsts;
29210529Smorr@cs.wisc.edu}
29310529Smorr@cs.wisc.edu
29410529Smorr@cs.wisc.eduvoid
29510529Smorr@cs.wisc.eduSimpleCPU::resetStats()
29610529Smorr@cs.wisc.edu{
29710529Smorr@cs.wisc.edu    startNumInst = numInst;
29810529Smorr@cs.wisc.edu    notIdleFraction = (_status != Idle);
29910529Smorr@cs.wisc.edu}
30010529Smorr@cs.wisc.edu
30110529Smorr@cs.wisc.eduvoid
30210529Smorr@cs.wisc.eduSimpleCPU::serialize(ostream &os)
30310529Smorr@cs.wisc.edu{
30410529Smorr@cs.wisc.edu    SERIALIZE_ENUM(_status);
30510529Smorr@cs.wisc.edu    SERIALIZE_SCALAR(inst);
30610529Smorr@cs.wisc.edu    nameOut(os, csprintf("%s.xc", name()));
30710529Smorr@cs.wisc.edu    xc->serialize(os);
30810529Smorr@cs.wisc.edu    nameOut(os, csprintf("%s.tickEvent", name()));
30910529Smorr@cs.wisc.edu    tickEvent.serialize(os);
31010529Smorr@cs.wisc.edu    nameOut(os, csprintf("%s.cacheCompletionEvent", name()));
31110529Smorr@cs.wisc.edu    cacheCompletionEvent.serialize(os);
31210529Smorr@cs.wisc.edu}
31310529Smorr@cs.wisc.edu
31410529Smorr@cs.wisc.eduvoid
31510529Smorr@cs.wisc.eduSimpleCPU::unserialize(Checkpoint *cp, const string &section)
31610529Smorr@cs.wisc.edu{
31710529Smorr@cs.wisc.edu    UNSERIALIZE_ENUM(_status);
31810529Smorr@cs.wisc.edu    UNSERIALIZE_SCALAR(inst);
31910529Smorr@cs.wisc.edu    xc->unserialize(cp, csprintf("%s.xc", section));
32010529Smorr@cs.wisc.edu    tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
32110529Smorr@cs.wisc.edu    cacheCompletionEvent
32210529Smorr@cs.wisc.edu        .unserialize(cp, csprintf("%s.cacheCompletionEvent", section));
32310529Smorr@cs.wisc.edu}
32410529Smorr@cs.wisc.edu
32510529Smorr@cs.wisc.eduvoid
3261129SN/Achange_thread_state(int thread_number, int activate, int priority)
3271129SN/A{
3289523SAndreas.Sandberg@ARM.com}
3292680Sktlim@umich.edu
3309523SAndreas.Sandberg@ARM.comFault
3319523SAndreas.Sandberg@ARM.comSimpleCPU::copySrcTranslate(Addr src)
3329523SAndreas.Sandberg@ARM.com{
3331129SN/A    memReq->reset(src, (dcacheInterface) ?
334180SN/A                  dcacheInterface->getBlockSize()
3352SN/A                  : 64);
3361917SN/A
3371917SN/A    // translate to physical address
3388779Sgblack@eecs.umich.edu    Fault fault = xc->translateDataReadReq(memReq);
3399433SAndreas.Sandberg@ARM.com
3408779Sgblack@eecs.umich.edu    if (fault == No_Fault) {
3418779Sgblack@eecs.umich.edu        xc->copySrcAddr = src;
3422356SN/A        xc->copySrcPhysAddr = memReq->paddr;
3435529Snate@binkert.org    } else {
3449179Sandreas.hansson@arm.com        xc->copySrcAddr = 0;
3452356SN/A        xc->copySrcPhysAddr = 0;
3461917SN/A    }
3471917SN/A    return fault;
34810464SAndreas.Sandberg@ARM.com}
34910464SAndreas.Sandberg@ARM.com
35010464SAndreas.Sandberg@ARM.comFault
35110464SAndreas.Sandberg@ARM.comSimpleCPU::copy(Addr dest)
35210464SAndreas.Sandberg@ARM.com{
35310464SAndreas.Sandberg@ARM.com    int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
35410464SAndreas.Sandberg@ARM.com    uint8_t data[blk_size];
35510464SAndreas.Sandberg@ARM.com    assert(xc->copySrcPhysAddr);
35610464SAndreas.Sandberg@ARM.com    memReq->reset(dest, blk_size);
35710464SAndreas.Sandberg@ARM.com    // translate to physical address
35810464SAndreas.Sandberg@ARM.com    Fault fault = xc->translateDataWriteReq(memReq);
35910464SAndreas.Sandberg@ARM.com    if (fault == No_Fault) {
36010464SAndreas.Sandberg@ARM.com        Addr dest_addr = memReq->paddr;
36110464SAndreas.Sandberg@ARM.com        // Need to read straight from memory since we have more than 8 bytes.
36210464SAndreas.Sandberg@ARM.com        memReq->paddr = xc->copySrcPhysAddr;
36310464SAndreas.Sandberg@ARM.com        xc->mem->read(memReq, data);
36410464SAndreas.Sandberg@ARM.com        memReq->paddr = dest_addr;
36510464SAndreas.Sandberg@ARM.com        xc->mem->write(memReq, data);
36610464SAndreas.Sandberg@ARM.com    }
36710464SAndreas.Sandberg@ARM.com    return fault;
36810464SAndreas.Sandberg@ARM.com}
36910464SAndreas.Sandberg@ARM.com
37010464SAndreas.Sandberg@ARM.com// precise architected memory state accessor macros
37110464SAndreas.Sandberg@ARM.comtemplate <class T>
37210464SAndreas.Sandberg@ARM.comFault
37310464SAndreas.Sandberg@ARM.comSimpleCPU::read(Addr addr, T &data, unsigned flags)
37410464SAndreas.Sandberg@ARM.com{
37510464SAndreas.Sandberg@ARM.com    memReq->reset(addr, sizeof(T), flags);
37610464SAndreas.Sandberg@ARM.com
37710464SAndreas.Sandberg@ARM.com    // translate to physical address
37810464SAndreas.Sandberg@ARM.com    Fault fault = xc->translateDataReadReq(memReq);
37910464SAndreas.Sandberg@ARM.com
38010464SAndreas.Sandberg@ARM.com    // do functional access
38110464SAndreas.Sandberg@ARM.com    if (fault == No_Fault)
38210464SAndreas.Sandberg@ARM.com        fault = xc->read(memReq, data);
38310464SAndreas.Sandberg@ARM.com
3841917SN/A    if (traceData) {
3851917SN/A        traceData->setAddr(addr);
3862SN/A        if (fault == No_Fault)
3872SN/A            traceData->setData(data);
388729SN/A    }
389707SN/A
390707SN/A    // if we have a cache, do cache access too
391707SN/A    if (fault == No_Fault && dcacheInterface) {
392707SN/A        memReq->cmd = Read;
393707SN/A        memReq->completionEvent = NULL;
394707SN/A        memReq->time = curTick;
3957914SBrad.Beckmann@amd.com        MemAccessResult result = dcacheInterface->access(memReq);
3967914SBrad.Beckmann@amd.com
3977914SBrad.Beckmann@amd.com        // Ugly hack to get an event scheduled *only* if the access is
3987914SBrad.Beckmann@amd.com        // a miss.  We really should add first-class support for this
3997914SBrad.Beckmann@amd.com        // at some point.
4007914SBrad.Beckmann@amd.com        if (result != MA_HIT && dcacheInterface->doEvents()) {
4017914SBrad.Beckmann@amd.com            memReq->completionEvent = &cacheCompletionEvent;
4027914SBrad.Beckmann@amd.com            lastDcacheStall = curTick;
4037914SBrad.Beckmann@amd.com            unscheduleTickEvent();
4047914SBrad.Beckmann@amd.com            _status = DcacheMissStall;
4052680Sktlim@umich.edu        }
4062SN/A    }
4072SN/A
4082SN/A    return fault;
4092SN/A}
4102680Sktlim@umich.edu
4112SN/A#ifndef DOXYGEN_SHOULD_SKIP_THIS
4122SN/A
4132680Sktlim@umich.edutemplate
4142SN/AFault
4152SN/ASimpleCPU::read(Addr addr, uint64_t &data, unsigned flags);
4169294Sandreas.hansson@arm.com
4179294Sandreas.hansson@arm.comtemplate
4188850Sandreas.hansson@arm.comFault
4198850Sandreas.hansson@arm.comSimpleCPU::read(Addr addr, uint32_t &data, unsigned flags);
4208850Sandreas.hansson@arm.com
4218850Sandreas.hansson@arm.comtemplate
4229608Sandreas.hansson@arm.comFault
4238850Sandreas.hansson@arm.comSimpleCPU::read(Addr addr, uint16_t &data, unsigned flags);
4248922Swilliam.wang@arm.com
4258850Sandreas.hansson@arm.comtemplate
4268922Swilliam.wang@arm.comFault
4278850Sandreas.hansson@arm.comSimpleCPU::read(Addr addr, uint8_t &data, unsigned flags);
4288922Swilliam.wang@arm.com
4298850Sandreas.hansson@arm.com#endif //DOXYGEN_SHOULD_SKIP_THIS
4308850Sandreas.hansson@arm.com
431180SN/Atemplate<>
4322680Sktlim@umich.eduFault
433180SN/ASimpleCPU::read(Addr addr, double &data, unsigned flags)
4346221Snate@binkert.org{
4356221Snate@binkert.org    return read(addr, *(uint64_t*)&data, flags);
4366221Snate@binkert.org}
4372378SN/A
4385718Shsul@eecs.umich.edutemplate<>
4395718Shsul@eecs.umich.eduFault
4405718Shsul@eecs.umich.eduSimpleCPU::read(Addr addr, float &data, unsigned flags)
4415718Shsul@eecs.umich.edu{
4425718Shsul@eecs.umich.edu    return read(addr, *(uint32_t*)&data, flags);
4435718Shsul@eecs.umich.edu}
4445718Shsul@eecs.umich.edu
4456221Snate@binkert.org
4465718Shsul@eecs.umich.edutemplate<>
4475718Shsul@eecs.umich.eduFault
4485718Shsul@eecs.umich.eduSimpleCPU::read(Addr addr, int32_t &data, unsigned flags)
4498779Sgblack@eecs.umich.edu{
4508779Sgblack@eecs.umich.edu    return read(addr, (uint32_t&)data, flags);
4518779Sgblack@eecs.umich.edu}
452180SN/A
453180SN/A
454180SN/Atemplate <class T>
455180SN/AFault
4564000Ssaidi@eecs.umich.eduSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
4574000Ssaidi@eecs.umich.edu{
4584000Ssaidi@eecs.umich.edu    if (traceData) {
4596221Snate@binkert.org        traceData->setAddr(addr);
4606221Snate@binkert.org        traceData->setData(data);
4616221Snate@binkert.org    }
4626221Snate@binkert.org
4634000Ssaidi@eecs.umich.edu    memReq->reset(addr, sizeof(T), flags);
4644000Ssaidi@eecs.umich.edu
4654000Ssaidi@eecs.umich.edu    // translate to physical address
4664000Ssaidi@eecs.umich.edu    Fault fault = xc->translateDataWriteReq(memReq);
467180SN/A
4682798Sktlim@umich.edu    // do functional access
469180SN/A    if (fault == No_Fault)
4709430SAndreas.Sandberg@ARM.com        fault = xc->write(memReq, data);
4719430SAndreas.Sandberg@ARM.com
4722359SN/A    if (fault == No_Fault && dcacheInterface) {
4735606Snate@binkert.org        memReq->cmd = Write;
4749446SAndreas.Sandberg@ARM.com        memcpy(memReq->data,(uint8_t *)&data,memReq->size);
4759446SAndreas.Sandberg@ARM.com        memReq->completionEvent = NULL;
4769446SAndreas.Sandberg@ARM.com        memReq->time = curTick;
4779446SAndreas.Sandberg@ARM.com        MemAccessResult result = dcacheInterface->access(memReq);
478180SN/A
479180SN/A        // Ugly hack to get an event scheduled *only* if the access is
480180SN/A        // a miss.  We really should add first-class support for this
4818737Skoansin.tan@gmail.com        // at some point.
482180SN/A        if (result != MA_HIT && dcacheInterface->doEvents()) {
4832680Sktlim@umich.edu            memReq->completionEvent = &cacheCompletionEvent;
4849152Satgutier@umich.edu            lastDcacheStall = curTick;
4859430SAndreas.Sandberg@ARM.com            unscheduleTickEvent();
4869430SAndreas.Sandberg@ARM.com            _status = DcacheMissStall;
4879332Sdam.sunwoo@arm.com        }
4889332Sdam.sunwoo@arm.com    }
4899430SAndreas.Sandberg@ARM.com
4905712Shsul@eecs.umich.edu    if (res && (fault == No_Fault))
4916221Snate@binkert.org        *res = memReq->result;
4926221Snate@binkert.org
4932680Sktlim@umich.edu    return fault;
4942680Sktlim@umich.edu}
495180SN/A
4962680Sktlim@umich.edu
4972651Ssaidi@eecs.umich.edu#ifndef DOXYGEN_SHOULD_SKIP_THIS
4982680Sktlim@umich.edutemplate
4992651Ssaidi@eecs.umich.eduFault
5005714Shsul@eecs.umich.eduSimpleCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res);
5015715Shsul@eecs.umich.edu
5025714Shsul@eecs.umich.edutemplate
5032359SN/AFault
5045875Ssteve.reinhardt@amd.comSimpleCPU::write(uint32_t data, Addr addr, unsigned flags, uint64_t *res);
5055875Ssteve.reinhardt@amd.com
5065875Ssteve.reinhardt@amd.comtemplate
5075875Ssteve.reinhardt@amd.comFault
5085217Ssaidi@eecs.umich.eduSimpleCPU::write(uint16_t data, Addr addr, unsigned flags, uint64_t *res);
5095875Ssteve.reinhardt@amd.com
5107781SAli.Saidi@ARM.comtemplate
5119294Sandreas.hansson@arm.comFault
5129294Sandreas.hansson@arm.comSimpleCPU::write(uint8_t data, Addr addr, unsigned flags, uint64_t *res);
5139294Sandreas.hansson@arm.com
5149294Sandreas.hansson@arm.com#endif //DOXYGEN_SHOULD_SKIP_THIS
5157781SAli.Saidi@ARM.com
5167781SAli.Saidi@ARM.comtemplate<>
5179178Sandreas.hansson@arm.comFault
5189178Sandreas.hansson@arm.comSimpleCPU::write(double data, Addr addr, unsigned flags, uint64_t *res)
5197781SAli.Saidi@ARM.com{
5209178Sandreas.hansson@arm.com    return write(*(uint64_t*)&data, addr, flags, res);
5219294Sandreas.hansson@arm.com}
5229178Sandreas.hansson@arm.com
5238922Swilliam.wang@arm.comtemplate<>
5247781SAli.Saidi@ARM.comFault
5259178Sandreas.hansson@arm.comSimpleCPU::write(float data, Addr addr, unsigned flags, uint64_t *res)
5269178Sandreas.hansson@arm.com{
5277781SAli.Saidi@ARM.com    return write(*(uint32_t*)&data, addr, flags, res);
5289178Sandreas.hansson@arm.com}
5299294Sandreas.hansson@arm.com
5309178Sandreas.hansson@arm.com
5318922Swilliam.wang@arm.comtemplate<>
5327781SAli.Saidi@ARM.comFault
53310194SGeoffrey.Blake@arm.comSimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
53410194SGeoffrey.Blake@arm.com{
5358733Sgeoffrey.blake@arm.com    return write((uint32_t)data, addr, flags, res);
5368887Sgeoffrey.blake@arm.com}
5378887Sgeoffrey.blake@arm.com
5388887Sgeoffrey.blake@arm.com
5398887Sgeoffrey.blake@arm.com#ifdef FULL_SYSTEM
5408887Sgeoffrey.blake@arm.comAddr
5419294Sandreas.hansson@arm.comSimpleCPU::dbg_vtophys(Addr addr)
5428922Swilliam.wang@arm.com{
5439294Sandreas.hansson@arm.com    return vtophys(xc, addr);
5448922Swilliam.wang@arm.com}
5459294Sandreas.hansson@arm.com#endif // FULL_SYSTEM
5468922Swilliam.wang@arm.com
5479294Sandreas.hansson@arm.comTick save_cycle = 0;
5488922Swilliam.wang@arm.com
5498733Sgeoffrey.blake@arm.com
55010194SGeoffrey.Blake@arm.comvoid
55110194SGeoffrey.Blake@arm.comSimpleCPU::processCacheCompletion()
55210194SGeoffrey.Blake@arm.com{
5538887Sgeoffrey.blake@arm.com    switch (status()) {
5549178Sandreas.hansson@arm.com      case IcacheMissStall:
5559178Sandreas.hansson@arm.com        icacheStallCycles += curTick - lastIcacheStall;
5568887Sgeoffrey.blake@arm.com        _status = IcacheMissComplete;
5579178Sandreas.hansson@arm.com        scheduleTickEvent(1);
5589294Sandreas.hansson@arm.com        break;
5599294Sandreas.hansson@arm.com      case DcacheMissStall:
5609178Sandreas.hansson@arm.com        dcacheStallCycles += curTick - lastDcacheStall;
5618922Swilliam.wang@arm.com        _status = Running;
5628887Sgeoffrey.blake@arm.com        scheduleTickEvent(1);
5639178Sandreas.hansson@arm.com        break;
5649178Sandreas.hansson@arm.com      case SwitchedOut:
5658887Sgeoffrey.blake@arm.com        // If this CPU has been switched out due to sampling/warm-up,
5669178Sandreas.hansson@arm.com        // ignore any further status changes (e.g., due to cache
5679294Sandreas.hansson@arm.com        // misses outstanding at the time of the switch).
5689294Sandreas.hansson@arm.com        return;
5699178Sandreas.hansson@arm.com      default:
5708922Swilliam.wang@arm.com        panic("SimpleCPU::processCacheCompletion: bad state");
5718887Sgeoffrey.blake@arm.com        break;
5728733Sgeoffrey.blake@arm.com    }
573180SN/A}
574605SN/A
5753520Sgblack@eecs.umich.edu#ifdef FULL_SYSTEM
5765810Sgblack@eecs.umich.eduvoid
5779152Satgutier@umich.eduSimpleCPU::post_interrupt(int int_num, int index)
5782254SN/A{
5798779Sgblack@eecs.umich.edu    BaseCPU::post_interrupt(int_num, index);
5808779Sgblack@eecs.umich.edu
5818779Sgblack@eecs.umich.edu    if (xc->status() == ExecContext::Suspended) {
5822254SN/A                DPRINTF(IPI,"Suspended Processor awoke\n");
5838779Sgblack@eecs.umich.edu        xc->activate();
5848779Sgblack@eecs.umich.edu        Annotate::Resume(xc);
5858779Sgblack@eecs.umich.edu    }
5864192Sktlim@umich.edu}
5879178Sandreas.hansson@arm.com#endif // FULL_SYSTEM
5889178Sandreas.hansson@arm.com
5899178Sandreas.hansson@arm.com/* start simulation, program loaded, processor precise state initialized */
5909178Sandreas.hansson@arm.comvoid
5919178Sandreas.hansson@arm.comSimpleCPU::tick()
5929178Sandreas.hansson@arm.com{
5939294Sandreas.hansson@arm.com    traceData = NULL;
5949178Sandreas.hansson@arm.com
5959178Sandreas.hansson@arm.com    Fault fault = No_Fault;
5964192Sktlim@umich.edu
5979178Sandreas.hansson@arm.com#ifdef FULL_SYSTEM
5989178Sandreas.hansson@arm.com    if (AlphaISA::check_interrupts &&
5999294Sandreas.hansson@arm.com        xc->cpu->check_interrupts() &&
6009178Sandreas.hansson@arm.com        !PC_PAL(xc->regs.pc) &&
6019178Sandreas.hansson@arm.com        status() != IcacheMissComplete) {
602180SN/A        int ipl = 0;
603180SN/A        int summary = 0;
6049446SAndreas.Sandberg@ARM.com        AlphaISA::check_interrupts = 0;
6059446SAndreas.Sandberg@ARM.com        IntReg *ipr = xc->regs.ipr;
6069446SAndreas.Sandberg@ARM.com
6079446SAndreas.Sandberg@ARM.com        if (xc->regs.ipr[TheISA::IPR_SIRR]) {
6089446SAndreas.Sandberg@ARM.com            for (int i = TheISA::INTLEVEL_SOFTWARE_MIN;
6099446SAndreas.Sandberg@ARM.com                 i < TheISA::INTLEVEL_SOFTWARE_MAX; i++) {
6109446SAndreas.Sandberg@ARM.com                if (ipr[TheISA::IPR_SIRR] & (ULL(1) << i)) {
6119446SAndreas.Sandberg@ARM.com                    // See table 4-19 of 21164 hardware reference
6129446SAndreas.Sandberg@ARM.com                    ipl = (i - TheISA::INTLEVEL_SOFTWARE_MIN) + 1;
6139446SAndreas.Sandberg@ARM.com                    summary |= (ULL(1) << i);
6149446SAndreas.Sandberg@ARM.com                }
6159446SAndreas.Sandberg@ARM.com            }
6169446SAndreas.Sandberg@ARM.com        }
6179446SAndreas.Sandberg@ARM.com
6189446SAndreas.Sandberg@ARM.com        uint64_t interrupts = xc->cpu->intr_status();
6199446SAndreas.Sandberg@ARM.com        for (int i = TheISA::INTLEVEL_EXTERNAL_MIN;
620180SN/A            i < TheISA::INTLEVEL_EXTERNAL_MAX; i++) {
6215536Srstrong@hp.com            if (interrupts & (ULL(1) << i)) {
6225606Snate@binkert.org                // See table 4-19 of 21164 hardware reference
6231917SN/A                ipl = i;
6241917SN/A                summary |= (ULL(1) << i);
6251917SN/A            }
6261917SN/A        }
6271917SN/A
6286221Snate@binkert.org        if (ipr[TheISA::IPR_ASTRR])
6296221Snate@binkert.org            panic("asynchronous traps not implemented\n");
6302680Sktlim@umich.edu
6312680Sktlim@umich.edu        if (ipl && ipl > xc->regs.ipr[TheISA::IPR_IPLR]) {
6321917SN/A            ipr[TheISA::IPR_ISR] = summary;
6332254SN/A            ipr[TheISA::IPR_INTID] = ipl;
6347823Ssteve.reinhardt@amd.com            xc->ev5_trap(Interrupt_Fault);
6351917SN/A
6361917SN/A            DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
6372SN/A                    ipr[TheISA::IPR_IPLR], ipl, summary);
638921SN/A        }
639921SN/A    }
6404000Ssaidi@eecs.umich.edu#endif
6419332Sdam.sunwoo@arm.com
6429448SAndreas.Sandberg@ARM.com    // maintain $r0 semantics
6439448SAndreas.Sandberg@ARM.com    xc->regs.intRegFile[ZeroReg] = 0;
6449448SAndreas.Sandberg@ARM.com#ifdef TARGET_ALPHA
6459448SAndreas.Sandberg@ARM.com    xc->regs.floatRegFile.d[ZeroReg] = 0.0;
6469448SAndreas.Sandberg@ARM.com#endif // TARGET_ALPHA
6479448SAndreas.Sandberg@ARM.com
6489332Sdam.sunwoo@arm.com    if (status() == IcacheMissComplete) {
6499448SAndreas.Sandberg@ARM.com        // We've already fetched an instruction and were stalled on an
6509448SAndreas.Sandberg@ARM.com        // I-cache miss.  No need to fetch it again.
6519448SAndreas.Sandberg@ARM.com
6529448SAndreas.Sandberg@ARM.com        // Set status to running; tick event will get rescheduled if
6539448SAndreas.Sandberg@ARM.com        // necessary at end of tick() function.
6549448SAndreas.Sandberg@ARM.com        _status = Running;
6559448SAndreas.Sandberg@ARM.com    }
6569448SAndreas.Sandberg@ARM.com    else {
657921SN/A        // Try to fetch an instruction
658921SN/A
659921SN/A        // set up memory request for instruction fetch
660921SN/A#ifdef FULL_SYSTEM
661921SN/A#define IFETCH_FLAGS(pc)	((pc) & 1) ? PHYSICAL : 0
6624000Ssaidi@eecs.umich.edu#else
6639448SAndreas.Sandberg@ARM.com#define IFETCH_FLAGS(pc)	0
6649448SAndreas.Sandberg@ARM.com#endif
6659448SAndreas.Sandberg@ARM.com
6669448SAndreas.Sandberg@ARM.com        memReq->cmd = Read;
6679448SAndreas.Sandberg@ARM.com        memReq->reset(xc->regs.pc & ~3, sizeof(uint32_t),
6689448SAndreas.Sandberg@ARM.com                     IFETCH_FLAGS(xc->regs.pc));
6699448SAndreas.Sandberg@ARM.com
6709448SAndreas.Sandberg@ARM.com        fault = xc->translateInstReq(memReq);
6719448SAndreas.Sandberg@ARM.com
672921SN/A        if (fault == No_Fault)
673921SN/A            fault = xc->mem->read(memReq, inst);
6741191SN/A
6759749Sandreas@sandberg.pp.se        if (icacheInterface && fault == No_Fault) {
6769749Sandreas@sandberg.pp.se            memReq->completionEvent = NULL;
6779749Sandreas@sandberg.pp.se
6789983Sstever@gmail.com            memReq->time = curTick;
6799749Sandreas@sandberg.pp.se            MemAccessResult result = icacheInterface->access(memReq);
6809749Sandreas@sandberg.pp.se
6819749Sandreas@sandberg.pp.se            // Ugly hack to get an event scheduled *only* if the access is
6829749Sandreas@sandberg.pp.se            // a miss.  We really should add first-class support for this
68310529Smorr@cs.wisc.edu            // at some point.
68410529Smorr@cs.wisc.edu            if (result != MA_HIT && icacheInterface->doEvents()) {
68510529Smorr@cs.wisc.edu                memReq->completionEvent = &cacheCompletionEvent;
68610529Smorr@cs.wisc.edu                lastIcacheStall = curTick;
68710529Smorr@cs.wisc.edu                unscheduleTickEvent();
68810529Smorr@cs.wisc.edu                _status = IcacheMissStall;
68910529Smorr@cs.wisc.edu                return;
69010529Smorr@cs.wisc.edu            }
69110529Smorr@cs.wisc.edu        }
69210529Smorr@cs.wisc.edu    }
69310529Smorr@cs.wisc.edu
69410529Smorr@cs.wisc.edu    // If we've got a valid instruction (i.e., no fault on instruction
69510529Smorr@cs.wisc.edu    // fetch), then execute it.
69610529Smorr@cs.wisc.edu    if (fault == No_Fault) {
69710529Smorr@cs.wisc.edu
69810529Smorr@cs.wisc.edu        // keep an instruction count
69910529Smorr@cs.wisc.edu        numInst++;
70010529Smorr@cs.wisc.edu
70110529Smorr@cs.wisc.edu        // check for instruction-count-based events
7029749Sandreas@sandberg.pp.se        comInstEventQueue[0]->serviceEvents(numInst);
7039749Sandreas@sandberg.pp.se
7049749Sandreas@sandberg.pp.se        // decode the instruction
7059749Sandreas@sandberg.pp.se        StaticInstPtr<TheISA> si(inst);
7069983Sstever@gmail.com
7079749Sandreas@sandberg.pp.se        traceData = Trace::getInstRecord(curTick, xc, this, si,
7089749Sandreas@sandberg.pp.se                                         xc->regs.pc);
7099749Sandreas@sandberg.pp.se
7109749Sandreas@sandberg.pp.se#ifdef FULL_SYSTEM
7119749Sandreas@sandberg.pp.se        xc->regs.opcode = (inst >> 26) & 0x3f;
7129749Sandreas@sandberg.pp.se        xc->regs.ra = (inst >> 21) & 0x1f;
7131191SN/A#endif // FULL_SYSTEM
7141191SN/A
7151191SN/A        xc->func_exe_inst++;
7161191SN/A
7171191SN/A        fault = si->execute(this, xc, traceData);
7181191SN/A#ifdef FS_MEASURE
7191191SN/A        if (!(xc->misspeculating()) && (xc->system->bin)) {
7201191SN/A            SWContext *ctx = xc->swCtx;
7211191SN/A            if (ctx && !ctx->callStack.empty()) {
7221191SN/A                if (si->isCall()) {
7231191SN/A                    ctx->calls++;
7241191SN/A                }
7251191SN/A                if (si->isReturn()) {
7261191SN/A                     if (ctx->calls == 0) {
7271191SN/A                        fnCall *top = ctx->callStack.top();
7281191SN/A                        DPRINTF(TCPIP, "Removing %s from callstack.\n", top->name);
7291191SN/A                        delete top;
7301191SN/A                        ctx->callStack.pop();
7311191SN/A                        if (ctx->callStack.empty())
7321191SN/A                            xc->system->nonPath->activate();
7331191SN/A                        else
7347823Ssteve.reinhardt@amd.com                            ctx->callStack.top()->myBin->activate();
7357823Ssteve.reinhardt@amd.com
7361191SN/A                        xc->system->dumpState(xc);
7371191SN/A                    } else {
738                        ctx->calls--;
739                    }
740                }
741            }
742        }
743#endif
744        if (si->isMemRef()) {
745            numMemRefs++;
746        }
747
748        if (si->isLoad()) {
749            ++numLoad;
750            comLoadEventQueue[0]->serviceEvents(numLoad);
751        }
752
753        if (traceData)
754            traceData->finalize();
755
756    }	// if (fault == No_Fault)
757
758    if (fault != No_Fault) {
759#ifdef FULL_SYSTEM
760        xc->ev5_trap(fault);
761#else // !FULL_SYSTEM
762        fatal("fault (%d) detected @ PC 0x%08p", fault, xc->regs.pc);
763#endif // FULL_SYSTEM
764    }
765    else {
766        // go to the next instruction
767        xc->regs.pc = xc->regs.npc;
768        xc->regs.npc += sizeof(MachInst);
769    }
770
771#ifdef FULL_SYSTEM
772    Addr oldpc;
773    do {
774        oldpc = xc->regs.pc;
775        system->pcEventQueue.service(xc);
776    } while (oldpc != xc->regs.pc);
777#endif
778
779    assert(status() == Running ||
780           status() == Idle ||
781           status() == DcacheMissStall);
782
783    if (status() == Running && !tickEvent.scheduled())
784        tickEvent.schedule(curTick + 1);
785}
786
787
788////////////////////////////////////////////////////////////////////////
789//
790//  SimpleCPU Simulation Object
791//
792BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
793
794    Param<Counter> max_insts_any_thread;
795    Param<Counter> max_insts_all_threads;
796    Param<Counter> max_loads_any_thread;
797    Param<Counter> max_loads_all_threads;
798
799#ifdef FULL_SYSTEM
800    SimObjectParam<AlphaItb *> itb;
801    SimObjectParam<AlphaDtb *> dtb;
802    SimObjectParam<FunctionalMemory *> mem;
803    SimObjectParam<System *> system;
804    Param<int> mult;
805#else
806    SimObjectParam<Process *> workload;
807#endif // FULL_SYSTEM
808
809    SimObjectParam<BaseMem *> icache;
810    SimObjectParam<BaseMem *> dcache;
811
812    Param<bool> defer_registration;
813
814END_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
815
816BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
817
818    INIT_PARAM_DFLT(max_insts_any_thread,
819                    "terminate when any thread reaches this inst count",
820                    0),
821    INIT_PARAM_DFLT(max_insts_all_threads,
822                    "terminate when all threads have reached this inst count",
823                    0),
824    INIT_PARAM_DFLT(max_loads_any_thread,
825                    "terminate when any thread reaches this load count",
826                    0),
827    INIT_PARAM_DFLT(max_loads_all_threads,
828                    "terminate when all threads have reached this load count",
829                    0),
830
831#ifdef FULL_SYSTEM
832    INIT_PARAM(itb, "Instruction TLB"),
833    INIT_PARAM(dtb, "Data TLB"),
834    INIT_PARAM(mem, "memory"),
835    INIT_PARAM(system, "system object"),
836    INIT_PARAM_DFLT(mult, "system clock multiplier", 1),
837#else
838    INIT_PARAM(workload, "processes to run"),
839#endif // FULL_SYSTEM
840
841    INIT_PARAM_DFLT(icache, "L1 instruction cache object", NULL),
842    INIT_PARAM_DFLT(dcache, "L1 data cache object", NULL),
843    INIT_PARAM_DFLT(defer_registration, "defer registration with system "
844                    "(for sampling)", false)
845
846END_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
847
848
849CREATE_SIM_OBJECT(SimpleCPU)
850{
851    SimpleCPU *cpu;
852#ifdef FULL_SYSTEM
853    if (mult != 1)
854        panic("processor clock multiplier must be 1\n");
855
856    cpu = new SimpleCPU(getInstanceName(), system,
857                        max_insts_any_thread, max_insts_all_threads,
858                        max_loads_any_thread, max_loads_all_threads,
859                        itb, dtb, mem,
860                        (icache) ? icache->getInterface() : NULL,
861                        (dcache) ? dcache->getInterface() : NULL,
862                        defer_registration,
863                        ticksPerSecond * mult);
864#else
865
866    cpu = new SimpleCPU(getInstanceName(), workload,
867                        max_insts_any_thread, max_insts_all_threads,
868                        max_loads_any_thread, max_loads_all_threads,
869                        (icache) ? icache->getInterface() : NULL,
870                        (dcache) ? dcache->getInterface() : NULL,
871                        defer_registration);
872
873#endif // FULL_SYSTEM
874#if 0
875    if (!defer_registration) {
876        cpu->registerExecContexts();
877    }
878#endif
879    return cpu;
880}
881
882REGISTER_SIM_OBJECT("SimpleCPU", SimpleCPU)
883
884