summaryrefslogtreecommitdiff
path: root/src/arch/arm/locked_mem.hh
diff options
context:
space:
mode:
authorAli Saidi <Ali.Saidi@ARM.com>2011-04-04 11:42:29 -0500
committerAli Saidi <Ali.Saidi@ARM.com>2011-04-04 11:42:29 -0500
commit8af1eeec6f28d9722802bf1588c911711db07ddd (patch)
tree79f0ba732e6aa8935e78a6e8e8f15896784f370e /src/arch/arm/locked_mem.hh
parent6b6989049383b67a2daef562a0319421ff1a8067 (diff)
downloadgem5-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.hh34
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;
}