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