Merge with head, hopefully the last time for this batch.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 1 Feb 2012 06:40:08 +0000 (22:40 -0800)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 1 Feb 2012 06:40:08 +0000 (22:40 -0800)
56 files changed:
1  2 
SConstruct
src/arch/alpha/tlb.cc
src/arch/arm/insts/static_inst.hh
src/arch/arm/isa/formats/m5ops.isa
src/arch/arm/isa/insts/m5ops.isa
src/arch/arm/isa/insts/misc.isa
src/arch/arm/tlb.cc
src/arch/arm/tlb.hh
src/arch/arm/utility.cc
src/arch/mips/faults.cc
src/arch/mips/faults.hh
src/cpu/BaseCPU.py
src/cpu/SConscript
src/cpu/base.cc
src/cpu/base.hh
src/cpu/base_dyn_inst.hh
src/cpu/checker/cpu.cc
src/cpu/checker/cpu.hh
src/cpu/checker/cpu_impl.hh
src/cpu/checker/thread_context.hh
src/cpu/dummy_checker_builder.cc
src/cpu/inorder/cpu.cc
src/cpu/inorder/cpu.hh
src/cpu/inorder/resources/cache_unit.hh
src/cpu/inorder/thread_context.cc
src/cpu/o3/O3CPU.py
src/cpu/o3/checker_builder.cc
src/cpu/o3/commit.hh
src/cpu/o3/commit_impl.hh
src/cpu/o3/cpu.cc
src/cpu/o3/cpu.hh
src/cpu/o3/decode_impl.hh
src/cpu/o3/dyn_inst_impl.hh
src/cpu/o3/fetch_impl.hh
src/cpu/o3/iew.hh
src/cpu/o3/lsq.hh
src/cpu/o3/lsq_unit.hh
src/cpu/o3/thread_context.hh
src/cpu/o3/thread_context_impl.hh
src/cpu/simple/atomic.cc
src/cpu/simple/base.cc
src/cpu/simple/base.hh
src/cpu/simple/timing.cc
src/cpu/simple_thread.cc
src/cpu/simple_thread.hh
src/cpu/thread_context.hh
src/cpu/thread_state.hh
src/dev/pcidev.cc
src/mem/cache/base.cc
src/mem/cache/base.hh
src/sim/process.cc
src/sim/process.hh
src/sim/process_impl.hh
src/sim/pseudo_inst.cc
src/sim/pseudo_inst.hh
src/sim/syscall_emul.hh

diff --cc SConstruct
Simple merge
Simple merge
index d65555822234eaf762b24ba83c488346154f6f2c,5af97b7961ed26d971f4e406a110b3ba0ea06e57..c36024ecd60afd3a1a897bdb9977e788317133be
@@@ -46,7 -46,7 +46,8 @@@
  #include "arch/arm/utility.hh"
  #include "base/trace.hh"
  #include "cpu/static_inst.hh"
+ #include "sim/byteswap.hh"
 +#include "sim/full_system.hh"
  
  namespace ArmISA
  {
index 3b08acad7c17936e5ca924499ce13ad2abf83273,534d12cd933139ccd7fc92d6fafd89ea709a9801..1eb7d3f652578e7438ce98be81ecf3484c4df4a9
@@@ -59,10 -63,15 +59,11 @@@ def format M5ops() {
              case 0x41: return new Dumpstats(machInst);
              case 0x42: return new Dumpresetstats(machInst);
              case 0x43: return new M5checkpoint(machInst);
 -#if FULL_SYSTEM
+             case 0x4F: return new M5writefile(machInst);
              case 0x50: return new M5readfile(machInst);
 -#endif
              case 0x51: return new M5break(machInst);
              case 0x52: return new M5switchcpu(machInst);
 -#if FULL_SYSTEM
              case 0x53: return new M5addsymbol(machInst);
 -#endif
              case 0x54: return new M5panic(machInst);
              case 0x5a: return new M5workbegin(machInst);
              case 0x5b: return new M5workend(machInst);
index da2e1088606f5ba13f9ac1f11817fdbdcc641563,1a154459eaf3d67759c979216ef1b5854221a295..a32bf6dfc3d923599581badeb3aa25032644e06a
@@@ -261,6 -265,24 +261,22 @@@ let {
      decoder_output += BasicConstructor.subst(m5readfileIop)
      exec_output += PredOpExecute.subst(m5readfileIop)
  
 -#if FULL_SYSTEM
+     m5writefileCode = '''
 -#endif
+     int n = 4;
+     uint64_t offset = getArgument(xc->tcBase(), n, sizeof(uint64_t), false);
+     n = 6;
+     Addr filenameAddr = getArgument(xc->tcBase(), n, sizeof(Addr), false);
+     R0 = PseudoInst::writefile(xc->tcBase(), R0, join32to64(R3,R2), offset,
+                                 filenameAddr);
+     '''
+     m5writefileIop = InstObjParams("m5writefile", "M5writefile", "PredOp",
+                            { "code": m5writefileCode,
+                              "predicate_test": predicateTest },
+                              ["IsNonSpeculative"])
+     header_output += BasicDeclare.subst(m5writefileIop)
+     decoder_output += BasicConstructor.subst(m5writefileIop)
+     exec_output += PredOpExecute.subst(m5writefileIop)
      m5breakIop = InstObjParams("m5break", "M5break", "PredOp",
                             { "code": "PseudoInst::debugbreak(xc->tcBase());",
                               "predicate_test": predicateTest },
Simple merge
index b19ad5265963761737c6a9e22bcb77e419327761,f4dc476552882dc50118bc833ba48c597f1d60ce..0b003e9fb06eb3d019b67b2f33c4ab7231c9e354
@@@ -686,6 -703,20 +689,19 @@@ TLB::translateAtomic(RequestPtr req, Th
      return fault;
  }
  
 -#if FULL_SYSTEM
 -    fault = translateFs(req, tc, mode, NULL, delay, false, true);
 -#else
 -    fault = translateSe(req, tc, mode, NULL, delay, false);
 -#endif
+ Fault
+ TLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode)
+ {
+     bool delay = false;
+     Fault fault;
++    if (FullSystem)
++        fault = translateFs(req, tc, mode, NULL, delay, false, true);
++    else
++        fault = translateSe(req, tc, mode, NULL, delay, false);
+     assert(!delay);
+     return fault;
+ }
  Fault
  TLB::translateTiming(RequestPtr req, ThreadContext *tc,
          Translation *translation, Mode mode)
index 0bf13fe830bc31b320405f7b84e062ddb0df456d,bdfa2fc9fdc032b0bcc3715d6bd3054ae9750324..daf59f01d17b6ad60a65eef66cd41781679eddf8
@@@ -193,10 -201,14 +199,11 @@@ class TLB : public BaseTL
          return _attr;
      }
  
 -#if FULL_SYSTEM
      Fault translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
-             Translation *translation, bool &delay, bool timing);
+             Translation *translation, bool &delay,
+             bool timing, bool functional = false);
 -#else
      Fault translateSe(RequestPtr req, ThreadContext *tc, Mode mode,
              Translation *translation, bool &delay, bool timing);
 -#endif
      Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
      Fault translateTiming(RequestPtr req, ThreadContext *tc,
              Translation *translation, Mode mode);
index ac81c7db6cbc9035aa3a90ac20c8841e52a66080,b31dc432425b50b13b80d2abf9e243f85e92f1f2..0527e135fdac00b78718e38abce05007dfff46f6
  
  #include "arch/arm/faults.hh"
  #include "arch/arm/isa_traits.hh"
 +#include "arch/arm/tlb.hh"
  #include "arch/arm/utility.hh"
 +#include "arch/arm/vtophys.hh"
+ #include "config/use_checker.hh"
  #include "cpu/thread_context.hh"
 -
 -#if FULL_SYSTEM
 -#include "arch/arm/vtophys.hh"
  #include "mem/fs_translating_port_proxy.hh"
 -#endif
 -
 -#include "arch/arm/tlb.hh"
 +#include "sim/full_system.hh"
  
  namespace ArmISA {
  
Simple merge
Simple merge
index 19464acbccb5fbe60f94bcc0765d6f778c9b0373,77ba35b19d40a4f0ee53e36c51681f84e7be1a14..fda0a3bc8f4e0b13fa67c9dfcb621d5675f55776
@@@ -170,16 -183,22 +169,21 @@@ class BaseCPU(MemObject)
          self.icache_port = ic.cpu_side
          self.dcache_port = dc.cpu_side
          self._cached_ports = ['icache.mem_side', 'dcache.mem_side']
 -        if buildEnv['FULL_SYSTEM']:
 -            if buildEnv['TARGET_ISA'] in ['x86', 'arm']:
 -                if iwc and dwc:
 -                    self.itb_walker_cache = iwc
 -                    self.dtb_walker_cache = dwc
 -                    self.itb.walker.port = iwc.cpu_side
 -                    self.dtb.walker.port = dwc.cpu_side
 -                    self._cached_ports += ["itb_walker_cache.mem_side", \
 -                                           "dtb_walker_cache.mem_side"]
 -                else:
 -                    self._cached_ports += ["itb.walker.port", "dtb.walker.port"]
 -                # Checker doesn't need its own tlb caches because it does
 -                # functional accesses only
 -                if buildEnv['USE_CHECKER']:
 -                    self._cached_ports += ["checker.itb.walker.port", \
 -                                           "checker.dtb.walker.port"]
 +        if buildEnv['TARGET_ISA'] in ['x86', 'arm']:
 +            if iwc and dwc:
 +                self.itb_walker_cache = iwc
 +                self.dtb_walker_cache = dwc
 +                self.itb.walker.port = iwc.cpu_side
 +                self.dtb.walker.port = dwc.cpu_side
 +                self._cached_ports += ["itb_walker_cache.mem_side", \
 +                                       "dtb_walker_cache.mem_side"]
 +            else:
 +                self._cached_ports += ["itb.walker.port", "dtb.walker.port"]
++            # Checker doesn't need its own tlb caches because it does
++            # functional accesses only
++            if buildEnv['USE_CHECKER']:
++                self._cached_ports += ["checker.itb.walker.port", \
++                                       "checker.dtb.walker.port"]
  
      def addTwoLevelCacheHierarchy(self, ic, dc, l2c, iwc = None, dwc = None):
          self.addPrivateSplitL1Caches(ic, dc, iwc, dwc)
index ff731336a61469d59d4be1c98614142504687fe2,5b276380eb0a27ae52315920b67587a2cf37caef..de59dcc24d93b7da9f08f22cc9bb9e843c5ba2aa
@@@ -129,12 -126,20 +129,14 @@@ Source('simple_thread.cc'
  Source('thread_context.cc')
  Source('thread_state.cc')
  
 -if env['FULL_SYSTEM']:
 -    SimObject('IntrControl.py')
 -
 -    Source('intr_control.cc')
 -    Source('profile.cc')
 -
 -    if env['TARGET_ISA'] == 'sparc':
 -        SimObject('LegionTrace.py')
 -        Source('legiontrace.cc')
 +if env['TARGET_ISA'] == 'sparc':
 +    SimObject('LegionTrace.py')
 +    Source('legiontrace.cc')
  
  if env['USE_CHECKER']:
+     SimObject('DummyChecker.py')
      Source('checker/cpu.cc')
+     Source('dummy_checker_builder.cc')
      DebugFlag('Checker')
      checker_supports = False
      for i in CheckerSupportedCPUList:
diff --cc src/cpu/base.cc
index d174995a98d189c42cb230315b18178956911ecf,f9ae9ce5d6d05450a40a3b781d5cf22b72ed3cf2..977769126314e7e983a398631426e8f156a25f2e
@@@ -212,13 -223,16 +217,16 @@@ BaseCPU::BaseCPU(Params *p
              schedule(event, p->function_trace_start);
          }
      }
-     interrupts->setCPU(this);
 -#if FULL_SYSTEM
+     // Check if CPU model has interrupts connected. The CheckerCPU
+     // cannot take interrupts directly for example.
+     if (interrupts)
+         interrupts->setCPU(this);
  
 -    profileEvent = NULL;
 -    if (params()->profile)
 -        profileEvent = new ProfileEvent(this, params()->profile);
 -#endif
 +    if (FullSystem) {
 +        profileEvent = NULL;
 +        if (params()->profile)
 +            profileEvent = new ProfileEvent(this, params()->profile);
 +    }
      tracer = params()->tracer;
  }
  
@@@ -396,8 -418,38 +406,37 @@@ BaseCPU::takeOverFrom(BaseCPU *oldCPU
              new_dtb_port->setPeer(peer);
              peer->setPeer(new_dtb_port);
          }
+ #if USE_CHECKER
+         Port *old_checker_itb_port, *old_checker_dtb_port;
+         Port *new_checker_itb_port, *new_checker_dtb_port;
+         CheckerCPU *oldChecker =
+             dynamic_cast<CheckerCPU*>(oldTC->getCheckerCpuPtr());
+         CheckerCPU *newChecker =
+             dynamic_cast<CheckerCPU*>(newTC->getCheckerCpuPtr());
+         old_checker_itb_port = oldChecker->getITBPtr()->getPort();
+         old_checker_dtb_port = oldChecker->getDTBPtr()->getPort();
+         new_checker_itb_port = newChecker->getITBPtr()->getPort();
+         new_checker_dtb_port = newChecker->getDTBPtr()->getPort();
+         // Move over any table walker ports if they exist for checker
+         if (new_checker_itb_port && !new_checker_itb_port->isConnected()) {
+             assert(old_checker_itb_port);
+             Port *peer = old_checker_itb_port->getPeer();;
+             new_checker_itb_port->setPeer(peer);
+             peer->setPeer(new_checker_itb_port);
+         }
+         if (new_checker_dtb_port && !new_checker_dtb_port->isConnected()) {
+             assert(old_checker_dtb_port);
+             Port *peer = old_checker_dtb_port->getPeer();;
+             new_checker_dtb_port->setPeer(peer);
+             peer->setPeer(new_checker_dtb_port);
+         }
+ #endif
      }
  
 -#if FULL_SYSTEM
      interrupts = oldCPU->interrupts;
      interrupts->setCPU(this);
  
diff --cc src/cpu/base.hh
Simple merge
index 9089d1069ad1b5ee439e7b540e62dd5dce675427,14889a206d1d458e05419a972cd159888549ac5c..2b0e26cd21930d850263fb8a1322eb510f2fca9b
@@@ -53,7 -54,9 +54,8 @@@
  #include "arch/utility.hh"
  #include "base/fast_alloc.hh"
  #include "base/trace.hh"
 -#include "config/full_system.hh"
  #include "config/the_isa.hh"
+ #include "config/use_checker.hh"
  #include "cpu/o3/comm.hh"
  #include "cpu/exetrace.hh"
  #include "cpu/inst_seq.hh"
index ec4496eb49d67d94f6eecd6e0e409907a76dacd9,7c9e4f78158dddcfbc288281da781d4d6138010e..c905c62eb5c115b486eadc80607e8c9cf55213e7
  #include "cpu/simple_thread.hh"
  #include "cpu/static_inst.hh"
  #include "cpu/thread_context.hh"
+ #include "params/CheckerCPU.hh"
+ #include "sim/tlb.hh"
  
 -#if FULL_SYSTEM
 -#include "arch/kernel_stats.hh"
 -#include "arch/vtophys.hh"
 -#endif // FULL_SYSTEM
 -
  using namespace std;
- //The CheckerCPU does alpha only
- using namespace AlphaISA;
+ using namespace TheISA;
  
  void
  CheckerCPU::init()
@@@ -65,14 -84,18 +81,15 @@@ CheckerCPU::CheckerCPU(Params *p
      warnOnlyOnLoadError = p->warnOnlyOnLoadError;
      itb = p->itb;
      dtb = p->dtb;
 -#if FULL_SYSTEM
      systemPtr = NULL;
-     process = p->process;
-     thread = new SimpleThread(this, /* thread_num */ 0, process);
 -#else
+     workload = p->workload;
+     // XXX: This is a hack to get this to work some
+     thread = new SimpleThread(this, /* thread_num */ 0, workload[0], itb, dtb);
  
      tc = thread->getTC();
      threadContexts.push_back(tc);
 -#endif
  
-     result.integer = 0;
+     updateOnError = true;
  }
  
  CheckerCPU::~CheckerCPU()
@@@ -119,198 -137,215 +129,213 @@@ CheckerCPU::serialize(ostream &os
  void
  CheckerCPU::unserialize(Checkpoint *cp, const string &section)
  {
- /*
-     BaseCPU::unserialize(cp, section);
-     UNSERIALIZE_SCALAR(inst);
-     thread->unserialize(cp, csprintf("%s.xc", section));
- */
  }
  
- template <class T>
  Fault
- CheckerCPU::read(Addr addr, T &data, unsigned flags)
+ CheckerCPU::readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags)
  {
-     // need to fill in CPU & thread IDs here
-     memReq = new Request();
+     Fault fault = NoFault;
+     unsigned blockSize = dcachePort->peerBlockSize();
+     int fullSize = size;
+     Addr secondAddr = roundDown(addr + size - 1, blockSize);
+     bool checked_flags = false;
+     bool flags_match = true;
+     Addr pAddr = 0x0;
+     if (secondAddr > addr)
+        size = secondAddr - addr;
+     // Need to account for multiple accesses like the Atomic and TimingSimple
+     while (1) {
+         memReq = new Request();
+         memReq->setVirt(0, addr, size, flags, thread->pcState().instAddr());
+         // translate to physical address
+         fault = dtb->translateFunctional(memReq, tc, BaseTLB::Read);
+         if (!checked_flags && fault == NoFault && unverifiedReq) {
+             flags_match = checkFlags(unverifiedReq, memReq->getVaddr(),
+                                      memReq->getPaddr(), memReq->getFlags());
+             pAddr = memReq->getPaddr();
+             checked_flags = true;
+         }
  
-     memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC());
+         // Now do the access
+         if (fault == NoFault &&
+             !memReq->getFlags().isSet(Request::NO_ACCESS)) {
+             PacketPtr pkt = new Packet(memReq,
+                               memReq->isLLSC() ?
+                               MemCmd::LoadLockedReq : MemCmd::ReadReq,
+                               Packet::Broadcast);
+             pkt->dataStatic(data);
+             if (!(memReq->isUncacheable() || memReq->isMmappedIpr())) {
+                 // Access memory to see if we have the same data
+                 dcachePort->sendFunctional(pkt);
+             } else {
+                 // Assume the data is correct if it's an uncached access
+                 memcpy(data, unverifiedMemData, size);
+             }
+             delete memReq;
+             memReq = NULL;
+             delete pkt;
+         }
  
-     // translate to physical address
-     dtb->translateAtomic(memReq, tc, false);
+         if (fault != NoFault) {
+             if (memReq->isPrefetch()) {
+                 fault = NoFault;
+             }
+             delete memReq;
+             memReq = NULL;
+             break;
+         }
  
-     PacketPtr pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
+         if (memReq != NULL) {
+             delete memReq;
+         }
  
-     pkt->dataStatic(&data);
+         //If we don't need to access a second cache line, stop now.
+         if (secondAddr <= addr)
+         {
+             break;
+         }
  
-     if (!(memReq->isUncacheable())) {
-         // Access memory to see if we have the same data
-         dcachePort->sendFunctional(pkt);
-     } else {
-         // Assume the data is correct if it's an uncached access
-         memcpy(&data, &unverifiedResult.integer, sizeof(T));
+         // Setup for accessing next cache line
+         data += size;
+         unverifiedMemData += size;
+         size = addr + fullSize - secondAddr;
+         addr = secondAddr;
      }
  
-     delete pkt;
+     if (!flags_match) {
+         warn("%lli: Flags do not match CPU:%#x %#x %#x Checker:%#x %#x %#x\n",
+              curTick(), unverifiedReq->getVaddr(), unverifiedReq->getPaddr(),
+              unverifiedReq->getFlags(), addr, pAddr, flags);
+         handleError();
+     }
  
-     return NoFault;
+     return fault;
  }
  
- #ifndef DOXYGEN_SHOULD_SKIP_THIS
- template
- Fault
- CheckerCPU::read(Addr addr, uint64_t &data, unsigned flags);
- template
- Fault
- CheckerCPU::read(Addr addr, uint32_t &data, unsigned flags);
- template
  Fault
- CheckerCPU::read(Addr addr, uint16_t &data, unsigned flags);
- template
- Fault
- CheckerCPU::read(Addr addr, uint8_t &data, unsigned flags);
- #endif //DOXYGEN_SHOULD_SKIP_THIS
- template<>
- Fault
- CheckerCPU::read(Addr addr, double &data, unsigned flags)
+ CheckerCPU::writeMem(uint8_t *data, unsigned size,
+                      Addr addr, unsigned flags, uint64_t *res)
  {
-     return read(addr, *(uint64_t*)&data, flags);
- }
+     Fault fault = NoFault;
+     bool checked_flags = false;
+     bool flags_match = true;
+     Addr pAddr = 0x0;
  
- template<>
- Fault
- CheckerCPU::read(Addr addr, float &data, unsigned flags)
- {
-     return read(addr, *(uint32_t*)&data, flags);
- }
+     unsigned blockSize = dcachePort->peerBlockSize();
+     int fullSize = size;
  
- template<>
- Fault
- CheckerCPU::read(Addr addr, int32_t &data, unsigned flags)
- {
-     return read(addr, (uint32_t&)data, flags);
- }
+     Addr secondAddr = roundDown(addr + size - 1, blockSize);
  
- template <class T>
- Fault
- CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
- {
-     // need to fill in CPU & thread IDs here
-     memReq = new Request();
-     memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC());
-     // translate to physical address
-     dtb->translateAtomic(memReq, tc, true);
-     // Can compare the write data and result only if it's cacheable,
-     // not a store conditional, or is a store conditional that
-     // succeeded.
-     // @todo: Verify that actual memory matches up with these values.
-     // Right now it only verifies that the instruction data is the
-     // same as what was in the request that got sent to memory; there
-     // is no verification that it is the same as what is in memory.
-     // This is because the LSQ would have to be snooped in the CPU to
-     // verify this data.
-     if (unverifiedReq &&
-         !(unverifiedReq->isUncacheable()) &&
-         (!(unverifiedReq->isLLSC()) ||
-          ((unverifiedReq->isLLSC()) &&
-           unverifiedReq->getExtraData() == 1))) {
-         T inst_data;
- /*
-         // This code would work if the LSQ allowed for snooping.
-         PacketPtr pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
-         pkt.dataStatic(&inst_data);
+     if (secondAddr > addr)
+         size = secondAddr - addr;
  
-         dcachePort->sendFunctional(pkt);
+     // Need to account for a multiple access like Atomic and Timing CPUs
+     while (1) {
+         memReq = new Request();
+         memReq->setVirt(0, addr, size, flags, thread->pcState().instAddr());
  
-         delete pkt;
- */
-         memcpy(&inst_data, unverifiedMemData, sizeof(T));
+         // translate to physical address
+         fault = dtb->translateFunctional(memReq, tc, BaseTLB::Write);
  
-         if (data != inst_data) {
-             warn("%lli: Store value does not match value in memory! "
-                  "Instruction: %#x, memory: %#x",
-                  curTick(), inst_data, data);
-             handleError();
+         if (!checked_flags && fault == NoFault && unverifiedReq) {
+            flags_match = checkFlags(unverifiedReq, memReq->getVaddr(),
+                                     memReq->getPaddr(), memReq->getFlags());
+            pAddr = memReq->getPaddr();
+            checked_flags = true;
          }
-     }
-     // Assume the result was the same as the one passed in.  This checker
-     // doesn't check if the SC should succeed or fail, it just checks the
-     // value.
-     if (res && unverifiedReq->scResultValid())
-         *res = unverifiedReq->getExtraData();
-     return NoFault;
- }
- #ifndef DOXYGEN_SHOULD_SKIP_THIS
- template
- Fault
- CheckerCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res);
- template
- Fault
- CheckerCPU::write(uint32_t data, Addr addr, unsigned flags, uint64_t *res);
- template
- Fault
- CheckerCPU::write(uint16_t data, Addr addr, unsigned flags, uint64_t *res);
- template
- Fault
- CheckerCPU::write(uint8_t data, Addr addr, unsigned flags, uint64_t *res);
- #endif //DOXYGEN_SHOULD_SKIP_THIS
  
- template<>
- Fault
- CheckerCPU::write(double data, Addr addr, unsigned flags, uint64_t *res)
- {
-     return write(*(uint64_t*)&data, addr, flags, res);
- }
- template<>
- Fault
- CheckerCPU::write(float data, Addr addr, unsigned flags, uint64_t *res)
- {
-     return write(*(uint32_t*)&data, addr, flags, res);
- }
+         /*
+          * We don't actually check memory for the store because there
+          * is no guarantee it has left the lsq yet, and therefore we
+          * can't verify the memory on stores without lsq snooping
+          * enabled.  This is left as future work for the Checker: LSQ snooping
+          * and memory validation after stores have committed.
+          */
+         delete memReq;
+         //If we don't need to access a second cache line, stop now.
+         if (fault != NoFault || secondAddr <= addr)
+         {
+             if (fault != NoFault && memReq->isPrefetch()) {
+               fault = NoFault;
+             }
+             break;
+         }
  
- template<>
- Fault
- CheckerCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
- {
-     return write((uint32_t)data, addr, flags, res);
+         //Update size and access address
+         size = addr + fullSize - secondAddr;
+         //And access the right address.
+         addr = secondAddr;
+    }
+    if (!flags_match) {
+        warn("%lli: Flags do not match CPU:%#x %#x Checker:%#x %#x %#x\n",
+             curTick(), unverifiedReq->getVaddr(), unverifiedReq->getPaddr(),
+             unverifiedReq->getFlags(), addr, pAddr, flags);
+        handleError();
+    }
+    // Assume the result was the same as the one passed in.  This checker
+    // doesn't check if the SC should succeed or fail, it just checks the
+    // value.
+    if (unverifiedReq && res && unverifiedReq->extraDataValid())
+        *res = unverifiedReq->getExtraData();
+    // Entire purpose here is to make sure we are getting the
+    // same data to send to the mem system as the CPU did.
+    // Cannot check this is actually what went to memory because
+    // there stores can be in ld/st queue or coherent operations
+    // overwriting values.
+    bool extraData;
+    if (unverifiedReq) {
+        extraData = unverifiedReq->extraDataValid() ?
+                         unverifiedReq->getExtraData() : 1;
+    }
+    if (unverifiedReq && unverifiedMemData &&
+        memcmp(data, unverifiedMemData, fullSize) && extraData) {
+            warn("%lli: Store value does not match value sent to memory!\
+                   data: %#x inst_data: %#x", curTick(), data,
+                   unverifiedMemData);
+        handleError();
+    }
+    return fault;
  }
  
 -#if FULL_SYSTEM
  Addr
  CheckerCPU::dbg_vtophys(Addr addr)
  {
      return vtophys(tc, addr);
  }
 -#endif // FULL_SYSTEM
  
+ /**
+  * Checks if the flags set by the Checker and Checkee match.
+  */
  bool
- CheckerCPU::checkFlags(Request *req)
+ CheckerCPU::checkFlags(Request *unverified_req, Addr vAddr,
+                        Addr pAddr, int flags)
  {
-     // Remove any dynamic flags that don't have to do with the request itself.
-     unsigned flags = unverifiedReq->getFlags();
-     unsigned mask = LOCKED | PHYSICAL | VPTE | ALTMODE | UNCACHEABLE | PREFETCH;
-     flags = flags & (mask);
-     if (flags == req->getFlags()) {
+     Addr unverifiedVAddr = unverified_req->getVaddr();
+     Addr unverifiedPAddr = unverified_req->getPaddr();
+     int unverifiedFlags = unverified_req->getFlags();
+     if (unverifiedVAddr != vAddr ||
+         unverifiedPAddr != pAddr ||
+         unverifiedFlags != flags) {
          return false;
-     } else {
-         return true;
      }
+     return true;
  }
  
  void
index a3e95137dc5480285bc0ed12931d5bc5d5643dc6,1419051a62846b911a31ec59c232237c6eff3405..6f5125625b4db35596222691b50a57c54badd21d
  #include <map>
  #include <queue>
  
+ #include "arch/predecoder.hh"
  #include "arch/types.hh"
  #include "base/statistics.hh"
 -#include "config/full_system.hh"
  #include "cpu/base.hh"
  #include "cpu/base_dyn_inst.hh"
  #include "cpu/pc_event.hh"
@@@ -49,16 -66,19 +64,10 @@@ namespace TheIS
  {
      class TLB;
  }
 -class Processor;
 -class PhysicalMemory;
  
 -#else
 -
 -class Process;
 -
 -#endif // FULL_SYSTEM
  template <class>
  class BaseDynInst;
- class CheckerCPUParams;
- class Checkpoint;
- class MemInterface;
- class PhysicalMemory;
- class Process;
- class Processor;
  class ThreadContext;
 -class MemInterface;
 -class Checkpoint;
  class Request;
  
  /**
@@@ -265,8 -328,19 +315,17 @@@ class CheckerCPU : public BaseCP
          this->dtb->demapPage(vaddr, asn);
      }
  
 -#if FULL_SYSTEM
+     Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags);
+     Fault writeMem(uint8_t *data, unsigned size,
+                    Addr addr, unsigned flags, uint64_t *res);
+     void setStCondFailures(unsigned sc_failures)
+     {}
+     /////////////////////////////////////////////////////
      Fault hwrei() { return thread->hwrei(); }
      bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
 -#else
+     void wakeup() { }
      // Assume that the normal CPU's call to syscall was successful.
      // The checker's state would have already been updated by the syscall.
      void syscall(uint64_t callnum) { }
index 7d8cc8a1944d31615aaef388d7c33342ac368a5e,8c8789cb6b679fa7886349a8e79f76ba37376459..7a99feb06beb870c35b54d41adb7f8ac2a2608fe
  #include <list>
  #include <string>
  
 +#include "arch/vtophys.hh"
  #include "base/refcnt.hh"
  #include "config/the_isa.hh"
- #include "cpu/checker/cpu.hh"
  #include "cpu/base_dyn_inst.hh"
+ #include "cpu/exetrace.hh"
  #include "cpu/simple_thread.hh"
  #include "cpu/static_inst.hh"
  #include "cpu/thread_context.hh"
+ #include "cpu/checker/cpu.hh"
+ #include "debug/Checker.hh"
 +#include "sim/full_system.hh"
  #include "sim/sim_object.hh"
  #include "sim/stats.hh"
  
 -#if FULL_SYSTEM
 -#include "arch/vtophys.hh"
 -#endif // FULL_SYSTEM
 -
  using namespace std;
- //The CheckerCPU does alpha only
- using namespace AlphaISA;
+ using namespace TheISA;
+ template <class Impl>
+ void
+ Checker<Impl>::advancePC(Fault fault)
+ {
+     if (fault != NoFault) {
+         curMacroStaticInst = StaticInst::nullStaticInstPtr;
+         fault->invoke(tc, curStaticInst);
+         predecoder.reset();
+     } else {
+         if (curStaticInst) {
+             if (curStaticInst->isLastMicroop())
+                 curMacroStaticInst = StaticInst::nullStaticInstPtr;
+             TheISA::PCState pcState = thread->pcState();
+             TheISA::advancePC(pcState, curStaticInst);
+             thread->pcState(pcState);
+             DPRINTF(Checker, "Advancing PC to %s.\n", thread->pcState());
+         }
+     }
+ }
+ //////////////////////////////////////////////////
+ template <class Impl>
+ void
+ Checker<Impl>::handlePendingInt()
+ {
+     DPRINTF(Checker, "IRQ detected at PC: %s with %d insts in buffer\n",
+                      thread->pcState(), instList.size());
+     DynInstPtr boundaryInst = NULL;
+     if (!instList.empty()) {
+         // Set the instructions as completed and verify as much as possible.
+         DynInstPtr inst;
+         typename std::list<DynInstPtr>::iterator itr;
+         for (itr = instList.begin(); itr != instList.end(); itr++) {
+             (*itr)->setCompleted();
+         }
+         inst = instList.front();
+         boundaryInst = instList.back();
+         verify(inst); // verify the instructions
+         inst = NULL;
+     }
+     if ((!boundaryInst && curMacroStaticInst &&
+           curStaticInst->isDelayedCommit() &&
+           !curStaticInst->isLastMicroop()) ||
+         (boundaryInst && boundaryInst->isDelayedCommit() &&
+          !boundaryInst->isLastMicroop())) {
+         panic("%lli: Trying to take an interrupt in middle of "
+               "a non-interuptable instruction!", curTick());
+     }
+     boundaryInst = NULL;
+     predecoder.reset();
+     curMacroStaticInst = StaticInst::nullStaticInstPtr;
+ }
  
- template <class DynInstPtr>
+ template <class Impl>
  void
- Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
+ Checker<Impl>::verify(DynInstPtr &completed_inst)
  {
      DynInstPtr inst;
  
              }
          }
  
+         // Take any faults here
          if (fault != NoFault) {
 -#if FULL_SYSTEM
              fault->invoke(tc, curStaticInst);
              willChangePC = true;
-             newPC = thread->readPC();
-             DPRINTF(Checker, "Fault, PC is now %#x\n", newPC);
+             newPCState = thread->pcState();
+             DPRINTF(Checker, "Fault, PC is now %s\n", newPCState);
+             curMacroStaticInst = StaticInst::nullStaticInstPtr;
 -#endif
          } else {
- #if THE_ISA != MIPS_ISA
-             // go to the next instruction
-             thread->setPC(thread->readNextPC());
-             thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
- #else
-             // go to the next instruction
-             thread->setPC(thread->readNextPC());
-             thread->setNextPC(thread->readNextNPC());
-             thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
- #endif
+            advancePC(fault);
          }
  
 -#if FULL_SYSTEM
 -        // @todo: Determine if these should happen only if the
 -        // instruction hasn't faulted.  In the SimpleCPU case this may
 -        // not be true, but in the O3 or Ozone case this may be true.
 -        Addr oldpc;
 -        int count = 0;
 -        do {
 -            oldpc = thread->instAddr();
 -            system->pcEventQueue.service(tc);
 -            count++;
 -        } while (oldpc != thread->instAddr());
 -        if (count > 1) {
 -            willChangePC = true;
 -            newPCState = thread->pcState();
 -            DPRINTF(Checker, "PC Event, PC is now %s\n", newPCState);
 +        if (FullSystem) {
 +            // @todo: Determine if these should happen only if the
 +            // instruction hasn't faulted.  In the SimpleCPU case this may
 +            // not be true, but in the O3 or Ozone case this may be true.
 +            Addr oldpc;
 +            int count = 0;
 +            do {
-                 oldpc = thread->readPC();
++                oldpc = thread->instAddr();
 +                system->pcEventQueue.service(tc);
 +                count++;
-             } while (oldpc != thread->readPC());
++            } while (oldpc != thread->instAddr());
 +            if (count > 1) {
 +                willChangePC = true;
-                 newPC = thread->readPC();
-                 DPRINTF(Checker, "PC Event, PC is now %#x\n", newPC);
++                newPCState = thread->pcState();
++                DPRINTF(Checker, "PC Event, PC is now %s\n", newPCState);
 +            }
          }
 -#endif
  
          // @todo:  Optionally can check all registers. (Or just those
          // that have been modified).
index 178ded80e3906d3aab44df6cbff39bfe025703c6,d66854b23cba3e2a1527a26f5652ac745ba16025..d21de9f539af91316120c75cc6f4671b25d16831
@@@ -89,8 -112,13 +112,12 @@@ class CheckerThreadContext : public Thr
  
      TheISA::TLB *getDTBPtr() { return actualTC->getDTBPtr(); }
  
+     BaseCPU *getCheckerCpuPtr() { return checkerTC->getCpuPtr(); }
+     Decoder *getDecoderPtr() { return actualTC->getDecoderPtr(); }
      System *getSystemPtr() { return actualTC->getSystemPtr(); }
  
 -#if FULL_SYSTEM
      PhysicalMemory *getPhysMemPtr() { return actualTC->getPhysMemPtr(); }
  
      TheISA::Kernel::Statistics *getKernelStats()
      FSTranslatingPortProxy* getVirtProxy()
      { return actualTC->getVirtProxy(); }
  
 -#else
 -    SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
+     //XXX: How does this work now?
+     void initMemProxies(ThreadContext *tc)
+     { actualTC->initMemProxies(tc); }
+     void connectMemPorts(ThreadContext *tc)
+     {
+         actualTC->connectMemPorts(tc);
+     }
 -    Process *getProcessPtr() { return actualTC->getProcessPtr(); }
 +    SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
  
 -#endif
+     /** Executes a syscall in SE mode. */
+     void syscall(int64_t callnum)
+     { return actualTC->syscall(callnum); }
      Status status() const { return actualTC->status(); }
  
      void setStatus(Status new_status)
      void activate(int delay = 1) { actualTC->activate(delay); }
  
      /// Set the status to Suspended.
-     void suspend() { actualTC->suspend(); }
+     void suspend(int delay) { actualTC->suspend(delay); }
  
      /// Set the status to Halted.
-     void halt() { actualTC->halt(); }
+     void halt(int delay) { actualTC->halt(delay); }
  
 -#if FULL_SYSTEM
      void dumpFuncProfile() { actualTC->dumpFuncProfile(); }
 -#endif
  
      void takeOverFrom(ThreadContext *oldContext)
      {
  
      void profileClear() { return actualTC->profileClear(); }
      void profileSample() { return actualTC->profileSample(); }
 -#endif
  
-     int threadId() { return actualTC->threadId(); }
      // @todo: Do I need this?
      void copyArchRegs(ThreadContext *tc)
      {
index 0000000000000000000000000000000000000000,28f0609314ad1d92e7867f067c7892bb32042a2f..0c83dabd0d4ae1e2b6114ce303bbaf575dfca031
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,100 +1,97 @@@
 -#if FULL_SYSTEM
+ /*
+  * Copyright (c) 2011 ARM Limited
+  * All rights reserved
+  *
+  * The license below extends only to copyright in the software and shall
+  * not be construed as granting a license to any other intellectual
+  * property including but not limited to intellectual property relating
+  * to a hardware implementation of the functionality of the software
+  * licensed hereunder.  You may use the software subject to the license
+  * terms below provided that you ensure that this notice is replicated
+  * unmodified and in its entirety in all distributions of the software,
+  * modified or unmodified, in source code or in binary form.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions are
+  * met: redistributions of source code must retain the above copyright
+  * notice, this list of conditions and the following disclaimer;
+  * redistributions in binary form must reproduce the above copyright
+  * notice, this list of conditions and the following disclaimer in the
+  * documentation and/or other materials provided with the distribution;
+  * neither the name of the copyright holders nor the names of its
+  * contributors may be used to endorse or promote products derived from
+  * this software without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  * Authors: Geoffrey Blake
+  */
+ #include <string>
+ #include "cpu/checker/cpu.hh"
+ #include "cpu/inst_seq.hh"
+ #include "params/DummyChecker.hh"
+ #include "sim/process.hh"
+ #include "sim/sim_object.hh"
+ class MemObject;
+ /**
+  * Specific non-templated derived class used for SimObject configuration.
+  */
+ class DummyChecker : public CheckerCPU
+ {
+   public:
+     DummyChecker(Params *p)
+           : CheckerCPU(p)
+     { }
+ };
+ ////////////////////////////////////////////////////////////////////////
+ //
+ //  DummyChecker Simulation Object
+ //
+ DummyChecker *
+ DummyCheckerParams::create()
+ {
+     DummyChecker::Params *params = new DummyChecker::Params();
+     params->name = name;
+     params->numThreads = numThreads;
+     params->max_insts_any_thread = 0;
+     params->max_insts_all_threads = 0;
+     params->max_loads_any_thread = 0;
+     params->max_loads_all_threads = 0;
+     params->clock = clock;
+     // Hack to touch all parameters.  Consider not deriving Checker
+     // from BaseCPU..it's not really a CPU in the end.
+     Counter temp;
+     temp = max_insts_any_thread;
+     temp = max_insts_all_threads;
+     temp = max_loads_any_thread;
+     temp = max_loads_all_threads;
+     Tick temp2 = progress_interval;
+     params->progress_interval = 0;
+     temp2++;
+     params->itb = itb;
+     params->dtb = dtb;
+     params->system = system;
+     params->cpu_id = cpu_id;
 -#else
+     params->profile = profile;
+     params->interrupts = NULL;
 -#endif
+     params->workload = workload;
+     DummyChecker *cpu = new DummyChecker(params);
+     return cpu;
+ }
Simple merge
Simple merge
Simple merge
index c3e561cd9671202812e65cf5b895db040834429a,edce7d8c791446c3f2682432a0bba13ca2617a03..acc7a90561280a5ed559a612772aeeff18a83b65
@@@ -40,11 -40,21 +40,15 @@@ class DerivO3CPU(BaseCPU)
      activity = Param.Unsigned(0, "Initial count")
  
      if buildEnv['USE_CHECKER']:
-         checker = Param.BaseCPU(O3Checker(workload=Parent.workload,
 -        if not buildEnv['FULL_SYSTEM']:
 -            # FIXME: Shouldn't need to derefernce Parent.workload
 -            #        Somewhere in the param parsing code
 -            #        src/python/m5/params.py is and error that
 -            #        has trouble converting the workload parameter properly.
 -            checker = Param.BaseCPU(O3Checker(workload=Parent.workload[0],
 -                                              exitOnError=False,
 -                                              updateOnError=True,
 -                                              warnOnlyOnLoadError=True),
 -                                              "checker")
 -        else:
 -            checker = Param.BaseCPU(O3Checker(exitOnError=False,
 -                                              updateOnError=True,
 -                                              warnOnlyOnLoadError=True),
 -                                              "checker")
++        # FIXME: Shouldn't need to derefernce Parent.workload
++        #        Somewhere in the param parsing code
++        #        src/python/m5/params.py is and error that
++        #        has trouble converting the workload parameter properly.
++        checker = Param.BaseCPU(O3Checker(workload=Parent.workload[0],
 +                                          exitOnError=False,
 +                                          updateOnError=True,
-                                           warnOnlyOnLoadError=False),
-                                 "checker")
++                                          warnOnlyOnLoadError=True),
++                                          "checker")
          checker.itb = Parent.itb
          checker.dtb = Parent.dtb
  
index b34613f6825524dfe0bfcbaf10bc744873d264ee,73e8b516226dc231f54ed8c829a2af367f1f8704..72b50d1049df14cc3d5d53b520959026936a9144
@@@ -90,8 -100,12 +100,9 @@@ O3CheckerParams::create(
      params->dtb = dtb;
      params->system = system;
      params->cpu_id = cpu_id;
 -#if FULL_SYSTEM
      params->profile = profile;
-     params->process = workload;
+     params->interrupts = NULL;
 -#else
+     params->workload = workload;
 -#endif
  
      O3Checker *cpu = new O3Checker(params);
      return cpu;
Simple merge
index b6a4c03870c3f12b444821219822c1934f73a772,cb2f9a634dbb4be75e802e0ad694af8a238a7f02..edf7e861b3b5b42ec96ad6f2965a3055ca09e837
@@@ -768,16 -779,17 +774,16 @@@ template <class Impl
  void
  DefaultCommit<Impl>::commit()
  {
 -
 -#if FULL_SYSTEM
 -    // Check for any interrupt that we've already squashed for and
 -    // start processing it.
 -    if (interrupt != NoFault)
 -        handleInterrupt();
 -
 -    // Check if we have a interrupt and get read to handle it
 -    if (cpu->checkInterrupts(cpu->tcBase(0)))
 -        propagateInterrupt();
 -#endif // FULL_SYSTEM
 +    if (FullSystem) {
-         // Check for any interrupt that we've already squashed for and start
-         // processing it.
++        // Check for any interrupt that we've already squashed for and
++        // start processing it.
 +        if (interrupt != NoFault)
 +            handleInterrupt();
 +
 +        // Check if we have a interrupt and get read to handle it
 +        if (cpu->checkInterrupts(cpu->tcBase(0)))
 +            propagateInterrupt();
 +    }
  
      ////////////////////////////////////
      // Check for any possible squashes, handle them first
index ef08c96f436ebb5e6d01551861c6cd6c66f4f7e2,cede7ae184b240bb244df126a1a1f3f35099ae50..d162709439dc2efc28d62a94e63888f6f48d5827
  #include "sim/stat_control.hh"
  #include "sim/system.hh"
  
 -#if FULL_SYSTEM
 -#include "cpu/quiesce_event.hh"
 -#else
 -#include "sim/process.hh"
 -#endif
 -
  #if USE_CHECKER
  #include "cpu/checker/cpu.hh"
+ #include "cpu/checker/thread_context.hh"
  #endif
  
  #if THE_ISA == ALPHA_ISA
@@@ -265,9 -269,11 +266,9 @@@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUPa
  #if USE_CHECKER
      if (params->checker) {
          BaseCPU *temp_checker = params->checker;
-         checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
+         checker = dynamic_cast<Checker<Impl> *>(temp_checker);
          checker->setIcachePort(&icachePort);
 -#if FULL_SYSTEM
          checker->setSystem(params->system);
 -#endif
      } else {
          checker = NULL;
      }
Simple merge
index 985e928260c0261be098efbf1a6c771a0c0bc509,7fa25106aa64d8a8c1ea3c67d05535fd5b650a7a..60bca1041bdfaf77832b9d4ee2ec7c00e37f65b7
  #include "debug/Activity.hh"
  #include "debug/Decode.hh"
  #include "params/DerivO3CPU.hh"
 +#include "sim/full_system.hh"
  
- using namespace std;
+ // clang complains about std::set being overloaded with Packet::set if
+ // we open up the entire namespace std
+ using std::list;
  
  template<class Impl>
  DefaultDecode<Impl>::DefaultDecode(O3CPU *_cpu, DerivO3CPUParams *params)
index 76a456ee3f27cb6d42211bd1eb33266d231d13af,8a01b2575bf0500a814b0905cd0797cc07422899..ed1e374e8a1920cb364c2392ce96558c5d6d42f4
@@@ -41,8 -41,8 +41,9 @@@
   */
  
  #include "base/cp_annotate.hh"
+ #include "config/use_checker.hh"
  #include "cpu/o3/dyn_inst.hh"
 +#include "sim/full_system.hh"
  
  template <class Impl>
  BaseO3DynInst<Impl>::BaseO3DynInst(StaticInstPtr staticInst,
index 1b82f8a4c995455a117b35becd5716c0ae463e70,463509cf178cc599ff5385a256aa0773471d21b6..553198980545601122d24172389b7a0efc11f9be
  
  #include <algorithm>
  #include <cstring>
+ #include <list>
+ #include <map>
+ #include <queue>
  
  #include "arch/isa_traits.hh"
 +#include "arch/tlb.hh"
  #include "arch/utility.hh"
 +#include "arch/vtophys.hh"
  #include "base/types.hh"
  #include "config/the_isa.hh"
  #include "config/use_checker.hh"
  #include "sim/byteswap.hh"
  #include "sim/core.hh"
  #include "sim/eventq.hh"
 -
 -#if FULL_SYSTEM
 -#include "arch/tlb.hh"
 -#include "arch/vtophys.hh"
 +#include "sim/full_system.hh"
  #include "sim/system.hh"
 -#endif // FULL_SYSTEM
  
+ #if USE_CHECKER
+ #include "cpu/checker/cpu.hh"
+ #endif // USE_CHECKER
  using namespace std;
  
  template<class Impl>
Simple merge
Simple merge
Simple merge
Simple merge
index 5ba4544584b9b942298d0583df9935b20e228f4f,5a412c1618267e4c608507c3604ab625bd79f608..2ea39f3eb6044f022a7b668fdccc204704bae0ca
   *          Korey Sewell
   */
  
 +#include "arch/kernel_stats.hh"
  #include "arch/registers.hh"
  #include "config/the_isa.hh"
+ #include "config/use_checker.hh"
  #include "cpu/o3/thread_context.hh"
  #include "cpu/quiesce_event.hh"
  #include "debug/O3CPU.hh"
Simple merge
index 610cc6b89b54337d59a99037dacdc226f9492f85,e56dc0fbb89b8610af099b008f2f53e852e4985c..97ce3264a2bbbf743e6b28a7dbb25e924ef843ff
  #include "sim/stats.hh"
  #include "sim/system.hh"
  
 -#if FULL_SYSTEM
 -#include "arch/kernel_stats.hh"
 -#include "arch/stacktrace.hh"
 -#include "arch/tlb.hh"
 -#include "arch/vtophys.hh"
 -#else // !FULL_SYSTEM
 -#include "mem/mem_object.hh"
 -#endif // FULL_SYSTEM
 -
+ #if USE_CHECKER
+ #include "cpu/checker/cpu.hh"
+ #include "cpu/checker/thread_context.hh"
+ #endif
  using namespace std;
  using namespace TheISA;
  
@@@ -95,6 -105,21 +101,19 @@@ BaseSimpleCPU::BaseSimpleCPU(BaseSimple
  
      tc = thread->getTC();
  
 -#if FULL_SYSTEM
+ #if USE_CHECKER
+     if (p->checker) {
+         BaseCPU *temp_checker = p->checker;
+         checker = dynamic_cast<CheckerCPU *>(temp_checker);
 -#endif
+         checker->setSystem(p->system);
+         // Manipulate thread context
+         ThreadContext *cpu_tc = tc;
+         tc = new CheckerThreadContext<ThreadContext>(cpu_tc, this->checker);
+     } else {
+         checker = NULL;
+     }
+ #endif
      numInst = 0;
      startNumInst = 0;
      numLoad = 0;
index 0e5526040c31c2390a5f3cdac44239feeb146e6c,3535539d0de5a9c542a5b9e35fecb1e6c6371249..55dec5d53a5ecb3979eef8d1e4b1430d42b3edf4
@@@ -35,7 -47,9 +47,8 @@@
  
  #include "arch/predecoder.hh"
  #include "base/statistics.hh"
 -#include "config/full_system.hh"
  #include "config/the_isa.hh"
+ #include "config/use_checker.hh"
  #include "cpu/base.hh"
  #include "cpu/decode.hh"
  #include "cpu/pc_event.hh"
  #include "mem/port.hh"
  #include "mem/request.hh"
  #include "sim/eventq.hh"
 +#include "sim/full_system.hh"
  #include "sim/system.hh"
  
+ #if USE_CHECKER
+ #include "cpu/checker/cpu.hh"
+ #endif
  // forward declarations
 -#if FULL_SYSTEM
 -class Processor;
 -namespace TheISA
 -{
 -    class ITB;
 -    class DTB;
 -}
 +class Checkpoint;
  class MemObject;
 -
 -#else
 -
  class Process;
 -
 -#endif // FULL_SYSTEM
 +class Processor;
 +class ThreadContext;
  
  namespace TheISA
  {
Simple merge
index a12ab8e8a09c37d17b71fb14c4d77c324939f950,8e7127269f69000733f941cb7785649bd971ba3f..e193b127323e5dee9854c973e9761c4b1b055a9b
  #include "base/cprintf.hh"
  #include "base/output.hh"
  #include "base/trace.hh"
 +#include "config/the_isa.hh"
 +#include "cpu/base.hh"
  #include "cpu/profile.hh"
  #include "cpu/quiesce_event.hh"
- #include "params/BaseCPU.hh"
 +#include "cpu/simple_thread.hh"
 +#include "cpu/thread_context.hh"
  #include "mem/fs_translating_port_proxy.hh"
 -#include "sim/serialize.hh"
 -#include "sim/sim_exit.hh"
 -#else
  #include "mem/se_translating_port_proxy.hh"
++#include "params/BaseCPU.hh"
 +#include "sim/full_system.hh"
  #include "sim/process.hh"
- #include "sim/process.hh"
 +#include "sim/serialize.hh"
 +#include "sim/sim_exit.hh"
  #include "sim/system.hh"
 -#endif
  
  using namespace std;
  
  // constructor
 -#if FULL_SYSTEM
 +SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process,
 +                           TheISA::TLB *_itb, TheISA::TLB *_dtb)
-     : ThreadState(_cpu, _thread_num, _process),
-       cpu(_cpu), itb(_itb), dtb(_dtb)
++    : ThreadState(_cpu, _thread_num, _process), itb(_itb), dtb(_dtb)
 +{
 +    clearArchRegs();
 +    tc = new ProxyThreadContext<SimpleThread>(this);
 +}
  SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
                             TheISA::TLB *_itb, TheISA::TLB *_dtb,
                             bool use_kernel_stats)
-     : ThreadState(_cpu, _thread_num, NULL),
-       cpu(_cpu), system(_sys), itb(_itb), dtb(_dtb)
 -    : ThreadState(_cpu, _thread_num),
 -      system(_sys), itb(_itb), dtb(_dtb)
--
++    : ThreadState(_cpu, _thread_num, NULL), system(_sys), itb(_itb), dtb(_dtb)
  {
      tc = new ProxyThreadContext<SimpleThread>(this);
  
@@@ -199,15 -212,18 +195,16 @@@ SimpleThread::unserialize(Checkpoint *c
      // 
      // Now must unserialize all the ISA dependent state
      //
-     isa.unserialize(cpu, cp, section);
+     isa.unserialize(baseCpu, cp, section);
  }
  
 -#if FULL_SYSTEM
  void
  SimpleThread::dumpFuncProfile()
  {
-     std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
+     std::ostream *os = simout.create(csprintf("profile.%s.dat",
+                                               baseCpu->name()));
      profile->dump(tc, *os);
  }
 -#endif
  
  void
  SimpleThread::activate(int delay)
@@@ -236,8 -252,17 +233,8 @@@ SimpleThread::suspend(
  
      lastActivate = curTick();
      lastSuspend = curTick();
 -/*
 -#if FULL_SYSTEM
 -    // Don't change the status from active if there are pending interrupts
 -    if (cpu->checkInterrupts()) {
 -        assert(status() == ThreadContext::Active);
 -        return;
 -    }
 -#endif
 -*/
      _status = ThreadContext::Suspended;
-     cpu->suspendContext(_threadId);
+     baseCpu->suspendContext(_threadId);
  }
  
  
index 97964c0e8c2f5262d68c73fee239546c26800d3c,46ed92ce8bd6cf539ad6397e5a92e91d2b854676..39cb96c3abf97e17670f80133e417a8729aaf5d0
@@@ -38,7 -50,9 +50,8 @@@
  #include "arch/tlb.hh"
  #include "arch/types.hh"
  #include "base/types.hh"
 -#include "config/full_system.hh"
  #include "config/the_isa.hh"
+ #include "config/use_checker.hh"
  #include "cpu/decode.hh"
  #include "cpu/thread_context.hh"
  #include "cpu/thread_state.hh"
index 261ace7cf950ee4f9d5c0f3e23efff4dd9d2fd9f,946c35249426f77951bebd149f12d1523c6eecf6..2f2e5b02b7a5febd70997d172bf3c258a7e6301d
@@@ -37,7 -49,9 +49,8 @@@
  #include "arch/registers.hh"
  #include "arch/types.hh"
  #include "base/types.hh"
 -#include "config/full_system.hh"
  #include "config/the_isa.hh"
+ #include "config/use_checker.hh"
  
  // @todo: Figure out a more architecture independent way to obtain the ITB and
  // DTB pointers.
index 30bb64ed7602bd559d788e2fb2ca11b4c94d2efe,f14daaeb8a1bf83119fe9deb6def399d367b52b3..3622ed37fff8a1d81771c9548dde2e1f8b7c4a2e
@@@ -62,9 -67,13 +62,9 @@@ class FSTranslatingPort
  struct ThreadState {
      typedef ThreadContext::Status Status;
  
 -#if FULL_SYSTEM
 -    ThreadState(BaseCPU *cpu, ThreadID _tid);
 -#else
      ThreadState(BaseCPU *cpu, ThreadID _tid, Process *_process);
 -#endif
  
-     ~ThreadState();
+     virtual ~ThreadState();
  
      void serialize(std::ostream &os);
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index b72fdca4a3f150b3e0cb80ef3d0e1b8ac58e6f52,4e6c46f8e99f9e3480c8738277fddd42609d3405..8a7f0c4696cbd92b8387f735e3a48a2248d72ded
  #include <fstream>
  #include <string>
  
 +#include "arch/kernel_stats.hh"
  #include "arch/vtophys.hh"
  #include "base/debug.hh"
 -#include "config/full_system.hh"
+ #include "base/output.hh"
  #include "config/the_isa.hh"
  #include "cpu/base.hh"
  #include "cpu/quiesce_event.hh"
@@@ -387,6 -359,50 +388,48 @@@ readfile(ThreadContext *tc, Addr vaddr
      return result;
  }
  
 -#endif
 -
+ uint64_t
+ writefile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset,
+             Addr filename_addr)
+ {
+     ostream *os;
+     // copy out target filename
+     char fn[100];
+     std::string filename;
+     CopyStringOut(tc, fn, filename_addr, 100);
+     filename = std::string(fn);
+     if (offset == 0) {
+         // create a new file (truncate)
+         os = simout.create(filename, true);
+     } else {
+         // do not truncate file if offset is non-zero
+         // (ios::in flag is required as well to keep the existing data
+         //  intact, otherwise existing data will be zeroed out.)
+         os = simout.openFile(simout.directory() + filename,
+                             ios::in | ios::out | ios::binary);
+     }
+     if (!os)
+         panic("could not open file %s\n", filename);
+     // seek to offset
+     os->seekp(offset);
+     // copy out data and write to file
+     char *buf = new char[len];
+     CopyOut(tc, buf, vaddr, len);
+     os->write(buf, len);
+     if (os->fail() || os->bad())
+         panic("Error while doing writefile!\n");
+     simout.close(os);
+     delete [] buf;
+     return len;
+ }
  void
  debugbreak(ThreadContext *tc)
  {
Simple merge
Simple merge