diff options
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/base.hh | 4 | ||||
-rw-r--r-- | src/cpu/base_dyn_inst.hh | 42 | ||||
-rw-r--r-- | src/cpu/base_dyn_inst_impl.hh | 1 | ||||
-rw-r--r-- | src/cpu/exetrace.cc | 32 | ||||
-rw-r--r-- | src/cpu/m5legion_interface.h | 28 | ||||
-rw-r--r-- | src/cpu/o3/alpha/cpu_builder.cc | 12 | ||||
-rw-r--r-- | src/cpu/o3/alpha/cpu_impl.hh | 2 | ||||
-rw-r--r-- | src/cpu/o3/fetch_impl.hh | 16 | ||||
-rw-r--r-- | src/cpu/o3/lsq_unit.hh | 9 | ||||
-rw-r--r-- | src/cpu/o3/lsq_unit_impl.hh | 40 | ||||
-rw-r--r-- | src/cpu/ozone/cpu_builder.cc | 10 | ||||
-rw-r--r-- | src/cpu/simple/atomic.cc | 10 | ||||
-rw-r--r-- | src/cpu/simple/timing.cc | 10 |
13 files changed, 164 insertions, 52 deletions
diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 9257778ef..788f77e3a 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -155,6 +155,10 @@ class BaseCPU : public MemObject int cpu_id; #if FULL_SYSTEM Tick profile; + + bool do_statistics_insts; + bool do_checkpoint_insts; + bool do_quiesce; #endif Tick progress_interval; BaseCPU *checker; diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index c68810954..4a4555566 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -206,6 +206,9 @@ class BaseDynInst : public FastAlloc, public RefCounted */ Result instResult; + /** Records changes to result? */ + bool recordResult; + /** PC of this instruction. */ Addr PC; @@ -263,6 +266,9 @@ class BaseDynInst : public FastAlloc, public RefCounted /** Dumps out contents of this BaseDynInst into given string. */ void dump(std::string &outstring); + /** Read this CPU's ID. */ + int readCpuId() { return cpu->readCpuId(); } + /** Returns the fault type. */ Fault getFault() { return fault; } @@ -402,37 +408,42 @@ class BaseDynInst : public FastAlloc, public RefCounted /** Records an integer register being set to a value. */ void setIntReg(const StaticInst *si, int idx, uint64_t val) { - instResult.integer = val; + if (recordResult) + instResult.integer = val; } /** Records an fp register being set to a value. */ void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) { - if (width == 32) - instResult.dbl = (double)val; - else if (width == 64) - instResult.dbl = val; - else - panic("Unsupported width!"); + if (recordResult) { + if (width == 32) + instResult.dbl = (double)val; + else if (width == 64) + instResult.dbl = val; + else + panic("Unsupported width!"); + } } /** Records an fp register being set to a value. */ void setFloatReg(const StaticInst *si, int idx, FloatReg val) { -// instResult.fp = val; - instResult.dbl = (double)val; + if (recordResult) + instResult.dbl = (double)val; } /** Records an fp register being set to an integer value. */ void setFloatRegBits(const StaticInst *si, int idx, uint64_t val, int width) { - instResult.integer = val; + if (recordResult) + instResult.integer = val; } /** Records an fp register being set to an integer value. */ void setFloatRegBits(const StaticInst *si, int idx, uint64_t val) { - instResult.integer = val; + if (recordResult) + instResult.integer = val; } /** Records that one of the source registers is ready. */ @@ -624,6 +635,15 @@ class BaseDynInst : public FastAlloc, public RefCounted /** Sets iterator for this instruction in the list of all insts. */ void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; } + + public: + /** Returns the number of consecutive store conditional failures. */ + unsigned readStCondFailures() + { return thread->storeCondFailures; } + + /** Sets the number of consecutive store conditional failures. */ + void setStCondFailures(unsigned sc_failures) + { thread->storeCondFailures = sc_failures; } }; template<class Impl> diff --git a/src/cpu/base_dyn_inst_impl.hh b/src/cpu/base_dyn_inst_impl.hh index d6cdff5c5..2f6859de2 100644 --- a/src/cpu/base_dyn_inst_impl.hh +++ b/src/cpu/base_dyn_inst_impl.hh @@ -97,6 +97,7 @@ BaseDynInst<Impl>::initVars() readyRegs = 0; instResult.integer = 0; + recordResult = true; status.reset(); diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index ef06e0699..113f0fe74 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -39,12 +39,17 @@ #include "arch/regfile.hh" #include "arch/utility.hh" #include "base/loader/symtab.hh" +#include "config/full_system.hh" #include "cpu/base.hh" #include "cpu/exetrace.hh" #include "cpu/static_inst.hh" #include "sim/param.hh" #include "sim/system.hh" +#if FULL_SYSTEM +#include "arch/tlb.hh" +#endif + //XXX This is temporary #include "arch/isa_specific.hh" #include "cpu/m5legion_interface.h" @@ -232,17 +237,22 @@ Trace::InstRecord::dump(ostream &outs) bool diffPC = false; bool diffInst = false; bool diffRegs = false; + Addr m5Pc, lgnPc; + if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) { while (!compared) { + m5Pc = PC & TheISA::PAddrImplMask; + lgnPc = shared_data->pc & TheISA::PAddrImplMask; if (shared_data->flags == OWN_M5) { - if (shared_data->pc != PC) + if (lgnPc != m5Pc) diffPC = true; if (shared_data->instruction != staticInst->machInst) diffInst = true; - for (int i = 0; i < TheISA::NumIntRegs; i++) { - if (thread->readIntReg(i) != shared_data->intregs[i]) + for (int i = 0; i < TheISA::NumRegularIntRegs; i++) { + if (thread->readIntReg(i) != shared_data->intregs[i]) { diffRegs = true; + } } if (diffPC || diffInst || diffRegs ) { @@ -253,19 +263,19 @@ Trace::InstRecord::dump(ostream &outs) outs << " [Instruction]"; if (diffRegs) outs << " [IntRegs]"; - outs << endl << endl;; + outs << endl << endl; - outs << setfill(' ') << setw(15) + outs << right << setfill(' ') << setw(15) << "M5 PC: " << "0x"<< setw(16) << setfill('0') - << hex << PC << endl; + << hex << m5Pc << endl; outs << setfill(' ') << setw(15) << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex - << shared_data->pc << endl << endl; + << lgnPc << endl << endl; outs << setfill(' ') << setw(15) << "M5 Inst: " << "0x"<< setw(8) << setfill('0') << hex << staticInst->machInst - << staticInst->disassemble(PC, debugSymbolTable) + << staticInst->disassemble(m5Pc, debugSymbolTable) << endl; StaticInstPtr legionInst = StaticInst::decode(makeExtMI(shared_data->instruction, thread)); @@ -273,7 +283,7 @@ Trace::InstRecord::dump(ostream &outs) << " Legion Inst: " << "0x" << setw(8) << setfill('0') << hex << shared_data->instruction - << legionInst->disassemble(shared_data->pc, debugSymbolTable) + << legionInst->disassemble(lgnPc, debugSymbolTable) << endl; outs << endl; @@ -386,7 +396,7 @@ Trace::InstRecord::setParams() // If were going to be in lockstep with Legion // Setup shared memory, and get otherwise ready if (flags[LEGION_LOCKSTEP]) { - int shmfd = shmget(getuid(), sizeof(SharedData), 0777); + int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777); if (shmfd < 0) fatal("Couldn't get shared memory fd. Is Legion running?"); @@ -401,6 +411,8 @@ Trace::InstRecord::setParams() fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION, shared_data->version); + // step legion forward one cycle so we can get register values + shared_data->flags = OWN_LEGION; } } diff --git a/src/cpu/m5legion_interface.h b/src/cpu/m5legion_interface.h index 9338d9ca0..373fbeb11 100644 --- a/src/cpu/m5legion_interface.h +++ b/src/cpu/m5legion_interface.h @@ -30,7 +30,7 @@ #include <unistd.h> -#define VERSION 0xA1000002 +#define VERSION 0xA1000005 #define OWN_M5 0x000000AA #define OWN_LEGION 0x00000055 @@ -41,9 +41,35 @@ typedef struct { uint32_t version; uint64_t pc; + uint64_t new_pc; uint32_t instruction; + uint32_t new_instruction; uint64_t intregs[32]; + uint64_t tpc[8]; + uint64_t tnpc[8]; + uint64_t tstate[8]; + uint16_t tt[8]; + uint64_t tba; + + uint64_t hpstate; + uint64_t htstate[8]; + uint64_t htba; + uint16_t pstate; + + uint64_t y; + uint8_t ccr; + uint8_t tl; + uint8_t gl; + uint8_t asi; + uint8_t pil; + + uint8_t cwp; + uint8_t cansave; + uint8_t canrestore; + uint8_t otherwin; + uint8_t cleanwin; + } SharedData; /** !!! ^^^ Increment VERSION on change ^^^ !!! **/ diff --git a/src/cpu/o3/alpha/cpu_builder.cc b/src/cpu/o3/alpha/cpu_builder.cc index be8ad8de6..09ccc7f65 100644 --- a/src/cpu/o3/alpha/cpu_builder.cc +++ b/src/cpu/o3/alpha/cpu_builder.cc @@ -57,6 +57,10 @@ Param<int> cpu_id; SimObjectParam<AlphaISA::ITB *> itb; SimObjectParam<AlphaISA::DTB *> dtb; Param<Tick> profile; + +Param<bool> do_quiesce; +Param<bool> do_checkpoint_insts; +Param<bool> do_statistics_insts; #else SimObjectVectorParam<Process *> workload; #endif // FULL_SYSTEM @@ -163,6 +167,10 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivO3CPU) INIT_PARAM(itb, "Instruction translation buffer"), INIT_PARAM(dtb, "Data translation buffer"), INIT_PARAM(profile, ""), + + INIT_PARAM(do_quiesce, ""), + INIT_PARAM(do_checkpoint_insts, ""), + INIT_PARAM(do_statistics_insts, ""), #else INIT_PARAM(workload, "Processes to run"), #endif // FULL_SYSTEM @@ -306,6 +314,10 @@ CREATE_SIM_OBJECT(DerivO3CPU) params->itb = itb; params->dtb = dtb; params->profile = profile; + + params->do_quiesce = do_quiesce; + params->do_checkpoint_insts = do_checkpoint_insts; + params->do_statistics_insts = do_statistics_insts; #else params->workload = workload; #endif // FULL_SYSTEM diff --git a/src/cpu/o3/alpha/cpu_impl.hh b/src/cpu/o3/alpha/cpu_impl.hh index f5c394826..b2ef78360 100644 --- a/src/cpu/o3/alpha/cpu_impl.hh +++ b/src/cpu/o3/alpha/cpu_impl.hh @@ -231,7 +231,7 @@ Fault AlphaO3CPU<Impl>::hwrei(unsigned tid) { // Need to clear the lock flag upon returning from an interrupt. - this->lockFlag = false; + this->setMiscReg(AlphaISA::MISCREG_LOCKFLAG, false, tid); this->thread[tid]->kernelStats->hwrei(); diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index b1fae8cf0..a5478d4f8 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -62,7 +62,8 @@ template<class Impl> void DefaultFetch<Impl>::IcachePort::recvFunctional(PacketPtr pkt) { - warn("Default fetch doesn't update it's state from a functional call."); + DPRINTF(Fetch, "DefaultFetch doesn't update its state from a " + "functional call."); } template<class Impl> @@ -79,6 +80,7 @@ template<class Impl> bool DefaultFetch<Impl>::IcachePort::recvTiming(PacketPtr pkt) { + DPRINTF(Fetch, "Received timing\n"); if (pkt->isResponse()) { fetch->processCacheCompletion(pkt); } @@ -1171,8 +1173,8 @@ DefaultFetch<Impl>::fetch(bool &status_change) fetch_PC = next_PC; if (instruction->isQuiesce()) { -// warn("%lli: Quiesce instruction encountered, halting fetch!", -// curTick); + DPRINTF(Fetch, "Quiesce instruction encountered, halting fetch!", + curTick); fetchStatus[tid] = QuiescePending; ++numInst; status_change = true; @@ -1286,11 +1288,13 @@ DefaultFetch<Impl>::fetch(bool &status_change) fetchStatus[tid] = TrapPending; status_change = true; - -// warn("%lli fault (%d) detected @ PC %08p", curTick, fault, PC[tid]); #else // !FULL_SYSTEM - warn("cycle %lli: fault (%s) detected @ PC %08p", curTick, fault->name(), PC[tid]); + fetchStatus[tid] = TrapPending; + status_change = true; + #endif // FULL_SYSTEM + DPRINTF(Fetch, "[tid:%i]: fault (%s) detected @ PC %08p", + tid, fault->name(), PC[tid]); } } diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh index 1b207fdbc..a2e11173e 100644 --- a/src/cpu/o3/lsq_unit.hh +++ b/src/cpu/o3/lsq_unit.hh @@ -37,6 +37,7 @@ #include <queue> #include "arch/faults.hh" +#include "arch/locked_mem.hh" #include "config/full_system.hh" #include "base/hashmap.hh" #include "cpu/inst_seq.hh" @@ -510,8 +511,12 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx) #if FULL_SYSTEM if (req->isLocked()) { - cpu->lockAddr = req->getPaddr(); - cpu->lockFlag = true; + // Disable recording the result temporarily. Writing to misc + // regs normally updates the result, but this is not the + // desired behavior when handling store conditionals. + load_inst->recordResult = false; + TheISA::handleLockedRead(load_inst.get(), req); + load_inst->recordResult = true; } #endif diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index 9a0e48819..4facea9f9 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -29,6 +29,7 @@ * Korey Sewell */ +#include "arch/locked_mem.hh" #include "config/use_checker.hh" #include "cpu/o3/lsq.hh" @@ -615,27 +616,24 @@ LSQUnit<Impl>::writebackStores() // @todo: Remove this SC hack once the memory system handles it. if (req->isLocked()) { - if (req->isUncacheable()) { - req->setScResult(2); - } else { - if (cpu->lockFlag) { - req->setScResult(1); - DPRINTF(LSQUnit, "Store conditional [sn:%lli] succeeded.", - inst->seqNum); - } else { - req->setScResult(0); - // Hack: Instantly complete this store. -// completeDataAccess(data_pkt); - DPRINTF(LSQUnit, "Store conditional [sn:%lli] failed. " - "Instantly completing it.\n", - inst->seqNum); - WritebackEvent *wb = new WritebackEvent(inst, data_pkt, this); - wb->schedule(curTick + 1); - delete state; - completeStore(storeWBIdx); - incrStIdx(storeWBIdx); - continue; - } + // Disable recording the result temporarily. Writing to + // misc regs normally updates the result, but this is not + // the desired behavior when handling store conditionals. + inst->recordResult = false; + bool success = TheISA::handleLockedWrite(inst.get(), req); + inst->recordResult = true; + + if (!success) { + // Instantly complete this store. + DPRINTF(LSQUnit, "Store conditional [sn:%lli] failed. " + "Instantly completing it.\n", + inst->seqNum); + WritebackEvent *wb = new WritebackEvent(inst, data_pkt, this); + wb->schedule(curTick + 1); + delete state; + completeStore(storeWBIdx); + incrStIdx(storeWBIdx); + continue; } } else { // Non-store conditionals do not need a writeback. diff --git a/src/cpu/ozone/cpu_builder.cc b/src/cpu/ozone/cpu_builder.cc index 39337dbff..155f0ce09 100644 --- a/src/cpu/ozone/cpu_builder.cc +++ b/src/cpu/ozone/cpu_builder.cc @@ -64,6 +64,10 @@ Param<int> cpu_id; SimObjectParam<TheISA::ITB *> itb; SimObjectParam<TheISA::DTB *> dtb; Param<Tick> profile; + +Param<bool> do_quiesce; +Param<bool> do_checkpoint_insts; +Param<bool> do_statistics_insts #else SimObjectVectorParam<Process *> workload; //SimObjectParam<PageTable *> page_table; @@ -184,6 +188,9 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivOzoneCPU) INIT_PARAM(itb, "Instruction translation buffer"), INIT_PARAM(dtb, "Data translation buffer"), INIT_PARAM(profile, ""), + INIT_PARAM(do_quiesce, ""), + INIT_PARAM(do_checkpoint_insts, ""), + INIT_PARAM(do_statistics_insts, ""), #else INIT_PARAM(workload, "Processes to run"), // INIT_PARAM(page_table, "Page table"), @@ -341,6 +348,9 @@ CREATE_SIM_OBJECT(DerivOzoneCPU) params->itb = itb; params->dtb = dtb; params->profile = profile; + params->do_quiesce = do_quiesce; + params->do_checkpoint_insts = do_checkpoint_insts; + params->do_statistics_insts = do_statistics_insts; #else params->workload = workload; // params->pTable = page_table; diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index f94ea0917..58dc1fe5f 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -503,6 +503,10 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AtomicSimpleCPU) SimObjectParam<TheISA::ITB *> itb; SimObjectParam<TheISA::DTB *> dtb; Param<Tick> profile; + + Param<bool> do_quiesce; + Param<bool> do_checkpoint_insts; + Param<bool> do_statistics_insts; #else SimObjectParam<Process *> workload; #endif // FULL_SYSTEM @@ -535,6 +539,9 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AtomicSimpleCPU) INIT_PARAM(itb, "Instruction TLB"), INIT_PARAM(dtb, "Data TLB"), INIT_PARAM(profile, ""), + INIT_PARAM(do_quiesce, ""), + INIT_PARAM(do_checkpoint_insts, ""), + INIT_PARAM(do_statistics_insts, ""), #else INIT_PARAM(workload, "processes to run"), #endif // FULL_SYSTEM @@ -572,6 +579,9 @@ CREATE_SIM_OBJECT(AtomicSimpleCPU) params->itb = itb; params->dtb = dtb; params->profile = profile; + params->do_quiesce = do_quiesce; + params->do_checkpoint_insts = do_checkpoint_insts; + params->do_statistics_insts = do_statistics_insts; #else params->process = workload; #endif diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index abf316095..db2c940c0 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -665,6 +665,10 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TimingSimpleCPU) SimObjectParam<TheISA::ITB *> itb; SimObjectParam<TheISA::DTB *> dtb; Param<Tick> profile; + + Param<bool> do_quiesce; + Param<bool> do_checkpoint_insts; + Param<bool> do_statistics_insts; #else SimObjectParam<Process *> workload; #endif // FULL_SYSTEM @@ -697,6 +701,9 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TimingSimpleCPU) INIT_PARAM(itb, "Instruction TLB"), INIT_PARAM(dtb, "Data TLB"), INIT_PARAM(profile, ""), + INIT_PARAM(do_quiesce, ""), + INIT_PARAM(do_checkpoint_insts, ""), + INIT_PARAM(do_statistics_insts, ""), #else INIT_PARAM(workload, "processes to run"), #endif // FULL_SYSTEM @@ -732,6 +739,9 @@ CREATE_SIM_OBJECT(TimingSimpleCPU) params->itb = itb; params->dtb = dtb; params->profile = profile; + params->do_quiesce = do_quiesce; + params->do_checkpoint_insts = do_checkpoint_insts; + params->do_statistics_insts = do_statistics_insts; #else params->process = workload; #endif |