atomic.cc revision 2631
12381SN/A/* 213732Snikos.nikoleris@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 38949Sandreas.hansson@arm.com * All rights reserved. 48949Sandreas.hansson@arm.com * 58949Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 68949Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 78949Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 88949Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 98949Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 108949Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 118949Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 128949Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 138949Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 142592SN/A * this software without specific prior written permission. 1510975Sdavid.hashe@amd.com * 162381SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172381SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182381SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192381SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202381SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212381SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222381SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232381SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242381SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252381SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262381SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272381SN/A */ 282381SN/A 292381SN/A#include "arch/utility.hh" 302381SN/A#include "cpu/exetrace.hh" 312381SN/A#include "cpu/simple/atomic.hh" 322381SN/A#include "mem/packet_impl.hh" 332381SN/A#include "sim/builder.hh" 342381SN/A 352381SN/Ausing namespace std; 362381SN/Ausing namespace TheISA; 372381SN/A 382381SN/AAtomicSimpleCPU::TickEvent::TickEvent(AtomicSimpleCPU *c) 392381SN/A : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c) 402665Ssaidi@eecs.umich.edu{ 412665Ssaidi@eecs.umich.edu} 422665Ssaidi@eecs.umich.edu 432665Ssaidi@eecs.umich.edu 449031Sandreas.hansson@arm.comvoid 4512349Snikos.nikoleris@arm.comAtomicSimpleCPU::TickEvent::process() 462381SN/A{ 472381SN/A cpu->tick(); 482381SN/A} 492381SN/A 502662Sstever@eecs.umich.educonst char * 512381SN/AAtomicSimpleCPU::TickEvent::description() 522381SN/A{ 532381SN/A return "AtomicSimpleCPU tick event"; 542381SN/A} 552381SN/A 568229Snate@binkert.org 573348Sbinkertn@umich.eduvoid 583348Sbinkertn@umich.eduAtomicSimpleCPU::init() 593348Sbinkertn@umich.edu{ 6013856Sodanrc@yahoo.com.br //Create Memory Ports (conect them up) 615735Snate@binkert.org Port *mem_dport = mem->getPort(""); 624024Sbinkertn@umich.edu dcachePort.setPeer(mem_dport); 635735Snate@binkert.org mem_dport->setPeer(&dcachePort); 6412334Sgabeblack@google.com 655314Sstever@gmail.com Port *mem_iport = mem->getPort(""); 666216Snate@binkert.org icachePort.setPeer(mem_iport); 6713347Sgabeblack@google.com mem_iport->setPeer(&icachePort); 682392SN/A 694167Sbinkertn@umich.edu BaseCPU::init(); 702394SN/A#if FULL_SYSTEM 718737Skoansin.tan@gmail.com for (int i = 0; i < execContexts.size(); ++i) { 723349Sbinkertn@umich.edu ExecContext *xc = execContexts[i]; 732394SN/A 742812Srdreslin@umich.edu // initialize CPU, including PC 7512351Snikos.nikoleris@arm.com TheISA::initCPU(xc, xc->readCpuId()); 762812Srdreslin@umich.edu } 774022Sstever@eecs.umich.edu#endif 784022Sstever@eecs.umich.edu} 795735Snate@binkert.org 805735Snate@binkert.orgbool 814022Sstever@eecs.umich.eduAtomicSimpleCPU::CpuPort::recvTiming(Packet *pkt) 825735Snate@binkert.org{ 835735Snate@binkert.org panic("AtomicSimpleCPU doesn't expect recvAtomic callback!"); 845735Snate@binkert.org return true; 854022Sstever@eecs.umich.edu} 864022Sstever@eecs.umich.edu 874022Sstever@eecs.umich.eduTick 884022Sstever@eecs.umich.eduAtomicSimpleCPU::CpuPort::recvAtomic(Packet *pkt) 894473Sstever@eecs.umich.edu{ 905319Sstever@gmail.com panic("AtomicSimpleCPU doesn't expect recvAtomic callback!"); 914022Sstever@eecs.umich.edu return curTick; 924022Sstever@eecs.umich.edu} 9311199Sandreas.hansson@arm.com 9411199Sandreas.hansson@arm.comvoid 9512344Snikos.nikoleris@arm.comAtomicSimpleCPU::CpuPort::recvFunctional(Packet *pkt) 9610883Sali.jafri@arm.com{ 974022Sstever@eecs.umich.edu panic("AtomicSimpleCPU doesn't expect recvFunctional callback!"); 9813367Syuetsu.kodama@riken.jp} 994022Sstever@eecs.umich.edu 1004022Sstever@eecs.umich.eduvoid 1014022Sstever@eecs.umich.eduAtomicSimpleCPU::CpuPort::recvStatusChange(Status status) 10210886Sandreas.hansson@arm.com{ 1034022Sstever@eecs.umich.edu if (status == RangeChange) 1047465Ssteve.reinhardt@amd.com return; 1054628Sstever@eecs.umich.edu 1067465Ssteve.reinhardt@amd.com panic("AtomicSimpleCPU doesn't expect recvStatusChange callback!"); 1077465Ssteve.reinhardt@amd.com} 1084022Sstever@eecs.umich.edu 1094022Sstever@eecs.umich.eduPacket * 11010885Sandreas.hansson@arm.comAtomicSimpleCPU::CpuPort::recvRetry() 11110885Sandreas.hansson@arm.com{ 1124626Sstever@eecs.umich.edu panic("AtomicSimpleCPU doesn't expect recvRetry callback!"); 1134626Sstever@eecs.umich.edu return NULL; 1147669Ssteve.reinhardt@amd.com} 1154626Sstever@eecs.umich.edu 1164040Ssaidi@eecs.umich.edu 1174040Ssaidi@eecs.umich.eduAtomicSimpleCPU::AtomicSimpleCPU(Params *p) 1185650Sgblack@eecs.umich.edu : BaseSimpleCPU(p), tickEvent(this), 1195650Sgblack@eecs.umich.edu width(p->width), simulate_stalls(p->simulate_stalls), 12011256Santhony.gutierrez@amd.com icachePort(this), dcachePort(this) 12111256Santhony.gutierrez@amd.com{ 12212347Snikos.nikoleris@arm.com _status = Idle; 12312347Snikos.nikoleris@arm.com 12412347Snikos.nikoleris@arm.com ifetch_req = new Request(true); 12512347Snikos.nikoleris@arm.com ifetch_req->setAsid(0); 1264870Sstever@eecs.umich.edu // @todo fix me and get the real cpu iD!!! 1274870Sstever@eecs.umich.edu ifetch_req->setCpuNum(0); 1284870Sstever@eecs.umich.edu ifetch_req->setSize(sizeof(MachInst)); 1294870Sstever@eecs.umich.edu ifetch_pkt = new Packet; 1304870Sstever@eecs.umich.edu ifetch_pkt->cmd = Read; 1314870Sstever@eecs.umich.edu ifetch_pkt->dataStatic(&inst); 1328436SBrad.Beckmann@amd.com ifetch_pkt->req = ifetch_req; 1338436SBrad.Beckmann@amd.com ifetch_pkt->size = sizeof(MachInst); 1345314Sstever@gmail.com ifetch_pkt->dest = Packet::Broadcast; 1355314Sstever@gmail.com 1368184Ssomayeh@cs.wisc.edu data_read_req = new Request(true); 13710886Sandreas.hansson@arm.com // @todo fix me and get the real cpu iD!!! 13810886Sandreas.hansson@arm.com data_read_req->setCpuNum(0); 1394022Sstever@eecs.umich.edu data_read_req->setAsid(0); 1404022Sstever@eecs.umich.edu data_read_pkt = new Packet; 1414022Sstever@eecs.umich.edu data_read_pkt->cmd = Read; 1424022Sstever@eecs.umich.edu data_read_pkt->dataStatic(&dataReg); 1435735Snate@binkert.org data_read_pkt->req = data_read_req; 1445735Snate@binkert.org data_read_pkt->dest = Packet::Broadcast; 1455735Snate@binkert.org 1464022Sstever@eecs.umich.edu data_write_req = new Request(true); 1474022Sstever@eecs.umich.edu // @todo fix me and get the real cpu iD!!! 1484626Sstever@eecs.umich.edu data_write_req->setCpuNum(0); 1494626Sstever@eecs.umich.edu data_write_req->setAsid(0); 1507465Ssteve.reinhardt@amd.com data_write_pkt = new Packet; 1514022Sstever@eecs.umich.edu data_write_pkt->cmd = Write; 15212347Snikos.nikoleris@arm.com data_write_pkt->req = data_write_req; 15311284Sandreas.hansson@arm.com data_write_pkt->dest = Packet::Broadcast; 1544626Sstever@eecs.umich.edu} 1554626Sstever@eecs.umich.edu 1564626Sstever@eecs.umich.edu 15711199Sandreas.hansson@arm.comAtomicSimpleCPU::~AtomicSimpleCPU() 1584022Sstever@eecs.umich.edu{ 1594022Sstever@eecs.umich.edu} 1606076Sgblack@eecs.umich.edu 1614626Sstever@eecs.umich.eduvoid 1624870Sstever@eecs.umich.eduAtomicSimpleCPU::serialize(ostream &os) 1635314Sstever@gmail.com{ 1648184Ssomayeh@cs.wisc.edu BaseSimpleCPU::serialize(os); 16511600Sandreas.hansson@arm.com SERIALIZE_ENUM(_status); 1664022Sstever@eecs.umich.edu nameOut(os, csprintf("%s.tickEvent", name())); 1674022Sstever@eecs.umich.edu tickEvent.serialize(os); 1684022Sstever@eecs.umich.edu} 1695735Snate@binkert.org 1705735Snate@binkert.orgvoid 1715735Snate@binkert.orgAtomicSimpleCPU::unserialize(Checkpoint *cp, const string §ion) 1725735Snate@binkert.org{ 1735735Snate@binkert.org BaseSimpleCPU::unserialize(cp, section); 1745735Snate@binkert.org UNSERIALIZE_ENUM(_status); 1755735Snate@binkert.org tickEvent.unserialize(cp, csprintf("%s.tickEvent", section)); 1764022Sstever@eecs.umich.edu} 1775735Snate@binkert.org 1785735Snate@binkert.orgvoid 1794022Sstever@eecs.umich.eduAtomicSimpleCPU::switchOut(Sampler *s) 1805735Snate@binkert.org{ 1814022Sstever@eecs.umich.edu sampler = s; 1824022Sstever@eecs.umich.edu if (status() == Running) { 1834022Sstever@eecs.umich.edu _status = SwitchedOut; 1845735Snate@binkert.org 1854022Sstever@eecs.umich.edu tickEvent.squash(); 1864022Sstever@eecs.umich.edu } 1874022Sstever@eecs.umich.edu sampler->signalSwitched(); 1884022Sstever@eecs.umich.edu} 1894022Sstever@eecs.umich.edu 1904022Sstever@eecs.umich.edu 1915735Snate@binkert.orgvoid 1925735Snate@binkert.orgAtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU) 1935735Snate@binkert.org{ 1944022Sstever@eecs.umich.edu BaseCPU::takeOverFrom(oldCPU); 1954022Sstever@eecs.umich.edu 1964022Sstever@eecs.umich.edu assert(!tickEvent.scheduled()); 1974022Sstever@eecs.umich.edu 1984022Sstever@eecs.umich.edu // if any of this CPU's ExecContexts are active, mark the CPU as 19910583SCurtis.Dunham@arm.com // running and schedule its tick event. 20010583SCurtis.Dunham@arm.com for (int i = 0; i < execContexts.size(); ++i) { 20110583SCurtis.Dunham@arm.com ExecContext *xc = execContexts[i]; 20210583SCurtis.Dunham@arm.com if (xc->status() == ExecContext::Active && _status != Running) { 20310583SCurtis.Dunham@arm.com _status = Running; 20411284Sandreas.hansson@arm.com tickEvent.schedule(curTick); 20510583SCurtis.Dunham@arm.com break; 20610583SCurtis.Dunham@arm.com } 20711199Sandreas.hansson@arm.com } 20812347Snikos.nikoleris@arm.com} 20911600Sandreas.hansson@arm.com 21011199Sandreas.hansson@arm.com 21111199Sandreas.hansson@arm.comvoid 21211199Sandreas.hansson@arm.comAtomicSimpleCPU::activateContext(int thread_num, int delay) 21311199Sandreas.hansson@arm.com{ 21411199Sandreas.hansson@arm.com assert(thread_num == 0); 21511199Sandreas.hansson@arm.com assert(cpuXC); 21610570Sandreas.hansson@arm.com 21710570Sandreas.hansson@arm.com assert(_status == Idle); 21810570Sandreas.hansson@arm.com assert(!tickEvent.scheduled()); 21910570Sandreas.hansson@arm.com 22010570Sandreas.hansson@arm.com notIdleFraction++; 22110570Sandreas.hansson@arm.com tickEvent.schedule(curTick + cycles(delay)); 2224022Sstever@eecs.umich.edu _status = Running; 2236102Sgblack@eecs.umich.edu} 22410343SCurtis.Dunham@arm.com 22510343SCurtis.Dunham@arm.com 22610343SCurtis.Dunham@arm.comvoid 22710343SCurtis.Dunham@arm.comAtomicSimpleCPU::suspendContext(int thread_num) 2284870Sstever@eecs.umich.edu{ 2295314Sstever@gmail.com assert(thread_num == 0); 2308184Ssomayeh@cs.wisc.edu assert(cpuXC); 2314022Sstever@eecs.umich.edu 23211294Sandreas.hansson@arm.com assert(_status == Running); 2335735Snate@binkert.org 2345735Snate@binkert.org // tick event may not be scheduled if this gets called from inside 2354022Sstever@eecs.umich.edu // an instruction's execution, e.g. "quiesce" 2364022Sstever@eecs.umich.edu if (tickEvent.scheduled()) 2374022Sstever@eecs.umich.edu tickEvent.deschedule(); 2385735Snate@binkert.org 2395735Snate@binkert.org notIdleFraction--; 2404022Sstever@eecs.umich.edu _status = Idle; 2414022Sstever@eecs.umich.edu} 2425735Snate@binkert.org 2435735Snate@binkert.org 2445735Snate@binkert.orgtemplate <class T> 2454022Sstever@eecs.umich.eduFault 2465735Snate@binkert.orgAtomicSimpleCPU::read(Addr addr, T &data, unsigned flags) 2475735Snate@binkert.org{ 2484022Sstever@eecs.umich.edu data_read_req->setVaddr(addr); 2494022Sstever@eecs.umich.edu data_read_req->setSize(sizeof(T)); 2502381SN/A data_read_req->setFlags(flags); 2512662Sstever@eecs.umich.edu data_read_req->setTime(curTick); 2522662Sstever@eecs.umich.edu 2532662Sstever@eecs.umich.edu if (traceData) { 2542662Sstever@eecs.umich.edu traceData->setAddr(addr); 2552662Sstever@eecs.umich.edu } 2562381SN/A 2579044SAli.Saidi@ARM.com // translate to physical address 2582381SN/A Fault fault = cpuXC->translateDataReadReq(data_read_req); 2592813Srdreslin@umich.edu 2605735Snate@binkert.org // Now do the access. 2615735Snate@binkert.org if (fault == NoFault) { 2624022Sstever@eecs.umich.edu data_read_pkt->reset(); 2635735Snate@binkert.org data_read_pkt->addr = data_read_req->getPaddr(); 2645735Snate@binkert.org data_read_pkt->size = sizeof(T); 26510938Sandreas.hansson@arm.com 26610938Sandreas.hansson@arm.com dcache_complete = dcachePort.sendAtomic(data_read_pkt); 26712349Snikos.nikoleris@arm.com dcache_access = true; 26810938Sandreas.hansson@arm.com 26913732Snikos.nikoleris@arm.com assert(data_read_pkt->result == Success); 27013732Snikos.nikoleris@arm.com data = data_read_pkt->get<T>(); 27113732Snikos.nikoleris@arm.com 27211284Sandreas.hansson@arm.com } 27311284Sandreas.hansson@arm.com 27411284Sandreas.hansson@arm.com // This will need a new way to tell if it has a dcache attached. 27511284Sandreas.hansson@arm.com if (data_read_req->getFlags() & UNCACHEABLE) 27610938Sandreas.hansson@arm.com recordEvent("Uncached Read"); 27710938Sandreas.hansson@arm.com 27810938Sandreas.hansson@arm.com return fault; 27911284Sandreas.hansson@arm.com} 28011284Sandreas.hansson@arm.com 28111284Sandreas.hansson@arm.com#ifndef DOXYGEN_SHOULD_SKIP_THIS 28211284Sandreas.hansson@arm.com 28311284Sandreas.hansson@arm.comtemplate 28411284Sandreas.hansson@arm.comFault 28511284Sandreas.hansson@arm.comAtomicSimpleCPU::read(Addr addr, uint64_t &data, unsigned flags); 28611284Sandreas.hansson@arm.com 28711284Sandreas.hansson@arm.comtemplate 28810938Sandreas.hansson@arm.comFault 28912346Snikos.nikoleris@arm.comAtomicSimpleCPU::read(Addr addr, uint32_t &data, unsigned flags); 29012346Snikos.nikoleris@arm.com 29112346Snikos.nikoleris@arm.comtemplate 29212346Snikos.nikoleris@arm.comFault 29312349Snikos.nikoleris@arm.comAtomicSimpleCPU::read(Addr addr, uint16_t &data, unsigned flags); 29412349Snikos.nikoleris@arm.com 29512349Snikos.nikoleris@arm.comtemplate 29612349Snikos.nikoleris@arm.comFault 29711057Sandreas.hansson@arm.comAtomicSimpleCPU::read(Addr addr, uint8_t &data, unsigned flags); 29811057Sandreas.hansson@arm.com 29911057Sandreas.hansson@arm.com#endif //DOXYGEN_SHOULD_SKIP_THIS 30011057Sandreas.hansson@arm.com 30110938Sandreas.hansson@arm.comtemplate<> 30210938Sandreas.hansson@arm.comFault 30310938Sandreas.hansson@arm.comAtomicSimpleCPU::read(Addr addr, double &data, unsigned flags) 30410938Sandreas.hansson@arm.com{ 30510938Sandreas.hansson@arm.com return read(addr, *(uint64_t*)&data, flags); 30610938Sandreas.hansson@arm.com} 30710938Sandreas.hansson@arm.com 30810938Sandreas.hansson@arm.comtemplate<> 30910938Sandreas.hansson@arm.comFault 31010938Sandreas.hansson@arm.comAtomicSimpleCPU::read(Addr addr, float &data, unsigned flags) 31110938Sandreas.hansson@arm.com{ 31210938Sandreas.hansson@arm.com return read(addr, *(uint32_t*)&data, flags); 31310938Sandreas.hansson@arm.com} 31410938Sandreas.hansson@arm.com 31510938Sandreas.hansson@arm.com 31610938Sandreas.hansson@arm.comtemplate<> 3175735Snate@binkert.orgFault 3185735Snate@binkert.orgAtomicSimpleCPU::read(Addr addr, int32_t &data, unsigned flags) 3195735Snate@binkert.org{ 3205735Snate@binkert.org return read(addr, (uint32_t&)data, flags); 3214022Sstever@eecs.umich.edu} 3224022Sstever@eecs.umich.edu 3235735Snate@binkert.org 3244870Sstever@eecs.umich.edutemplate <class T> 3254870Sstever@eecs.umich.eduFault 32612351Snikos.nikoleris@arm.comAtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) 32712351Snikos.nikoleris@arm.com{ 3285735Snate@binkert.org data_write_req->setVaddr(addr); 32912749Sgiacomo.travaglini@arm.com data_write_req->setTime(curTick); 3304870Sstever@eecs.umich.edu data_write_req->setSize(sizeof(T)); 3312566SN/A data_write_req->setFlags(flags); 3325735Snate@binkert.org 33312633Sodanrc@yahoo.com.br if (traceData) { 33412633Sodanrc@yahoo.com.br traceData->setAddr(addr); 3355735Snate@binkert.org } 33612633Sodanrc@yahoo.com.br 3375735Snate@binkert.org // translate to physical address 3382566SN/A Fault fault = cpuXC->translateDataWriteReq(data_write_req); 3392566SN/A 3402566SN/A // Now do the access. 3415735Snate@binkert.org if (fault == NoFault) { 3425735Snate@binkert.org data_write_pkt->reset(); 3432381SN/A data = htog(data); 3442381SN/A data_write_pkt->dataStatic(&data); 34510028SGiacomo.Gabrielli@arm.com data_write_pkt->addr = data_write_req->getPaddr(); 34610028SGiacomo.Gabrielli@arm.com data_write_pkt->size = sizeof(T); 34710028SGiacomo.Gabrielli@arm.com 3485735Snate@binkert.org dcache_complete = dcachePort.sendAtomic(data_write_pkt); 3496227Snate@binkert.org dcache_access = true; 3502381SN/A 3515735Snate@binkert.org assert(data_write_pkt->result == Success); 35210723Sandreas.hansson@arm.com 3538668Sgeoffrey.blake@arm.com if (res && data_write_req->getFlags() & LOCKED) { 35410723Sandreas.hansson@arm.com *res = data_write_req->getScResult(); 3558668Sgeoffrey.blake@arm.com } 35612966SMatteo.Andreozzi@arm.com } 35712966SMatteo.Andreozzi@arm.com 35812966SMatteo.Andreozzi@arm.com // This will need a new way to tell if it's hooked up to a cache or not. 3592641Sstever@eecs.umich.edu if (data_write_req->getFlags() & UNCACHEABLE) 3602811Srdreslin@umich.edu recordEvent("Uncached Write"); 3619547Sandreas.hansson@arm.com 36210694SMarco.Balboni@ARM.com // If the write needs to have a fault on the access, consider calling 36310405Sandreas.hansson@arm.com // changeStatus() and changing it to "bad addr write" or something. 36410405Sandreas.hansson@arm.com return fault; 36510405Sandreas.hansson@arm.com} 36610405Sandreas.hansson@arm.com 3679547Sandreas.hansson@arm.com 36810694SMarco.Balboni@ARM.com#ifndef DOXYGEN_SHOULD_SKIP_THIS 3693218Sgblack@eecs.umich.edutemplate 3709547Sandreas.hansson@arm.comFault 37111127Sandreas.hansson@arm.comAtomicSimpleCPU::write(uint64_t data, Addr addr, 37211127Sandreas.hansson@arm.com unsigned flags, uint64_t *res); 37311127Sandreas.hansson@arm.com 37411127Sandreas.hansson@arm.comtemplate 37511127Sandreas.hansson@arm.comFault 37611127Sandreas.hansson@arm.comAtomicSimpleCPU::write(uint32_t data, Addr addr, 37711127Sandreas.hansson@arm.com unsigned flags, uint64_t *res); 37811127Sandreas.hansson@arm.com 37910694SMarco.Balboni@ARM.comtemplate 38010694SMarco.Balboni@ARM.comFault 38110694SMarco.Balboni@ARM.comAtomicSimpleCPU::write(uint16_t data, Addr addr, 38210694SMarco.Balboni@ARM.com unsigned flags, uint64_t *res); 38310405Sandreas.hansson@arm.com 38410405Sandreas.hansson@arm.comtemplate 3859547Sandreas.hansson@arm.comFault 38610694SMarco.Balboni@ARM.comAtomicSimpleCPU::write(uint8_t data, Addr addr, 3873218Sgblack@eecs.umich.edu unsigned flags, uint64_t *res); 3885735Snate@binkert.org 3895735Snate@binkert.org#endif //DOXYGEN_SHOULD_SKIP_THIS 39013892Sgabeblack@google.com 3919542Sandreas.hansson@arm.comtemplate<> 39213892Sgabeblack@google.comFault 3939542Sandreas.hansson@arm.comAtomicSimpleCPU::write(double data, Addr addr, unsigned flags, uint64_t *res) 3949542Sandreas.hansson@arm.com{ 3959542Sandreas.hansson@arm.com return write(*(uint64_t*)&data, addr, flags, res); 3969542Sandreas.hansson@arm.com} 39713892Sgabeblack@google.com 3989542Sandreas.hansson@arm.comtemplate<> 39913892Sgabeblack@google.comFault 4009542Sandreas.hansson@arm.comAtomicSimpleCPU::write(float data, Addr addr, unsigned flags, uint64_t *res) 4019542Sandreas.hansson@arm.com{ 4029542Sandreas.hansson@arm.com return write(*(uint32_t*)&data, addr, flags, res); 4039542Sandreas.hansson@arm.com} 4045735Snate@binkert.org 4055735Snate@binkert.org 4065735Snate@binkert.orgtemplate<> 4079542Sandreas.hansson@arm.comFault 4089542Sandreas.hansson@arm.comAtomicSimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res) 4092641Sstever@eecs.umich.edu{ 4102641Sstever@eecs.umich.edu return write((uint32_t)data, addr, flags, res); 4112641Sstever@eecs.umich.edu} 4125315Sstever@gmail.com 4135315Sstever@gmail.com 4145315Sstever@gmail.comvoid 4155315Sstever@gmail.comAtomicSimpleCPU::tick() 4169044SAli.Saidi@ARM.com{ 4175735Snate@binkert.org Tick latency = cycles(1); // instruction takes one cycle by default 4185735Snate@binkert.org 4195735Snate@binkert.org for (int i = 0; i < width; ++i) { 4205735Snate@binkert.org numCycles++; 4215735Snate@binkert.org 4225735Snate@binkert.org checkForInterrupts(); 4235735Snate@binkert.org 4245314Sstever@gmail.com ifetch_req->resetMin(); 4255314Sstever@gmail.com ifetch_pkt->reset(); 4265314Sstever@gmail.com Fault fault = setupFetchPacket(ifetch_pkt); 4275735Snate@binkert.org 4285314Sstever@gmail.com if (fault == NoFault) { 4295314Sstever@gmail.com Tick icache_complete = icachePort.sendAtomic(ifetch_pkt); 4305314Sstever@gmail.com // ifetch_req is initialized to read the instruction directly 4315314Sstever@gmail.com // into the CPU object's inst field. 4325314Sstever@gmail.com 4335314Sstever@gmail.com dcache_access = false; // assume no dcache access 4345314Sstever@gmail.com preExecute(); 4355314Sstever@gmail.com fault = curStaticInst->execute(this, traceData); 4365314Sstever@gmail.com postExecute(); 4375314Sstever@gmail.com 4385314Sstever@gmail.com if (traceData) { 4395314Sstever@gmail.com traceData->finalize(); 4405314Sstever@gmail.com } 4415314Sstever@gmail.com 4425735Snate@binkert.org if (simulate_stalls) { 4435735Snate@binkert.org // This calculation assumes that the icache and dcache 4445735Snate@binkert.org // access latencies are always a multiple of the CPU's 4455314Sstever@gmail.com // cycle time. If not, the next tick event may get 4465315Sstever@gmail.com // scheduled at a non-integer multiple of the CPU 4475735Snate@binkert.org // cycle time. 4485735Snate@binkert.org Tick icache_stall = icache_complete - curTick - cycles(1); 4495315Sstever@gmail.com Tick dcache_stall = 4505735Snate@binkert.org dcache_access ? dcache_complete - curTick - cycles(1) : 0; 4515735Snate@binkert.org latency += icache_stall + dcache_stall; 4525314Sstever@gmail.com } 4535314Sstever@gmail.com 4545735Snate@binkert.org } 4555735Snate@binkert.org 4565735Snate@binkert.org advancePC(fault); 4575735Snate@binkert.org } 4585314Sstever@gmail.com 4595735Snate@binkert.org if (_status != Idle) 4605735Snate@binkert.org tickEvent.schedule(curTick + latency); 4615735Snate@binkert.org} 4625315Sstever@gmail.com 4635735Snate@binkert.org 4645735Snate@binkert.org//////////////////////////////////////////////////////////////////////// 4655314Sstever@gmail.com// 4665735Snate@binkert.org// AtomicSimpleCPU Simulation Object 4675735Snate@binkert.org// 4685735Snate@binkert.orgBEGIN_DECLARE_SIM_OBJECT_PARAMS(AtomicSimpleCPU) 4695735Snate@binkert.org 4705735Snate@binkert.org Param<Counter> max_insts_any_thread; 4715314Sstever@gmail.com Param<Counter> max_insts_all_threads; 4725314Sstever@gmail.com Param<Counter> max_loads_any_thread; 4735314Sstever@gmail.com Param<Counter> max_loads_all_threads; 4745735Snate@binkert.org SimObjectParam<MemObject *> mem; 4755735Snate@binkert.org 4765735Snate@binkert.org#if FULL_SYSTEM 4775735Snate@binkert.org SimObjectParam<AlphaITB *> itb; 4789542Sandreas.hansson@arm.com SimObjectParam<AlphaDTB *> dtb; 4795735Snate@binkert.org SimObjectParam<System *> system; 4805735Snate@binkert.org Param<int> cpu_id; 4815735Snate@binkert.org Param<Tick> profile; 4822662Sstever@eecs.umich.edu#else 4832641Sstever@eecs.umich.edu SimObjectParam<Process *> workload; 4849542Sandreas.hansson@arm.com#endif // FULL_SYSTEM 4859542Sandreas.hansson@arm.com 4869542Sandreas.hansson@arm.com Param<int> clock; 4879542Sandreas.hansson@arm.com 4889542Sandreas.hansson@arm.com Param<bool> defer_registration; 4899542Sandreas.hansson@arm.com Param<int> width; 4909542Sandreas.hansson@arm.com Param<bool> function_trace; 4919542Sandreas.hansson@arm.com Param<Tick> function_trace_start; 4929542Sandreas.hansson@arm.com Param<bool> simulate_stalls; 4939542Sandreas.hansson@arm.com 4949542Sandreas.hansson@arm.comEND_DECLARE_SIM_OBJECT_PARAMS(AtomicSimpleCPU) 4959542Sandreas.hansson@arm.com 4969542Sandreas.hansson@arm.comBEGIN_INIT_SIM_OBJECT_PARAMS(AtomicSimpleCPU) 4979542Sandreas.hansson@arm.com 4989542Sandreas.hansson@arm.com INIT_PARAM(max_insts_any_thread, 4999542Sandreas.hansson@arm.com "terminate when any thread reaches this inst count"), 5009542Sandreas.hansson@arm.com INIT_PARAM(max_insts_all_threads, 5019542Sandreas.hansson@arm.com "terminate when all threads have reached this inst count"), 5029542Sandreas.hansson@arm.com INIT_PARAM(max_loads_any_thread, 5039542Sandreas.hansson@arm.com "terminate when any thread reaches this load count"), 5049543Ssascha.bischoff@arm.com INIT_PARAM(max_loads_all_threads, 5059543Ssascha.bischoff@arm.com "terminate when all threads have reached this load count"), 5069543Ssascha.bischoff@arm.com INIT_PARAM(mem, "memory"), 5079543Ssascha.bischoff@arm.com 5089543Ssascha.bischoff@arm.com#if FULL_SYSTEM 5099543Ssascha.bischoff@arm.com INIT_PARAM(itb, "Instruction TLB"), 5109543Ssascha.bischoff@arm.com INIT_PARAM(dtb, "Data TLB"), 5119543Ssascha.bischoff@arm.com INIT_PARAM(system, "system object"), 5129543Ssascha.bischoff@arm.com INIT_PARAM(cpu_id, "processor ID"), 5139543Ssascha.bischoff@arm.com INIT_PARAM(profile, ""), 5149543Ssascha.bischoff@arm.com#else 5159543Ssascha.bischoff@arm.com INIT_PARAM(workload, "processes to run"), 5169543Ssascha.bischoff@arm.com#endif // FULL_SYSTEM 5179543Ssascha.bischoff@arm.com 5189543Ssascha.bischoff@arm.com INIT_PARAM(clock, "clock speed"), 5199543Ssascha.bischoff@arm.com INIT_PARAM(defer_registration, "defer system registration (for sampling)"), 5209543Ssascha.bischoff@arm.com INIT_PARAM(width, "cpu width"), 5219543Ssascha.bischoff@arm.com INIT_PARAM(function_trace, "Enable function trace"), 5229543Ssascha.bischoff@arm.com INIT_PARAM(function_trace_start, "Cycle to start function trace"), 5235735Snate@binkert.org INIT_PARAM(simulate_stalls, "Simulate cache stall cycles") 5245735Snate@binkert.org 5254022Sstever@eecs.umich.eduEND_INIT_SIM_OBJECT_PARAMS(AtomicSimpleCPU) 5262811Srdreslin@umich.edu 5275735Snate@binkert.org 5284022Sstever@eecs.umich.eduCREATE_SIM_OBJECT(AtomicSimpleCPU) 5292811Srdreslin@umich.edu{ 53010583SCurtis.Dunham@arm.com AtomicSimpleCPU::Params *params = new AtomicSimpleCPU::Params(); 53110583SCurtis.Dunham@arm.com params->name = getInstanceName(); 53210583SCurtis.Dunham@arm.com params->numberOfThreads = 1; 53310583SCurtis.Dunham@arm.com params->max_insts_any_thread = max_insts_any_thread; 53410583SCurtis.Dunham@arm.com params->max_insts_all_threads = max_insts_all_threads; 53511287Sandreas.hansson@arm.com params->max_loads_any_thread = max_loads_any_thread; 53611287Sandreas.hansson@arm.com params->max_loads_all_threads = max_loads_all_threads; 53711287Sandreas.hansson@arm.com params->deferRegistration = defer_registration; 53811287Sandreas.hansson@arm.com params->clock = clock; 53911287Sandreas.hansson@arm.com params->functionTrace = function_trace; 54011287Sandreas.hansson@arm.com params->functionTraceStart = function_trace_start; 54111287Sandreas.hansson@arm.com params->width = width; 54211287Sandreas.hansson@arm.com params->simulate_stalls = simulate_stalls; 54311287Sandreas.hansson@arm.com params->mem = mem; 54410583SCurtis.Dunham@arm.com 54510583SCurtis.Dunham@arm.com#if FULL_SYSTEM 54611199Sandreas.hansson@arm.com params->itb = itb; 54712347Snikos.nikoleris@arm.com params->dtb = dtb; 54811600Sandreas.hansson@arm.com params->system = system; 54911199Sandreas.hansson@arm.com params->cpu_id = cpu_id; 55010583SCurtis.Dunham@arm.com params->profile = profile; 55111286Sandreas.hansson@arm.com#else 55211286Sandreas.hansson@arm.com params->process = workload; 55311286Sandreas.hansson@arm.com#endif 55411286Sandreas.hansson@arm.com 55511286Sandreas.hansson@arm.com AtomicSimpleCPU *cpu = new AtomicSimpleCPU(params); 55610583SCurtis.Dunham@arm.com return cpu; 55710583SCurtis.Dunham@arm.com} 55810583SCurtis.Dunham@arm.com 55910583SCurtis.Dunham@arm.comREGISTER_SIM_OBJECT("AtomicSimpleCPU", AtomicSimpleCPU) 5602812Srdreslin@umich.edu 56113350Snikos.nikoleris@arm.com