timing.cc revision 5221
1360SN/A/*
210850SGiacomo.Gabrielli@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
310796Sbrandon.potter@amd.com * All rights reserved.
410027SChris.Adeniyi-Jones@arm.com *
510027SChris.Adeniyi-Jones@arm.com * Redistribution and use in source and binary forms, with or without
610027SChris.Adeniyi-Jones@arm.com * modification, are permitted provided that the following conditions are
710027SChris.Adeniyi-Jones@arm.com * met: redistributions of source code must retain the above copyright
810027SChris.Adeniyi-Jones@arm.com * notice, this list of conditions and the following disclaimer;
910027SChris.Adeniyi-Jones@arm.com * redistributions in binary form must reproduce the above copyright
1010027SChris.Adeniyi-Jones@arm.com * notice, this list of conditions and the following disclaimer in the
1110027SChris.Adeniyi-Jones@arm.com * documentation and/or other materials provided with the distribution;
1210027SChris.Adeniyi-Jones@arm.com * neither the name of the copyright holders nor the names of its
1310027SChris.Adeniyi-Jones@arm.com * contributors may be used to endorse or promote products derived from
1410027SChris.Adeniyi-Jones@arm.com * this software without specific prior written permission.
151458SN/A *
16360SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17360SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18360SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19360SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20360SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21360SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22360SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23360SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24360SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25360SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26360SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27360SN/A *
28360SN/A * Authors: Steve Reinhardt
29360SN/A */
30360SN/A
31360SN/A#include "arch/locked_mem.hh"
32360SN/A#include "arch/mmaped_ipr.hh"
33360SN/A#include "arch/utility.hh"
34360SN/A#include "base/bigint.hh"
35360SN/A#include "cpu/exetrace.hh"
36360SN/A#include "cpu/simple/timing.hh"
37360SN/A#include "mem/packet.hh"
38360SN/A#include "mem/packet_access.hh"
39360SN/A#include "params/TimingSimpleCPU.hh"
402665Ssaidi@eecs.umich.edu#include "sim/system.hh"
412665Ssaidi@eecs.umich.edu
422665Ssaidi@eecs.umich.eduusing namespace std;
43360SN/Ausing namespace TheISA;
44360SN/A
451354SN/APort *
461354SN/ATimingSimpleCPU::getPort(const std::string &if_name, int idx)
47360SN/A{
482764Sstever@eecs.umich.edu    if (if_name == "dcache_port")
499202Spalle@lyckegaard.dk        return &dcachePort;
509202Spalle@lyckegaard.dk    else if (if_name == "icache_port")
512064SN/A        return &icachePort;
52360SN/A    else
53360SN/A        panic("No Such Port\n");
54360SN/A}
55360SN/A
56360SN/Avoid
57360SN/ATimingSimpleCPU::init()
581809SN/A{
595543Ssaidi@eecs.umich.edu    BaseCPU::init();
601809SN/A#if FULL_SYSTEM
613113Sgblack@eecs.umich.edu    for (int i = 0; i < threadContexts.size(); ++i) {
628229Snate@binkert.org        ThreadContext *tc = threadContexts[i];
638229Snate@binkert.org
643113Sgblack@eecs.umich.edu        // initialize CPU, including PC
657075Snate@binkert.org        TheISA::initCPU(tc, tc->readCpuId());
668229Snate@binkert.org    }
677075Snate@binkert.org#endif
68360SN/A}
692474SN/A
705543Ssaidi@eecs.umich.eduTick
712462SN/ATimingSimpleCPU::CpuPort::recvAtomic(PacketPtr pkt)
721354SN/A{
736216Snate@binkert.org    panic("TimingSimpleCPU doesn't expect recvAtomic callback!");
746658Snate@binkert.org    return curTick;
752474SN/A}
762680Sktlim@umich.edu
7711380Salexandru.dutu@amd.comvoid
788232Snate@binkert.orgTimingSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt)
798229Snate@binkert.org{
807678Sgblack@eecs.umich.edu    //No internal storage to update, jusst return
8110496Ssteve.reinhardt@amd.com    return;
828229Snate@binkert.org}
8310497Ssteve.reinhardt@amd.com
848766Sgblack@eecs.umich.eduvoid
856640Svince@csl.cornell.eduTimingSimpleCPU::CpuPort::recvStatusChange(Status status)
86360SN/A{
8711380Salexandru.dutu@amd.com    if (status == RangeChange) {
8811380Salexandru.dutu@amd.com        if (!snoopRangeSent) {
8911380Salexandru.dutu@amd.com            snoopRangeSent = true;
9011380Salexandru.dutu@amd.com            sendStatusChange(Port::RangeChange);
9111380Salexandru.dutu@amd.com        }
9211380Salexandru.dutu@amd.com        return;
9311380Salexandru.dutu@amd.com    }
9411380Salexandru.dutu@amd.com
95360SN/A    panic("TimingSimpleCPU doesn't expect recvStatusChange callback!");
96360SN/A}
97360SN/A
98360SN/A
99360SN/Avoid
100360SN/ATimingSimpleCPU::CpuPort::TickEvent::schedule(PacketPtr _pkt, Tick t)
101360SN/A{
102378SN/A    pkt = _pkt;
1031450SN/A    Event::schedule(t);
1043114Sgblack@eecs.umich.edu}
105360SN/A
1065543Ssaidi@eecs.umich.eduTimingSimpleCPU::TimingSimpleCPU(Params *p)
1075543Ssaidi@eecs.umich.edu    : BaseSimpleCPU(p), icachePort(this, p->clock), dcachePort(this, p->clock)
1085543Ssaidi@eecs.umich.edu{
10910831Ssteve.reinhardt@amd.com    _status = Idle;
110360SN/A
111360SN/A    icachePort.snoopRangeSent = false;
112360SN/A    dcachePort.snoopRangeSent = false;
113360SN/A
114360SN/A    ifetch_pkt = dcache_pkt = NULL;
1152680Sktlim@umich.edu    drainEvent = NULL;
116360SN/A    fetchEvent = NULL;
11710831Ssteve.reinhardt@amd.com    previousTick = 0;
11810831Ssteve.reinhardt@amd.com    changeState(SimObject::Running);
119360SN/A}
120360SN/A
121360SN/A
122360SN/ATimingSimpleCPU::~TimingSimpleCPU()
12310831Ssteve.reinhardt@amd.com{
124360SN/A}
125360SN/A
126360SN/Avoid
127360SN/ATimingSimpleCPU::serialize(ostream &os)
1283114Sgblack@eecs.umich.edu{
12910831Ssteve.reinhardt@amd.com    SimObject::State so_state = SimObject::getState();
13010831Ssteve.reinhardt@amd.com    SERIALIZE_ENUM(so_state);
13110831Ssteve.reinhardt@amd.com    BaseSimpleCPU::serialize(os);
132360SN/A}
133360SN/A
134360SN/Avoid
135360SN/ATimingSimpleCPU::unserialize(Checkpoint *cp, const string &section)
136360SN/A{
137360SN/A    SimObject::State so_state;
138360SN/A    UNSERIALIZE_ENUM(so_state);
139360SN/A    BaseSimpleCPU::unserialize(cp, section);
140360SN/A}
141360SN/A
142360SN/Aunsigned int
143360SN/ATimingSimpleCPU::drain(Event *drain_event)
144378SN/A{
1451706SN/A    // TimingSimpleCPU is ready to drain if it's not waiting for
1463114Sgblack@eecs.umich.edu    // an access to complete.
147378SN/A    if (status() == Idle || status() == Running || status() == SwitchedOut) {
148378SN/A        changeState(SimObject::Drained);
149378SN/A        return 0;
150378SN/A    } else {
151378SN/A        changeState(SimObject::Draining);
1521706SN/A        drainEvent = drain_event;
1533114Sgblack@eecs.umich.edu        return 1;
154360SN/A    }
1556109Ssanchezd@stanford.edu}
1561706SN/A
1573114Sgblack@eecs.umich.eduvoid
158378SN/ATimingSimpleCPU::resume()
1596109Ssanchezd@stanford.edu{
1606109Ssanchezd@stanford.edu    DPRINTF(SimpleCPU, "Resume\n");
1616109Ssanchezd@stanford.edu    if (_status != SwitchedOut && _status != Idle) {
1626109Ssanchezd@stanford.edu        assert(system->getMemoryMode() == Enums::timing);
163378SN/A
1641706SN/A        // Delete the old event if it existed.
1653114Sgblack@eecs.umich.edu        if (fetchEvent) {
166378SN/A            if (fetchEvent->scheduled())
1675748SSteve.Reinhardt@amd.com                fetchEvent->deschedule();
1685748SSteve.Reinhardt@amd.com
1695748SSteve.Reinhardt@amd.com            delete fetchEvent;
170378SN/A        }
171378SN/A
1721706SN/A        fetchEvent = new FetchEvent(this, nextCycle());
1733114Sgblack@eecs.umich.edu    }
174378SN/A
175378SN/A    changeState(SimObject::Running);
1761706SN/A}
1773114Sgblack@eecs.umich.edu
178378SN/Avoid
179378SN/ATimingSimpleCPU::switchOut()
1801706SN/A{
1813114Sgblack@eecs.umich.edu    assert(status() == Running || status() == Idle);
182378SN/A    _status = SwitchedOut;
183378SN/A    numCycles += tickToCycles(curTick - previousTick);
1841706SN/A
1853114Sgblack@eecs.umich.edu    // If we've been scheduled to resume but are then told to switch out,
186378SN/A    // we'll need to cancel it.
1874118Sgblack@eecs.umich.edu    if (fetchEvent && fetchEvent->scheduled())
1884118Sgblack@eecs.umich.edu        fetchEvent->deschedule();
1894118Sgblack@eecs.umich.edu}
1904118Sgblack@eecs.umich.edu
191378SN/A
1921706SN/Avoid
1933114Sgblack@eecs.umich.eduTimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
194378SN/A{
195378SN/A    BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort);
1961706SN/A
1973114Sgblack@eecs.umich.edu    // if any of this CPU's ThreadContexts are active, mark the CPU as
198360SN/A    // running and schedule its tick event.
1995513SMichael.Adler@intel.com    for (int i = 0; i < threadContexts.size(); ++i) {
2005513SMichael.Adler@intel.com        ThreadContext *tc = threadContexts[i];
2015513SMichael.Adler@intel.com        if (tc->status() == ThreadContext::Active && _status != Running) {
2025513SMichael.Adler@intel.com            _status = Running;
20310203SAli.Saidi@ARM.com            break;
20410203SAli.Saidi@ARM.com        }
20510203SAli.Saidi@ARM.com    }
20610203SAli.Saidi@ARM.com
2075513SMichael.Adler@intel.com    if (_status != Running) {
2085513SMichael.Adler@intel.com        _status = Idle;
2095513SMichael.Adler@intel.com    }
210511SN/A    assert(threadContexts.size() == 1);
21110633Smichaelupton@gmail.com    cpuId = tc->readCpuId();
21210633Smichaelupton@gmail.com    previousTick = curTick;
21310633Smichaelupton@gmail.com}
2141706SN/A
2153114Sgblack@eecs.umich.edu
216511SN/Avoid
2175513SMichael.Adler@intel.comTimingSimpleCPU::activateContext(int thread_num, int delay)
2185513SMichael.Adler@intel.com{
2195513SMichael.Adler@intel.com    DPRINTF(SimpleCPU, "ActivateContext %d (%d cycles)\n", thread_num, delay);
2205513SMichael.Adler@intel.com
221511SN/A    assert(thread_num == 0);
2221706SN/A    assert(thread);
2233114Sgblack@eecs.umich.edu
2241706SN/A    assert(_status == Idle);
2251706SN/A
2261706SN/A    notIdleFraction++;
2271706SN/A    _status = Running;
2283114Sgblack@eecs.umich.edu
2291706SN/A    // kick things off by initiating the fetch of the next instruction
2301706SN/A    fetchEvent = new FetchEvent(this, nextCycle(curTick + ticks(delay)));
2311706SN/A}
2321706SN/A
2333114Sgblack@eecs.umich.edu
2341706SN/Avoid
235511SN/ATimingSimpleCPU::suspendContext(int thread_num)
2366703Svince@csl.cornell.edu{
2376703Svince@csl.cornell.edu    DPRINTF(SimpleCPU, "SuspendContext %d\n", thread_num);
2386703Svince@csl.cornell.edu
2396703Svince@csl.cornell.edu    assert(thread_num == 0);
2406685Stjones1@inf.ed.ac.uk    assert(thread);
2416685Stjones1@inf.ed.ac.uk
2426685Stjones1@inf.ed.ac.uk    assert(_status == Running);
2436685Stjones1@inf.ed.ac.uk
2446685Stjones1@inf.ed.ac.uk    // just change status to Idle... if status != Running,
2455513SMichael.Adler@intel.com    // completeInst() will not initiate fetch of next instruction.
2465513SMichael.Adler@intel.com
2475513SMichael.Adler@intel.com    notIdleFraction--;
2485513SMichael.Adler@intel.com    _status = Idle;
2495513SMichael.Adler@intel.com}
2501999SN/A
2511999SN/A
2523114Sgblack@eecs.umich.edutemplate <class T>
2531999SN/AFault
2541999SN/ATimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
2551999SN/A{
2561999SN/A    Request *req =
2573114Sgblack@eecs.umich.edu        new Request(/* asid */ 0, addr, sizeof(T), flags, thread->readPC(),
2581999SN/A                    cpuId, /* thread ID */ 0);
2593079Sstever@eecs.umich.edu
2603079Sstever@eecs.umich.edu    if (traceData) {
2613114Sgblack@eecs.umich.edu        traceData->setAddr(req->getVaddr());
2623079Sstever@eecs.umich.edu    }
2632093SN/A
2642093SN/A   // translate to physical address
2653114Sgblack@eecs.umich.edu    Fault fault = thread->translateDataReadReq(req);
2662093SN/A
2672687Sksewell@umich.edu    // Now do the access.
2682687Sksewell@umich.edu    if (fault == NoFault) {
2693114Sgblack@eecs.umich.edu        PacketPtr pkt =
2702687Sksewell@umich.edu            new Packet(req,
2712238SN/A                       (req->isLocked() ?
2722238SN/A                        MemCmd::LoadLockedReq : MemCmd::ReadReq),
2733114Sgblack@eecs.umich.edu                       Packet::Broadcast);
2742238SN/A        pkt->dataDynamic<T>(new T);
2752238SN/A
2762238SN/A        if (req->isMmapedIpr()) {
2773114Sgblack@eecs.umich.edu            Tick delay;
2782238SN/A            delay = TheISA::handleIprRead(thread->getTC(), pkt);
2792238SN/A            new IprEvent(pkt, this, nextCycle(curTick + delay));
2802238SN/A            _status = DcacheWaitResponse;
2813114Sgblack@eecs.umich.edu            dcache_pkt = NULL;
2822238SN/A        } else if (!dcachePort.sendTiming(pkt)) {
2832238SN/A            _status = DcacheRetry;
2842238SN/A            dcache_pkt = pkt;
2853114Sgblack@eecs.umich.edu        } else {
2862238SN/A            _status = DcacheWaitResponse;
2872238SN/A            // memory system takes ownership of packet
2882238SN/A            dcache_pkt = NULL;
2893114Sgblack@eecs.umich.edu        }
2902238SN/A
2912238SN/A        // This will need a new way to tell if it has a dcache attached.
2922238SN/A        if (req->isUncacheable())
2933114Sgblack@eecs.umich.edu            recordEvent("Uncached Read");
2942238SN/A    } else {
2952238SN/A        delete req;
2962238SN/A    }
2973114Sgblack@eecs.umich.edu
2982238SN/A    return fault;
2996109Ssanchezd@stanford.edu}
3006109Ssanchezd@stanford.edu
3016109Ssanchezd@stanford.eduFault
3022238SN/ATimingSimpleCPU::translateDataReadAddr(Addr vaddr, Addr &paddr,
3039455Smitch.hayenga+gem5@gmail.com        int size, unsigned flags)
3049455Smitch.hayenga+gem5@gmail.com{
3059455Smitch.hayenga+gem5@gmail.com    Request *req =
30610203SAli.Saidi@ARM.com        new Request(0, vaddr, size, flags, thread->readPC(), cpuId, 0);
30710203SAli.Saidi@ARM.com
30810203SAli.Saidi@ARM.com    if (traceData) {
3099455Smitch.hayenga+gem5@gmail.com        traceData->setAddr(vaddr);
3109112Smarc.orr@gmail.com    }
3119112Smarc.orr@gmail.com
3129112Smarc.orr@gmail.com    Fault fault = thread->translateDataWriteReq(req);
3139112Smarc.orr@gmail.com
3149112Smarc.orr@gmail.com    if (fault == NoFault)
3159112Smarc.orr@gmail.com        paddr = req->getPaddr();
3169112Smarc.orr@gmail.com
3179112Smarc.orr@gmail.com    delete req;
3189112Smarc.orr@gmail.com    return fault;
3199112Smarc.orr@gmail.com}
3209112Smarc.orr@gmail.com
3219112Smarc.orr@gmail.com#ifndef DOXYGEN_SHOULD_SKIP_THIS
3229112Smarc.orr@gmail.com
3239112Smarc.orr@gmail.comtemplate
3249112Smarc.orr@gmail.comFault
3259112Smarc.orr@gmail.comTimingSimpleCPU::read(Addr addr, Twin64_t &data, unsigned flags);
3269112Smarc.orr@gmail.com
3279112Smarc.orr@gmail.comtemplate
3289112Smarc.orr@gmail.comFault
3299112Smarc.orr@gmail.comTimingSimpleCPU::read(Addr addr, Twin32_t &data, unsigned flags);
3309112Smarc.orr@gmail.com
3319112Smarc.orr@gmail.comtemplate
3329112Smarc.orr@gmail.comFault
3339112Smarc.orr@gmail.comTimingSimpleCPU::read(Addr addr, uint64_t &data, unsigned flags);
3349238Slluc.alvarez@bsc.es
3359112Smarc.orr@gmail.comtemplate
3369112Smarc.orr@gmail.comFault
3379112Smarc.orr@gmail.comTimingSimpleCPU::read(Addr addr, uint32_t &data, unsigned flags);
3389112Smarc.orr@gmail.com
3399112Smarc.orr@gmail.comtemplate
3409112Smarc.orr@gmail.comFault
3419112Smarc.orr@gmail.comTimingSimpleCPU::read(Addr addr, uint16_t &data, unsigned flags);
3429112Smarc.orr@gmail.com
3439112Smarc.orr@gmail.comtemplate
3449112Smarc.orr@gmail.comFault
34511367Sandreas.hansson@arm.comTimingSimpleCPU::read(Addr addr, uint8_t &data, unsigned flags);
3469112Smarc.orr@gmail.com
34711321Ssteve.reinhardt@amd.com#endif //DOXYGEN_SHOULD_SKIP_THIS
3489112Smarc.orr@gmail.com
3499112Smarc.orr@gmail.comtemplate<>
3509112Smarc.orr@gmail.comFault
3519112Smarc.orr@gmail.comTimingSimpleCPU::read(Addr addr, double &data, unsigned flags)
3529112Smarc.orr@gmail.com{
3539112Smarc.orr@gmail.com    return read(addr, *(uint64_t*)&data, flags);
3549112Smarc.orr@gmail.com}
3559112Smarc.orr@gmail.com
3569112Smarc.orr@gmail.comtemplate<>
3579112Smarc.orr@gmail.comFault
3589112Smarc.orr@gmail.comTimingSimpleCPU::read(Addr addr, float &data, unsigned flags)
3599112Smarc.orr@gmail.com{
3609112Smarc.orr@gmail.com    return read(addr, *(uint32_t*)&data, flags);
3619112Smarc.orr@gmail.com}
3629112Smarc.orr@gmail.com
3639112Smarc.orr@gmail.com
3649112Smarc.orr@gmail.comtemplate<>
3659112Smarc.orr@gmail.comFault
3669112Smarc.orr@gmail.comTimingSimpleCPU::read(Addr addr, int32_t &data, unsigned flags)
3679112Smarc.orr@gmail.com{
3689112Smarc.orr@gmail.com    return read(addr, (uint32_t&)data, flags);
3699112Smarc.orr@gmail.com}
3709112Smarc.orr@gmail.com
3719112Smarc.orr@gmail.com
3729112Smarc.orr@gmail.comtemplate <class T>
3739112Smarc.orr@gmail.comFault
3749112Smarc.orr@gmail.comTimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
3759112Smarc.orr@gmail.com{
3769112Smarc.orr@gmail.com    Request *req =
37711321Ssteve.reinhardt@amd.com        new Request(/* asid */ 0, addr, sizeof(T), flags, thread->readPC(),
3789112Smarc.orr@gmail.com                    cpuId, /* thread ID */ 0);
3799112Smarc.orr@gmail.com
3809112Smarc.orr@gmail.com    if (traceData) {
3819112Smarc.orr@gmail.com        traceData->setAddr(req->getVaddr());
3829112Smarc.orr@gmail.com    }
3839112Smarc.orr@gmail.com
3849112Smarc.orr@gmail.com    // translate to physical address
3859112Smarc.orr@gmail.com    Fault fault = thread->translateDataWriteReq(req);
3869238Slluc.alvarez@bsc.es
3879112Smarc.orr@gmail.com    // Now do the access.
3889112Smarc.orr@gmail.com    if (fault == NoFault) {
3899112Smarc.orr@gmail.com        MemCmd cmd = MemCmd::WriteReq; // default
3909112Smarc.orr@gmail.com        bool do_access = true;  // flag to suppress cache access
3919112Smarc.orr@gmail.com
3922238SN/A        if (req->isLocked()) {
3932238SN/A            cmd = MemCmd::StoreCondReq;
3942238SN/A            do_access = TheISA::handleLockedWrite(thread, req);
3952238SN/A        } else if (req->isSwap()) {
3963114Sgblack@eecs.umich.edu            cmd = MemCmd::SwapReq;
3972238SN/A            if (req->isCondSwap()) {
3982238SN/A                assert(res);
3992238SN/A                req->setExtraData(*res);
4003114Sgblack@eecs.umich.edu            }
4012238SN/A        }
4022238SN/A
4032238SN/A        // Note: need to allocate dcache_pkt even if do_access is
4043114Sgblack@eecs.umich.edu        // false, as it's used unconditionally to call completeAcc().
4052238SN/A        assert(dcache_pkt == NULL);
4062238SN/A        dcache_pkt = new Packet(req, cmd, Packet::Broadcast);
4072238SN/A        dcache_pkt->allocate();
4083114Sgblack@eecs.umich.edu        dcache_pkt->set(data);
4092238SN/A
4102238SN/A        if (do_access) {
4111354SN/A            if (req->isMmapedIpr()) {
4121354SN/A                Tick delay;
41310796Sbrandon.potter@amd.com                dcache_pkt->set(htog(data));
41410796Sbrandon.potter@amd.com                delay = TheISA::handleIprWrite(thread->getTC(), dcache_pkt);
4151354SN/A                new IprEvent(dcache_pkt, this, nextCycle(curTick + delay));
4161354SN/A                _status = DcacheWaitResponse;
4171354SN/A                dcache_pkt = NULL;
4181354SN/A            } else if (!dcachePort.sendTiming(dcache_pkt)) {
4191354SN/A                _status = DcacheRetry;
4201354SN/A            } else {
4211354SN/A                _status = DcacheWaitResponse;
4221354SN/A                // memory system takes ownership of packet
4231354SN/A                dcache_pkt = NULL;
4241354SN/A            }
42510796Sbrandon.potter@amd.com        }
4261354SN/A        // This will need a new way to tell if it's hooked up to a cache or not.
42710796Sbrandon.potter@amd.com        if (req->isUncacheable())
4281354SN/A            recordEvent("Uncached Write");
4291354SN/A    } else {
4301354SN/A        delete req;
4311354SN/A    }
43210796Sbrandon.potter@amd.com
43310796Sbrandon.potter@amd.com
43410796Sbrandon.potter@amd.com    // If the write needs to have a fault on the access, consider calling
43510796Sbrandon.potter@amd.com    // changeStatus() and changing it to "bad addr write" or something.
43610796Sbrandon.potter@amd.com    return fault;
43710796Sbrandon.potter@amd.com}
43810796Sbrandon.potter@amd.com
43910796Sbrandon.potter@amd.comFault
44010796Sbrandon.potter@amd.comTimingSimpleCPU::translateDataWriteAddr(Addr vaddr, Addr &paddr,
44110796Sbrandon.potter@amd.com        int size, unsigned flags)
44210796Sbrandon.potter@amd.com{
443360SN/A    Request *req =
444360SN/A        new Request(0, vaddr, size, flags, thread->readPC(), cpuId, 0);
445360SN/A
446360SN/A    if (traceData) {
447360SN/A        traceData->setAddr(vaddr);
448360SN/A    }
449360SN/A
4503113Sgblack@eecs.umich.edu    Fault fault = thread->translateDataWriteReq(req);
4513113Sgblack@eecs.umich.edu
4523113Sgblack@eecs.umich.edu    if (fault == NoFault)
4533113Sgblack@eecs.umich.edu        paddr = req->getPaddr();
4543113Sgblack@eecs.umich.edu
4553113Sgblack@eecs.umich.edu    delete req;
4563113Sgblack@eecs.umich.edu    return fault;
4573113Sgblack@eecs.umich.edu}
4583113Sgblack@eecs.umich.edu
4593113Sgblack@eecs.umich.edu
4603113Sgblack@eecs.umich.edu#ifndef DOXYGEN_SHOULD_SKIP_THIS
4613113Sgblack@eecs.umich.edutemplate
4623113Sgblack@eecs.umich.eduFault
4633113Sgblack@eecs.umich.eduTimingSimpleCPU::write(Twin32_t data, Addr addr,
4643113Sgblack@eecs.umich.edu                       unsigned flags, uint64_t *res);
4653113Sgblack@eecs.umich.edu
4664189Sgblack@eecs.umich.edutemplate
4674189Sgblack@eecs.umich.eduFault
4683113Sgblack@eecs.umich.eduTimingSimpleCPU::write(Twin64_t data, Addr addr,
4693113Sgblack@eecs.umich.edu                       unsigned flags, uint64_t *res);
4703113Sgblack@eecs.umich.edu
4713113Sgblack@eecs.umich.edutemplate
4728737Skoansin.tan@gmail.comFault
4733113Sgblack@eecs.umich.eduTimingSimpleCPU::write(uint64_t data, Addr addr,
4748737Skoansin.tan@gmail.com                       unsigned flags, uint64_t *res);
4753277Sgblack@eecs.umich.edu
4765515SMichael.Adler@intel.comtemplate
4775515SMichael.Adler@intel.comFault
4785515SMichael.Adler@intel.comTimingSimpleCPU::write(uint32_t data, Addr addr,
4795515SMichael.Adler@intel.com                       unsigned flags, uint64_t *res);
4805515SMichael.Adler@intel.com
4818737Skoansin.tan@gmail.comtemplate
4823277Sgblack@eecs.umich.eduFault
4838737Skoansin.tan@gmail.comTimingSimpleCPU::write(uint16_t data, Addr addr,
4843277Sgblack@eecs.umich.edu                       unsigned flags, uint64_t *res);
4858737Skoansin.tan@gmail.com
4863277Sgblack@eecs.umich.edutemplate
4878737Skoansin.tan@gmail.comFault
4883113Sgblack@eecs.umich.eduTimingSimpleCPU::write(uint8_t data, Addr addr,
4893113Sgblack@eecs.umich.edu                       unsigned flags, uint64_t *res);
4903113Sgblack@eecs.umich.edu
4913113Sgblack@eecs.umich.edu#endif //DOXYGEN_SHOULD_SKIP_THIS
4928737Skoansin.tan@gmail.com
4933113Sgblack@eecs.umich.edutemplate<>
4948737Skoansin.tan@gmail.comFault
4953114Sgblack@eecs.umich.eduTimingSimpleCPU::write(double data, Addr addr, unsigned flags, uint64_t *res)
4968737Skoansin.tan@gmail.com{
4973114Sgblack@eecs.umich.edu    return write(*(uint64_t*)&data, addr, flags, res);
4988737Skoansin.tan@gmail.com}
4993114Sgblack@eecs.umich.edu
5008737Skoansin.tan@gmail.comtemplate<>
5014061Sgblack@eecs.umich.eduFault
5024061Sgblack@eecs.umich.eduTimingSimpleCPU::write(float data, Addr addr, unsigned flags, uint64_t *res)
5034061Sgblack@eecs.umich.edu{
5048737Skoansin.tan@gmail.com    return write(*(uint32_t*)&data, addr, flags, res);
5053113Sgblack@eecs.umich.edu}
5068737Skoansin.tan@gmail.com
5073113Sgblack@eecs.umich.edu
5083113Sgblack@eecs.umich.edutemplate<>
5093113Sgblack@eecs.umich.eduFault
5103113Sgblack@eecs.umich.eduTimingSimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
5113113Sgblack@eecs.umich.edu{
5123113Sgblack@eecs.umich.edu    return write((uint32_t)data, addr, flags, res);
5133113Sgblack@eecs.umich.edu}
5143113Sgblack@eecs.umich.edu
5154189Sgblack@eecs.umich.edu
5164189Sgblack@eecs.umich.eduvoid
5173113Sgblack@eecs.umich.eduTimingSimpleCPU::fetch()
5183113Sgblack@eecs.umich.edu{
5193113Sgblack@eecs.umich.edu    DPRINTF(SimpleCPU, "Fetch\n");
5208737Skoansin.tan@gmail.com
5213113Sgblack@eecs.umich.edu    if (!curStaticInst || !curStaticInst->isDelayedCommit())
5228737Skoansin.tan@gmail.com        checkForInterrupts();
5233113Sgblack@eecs.umich.edu
5248737Skoansin.tan@gmail.com    Request *ifetch_req = new Request();
5253113Sgblack@eecs.umich.edu    ifetch_req->setThreadContext(cpuId, /* thread ID */ 0);
5263113Sgblack@eecs.umich.edu    Fault fault = setupFetchRequest(ifetch_req);
5273113Sgblack@eecs.umich.edu
5283113Sgblack@eecs.umich.edu    ifetch_pkt = new Packet(ifetch_req, MemCmd::ReadReq, Packet::Broadcast);
5293113Sgblack@eecs.umich.edu    ifetch_pkt->dataStatic(&inst);
5303113Sgblack@eecs.umich.edu
5313113Sgblack@eecs.umich.edu    if (fault == NoFault) {
5323113Sgblack@eecs.umich.edu        if (!icachePort.sendTiming(ifetch_pkt)) {
5333113Sgblack@eecs.umich.edu            // Need to wait for retry
5343113Sgblack@eecs.umich.edu            _status = IcacheRetry;
5358852Sandreas.hansson@arm.com        } else {
5363113Sgblack@eecs.umich.edu            // Need to wait for cache to respond
5373113Sgblack@eecs.umich.edu            _status = IcacheWaitResponse;
5383113Sgblack@eecs.umich.edu            // ownership of packet transferred to memory system
5393113Sgblack@eecs.umich.edu            ifetch_pkt = NULL;
5403113Sgblack@eecs.umich.edu        }
5413113Sgblack@eecs.umich.edu    } else {
5423113Sgblack@eecs.umich.edu        delete ifetch_req;
5433113Sgblack@eecs.umich.edu        delete ifetch_pkt;
5443113Sgblack@eecs.umich.edu        // fetch fault: advance directly to next instruction (fault handler)
5453113Sgblack@eecs.umich.edu        advanceInst(fault);
5468852Sandreas.hansson@arm.com    }
5473113Sgblack@eecs.umich.edu
5483113Sgblack@eecs.umich.edu    numCycles += tickToCycles(curTick - previousTick);
5493113Sgblack@eecs.umich.edu    previousTick = curTick;
5503113Sgblack@eecs.umich.edu}
5516686Stjones1@inf.ed.ac.uk
5523113Sgblack@eecs.umich.edu
5533113Sgblack@eecs.umich.eduvoid
5543113Sgblack@eecs.umich.eduTimingSimpleCPU::advanceInst(Fault fault)
555378SN/A{
556378SN/A    advancePC(fault);
5579141Smarc.orr@gmail.com
5589141Smarc.orr@gmail.com    if (_status == Running) {
559360SN/A        // kick off fetch of next instruction... callback from icache
5601450SN/A        // response will cause that instruction to be executed,
5613114Sgblack@eecs.umich.edu        // keeping the CPU running.
5622680Sktlim@umich.edu        fetch();
563360SN/A    }
5646701Sgblack@eecs.umich.edu}
56510930Sbrandon.potter@amd.com
5666701Sgblack@eecs.umich.edu
567360SN/Avoid
56810930Sbrandon.potter@amd.comTimingSimpleCPU::completeIfetch(PacketPtr pkt)
569360SN/A{
57010932Sbrandon.potter@amd.com    DPRINTF(SimpleCPU, "Complete ICache Fetch\n");
57110496Ssteve.reinhardt@amd.com
57210930Sbrandon.potter@amd.com    // received a response from the icache: execute the received
573360SN/A    // instruction
5741458SN/A    assert(!pkt->isError());
575360SN/A    assert(_status == IcacheWaitResponse);
576360SN/A
57710930Sbrandon.potter@amd.com    _status = Running;
57810930Sbrandon.potter@amd.com
57910496Ssteve.reinhardt@amd.com    numCycles += tickToCycles(curTick - previousTick);
58010496Ssteve.reinhardt@amd.com    previousTick = curTick;
5819141Smarc.orr@gmail.com
5821458SN/A    if (getState() == SimObject::Draining) {
5839141Smarc.orr@gmail.com        delete pkt->req;
584360SN/A        delete pkt;
5859141Smarc.orr@gmail.com
58610930Sbrandon.potter@amd.com        completeDrain();
5879141Smarc.orr@gmail.com        return;
588360SN/A    }
589360SN/A
590360SN/A    preExecute();
59110027SChris.Adeniyi-Jones@arm.com    if (curStaticInst->isMemRef() && !curStaticInst->isDataPrefetch()) {
5923114Sgblack@eecs.umich.edu        // load or store: just send to dcache
59310027SChris.Adeniyi-Jones@arm.com        Fault fault = curStaticInst->initiateAcc(this, traceData);
594360SN/A        if (_status != Running) {
595360SN/A            // instruction will complete in dcache response callback
596360SN/A            assert(_status == DcacheWaitResponse || _status == DcacheRetry);
5978852Sandreas.hansson@arm.com            assert(fault == NoFault);
5986701Sgblack@eecs.umich.edu        } else {
5991458SN/A            if (fault == NoFault) {
600360SN/A                // early fail on store conditional: complete now
6016701Sgblack@eecs.umich.edu                assert(dcache_pkt != NULL);
6026701Sgblack@eecs.umich.edu                fault = curStaticInst->completeAcc(dcache_pkt, this,
603360SN/A                                                   traceData);
604360SN/A                delete dcache_pkt->req;
605360SN/A                delete dcache_pkt;
606360SN/A                dcache_pkt = NULL;
607360SN/A
608360SN/A                // keep an instruction count
609360SN/A                if (fault == NoFault)
610360SN/A                    countInst();
611360SN/A            } else if (traceData) {
612360SN/A                // If there was a fault, we shouldn't trace this instruction.
613360SN/A                delete traceData;
614360SN/A                traceData = NULL;
6151706SN/A            }
616360SN/A
617360SN/A            postExecute();
618360SN/A            // @todo remove me after debugging with legion done
619360SN/A            if (curStaticInst && (!curStaticInst->isMicroop() ||
620360SN/A                        curStaticInst->isFirstMicroop()))
6213669Sbinkertn@umich.edu                instCnt++;
6223669Sbinkertn@umich.edu            advanceInst(fault);
6233669Sbinkertn@umich.edu        }
6241706SN/A    } else {
6251706SN/A        // non-memory instruction: execute completely now
62610496Ssteve.reinhardt@amd.com        Fault fault = curStaticInst->execute(this, traceData);
62710496Ssteve.reinhardt@amd.com
62810496Ssteve.reinhardt@amd.com        // keep an instruction count
62910496Ssteve.reinhardt@amd.com        if (fault == NoFault)
63010496Ssteve.reinhardt@amd.com            countInst();
63110496Ssteve.reinhardt@amd.com        else if (traceData) {
63210496Ssteve.reinhardt@amd.com            // If there was a fault, we shouldn't trace this instruction.
63310496Ssteve.reinhardt@amd.com            delete traceData;
63410496Ssteve.reinhardt@amd.com            traceData = NULL;
63510496Ssteve.reinhardt@amd.com        }
63610496Ssteve.reinhardt@amd.com
63710496Ssteve.reinhardt@amd.com        postExecute();
63810496Ssteve.reinhardt@amd.com        // @todo remove me after debugging with legion done
63910496Ssteve.reinhardt@amd.com        if (curStaticInst && (!curStaticInst->isMicroop() ||
64010496Ssteve.reinhardt@amd.com                    curStaticInst->isFirstMicroop()))
64110496Ssteve.reinhardt@amd.com            instCnt++;
64210496Ssteve.reinhardt@amd.com        advanceInst(fault);
64310496Ssteve.reinhardt@amd.com    }
64410496Ssteve.reinhardt@amd.com
64510496Ssteve.reinhardt@amd.com    delete pkt->req;
6465795Ssaidi@eecs.umich.edu    delete pkt;
6479143Ssteve.reinhardt@amd.com}
6489142Ssteve.reinhardt@amd.com
6499142Ssteve.reinhardt@amd.comvoid
6509143Ssteve.reinhardt@amd.comTimingSimpleCPU::IcachePort::ITickEvent::process()
6515795Ssaidi@eecs.umich.edu{
6529143Ssteve.reinhardt@amd.com    cpu->completeIfetch(pkt);
6535795Ssaidi@eecs.umich.edu}
6545795Ssaidi@eecs.umich.edu
6555795Ssaidi@eecs.umich.edubool
6569143Ssteve.reinhardt@amd.comTimingSimpleCPU::IcachePort::recvTiming(PacketPtr pkt)
6575795Ssaidi@eecs.umich.edu{
658360SN/A    if (pkt->isResponse() && !pkt->wasNacked()) {
6599143Ssteve.reinhardt@amd.com        // delay processing of returned data until next CPU clock edge
6609143Ssteve.reinhardt@amd.com        Tick next_tick = cpu->nextCycle(curTick);
6619143Ssteve.reinhardt@amd.com
66210932Sbrandon.potter@amd.com        if (next_tick == curTick)
663360SN/A            cpu->completeIfetch(pkt);
664360SN/A        else
66510027SChris.Adeniyi-Jones@arm.com            tickEvent.schedule(pkt, next_tick);
66610027SChris.Adeniyi-Jones@arm.com
66710027SChris.Adeniyi-Jones@arm.com        return true;
66810027SChris.Adeniyi-Jones@arm.com    }
66910027SChris.Adeniyi-Jones@arm.com    else if (pkt->wasNacked()) {
67010027SChris.Adeniyi-Jones@arm.com        assert(cpu->_status == IcacheWaitResponse);
67110027SChris.Adeniyi-Jones@arm.com        pkt->reinitNacked();
67210027SChris.Adeniyi-Jones@arm.com        if (!sendTiming(pkt)) {
67310027SChris.Adeniyi-Jones@arm.com            cpu->_status = IcacheRetry;
67410027SChris.Adeniyi-Jones@arm.com            cpu->ifetch_pkt = pkt;
67510027SChris.Adeniyi-Jones@arm.com        }
67610027SChris.Adeniyi-Jones@arm.com    }
67710027SChris.Adeniyi-Jones@arm.com    //Snooping a Coherence Request, do nothing
67810027SChris.Adeniyi-Jones@arm.com    return true;
67910027SChris.Adeniyi-Jones@arm.com}
68010027SChris.Adeniyi-Jones@arm.com
68110027SChris.Adeniyi-Jones@arm.comvoid
68210027SChris.Adeniyi-Jones@arm.comTimingSimpleCPU::IcachePort::recvRetry()
68310027SChris.Adeniyi-Jones@arm.com{
68410027SChris.Adeniyi-Jones@arm.com    // we shouldn't get a retry unless we have a packet that we're
68510027SChris.Adeniyi-Jones@arm.com    // waiting to transmit
68610027SChris.Adeniyi-Jones@arm.com    assert(cpu->ifetch_pkt != NULL);
68710633Smichaelupton@gmail.com    assert(cpu->_status == IcacheRetry);
68810633Smichaelupton@gmail.com    PacketPtr tmp = cpu->ifetch_pkt;
68910633Smichaelupton@gmail.com    if (sendTiming(tmp)) {
69010633Smichaelupton@gmail.com        cpu->_status = IcacheWaitResponse;
69110633Smichaelupton@gmail.com        cpu->ifetch_pkt = NULL;
69210633Smichaelupton@gmail.com    }
69310633Smichaelupton@gmail.com}
69410633Smichaelupton@gmail.com
69510633Smichaelupton@gmail.comvoid
69610633Smichaelupton@gmail.comTimingSimpleCPU::completeDataAccess(PacketPtr pkt)
69710633Smichaelupton@gmail.com{
69810633Smichaelupton@gmail.com    // received a response from the dcache: complete the load or store
69910633Smichaelupton@gmail.com    // instruction
70010633Smichaelupton@gmail.com    assert(!pkt->isError());
70110203SAli.Saidi@ARM.com    assert(_status == DcacheWaitResponse);
70210203SAli.Saidi@ARM.com    _status = Running;
70310203SAli.Saidi@ARM.com
70410203SAli.Saidi@ARM.com    numCycles += tickToCycles(curTick - previousTick);
70510203SAli.Saidi@ARM.com    previousTick = curTick;
70610203SAli.Saidi@ARM.com
70710203SAli.Saidi@ARM.com    Fault fault = curStaticInst->completeAcc(pkt, this, traceData);
70810203SAli.Saidi@ARM.com
70910203SAli.Saidi@ARM.com    // keep an instruction count
71010203SAli.Saidi@ARM.com    if (fault == NoFault)
71110203SAli.Saidi@ARM.com        countInst();
71210203SAli.Saidi@ARM.com    else if (traceData) {
71310203SAli.Saidi@ARM.com        // If there was a fault, we shouldn't trace this instruction.
71410203SAli.Saidi@ARM.com        delete traceData;
71510203SAli.Saidi@ARM.com        traceData = NULL;
71610203SAli.Saidi@ARM.com    }
71710203SAli.Saidi@ARM.com
71810203SAli.Saidi@ARM.com    if (pkt->isRead() && pkt->isLocked()) {
71910203SAli.Saidi@ARM.com        TheISA::handleLockedRead(thread, pkt->req);
72010203SAli.Saidi@ARM.com    }
72110203SAli.Saidi@ARM.com
72210203SAli.Saidi@ARM.com    delete pkt->req;
72310203SAli.Saidi@ARM.com    delete pkt;
72410203SAli.Saidi@ARM.com
72510203SAli.Saidi@ARM.com    postExecute();
72610203SAli.Saidi@ARM.com
72710850SGiacomo.Gabrielli@arm.com    if (getState() == SimObject::Draining) {
72810850SGiacomo.Gabrielli@arm.com        advancePC(fault);
72910850SGiacomo.Gabrielli@arm.com        completeDrain();
73010850SGiacomo.Gabrielli@arm.com
73110850SGiacomo.Gabrielli@arm.com        return;
73210850SGiacomo.Gabrielli@arm.com    }
73310850SGiacomo.Gabrielli@arm.com
73410850SGiacomo.Gabrielli@arm.com    advanceInst(fault);
73510850SGiacomo.Gabrielli@arm.com}
73610850SGiacomo.Gabrielli@arm.com
73710850SGiacomo.Gabrielli@arm.com
73810850SGiacomo.Gabrielli@arm.comvoid
73910850SGiacomo.Gabrielli@arm.comTimingSimpleCPU::completeDrain()
74010850SGiacomo.Gabrielli@arm.com{
74110850SGiacomo.Gabrielli@arm.com    DPRINTF(Config, "Done draining\n");
74210850SGiacomo.Gabrielli@arm.com    changeState(SimObject::Drained);
74310850SGiacomo.Gabrielli@arm.com    drainEvent->process();
74410850SGiacomo.Gabrielli@arm.com}
74510850SGiacomo.Gabrielli@arm.com
74610850SGiacomo.Gabrielli@arm.comvoid
74710850SGiacomo.Gabrielli@arm.comTimingSimpleCPU::DcachePort::setPeer(Port *port)
74810850SGiacomo.Gabrielli@arm.com{
74910850SGiacomo.Gabrielli@arm.com    Port::setPeer(port);
75010850SGiacomo.Gabrielli@arm.com
75110850SGiacomo.Gabrielli@arm.com#if FULL_SYSTEM
75210850SGiacomo.Gabrielli@arm.com    // Update the ThreadContext's memory ports (Functional/Virtual
75310850SGiacomo.Gabrielli@arm.com    // Ports)
75410850SGiacomo.Gabrielli@arm.com    cpu->tcBase()->connectMemPorts();
75510850SGiacomo.Gabrielli@arm.com#endif
75610850SGiacomo.Gabrielli@arm.com}
75710850SGiacomo.Gabrielli@arm.com
75810850SGiacomo.Gabrielli@arm.combool
75910850SGiacomo.Gabrielli@arm.comTimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
76010850SGiacomo.Gabrielli@arm.com{
76110850SGiacomo.Gabrielli@arm.com    if (pkt->isResponse() && !pkt->wasNacked()) {
76210850SGiacomo.Gabrielli@arm.com        // delay processing of returned data until next CPU clock edge
7636640Svince@csl.cornell.edu        Tick next_tick = cpu->nextCycle(curTick);
7646640Svince@csl.cornell.edu
7656640Svince@csl.cornell.edu        if (next_tick == curTick)
7666640Svince@csl.cornell.edu            cpu->completeDataAccess(pkt);
7676640Svince@csl.cornell.edu        else
7686640Svince@csl.cornell.edu            tickEvent.schedule(pkt, next_tick);
7696640Svince@csl.cornell.edu
7706701Sgblack@eecs.umich.edu        return true;
7716701Sgblack@eecs.umich.edu    }
77210793Sbrandon.potter@amd.com    else if (pkt->wasNacked()) {
7736640Svince@csl.cornell.edu        assert(cpu->_status == DcacheWaitResponse);
7746701Sgblack@eecs.umich.edu        pkt->reinitNacked();
7756701Sgblack@eecs.umich.edu        if (!sendTiming(pkt)) {
7766640Svince@csl.cornell.edu            cpu->_status = DcacheRetry;
7778706Sandreas.hansson@arm.com            cpu->dcache_pkt = pkt;
7786640Svince@csl.cornell.edu        }
7796701Sgblack@eecs.umich.edu    }
7806640Svince@csl.cornell.edu    //Snooping a Coherence Request, do nothing
781360SN/A    return true;
7821999SN/A}
7831999SN/A
7841999SN/Avoid
7853114Sgblack@eecs.umich.eduTimingSimpleCPU::DcachePort::DTickEvent::process()
7862680Sktlim@umich.edu{
7871999SN/A    cpu->completeDataAccess(pkt);
7881999SN/A}
7891999SN/A
7906701Sgblack@eecs.umich.eduvoid
7918852Sandreas.hansson@arm.comTimingSimpleCPU::DcachePort::recvRetry()
7926701Sgblack@eecs.umich.edu{
7931999SN/A    // we shouldn't get a retry unless we have a packet that we're
7946701Sgblack@eecs.umich.edu    // waiting to transmit
7951999SN/A    assert(cpu->dcache_pkt != NULL);
7966701Sgblack@eecs.umich.edu    assert(cpu->_status == DcacheRetry);
7971999SN/A    PacketPtr tmp = cpu->dcache_pkt;
7981999SN/A    if (sendTiming(tmp)) {
7991999SN/A        cpu->_status = DcacheWaitResponse;
8001999SN/A        // memory system takes ownership of packet
8011999SN/A        cpu->dcache_pkt = NULL;
8023669Sbinkertn@umich.edu    }
8033669Sbinkertn@umich.edu}
8043669Sbinkertn@umich.edu
8051999SN/ATimingSimpleCPU::IprEvent::IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu, Tick t)
8061999SN/A    : Event(&mainEventQueue), pkt(_pkt), cpu(_cpu)
8071999SN/A{
8082218SN/A    schedule(t);
8091999SN/A}
8101999SN/A
8111999SN/Avoid
8121999SN/ATimingSimpleCPU::IprEvent::process()
8131999SN/A{
8141999SN/A    cpu->completeDataAccess(pkt);
8151999SN/A}
8161999SN/A
8173114Sgblack@eecs.umich.educonst char *
8182680Sktlim@umich.eduTimingSimpleCPU::IprEvent::description()
8191999SN/A{
8206701Sgblack@eecs.umich.edu    return "Timing Simple CPU Delay IPR event";
82110931Sbrandon.potter@amd.com}
82210931Sbrandon.potter@amd.com
82310931Sbrandon.potter@amd.com
82410932Sbrandon.potter@amd.com////////////////////////////////////////////////////////////////////////
82510931Sbrandon.potter@amd.com//
8261999SN/A//  TimingSimpleCPU Simulation Object
8271999SN/A//
8281999SN/ATimingSimpleCPU *
8291999SN/ATimingSimpleCPUParams::create()
8301999SN/A{
8311999SN/A    TimingSimpleCPU::Params *params = new TimingSimpleCPU::Params();
8321999SN/A    params->name = name;
8331999SN/A    params->numberOfThreads = 1;
83410931Sbrandon.potter@amd.com    params->max_insts_any_thread = max_insts_any_thread;
8351999SN/A    params->max_insts_all_threads = max_insts_all_threads;
8362218SN/A    params->max_loads_any_thread = max_loads_any_thread;
8371999SN/A    params->max_loads_all_threads = max_loads_all_threads;
8381999SN/A    params->progress_interval = progress_interval;
8391999SN/A    params->deferRegistration = defer_registration;
8401999SN/A    params->clock = clock;
8415877Shsul@eecs.umich.edu    params->phase = phase;
8425877Shsul@eecs.umich.edu    params->functionTrace = function_trace;
8435877Shsul@eecs.umich.edu    params->functionTraceStart = function_trace_start;
8445877Shsul@eecs.umich.edu    params->system = system;
8455877Shsul@eecs.umich.edu    params->cpu_id = cpu_id;
8466701Sgblack@eecs.umich.edu    params->tracer = tracer;
8476701Sgblack@eecs.umich.edu
8486701Sgblack@eecs.umich.edu    params->itb = itb;
8496701Sgblack@eecs.umich.edu    params->dtb = dtb;
8506701Sgblack@eecs.umich.edu#if FULL_SYSTEM
85110027SChris.Adeniyi-Jones@arm.com    params->profile = profile;
85210027SChris.Adeniyi-Jones@arm.com    params->do_quiesce = do_quiesce;
85310027SChris.Adeniyi-Jones@arm.com    params->do_checkpoint_insts = do_checkpoint_insts;
85410027SChris.Adeniyi-Jones@arm.com    params->do_statistics_insts = do_statistics_insts;
85510027SChris.Adeniyi-Jones@arm.com#else
8565877Shsul@eecs.umich.edu    if (workload.size() != 1)
85710318Sandreas.hansson@arm.com        panic("only one workload allowed");
85810318Sandreas.hansson@arm.com    params->process = workload[0];
8595877Shsul@eecs.umich.edu#endif
8605877Shsul@eecs.umich.edu
8615877Shsul@eecs.umich.edu    TimingSimpleCPU *cpu = new TimingSimpleCPU(params);
8625877Shsul@eecs.umich.edu    return cpu;
86310486Stjablin@gmail.com}
86410486Stjablin@gmail.com