abstract_mem.cc revision 9405
1955SN/A/* 2955SN/A * Copyright (c) 2010-2012 ARM Limited 312230Sgiacomo.travaglini@arm.com * All rights reserved 49812Sandreas.hansson@arm.com * 59812Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 69812Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 79812Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 89812Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 99812Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 109812Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 119812Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 129812Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 139812Sandreas.hansson@arm.com * 149812Sandreas.hansson@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 157816Ssteve.reinhardt@amd.com * All rights reserved. 165871Snate@binkert.org * 171762SN/A * Redistribution and use in source and binary forms, with or without 18955SN/A * modification, are permitted provided that the following conditions are 19955SN/A * met: redistributions of source code must retain the above copyright 20955SN/A * notice, this list of conditions and the following disclaimer; 21955SN/A * redistributions in binary form must reproduce the above copyright 22955SN/A * notice, this list of conditions and the following disclaimer in the 23955SN/A * documentation and/or other materials provided with the distribution; 24955SN/A * neither the name of the copyright holders nor the names of its 25955SN/A * contributors may be used to endorse or promote products derived from 26955SN/A * this software without specific prior written permission. 27955SN/A * 28955SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39955SN/A * 40955SN/A * Authors: Ron Dreslinski 41955SN/A * Ali Saidi 422665Ssaidi@eecs.umich.edu * Andreas Hansson 432665Ssaidi@eecs.umich.edu */ 445863Snate@binkert.org 45955SN/A#include "arch/registers.hh" 46955SN/A#include "config/the_isa.hh" 47955SN/A#include "debug/LLSC.hh" 48955SN/A#include "debug/MemoryAccess.hh" 49955SN/A#include "mem/abstract_mem.hh" 508878Ssteve.reinhardt@amd.com#include "mem/packet_access.hh" 512632Sstever@eecs.umich.edu#include "sim/system.hh" 528878Ssteve.reinhardt@amd.com 532632Sstever@eecs.umich.eduusing namespace std; 54955SN/A 558878Ssteve.reinhardt@amd.comAbstractMemory::AbstractMemory(const Params *p) : 562632Sstever@eecs.umich.edu MemObject(p), range(params()->range), pmemAddr(NULL), 572761Sstever@eecs.umich.edu confTableReported(p->conf_table_reported), inAddrMap(p->in_addr_map), 582632Sstever@eecs.umich.edu _system(NULL) 592632Sstever@eecs.umich.edu{ 602632Sstever@eecs.umich.edu if (size() % TheISA::PageBytes != 0) 612761Sstever@eecs.umich.edu panic("Memory Size not divisible by page size\n"); 622761Sstever@eecs.umich.edu} 632761Sstever@eecs.umich.edu 648878Ssteve.reinhardt@amd.comvoid 658878Ssteve.reinhardt@amd.comAbstractMemory::setBackingStore(uint8_t* pmem_addr) 662761Sstever@eecs.umich.edu{ 672761Sstever@eecs.umich.edu pmemAddr = pmem_addr; 682761Sstever@eecs.umich.edu} 692761Sstever@eecs.umich.edu 702761Sstever@eecs.umich.eduvoid 718878Ssteve.reinhardt@amd.comAbstractMemory::regStats() 728878Ssteve.reinhardt@amd.com{ 732632Sstever@eecs.umich.edu using namespace Stats; 742632Sstever@eecs.umich.edu 758878Ssteve.reinhardt@amd.com assert(system()); 768878Ssteve.reinhardt@amd.com 772632Sstever@eecs.umich.edu bytesRead 78955SN/A .init(system()->maxMasters()) 79955SN/A .name(name() + ".bytes_read") 80955SN/A .desc("Number of bytes read from this memory") 816654Snate@binkert.org .flags(total | nozero | nonan) 8210196SCurtis.Dunham@arm.com ; 83955SN/A for (int i = 0; i < system()->maxMasters(); i++) { 845396Ssaidi@eecs.umich.edu bytesRead.subname(i, system()->getMasterName(i)); 8511401Sandreas.sandberg@arm.com } 865863Snate@binkert.org bytesInstRead 875863Snate@binkert.org .init(system()->maxMasters()) 884202Sbinkertn@umich.edu .name(name() + ".bytes_inst_read") 895863Snate@binkert.org .desc("Number of instructions bytes read from this memory") 905863Snate@binkert.org .flags(total | nozero | nonan) 915863Snate@binkert.org ; 925863Snate@binkert.org for (int i = 0; i < system()->maxMasters(); i++) { 93955SN/A bytesInstRead.subname(i, system()->getMasterName(i)); 946654Snate@binkert.org } 955273Sstever@gmail.com bytesWritten 965871Snate@binkert.org .init(system()->maxMasters()) 975273Sstever@gmail.com .name(name() + ".bytes_written") 986654Snate@binkert.org .desc("Number of bytes written to this memory") 995396Ssaidi@eecs.umich.edu .flags(total | nozero | nonan) 1008120Sgblack@eecs.umich.edu ; 1018120Sgblack@eecs.umich.edu for (int i = 0; i < system()->maxMasters(); i++) { 1028120Sgblack@eecs.umich.edu bytesWritten.subname(i, system()->getMasterName(i)); 1038120Sgblack@eecs.umich.edu } 1048120Sgblack@eecs.umich.edu numReads 1058120Sgblack@eecs.umich.edu .init(system()->maxMasters()) 1068120Sgblack@eecs.umich.edu .name(name() + ".num_reads") 1078120Sgblack@eecs.umich.edu .desc("Number of read requests responded to by this memory") 1088879Ssteve.reinhardt@amd.com .flags(total | nozero | nonan) 1098879Ssteve.reinhardt@amd.com ; 1108879Ssteve.reinhardt@amd.com for (int i = 0; i < system()->maxMasters(); i++) { 1118879Ssteve.reinhardt@amd.com numReads.subname(i, system()->getMasterName(i)); 1128879Ssteve.reinhardt@amd.com } 1138879Ssteve.reinhardt@amd.com numWrites 1148879Ssteve.reinhardt@amd.com .init(system()->maxMasters()) 1158879Ssteve.reinhardt@amd.com .name(name() + ".num_writes") 1168879Ssteve.reinhardt@amd.com .desc("Number of write requests responded to by this memory") 1178879Ssteve.reinhardt@amd.com .flags(total | nozero | nonan) 1188879Ssteve.reinhardt@amd.com ; 1198879Ssteve.reinhardt@amd.com for (int i = 0; i < system()->maxMasters(); i++) { 1208879Ssteve.reinhardt@amd.com numWrites.subname(i, system()->getMasterName(i)); 1218120Sgblack@eecs.umich.edu } 1228120Sgblack@eecs.umich.edu numOther 1238120Sgblack@eecs.umich.edu .init(system()->maxMasters()) 1248120Sgblack@eecs.umich.edu .name(name() + ".num_other") 1258120Sgblack@eecs.umich.edu .desc("Number of other requests responded to by this memory") 1268120Sgblack@eecs.umich.edu .flags(total | nozero | nonan) 1278120Sgblack@eecs.umich.edu ; 1288120Sgblack@eecs.umich.edu for (int i = 0; i < system()->maxMasters(); i++) { 1298120Sgblack@eecs.umich.edu numOther.subname(i, system()->getMasterName(i)); 1308120Sgblack@eecs.umich.edu } 1318120Sgblack@eecs.umich.edu bwRead 1328120Sgblack@eecs.umich.edu .name(name() + ".bw_read") 1338120Sgblack@eecs.umich.edu .desc("Total read bandwidth from this memory (bytes/s)") 1348120Sgblack@eecs.umich.edu .precision(0) 1358879Ssteve.reinhardt@amd.com .prereq(bytesRead) 1368879Ssteve.reinhardt@amd.com .flags(total | nozero | nonan) 1378879Ssteve.reinhardt@amd.com ; 1388879Ssteve.reinhardt@amd.com for (int i = 0; i < system()->maxMasters(); i++) { 13910458Sandreas.hansson@arm.com bwRead.subname(i, system()->getMasterName(i)); 14010458Sandreas.hansson@arm.com } 14110458Sandreas.hansson@arm.com 1428879Ssteve.reinhardt@amd.com bwInstRead 1438879Ssteve.reinhardt@amd.com .name(name() + ".bw_inst_read") 1448879Ssteve.reinhardt@amd.com .desc("Instruction read bandwidth from this memory (bytes/s)") 1458879Ssteve.reinhardt@amd.com .precision(0) 1469227Sandreas.hansson@arm.com .prereq(bytesInstRead) 1479227Sandreas.hansson@arm.com .flags(total | nozero | nonan) 14812063Sgabeblack@google.com ; 14912063Sgabeblack@google.com for (int i = 0; i < system()->maxMasters(); i++) { 15012063Sgabeblack@google.com bwInstRead.subname(i, system()->getMasterName(i)); 1518879Ssteve.reinhardt@amd.com } 1528879Ssteve.reinhardt@amd.com bwWrite 1538879Ssteve.reinhardt@amd.com .name(name() + ".bw_write") 1548879Ssteve.reinhardt@amd.com .desc("Write bandwidth from this memory (bytes/s)") 15510453SAndrew.Bardsley@arm.com .precision(0) 15610453SAndrew.Bardsley@arm.com .prereq(bytesWritten) 15710453SAndrew.Bardsley@arm.com .flags(total | nozero | nonan) 15810456SCurtis.Dunham@arm.com ; 15910456SCurtis.Dunham@arm.com for (int i = 0; i < system()->maxMasters(); i++) { 16010456SCurtis.Dunham@arm.com bwWrite.subname(i, system()->getMasterName(i)); 16110457Sandreas.hansson@arm.com } 16210457Sandreas.hansson@arm.com bwTotal 16311342Sandreas.hansson@arm.com .name(name() + ".bw_total") 16411342Sandreas.hansson@arm.com .desc("Total bandwidth to/from this memory (bytes/s)") 1658120Sgblack@eecs.umich.edu .precision(0) 16612063Sgabeblack@google.com .prereq(bwTotal) 16712063Sgabeblack@google.com .flags(total | nozero | nonan) 16812063Sgabeblack@google.com ; 16912063Sgabeblack@google.com for (int i = 0; i < system()->maxMasters(); i++) { 1705871Snate@binkert.org bwTotal.subname(i, system()->getMasterName(i)); 1715871Snate@binkert.org } 1726121Snate@binkert.org bwRead = bytesRead / simSeconds; 1735871Snate@binkert.org bwInstRead = bytesInstRead / simSeconds; 1745871Snate@binkert.org bwWrite = bytesWritten / simSeconds; 1759926Sstan.czerniawski@arm.com bwTotal = (bytesRead + bytesWritten) / simSeconds; 17612243Sgabeblack@google.com} 1771533SN/A 17812246Sgabeblack@google.comAddrRange 17912246Sgabeblack@google.comAbstractMemory::getAddrRange() const 18012246Sgabeblack@google.com{ 18112246Sgabeblack@google.com return range; 1829239Sandreas.hansson@arm.com} 1839239Sandreas.hansson@arm.com 1849239Sandreas.hansson@arm.com// Add load-locked to tracking list. Should only be called if the 1859239Sandreas.hansson@arm.com// operation is a load and the LLSC flag is set. 1869239Sandreas.hansson@arm.comvoid 1879239Sandreas.hansson@arm.comAbstractMemory::trackLoadLocked(PacketPtr pkt) 1889239Sandreas.hansson@arm.com{ 189955SN/A Request *req = pkt->req; 190955SN/A Addr paddr = LockedAddr::mask(req->getPaddr()); 1912632Sstever@eecs.umich.edu 1922632Sstever@eecs.umich.edu // first we check if we already have a locked addr for this 193955SN/A // xc. Since each xc only gets one, we just update the 194955SN/A // existing record with the new address. 195955SN/A list<LockedAddr>::iterator i; 196955SN/A 1978878Ssteve.reinhardt@amd.com for (i = lockedAddrList.begin(); i != lockedAddrList.end(); ++i) { 198955SN/A if (i->matchesContext(req)) { 1992632Sstever@eecs.umich.edu DPRINTF(LLSC, "Modifying lock record: context %d addr %#x\n", 2002632Sstever@eecs.umich.edu req->contextId(), paddr); 2012632Sstever@eecs.umich.edu i->addr = paddr; 2022632Sstever@eecs.umich.edu return; 2032632Sstever@eecs.umich.edu } 2042632Sstever@eecs.umich.edu } 2052632Sstever@eecs.umich.edu 2068268Ssteve.reinhardt@amd.com // no record for this xc: need to allocate a new one 2078268Ssteve.reinhardt@amd.com DPRINTF(LLSC, "Adding lock record: context %d addr %#x\n", 2088268Ssteve.reinhardt@amd.com req->contextId(), paddr); 2098268Ssteve.reinhardt@amd.com lockedAddrList.push_front(LockedAddr(req)); 2108268Ssteve.reinhardt@amd.com} 2118268Ssteve.reinhardt@amd.com 2128268Ssteve.reinhardt@amd.com 2132632Sstever@eecs.umich.edu// Called on *writes* only... both regular stores and 2142632Sstever@eecs.umich.edu// store-conditional operations. Check for conventional stores which 2152632Sstever@eecs.umich.edu// conflict with locked addresses, and for success/failure of store 2162632Sstever@eecs.umich.edu// conditionals. 2178268Ssteve.reinhardt@amd.combool 2182632Sstever@eecs.umich.eduAbstractMemory::checkLockedAddrList(PacketPtr pkt) 2198268Ssteve.reinhardt@amd.com{ 2208268Ssteve.reinhardt@amd.com Request *req = pkt->req; 2218268Ssteve.reinhardt@amd.com Addr paddr = LockedAddr::mask(req->getPaddr()); 2228268Ssteve.reinhardt@amd.com bool isLLSC = pkt->isLLSC(); 2233718Sstever@eecs.umich.edu 2242634Sstever@eecs.umich.edu // Initialize return value. Non-conditional stores always 2252634Sstever@eecs.umich.edu // succeed. Assume conditional stores will fail until proven 2265863Snate@binkert.org // otherwise. 2272638Sstever@eecs.umich.edu bool allowStore = !isLLSC; 2288268Ssteve.reinhardt@amd.com 2292632Sstever@eecs.umich.edu // Iterate over list. Note that there could be multiple matching records, 2302632Sstever@eecs.umich.edu // as more than one context could have done a load locked to this location. 2312632Sstever@eecs.umich.edu // Only remove records when we succeed in finding a record for (xc, addr); 2322632Sstever@eecs.umich.edu // then, remove all records with this address. Failed store-conditionals do 2332632Sstever@eecs.umich.edu // not blow unrelated reservations. 2341858SN/A list<LockedAddr>::iterator i = lockedAddrList.begin(); 2353716Sstever@eecs.umich.edu 2362638Sstever@eecs.umich.edu if (isLLSC) { 2372638Sstever@eecs.umich.edu while (i != lockedAddrList.end()) { 2382638Sstever@eecs.umich.edu if (i->addr == paddr && i->matchesContext(req)) { 2392638Sstever@eecs.umich.edu // it's a store conditional, and as far as the memory system can 2402638Sstever@eecs.umich.edu // tell, the requesting context's lock is still valid. 2412638Sstever@eecs.umich.edu DPRINTF(LLSC, "StCond success: context %d addr %#x\n", 2422638Sstever@eecs.umich.edu req->contextId(), paddr); 2435863Snate@binkert.org allowStore = true; 2445863Snate@binkert.org break; 2455863Snate@binkert.org } 246955SN/A // If we didn't find a match, keep searching! Someone else may well 2475341Sstever@gmail.com // have a reservation on this line here but we may find ours in just 2485341Sstever@gmail.com // a little while. 2495863Snate@binkert.org i++; 2507756SAli.Saidi@ARM.com } 2515341Sstever@gmail.com req->setExtraData(allowStore ? 1 : 0); 2526121Snate@binkert.org } 2534494Ssaidi@eecs.umich.edu // LLSCs that succeeded AND non-LLSC stores both fall into here: 2546121Snate@binkert.org if (allowStore) { 2551105SN/A // We write address paddr. However, there may be several entries with a 2562667Sstever@eecs.umich.edu // reservation on this address (for other contextIds) and they must all 2572667Sstever@eecs.umich.edu // be removed. 2582667Sstever@eecs.umich.edu i = lockedAddrList.begin(); 2592667Sstever@eecs.umich.edu while (i != lockedAddrList.end()) { 2606121Snate@binkert.org if (i->addr == paddr) { 2612667Sstever@eecs.umich.edu DPRINTF(LLSC, "Erasing lock record: context %d addr %#x\n", 2625341Sstever@gmail.com i->contextId, paddr); 2635863Snate@binkert.org i = lockedAddrList.erase(i); 2645341Sstever@gmail.com } else { 2655341Sstever@gmail.com i++; 2665341Sstever@gmail.com } 2678120Sgblack@eecs.umich.edu } 2685341Sstever@gmail.com } 2698120Sgblack@eecs.umich.edu 2705341Sstever@gmail.com return allowStore; 2718120Sgblack@eecs.umich.edu} 2726121Snate@binkert.org 2736121Snate@binkert.org 2749396Sandreas.hansson@arm.com#if TRACING_ON 2755397Ssaidi@eecs.umich.edu 2765397Ssaidi@eecs.umich.edu#define CASE(A, T) \ 2777727SAli.Saidi@ARM.com case sizeof(T): \ 2788268Ssteve.reinhardt@amd.com DPRINTF(MemoryAccess,"%s of size %i on address 0x%x data 0x%x\n", \ 2796168Snate@binkert.org A, pkt->getSize(), pkt->getAddr(), pkt->get<T>()); \ 2805341Sstever@gmail.com break 2818120Sgblack@eecs.umich.edu 2828120Sgblack@eecs.umich.edu 2838120Sgblack@eecs.umich.edu#define TRACE_PACKET(A) \ 2846814Sgblack@eecs.umich.edu do { \ 2855863Snate@binkert.org switch (pkt->getSize()) { \ 2868120Sgblack@eecs.umich.edu CASE(A, uint64_t); \ 2875341Sstever@gmail.com CASE(A, uint32_t); \ 2885863Snate@binkert.org CASE(A, uint16_t); \ 2898268Ssteve.reinhardt@amd.com CASE(A, uint8_t); \ 2906121Snate@binkert.org default: \ 2916121Snate@binkert.org DPRINTF(MemoryAccess, "%s of size %i on address 0x%x\n", \ 2928268Ssteve.reinhardt@amd.com A, pkt->getSize(), pkt->getAddr()); \ 2935742Snate@binkert.org DDUMP(MemoryAccess, pkt->getPtr<uint8_t>(), pkt->getSize());\ 2945742Snate@binkert.org } \ 2955341Sstever@gmail.com } while (0) 2965742Snate@binkert.org 2975742Snate@binkert.org#else 2985341Sstever@gmail.com 2996017Snate@binkert.org#define TRACE_PACKET(A) 3006121Snate@binkert.org 3016017Snate@binkert.org#endif 30212158Sandreas.sandberg@arm.com 30312158Sandreas.sandberg@arm.comvoid 30412158Sandreas.sandberg@arm.comAbstractMemory::access(PacketPtr pkt) 3058120Sgblack@eecs.umich.edu{ 3067756SAli.Saidi@ARM.com assert(AddrRange(pkt->getAddr(), 3077756SAli.Saidi@ARM.com pkt->getAddr() + pkt->getSize() - 1).isSubset(range)); 3087756SAli.Saidi@ARM.com 3097756SAli.Saidi@ARM.com if (pkt->memInhibitAsserted()) { 3107816Ssteve.reinhardt@amd.com DPRINTF(MemoryAccess, "mem inhibited on 0x%x: not responding\n", 3117816Ssteve.reinhardt@amd.com pkt->getAddr()); 3127816Ssteve.reinhardt@amd.com return; 3137816Ssteve.reinhardt@amd.com } 3147816Ssteve.reinhardt@amd.com 31511979Sgabeblack@google.com uint8_t *hostAddr = pmemAddr + pkt->getAddr() - range.start(); 3167816Ssteve.reinhardt@amd.com 3177816Ssteve.reinhardt@amd.com if (pkt->cmd == MemCmd::SwapReq) { 3187816Ssteve.reinhardt@amd.com TheISA::IntReg overwrite_val; 3197816Ssteve.reinhardt@amd.com bool overwrite_mem; 3207756SAli.Saidi@ARM.com uint64_t condition_val64; 3217756SAli.Saidi@ARM.com uint32_t condition_val32; 3229227Sandreas.hansson@arm.com 3239227Sandreas.hansson@arm.com if (!pmemAddr) 3249227Sandreas.hansson@arm.com panic("Swap only works if there is real memory (i.e. null=False)"); 3259227Sandreas.hansson@arm.com assert(sizeof(TheISA::IntReg) >= pkt->getSize()); 3269590Sandreas@sandberg.pp.se 3279590Sandreas@sandberg.pp.se overwrite_mem = true; 3289590Sandreas@sandberg.pp.se // keep a copy of our possible write value, and copy what is at the 3299590Sandreas@sandberg.pp.se // memory address into the packet 3309590Sandreas@sandberg.pp.se std::memcpy(&overwrite_val, pkt->getPtr<uint8_t>(), pkt->getSize()); 3319590Sandreas@sandberg.pp.se std::memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize()); 3326654Snate@binkert.org 3336654Snate@binkert.org if (pkt->req->isCondSwap()) { 3345871Snate@binkert.org if (pkt->getSize() == sizeof(uint64_t)) { 3356121Snate@binkert.org condition_val64 = pkt->req->getExtraData(); 3368946Sandreas.hansson@arm.com overwrite_mem = !std::memcmp(&condition_val64, hostAddr, 3379419Sandreas.hansson@arm.com sizeof(uint64_t)); 3383940Ssaidi@eecs.umich.edu } else if (pkt->getSize() == sizeof(uint32_t)) { 3393918Ssaidi@eecs.umich.edu condition_val32 = (uint32_t)pkt->req->getExtraData(); 3403918Ssaidi@eecs.umich.edu overwrite_mem = !std::memcmp(&condition_val32, hostAddr, 3411858SN/A sizeof(uint32_t)); 3429556Sandreas.hansson@arm.com } else 3439556Sandreas.hansson@arm.com panic("Invalid size for conditional read/write\n"); 3449556Sandreas.hansson@arm.com } 3459556Sandreas.hansson@arm.com 34611294Sandreas.hansson@arm.com if (overwrite_mem) 34711294Sandreas.hansson@arm.com std::memcpy(hostAddr, &overwrite_val, pkt->getSize()); 34811294Sandreas.hansson@arm.com 34911294Sandreas.hansson@arm.com assert(!pkt->req->isInstFetch()); 35010878Sandreas.hansson@arm.com TRACE_PACKET("Read/Write"); 35110878Sandreas.hansson@arm.com numOther[pkt->req->masterId()]++; 35211811Sbaz21@cam.ac.uk } else if (pkt->isRead()) { 35311811Sbaz21@cam.ac.uk assert(!pkt->isWrite()); 35411811Sbaz21@cam.ac.uk if (pkt->isLLSC()) { 35511982Sgabeblack@google.com trackLoadLocked(pkt); 35611982Sgabeblack@google.com } 35711982Sgabeblack@google.com if (pmemAddr) 35811982Sgabeblack@google.com memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize()); 35911992Sgabeblack@google.com TRACE_PACKET(pkt->req->isInstFetch() ? "IFetch" : "Read"); 36011982Sgabeblack@google.com numReads[pkt->req->masterId()]++; 36111982Sgabeblack@google.com bytesRead[pkt->req->masterId()] += pkt->getSize(); 3629556Sandreas.hansson@arm.com if (pkt->req->isInstFetch()) 3639556Sandreas.hansson@arm.com bytesInstRead[pkt->req->masterId()] += pkt->getSize(); 3649556Sandreas.hansson@arm.com } else if (pkt->isWrite()) { 3659556Sandreas.hansson@arm.com if (writeOK(pkt)) { 3669556Sandreas.hansson@arm.com if (pmemAddr) 3679556Sandreas.hansson@arm.com memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize()); 3689556Sandreas.hansson@arm.com assert(!pkt->req->isInstFetch()); 3699556Sandreas.hansson@arm.com TRACE_PACKET("Write"); 3709556Sandreas.hansson@arm.com numWrites[pkt->req->masterId()]++; 3719556Sandreas.hansson@arm.com bytesWritten[pkt->req->masterId()] += pkt->getSize(); 3729556Sandreas.hansson@arm.com } 3739556Sandreas.hansson@arm.com } else if (pkt->isInvalidate()) { 3749556Sandreas.hansson@arm.com // no need to do anything 3759556Sandreas.hansson@arm.com } else { 3769556Sandreas.hansson@arm.com panic("unimplemented"); 3779556Sandreas.hansson@arm.com } 3789556Sandreas.hansson@arm.com 3799556Sandreas.hansson@arm.com if (pkt->needsResponse()) { 3809556Sandreas.hansson@arm.com pkt->makeResponse(); 3816121Snate@binkert.org } 38211500Sandreas.hansson@arm.com} 38310238Sandreas.hansson@arm.com 38410878Sandreas.hansson@arm.comvoid 3859420Sandreas.hansson@arm.comAbstractMemory::functionalAccess(PacketPtr pkt) 38611500Sandreas.hansson@arm.com{ 38711500Sandreas.hansson@arm.com assert(AddrRange(pkt->getAddr(), 3889420Sandreas.hansson@arm.com pkt->getAddr() + pkt->getSize() - 1).isSubset(range)); 3899420Sandreas.hansson@arm.com 3909420Sandreas.hansson@arm.com uint8_t *hostAddr = pmemAddr + pkt->getAddr() - range.start(); 3919420Sandreas.hansson@arm.com 3929420Sandreas.hansson@arm.com if (pkt->isRead()) { 39312063Sgabeblack@google.com if (pmemAddr) 39412063Sgabeblack@google.com memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize()); 39512063Sgabeblack@google.com TRACE_PACKET("Read"); 39612063Sgabeblack@google.com pkt->makeResponse(); 39712063Sgabeblack@google.com } else if (pkt->isWrite()) { 39812063Sgabeblack@google.com if (pmemAddr) 39912063Sgabeblack@google.com memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize()); 40012063Sgabeblack@google.com TRACE_PACKET("Write"); 40112063Sgabeblack@google.com pkt->makeResponse(); 40212063Sgabeblack@google.com } else if (pkt->isPrint()) { 40312063Sgabeblack@google.com Packet::PrintReqState *prs = 40412063Sgabeblack@google.com dynamic_cast<Packet::PrintReqState*>(pkt->senderState); 40512063Sgabeblack@google.com assert(prs); 40612063Sgabeblack@google.com // Need to call printLabels() explicitly since we're not going 40712063Sgabeblack@google.com // through printObj(). 40812063Sgabeblack@google.com prs->printLabels(); 40912063Sgabeblack@google.com // Right now we just print the single byte at the specified address. 41012063Sgabeblack@google.com ccprintf(prs->os, "%s%#x\n", prs->curPrefix(), *hostAddr); 41112063Sgabeblack@google.com } else { 41212063Sgabeblack@google.com panic("AbstractMemory: unimplemented functional command %s", 41312063Sgabeblack@google.com pkt->cmdString()); 41412063Sgabeblack@google.com } 41510264Sandreas.hansson@arm.com} 41610264Sandreas.hansson@arm.com