Add in support for LL/SC in the O3 CPU. Needs to be fully tested.
src/cpu/base_dyn_inst.hh: Extend BaseDynInst a little bit so it can be use as a TC as well (specifically for ll/sc code). src/cpu/base_dyn_inst_impl.hh: Add variable to track if the result of the instruction should be recorded. src/cpu/o3/alpha/cpu_impl.hh: Clear lock flag upon hwrei. src/cpu/o3/lsq_unit.hh: Use ISA specified handling of locked reads. src/cpu/o3/lsq_unit_impl.hh: Use ISA specified handling of locked writes. --HG-- extra : convert_revision : 1f5c789c35deb4b016573c02af4aab60d726c0e5
This commit is contained in:
parent
75ecd3be60
commit
1926faac06
5 changed files with 59 additions and 35 deletions
|
@ -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,12 +408,14 @@ 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)
|
||||
{
|
||||
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 (recordResult) {
|
||||
if (width == 32)
|
||||
instResult.dbl = (double)val;
|
||||
else if (width == 64)
|
||||
|
@ -415,23 +423,26 @@ class BaseDynInst : public FastAlloc, public RefCounted
|
|||
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;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (recordResult)
|
||||
instResult.integer = val;
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
|
|
@ -97,6 +97,7 @@ BaseDynInst<Impl>::initVars()
|
|||
readyRegs = 0;
|
||||
|
||||
instResult.integer = 0;
|
||||
recordResult = true;
|
||||
|
||||
status.reset();
|
||||
|
||||
|
|
|
@ -260,7 +260,7 @@ Fault
|
|||
AlphaO3CPU<Impl>::hwrei(unsigned tid)
|
||||
{
|
||||
// Need to clear the lock flag upon returning from an interrupt.
|
||||
this->lockFlag = false;
|
||||
this->setMiscReg(TheISA::Lock_Flag_DepTag, false, tid);
|
||||
|
||||
this->thread[tid]->kernelStats->hwrei();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* Korey Sewell
|
||||
*/
|
||||
|
||||
#include "arch/locked_mem.hh"
|
||||
#include "config/use_checker.hh"
|
||||
|
||||
#include "cpu/o3/lsq.hh"
|
||||
|
@ -614,17 +615,15 @@ 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);
|
||||
// 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);
|
||||
|
@ -635,7 +634,6 @@ LSQUnit<Impl>::writebackStores()
|
|||
incrStIdx(storeWBIdx);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Non-store conditionals do not need a writeback.
|
||||
state->noWB = true;
|
||||
|
|
Loading…
Reference in a new issue