abstract_mem.cc revision 9405
12391SN/A/*
28931Sandreas.hansson@arm.com * Copyright (c) 2010-2012 ARM Limited
37733SN/A * All rights reserved
47733SN/A *
57733SN/A * The license below extends only to copyright in the software and shall
67733SN/A * not be construed as granting a license to any other intellectual
77733SN/A * property including but not limited to intellectual property relating
87733SN/A * to a hardware implementation of the functionality of the software
97733SN/A * licensed hereunder.  You may use the software subject to the license
107733SN/A * terms below provided that you ensure that this notice is replicated
117733SN/A * unmodified and in its entirety in all distributions of the software,
127733SN/A * modified or unmodified, in source code or in binary form.
137733SN/A *
142391SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan
152391SN/A * All rights reserved.
162391SN/A *
172391SN/A * Redistribution and use in source and binary forms, with or without
182391SN/A * modification, are permitted provided that the following conditions are
192391SN/A * met: redistributions of source code must retain the above copyright
202391SN/A * notice, this list of conditions and the following disclaimer;
212391SN/A * redistributions in binary form must reproduce the above copyright
222391SN/A * notice, this list of conditions and the following disclaimer in the
232391SN/A * documentation and/or other materials provided with the distribution;
242391SN/A * neither the name of the copyright holders nor the names of its
252391SN/A * contributors may be used to endorse or promote products derived from
262391SN/A * this software without specific prior written permission.
272391SN/A *
282391SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292391SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302391SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312391SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322391SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332391SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342391SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352391SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362391SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372391SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382391SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392665SN/A *
402665SN/A * Authors: Ron Dreslinski
412914SN/A *          Ali Saidi
428931Sandreas.hansson@arm.com *          Andreas Hansson
432391SN/A */
442391SN/A
456329SN/A#include "arch/registers.hh"
466658SN/A#include "config/the_isa.hh"
478232SN/A#include "debug/LLSC.hh"
488232SN/A#include "debug/MemoryAccess.hh"
498931Sandreas.hansson@arm.com#include "mem/abstract_mem.hh"
503879SN/A#include "mem/packet_access.hh"
519053Sdam.sunwoo@arm.com#include "sim/system.hh"
522394SN/A
532391SN/Ausing namespace std;
542391SN/A
558931Sandreas.hansson@arm.comAbstractMemory::AbstractMemory(const Params *p) :
568931Sandreas.hansson@arm.com    MemObject(p), range(params()->range), pmemAddr(NULL),
579053Sdam.sunwoo@arm.com    confTableReported(p->conf_table_reported), inAddrMap(p->in_addr_map),
589053Sdam.sunwoo@arm.com    _system(NULL)
592391SN/A{
607730SN/A    if (size() % TheISA::PageBytes != 0)
612391SN/A        panic("Memory Size not divisible by page size\n");
622391SN/A}
632391SN/A
649293Sandreas.hansson@arm.comvoid
659293Sandreas.hansson@arm.comAbstractMemory::setBackingStore(uint8_t* pmem_addr)
662391SN/A{
679293Sandreas.hansson@arm.com    pmemAddr = pmem_addr;
682391SN/A}
692391SN/A
708719SN/Avoid
718931Sandreas.hansson@arm.comAbstractMemory::regStats()
728719SN/A{
738719SN/A    using namespace Stats;
748719SN/A
759053Sdam.sunwoo@arm.com    assert(system());
769053Sdam.sunwoo@arm.com
778719SN/A    bytesRead
789053Sdam.sunwoo@arm.com        .init(system()->maxMasters())
798719SN/A        .name(name() + ".bytes_read")
808719SN/A        .desc("Number of bytes read from this memory")
819053Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
828719SN/A        ;
839053Sdam.sunwoo@arm.com    for (int i = 0; i < system()->maxMasters(); i++) {
849053Sdam.sunwoo@arm.com        bytesRead.subname(i, system()->getMasterName(i));
859053Sdam.sunwoo@arm.com    }
868719SN/A    bytesInstRead
879053Sdam.sunwoo@arm.com        .init(system()->maxMasters())
888719SN/A        .name(name() + ".bytes_inst_read")
898719SN/A        .desc("Number of instructions bytes read from this memory")
909053Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
918719SN/A        ;
929053Sdam.sunwoo@arm.com    for (int i = 0; i < system()->maxMasters(); i++) {
939053Sdam.sunwoo@arm.com        bytesInstRead.subname(i, system()->getMasterName(i));
949053Sdam.sunwoo@arm.com    }
958719SN/A    bytesWritten
969053Sdam.sunwoo@arm.com        .init(system()->maxMasters())
978719SN/A        .name(name() + ".bytes_written")
988719SN/A        .desc("Number of bytes written to this memory")
999053Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
1008719SN/A        ;
1019053Sdam.sunwoo@arm.com    for (int i = 0; i < system()->maxMasters(); i++) {
1029053Sdam.sunwoo@arm.com        bytesWritten.subname(i, system()->getMasterName(i));
1039053Sdam.sunwoo@arm.com    }
1048719SN/A    numReads
1059053Sdam.sunwoo@arm.com        .init(system()->maxMasters())
1068719SN/A        .name(name() + ".num_reads")
1078719SN/A        .desc("Number of read requests responded to by this memory")
1089053Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
1098719SN/A        ;
1109053Sdam.sunwoo@arm.com    for (int i = 0; i < system()->maxMasters(); i++) {
1119053Sdam.sunwoo@arm.com        numReads.subname(i, system()->getMasterName(i));
1129053Sdam.sunwoo@arm.com    }
1138719SN/A    numWrites
1149053Sdam.sunwoo@arm.com        .init(system()->maxMasters())
1158719SN/A        .name(name() + ".num_writes")
1168719SN/A        .desc("Number of write requests responded to by this memory")
1179053Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
1188719SN/A        ;
1199053Sdam.sunwoo@arm.com    for (int i = 0; i < system()->maxMasters(); i++) {
1209053Sdam.sunwoo@arm.com        numWrites.subname(i, system()->getMasterName(i));
1219053Sdam.sunwoo@arm.com    }
1228719SN/A    numOther
1239053Sdam.sunwoo@arm.com        .init(system()->maxMasters())
1248719SN/A        .name(name() + ".num_other")
1258719SN/A        .desc("Number of other requests responded to by this memory")
1269053Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
1278719SN/A        ;
1289053Sdam.sunwoo@arm.com    for (int i = 0; i < system()->maxMasters(); i++) {
1299053Sdam.sunwoo@arm.com        numOther.subname(i, system()->getMasterName(i));
1309053Sdam.sunwoo@arm.com    }
1318719SN/A    bwRead
1328719SN/A        .name(name() + ".bw_read")
1338719SN/A        .desc("Total read bandwidth from this memory (bytes/s)")
1348719SN/A        .precision(0)
1358719SN/A        .prereq(bytesRead)
1369053Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
1378719SN/A        ;
1389053Sdam.sunwoo@arm.com    for (int i = 0; i < system()->maxMasters(); i++) {
1399053Sdam.sunwoo@arm.com        bwRead.subname(i, system()->getMasterName(i));
1409053Sdam.sunwoo@arm.com    }
1419053Sdam.sunwoo@arm.com
1428719SN/A    bwInstRead
1438719SN/A        .name(name() + ".bw_inst_read")
1448719SN/A        .desc("Instruction read bandwidth from this memory (bytes/s)")
1458719SN/A        .precision(0)
1468719SN/A        .prereq(bytesInstRead)
1479053Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
1488719SN/A        ;
1499053Sdam.sunwoo@arm.com    for (int i = 0; i < system()->maxMasters(); i++) {
1509053Sdam.sunwoo@arm.com        bwInstRead.subname(i, system()->getMasterName(i));
1519053Sdam.sunwoo@arm.com    }
1528719SN/A    bwWrite
1538719SN/A        .name(name() + ".bw_write")
1548719SN/A        .desc("Write bandwidth from this memory (bytes/s)")
1558719SN/A        .precision(0)
1568719SN/A        .prereq(bytesWritten)
1579053Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
1588719SN/A        ;
1599053Sdam.sunwoo@arm.com    for (int i = 0; i < system()->maxMasters(); i++) {
1609053Sdam.sunwoo@arm.com        bwWrite.subname(i, system()->getMasterName(i));
1619053Sdam.sunwoo@arm.com    }
1628719SN/A    bwTotal
1638719SN/A        .name(name() + ".bw_total")
1648719SN/A        .desc("Total bandwidth to/from this memory (bytes/s)")
1658719SN/A        .precision(0)
1668719SN/A        .prereq(bwTotal)
1679053Sdam.sunwoo@arm.com        .flags(total | nozero | nonan)
1688719SN/A        ;
1699053Sdam.sunwoo@arm.com    for (int i = 0; i < system()->maxMasters(); i++) {
1709053Sdam.sunwoo@arm.com        bwTotal.subname(i, system()->getMasterName(i));
1719053Sdam.sunwoo@arm.com    }
1728719SN/A    bwRead = bytesRead / simSeconds;
1738719SN/A    bwInstRead = bytesInstRead / simSeconds;
1748719SN/A    bwWrite = bytesWritten / simSeconds;
1758719SN/A    bwTotal = (bytesRead + bytesWritten) / simSeconds;
1768719SN/A}
1778719SN/A
1789235Sandreas.hansson@arm.comAddrRange
1799098Sandreas.hansson@arm.comAbstractMemory::getAddrRange() const
1802408SN/A{
1818931Sandreas.hansson@arm.com    return range;
1822408SN/A}
1832408SN/A
1843170SN/A// Add load-locked to tracking list.  Should only be called if the
1856076SN/A// operation is a load and the LLSC flag is set.
1863170SN/Avoid
1878931Sandreas.hansson@arm.comAbstractMemory::trackLoadLocked(PacketPtr pkt)
1883170SN/A{
1894626SN/A    Request *req = pkt->req;
1903170SN/A    Addr paddr = LockedAddr::mask(req->getPaddr());
1913170SN/A
1923170SN/A    // first we check if we already have a locked addr for this
1933170SN/A    // xc.  Since each xc only gets one, we just update the
1943170SN/A    // existing record with the new address.
1953170SN/A    list<LockedAddr>::iterator i;
1963170SN/A
1973170SN/A    for (i = lockedAddrList.begin(); i != lockedAddrList.end(); ++i) {
1983170SN/A        if (i->matchesContext(req)) {
1995714SN/A            DPRINTF(LLSC, "Modifying lock record: context %d addr %#x\n",
2005714SN/A                    req->contextId(), paddr);
2013170SN/A            i->addr = paddr;
2023170SN/A            return;
2033170SN/A        }
2043170SN/A    }
2053170SN/A
2063170SN/A    // no record for this xc: need to allocate a new one
2075714SN/A    DPRINTF(LLSC, "Adding lock record: context %d addr %#x\n",
2085714SN/A            req->contextId(), paddr);
2093170SN/A    lockedAddrList.push_front(LockedAddr(req));
2103170SN/A}
2113170SN/A
2123170SN/A
2133170SN/A// Called on *writes* only... both regular stores and
2143170SN/A// store-conditional operations.  Check for conventional stores which
2153170SN/A// conflict with locked addresses, and for success/failure of store
2163170SN/A// conditionals.
2173170SN/Abool
2188931Sandreas.hansson@arm.comAbstractMemory::checkLockedAddrList(PacketPtr pkt)
2193170SN/A{
2204626SN/A    Request *req = pkt->req;
2213170SN/A    Addr paddr = LockedAddr::mask(req->getPaddr());
2226102SN/A    bool isLLSC = pkt->isLLSC();
2233170SN/A
2243170SN/A    // Initialize return value.  Non-conditional stores always
2253170SN/A    // succeed.  Assume conditional stores will fail until proven
2263170SN/A    // otherwise.
2279080Smatt.evans@arm.com    bool allowStore = !isLLSC;
2283170SN/A
2299080Smatt.evans@arm.com    // Iterate over list.  Note that there could be multiple matching records,
2309080Smatt.evans@arm.com    // as more than one context could have done a load locked to this location.
2319080Smatt.evans@arm.com    // Only remove records when we succeed in finding a record for (xc, addr);
2329080Smatt.evans@arm.com    // then, remove all records with this address.  Failed store-conditionals do
2339080Smatt.evans@arm.com    // not blow unrelated reservations.
2343170SN/A    list<LockedAddr>::iterator i = lockedAddrList.begin();
2353170SN/A
2369080Smatt.evans@arm.com    if (isLLSC) {
2379080Smatt.evans@arm.com        while (i != lockedAddrList.end()) {
2389080Smatt.evans@arm.com            if (i->addr == paddr && i->matchesContext(req)) {
2399080Smatt.evans@arm.com                // it's a store conditional, and as far as the memory system can
2409080Smatt.evans@arm.com                // tell, the requesting context's lock is still valid.
2415714SN/A                DPRINTF(LLSC, "StCond success: context %d addr %#x\n",
2425714SN/A                        req->contextId(), paddr);
2439080Smatt.evans@arm.com                allowStore = true;
2449080Smatt.evans@arm.com                break;
2453170SN/A            }
2469080Smatt.evans@arm.com            // If we didn't find a match, keep searching!  Someone else may well
2479080Smatt.evans@arm.com            // have a reservation on this line here but we may find ours in just
2489080Smatt.evans@arm.com            // a little while.
2499080Smatt.evans@arm.com            i++;
2503170SN/A        }
2519080Smatt.evans@arm.com        req->setExtraData(allowStore ? 1 : 0);
2529080Smatt.evans@arm.com    }
2539080Smatt.evans@arm.com    // LLSCs that succeeded AND non-LLSC stores both fall into here:
2549080Smatt.evans@arm.com    if (allowStore) {
2559080Smatt.evans@arm.com        // We write address paddr.  However, there may be several entries with a
2569080Smatt.evans@arm.com        // reservation on this address (for other contextIds) and they must all
2579080Smatt.evans@arm.com        // be removed.
2589080Smatt.evans@arm.com        i = lockedAddrList.begin();
2599080Smatt.evans@arm.com        while (i != lockedAddrList.end()) {
2609080Smatt.evans@arm.com            if (i->addr == paddr) {
2619080Smatt.evans@arm.com                DPRINTF(LLSC, "Erasing lock record: context %d addr %#x\n",
2629080Smatt.evans@arm.com                        i->contextId, paddr);
2639080Smatt.evans@arm.com                i = lockedAddrList.erase(i);
2649080Smatt.evans@arm.com            } else {
2659080Smatt.evans@arm.com                i++;
2669080Smatt.evans@arm.com            }
2673170SN/A        }
2683170SN/A    }
2693170SN/A
2709080Smatt.evans@arm.com    return allowStore;
2713170SN/A}
2723170SN/A
2734626SN/A
2744626SN/A#if TRACING_ON
2754626SN/A
2764626SN/A#define CASE(A, T)                                                      \
2774626SN/A  case sizeof(T):                                                       \
2786429SN/A    DPRINTF(MemoryAccess,"%s of size %i on address 0x%x data 0x%x\n",   \
2796429SN/A            A, pkt->getSize(), pkt->getAddr(), pkt->get<T>());          \
2804626SN/A  break
2814626SN/A
2824626SN/A
2834626SN/A#define TRACE_PACKET(A)                                                 \
2844626SN/A    do {                                                                \
2854626SN/A        switch (pkt->getSize()) {                                       \
2864626SN/A          CASE(A, uint64_t);                                            \
2874626SN/A          CASE(A, uint32_t);                                            \
2884626SN/A          CASE(A, uint16_t);                                            \
2894626SN/A          CASE(A, uint8_t);                                             \
2904626SN/A          default:                                                      \
2916429SN/A            DPRINTF(MemoryAccess, "%s of size %i on address 0x%x\n",    \
2926429SN/A                    A, pkt->getSize(), pkt->getAddr());                 \
2938077SN/A            DDUMP(MemoryAccess, pkt->getPtr<uint8_t>(), pkt->getSize());\
2944626SN/A        }                                                               \
2954626SN/A    } while (0)
2964626SN/A
2974626SN/A#else
2984626SN/A
2994626SN/A#define TRACE_PACKET(A)
3004626SN/A
3014626SN/A#endif
3024626SN/A
3038931Sandreas.hansson@arm.comvoid
3048931Sandreas.hansson@arm.comAbstractMemory::access(PacketPtr pkt)
3052413SN/A{
3069405Sandreas.hansson@arm.com    assert(AddrRange(pkt->getAddr(),
3079405Sandreas.hansson@arm.com                     pkt->getAddr() + pkt->getSize() - 1).isSubset(range));
3082414SN/A
3094626SN/A    if (pkt->memInhibitAsserted()) {
3104626SN/A        DPRINTF(MemoryAccess, "mem inhibited on 0x%x: not responding\n",
3114626SN/A                pkt->getAddr());
3128931Sandreas.hansson@arm.com        return;
3133175SN/A    }
3144626SN/A
3159405Sandreas.hansson@arm.com    uint8_t *hostAddr = pmemAddr + pkt->getAddr() - range.start();
3164626SN/A
3174626SN/A    if (pkt->cmd == MemCmd::SwapReq) {
3188931Sandreas.hansson@arm.com        TheISA::IntReg overwrite_val;
3194040SN/A        bool overwrite_mem;
3204040SN/A        uint64_t condition_val64;
3214040SN/A        uint32_t condition_val32;
3224040SN/A
3235477SN/A        if (!pmemAddr)
3245477SN/A            panic("Swap only works if there is real memory (i.e. null=False)");
3258931Sandreas.hansson@arm.com        assert(sizeof(TheISA::IntReg) >= pkt->getSize());
3264040SN/A
3274040SN/A        overwrite_mem = true;
3284040SN/A        // keep a copy of our possible write value, and copy what is at the
3294040SN/A        // memory address into the packet
3304052SN/A        std::memcpy(&overwrite_val, pkt->getPtr<uint8_t>(), pkt->getSize());
3314626SN/A        std::memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize());
3324040SN/A
3334040SN/A        if (pkt->req->isCondSwap()) {
3344040SN/A            if (pkt->getSize() == sizeof(uint64_t)) {
3354052SN/A                condition_val64 = pkt->req->getExtraData();
3364626SN/A                overwrite_mem = !std::memcmp(&condition_val64, hostAddr,
3374626SN/A                                             sizeof(uint64_t));
3384040SN/A            } else if (pkt->getSize() == sizeof(uint32_t)) {
3394052SN/A                condition_val32 = (uint32_t)pkt->req->getExtraData();
3404626SN/A                overwrite_mem = !std::memcmp(&condition_val32, hostAddr,
3414626SN/A                                             sizeof(uint32_t));
3424040SN/A            } else
3434040SN/A                panic("Invalid size for conditional read/write\n");
3444040SN/A        }
3454040SN/A
3464040SN/A        if (overwrite_mem)
3474626SN/A            std::memcpy(hostAddr, &overwrite_val, pkt->getSize());
3484040SN/A
3496429SN/A        assert(!pkt->req->isInstFetch());
3504626SN/A        TRACE_PACKET("Read/Write");
3519053Sdam.sunwoo@arm.com        numOther[pkt->req->masterId()]++;
3524626SN/A    } else if (pkt->isRead()) {
3534626SN/A        assert(!pkt->isWrite());
3546102SN/A        if (pkt->isLLSC()) {
3554626SN/A            trackLoadLocked(pkt);
3564040SN/A        }
3575477SN/A        if (pmemAddr)
3585477SN/A            memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize());
3596429SN/A        TRACE_PACKET(pkt->req->isInstFetch() ? "IFetch" : "Read");
3609053Sdam.sunwoo@arm.com        numReads[pkt->req->masterId()]++;
3619053Sdam.sunwoo@arm.com        bytesRead[pkt->req->masterId()] += pkt->getSize();
3628719SN/A        if (pkt->req->isInstFetch())
3639053Sdam.sunwoo@arm.com            bytesInstRead[pkt->req->masterId()] += pkt->getSize();
3644626SN/A    } else if (pkt->isWrite()) {
3654626SN/A        if (writeOK(pkt)) {
3665477SN/A            if (pmemAddr)
3675477SN/A                memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize());
3686429SN/A            assert(!pkt->req->isInstFetch());
3694626SN/A            TRACE_PACKET("Write");
3709053Sdam.sunwoo@arm.com            numWrites[pkt->req->masterId()]++;
3719053Sdam.sunwoo@arm.com            bytesWritten[pkt->req->masterId()] += pkt->getSize();
3724626SN/A        }
3734626SN/A    } else if (pkt->isInvalidate()) {
3748931Sandreas.hansson@arm.com        // no need to do anything
3754040SN/A    } else {
3762413SN/A        panic("unimplemented");
3772413SN/A    }
3782420SN/A
3794626SN/A    if (pkt->needsResponse()) {
3808931Sandreas.hansson@arm.com        pkt->makeResponse();
3814626SN/A    }
3822413SN/A}
3832413SN/A
3848931Sandreas.hansson@arm.comvoid
3858931Sandreas.hansson@arm.comAbstractMemory::functionalAccess(PacketPtr pkt)
3868931Sandreas.hansson@arm.com{
3879405Sandreas.hansson@arm.com    assert(AddrRange(pkt->getAddr(),
3889405Sandreas.hansson@arm.com                     pkt->getAddr() + pkt->getSize() - 1).isSubset(range));
3894626SN/A
3909405Sandreas.hansson@arm.com    uint8_t *hostAddr = pmemAddr + pkt->getAddr() - range.start();
3914626SN/A
3925314SN/A    if (pkt->isRead()) {
3935477SN/A        if (pmemAddr)
3945477SN/A            memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize());
3954626SN/A        TRACE_PACKET("Read");
3968931Sandreas.hansson@arm.com        pkt->makeResponse();
3975314SN/A    } else if (pkt->isWrite()) {
3985477SN/A        if (pmemAddr)
3995477SN/A            memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize());
4004626SN/A        TRACE_PACKET("Write");
4018931Sandreas.hansson@arm.com        pkt->makeResponse();
4025314SN/A    } else if (pkt->isPrint()) {
4035315SN/A        Packet::PrintReqState *prs =
4045315SN/A            dynamic_cast<Packet::PrintReqState*>(pkt->senderState);
4058992SAli.Saidi@ARM.com        assert(prs);
4065315SN/A        // Need to call printLabels() explicitly since we're not going
4075315SN/A        // through printObj().
4085314SN/A        prs->printLabels();
4095315SN/A        // Right now we just print the single byte at the specified address.
4105314SN/A        ccprintf(prs->os, "%s%#x\n", prs->curPrefix(), *hostAddr);
4114626SN/A    } else {
4128931Sandreas.hansson@arm.com        panic("AbstractMemory: unimplemented functional command %s",
4134626SN/A              pkt->cmdString());
4144626SN/A    }
4154490SN/A}
416