diff options
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; } |