From 1853d57dc3e7fdfd9dca9a4fe388a1234dd6219b Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Fri, 3 Sep 2021 10:31:34 -0700 Subject: [PATCH] misc: Revert "arch,cpu,mem,sim: Fold arch/locked_mem.hh..." This reverts commit a3f85217abae1ab340eadc4881253230f99cb4f7, https://gem5-review.googlesource.com/c/public/gem5/+/48384 The reason for reverting this commit is it causes the Nightly build to timeout: https://www.mail-archive.com/gem5-dev@gem5.org/msg40344.html The exact cause of this failure was a stalling with the O3 processor on ARM. The simulation reaches the following error and repeats until timeout: ``` build/ARM/arch/arm/isa.cc:2634: warn: context 0: 2136500000 consecutive store conditional failures ``` The "realview-o3-ARM-x86_64-opt" test can replicate this: ``` ./main.py run -j8 --uid SuiteUID:tests/gem5/fs/linux/arm/test.py:realview-o3-ARM-x86_64-opt ``` Change-Id: I9e9a20753c2a25c143e6a73f58716feb41861cde Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49927 Maintainer: Bobby R. Bruce Maintainer: Giacomo Travaglini Reviewed-by: Giacomo Travaglini Reviewed-by: Gabe Black Tested-by: kokoro --- src/arch/SConscript | 1 + src/arch/arm/insts/tme64ruby.cc | 5 +- src/arch/arm/isa.cc | 101 ------------------- src/arch/arm/isa.hh | 10 -- src/arch/arm/locked_mem.hh | 168 ++++++++++++++++++++++++++++++++ src/arch/generic/isa.hh | 15 --- src/arch/generic/locked_mem.hh | 101 +++++++++++++++++++ src/arch/mips/locked_mem.hh | 154 +++++++++++++++++++++++++++++ src/arch/null/locked_mem.hh | 63 ++++++++++++ src/arch/power/locked_mem.hh | 53 ++++++++++ src/arch/riscv/SConscript | 1 + src/arch/riscv/isa.cc | 76 --------------- src/arch/riscv/isa.hh | 9 -- src/arch/riscv/locked_mem.cc | 14 +++ src/arch/riscv/locked_mem.hh | 147 ++++++++++++++++++++++++++++ src/arch/sparc/locked_mem.hh | 51 ++++++++++ src/arch/x86/locked_mem.hh | 51 ++++++++++ src/cpu/minor/lsq.cc | 15 +-- src/cpu/o3/lsq_unit.cc | 14 +-- src/cpu/simple/atomic.cc | 18 ++-- src/cpu/simple/timing.cc | 11 +-- src/mem/abstract_mem.cc | 3 +- src/sim/faults.cc | 3 +- 23 files changed, 840 insertions(+), 244 deletions(-) create mode 100644 src/arch/arm/locked_mem.hh create mode 100644 src/arch/generic/locked_mem.hh create mode 100644 src/arch/mips/locked_mem.hh create mode 100644 src/arch/null/locked_mem.hh create mode 100644 src/arch/power/locked_mem.hh create mode 100644 src/arch/riscv/locked_mem.cc create mode 100644 src/arch/riscv/locked_mem.hh create mode 100644 src/arch/sparc/locked_mem.hh create mode 100644 src/arch/x86/locked_mem.hh diff --git a/src/arch/SConscript b/src/arch/SConscript index e1387d9602..fb9f463717 100644 --- a/src/arch/SConscript +++ b/src/arch/SConscript @@ -59,6 +59,7 @@ env.SwitchingHeaders( Split(''' decoder.hh isa.hh + locked_mem.hh page_size.hh pcstate.hh vecregs.hh diff --git a/src/arch/arm/insts/tme64ruby.cc b/src/arch/arm/insts/tme64ruby.cc index 12cc87857a..26ff3d04df 100644 --- a/src/arch/arm/insts/tme64ruby.cc +++ b/src/arch/arm/insts/tme64ruby.cc @@ -38,6 +38,7 @@ #include "arch/arm/faults.hh" #include "arch/arm/htm.hh" #include "arch/arm/insts/tme64.hh" +#include "arch/arm/locked_mem.hh" #include "arch/generic/memhelpers.hh" #include "debug/ArmTme.hh" #include "mem/packet_access.hh" @@ -119,7 +120,7 @@ Tstart64::completeAcc(PacketPtr pkt, ExecContext *xc, armcpt->save(tc); armcpt->destinationRegister(dest); - tc->getIsaPtr()->globalClearExclusive(); + ArmISA::globalClearExclusive(tc); } xc->setIntRegOperand(this, 0, (Dest64) & mask(intWidth)); @@ -261,7 +262,7 @@ MicroTcommit64::completeAcc(PacketPtr pkt, ExecContext *xc, assert(tme_checkpoint->valid()); tme_checkpoint->reset(); - tc->getIsaPtr()->globalClearExclusive(); + ArmISA::globalClearExclusive(tc); } } diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index ebdff91f06..51856cad94 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -42,17 +42,14 @@ #include "arch/arm/interrupts.hh" #include "arch/arm/mmu.hh" #include "arch/arm/pmu.hh" -#include "arch/arm/regs/misc.hh" #include "arch/arm/self_debug.hh" #include "arch/arm/system.hh" #include "arch/arm/tlbi_op.hh" -#include "arch/arm/utility.hh" #include "base/cprintf.hh" #include "cpu/base.hh" #include "cpu/checker/cpu.hh" #include "cpu/reg_class.hh" #include "debug/Arm.hh" -#include "debug/LLSC.hh" #include "debug/MiscRegs.hh" #include "dev/arm/generic_timer.hh" #include "dev/arm/gic_v3.hh" @@ -2558,103 +2555,5 @@ ISA::MiscRegLUTEntryInitializer::highest(ArmSystem *const sys) const return *this; } -void -ISA::handleLockedSnoop(PacketPtr pkt, Addr cacheBlockMask) -{ - // Should only every see invalidations / direct writes - assert(pkt->isInvalidate() || pkt->isWrite()); - - DPRINTF(LLSC, "%s: handling snoop for address: %#x locked: %d\n", - tc->getCpuPtr()->name(), pkt->getAddr(), - tc->readMiscReg(MISCREG_LOCKFLAG)); - if (!tc->readMiscReg(MISCREG_LOCKFLAG)) - return; - - Addr locked_addr = tc->readMiscReg(MISCREG_LOCKADDR) & cacheBlockMask; - // If no caches are attached, the snoop address always needs to be masked - Addr snoop_addr = pkt->getAddr() & cacheBlockMask; - - DPRINTF(LLSC, "%s: handling snoop for address: %#x locked addr: %#x\n", - tc->getCpuPtr()->name(), snoop_addr, locked_addr); - if (locked_addr == snoop_addr) { - DPRINTF(LLSC, "%s: address match, clearing lock and signaling sev\n", - tc->getCpuPtr()->name()); - tc->setMiscReg(MISCREG_LOCKFLAG, false); - // Implement ARMv8 WFE/SEV semantics - sendEvent(tc); - tc->setMiscReg(MISCREG_SEV_MAILBOX, true); - } -} - -void -ISA::handleLockedRead(const RequestPtr &req) -{ - tc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr()); - tc->setMiscReg(MISCREG_LOCKFLAG, true); - DPRINTF(LLSC, "%s: Placing address %#x in monitor\n", - tc->getCpuPtr()->name(), req->getPaddr()); -} - -void -ISA::handleLockedSnoopHit() -{ - DPRINTF(LLSC, "%s: handling snoop lock hit address: %#x\n", - tc->getCpuPtr()->name(), tc->readMiscReg(MISCREG_LOCKADDR)); - tc->setMiscReg(MISCREG_LOCKFLAG, false); - tc->setMiscReg(MISCREG_SEV_MAILBOX, true); -} - -bool -ISA::handleLockedWrite(const RequestPtr &req, Addr cacheBlockMask) -{ - if (req->isSwap()) - return true; - - DPRINTF(LLSC, "%s: handling locked write for address %#x in monitor\n", - tc->getCpuPtr()->name(), req->getPaddr()); - // Verify that the lock flag is still set and the address - // is correct - bool lock_flag = tc->readMiscReg(MISCREG_LOCKFLAG); - Addr lock_addr = tc->readMiscReg(MISCREG_LOCKADDR) & cacheBlockMask; - if (!lock_flag || (req->getPaddr() & cacheBlockMask) != lock_addr) { - // Lock flag not set or addr mismatch in CPU; - // don't even bother sending to memory system - req->setExtraData(0); - tc->setMiscReg(MISCREG_LOCKFLAG, false); - DPRINTF(LLSC, "%s: clearing lock flag in handle locked write\n", - tc->getCpuPtr()->name()); - // 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 = tc->readStCondFailures(); - stCondFailures++; - tc->setStCondFailures(stCondFailures); - if (stCondFailures % 100000 == 0) { - warn("context %d: %d consecutive " - "store conditional failures\n", - tc->contextId(), stCondFailures); - } - - // store conditional failed already, so don't issue it to mem - return false; - } - return true; -} - -void -ISA::globalClearExclusive() -{ - // 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. - DPRINTF(LLSC, "Clearing lock and signaling sev\n"); - tc->setMiscReg(MISCREG_LOCKFLAG, false); - // Implement ARMv8 WFE/SEV semantics - sendEvent(tc); - tc->setMiscReg(MISCREG_SEV_MAILBOX, true); -} - } // namespace ArmISA } // namespace gem5 diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 09bfe1cc0a..0e384839fb 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -919,16 +919,6 @@ namespace ArmISA } void copyRegsFrom(ThreadContext *src) override; - - void handleLockedRead(const RequestPtr &req) override; - - bool handleLockedWrite(const RequestPtr &req, - Addr cacheBlockMask) override; - - void handleLockedSnoop(PacketPtr pkt, Addr cacheBlockMask) override; - void handleLockedSnoopHit() override; - - void globalClearExclusive() override; }; } // namespace ArmISA diff --git a/src/arch/arm/locked_mem.hh b/src/arch/arm/locked_mem.hh new file mode 100644 index 0000000000..103c07f530 --- /dev/null +++ b/src/arch/arm/locked_mem.hh @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2012-2013,2017, 2020 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_ARM_LOCKED_MEM_HH__ +#define __ARCH_ARM_LOCKED_MEM_HH__ + +/** + * @file + * + * ISA-specific helper functions for locked memory accesses. + */ + +#include "arch/arm/regs/misc.hh" +#include "arch/arm/utility.hh" +#include "debug/LLSC.hh" +#include "mem/packet.hh" +#include "mem/request.hh" + +namespace gem5 +{ + +namespace ArmISA +{ +template +inline void +handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask) +{ + // Should only every see invalidations / direct writes + assert(pkt->isInvalidate() || pkt->isWrite()); + + DPRINTF(LLSC,"%s: handling snoop for address: %#x locked: %d\n", + xc->getCpuPtr()->name(),pkt->getAddr(), + xc->readMiscReg(MISCREG_LOCKFLAG)); + if (!xc->readMiscReg(MISCREG_LOCKFLAG)) + return; + + Addr locked_addr = xc->readMiscReg(MISCREG_LOCKADDR) & cacheBlockMask; + // If no caches are attached, the snoop address always needs to be masked + Addr snoop_addr = pkt->getAddr() & cacheBlockMask; + + DPRINTF(LLSC,"%s: handling snoop for address: %#x locked addr: %#x\n", + xc->getCpuPtr()->name(),snoop_addr, locked_addr); + if (locked_addr == snoop_addr) { + DPRINTF(LLSC,"%s: address match, clearing lock and signaling sev\n", + xc->getCpuPtr()->name()); + xc->setMiscReg(MISCREG_LOCKFLAG, false); + // Implement ARMv8 WFE/SEV semantics + sendEvent(xc); + xc->setMiscReg(MISCREG_SEV_MAILBOX, true); + } +} + +template +inline void +handleLockedRead(XC *xc, const RequestPtr &req) +{ + xc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr()); + xc->setMiscReg(MISCREG_LOCKFLAG, true); + DPRINTF(LLSC,"%s: Placing address %#x in monitor\n", xc->getCpuPtr()->name(), + req->getPaddr()); +} + +template +inline void +handleLockedSnoopHit(XC *xc) +{ + DPRINTF(LLSC,"%s: handling snoop lock hit address: %#x\n", + xc->getCpuPtr()->name(), xc->readMiscReg(MISCREG_LOCKADDR)); + xc->setMiscReg(MISCREG_LOCKFLAG, false); + xc->setMiscReg(MISCREG_SEV_MAILBOX, true); +} + +template +inline bool +handleLockedWrite(XC *xc, const RequestPtr &req, Addr cacheBlockMask) +{ + if (req->isSwap()) + return true; + + DPRINTF(LLSC,"%s: handling locked write for address %#x in monitor\n", + xc->getCpuPtr()->name(), req->getPaddr()); + // 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) & cacheBlockMask; + if (!lock_flag || (req->getPaddr() & cacheBlockMask) != 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); + DPRINTF(LLSC,"%s: clearing lock flag in handle locked write\n", + xc->getCpuPtr()->name()); + // 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; +} + +template +inline void +globalClearExclusive(XC *xc) +{ + // 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. + DPRINTF(LLSC,"Clearing lock and signaling sev\n"); + xc->setMiscReg(MISCREG_LOCKFLAG, false); + // Implement ARMv8 WFE/SEV semantics + sendEvent(xc); + xc->setMiscReg(MISCREG_SEV_MAILBOX, true); +} + +} // namespace ArmISA +} // namespace gem5 + +#endif diff --git a/src/arch/generic/isa.hh b/src/arch/generic/isa.hh index 11eee9da3c..02decf2bfe 100644 --- a/src/arch/generic/isa.hh +++ b/src/arch/generic/isa.hh @@ -44,8 +44,6 @@ #include "cpu/reg_class.hh" #include "enums/VecRegRenameMode.hh" -#include "mem/packet.hh" -#include "mem/request.hh" #include "sim/sim_object.hh" namespace gem5 @@ -86,19 +84,6 @@ class BaseISA : public SimObject } const RegClasses ®Classes() const { return _regClasses; } - - // Locked memory handling functions. - virtual void handleLockedRead(const RequestPtr &req) {} - virtual bool - handleLockedWrite(const RequestPtr &req, Addr cacheBlockMask) - { - return true; - } - - virtual void handleLockedSnoop(PacketPtr pkt, Addr cacheBlockMask) {} - virtual void handleLockedSnoopHit() {} - - virtual void globalClearExclusive() {} }; } // namespace gem5 diff --git a/src/arch/generic/locked_mem.hh b/src/arch/generic/locked_mem.hh new file mode 100644 index 0000000000..8a78e66411 --- /dev/null +++ b/src/arch/generic/locked_mem.hh @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2017 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_GENERIC_LOCKED_MEM_HH__ +#define __ARCH_GENERIC_LOCKED_MEM_HH__ + +/** + * @file + * + * Generic helper functions for locked memory accesses. + */ + +#include "base/compiler.hh" +#include "mem/packet.hh" +#include "mem/request.hh" + +namespace gem5 +{ + +namespace GenericISA +{ + +GEM5_DEPRECATED_NAMESPACE(LockedMem, locked_mem); +namespace locked_mem +{ + +template +inline void +handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask) +{ +} + +template +inline void +handleLockedRead(XC *xc, const RequestPtr &req) +{ +} + +template +inline void +handleLockedSnoopHit(XC *xc) +{ +} + + +template +inline bool +handleLockedWrite(XC *xc, const RequestPtr &req, Addr cacheBlockMask) +{ + return true; +} + +template +inline void +globalClearExclusive(XC *xc) +{ +} + +} // namespace locked_mem + +} // namespace Generic ISA +} // namespace gem5 + +#endif diff --git a/src/arch/mips/locked_mem.hh b/src/arch/mips/locked_mem.hh new file mode 100644 index 0000000000..f8e1b295ec --- /dev/null +++ b/src/arch/mips/locked_mem.hh @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2012 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Copyright (c) 2006-2007 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_MIPS_LOCKED_MEM_HH__ +#define __ARCH_MIPS_LOCKED_MEM_HH__ + +/** + * @file + * + * ISA-specific helper functions for locked memory accesses. + */ + +#include "arch/mips/regs/misc.hh" +#include "base/logging.hh" +#include "base/trace.hh" +#include "cpu/base.hh" +#include "debug/LLSC.hh" +#include "mem/packet.hh" +#include "mem/request.hh" + +namespace gem5 +{ + +namespace MipsISA +{ +template +inline void +handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask) +{ + if (!xc->readMiscReg(MISCREG_LLFLAG)) + return; + + Addr locked_addr = xc->readMiscReg(MISCREG_LLADDR) & cacheBlockMask; + Addr snoop_addr = pkt->getAddr() & cacheBlockMask; + + if (locked_addr == snoop_addr) + xc->setMiscReg(MISCREG_LLFLAG, false); +} + + +template +inline void +handleLockedRead(XC *xc, const RequestPtr &req) +{ + xc->setMiscReg(MISCREG_LLADDR, req->getPaddr() & ~0xf); + xc->setMiscReg(MISCREG_LLFLAG, true); + DPRINTF(LLSC, "[cid:%i]: Load-Link Flag Set & Load-Link" + " Address set to %x.\n", + req->contextId(), req->getPaddr() & ~0xf); +} + +template +inline void +handleLockedSnoopHit(XC *xc) +{ +} + +template +inline bool +handleLockedWrite(XC *xc, const RequestPtr &req, Addr cacheBlockMask) +{ + 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(MISCREG_LLFLAG); + Addr lock_addr = xc->readMiscReg(MISCREG_LLADDR); + + 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_LLFLAG, 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("%i: context %d: %d consecutive " + "store conditional failures\n", + curTick(), xc->contextId(), stCondFailures); + } + + if (!lock_flag){ + DPRINTF(LLSC, "[cid:%i]: Lock Flag Set, " + "Store Conditional Failed.\n", + req->contextId()); + } else if ((req->getPaddr() & ~0xf) != lock_addr) { + DPRINTF(LLSC, "[cid:%i]: Load-Link Address Mismatch, " + "Store Conditional Failed.\n", + req->contextId()); + } + // store conditional failed already, so don't issue it to mem + return false; + } + } + + return true; +} + +template +inline void +globalClearExclusive(XC *xc) +{ + xc->getCpuPtr()->wakeup(xc->threadId()); +} + +} // namespace MipsISA +} // namespace gem5 + +#endif diff --git a/src/arch/null/locked_mem.hh b/src/arch/null/locked_mem.hh new file mode 100644 index 0000000000..db53a706c5 --- /dev/null +++ b/src/arch/null/locked_mem.hh @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_NULL_LOCKED_MEM_HH__ +#define __ARCH_NULL_LOCKED_MEM_HH__ + +/** + * @file + * + * ISA-specific helper functions for locked memory accesses. + */ + +#include "arch/generic/locked_mem.hh" + +namespace gem5 +{ + +namespace NullISA +{ + +using namespace GenericISA::locked_mem; + +} // namespace NullISA +} // namespace gem5 + +#endif diff --git a/src/arch/power/locked_mem.hh b/src/arch/power/locked_mem.hh new file mode 100644 index 0000000000..b225914a2d --- /dev/null +++ b/src/arch/power/locked_mem.hh @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_POWER_LOCKED_MEM_HH__ +#define __ARCH_POWER_LOCKED_MEM_HH__ + +/** + * @file + * + * ISA-specific helper functions for locked memory accesses. + */ + +#include "arch/generic/locked_mem.hh" + +namespace gem5 +{ + +namespace PowerISA +{ + +using namespace GenericISA::locked_mem; + +} // namespace PowerISA +} // namespace gem5 + +#endif // __ARCH_POWER_LOCKED_MEM_HH__ diff --git a/src/arch/riscv/SConscript b/src/arch/riscv/SConscript index 4861c69d6d..17186c030a 100644 --- a/src/arch/riscv/SConscript +++ b/src/arch/riscv/SConscript @@ -47,6 +47,7 @@ if env['TARGET_ISA'] == 'riscv': Source('decoder.cc') Source('faults.cc') Source('isa.cc') + Source('locked_mem.cc') Source('process.cc') Source('pagetable.cc') Source('pagetable_walker.cc') diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index ac2725f41b..a987bfe4b0 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -43,14 +43,9 @@ #include "arch/riscv/regs/misc.hh" #include "base/bitfield.hh" #include "base/compiler.hh" -#include "base/logging.hh" -#include "base/trace.hh" #include "cpu/base.hh" #include "debug/Checkpoint.hh" -#include "debug/LLSC.hh" #include "debug/RiscvMisc.hh" -#include "mem/packet.hh" -#include "mem/request.hh" #include "params/RiscvISA.hh" #include "sim/pseudo_inst.hh" @@ -489,76 +484,5 @@ ISA::unserialize(CheckpointIn &cp) UNSERIALIZE_CONTAINER(miscRegFile); } -const int WARN_FAILURE = 10000; - -// RISC-V allows multiple locks per hart, but each SC has to unlock the most -// recent one, so we use a stack here. -std::unordered_map> locked_addrs; - -void -ISA::handleLockedSnoop(PacketPtr pkt, Addr cacheBlockMask) -{ - std::stack& locked_addr_stack = locked_addrs[tc->contextId()]; - - if (locked_addr_stack.empty()) - return; - Addr snoop_addr = pkt->getAddr() & cacheBlockMask; - DPRINTF(LLSC, "Locked snoop on address %x.\n", snoop_addr); - if ((locked_addr_stack.top() & cacheBlockMask) == snoop_addr) - locked_addr_stack.pop(); -} - - -void -ISA::handleLockedRead(const RequestPtr &req) -{ - std::stack& locked_addr_stack = locked_addrs[tc->contextId()]; - - locked_addr_stack.push(req->getPaddr() & ~0xF); - DPRINTF(LLSC, "[cid:%d]: Reserved address %x.\n", - req->contextId(), req->getPaddr() & ~0xF); -} - -bool -ISA::handleLockedWrite(const RequestPtr &req, Addr cacheBlockMask) -{ - std::stack& locked_addr_stack = locked_addrs[tc->contextId()]; - - // Normally RISC-V uses zero to indicate success and nonzero to indicate - // failure (right now only 1 is reserved), but in gem5 zero indicates - // failure and one indicates success, so here we conform to that (it should - // be switched in the instruction's implementation) - - DPRINTF(LLSC, "[cid:%d]: locked_addrs empty? %s.\n", req->contextId(), - locked_addr_stack.empty() ? "yes" : "no"); - if (!locked_addr_stack.empty()) { - DPRINTF(LLSC, "[cid:%d]: addr = %x.\n", req->contextId(), - req->getPaddr() & ~0xF); - DPRINTF(LLSC, "[cid:%d]: last locked addr = %x.\n", req->contextId(), - locked_addr_stack.top()); - } - if (locked_addr_stack.empty() - || locked_addr_stack.top() != ((req->getPaddr() & ~0xF))) { - req->setExtraData(0); - int stCondFailures = tc->readStCondFailures(); - tc->setStCondFailures(++stCondFailures); - if (stCondFailures % WARN_FAILURE == 0) { - warn("%i: context %d: %d consecutive SC failures.\n", - curTick(), tc->contextId(), stCondFailures); - } - return false; - } - if (req->isUncacheable()) { - req->setExtraData(2); - } - return true; -} - -void -ISA::globalClearExclusive() -{ - tc->getCpuPtr()->wakeup(tc->threadId()); -} - } // namespace RiscvISA } // namespace gem5 diff --git a/src/arch/riscv/isa.hh b/src/arch/riscv/isa.hh index 4521c52dd1..3597310ecb 100644 --- a/src/arch/riscv/isa.hh +++ b/src/arch/riscv/isa.hh @@ -98,15 +98,6 @@ class ISA : public BaseISA void unserialize(CheckpointIn &cp) override; ISA(const Params &p); - - void handleLockedRead(const RequestPtr &req) override; - - bool handleLockedWrite(const RequestPtr &req, - Addr cacheBlockMask) override; - - void handleLockedSnoop(PacketPtr pkt, Addr cacheBlockMask) override; - - void globalClearExclusive() override; }; } // namespace RiscvISA diff --git a/src/arch/riscv/locked_mem.cc b/src/arch/riscv/locked_mem.cc new file mode 100644 index 0000000000..1c575347e9 --- /dev/null +++ b/src/arch/riscv/locked_mem.cc @@ -0,0 +1,14 @@ +#include "arch/riscv/locked_mem.hh" + +#include + +#include "base/types.hh" + +namespace gem5 +{ + +namespace RiscvISA +{ + std::unordered_map> locked_addrs; +} // namespace RiscvISA +} // namespace gem5 diff --git a/src/arch/riscv/locked_mem.hh b/src/arch/riscv/locked_mem.hh new file mode 100644 index 0000000000..53f7137adf --- /dev/null +++ b/src/arch/riscv/locked_mem.hh @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * Copyright (c) 2012 ARM Limited + * Copyright (c) 2014-2015 Sven Karlsson + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Copyright (c) 2006-2007 The Regents of The University of Michigan + * Copyright (c) 2016 The University of Virginia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_RISCV_LOCKED_MEM_HH__ +#define __ARCH_RISCV_LOCKED_MEM_HH__ + +#include +#include + +#include "base/logging.hh" +#include "base/trace.hh" +#include "cpu/base.hh" +#include "debug/LLSC.hh" +#include "mem/packet.hh" +#include "mem/request.hh" + +namespace gem5 +{ + +/* + * ISA-specific helper functions for locked memory accesses. + */ +namespace RiscvISA +{ + +const int WARN_FAILURE = 10000; + +// RISC-V allows multiple locks per hart, but each SC has to unlock the most +// recent one, so we use a stack here. +extern std::unordered_map> locked_addrs; + +template inline void +handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask) +{ + std::stack& locked_addr_stack = locked_addrs[xc->contextId()]; + + if (locked_addr_stack.empty()) + return; + Addr snoop_addr = pkt->getAddr() & cacheBlockMask; + DPRINTF(LLSC, "Locked snoop on address %x.\n", snoop_addr); + if ((locked_addr_stack.top() & cacheBlockMask) == snoop_addr) + locked_addr_stack.pop(); +} + + +template inline void +handleLockedRead(XC *xc, const RequestPtr &req) +{ + std::stack& locked_addr_stack = locked_addrs[xc->contextId()]; + + locked_addr_stack.push(req->getPaddr() & ~0xF); + DPRINTF(LLSC, "[cid:%d]: Reserved address %x.\n", + req->contextId(), req->getPaddr() & ~0xF); +} + +template inline void +handleLockedSnoopHit(XC *xc) +{} + +template inline bool +handleLockedWrite(XC *xc, const RequestPtr &req, Addr cacheBlockMask) +{ + std::stack& locked_addr_stack = locked_addrs[xc->contextId()]; + + // Normally RISC-V uses zero to indicate success and nonzero to indicate + // failure (right now only 1 is reserved), but in gem5 zero indicates + // failure and one indicates success, so here we conform to that (it should + // be switched in the instruction's implementation) + + DPRINTF(LLSC, "[cid:%d]: locked_addrs empty? %s.\n", req->contextId(), + locked_addr_stack.empty() ? "yes" : "no"); + if (!locked_addr_stack.empty()) { + DPRINTF(LLSC, "[cid:%d]: addr = %x.\n", req->contextId(), + req->getPaddr() & ~0xF); + DPRINTF(LLSC, "[cid:%d]: last locked addr = %x.\n", req->contextId(), + locked_addr_stack.top()); + } + if (locked_addr_stack.empty() + || locked_addr_stack.top() != ((req->getPaddr() & ~0xF))) { + req->setExtraData(0); + int stCondFailures = xc->readStCondFailures(); + xc->setStCondFailures(++stCondFailures); + if (stCondFailures % WARN_FAILURE == 0) { + warn("%i: context %d: %d consecutive SC failures.\n", + curTick(), xc->contextId(), stCondFailures); + } + return false; + } + if (req->isUncacheable()) { + req->setExtraData(2); + } + return true; +} + +template +inline void +globalClearExclusive(XC *xc) +{ + xc->getCpuPtr()->wakeup(xc->threadId()); +} + +} // namespace RiscvISA +} // namespace gem5 + +#endif // __ARCH_RISCV_LOCKED_MEM_HH__ diff --git a/src/arch/sparc/locked_mem.hh b/src/arch/sparc/locked_mem.hh new file mode 100644 index 0000000000..de19d61ecd --- /dev/null +++ b/src/arch/sparc/locked_mem.hh @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_SPARC_LOCKED_MEM_HH__ +#define __ARCH_SPARC_LOCKED_MEM_HH__ + +/** + * @file + * + * ISA-specific helper functions for locked memory accesses. + */ + +#include "arch/generic/locked_mem.hh" + +namespace gem5 +{ + +namespace SparcISA +{ + +using namespace GenericISA::locked_mem; + +} // namespace SparcISA +} // namespace gem5 + +#endif diff --git a/src/arch/x86/locked_mem.hh b/src/arch/x86/locked_mem.hh new file mode 100644 index 0000000000..73959b3891 --- /dev/null +++ b/src/arch/x86/locked_mem.hh @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_X86_LOCKEDMEM_HH__ +#define __ARCH_X86_LOCKEDMEM_HH__ + +/** + * @file + * + * ISA-specific helper functions for locked memory accesses. + */ + +#include "arch/generic/locked_mem.hh" + +namespace gem5 +{ + +namespace X86ISA +{ + +using namespace GenericISA::locked_mem; + +} // namespace X86ISA +} // namespace gem5 + +#endif // __ARCH_X86_LOCKEDMEM_HH__ diff --git a/src/cpu/minor/lsq.cc b/src/cpu/minor/lsq.cc index 1024b03ddc..1b2d7dd597 100644 --- a/src/cpu/minor/lsq.cc +++ b/src/cpu/minor/lsq.cc @@ -40,6 +40,7 @@ #include #include +#include "arch/locked_mem.hh" #include "base/compiler.hh" #include "base/logging.hh" #include "base/trace.hh" @@ -1136,10 +1137,10 @@ LSQ::tryToSendToTransfers(LSQRequestPtr request) /* Handle LLSC requests and tests */ if (is_load) { - thread.getIsaPtr()->handleLockedRead(request->request); + TheISA::handleLockedRead(&context, request->request); } else { - do_access = thread.getIsaPtr()->handleLockedWrite(request->request, - cacheBlockMask); + do_access = TheISA::handleLockedWrite(&context, + request->request, cacheBlockMask); if (!do_access) { DPRINTF(MinorMem, "Not perfoming a memory " @@ -1768,8 +1769,8 @@ LSQ::recvTimingSnoopReq(PacketPtr pkt) if (pkt->isInvalidate() || pkt->isWrite()) { for (ThreadID tid = 0; tid < cpu.numThreads; tid++) { - cpu.getContext(tid)->getIsaPtr()->handleLockedSnoop( - pkt, cacheBlockMask); + TheISA::handleLockedSnoop(cpu.getContext(tid), pkt, + cacheBlockMask); } } } @@ -1790,8 +1791,8 @@ LSQ::threadSnoop(LSQRequestPtr request) } if (pkt->isInvalidate() || pkt->isWrite()) { - cpu.getContext(tid)->getIsaPtr()->handleLockedSnoop(pkt, - cacheBlockMask); + TheISA::handleLockedSnoop(cpu.getContext(tid), pkt, + cacheBlockMask); } } } diff --git a/src/cpu/o3/lsq_unit.cc b/src/cpu/o3/lsq_unit.cc index 0ccf9fdb01..039184d444 100644 --- a/src/cpu/o3/lsq_unit.cc +++ b/src/cpu/o3/lsq_unit.cc @@ -42,6 +42,7 @@ #include "cpu/o3/lsq_unit.hh" #include "arch/generic/debugfaults.hh" +#include "arch/locked_mem.hh" #include "base/str.hh" #include "config/the_isa.hh" #include "cpu/checker/cpu.hh" @@ -451,7 +452,7 @@ LSQUnit::checkSnoop(PacketPtr pkt) gem5::ThreadContext *tc = cpu->getContext(x); bool no_squash = cpu->thread[x]->noSquashFromTC; cpu->thread[x]->noSquashFromTC = true; - tc->getIsaPtr()->handleLockedSnoop(pkt, cacheBlockMask); + TheISA::handleLockedSnoop(tc, pkt, cacheBlockMask); cpu->thread[x]->noSquashFromTC = no_squash; } @@ -469,9 +470,8 @@ LSQUnit::checkSnoop(PacketPtr pkt) // Check that this snoop didn't just invalidate our lock flag if (ld_inst->effAddrValid() && req->isCacheBlockHit(invalidate_addr, cacheBlockMask) - && ld_inst->memReqFlags & Request::LLSC) { - ld_inst->tcBase()->getIsaPtr()->handleLockedSnoopHit(); - } + && ld_inst->memReqFlags & Request::LLSC) + TheISA::handleLockedSnoopHit(ld_inst.get()); bool force_squash = false; @@ -508,7 +508,7 @@ LSQUnit::checkSnoop(PacketPtr pkt) // address since the LOCK* flags don't get updated until // commit. if (ld_inst->memReqFlags & Request::LLSC) - ld_inst->tcBase()->getIsaPtr()->handleLockedSnoopHit(); + TheISA::handleLockedSnoopHit(ld_inst.get()); // If a older load checks this and it's true // then we might have missed the snoop @@ -882,7 +882,7 @@ LSQUnit::writebackStores() // misc regs normally updates the result, but this is not // the desired behavior when handling store conditionals. inst->recordResult(false); - bool success = inst->tcBase()->getIsaPtr()->handleLockedWrite( + bool success = TheISA::handleLockedWrite(inst.get(), req->request(), cacheBlockMask); inst->recordResult(true); req->packetSent(); @@ -1348,7 +1348,7 @@ LSQUnit::read(LSQRequest *req, int load_idx) // regs normally updates the result, but this is not the // desired behavior when handling store conditionals. load_inst->recordResult(false); - load_inst->tcBase()->getIsaPtr()->handleLockedRead(req->mainRequest()); + TheISA::handleLockedRead(load_inst.get(), req->mainRequest()); load_inst->recordResult(true); } diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index de1a7335d3..12accc3f6d 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -41,6 +41,7 @@ #include "cpu/simple/atomic.hh" +#include "arch/locked_mem.hh" #include "base/output.hh" #include "config/the_isa.hh" #include "cpu/exetrace.hh" @@ -132,8 +133,8 @@ AtomicSimpleCPU::threadSnoop(PacketPtr pkt, ThreadID sender) wakeup(tid); } - threadInfo[tid]->thread->getIsaPtr()->handleLockedSnoop(pkt, - dcachePort.cacheBlockMask); + TheISA::handleLockedSnoop(threadInfo[tid]->thread, + pkt, dcachePort.cacheBlockMask); } } } @@ -297,8 +298,7 @@ AtomicSimpleCPU::AtomicCPUDPort::recvAtomicSnoop(PacketPtr pkt) DPRINTF(SimpleCPU, "received invalidation for addr:%#x\n", pkt->getAddr()); for (auto &t_info : cpu->threadInfo) { - t_info->thread->getIsaPtr()->handleLockedSnoop(pkt, - cacheBlockMask); + TheISA::handleLockedSnoop(t_info->thread, pkt, cacheBlockMask); } } @@ -324,8 +324,7 @@ AtomicSimpleCPU::AtomicCPUDPort::recvFunctionalSnoop(PacketPtr pkt) DPRINTF(SimpleCPU, "received invalidation for addr:%#x\n", pkt->getAddr()); for (auto &t_info : cpu->threadInfo) { - t_info->thread->getIsaPtr()->handleLockedSnoop(pkt, - cacheBlockMask); + TheISA::handleLockedSnoop(t_info->thread, pkt, cacheBlockMask); } } } @@ -408,7 +407,7 @@ AtomicSimpleCPU::readMem(Addr addr, uint8_t *data, unsigned size, assert(!pkt.isError()); if (req->isLLSC()) { - thread->getIsaPtr()->handleLockedRead(req); + TheISA::handleLockedRead(thread, req); } } @@ -483,8 +482,9 @@ AtomicSimpleCPU::writeMem(uint8_t *data, unsigned size, Addr addr, if (req->isLLSC()) { assert(curr_frag_id == 0); - do_access = thread->getIsaPtr()->handleLockedWrite(req, - dcachePort.cacheBlockMask); + do_access = + TheISA::handleLockedWrite(thread, req, + dcachePort.cacheBlockMask); } else if (req->isSwap()) { assert(curr_frag_id == 0); if (req->isCondSwap()) { diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 8e9f34cdf3..68be79416a 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -41,6 +41,7 @@ #include "cpu/simple/timing.hh" +#include "arch/locked_mem.hh" #include "base/compiler.hh" #include "config/the_isa.hh" #include "cpu/exetrace.hh" @@ -275,7 +276,7 @@ TimingSimpleCPU::handleReadPacket(PacketPtr pkt) // We're about the issues a locked load, so tell the monitor // to start caring about this address if (pkt->isRead() && pkt->req->isLLSC()) { - thread->getIsaPtr()->handleLockedRead(pkt->req); + TheISA::handleLockedRead(thread, pkt->req); } if (req->isLocalAccess()) { Cycles delay = req->localAccessor(thread->getTC(), pkt); @@ -324,8 +325,7 @@ TimingSimpleCPU::sendData(const RequestPtr &req, uint8_t *data, uint64_t *res, bool do_access = true; // flag to suppress cache access if (req->isLLSC()) { - do_access = thread->getIsaPtr()->handleLockedWrite( - req, dcachePort.cacheBlockMask); + do_access = TheISA::handleLockedWrite(thread, req, dcachePort.cacheBlockMask); } else if (req->isCondSwap()) { assert(res); req->setExtraData(*res); @@ -641,7 +641,7 @@ TimingSimpleCPU::threadSnoop(PacketPtr pkt, ThreadID sender) if (getCpuAddrMonitor(tid)->doMonitor(pkt)) { wakeup(tid); } - threadInfo[tid]->thread->getIsaPtr()->handleLockedSnoop(pkt, + TheISA::handleLockedSnoop(threadInfo[tid]->thread, pkt, dcachePort.cacheBlockMask); } } @@ -1100,8 +1100,7 @@ TimingSimpleCPU::DcachePort::recvTimingSnoopReq(PacketPtr pkt) // It is not necessary to wake up the processor on all incoming packets if (pkt->isInvalidate() || pkt->isWrite()) { for (auto &t_info : cpu->threadInfo) { - t_info->thread->getIsaPtr()->handleLockedSnoop(pkt, - cacheBlockMask); + TheISA::handleLockedSnoop(t_info->thread, pkt, cacheBlockMask); } } } diff --git a/src/mem/abstract_mem.cc b/src/mem/abstract_mem.cc index 03f2557d63..a110a1e578 100644 --- a/src/mem/abstract_mem.cc +++ b/src/mem/abstract_mem.cc @@ -42,6 +42,7 @@ #include +#include "arch/locked_mem.hh" #include "base/loader/memory_image.hh" #include "base/loader/object_file.hh" #include "cpu/thread_context.hh" @@ -338,7 +339,7 @@ AbstractMemory::checkLockedAddrList(PacketPtr pkt) InvalidContextID; if (owner_cid != requestor_cid) { ThreadContext* ctx = system()->threads[owner_cid]; - ctx->getIsaPtr()->globalClearExclusive(); + TheISA::globalClearExclusive(ctx); } i = lockedAddrList.erase(i); } else { diff --git a/src/sim/faults.cc b/src/sim/faults.cc index 77956d89cf..fb63cf303f 100644 --- a/src/sim/faults.cc +++ b/src/sim/faults.cc @@ -43,6 +43,7 @@ #include #include "arch/decoder.hh" +#include "arch/locked_mem.hh" #include "base/logging.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" @@ -125,7 +126,7 @@ void GenericHtmFailureFault::invoke(ThreadContext *tc, checkpoint->restore(tc, getHtmFailureFaultCause()); // reset the global monitor - tc->getIsaPtr()->globalClearExclusive(); + TheISA::globalClearExclusive(tc); // send abort packet to ruby (in final breath) tc->htmAbortTransaction(htmUid, cause);