cpu.cc revision 8887:20ea02da9c53
112531Sandreas.sandberg@arm.com/*
212531Sandreas.sandberg@arm.com * Copyright (c) 2011 ARM Limited
312531Sandreas.sandberg@arm.com * All rights reserved
412531Sandreas.sandberg@arm.com *
512531Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
612531Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
712531Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
812531Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
912531Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1012531Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1112531Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1212531Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1312531Sandreas.sandberg@arm.com *
1412531Sandreas.sandberg@arm.com * Copyright (c) 2006 The Regents of The University of Michigan
1512531Sandreas.sandberg@arm.com * All rights reserved.
1612531Sandreas.sandberg@arm.com *
1712531Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
1812531Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
1912531Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
2012531Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
2112531Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
2212531Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
2312531Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
2412531Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
2512531Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
2612531Sandreas.sandberg@arm.com * this software without specific prior written permission.
2712531Sandreas.sandberg@arm.com *
2812531Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2912531Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3012531Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3112531Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3212531Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3312531Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3412531Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3512531Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3612531Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3712531Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3812531Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3912531Sandreas.sandberg@arm.com *
4012531Sandreas.sandberg@arm.com * Authors: Kevin Lim
4112531Sandreas.sandberg@arm.com *          Geoffrey Blake
4212531Sandreas.sandberg@arm.com */
4312531Sandreas.sandberg@arm.com
4412531Sandreas.sandberg@arm.com#include <list>
4512531Sandreas.sandberg@arm.com#include <string>
4612531Sandreas.sandberg@arm.com
4712531Sandreas.sandberg@arm.com#include "arch/kernel_stats.hh"
4812531Sandreas.sandberg@arm.com#include "arch/vtophys.hh"
4912531Sandreas.sandberg@arm.com#include "cpu/checker/cpu.hh"
5012531Sandreas.sandberg@arm.com#include "cpu/base.hh"
5112531Sandreas.sandberg@arm.com#include "cpu/simple_thread.hh"
5212531Sandreas.sandberg@arm.com#include "cpu/static_inst.hh"
5312531Sandreas.sandberg@arm.com#include "cpu/thread_context.hh"
5412531Sandreas.sandberg@arm.com#include "params/CheckerCPU.hh"
5512531Sandreas.sandberg@arm.com#include "sim/full_system.hh"
5612531Sandreas.sandberg@arm.com#include "sim/tlb.hh"
5712531Sandreas.sandberg@arm.com
5812531Sandreas.sandberg@arm.comusing namespace std;
5912531Sandreas.sandberg@arm.comusing namespace TheISA;
6012531Sandreas.sandberg@arm.com
6112531Sandreas.sandberg@arm.comvoid
6212531Sandreas.sandberg@arm.comCheckerCPU::init()
6312531Sandreas.sandberg@arm.com{
6412531Sandreas.sandberg@arm.com    masterId = systemPtr->getMasterId(name());
6512531Sandreas.sandberg@arm.com}
6612531Sandreas.sandberg@arm.com
6712531Sandreas.sandberg@arm.comCheckerCPU::CheckerCPU(Params *p)
6812531Sandreas.sandberg@arm.com    : BaseCPU(p, true), thread(NULL), tc(NULL)
6912531Sandreas.sandberg@arm.com{
7012531Sandreas.sandberg@arm.com    memReq = NULL;
7112531Sandreas.sandberg@arm.com    curStaticInst = NULL;
7212531Sandreas.sandberg@arm.com    curMacroStaticInst = NULL;
7312531Sandreas.sandberg@arm.com
7412531Sandreas.sandberg@arm.com    numInst = 0;
7512531Sandreas.sandberg@arm.com    startNumInst = 0;
7612531Sandreas.sandberg@arm.com    numLoad = 0;
7712531Sandreas.sandberg@arm.com    startNumLoad = 0;
7812531Sandreas.sandberg@arm.com    youngestSN = 0;
7912699Sandreas.sandberg@arm.com
8012531Sandreas.sandberg@arm.com    changedPC = willChangePC = changedNextPC = false;
8112531Sandreas.sandberg@arm.com
8212531Sandreas.sandberg@arm.com    exitOnError = p->exitOnError;
8312531Sandreas.sandberg@arm.com    warnOnlyOnLoadError = p->warnOnlyOnLoadError;
8412531Sandreas.sandberg@arm.com    itb = p->itb;
8512531Sandreas.sandberg@arm.com    dtb = p->dtb;
8612531Sandreas.sandberg@arm.com    systemPtr = NULL;
8712531Sandreas.sandberg@arm.com    workload = p->workload;
8812531Sandreas.sandberg@arm.com    thread = NULL;
8912531Sandreas.sandberg@arm.com
9012531Sandreas.sandberg@arm.com    updateOnError = true;
9112531Sandreas.sandberg@arm.com}
9212531Sandreas.sandberg@arm.com
9312531Sandreas.sandberg@arm.comCheckerCPU::~CheckerCPU()
9412531Sandreas.sandberg@arm.com{
9512531Sandreas.sandberg@arm.com}
9612531Sandreas.sandberg@arm.com
9712531Sandreas.sandberg@arm.comvoid
9812531Sandreas.sandberg@arm.comCheckerCPU::setSystem(System *system)
9912531Sandreas.sandberg@arm.com{
10012531Sandreas.sandberg@arm.com    systemPtr = system;
10112531Sandreas.sandberg@arm.com
10212531Sandreas.sandberg@arm.com    if (FullSystem) {
10312531Sandreas.sandberg@arm.com        thread = new SimpleThread(this, 0, systemPtr, itb, dtb, false);
10412531Sandreas.sandberg@arm.com    } else {
10512531Sandreas.sandberg@arm.com        thread = new SimpleThread(this, 0, systemPtr,
10612531Sandreas.sandberg@arm.com                                  workload.size() ? workload[0] : NULL,
10712531Sandreas.sandberg@arm.com                                  itb, dtb);
10812531Sandreas.sandberg@arm.com    }
10912531Sandreas.sandberg@arm.com
11012531Sandreas.sandberg@arm.com    tc = thread->getTC();
11112531Sandreas.sandberg@arm.com    threadContexts.push_back(tc);
11212531Sandreas.sandberg@arm.com    thread->kernelStats = NULL;
11312531Sandreas.sandberg@arm.com    // Thread should never be null after this
11412531Sandreas.sandberg@arm.com    assert(thread != NULL);
11512531Sandreas.sandberg@arm.com}
11612531Sandreas.sandberg@arm.com
11712531Sandreas.sandberg@arm.comvoid
11812531Sandreas.sandberg@arm.comCheckerCPU::setIcachePort(CpuPort *icache_port)
11912531Sandreas.sandberg@arm.com{
12012531Sandreas.sandberg@arm.com    icachePort = icache_port;
12112531Sandreas.sandberg@arm.com}
12212531Sandreas.sandberg@arm.com
12312531Sandreas.sandberg@arm.comvoid
12412698Sandreas.sandberg@arm.comCheckerCPU::setDcachePort(CpuPort *dcache_port)
12512698Sandreas.sandberg@arm.com{
12612698Sandreas.sandberg@arm.com    dcachePort = dcache_port;
12712698Sandreas.sandberg@arm.com}
12812698Sandreas.sandberg@arm.com
12912698Sandreas.sandberg@arm.comvoid
13012698Sandreas.sandberg@arm.comCheckerCPU::serialize(ostream &os)
13112698Sandreas.sandberg@arm.com{
13212698Sandreas.sandberg@arm.com}
13312531Sandreas.sandberg@arm.com
13412531Sandreas.sandberg@arm.comvoid
13512531Sandreas.sandberg@arm.comCheckerCPU::unserialize(Checkpoint *cp, const string &section)
13612531Sandreas.sandberg@arm.com{
13712531Sandreas.sandberg@arm.com}
13812531Sandreas.sandberg@arm.com
13912531Sandreas.sandberg@arm.comFault
14012698Sandreas.sandberg@arm.comCheckerCPU::readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags)
14112698Sandreas.sandberg@arm.com{
14212698Sandreas.sandberg@arm.com    Fault fault = NoFault;
14312698Sandreas.sandberg@arm.com    unsigned blockSize = dcachePort->peerBlockSize();
14412698Sandreas.sandberg@arm.com    int fullSize = size;
14512531Sandreas.sandberg@arm.com    Addr secondAddr = roundDown(addr + size - 1, blockSize);
14612531Sandreas.sandberg@arm.com    bool checked_flags = false;
14712531Sandreas.sandberg@arm.com    bool flags_match = true;
14812531Sandreas.sandberg@arm.com    Addr pAddr = 0x0;
14912531Sandreas.sandberg@arm.com
15012531Sandreas.sandberg@arm.com
15112531Sandreas.sandberg@arm.com    if (secondAddr > addr)
15212531Sandreas.sandberg@arm.com       size = secondAddr - addr;
15312531Sandreas.sandberg@arm.com
15412531Sandreas.sandberg@arm.com    // Need to account for multiple accesses like the Atomic and TimingSimple
15512531Sandreas.sandberg@arm.com    while (1) {
15612531Sandreas.sandberg@arm.com        memReq = new Request();
15712531Sandreas.sandberg@arm.com        memReq->setVirt(0, addr, size, flags, masterId, thread->pcState().instAddr());
15812531Sandreas.sandberg@arm.com
15912531Sandreas.sandberg@arm.com        // translate to physical address
16012531Sandreas.sandberg@arm.com        fault = dtb->translateFunctional(memReq, tc, BaseTLB::Read);
16112531Sandreas.sandberg@arm.com
16212531Sandreas.sandberg@arm.com        if (!checked_flags && fault == NoFault && unverifiedReq) {
16312531Sandreas.sandberg@arm.com            flags_match = checkFlags(unverifiedReq, memReq->getVaddr(),
16412531Sandreas.sandberg@arm.com                                     memReq->getPaddr(), memReq->getFlags());
16512531Sandreas.sandberg@arm.com            pAddr = memReq->getPaddr();
16612531Sandreas.sandberg@arm.com            checked_flags = true;
16712531Sandreas.sandberg@arm.com        }
16812531Sandreas.sandberg@arm.com
16912531Sandreas.sandberg@arm.com        // Now do the access
17012531Sandreas.sandberg@arm.com        if (fault == NoFault &&
17112531Sandreas.sandberg@arm.com            !memReq->getFlags().isSet(Request::NO_ACCESS)) {
17212531Sandreas.sandberg@arm.com            PacketPtr pkt = new Packet(memReq,
17312533Sandreas.sandberg@arm.com                              memReq->isLLSC() ?
17412531Sandreas.sandberg@arm.com                              MemCmd::LoadLockedReq : MemCmd::ReadReq,
17512531Sandreas.sandberg@arm.com                              Packet::Broadcast);
17612531Sandreas.sandberg@arm.com
17712531Sandreas.sandberg@arm.com            pkt->dataStatic(data);
17812531Sandreas.sandberg@arm.com
17912531Sandreas.sandberg@arm.com            if (!(memReq->isUncacheable() || memReq->isMmappedIpr())) {
18012531Sandreas.sandberg@arm.com                // Access memory to see if we have the same data
18112531Sandreas.sandberg@arm.com                dcachePort->sendFunctional(pkt);
18212531Sandreas.sandberg@arm.com            } else {
18312531Sandreas.sandberg@arm.com                // Assume the data is correct if it's an uncached access
18412531Sandreas.sandberg@arm.com                memcpy(data, unverifiedMemData, size);
18512531Sandreas.sandberg@arm.com            }
18612531Sandreas.sandberg@arm.com
18712531Sandreas.sandberg@arm.com            delete memReq;
18812531Sandreas.sandberg@arm.com            memReq = NULL;
18912531Sandreas.sandberg@arm.com            delete pkt;
19012531Sandreas.sandberg@arm.com        }
19112531Sandreas.sandberg@arm.com
19212531Sandreas.sandberg@arm.com        if (fault != NoFault) {
19312531Sandreas.sandberg@arm.com            if (memReq->isPrefetch()) {
19412531Sandreas.sandberg@arm.com                fault = NoFault;
19512531Sandreas.sandberg@arm.com            }
19612531Sandreas.sandberg@arm.com            delete memReq;
19712531Sandreas.sandberg@arm.com            memReq = NULL;
19812531Sandreas.sandberg@arm.com            break;
19912531Sandreas.sandberg@arm.com        }
20012531Sandreas.sandberg@arm.com
20112531Sandreas.sandberg@arm.com        if (memReq != NULL) {
20212531Sandreas.sandberg@arm.com            delete memReq;
20312531Sandreas.sandberg@arm.com        }
20412531Sandreas.sandberg@arm.com
20512531Sandreas.sandberg@arm.com        //If we don't need to access a second cache line, stop now.
20612531Sandreas.sandberg@arm.com        if (secondAddr <= addr)
20712531Sandreas.sandberg@arm.com        {
20812533Sandreas.sandberg@arm.com            break;
20912531Sandreas.sandberg@arm.com        }
21012531Sandreas.sandberg@arm.com
21112531Sandreas.sandberg@arm.com        // Setup for accessing next cache line
21212531Sandreas.sandberg@arm.com        data += size;
21312531Sandreas.sandberg@arm.com        unverifiedMemData += size;
21412531Sandreas.sandberg@arm.com        size = addr + fullSize - secondAddr;
21512531Sandreas.sandberg@arm.com        addr = secondAddr;
21612531Sandreas.sandberg@arm.com    }
21712531Sandreas.sandberg@arm.com
21812531Sandreas.sandberg@arm.com    if (!flags_match) {
21912531Sandreas.sandberg@arm.com        warn("%lli: Flags do not match CPU:%#x %#x %#x Checker:%#x %#x %#x\n",
22012531Sandreas.sandberg@arm.com             curTick(), unverifiedReq->getVaddr(), unverifiedReq->getPaddr(),
22112531Sandreas.sandberg@arm.com             unverifiedReq->getFlags(), addr, pAddr, flags);
22212531Sandreas.sandberg@arm.com        handleError();
22312531Sandreas.sandberg@arm.com    }
22412531Sandreas.sandberg@arm.com
22512531Sandreas.sandberg@arm.com    return fault;
22612531Sandreas.sandberg@arm.com}
22712531Sandreas.sandberg@arm.com
22812531Sandreas.sandberg@arm.comFault
22912531Sandreas.sandberg@arm.comCheckerCPU::writeMem(uint8_t *data, unsigned size,
23012531Sandreas.sandberg@arm.com                     Addr addr, unsigned flags, uint64_t *res)
23112531Sandreas.sandberg@arm.com{
23212531Sandreas.sandberg@arm.com    Fault fault = NoFault;
23312531Sandreas.sandberg@arm.com    bool checked_flags = false;
23412531Sandreas.sandberg@arm.com    bool flags_match = true;
23512531Sandreas.sandberg@arm.com    Addr pAddr = 0x0;
23612531Sandreas.sandberg@arm.com
23712531Sandreas.sandberg@arm.com    unsigned blockSize = dcachePort->peerBlockSize();
23812531Sandreas.sandberg@arm.com    int fullSize = size;
23912531Sandreas.sandberg@arm.com
24012531Sandreas.sandberg@arm.com    Addr secondAddr = roundDown(addr + size - 1, blockSize);
24112531Sandreas.sandberg@arm.com
24212531Sandreas.sandberg@arm.com    if (secondAddr > addr)
24312531Sandreas.sandberg@arm.com        size = secondAddr - addr;
24412531Sandreas.sandberg@arm.com
24512531Sandreas.sandberg@arm.com    // Need to account for a multiple access like Atomic and Timing CPUs
24612531Sandreas.sandberg@arm.com    while (1) {
24712531Sandreas.sandberg@arm.com        memReq = new Request();
24812531Sandreas.sandberg@arm.com        memReq->setVirt(0, addr, size, flags, masterId, thread->pcState().instAddr());
24912531Sandreas.sandberg@arm.com
25012531Sandreas.sandberg@arm.com        // translate to physical address
25112531Sandreas.sandberg@arm.com        fault = dtb->translateFunctional(memReq, tc, BaseTLB::Write);
25212533Sandreas.sandberg@arm.com
25312533Sandreas.sandberg@arm.com        if (!checked_flags && fault == NoFault && unverifiedReq) {
25412533Sandreas.sandberg@arm.com           flags_match = checkFlags(unverifiedReq, memReq->getVaddr(),
25512533Sandreas.sandberg@arm.com                                    memReq->getPaddr(), memReq->getFlags());
25612533Sandreas.sandberg@arm.com           pAddr = memReq->getPaddr();
25712533Sandreas.sandberg@arm.com           checked_flags = true;
25812533Sandreas.sandberg@arm.com        }
25912533Sandreas.sandberg@arm.com
26012533Sandreas.sandberg@arm.com        /*
26112533Sandreas.sandberg@arm.com         * We don't actually check memory for the store because there
26212533Sandreas.sandberg@arm.com         * is no guarantee it has left the lsq yet, and therefore we
26312533Sandreas.sandberg@arm.com         * can't verify the memory on stores without lsq snooping
26412533Sandreas.sandberg@arm.com         * enabled.  This is left as future work for the Checker: LSQ snooping
26512533Sandreas.sandberg@arm.com         * and memory validation after stores have committed.
26612533Sandreas.sandberg@arm.com         */
26712533Sandreas.sandberg@arm.com
26812533Sandreas.sandberg@arm.com        delete memReq;
26912531Sandreas.sandberg@arm.com
27012531Sandreas.sandberg@arm.com        //If we don't need to access a second cache line, stop now.
27112531Sandreas.sandberg@arm.com        if (fault != NoFault || secondAddr <= addr)
27212531Sandreas.sandberg@arm.com        {
27312531Sandreas.sandberg@arm.com            if (fault != NoFault && memReq->isPrefetch()) {
27412531Sandreas.sandberg@arm.com              fault = NoFault;
27512533Sandreas.sandberg@arm.com            }
27612531Sandreas.sandberg@arm.com            break;
27712531Sandreas.sandberg@arm.com        }
27812531Sandreas.sandberg@arm.com
27912531Sandreas.sandberg@arm.com        //Update size and access address
28012531Sandreas.sandberg@arm.com        size = addr + fullSize - secondAddr;
28112531Sandreas.sandberg@arm.com        //And access the right address.
28212531Sandreas.sandberg@arm.com        addr = secondAddr;
28312531Sandreas.sandberg@arm.com   }
28412531Sandreas.sandberg@arm.com
28512531Sandreas.sandberg@arm.com   if (!flags_match) {
28612531Sandreas.sandberg@arm.com       warn("%lli: Flags do not match CPU:%#x %#x Checker:%#x %#x %#x\n",
28712531Sandreas.sandberg@arm.com            curTick(), unverifiedReq->getVaddr(), unverifiedReq->getPaddr(),
28812531Sandreas.sandberg@arm.com            unverifiedReq->getFlags(), addr, pAddr, flags);
28912531Sandreas.sandberg@arm.com       handleError();
29012531Sandreas.sandberg@arm.com   }
29112531Sandreas.sandberg@arm.com
29212531Sandreas.sandberg@arm.com   // Assume the result was the same as the one passed in.  This checker
29312531Sandreas.sandberg@arm.com   // doesn't check if the SC should succeed or fail, it just checks the
29412531Sandreas.sandberg@arm.com   // value.
29512531Sandreas.sandberg@arm.com   if (unverifiedReq && res && unverifiedReq->extraDataValid())
29612531Sandreas.sandberg@arm.com       *res = unverifiedReq->getExtraData();
29712531Sandreas.sandberg@arm.com
29812531Sandreas.sandberg@arm.com   // Entire purpose here is to make sure we are getting the
29912531Sandreas.sandberg@arm.com   // same data to send to the mem system as the CPU did.
30012531Sandreas.sandberg@arm.com   // Cannot check this is actually what went to memory because
30112531Sandreas.sandberg@arm.com   // there stores can be in ld/st queue or coherent operations
30212531Sandreas.sandberg@arm.com   // overwriting values.
30312531Sandreas.sandberg@arm.com   bool extraData;
30412531Sandreas.sandberg@arm.com   if (unverifiedReq) {
30512531Sandreas.sandberg@arm.com       extraData = unverifiedReq->extraDataValid() ?
30612531Sandreas.sandberg@arm.com                        unverifiedReq->getExtraData() : 1;
30712531Sandreas.sandberg@arm.com   }
30812531Sandreas.sandberg@arm.com
30912531Sandreas.sandberg@arm.com   if (unverifiedReq && unverifiedMemData &&
31012531Sandreas.sandberg@arm.com       memcmp(data, unverifiedMemData, fullSize) && extraData) {
31112531Sandreas.sandberg@arm.com           warn("%lli: Store value does not match value sent to memory!\
31212531Sandreas.sandberg@arm.com                  data: %#x inst_data: %#x", curTick(), data,
31312531Sandreas.sandberg@arm.com                  unverifiedMemData);
31412531Sandreas.sandberg@arm.com       handleError();
31512531Sandreas.sandberg@arm.com   }
31612531Sandreas.sandberg@arm.com
31712531Sandreas.sandberg@arm.com   return fault;
31812531Sandreas.sandberg@arm.com}
31912531Sandreas.sandberg@arm.com
32012531Sandreas.sandberg@arm.comAddr
32112531Sandreas.sandberg@arm.comCheckerCPU::dbg_vtophys(Addr addr)
32212531Sandreas.sandberg@arm.com{
32312531Sandreas.sandberg@arm.com    return vtophys(tc, addr);
32412531Sandreas.sandberg@arm.com}
32512531Sandreas.sandberg@arm.com
32612531Sandreas.sandberg@arm.com/**
32712531Sandreas.sandberg@arm.com * Checks if the flags set by the Checker and Checkee match.
32812531Sandreas.sandberg@arm.com */
32912531Sandreas.sandberg@arm.combool
33012531Sandreas.sandberg@arm.comCheckerCPU::checkFlags(Request *unverified_req, Addr vAddr,
33112531Sandreas.sandberg@arm.com                       Addr pAddr, int flags)
33212531Sandreas.sandberg@arm.com{
33312531Sandreas.sandberg@arm.com    Addr unverifiedVAddr = unverified_req->getVaddr();
33412531Sandreas.sandberg@arm.com    Addr unverifiedPAddr = unverified_req->getPaddr();
33512533Sandreas.sandberg@arm.com    int unverifiedFlags = unverified_req->getFlags();
33612531Sandreas.sandberg@arm.com
33712531Sandreas.sandberg@arm.com    if (unverifiedVAddr != vAddr ||
33812531Sandreas.sandberg@arm.com        unverifiedPAddr != pAddr ||
33912531Sandreas.sandberg@arm.com        unverifiedFlags != flags) {
34012531Sandreas.sandberg@arm.com        return false;
34112531Sandreas.sandberg@arm.com    }
34212531Sandreas.sandberg@arm.com
34312531Sandreas.sandberg@arm.com    return true;
34412531Sandreas.sandberg@arm.com}
34512531Sandreas.sandberg@arm.com
34612531Sandreas.sandberg@arm.comvoid
34712531Sandreas.sandberg@arm.comCheckerCPU::dumpAndExit()
34812533Sandreas.sandberg@arm.com{
34912531Sandreas.sandberg@arm.com    warn("%lli: Checker PC:%s",
35012531Sandreas.sandberg@arm.com         curTick(), thread->pcState());
35112531Sandreas.sandberg@arm.com    panic("Checker found an error!");
35212531Sandreas.sandberg@arm.com}
35312531Sandreas.sandberg@arm.com