abstract_mem.cc revision 10466
12968SN/A/* 22968SN/A * Copyright (c) 2010-2012 ARM Limited 32968SN/A * All rights reserved 49988Snilay@cs.wisc.edu * 58835SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall 69988Snilay@cs.wisc.edu * not be construed as granting a license to any other intellectual 77935SN/A * property including but not limited to intellectual property relating 87935SN/A * to a hardware implementation of the functionality of the software 97935SN/A * licensed hereunder. You may use the software subject to the license 102968SN/A * terms below provided that you ensure that this notice is replicated 112968SN/A * unmodified and in its entirety in all distributions of the software, 122968SN/A * modified or unmodified, in source code or in binary form. 1310315Snilay@cs.wisc.edu * 144463SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan 152968SN/A * All rights reserved. 169885Sstever@gmail.com * 179885Sstever@gmail.com * Redistribution and use in source and binary forms, with or without 1811268Satgutier@umich.edu * modification, are permitted provided that the following conditions are 199988Snilay@cs.wisc.edu * met: redistributions of source code must retain the above copyright 2011312Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer; 212968SN/A * redistributions in binary form must reproduce the above copyright 2211268Satgutier@umich.edu * notice, this list of conditions and the following disclaimer in the 2310315Snilay@cs.wisc.edu * documentation and/or other materials provided with the distribution; 247670SN/A * neither the name of the copyright holders nor the names of its 2510315Snilay@cs.wisc.edu * contributors may be used to endorse or promote products derived from 262968SN/A * this software without specific prior written permission. 279481Snilay@cs.wisc.edu * 288721SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2910736Snilay@cs.wisc.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3011219Snilay@cs.wisc.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 318721SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3211268Satgutier@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3311312Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 343140SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352968SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362968SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 377935SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 387935SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 397935SN/A * 407935SN/A * Authors: Ron Dreslinski 417935SN/A * Ali Saidi 427935SN/A * Andreas Hansson 437935SN/A */ 448983Snate@binkert.org 452968SN/A#include <vector> 462968SN/A 472968SN/A#include "cpu/base.hh" 489885Sstever@gmail.com#include "cpu/thread_context.hh" 494463SN/A#include "debug/LLSC.hh" 509988Snilay@cs.wisc.edu#include "debug/MemoryAccess.hh" 518721SN/A#include "mem/abstract_mem.hh" 528721SN/A#include "mem/packet_access.hh" 538721SN/A#include "sim/system.hh" 548983Snate@binkert.org 558983Snate@binkert.orgusing namespace std; 562968SN/A 579885Sstever@gmail.comAbstractMemory::AbstractMemory(const Params *p) : 589885Sstever@gmail.com MemObject(p), range(params()->range), pmemAddr(NULL), 599885Sstever@gmail.com confTableReported(p->conf_table_reported), inAddrMap(p->in_addr_map), 6010315Snilay@cs.wisc.edu _system(NULL) 619988Snilay@cs.wisc.edu{ 6210315Snilay@cs.wisc.edu} 639885Sstever@gmail.com 649885Sstever@gmail.comvoid 652968SN/AAbstractMemory::init() 662968SN/A{ 679481Snilay@cs.wisc.edu assert(system()); 6810315Snilay@cs.wisc.edu 695876SN/A if (size() % _system->getPageBytes() != 0) 709885Sstever@gmail.com panic("Memory Size not divisible by page size\n"); 713171SN/A} 723638SN/A 733638SN/Avoid 743638SN/AAbstractMemory::setBackingStore(uint8_t* pmem_addr) 752968SN/A{ 769988Snilay@cs.wisc.edu pmemAddr = pmem_addr; 778983Snate@binkert.org} 782968SN/A 792968SN/Avoid 805723SN/AAbstractMemory::regStats() 819481Snilay@cs.wisc.edu{ 822968SN/A using namespace Stats; 832968SN/A 842968SN/A assert(system()); 852968SN/A 862968SN/A bytesRead 875575SN/A .init(system()->maxMasters()) 882968SN/A .name(name() + ".bytes_read") 893140SN/A .desc("Number of bytes read from this memory") 909885Sstever@gmail.com .flags(total | nozero | nonan) 915509SN/A ; 925509SN/A for (int i = 0; i < system()->maxMasters(); i++) { 9310315Snilay@cs.wisc.edu bytesRead.subname(i, system()->getMasterName(i)); 949481Snilay@cs.wisc.edu } 952968SN/A bytesInstRead 964938SN/A .init(system()->maxMasters()) 972968SN/A .name(name() + ".bytes_inst_read") 988835SAli.Saidi@ARM.com .desc("Number of instructions bytes read from this memory") 994463SN/A .flags(total | nozero | nonan) 1004463SN/A ; 1014463SN/A for (int i = 0; i < system()->maxMasters(); i++) { 1024463SN/A bytesInstRead.subname(i, system()->getMasterName(i)); 10311103Snilay@cs.wisc.edu } 1049885Sstever@gmail.com bytesWritten 1058983Snate@binkert.org .init(system()->maxMasters()) 1064463SN/A .name(name() + ".bytes_written") 1079885Sstever@gmail.com .desc("Number of bytes written to this memory") 10811219Snilay@cs.wisc.edu .flags(total | nozero | nonan) 10910636Snilay@cs.wisc.edu ; 1109988Snilay@cs.wisc.edu for (int i = 0; i < system()->maxMasters(); i++) { 1116123SN/A bytesWritten.subname(i, system()->getMasterName(i)); 1129481Snilay@cs.wisc.edu } 11311103Snilay@cs.wisc.edu numReads 1144463SN/A .init(system()->maxMasters()) 1154463SN/A .name(name() + ".num_reads") 1165876SN/A .desc("Number of read requests responded to by this memory") 1178835SAli.Saidi@ARM.com .flags(total | nozero | nonan) 1189481Snilay@cs.wisc.edu ; 11910036SAli.Saidi@ARM.com for (int i = 0; i < system()->maxMasters(); i++) { 1204463SN/A numReads.subname(i, system()->getMasterName(i)); 1218835SAli.Saidi@ARM.com } 1229885Sstever@gmail.com numWrites 1239481Snilay@cs.wisc.edu .init(system()->maxMasters()) 1244463SN/A .name(name() + ".num_writes") 12511219Snilay@cs.wisc.edu .desc("Number of write requests responded to by this memory") 1264463SN/A .flags(total | nozero | nonan) 1279481Snilay@cs.wisc.edu ; 1284463SN/A for (int i = 0; i < system()->maxMasters(); i++) { 1299885Sstever@gmail.com numWrites.subname(i, system()->getMasterName(i)); 1309885Sstever@gmail.com } 1319885Sstever@gmail.com numOther 1329885Sstever@gmail.com .init(system()->maxMasters()) 1339885Sstever@gmail.com .name(name() + ".num_other") 1349988Snilay@cs.wisc.edu .desc("Number of other requests responded to by this memory") 1359885Sstever@gmail.com .flags(total | nozero | nonan) 13610036SAli.Saidi@ARM.com ; 1379885Sstever@gmail.com for (int i = 0; i < system()->maxMasters(); i++) { 1389885Sstever@gmail.com numOther.subname(i, system()->getMasterName(i)); 1392968SN/A } 1406024SN/A bwRead 1419988Snilay@cs.wisc.edu .name(name() + ".bw_read") 1422968SN/A .desc("Total read bandwidth from this memory (bytes/s)") 1432968SN/A .precision(0) 1444463SN/A .prereq(bytesRead) 14511103Snilay@cs.wisc.edu .flags(total | nozero | nonan) 1469885Sstever@gmail.com ; 1478983Snate@binkert.org for (int i = 0; i < system()->maxMasters(); i++) { 1484463SN/A bwRead.subname(i, system()->getMasterName(i)); 1499885Sstever@gmail.com } 15011219Snilay@cs.wisc.edu 15110636Snilay@cs.wisc.edu bwInstRead 1529988Snilay@cs.wisc.edu .name(name() + ".bw_inst_read") 1536123SN/A .desc("Instruction read bandwidth from this memory (bytes/s)") 1549481Snilay@cs.wisc.edu .precision(0) 15511103Snilay@cs.wisc.edu .prereq(bytesInstRead) 1564463SN/A .flags(total | nozero | nonan) 1574463SN/A ; 1585876SN/A for (int i = 0; i < system()->maxMasters(); i++) { 1598835SAli.Saidi@ARM.com bwInstRead.subname(i, system()->getMasterName(i)); 1609481Snilay@cs.wisc.edu } 16110036SAli.Saidi@ARM.com bwWrite 1624463SN/A .name(name() + ".bw_write") 1638835SAli.Saidi@ARM.com .desc("Write bandwidth from this memory (bytes/s)") 1649885Sstever@gmail.com .precision(0) 1659481Snilay@cs.wisc.edu .prereq(bytesWritten) 1664463SN/A .flags(total | nozero | nonan) 16711219Snilay@cs.wisc.edu ; 1684463SN/A for (int i = 0; i < system()->maxMasters(); i++) { 1699481Snilay@cs.wisc.edu bwWrite.subname(i, system()->getMasterName(i)); 1704463SN/A } 1719885Sstever@gmail.com bwTotal 1729885Sstever@gmail.com .name(name() + ".bw_total") 1739885Sstever@gmail.com .desc("Total bandwidth to/from this memory (bytes/s)") 1749885Sstever@gmail.com .precision(0) 1759885Sstever@gmail.com .prereq(bwTotal) 1769988Snilay@cs.wisc.edu .flags(total | nozero | nonan) 1779885Sstever@gmail.com ; 17810036SAli.Saidi@ARM.com for (int i = 0; i < system()->maxMasters(); i++) { 1799885Sstever@gmail.com bwTotal.subname(i, system()->getMasterName(i)); 1809885Sstever@gmail.com } 1815723SN/A bwRead = bytesRead / simSeconds; 1825723SN/A bwInstRead = bytesInstRead / simSeconds; 1839988Snilay@cs.wisc.edu bwWrite = bytesWritten / simSeconds; 1845723SN/A bwTotal = (bytesRead + bytesWritten) / simSeconds; 1859481Snilay@cs.wisc.edu} 1869481Snilay@cs.wisc.edu 1879988Snilay@cs.wisc.eduAddrRange 18810036SAli.Saidi@ARM.comAbstractMemory::getAddrRange() const 1899481Snilay@cs.wisc.edu{ 1902968SN/A return range; 1916024SN/A} 1929988Snilay@cs.wisc.edu 1932968SN/A// Add load-locked to tracking list. Should only be called if the 1942968SN/A// operation is a load and the LLSC flag is set. 1959481Snilay@cs.wisc.eduvoid 19611103Snilay@cs.wisc.eduAbstractMemory::trackLoadLocked(PacketPtr pkt) 1979885Sstever@gmail.com{ 1989481Snilay@cs.wisc.edu Request *req = pkt->req; 1999481Snilay@cs.wisc.edu Addr paddr = LockedAddr::mask(req->getPaddr()); 2009885Sstever@gmail.com 20111219Snilay@cs.wisc.edu // first we check if we already have a locked addr for this 20210636Snilay@cs.wisc.edu // xc. Since each xc only gets one, we just update the 2039988Snilay@cs.wisc.edu // existing record with the new address. 2049481Snilay@cs.wisc.edu list<LockedAddr>::iterator i; 2059481Snilay@cs.wisc.edu 20611103Snilay@cs.wisc.edu for (i = lockedAddrList.begin(); i != lockedAddrList.end(); ++i) { 2079481Snilay@cs.wisc.edu if (i->matchesContext(req)) { 2089481Snilay@cs.wisc.edu DPRINTF(LLSC, "Modifying lock record: context %d addr %#x\n", 2099481Snilay@cs.wisc.edu req->contextId(), paddr); 2109481Snilay@cs.wisc.edu i->addr = paddr; 2119481Snilay@cs.wisc.edu return; 21210036SAli.Saidi@ARM.com } 2139481Snilay@cs.wisc.edu } 2149481Snilay@cs.wisc.edu 2159885Sstever@gmail.com // no record for this xc: need to allocate a new one 2169481Snilay@cs.wisc.edu DPRINTF(LLSC, "Adding lock record: context %d addr %#x\n", 2179481Snilay@cs.wisc.edu req->contextId(), paddr); 21811219Snilay@cs.wisc.edu lockedAddrList.push_front(LockedAddr(req)); 2199481Snilay@cs.wisc.edu} 2209481Snilay@cs.wisc.edu 2219481Snilay@cs.wisc.edu 2229885Sstever@gmail.com// Called on *writes* only... both regular stores and 2239885Sstever@gmail.com// store-conditional operations. Check for conventional stores which 2249885Sstever@gmail.com// conflict with locked addresses, and for success/failure of store 2259885Sstever@gmail.com// conditionals. 2269885Sstever@gmail.combool 2279988Snilay@cs.wisc.eduAbstractMemory::checkLockedAddrList(PacketPtr pkt) 2289885Sstever@gmail.com{ 22910036SAli.Saidi@ARM.com Request *req = pkt->req; 2309885Sstever@gmail.com Addr paddr = LockedAddr::mask(req->getPaddr()); 2319885Sstever@gmail.com bool isLLSC = pkt->isLLSC(); 2329481Snilay@cs.wisc.edu 23310451Snilay@cs.wisc.edu // Initialize return value. Non-conditional stores always 23411219Snilay@cs.wisc.edu // succeed. Assume conditional stores will fail until proven 2359885Sstever@gmail.com // otherwise. 2369988Snilay@cs.wisc.edu bool allowStore = !isLLSC; 23710736Snilay@cs.wisc.edu 23810736Snilay@cs.wisc.edu // Iterate over list. Note that there could be multiple matching records, 23910736Snilay@cs.wisc.edu // as more than one context could have done a load locked to this location. 24011219Snilay@cs.wisc.edu // Only remove records when we succeed in finding a record for (xc, addr); 24110736Snilay@cs.wisc.edu // then, remove all records with this address. Failed store-conditionals do 2429885Sstever@gmail.com // not blow unrelated reservations. 2439481Snilay@cs.wisc.edu list<LockedAddr>::iterator i = lockedAddrList.begin(); 2449481Snilay@cs.wisc.edu 2459481Snilay@cs.wisc.edu if (isLLSC) { 2469481Snilay@cs.wisc.edu while (i != lockedAddrList.end()) { 2479481Snilay@cs.wisc.edu if (i->addr == paddr && i->matchesContext(req)) { 24811219Snilay@cs.wisc.edu // it's a store conditional, and as far as the memory system can 24911219Snilay@cs.wisc.edu // tell, the requesting context's lock is still valid. 25011219Snilay@cs.wisc.edu DPRINTF(LLSC, "StCond success: context %d addr %#x\n", 25111219Snilay@cs.wisc.edu req->contextId(), paddr); 25211219Snilay@cs.wisc.edu allowStore = true; 25311219Snilay@cs.wisc.edu break; 25411219Snilay@cs.wisc.edu } 2554938SN/A // If we didn't find a match, keep searching! Someone else may well 2564938SN/A // have a reservation on this line here but we may find ours in just 2579988Snilay@cs.wisc.edu // a little while. 2584938SN/A i++; 2599885Sstever@gmail.com } 2609885Sstever@gmail.com req->setExtraData(allowStore ? 1 : 0); 2619885Sstever@gmail.com } 26210315Snilay@cs.wisc.edu // LLSCs that succeeded AND non-LLSC stores both fall into here: 2639988Snilay@cs.wisc.edu if (allowStore) { 26410315Snilay@cs.wisc.edu // We write address paddr. However, there may be several entries with a 2659885Sstever@gmail.com // reservation on this address (for other contextIds) and they must all 2669885Sstever@gmail.com // be removed. 2672968SN/A i = lockedAddrList.begin(); 2682968SN/A while (i != lockedAddrList.end()) { 2692968SN/A if (i->addr == paddr) { 2704463SN/A DPRINTF(LLSC, "Erasing lock record: context %d addr %#x\n", 2712968SN/A i->contextId, paddr); 2729988Snilay@cs.wisc.edu // For ARM, a spinlock would typically include a Wait 2732968SN/A // For Event (WFE) to conserve energy. The ARMv8 2742968SN/A // architecture specifies that an event is 2752968SN/A // automatically generated when clearing the exclusive 2762968SN/A // monitor to wake up the processor in WFE. 2772968SN/A system()->getThreadContext(i->contextId)->getCpuPtr()->wakeup(); 2782968SN/A i = lockedAddrList.erase(i); 2799988Snilay@cs.wisc.edu } else { 2805876SN/A i++; 2812968SN/A } 2822968SN/A } 2832968SN/A } 2842968SN/A 2852968SN/A return allowStore; 2869988Snilay@cs.wisc.edu} 28711268Satgutier@umich.edu 2882968SN/A 2892968SN/A#if TRACING_ON 2902968SN/A 2912968SN/A#define CASE(A, T) \ 2922968SN/A case sizeof(T): \ 2934463SN/A DPRINTF(MemoryAccess,"%s from %s of size %i on address 0x%x data " \ 2942968SN/A "0x%x %c\n", A, system()->getMasterName(pkt->req->masterId()),\ 2959988Snilay@cs.wisc.edu pkt->getSize(), pkt->getAddr(), pkt->get<T>(), \ 2962968SN/A pkt->req->isUncacheable() ? 'U' : 'C'); \ 2972968SN/A break 2982968SN/A 2992968SN/A 3002968SN/A#define TRACE_PACKET(A) \ 3012968SN/A do { \ 3029988Snilay@cs.wisc.edu switch (pkt->getSize()) { \ 3035876SN/A CASE(A, uint64_t); \ 3042968SN/A CASE(A, uint32_t); \ 3052968SN/A CASE(A, uint16_t); \ 3062968SN/A CASE(A, uint8_t); \ 3072968SN/A default: \ 3082968SN/A DPRINTF(MemoryAccess, "%s from %s of size %i on address 0x%x %c\n",\ 3099988Snilay@cs.wisc.edu A, system()->getMasterName(pkt->req->masterId()), \ 31011268Satgutier@umich.edu pkt->getSize(), pkt->getAddr(), \ 3112968SN/A pkt->req->isUncacheable() ? 'U' : 'C'); \ 3122968SN/A DDUMP(MemoryAccess, pkt->getPtr<uint8_t>(), pkt->getSize()); \ 31310315Snilay@cs.wisc.edu } \ 31410315Snilay@cs.wisc.edu } while (0) 31510315Snilay@cs.wisc.edu 31610315Snilay@cs.wisc.edu#else 31710315Snilay@cs.wisc.edu 31810315Snilay@cs.wisc.edu#define TRACE_PACKET(A) 31910315Snilay@cs.wisc.edu 32010315Snilay@cs.wisc.edu#endif 3212968SN/A 3222968SN/Avoid 3239988Snilay@cs.wisc.eduAbstractMemory::access(PacketPtr pkt) 3244103SN/A{ 3252968SN/A assert(AddrRange(pkt->getAddr(), 3262968SN/A pkt->getAddr() + pkt->getSize() - 1).isSubset(range)); 32710451Snilay@cs.wisc.edu 3289885Sstever@gmail.com if (pkt->memInhibitAsserted()) { 3299988Snilay@cs.wisc.edu DPRINTF(MemoryAccess, "mem inhibited on 0x%x: not responding\n", 33010736Snilay@cs.wisc.edu pkt->getAddr()); 33110736Snilay@cs.wisc.edu return; 33210736Snilay@cs.wisc.edu } 33311245Sandreas.sandberg@arm.com 33410736Snilay@cs.wisc.edu uint8_t *hostAddr = pmemAddr + pkt->getAddr() - range.start(); 33511245Sandreas.sandberg@arm.com 3368983Snate@binkert.org if (pkt->cmd == MemCmd::SwapReq) { 3374966SN/A std::vector<uint8_t> overwrite_val(pkt->getSize()); 3384966SN/A uint64_t condition_val64; 33911103Snilay@cs.wisc.edu uint32_t condition_val32; 3409885Sstever@gmail.com 3419481Snilay@cs.wisc.edu if (!pmemAddr) 3424966SN/A panic("Swap only works if there is real memory (i.e. null=False)"); 3439885Sstever@gmail.com 34411219Snilay@cs.wisc.edu bool overwrite_mem = true; 34510636Snilay@cs.wisc.edu // keep a copy of our possible write value, and copy what is at the 3469988Snilay@cs.wisc.edu // memory address into the packet 3476123SN/A std::memcpy(&overwrite_val[0], pkt->getPtr<uint8_t>(), pkt->getSize()); 3489481Snilay@cs.wisc.edu std::memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize()); 34911103Snilay@cs.wisc.edu 3504966SN/A if (pkt->req->isCondSwap()) { 3514966SN/A if (pkt->getSize() == sizeof(uint64_t)) { 3525876SN/A condition_val64 = pkt->req->getExtraData(); 3538835SAli.Saidi@ARM.com overwrite_mem = !std::memcmp(&condition_val64, hostAddr, 3549481Snilay@cs.wisc.edu sizeof(uint64_t)); 35510036SAli.Saidi@ARM.com } else if (pkt->getSize() == sizeof(uint32_t)) { 3564966SN/A condition_val32 = (uint32_t)pkt->req->getExtraData(); 3578835SAli.Saidi@ARM.com overwrite_mem = !std::memcmp(&condition_val32, hostAddr, 3589885Sstever@gmail.com sizeof(uint32_t)); 3594966SN/A } else 3604966SN/A panic("Invalid size for conditional read/write\n"); 36111219Snilay@cs.wisc.edu } 36211245Sandreas.sandberg@arm.com 3638983Snate@binkert.org if (overwrite_mem) 3644463SN/A std::memcpy(hostAddr, &overwrite_val[0], pkt->getSize()); 3659885Sstever@gmail.com 3669885Sstever@gmail.com assert(!pkt->req->isInstFetch()); 3679885Sstever@gmail.com TRACE_PACKET("Read/Write"); 3689885Sstever@gmail.com numOther[pkt->req->masterId()]++; 3699885Sstever@gmail.com } else if (pkt->isRead()) { 3709988Snilay@cs.wisc.edu assert(!pkt->isWrite()); 3719885Sstever@gmail.com if (pkt->isLLSC()) { 37210036SAli.Saidi@ARM.com trackLoadLocked(pkt); 3739885Sstever@gmail.com } 3749885Sstever@gmail.com if (pmemAddr) 3752968SN/A memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize()); 37610451Snilay@cs.wisc.edu TRACE_PACKET(pkt->req->isInstFetch() ? "IFetch" : "Read"); 3776123SN/A numReads[pkt->req->masterId()]++; 3789885Sstever@gmail.com bytesRead[pkt->req->masterId()] += pkt->getSize(); 3799988Snilay@cs.wisc.edu if (pkt->req->isInstFetch()) 38010736Snilay@cs.wisc.edu bytesInstRead[pkt->req->masterId()] += pkt->getSize(); 38110736Snilay@cs.wisc.edu } else if (pkt->isWrite()) { 38210736Snilay@cs.wisc.edu if (writeOK(pkt)) { 38310451Snilay@cs.wisc.edu if (pmemAddr) { 38410736Snilay@cs.wisc.edu memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize()); 3859885Sstever@gmail.com DPRINTF(MemoryAccess, "%s wrote %x bytes to address %x\n", 3867524SN/A __func__, pkt->getSize(), pkt->getAddr()); 38710736Snilay@cs.wisc.edu } 3886123SN/A assert(!pkt->req->isInstFetch()); 3899134Ssaidi@eecs.umich.edu TRACE_PACKET("Write"); 3909481Snilay@cs.wisc.edu numWrites[pkt->req->masterId()]++; 3912968SN/A bytesWritten[pkt->req->masterId()] += pkt->getSize(); 3926123SN/A } 3933505SN/A } else if (pkt->isInvalidate()) { 3949885Sstever@gmail.com // no need to do anything 3959988Snilay@cs.wisc.edu } else { 3968721SN/A panic("unimplemented"); 3973493SN/A } 3989481Snilay@cs.wisc.edu 3993505SN/A if (pkt->needsResponse()) { 4003505SN/A pkt->makeResponse(); 4013934SN/A } 4023934SN/A} 4033934SN/A 4043934SN/Avoid 4053493SN/AAbstractMemory::functionalAccess(PacketPtr pkt) 4063934SN/A{ 4073934SN/A assert(AddrRange(pkt->getAddr(), 4083493SN/A pkt->getAddr() + pkt->getSize() - 1).isSubset(range)); 4093493SN/A 4102968SN/A uint8_t *hostAddr = pmemAddr + pkt->getAddr() - range.start(); 4119988Snilay@cs.wisc.edu 4129988Snilay@cs.wisc.edu if (pkt->isRead()) { 4139885Sstever@gmail.com if (pmemAddr) 4149885Sstever@gmail.com memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize()); 4159988Snilay@cs.wisc.edu TRACE_PACKET("Read"); 4168983Snate@binkert.org pkt->makeResponse(); 4179988Snilay@cs.wisc.edu } else if (pkt->isWrite()) { 4189988Snilay@cs.wisc.edu if (pmemAddr) 4195509SN/A memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize()); 4202968SN/A TRACE_PACKET("Write"); 4218983Snate@binkert.org pkt->makeResponse(); 4222968SN/A } else if (pkt->isPrint()) { 4232968SN/A Packet::PrintReqState *prs = 4242968SN/A dynamic_cast<Packet::PrintReqState*>(pkt->senderState); 4252968SN/A assert(prs); 4262968SN/A // Need to call printLabels() explicitly since we're not going 4279988Snilay@cs.wisc.edu // through printObj(). 4282968SN/A prs->printLabels(); 4292968SN/A // Right now we just print the single byte at the specified address. 4302968SN/A ccprintf(prs->os, "%s%#x\n", prs->curPrefix(), *hostAddr); 4312968SN/A } else { 4329988Snilay@cs.wisc.edu panic("AbstractMemory: unimplemented functional command %s", 43311268Satgutier@umich.edu pkt->cmdString()); 4342968SN/A } 4352968SN/A} 4365509SN/A