diff options
author | Ali Saidi <Ali.Saidi@ARM.com> | 2011-04-04 11:42:29 -0500 |
---|---|---|
committer | Ali Saidi <Ali.Saidi@ARM.com> | 2011-04-04 11:42:29 -0500 |
commit | 8af1eeec6f28d9722802bf1588c911711db07ddd (patch) | |
tree | 79f0ba732e6aa8935e78a6e8e8f15896784f370e /src/arch/arm/locked_mem.hh | |
parent | 6b6989049383b67a2daef562a0319421ff1a8067 (diff) | |
download | gem5-8af1eeec6f28d9722802bf1588c911711db07ddd.tar.xz |
ARM: Use CPU local lock before sending load to mem system.
This change uses the locked_mem.hh header to handle implementing CLREX. It
simplifies the current implementation greatly.
Diffstat (limited to 'src/arch/arm/locked_mem.hh')
-rw-r--r-- | src/arch/arm/locked_mem.hh | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/arch/arm/locked_mem.hh b/src/arch/arm/locked_mem.hh index 41899273a..f902bdb49 100644 --- a/src/arch/arm/locked_mem.hh +++ b/src/arch/arm/locked_mem.hh @@ -26,7 +26,8 @@ * (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: Steve Reinhardt + * Authors: Ali Saidi + * Steve Reinhardt * Stephen Hines */ @@ -39,6 +40,7 @@ * ISA-specific helper functions for locked memory accesses. */ +#include "arch/arm/miscregs.hh" #include "mem/request.hh" @@ -48,6 +50,8 @@ template <class XC> inline void handleLockedRead(XC *xc, Request *req) { + xc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr() & ~0xf); + xc->setMiscReg(MISCREG_LOCKFLAG, true); } @@ -55,6 +59,34 @@ template <class XC> inline bool handleLockedWrite(XC *xc, Request *req) { + if (req->isSwap()) + return true; + + // Verify that the lock flag is still set and the address + // is correct + bool lock_flag = xc->readMiscReg(MISCREG_LOCKFLAG); + Addr lock_addr = xc->readMiscReg(MISCREG_LOCKADDR); + 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(MISCREG_LOCKFLAG, false); + // 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 % 100000 == 0) { + warn("context %d: %d consecutive " + "store conditional failures\n", + xc->contextId(), stCondFailures); + } + + // store conditional failed already, so don't issue it to mem + return false; + } return true; } |