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