cpu.cc revision 2789
12789Sktlim@umich.edu/*
22789Sktlim@umich.edu * Copyright (c) 2006 The Regents of The University of Michigan
32789Sktlim@umich.edu * All rights reserved.
42789Sktlim@umich.edu *
52789Sktlim@umich.edu * Redistribution and use in source and binary forms, with or without
62789Sktlim@umich.edu * modification, are permitted provided that the following conditions are
72789Sktlim@umich.edu * met: redistributions of source code must retain the above copyright
82789Sktlim@umich.edu * notice, this list of conditions and the following disclaimer;
92789Sktlim@umich.edu * redistributions in binary form must reproduce the above copyright
102789Sktlim@umich.edu * notice, this list of conditions and the following disclaimer in the
112789Sktlim@umich.edu * documentation and/or other materials provided with the distribution;
122789Sktlim@umich.edu * neither the name of the copyright holders nor the names of its
132789Sktlim@umich.edu * contributors may be used to endorse or promote products derived from
142789Sktlim@umich.edu * this software without specific prior written permission.
152789Sktlim@umich.edu *
162789Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172789Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182789Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192789Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202789Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212789Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222789Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232789Sktlim@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242789Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252789Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262789Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272789Sktlim@umich.edu *
282789Sktlim@umich.edu * Authors: Kevin Lim
292789Sktlim@umich.edu */
302789Sktlim@umich.edu
312789Sktlim@umich.edu#include <list>
322789Sktlim@umich.edu#include <string>
332789Sktlim@umich.edu
342789Sktlim@umich.edu#include "cpu/base.hh"
352789Sktlim@umich.edu#include "cpu/checker/cpu.hh"
362789Sktlim@umich.edu#include "cpu/simple_thread.hh"
372789Sktlim@umich.edu#include "cpu/thread_context.hh"
382789Sktlim@umich.edu#include "cpu/static_inst.hh"
392789Sktlim@umich.edu#include "mem/packet_impl.hh"
402789Sktlim@umich.edu#include "sim/byteswap.hh"
412789Sktlim@umich.edu
422789Sktlim@umich.edu#if FULL_SYSTEM
432789Sktlim@umich.edu#include "arch/vtophys.hh"
442789Sktlim@umich.edu#include "kern/kernel_stats.hh"
452789Sktlim@umich.edu#endif // FULL_SYSTEM
462789Sktlim@umich.edu
472789Sktlim@umich.eduusing namespace std;
482789Sktlim@umich.edu//The CheckerCPU does alpha only
492789Sktlim@umich.eduusing namespace AlphaISA;
502789Sktlim@umich.edu
512789Sktlim@umich.eduvoid
522789Sktlim@umich.eduCheckerCPU::init()
532789Sktlim@umich.edu{
542789Sktlim@umich.edu}
552789Sktlim@umich.edu
562789Sktlim@umich.eduCheckerCPU::CheckerCPU(Params *p)
572789Sktlim@umich.edu    : BaseCPU(p), thread(NULL), tc(NULL)
582789Sktlim@umich.edu{
592789Sktlim@umich.edu    memReq = NULL;
602789Sktlim@umich.edu
612789Sktlim@umich.edu    numInst = 0;
622789Sktlim@umich.edu    startNumInst = 0;
632789Sktlim@umich.edu    numLoad = 0;
642789Sktlim@umich.edu    startNumLoad = 0;
652789Sktlim@umich.edu    youngestSN = 0;
662789Sktlim@umich.edu
672789Sktlim@umich.edu    changedPC = willChangePC = changedNextPC = false;
682789Sktlim@umich.edu
692789Sktlim@umich.edu    exitOnError = p->exitOnError;
702789Sktlim@umich.edu    warnOnlyOnLoadError = p->warnOnlyOnLoadError;
712789Sktlim@umich.edu#if FULL_SYSTEM
722789Sktlim@umich.edu    itb = p->itb;
732789Sktlim@umich.edu    dtb = p->dtb;
742789Sktlim@umich.edu    systemPtr = NULL;
752789Sktlim@umich.edu#else
762789Sktlim@umich.edu    process = p->process;
772789Sktlim@umich.edu#endif
782789Sktlim@umich.edu
792789Sktlim@umich.edu    result.integer = 0;
802789Sktlim@umich.edu}
812789Sktlim@umich.edu
822789Sktlim@umich.eduCheckerCPU::~CheckerCPU()
832789Sktlim@umich.edu{
842789Sktlim@umich.edu}
852789Sktlim@umich.edu
862789Sktlim@umich.eduvoid
872789Sktlim@umich.eduCheckerCPU::setMemory(MemObject *mem)
882789Sktlim@umich.edu{
892789Sktlim@umich.edu#if !FULL_SYSTEM
902789Sktlim@umich.edu    memPtr = mem;
912789Sktlim@umich.edu    thread = new SimpleThread(this, /* thread_num */ 0, process,
922789Sktlim@umich.edu                              /* asid */ 0, mem);
932789Sktlim@umich.edu
942789Sktlim@umich.edu    thread->setStatus(ThreadContext::Suspended);
952789Sktlim@umich.edu    tc = thread->getTC();
962789Sktlim@umich.edu    threadContexts.push_back(tc);
972789Sktlim@umich.edu#endif
982789Sktlim@umich.edu}
992789Sktlim@umich.edu
1002789Sktlim@umich.eduvoid
1012789Sktlim@umich.eduCheckerCPU::setSystem(System *system)
1022789Sktlim@umich.edu{
1032789Sktlim@umich.edu#if FULL_SYSTEM
1042789Sktlim@umich.edu    systemPtr = system;
1052789Sktlim@umich.edu
1062789Sktlim@umich.edu    thread = new SimpleThread(this, 0, systemPtr, itb, dtb, false);
1072789Sktlim@umich.edu
1082789Sktlim@umich.edu    thread->setStatus(ThreadContext::Suspended);
1092789Sktlim@umich.edu    tc = thread->getTC();
1102789Sktlim@umich.edu    threadContexts.push_back(tc);
1112789Sktlim@umich.edu    delete thread->kernelStats;
1122789Sktlim@umich.edu    thread->kernelStats = NULL;
1132789Sktlim@umich.edu#endif
1142789Sktlim@umich.edu}
1152789Sktlim@umich.edu
1162789Sktlim@umich.eduvoid
1172789Sktlim@umich.eduCheckerCPU::setIcachePort(Port *icache_port)
1182789Sktlim@umich.edu{
1192789Sktlim@umich.edu    icachePort = icache_port;
1202789Sktlim@umich.edu}
1212789Sktlim@umich.edu
1222789Sktlim@umich.eduvoid
1232789Sktlim@umich.eduCheckerCPU::setDcachePort(Port *dcache_port)
1242789Sktlim@umich.edu{
1252789Sktlim@umich.edu    dcachePort = dcache_port;
1262789Sktlim@umich.edu}
1272789Sktlim@umich.edu
1282789Sktlim@umich.eduvoid
1292789Sktlim@umich.eduCheckerCPU::serialize(ostream &os)
1302789Sktlim@umich.edu{
1312789Sktlim@umich.edu/*
1322789Sktlim@umich.edu    BaseCPU::serialize(os);
1332789Sktlim@umich.edu    SERIALIZE_SCALAR(inst);
1342789Sktlim@umich.edu    nameOut(os, csprintf("%s.xc", name()));
1352789Sktlim@umich.edu    thread->serialize(os);
1362789Sktlim@umich.edu    cacheCompletionEvent.serialize(os);
1372789Sktlim@umich.edu*/
1382789Sktlim@umich.edu}
1392789Sktlim@umich.edu
1402789Sktlim@umich.eduvoid
1412789Sktlim@umich.eduCheckerCPU::unserialize(Checkpoint *cp, const string &section)
1422789Sktlim@umich.edu{
1432789Sktlim@umich.edu/*
1442789Sktlim@umich.edu    BaseCPU::unserialize(cp, section);
1452789Sktlim@umich.edu    UNSERIALIZE_SCALAR(inst);
1462789Sktlim@umich.edu    thread->unserialize(cp, csprintf("%s.xc", section));
1472789Sktlim@umich.edu*/
1482789Sktlim@umich.edu}
1492789Sktlim@umich.edu
1502789Sktlim@umich.eduFault
1512789Sktlim@umich.eduCheckerCPU::copySrcTranslate(Addr src)
1522789Sktlim@umich.edu{
1532789Sktlim@umich.edu    panic("Unimplemented!");
1542789Sktlim@umich.edu}
1552789Sktlim@umich.edu
1562789Sktlim@umich.eduFault
1572789Sktlim@umich.eduCheckerCPU::copy(Addr dest)
1582789Sktlim@umich.edu{
1592789Sktlim@umich.edu    panic("Unimplemented!");
1602789Sktlim@umich.edu}
1612789Sktlim@umich.edu
1622789Sktlim@umich.edutemplate <class T>
1632789Sktlim@umich.eduFault
1642789Sktlim@umich.eduCheckerCPU::read(Addr addr, T &data, unsigned flags)
1652789Sktlim@umich.edu{
1662789Sktlim@umich.edu    // need to fill in CPU & thread IDs here
1672789Sktlim@umich.edu    memReq = new Request();
1682789Sktlim@umich.edu
1692789Sktlim@umich.edu    memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC());
1702789Sktlim@umich.edu
1712789Sktlim@umich.edu    // translate to physical address
1722789Sktlim@umich.edu    translateDataReadReq(memReq);
1732789Sktlim@umich.edu
1742789Sktlim@umich.edu    Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
1752789Sktlim@umich.edu
1762789Sktlim@umich.edu    pkt->dataStatic(&data);
1772789Sktlim@umich.edu
1782789Sktlim@umich.edu    if (!(memReq->getFlags() & UNCACHEABLE)) {
1792789Sktlim@umich.edu        // Access memory to see if we have the same data
1802789Sktlim@umich.edu        dcachePort->sendFunctional(pkt);
1812789Sktlim@umich.edu    } else {
1822789Sktlim@umich.edu        // Assume the data is correct if it's an uncached access
1832789Sktlim@umich.edu        memcpy(&data, &unverifiedResult.integer, sizeof(T));
1842789Sktlim@umich.edu    }
1852789Sktlim@umich.edu
1862789Sktlim@umich.edu    delete pkt;
1872789Sktlim@umich.edu
1882789Sktlim@umich.edu    return NoFault;
1892789Sktlim@umich.edu}
1902789Sktlim@umich.edu
1912789Sktlim@umich.edu#ifndef DOXYGEN_SHOULD_SKIP_THIS
1922789Sktlim@umich.edu
1932789Sktlim@umich.edutemplate
1942789Sktlim@umich.eduFault
1952789Sktlim@umich.eduCheckerCPU::read(Addr addr, uint64_t &data, unsigned flags);
1962789Sktlim@umich.edu
1972789Sktlim@umich.edutemplate
1982789Sktlim@umich.eduFault
1992789Sktlim@umich.eduCheckerCPU::read(Addr addr, uint32_t &data, unsigned flags);
2002789Sktlim@umich.edu
2012789Sktlim@umich.edutemplate
2022789Sktlim@umich.eduFault
2032789Sktlim@umich.eduCheckerCPU::read(Addr addr, uint16_t &data, unsigned flags);
2042789Sktlim@umich.edu
2052789Sktlim@umich.edutemplate
2062789Sktlim@umich.eduFault
2072789Sktlim@umich.eduCheckerCPU::read(Addr addr, uint8_t &data, unsigned flags);
2082789Sktlim@umich.edu
2092789Sktlim@umich.edu#endif //DOXYGEN_SHOULD_SKIP_THIS
2102789Sktlim@umich.edu
2112789Sktlim@umich.edutemplate<>
2122789Sktlim@umich.eduFault
2132789Sktlim@umich.eduCheckerCPU::read(Addr addr, double &data, unsigned flags)
2142789Sktlim@umich.edu{
2152789Sktlim@umich.edu    return read(addr, *(uint64_t*)&data, flags);
2162789Sktlim@umich.edu}
2172789Sktlim@umich.edu
2182789Sktlim@umich.edutemplate<>
2192789Sktlim@umich.eduFault
2202789Sktlim@umich.eduCheckerCPU::read(Addr addr, float &data, unsigned flags)
2212789Sktlim@umich.edu{
2222789Sktlim@umich.edu    return read(addr, *(uint32_t*)&data, flags);
2232789Sktlim@umich.edu}
2242789Sktlim@umich.edu
2252789Sktlim@umich.edutemplate<>
2262789Sktlim@umich.eduFault
2272789Sktlim@umich.eduCheckerCPU::read(Addr addr, int32_t &data, unsigned flags)
2282789Sktlim@umich.edu{
2292789Sktlim@umich.edu    return read(addr, (uint32_t&)data, flags);
2302789Sktlim@umich.edu}
2312789Sktlim@umich.edu
2322789Sktlim@umich.edutemplate <class T>
2332789Sktlim@umich.eduFault
2342789Sktlim@umich.eduCheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
2352789Sktlim@umich.edu{
2362789Sktlim@umich.edu    // need to fill in CPU & thread IDs here
2372789Sktlim@umich.edu    memReq = new Request();
2382789Sktlim@umich.edu
2392789Sktlim@umich.edu    memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC());
2402789Sktlim@umich.edu
2412789Sktlim@umich.edu    // translate to physical address
2422789Sktlim@umich.edu    thread->translateDataWriteReq(memReq);
2432789Sktlim@umich.edu
2442789Sktlim@umich.edu    // Can compare the write data and result only if it's cacheable,
2452789Sktlim@umich.edu    // not a store conditional, or is a store conditional that
2462789Sktlim@umich.edu    // succeeded.
2472789Sktlim@umich.edu    // @todo: Verify that actual memory matches up with these values.
2482789Sktlim@umich.edu    // Right now it only verifies that the instruction data is the
2492789Sktlim@umich.edu    // same as what was in the request that got sent to memory; there
2502789Sktlim@umich.edu    // is no verification that it is the same as what is in memory.
2512789Sktlim@umich.edu    // This is because the LSQ would have to be snooped in the CPU to
2522789Sktlim@umich.edu    // verify this data.
2532789Sktlim@umich.edu    if (unverifiedReq &&
2542789Sktlim@umich.edu        !(unverifiedReq->getFlags() & UNCACHEABLE) &&
2552789Sktlim@umich.edu        (!(unverifiedReq->getFlags() & LOCKED) ||
2562789Sktlim@umich.edu         ((unverifiedReq->getFlags() & LOCKED) &&
2572789Sktlim@umich.edu          unverifiedReq->getScResult() == 1))) {
2582789Sktlim@umich.edu        T inst_data;
2592789Sktlim@umich.edu/*
2602789Sktlim@umich.edu        // This code would work if the LSQ allowed for snooping.
2612789Sktlim@umich.edu        Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
2622789Sktlim@umich.edu        pkt.dataStatic(&inst_data);
2632789Sktlim@umich.edu
2642789Sktlim@umich.edu        dcachePort->sendFunctional(pkt);
2652789Sktlim@umich.edu
2662789Sktlim@umich.edu        delete pkt;
2672789Sktlim@umich.edu*/
2682789Sktlim@umich.edu        memcpy(&inst_data, unverifiedMemData, sizeof(T));
2692789Sktlim@umich.edu
2702789Sktlim@umich.edu        if (data != inst_data) {
2712789Sktlim@umich.edu            warn("%lli: Store value does not match value in memory! "
2722789Sktlim@umich.edu                 "Instruction: %#x, memory: %#x",
2732789Sktlim@umich.edu                 curTick, inst_data, data);
2742789Sktlim@umich.edu            handleError();
2752789Sktlim@umich.edu        }
2762789Sktlim@umich.edu    }
2772789Sktlim@umich.edu
2782789Sktlim@umich.edu    // Assume the result was the same as the one passed in.  This checker
2792789Sktlim@umich.edu    // doesn't check if the SC should succeed or fail, it just checks the
2802789Sktlim@umich.edu    // value.
2812789Sktlim@umich.edu    if (res && unverifiedReq->scResultValid())
2822789Sktlim@umich.edu        *res = unverifiedReq->getScResult();
2832789Sktlim@umich.edu
2842789Sktlim@umich.edu    return NoFault;
2852789Sktlim@umich.edu}
2862789Sktlim@umich.edu
2872789Sktlim@umich.edu
2882789Sktlim@umich.edu#ifndef DOXYGEN_SHOULD_SKIP_THIS
2892789Sktlim@umich.edutemplate
2902789Sktlim@umich.eduFault
2912789Sktlim@umich.eduCheckerCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res);
2922789Sktlim@umich.edu
2932789Sktlim@umich.edutemplate
2942789Sktlim@umich.eduFault
2952789Sktlim@umich.eduCheckerCPU::write(uint32_t data, Addr addr, unsigned flags, uint64_t *res);
2962789Sktlim@umich.edu
2972789Sktlim@umich.edutemplate
2982789Sktlim@umich.eduFault
2992789Sktlim@umich.eduCheckerCPU::write(uint16_t data, Addr addr, unsigned flags, uint64_t *res);
3002789Sktlim@umich.edu
3012789Sktlim@umich.edutemplate
3022789Sktlim@umich.eduFault
3032789Sktlim@umich.eduCheckerCPU::write(uint8_t data, Addr addr, unsigned flags, uint64_t *res);
3042789Sktlim@umich.edu
3052789Sktlim@umich.edu#endif //DOXYGEN_SHOULD_SKIP_THIS
3062789Sktlim@umich.edu
3072789Sktlim@umich.edutemplate<>
3082789Sktlim@umich.eduFault
3092789Sktlim@umich.eduCheckerCPU::write(double data, Addr addr, unsigned flags, uint64_t *res)
3102789Sktlim@umich.edu{
3112789Sktlim@umich.edu    return write(*(uint64_t*)&data, addr, flags, res);
3122789Sktlim@umich.edu}
3132789Sktlim@umich.edu
3142789Sktlim@umich.edutemplate<>
3152789Sktlim@umich.eduFault
3162789Sktlim@umich.eduCheckerCPU::write(float data, Addr addr, unsigned flags, uint64_t *res)
3172789Sktlim@umich.edu{
3182789Sktlim@umich.edu    return write(*(uint32_t*)&data, addr, flags, res);
3192789Sktlim@umich.edu}
3202789Sktlim@umich.edu
3212789Sktlim@umich.edutemplate<>
3222789Sktlim@umich.eduFault
3232789Sktlim@umich.eduCheckerCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
3242789Sktlim@umich.edu{
3252789Sktlim@umich.edu    return write((uint32_t)data, addr, flags, res);
3262789Sktlim@umich.edu}
3272789Sktlim@umich.edu
3282789Sktlim@umich.edu
3292789Sktlim@umich.edu#if FULL_SYSTEM
3302789Sktlim@umich.eduAddr
3312789Sktlim@umich.eduCheckerCPU::dbg_vtophys(Addr addr)
3322789Sktlim@umich.edu{
3332789Sktlim@umich.edu    return vtophys(tc, addr);
3342789Sktlim@umich.edu}
3352789Sktlim@umich.edu#endif // FULL_SYSTEM
3362789Sktlim@umich.edu
3372789Sktlim@umich.edubool
3382789Sktlim@umich.eduCheckerCPU::translateInstReq(Request *req)
3392789Sktlim@umich.edu{
3402789Sktlim@umich.edu#if FULL_SYSTEM
3412789Sktlim@umich.edu    return (thread->translateInstReq(req) == NoFault);
3422789Sktlim@umich.edu#else
3432789Sktlim@umich.edu    thread->translateInstReq(req);
3442789Sktlim@umich.edu    return true;
3452789Sktlim@umich.edu#endif
3462789Sktlim@umich.edu}
3472789Sktlim@umich.edu
3482789Sktlim@umich.eduvoid
3492789Sktlim@umich.eduCheckerCPU::translateDataReadReq(Request *req)
3502789Sktlim@umich.edu{
3512789Sktlim@umich.edu    thread->translateDataReadReq(req);
3522789Sktlim@umich.edu
3532789Sktlim@umich.edu    if (req->getVaddr() != unverifiedReq->getVaddr()) {
3542789Sktlim@umich.edu        warn("%lli: Request virtual addresses do not match! Inst: %#x, "
3552789Sktlim@umich.edu             "checker: %#x",
3562789Sktlim@umich.edu             curTick, unverifiedReq->getVaddr(), req->getVaddr());
3572789Sktlim@umich.edu        handleError();
3582789Sktlim@umich.edu    }
3592789Sktlim@umich.edu    req->setPaddr(unverifiedReq->getPaddr());
3602789Sktlim@umich.edu
3612789Sktlim@umich.edu    if (checkFlags(req)) {
3622789Sktlim@umich.edu        warn("%lli: Request flags do not match! Inst: %#x, checker: %#x",
3632789Sktlim@umich.edu             curTick, unverifiedReq->getFlags(), req->getFlags());
3642789Sktlim@umich.edu        handleError();
3652789Sktlim@umich.edu    }
3662789Sktlim@umich.edu}
3672789Sktlim@umich.edu
3682789Sktlim@umich.eduvoid
3692789Sktlim@umich.eduCheckerCPU::translateDataWriteReq(Request *req)
3702789Sktlim@umich.edu{
3712789Sktlim@umich.edu    thread->translateDataWriteReq(req);
3722789Sktlim@umich.edu
3732789Sktlim@umich.edu    if (req->getVaddr() != unverifiedReq->getVaddr()) {
3742789Sktlim@umich.edu        warn("%lli: Request virtual addresses do not match! Inst: %#x, "
3752789Sktlim@umich.edu             "checker: %#x",
3762789Sktlim@umich.edu             curTick, unverifiedReq->getVaddr(), req->getVaddr());
3772789Sktlim@umich.edu        handleError();
3782789Sktlim@umich.edu    }
3792789Sktlim@umich.edu    req->setPaddr(unverifiedReq->getPaddr());
3802789Sktlim@umich.edu
3812789Sktlim@umich.edu    if (checkFlags(req)) {
3822789Sktlim@umich.edu        warn("%lli: Request flags do not match! Inst: %#x, checker: %#x",
3832789Sktlim@umich.edu             curTick, unverifiedReq->getFlags(), req->getFlags());
3842789Sktlim@umich.edu        handleError();
3852789Sktlim@umich.edu    }
3862789Sktlim@umich.edu}
3872789Sktlim@umich.edu
3882789Sktlim@umich.edubool
3892789Sktlim@umich.eduCheckerCPU::checkFlags(Request *req)
3902789Sktlim@umich.edu{
3912789Sktlim@umich.edu    // Remove any dynamic flags that don't have to do with the request itself.
3922789Sktlim@umich.edu    unsigned flags = unverifiedReq->getFlags();
3932789Sktlim@umich.edu    unsigned mask = LOCKED | PHYSICAL | VPTE | ALTMODE | UNCACHEABLE | NO_FAULT;
3942789Sktlim@umich.edu    flags = flags & (mask);
3952789Sktlim@umich.edu    if (flags == req->getFlags()) {
3962789Sktlim@umich.edu        return false;
3972789Sktlim@umich.edu    } else {
3982789Sktlim@umich.edu        return true;
3992789Sktlim@umich.edu    }
4002789Sktlim@umich.edu}
4012789Sktlim@umich.edu
4022789Sktlim@umich.eduvoid
4032789Sktlim@umich.eduCheckerCPU::dumpAndExit()
4042789Sktlim@umich.edu{
4052789Sktlim@umich.edu    warn("%lli: Checker PC:%#x, next PC:%#x",
4062789Sktlim@umich.edu         curTick, thread->readPC(), thread->readNextPC());
4072789Sktlim@umich.edu    panic("Checker found an error!");
4082789Sktlim@umich.edu}
409