From b10a0092aecbc6927e9a2336188615ed97614fd0 Mon Sep 17 00:00:00 2001 From: Nikos Nikoleris Date: Tue, 13 Jun 2017 11:14:00 +0100 Subject: mem: Signal the local monitor when clearing the global monitor ARM systems require the coordination of the global and local monitors. When the system is run without caches the global monitor is implemented in the abstract memory object. This change adds a callback from the abstract memory that notifies the local monitor when the global monitor is cleared. Additionally, for ARM systems the local monitor signals the event register and wakes the thread context up. Subsequent wait-for-event (WFE) instructions will be immediately signaled. Change-Id: If6c038f3a6bea7239ba4258f07f39c7f9a30500b Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/3760 Maintainer: Nikos Nikoleris Reviewed-by: Jason Lowe-Power --- src/mem/abstract_mem.cc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'src/mem/abstract_mem.cc') diff --git a/src/mem/abstract_mem.cc b/src/mem/abstract_mem.cc index e05296c3e..13a0873cb 100644 --- a/src/mem/abstract_mem.cc +++ b/src/mem/abstract_mem.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2012 ARM Limited + * Copyright (c) 2010-2012,2017 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -46,6 +46,7 @@ #include +#include "arch/locked_mem.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" #include "debug/LLSC.hh" @@ -272,13 +273,12 @@ AbstractMemory::checkLockedAddrList(PacketPtr pkt) if (i->addr == paddr) { DPRINTF(LLSC, "Erasing lock record: context %d addr %#x\n", i->contextId, paddr); - // For ARM, a spinlock would typically include a Wait - // For Event (WFE) to conserve energy. The ARMv8 - // architecture specifies that an event is - // automatically generated when clearing the exclusive - // monitor to wake up the processor in WFE. - ThreadContext* ctx = system()->getThreadContext(i->contextId); - ctx->getCpuPtr()->wakeup(ctx->threadId()); + ContextID owner_cid = i->contextId; + ContextID requester_cid = pkt->req->contextId(); + if (owner_cid != requester_cid) { + ThreadContext* ctx = system()->getThreadContext(owner_cid); + TheISA::globalClearExclusive(ctx); + } i = lockedAddrList.erase(i); } else { i++; @@ -387,6 +387,9 @@ AbstractMemory::access(PacketPtr pkt) } else if (pkt->isRead()) { assert(!pkt->isWrite()); if (pkt->isLLSC()) { + assert(!pkt->fromCache()); + // if the packet is not coming from a cache then we have + // to do the LL/SC tracking here trackLoadLocked(pkt); } if (pmemAddr) -- cgit v1.2.3