timing.cc revision 2630
12623SN/A/*
210596Sgabeblack@google.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
312276Sanouk.vanlaer@arm.com * All rights reserved.
47725SAli.Saidi@ARM.com *
57725SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without
67725SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are
77725SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright
87725SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer;
97725SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright
107725SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the
117725SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution;
127725SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its
137725SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from
147725SAli.Saidi@ARM.com * this software without specific prior written permission.
152623SN/A *
162623SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172623SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182623SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192623SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202623SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212623SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222623SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232623SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242623SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252623SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262623SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272623SN/A */
282623SN/A
292623SN/A#include "arch/utility.hh"
302623SN/A#include "cpu/exetrace.hh"
312623SN/A#include "cpu/simple/timing.hh"
322623SN/A#include "mem/packet_impl.hh"
332623SN/A#include "sim/builder.hh"
342623SN/A
352623SN/Ausing namespace std;
362623SN/Ausing namespace TheISA;
372623SN/A
382623SN/A
392623SN/Avoid
402665Ssaidi@eecs.umich.eduTimingSimpleCPU::init()
412665Ssaidi@eecs.umich.edu{
422623SN/A    //Create Memory Ports (conect them up)
432623SN/A    Port *mem_dport = mem->getPort("");
4411793Sbrandon.potter@amd.com    dcachePort.setPeer(mem_dport);
4511793Sbrandon.potter@amd.com    mem_dport->setPeer(&dcachePort);
463170Sstever@eecs.umich.edu
478105Sgblack@eecs.umich.edu    Port *mem_iport = mem->getPort("");
482623SN/A    icachePort.setPeer(mem_iport);
496658Snate@binkert.org    mem_iport->setPeer(&icachePort);
502623SN/A
518232Snate@binkert.org    BaseCPU::init();
529152Satgutier@umich.edu#if FULL_SYSTEM
538232Snate@binkert.org    for (int i = 0; i < execContexts.size(); ++i) {
5411793Sbrandon.potter@amd.com        ExecContext *xc = execContexts[i];
558232Snate@binkert.org
563348Sbinkertn@umich.edu        // initialize CPU, including PC
573348Sbinkertn@umich.edu        TheISA::initCPU(xc, xc->readCpuId());
584762Snate@binkert.org    }
597678Sgblack@eecs.umich.edu#endif
608779Sgblack@eecs.umich.edu}
612901Ssaidi@eecs.umich.edu
622623SN/ATick
632623SN/ATimingSimpleCPU::CpuPort::recvAtomic(Packet *pkt)
642623SN/A{
652623SN/A    panic("TimingSimpleCPU doesn't expect recvAtomic callback!");
662623SN/A    return curTick;
672623SN/A}
682623SN/A
6911147Smitch.hayenga@arm.comvoid
702623SN/ATimingSimpleCPU::CpuPort::recvFunctional(Packet *pkt)
712623SN/A{
722623SN/A    panic("TimingSimpleCPU doesn't expect recvFunctional callback!");
738707Sandreas.hansson@arm.com}
742948Ssaidi@eecs.umich.edu
752948Ssaidi@eecs.umich.eduvoid
765606Snate@binkert.orgTimingSimpleCPU::CpuPort::recvStatusChange(Status status)
772948Ssaidi@eecs.umich.edu{
782948Ssaidi@eecs.umich.edu    panic("TimingSimpleCPU doesn't expect recvStatusChange callback!");
795529Snate@binkert.org}
808707Sandreas.hansson@arm.com
819179Sandreas.hansson@arm.comTimingSimpleCPU::TimingSimpleCPU(Params *p)
8212085Sspwilson2@wisc.edu    : BaseSimpleCPU(p), icachePort(this), dcachePort(this)
832623SN/A{
842623SN/A    _status = Idle;
852623SN/A    ifetch_pkt = dcache_pkt = NULL;
862623SN/A}
872623SN/A
8810030SAli.Saidi@ARM.com
892623SN/ATimingSimpleCPU::~TimingSimpleCPU()
902623SN/A{
912623SN/A}
922623SN/A
9310913Sandreas.sandberg@arm.comvoid
9410913Sandreas.sandberg@arm.comTimingSimpleCPU::serialize(ostream &os)
952798Sktlim@umich.edu{
9612276Sanouk.vanlaer@arm.com    BaseSimpleCPU::serialize(os);
9712276Sanouk.vanlaer@arm.com    SERIALIZE_ENUM(_status);
9812276Sanouk.vanlaer@arm.com}
999448SAndreas.Sandberg@ARM.com
10010913Sandreas.sandberg@arm.comvoid
1019448SAndreas.Sandberg@ARM.comTimingSimpleCPU::unserialize(Checkpoint *cp, const string &section)
1029342SAndreas.Sandberg@arm.com{
1039448SAndreas.Sandberg@ARM.com    BaseSimpleCPU::unserialize(cp, section);
1049442SAndreas.Sandberg@ARM.com    UNSERIALIZE_ENUM(_status);
10511147Smitch.hayenga@arm.com}
10610913Sandreas.sandberg@arm.com
1072798Sktlim@umich.eduvoid
10811147Smitch.hayenga@arm.comTimingSimpleCPU::switchOut(Sampler *s)
1099442SAndreas.Sandberg@ARM.com{
1109442SAndreas.Sandberg@ARM.com    sampler = s;
1119442SAndreas.Sandberg@ARM.com    if (status() == Running) {
1129442SAndreas.Sandberg@ARM.com        _status = SwitchedOut;
1139448SAndreas.Sandberg@ARM.com    }
1149648Sdam.sunwoo@arm.com    sampler->signalSwitched();
1159442SAndreas.Sandberg@ARM.com}
11610913Sandreas.sandberg@arm.com
1172798Sktlim@umich.edu
1182623SN/Avoid
1192623SN/ATimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
1202623SN/A{
1219342SAndreas.Sandberg@arm.com    BaseCPU::takeOverFrom(oldCPU);
1222623SN/A
1239442SAndreas.Sandberg@ARM.com    // if any of this CPU's ExecContexts are active, mark the CPU as
1249448SAndreas.Sandberg@ARM.com    // running and schedule its tick event.
1259448SAndreas.Sandberg@ARM.com    for (int i = 0; i < execContexts.size(); ++i) {
1269442SAndreas.Sandberg@ARM.com        ExecContext *xc = execContexts[i];
1275221Ssaidi@eecs.umich.edu        if (xc->status() == ExecContext::Active && _status != Running) {
1289523SAndreas.Sandberg@ARM.com            _status = Running;
1293201Shsul@eecs.umich.edu            break;
1309448SAndreas.Sandberg@ARM.com        }
1319448SAndreas.Sandberg@ARM.com    }
13211147Smitch.hayenga@arm.com}
13311147Smitch.hayenga@arm.com
13411147Smitch.hayenga@arm.com
13511147Smitch.hayenga@arm.comvoid
13611147Smitch.hayenga@arm.comTimingSimpleCPU::activateContext(int thread_num, int delay)
13711147Smitch.hayenga@arm.com{
13811147Smitch.hayenga@arm.com    assert(thread_num == 0);
13911147Smitch.hayenga@arm.com    assert(cpuXC);
14011147Smitch.hayenga@arm.com
14111147Smitch.hayenga@arm.com    assert(_status == Idle);
14211147Smitch.hayenga@arm.com
14311147Smitch.hayenga@arm.com    notIdleFraction++;
14411147Smitch.hayenga@arm.com    _status = Running;
14511147Smitch.hayenga@arm.com    // kick things off by initiating the fetch of the next instruction
14611147Smitch.hayenga@arm.com    Event *e =
14711147Smitch.hayenga@arm.com        new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, true);
14811147Smitch.hayenga@arm.com    e->schedule(curTick + cycles(delay));
1492623SN/A}
15011147Smitch.hayenga@arm.com
15112276Sanouk.vanlaer@arm.com
15212276Sanouk.vanlaer@arm.comvoid
15312276Sanouk.vanlaer@arm.comTimingSimpleCPU::suspendContext(int thread_num)
15411147Smitch.hayenga@arm.com{
1559442SAndreas.Sandberg@ARM.com    assert(thread_num == 0);
1562798Sktlim@umich.edu    assert(cpuXC);
1579442SAndreas.Sandberg@ARM.com
1589442SAndreas.Sandberg@ARM.com    panic("TimingSimpleCPU::suspendContext not implemented");
1599442SAndreas.Sandberg@ARM.com
16010913Sandreas.sandberg@arm.com    assert(_status == Running);
1619442SAndreas.Sandberg@ARM.com
1629442SAndreas.Sandberg@ARM.com    notIdleFraction--;
16311147Smitch.hayenga@arm.com    _status = Idle;
1649442SAndreas.Sandberg@ARM.com}
1659442SAndreas.Sandberg@ARM.com
1669442SAndreas.Sandberg@ARM.com
1679442SAndreas.Sandberg@ARM.comtemplate <class T>
16810913Sandreas.sandberg@arm.comFault
1699442SAndreas.Sandberg@ARM.comTimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
1709442SAndreas.Sandberg@ARM.com{
1712798Sktlim@umich.edu    Request *data_read_req = new Request(true);
1722798Sktlim@umich.edu
1732798Sktlim@umich.edu    data_read_req->setVaddr(addr);
1742798Sktlim@umich.edu    data_read_req->setSize(sizeof(T));
1752798Sktlim@umich.edu    data_read_req->setFlags(flags);
17611147Smitch.hayenga@arm.com    data_read_req->setTime(curTick);
17711147Smitch.hayenga@arm.com
17811147Smitch.hayenga@arm.com    if (traceData) {
1799429SAndreas.Sandberg@ARM.com        traceData->setAddr(data_read_req->getVaddr());
1809429SAndreas.Sandberg@ARM.com    }
1819442SAndreas.Sandberg@ARM.com
1829342SAndreas.Sandberg@arm.com   // translate to physical address
18311147Smitch.hayenga@arm.com    Fault fault = cpuXC->translateDataReadReq(data_read_req);
18411147Smitch.hayenga@arm.com
1859442SAndreas.Sandberg@ARM.com    // Now do the access.
18610464SAndreas.Sandberg@ARM.com    if (fault == NoFault) {
18712284Sjose.marinho@arm.com        Packet *data_read_pkt = new Packet;
1882623SN/A        data_read_pkt->cmd = Read;
1892623SN/A        data_read_pkt->req = data_read_req;
1902623SN/A        data_read_pkt->dataDynamic<T>(new T);
1912623SN/A        data_read_pkt->addr = data_read_req->getPaddr();
1922623SN/A        data_read_pkt->size = sizeof(T);
1932623SN/A        data_read_pkt->dest = Packet::Broadcast;
1949429SAndreas.Sandberg@ARM.com
1952623SN/A        if (!dcachePort.sendTiming(data_read_pkt)) {
1969179Sandreas.hansson@arm.com            _status = DcacheRetry;
1972623SN/A            dcache_pkt = data_read_pkt;
1982623SN/A        } else {
1999523SAndreas.Sandberg@ARM.com            _status = DcacheWaitResponse;
2009523SAndreas.Sandberg@ARM.com            dcache_pkt = NULL;
2019523SAndreas.Sandberg@ARM.com        }
2029524SAndreas.Sandberg@ARM.com    }
2039523SAndreas.Sandberg@ARM.com
2049523SAndreas.Sandberg@ARM.com    // This will need a new way to tell if it has a dcache attached.
2059523SAndreas.Sandberg@ARM.com    if (data_read_req->getFlags() & UNCACHEABLE)
2069523SAndreas.Sandberg@ARM.com        recordEvent("Uncached Read");
2072623SN/A
2082623SN/A    return fault;
20910407Smitch.hayenga@arm.com}
2102623SN/A
21110407Smitch.hayenga@arm.com#ifndef DOXYGEN_SHOULD_SKIP_THIS
2125221Ssaidi@eecs.umich.edu
21311147Smitch.hayenga@arm.comtemplate
2142623SN/AFault
21511147Smitch.hayenga@arm.comTimingSimpleCPU::read(Addr addr, uint64_t &data, unsigned flags);
21611147Smitch.hayenga@arm.com
21711147Smitch.hayenga@arm.comtemplate
2183686Sktlim@umich.eduFault
2192623SN/ATimingSimpleCPU::read(Addr addr, uint32_t &data, unsigned flags);
22011147Smitch.hayenga@arm.com
22111147Smitch.hayenga@arm.comtemplate
22211147Smitch.hayenga@arm.comFault
22311147Smitch.hayenga@arm.comTimingSimpleCPU::read(Addr addr, uint16_t &data, unsigned flags);
22411147Smitch.hayenga@arm.com
22511147Smitch.hayenga@arm.comtemplate
22611147Smitch.hayenga@arm.comFault
22711526Sdavid.guillen@arm.comTimingSimpleCPU::read(Addr addr, uint8_t &data, unsigned flags);
22811526Sdavid.guillen@arm.com
2292623SN/A#endif //DOXYGEN_SHOULD_SKIP_THIS
2302623SN/A
2312623SN/Atemplate<>
2322623SN/AFault
2338737Skoansin.tan@gmail.comTimingSimpleCPU::read(Addr addr, double &data, unsigned flags)
2342623SN/A{
2355221Ssaidi@eecs.umich.edu    return read(addr, *(uint64_t*)&data, flags);
2365221Ssaidi@eecs.umich.edu}
23711147Smitch.hayenga@arm.com
23811147Smitch.hayenga@arm.comtemplate<>
2392623SN/AFault
2406043Sgblack@eecs.umich.eduTimingSimpleCPU::read(Addr addr, float &data, unsigned flags)
2416043Sgblack@eecs.umich.edu{
2426043Sgblack@eecs.umich.edu    return read(addr, *(uint32_t*)&data, flags);
2439342SAndreas.Sandberg@arm.com}
2442623SN/A
24511147Smitch.hayenga@arm.com
2462623SN/Atemplate<>
24711147Smitch.hayenga@arm.comFault
24811147Smitch.hayenga@arm.comTimingSimpleCPU::read(Addr addr, int32_t &data, unsigned flags)
24911147Smitch.hayenga@arm.com{
25011147Smitch.hayenga@arm.com    return read(addr, (uint32_t&)data, flags);
25111147Smitch.hayenga@arm.com}
25211147Smitch.hayenga@arm.com
25311147Smitch.hayenga@arm.com
25411526Sdavid.guillen@arm.comtemplate <class T>
25511526Sdavid.guillen@arm.comFault
2562623SN/ATimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
2572623SN/A{
2585728Sgblack@eecs.umich.edu    Request *data_write_req = new Request(true);
2595728Sgblack@eecs.umich.edu    data_write_req->setVaddr(addr);
2605728Sgblack@eecs.umich.edu    data_write_req->setTime(curTick);
26111147Smitch.hayenga@arm.com    data_write_req->setSize(sizeof(T));
26211147Smitch.hayenga@arm.com    data_write_req->setFlags(flags);
26311147Smitch.hayenga@arm.com
26412749Sgiacomo.travaglini@arm.com    // translate to physical address
26510533Sali.saidi@arm.com    Fault fault = cpuXC->translateDataWriteReq(data_write_req);
26610533Sali.saidi@arm.com    // Now do the access.
26710533Sali.saidi@arm.com    if (fault == NoFault) {
26810533Sali.saidi@arm.com        Packet *data_write_pkt = new Packet;
26910533Sali.saidi@arm.com        data_write_pkt->cmd = Write;
27010533Sali.saidi@arm.com        data_write_pkt->req = data_write_req;
2718105Sgblack@eecs.umich.edu        data_write_pkt->allocate();
2729180Sandreas.hansson@arm.com        data_write_pkt->size = sizeof(T);
2739179Sandreas.hansson@arm.com        data_write_pkt->set(data);
2745728Sgblack@eecs.umich.edu        data_write_pkt->addr = data_write_req->getPaddr();
2755728Sgblack@eecs.umich.edu        data_write_pkt->dest = Packet::Broadcast;
2768975Sandreas.hansson@arm.com
2775728Sgblack@eecs.umich.edu        if (!dcachePort.sendTiming(data_write_pkt)) {
2785728Sgblack@eecs.umich.edu            _status = DcacheRetry;
2795728Sgblack@eecs.umich.edu            dcache_pkt = data_write_pkt;
2805728Sgblack@eecs.umich.edu        } else {
2815728Sgblack@eecs.umich.edu            _status = DcacheWaitResponse;
2825728Sgblack@eecs.umich.edu            dcache_pkt = NULL;
2835728Sgblack@eecs.umich.edu        }
2845728Sgblack@eecs.umich.edu    }
2855728Sgblack@eecs.umich.edu
2862623SN/A    // This will need a new way to tell if it's hooked up to a cache or not.
2875894Sgblack@eecs.umich.edu    if (data_write_req->getFlags() & UNCACHEABLE)
28812749Sgiacomo.travaglini@arm.com        recordEvent("Uncached Write");
2896973Stjones1@inf.ed.ac.uk
2905744Sgblack@eecs.umich.edu    // If the write needs to have a fault on the access, consider calling
29111147Smitch.hayenga@arm.com    // changeStatus() and changing it to "bad addr write" or something.
29211147Smitch.hayenga@arm.com    return fault;
29311147Smitch.hayenga@arm.com}
29410653Sandreas.hansson@arm.com
29510566Sandreas.hansson@arm.com
29613652Sqtt2@cornell.edu#ifndef DOXYGEN_SHOULD_SKIP_THIS
2975894Sgblack@eecs.umich.edutemplate
2985894Sgblack@eecs.umich.eduFault
2995894Sgblack@eecs.umich.eduTimingSimpleCPU::write(uint64_t data, Addr addr,
3005894Sgblack@eecs.umich.edu                       unsigned flags, uint64_t *res);
3015894Sgblack@eecs.umich.edu
3025894Sgblack@eecs.umich.edutemplate
3035894Sgblack@eecs.umich.eduFault
3045894Sgblack@eecs.umich.eduTimingSimpleCPU::write(uint32_t data, Addr addr,
3055894Sgblack@eecs.umich.edu                       unsigned flags, uint64_t *res);
3066102Sgblack@eecs.umich.edu
30710030SAli.Saidi@ARM.comtemplate
3085894Sgblack@eecs.umich.eduFault
3095894Sgblack@eecs.umich.eduTimingSimpleCPU::write(uint16_t data, Addr addr,
3105894Sgblack@eecs.umich.edu                       unsigned flags, uint64_t *res);
3115894Sgblack@eecs.umich.edu
3125894Sgblack@eecs.umich.edutemplate
3135894Sgblack@eecs.umich.eduFault
3145894Sgblack@eecs.umich.eduTimingSimpleCPU::write(uint8_t data, Addr addr,
3155894Sgblack@eecs.umich.edu                       unsigned flags, uint64_t *res);
31611148Smitch.hayenga@arm.com
3175894Sgblack@eecs.umich.edu#endif //DOXYGEN_SHOULD_SKIP_THIS
3185894Sgblack@eecs.umich.edu
3195894Sgblack@eecs.umich.edutemplate<>
3205894Sgblack@eecs.umich.eduFault
3215894Sgblack@eecs.umich.eduTimingSimpleCPU::write(double data, Addr addr, unsigned flags, uint64_t *res)
3225894Sgblack@eecs.umich.edu{
3235894Sgblack@eecs.umich.edu    return write(*(uint64_t*)&data, addr, flags, res);
3245894Sgblack@eecs.umich.edu}
32512749Sgiacomo.travaglini@arm.com
32612749Sgiacomo.travaglini@arm.comtemplate<>
3275894Sgblack@eecs.umich.eduFault
3285894Sgblack@eecs.umich.eduTimingSimpleCPU::write(float data, Addr addr, unsigned flags, uint64_t *res)
3295894Sgblack@eecs.umich.edu{
3305894Sgblack@eecs.umich.edu    return write(*(uint32_t*)&data, addr, flags, res);
3315894Sgblack@eecs.umich.edu}
3325894Sgblack@eecs.umich.edu
3335894Sgblack@eecs.umich.edu
3345894Sgblack@eecs.umich.edutemplate<>
3357911Shestness@cs.utexas.eduFault
3367911Shestness@cs.utexas.eduTimingSimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
3375894Sgblack@eecs.umich.edu{
3385894Sgblack@eecs.umich.edu    return write((uint32_t)data, addr, flags, res);
3397911Shestness@cs.utexas.edu}
3407911Shestness@cs.utexas.edu
3415894Sgblack@eecs.umich.edu
3425894Sgblack@eecs.umich.eduvoid
3435894Sgblack@eecs.umich.eduTimingSimpleCPU::fetch()
3445894Sgblack@eecs.umich.edu{
3455894Sgblack@eecs.umich.edu    Request *ifetch_req = new Request(true);
3465894Sgblack@eecs.umich.edu    ifetch_req->setSize(sizeof(MachInst));
3477911Shestness@cs.utexas.edu
3487911Shestness@cs.utexas.edu    ifetch_pkt = new Packet;
3495894Sgblack@eecs.umich.edu    ifetch_pkt->cmd = Read;
3505894Sgblack@eecs.umich.edu    ifetch_pkt->dataStatic(&inst);
3515894Sgblack@eecs.umich.edu    ifetch_pkt->req = ifetch_req;
3527911Shestness@cs.utexas.edu    ifetch_pkt->size = sizeof(MachInst);
3537911Shestness@cs.utexas.edu    ifetch_pkt->dest = Packet::Broadcast;
3545894Sgblack@eecs.umich.edu
3555894Sgblack@eecs.umich.edu    Fault fault = setupFetchPacket(ifetch_pkt);
3565894Sgblack@eecs.umich.edu    if (fault == NoFault) {
3575894Sgblack@eecs.umich.edu        if (!icachePort.sendTiming(ifetch_pkt)) {
3585894Sgblack@eecs.umich.edu            // Need to wait for retry
3595894Sgblack@eecs.umich.edu            _status = IcacheRetry;
3605894Sgblack@eecs.umich.edu        } else {
3615894Sgblack@eecs.umich.edu            // Need to wait for cache to respond
36210379Sandreas.hansson@arm.com            _status = IcacheWaitResponse;
3635894Sgblack@eecs.umich.edu            // ownership of packet transferred to memory system
3646739Sgblack@eecs.umich.edu            ifetch_pkt = NULL;
3656739Sgblack@eecs.umich.edu        }
36610464SAndreas.Sandberg@ARM.com    } else {
36712284Sjose.marinho@arm.com        panic("TimingSimpleCPU fetch fault handling not implemented");
3685894Sgblack@eecs.umich.edu    }
3695894Sgblack@eecs.umich.edu}
3705894Sgblack@eecs.umich.edu
3715894Sgblack@eecs.umich.edu
3725894Sgblack@eecs.umich.eduvoid
3735744Sgblack@eecs.umich.eduTimingSimpleCPU::completeInst(Fault fault)
3745744Sgblack@eecs.umich.edu{
3755894Sgblack@eecs.umich.edu    postExecute();
3765894Sgblack@eecs.umich.edu
3779442SAndreas.Sandberg@ARM.com    if (traceData) {
3785894Sgblack@eecs.umich.edu        traceData->finalize();
3795894Sgblack@eecs.umich.edu    }
38010653Sandreas.hansson@arm.com
38112749Sgiacomo.travaglini@arm.com    advancePC(fault);
3825894Sgblack@eecs.umich.edu
38310653Sandreas.hansson@arm.com    fetch();
3845894Sgblack@eecs.umich.edu}
3855894Sgblack@eecs.umich.edu
3865894Sgblack@eecs.umich.edu
3875894Sgblack@eecs.umich.eduvoid
38812749Sgiacomo.travaglini@arm.comTimingSimpleCPU::completeIfetch()
3895894Sgblack@eecs.umich.edu{
3905894Sgblack@eecs.umich.edu    // received a response from the icache: execute the received
3915894Sgblack@eecs.umich.edu    // instruction
3925894Sgblack@eecs.umich.edu    assert(_status == IcacheWaitResponse);
3938105Sgblack@eecs.umich.edu    _status = Running;
3945744Sgblack@eecs.umich.edu    preExecute();
3955894Sgblack@eecs.umich.edu    if (curStaticInst->isMemRef()) {
39610653Sandreas.hansson@arm.com        // load or store: just send to dcache
3975894Sgblack@eecs.umich.edu        Fault fault = curStaticInst->initiateAcc(this, traceData);
3985894Sgblack@eecs.umich.edu        assert(fault == NoFault);
3995894Sgblack@eecs.umich.edu        assert(_status == DcacheWaitResponse);
40010653Sandreas.hansson@arm.com    } else {
40110653Sandreas.hansson@arm.com        // non-memory instruction: execute completely now
4025894Sgblack@eecs.umich.edu        Fault fault = curStaticInst->execute(this, traceData);
4038949Sandreas.hansson@arm.com        completeInst(fault);
4045744Sgblack@eecs.umich.edu    }
40510566Sandreas.hansson@arm.com}
4065744Sgblack@eecs.umich.edu
4075744Sgblack@eecs.umich.edu
4085744Sgblack@eecs.umich.edubool
4095744Sgblack@eecs.umich.eduTimingSimpleCPU::IcachePort::recvTiming(Packet *pkt)
4105744Sgblack@eecs.umich.edu{
4115744Sgblack@eecs.umich.edu    cpu->completeIfetch();
4125744Sgblack@eecs.umich.edu    return true;
4135744Sgblack@eecs.umich.edu}
4145744Sgblack@eecs.umich.edu
4155744Sgblack@eecs.umich.eduPacket *
4165744Sgblack@eecs.umich.eduTimingSimpleCPU::IcachePort::recvRetry()
4175744Sgblack@eecs.umich.edu{
4182623SN/A    // we shouldn't get a retry unless we have a packet that we're
41911608Snikos.nikoleris@arm.com    // waiting to transmit
42011608Snikos.nikoleris@arm.com    assert(cpu->ifetch_pkt != NULL);
42111303Ssteve.reinhardt@amd.com    assert(cpu->_status == IcacheRetry);
42211147Smitch.hayenga@arm.com    cpu->_status = IcacheWaitResponse;
42311147Smitch.hayenga@arm.com    Packet *tmp = cpu->ifetch_pkt;
42411147Smitch.hayenga@arm.com    cpu->ifetch_pkt = NULL;
4255728Sgblack@eecs.umich.edu    return tmp;
4265728Sgblack@eecs.umich.edu}
4277720Sgblack@eecs.umich.edu
4289814Sandreas.hansson@arm.comvoid
4296973Stjones1@inf.ed.ac.ukTimingSimpleCPU::completeDataAccess(Packet *pkt)
4302623SN/A{
43110665SAli.Saidi@ARM.com    // received a response from the dcache: complete the load or store
43210665SAli.Saidi@ARM.com    // instruction
4337045Ssteve.reinhardt@amd.com    assert(pkt->result == Success);
43412749Sgiacomo.travaglini@arm.com    assert(_status == DcacheWaitResponse);
43512749Sgiacomo.travaglini@arm.com    _status = Running;
43612749Sgiacomo.travaglini@arm.com
4375728Sgblack@eecs.umich.edu    Fault fault = curStaticInst->completeAcc(pkt, this, traceData);
43810024Sdam.sunwoo@arm.com
43910024Sdam.sunwoo@arm.com    completeInst(fault);
4407520Sgblack@eecs.umich.edu}
4415744Sgblack@eecs.umich.edu
4425728Sgblack@eecs.umich.edu
4435894Sgblack@eecs.umich.edu
4445744Sgblack@eecs.umich.edubool
4455894Sgblack@eecs.umich.eduTimingSimpleCPU::DcachePort::recvTiming(Packet *pkt)
4466102Sgblack@eecs.umich.edu{
4475894Sgblack@eecs.umich.edu    cpu->completeDataAccess(pkt);
4485894Sgblack@eecs.umich.edu    return true;
4496973Stjones1@inf.ed.ac.uk}
4507520Sgblack@eecs.umich.edu
4516973Stjones1@inf.ed.ac.ukPacket *
4528486Sgblack@eecs.umich.eduTimingSimpleCPU::DcachePort::recvRetry()
4538486Sgblack@eecs.umich.edu{
4548486Sgblack@eecs.umich.edu    // we shouldn't get a retry unless we have a packet that we're
4558486Sgblack@eecs.umich.edu    // waiting to transmit
4566973Stjones1@inf.ed.ac.uk    assert(cpu->dcache_pkt != NULL);
45711147Smitch.hayenga@arm.com    assert(cpu->_status == DcacheRetry);
45811147Smitch.hayenga@arm.com    cpu->_status = DcacheWaitResponse;
4595744Sgblack@eecs.umich.edu    Packet *tmp = cpu->dcache_pkt;
4606973Stjones1@inf.ed.ac.uk    cpu->dcache_pkt = NULL;
4617520Sgblack@eecs.umich.edu    return tmp;
4628486Sgblack@eecs.umich.edu}
4638486Sgblack@eecs.umich.edu
46411147Smitch.hayenga@arm.com
4652623SN/A////////////////////////////////////////////////////////////////////////
4662623SN/A//
4675728Sgblack@eecs.umich.edu//  TimingSimpleCPU Simulation Object
4682623SN/A//
4692623SN/ABEGIN_DECLARE_SIM_OBJECT_PARAMS(TimingSimpleCPU)
4705728Sgblack@eecs.umich.edu
4715728Sgblack@eecs.umich.edu    Param<Counter> max_insts_any_thread;
4725728Sgblack@eecs.umich.edu    Param<Counter> max_insts_all_threads;
47311147Smitch.hayenga@arm.com    Param<Counter> max_loads_any_thread;
47411147Smitch.hayenga@arm.com    Param<Counter> max_loads_all_threads;
47511147Smitch.hayenga@arm.com    SimObjectParam<MemObject *> mem;
47612749Sgiacomo.travaglini@arm.com
4778105Sgblack@eecs.umich.edu#if FULL_SYSTEM
4789180Sandreas.hansson@arm.com    SimObjectParam<AlphaITB *> itb;
4799179Sandreas.hansson@arm.com    SimObjectParam<AlphaDTB *> dtb;
4805728Sgblack@eecs.umich.edu    SimObjectParam<System *> system;
4815728Sgblack@eecs.umich.edu    Param<int> cpu_id;
4828975Sandreas.hansson@arm.com    Param<Tick> profile;
4835728Sgblack@eecs.umich.edu#else
4845728Sgblack@eecs.umich.edu    SimObjectParam<Process *> workload;
4855728Sgblack@eecs.umich.edu#endif // FULL_SYSTEM
4865728Sgblack@eecs.umich.edu
4875728Sgblack@eecs.umich.edu    Param<int> clock;
4885728Sgblack@eecs.umich.edu
4895728Sgblack@eecs.umich.edu    Param<bool> defer_registration;
4905728Sgblack@eecs.umich.edu    Param<int> width;
4912623SN/A    Param<bool> function_trace;
4922623SN/A    Param<Tick> function_trace_start;
4938444Sgblack@eecs.umich.edu    Param<bool> simulate_stalls;
49411608Snikos.nikoleris@arm.com
4952623SN/AEND_DECLARE_SIM_OBJECT_PARAMS(TimingSimpleCPU)
49611147Smitch.hayenga@arm.com
49711147Smitch.hayenga@arm.comBEGIN_INIT_SIM_OBJECT_PARAMS(TimingSimpleCPU)
49811147Smitch.hayenga@arm.com
4998443Sgblack@eecs.umich.edu    INIT_PARAM(max_insts_any_thread,
5005728Sgblack@eecs.umich.edu               "terminate when any thread reaches this inst count"),
5017720Sgblack@eecs.umich.edu    INIT_PARAM(max_insts_all_threads,
5029814Sandreas.hansson@arm.com               "terminate when all threads have reached this inst count"),
5036973Stjones1@inf.ed.ac.uk    INIT_PARAM(max_loads_any_thread,
5043169Sstever@eecs.umich.edu               "terminate when any thread reaches this load count"),
50510031SAli.Saidi@ARM.com    INIT_PARAM(max_loads_all_threads,
50612355Snikos.nikoleris@arm.com               "terminate when all threads have reached this load count"),
50710031SAli.Saidi@ARM.com    INIT_PARAM(mem, "memory"),
50810031SAli.Saidi@ARM.com
50910031SAli.Saidi@ARM.com#if FULL_SYSTEM
51010031SAli.Saidi@ARM.com    INIT_PARAM(itb, "Instruction TLB"),
51110031SAli.Saidi@ARM.com    INIT_PARAM(dtb, "Data TLB"),
51210031SAli.Saidi@ARM.com    INIT_PARAM(system, "system object"),
51310665SAli.Saidi@ARM.com    INIT_PARAM(cpu_id, "processor ID"),
51410665SAli.Saidi@ARM.com    INIT_PARAM(profile, ""),
5157045Ssteve.reinhardt@amd.com#else
51612749Sgiacomo.travaglini@arm.com    INIT_PARAM(workload, "processes to run"),
51712749Sgiacomo.travaglini@arm.com#endif // FULL_SYSTEM
51812749Sgiacomo.travaglini@arm.com
5195728Sgblack@eecs.umich.edu    INIT_PARAM(clock, "clock speed"),
52010024Sdam.sunwoo@arm.com    INIT_PARAM(defer_registration, "defer system registration (for sampling)"),
52110024Sdam.sunwoo@arm.com    INIT_PARAM(width, "cpu width"),
5227520Sgblack@eecs.umich.edu    INIT_PARAM(function_trace, "Enable function trace"),
5235744Sgblack@eecs.umich.edu    INIT_PARAM(function_trace_start, "Cycle to start function trace"),
5245728Sgblack@eecs.umich.edu    INIT_PARAM(simulate_stalls, "Simulate cache stall cycles")
5255894Sgblack@eecs.umich.edu
5265744Sgblack@eecs.umich.eduEND_INIT_SIM_OBJECT_PARAMS(TimingSimpleCPU)
5275894Sgblack@eecs.umich.edu
5286102Sgblack@eecs.umich.edu
5295894Sgblack@eecs.umich.eduCREATE_SIM_OBJECT(TimingSimpleCPU)
5305894Sgblack@eecs.umich.edu{
5316973Stjones1@inf.ed.ac.uk    TimingSimpleCPU::Params *params = new TimingSimpleCPU::Params();
5328443Sgblack@eecs.umich.edu    params->name = getInstanceName();
5338486Sgblack@eecs.umich.edu    params->numberOfThreads = 1;
5348486Sgblack@eecs.umich.edu    params->max_insts_any_thread = max_insts_any_thread;
5358486Sgblack@eecs.umich.edu    params->max_insts_all_threads = max_insts_all_threads;
5368486Sgblack@eecs.umich.edu    params->max_loads_any_thread = max_loads_any_thread;
5376973Stjones1@inf.ed.ac.uk    params->max_loads_all_threads = max_loads_all_threads;
53811147Smitch.hayenga@arm.com    params->deferRegistration = defer_registration;
53911147Smitch.hayenga@arm.com    params->clock = clock;
5405744Sgblack@eecs.umich.edu    params->functionTrace = function_trace;
5416973Stjones1@inf.ed.ac.uk    params->functionTraceStart = function_trace_start;
5428443Sgblack@eecs.umich.edu    params->mem = mem;
5438486Sgblack@eecs.umich.edu
5448486Sgblack@eecs.umich.edu#if FULL_SYSTEM
54511147Smitch.hayenga@arm.com    params->itb = itb;
5462623SN/A    params->dtb = dtb;
5472623SN/A    params->system = system;
5487045Ssteve.reinhardt@amd.com    params->cpu_id = cpu_id;
5495728Sgblack@eecs.umich.edu    params->profile = profile;
5502623SN/A#else
5512623SN/A    params->process = workload;
55213652Sqtt2@cornell.edu#endif
55313652Sqtt2@cornell.edu
55413652Sqtt2@cornell.edu    TimingSimpleCPU *cpu = new TimingSimpleCPU(params);
55513652Sqtt2@cornell.edu    return cpu;
55613652Sqtt2@cornell.edu}
55713652Sqtt2@cornell.edu
55813652Sqtt2@cornell.eduREGISTER_SIM_OBJECT("TimingSimpleCPU", TimingSimpleCPU)
55913652Sqtt2@cornell.edu
56013652Sqtt2@cornell.edu