summaryrefslogtreecommitdiff
path: root/src/arch/mips/locked_mem.hh
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2007-06-22 19:03:42 -0400
committerKorey Sewell <ksewell@umich.edu>2007-06-22 19:03:42 -0400
commit753adb38d5471d23315d1bcfc6a744d1c6e03975 (patch)
tree9ae1cc842f4c3756acf86147a5fd6772d7a6622f /src/arch/mips/locked_mem.hh
parent16c1b5484f576b6aebea9ab5ffab4ea64f080de0 (diff)
downloadgem5-753adb38d5471d23315d1bcfc6a744d1c6e03975.tar.xz
mips import pt. 1
src/arch/mips/SConscript: "mips import pt.1". --HG-- extra : convert_revision : 2e393341938bebf32fb638a209262d074fad4cc1
Diffstat (limited to 'src/arch/mips/locked_mem.hh')
-rw-r--r--src/arch/mips/locked_mem.hh54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/arch/mips/locked_mem.hh b/src/arch/mips/locked_mem.hh
index 363cf1e90..9d7d02a03 100644
--- a/src/arch/mips/locked_mem.hh
+++ b/src/arch/mips/locked_mem.hh
@@ -37,6 +37,9 @@
* ISA-specific helper functions for locked memory accesses.
*/
+#include "arch/isa_traits.hh"
+#include "base/misc.hh"
+#include "base/trace.hh"
#include "mem/request.hh"
@@ -46,6 +49,11 @@ template <class XC>
inline void
handleLockedRead(XC *xc, Request *req)
{
+ unsigned tid = req->getThreadNum();
+ xc->setMiscReg(LLAddr, req->getPaddr() & ~0xf, tid);
+ xc->setMiscReg(LLFlag, true, tid);
+ DPRINTF(LLSC, "[tid:%i]: Load-Link Flag Set & Load-Link Address set to %x.\n",
+ tid, req->getPaddr() & ~0xf);
}
@@ -53,6 +61,52 @@ template <class XC>
inline bool
handleLockedWrite(XC *xc, Request *req)
{
+ unsigned tid = req->getThreadNum();
+
+ if (req->isUncacheable()) {
+ // Funky Turbolaser mailbox access...don't update
+ // result register (see stq_c in decoder.isa)
+ req->setExtraData(2);
+ } else {
+ // standard store conditional
+ bool lock_flag = xc->readMiscReg(LLFlag, tid);
+ Addr lock_addr = xc->readMiscReg(LLAddr, tid);
+
+ if (!lock_flag || (req->getPaddr() & ~0xf) != lock_addr) {
+ // Lock flag not set or addr mismatch in CPU;
+ // don't even bother sending to memory system
+ req->setExtraData(0);
+ xc->setMiscReg(LLFlag, false, tid);
+
+ // the rest of this code is not architectural;
+ // it's just a debugging aid to help detect
+ // livelock by warning on long sequences of failed
+ // store conditionals
+ int stCondFailures = xc->readStCondFailures();
+ stCondFailures++;
+ xc->setStCondFailures(stCondFailures);
+ if (stCondFailures % 10 == 0) {
+ warn("%i: cpu %d: %d consecutive "
+ "store conditional failures\n",
+ curTick, xc->readCpuId(), stCondFailures);
+ }
+
+ if (stCondFailures == 5000) {
+ panic("Max (5000) Store Conditional Fails Reached. Check Code For Deadlock.\n");
+ }
+
+ if (!lock_flag){
+ DPRINTF(LLSC, "[tid:%i]: Lock Flag Set, Store Conditional Failed.\n",
+ tid);
+ } else if ((req->getPaddr() & ~0xf) != lock_addr) {
+ DPRINTF(LLSC, "[tid:%i]: Load-Link Address Mismatch, Store Conditional Failed.\n",
+ tid);
+ }
+ // store conditional failed already, so don't issue it to mem
+ return false;
+ }
+ }
+
return true;
}