111727Sar4jc@virginia.edu/*
211723Sar4jc@virginia.edu * Copyright (c) 2006 The Regents of The University of Michigan
311723Sar4jc@virginia.edu * Copyright (c) 2007-2008 The Florida State University
411723Sar4jc@virginia.edu * Copyright (c) 2009 The University of Edinburgh
511727Sar4jc@virginia.edu * Copyright (c) 2012 ARM Limited
611727Sar4jc@virginia.edu * Copyright (c) 2014-2015 Sven Karlsson
711727Sar4jc@virginia.edu * All rights reserved.
811727Sar4jc@virginia.edu *
911727Sar4jc@virginia.edu * The license below extends only to copyright in the software and shall
1011727Sar4jc@virginia.edu * not be construed as granting a license to any other intellectual
1111727Sar4jc@virginia.edu * property including but not limited to intellectual property relating
1211727Sar4jc@virginia.edu * to a hardware implementation of the functionality of the software
1311727Sar4jc@virginia.edu * licensed hereunder.  You may use the software subject to the license
1411727Sar4jc@virginia.edu * terms below provided that you ensure that this notice is replicated
1511727Sar4jc@virginia.edu * unmodified and in its entirety in all distributions of the software,
1611727Sar4jc@virginia.edu * modified or unmodified, in source code or in binary form.
1711727Sar4jc@virginia.edu *
1811727Sar4jc@virginia.edu * Copyright (c) 2006-2007 The Regents of The University of Michigan
1911727Sar4jc@virginia.edu * Copyright (c) 2016 The University of Virginia
2011723Sar4jc@virginia.edu * All rights reserved.
2111723Sar4jc@virginia.edu *
2211723Sar4jc@virginia.edu * Redistribution and use in source and binary forms, with or without
2311723Sar4jc@virginia.edu * modification, are permitted provided that the following conditions are
2411723Sar4jc@virginia.edu * met: redistributions of source code must retain the above copyright
2511723Sar4jc@virginia.edu * notice, this list of conditions and the following disclaimer;
2611723Sar4jc@virginia.edu * redistributions in binary form must reproduce the above copyright
2711723Sar4jc@virginia.edu * notice, this list of conditions and the following disclaimer in the
2811723Sar4jc@virginia.edu * documentation and/or other materials provided with the distribution;
2911723Sar4jc@virginia.edu * neither the name of the copyright holders nor the names of its
3011723Sar4jc@virginia.edu * contributors may be used to endorse or promote products derived from
3111723Sar4jc@virginia.edu * this software without specific prior written permission.
3211723Sar4jc@virginia.edu *
3311723Sar4jc@virginia.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3411723Sar4jc@virginia.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3511723Sar4jc@virginia.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3611723Sar4jc@virginia.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3711723Sar4jc@virginia.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3811723Sar4jc@virginia.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3911723Sar4jc@virginia.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
4011723Sar4jc@virginia.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
4111723Sar4jc@virginia.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
4211723Sar4jc@virginia.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
4311723Sar4jc@virginia.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4411723Sar4jc@virginia.edu *
4511723Sar4jc@virginia.edu * Authors: Steve Reinhardt
4611727Sar4jc@virginia.edu *          Alec Roelke
4711723Sar4jc@virginia.edu */
4811723Sar4jc@virginia.edu#ifndef __ARCH_RISCV_LOCKED_MEM_HH__
4911723Sar4jc@virginia.edu#define __ARCH_RISCV_LOCKED_MEM_HH__
5011723Sar4jc@virginia.edu
5111729Sar4jc@virginia.edu#include <stack>
5213653Sqtt2@cornell.edu#include <unordered_map>
5311729Sar4jc@virginia.edu
5411727Sar4jc@virginia.edu#include "arch/registers.hh"
5512334Sgabeblack@google.com#include "base/logging.hh"
5611727Sar4jc@virginia.edu#include "base/trace.hh"
5711727Sar4jc@virginia.edu#include "debug/LLSC.hh"
5811723Sar4jc@virginia.edu#include "mem/packet.hh"
5911723Sar4jc@virginia.edu#include "mem/request.hh"
6011723Sar4jc@virginia.edu
6111727Sar4jc@virginia.edu/*
6211727Sar4jc@virginia.edu * ISA-specific helper functions for locked memory accesses.
6311727Sar4jc@virginia.edu */
6411723Sar4jc@virginia.edunamespace RiscvISA
6511723Sar4jc@virginia.edu{
6611723Sar4jc@virginia.edu
6711729Sar4jc@virginia.educonst int WARN_FAILURE = 10000;
6811729Sar4jc@virginia.edu
6911729Sar4jc@virginia.edu// RISC-V allows multiple locks per hart, but each SC has to unlock the most
7011729Sar4jc@virginia.edu// recent one, so we use a stack here.
7113653Sqtt2@cornell.eduextern std::unordered_map<int, std::stack<Addr>> locked_addrs;
7211729Sar4jc@virginia.edu
7311729Sar4jc@virginia.edutemplate <class XC> inline void
7411729Sar4jc@virginia.eduhandleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
7511723Sar4jc@virginia.edu{
7613653Sqtt2@cornell.edu    std::stack<Addr>& locked_addr_stack = locked_addrs[xc->contextId()];
7713653Sqtt2@cornell.edu
7813653Sqtt2@cornell.edu    if (locked_addr_stack.empty())
7911727Sar4jc@virginia.edu        return;
8011729Sar4jc@virginia.edu    Addr snoop_addr = pkt->getAddr() & cacheBlockMask;
8111729Sar4jc@virginia.edu    DPRINTF(LLSC, "Locked snoop on address %x.\n", snoop_addr);
8213653Sqtt2@cornell.edu    if ((locked_addr_stack.top() & cacheBlockMask) == snoop_addr)
8313653Sqtt2@cornell.edu        locked_addr_stack.pop();
8411727Sar4jc@virginia.edu}
8511727Sar4jc@virginia.edu
8611727Sar4jc@virginia.edu
8711729Sar4jc@virginia.edutemplate <class XC> inline void
8812749Sgiacomo.travaglini@arm.comhandleLockedRead(XC *xc, const RequestPtr &req)
8911727Sar4jc@virginia.edu{
9013653Sqtt2@cornell.edu    std::stack<Addr>& locked_addr_stack = locked_addrs[xc->contextId()];
9113653Sqtt2@cornell.edu
9213653Sqtt2@cornell.edu    locked_addr_stack.push(req->getPaddr() & ~0xF);
9311729Sar4jc@virginia.edu    DPRINTF(LLSC, "[cid:%d]: Reserved address %x.\n",
9411729Sar4jc@virginia.edu            req->contextId(), req->getPaddr() & ~0xF);
9511723Sar4jc@virginia.edu}
9611723Sar4jc@virginia.edu
9711729Sar4jc@virginia.edutemplate <class XC> inline void
9811729Sar4jc@virginia.eduhandleLockedSnoopHit(XC *xc)
9911727Sar4jc@virginia.edu{}
10011723Sar4jc@virginia.edu
10111729Sar4jc@virginia.edutemplate <class XC> inline bool
10212749Sgiacomo.travaglini@arm.comhandleLockedWrite(XC *xc, const RequestPtr &req, Addr cacheBlockMask)
10311723Sar4jc@virginia.edu{
10413653Sqtt2@cornell.edu    std::stack<Addr>& locked_addr_stack = locked_addrs[xc->contextId()];
10513653Sqtt2@cornell.edu
10611729Sar4jc@virginia.edu    // Normally RISC-V uses zero to indicate success and nonzero to indicate
10711729Sar4jc@virginia.edu    // failure (right now only 1 is reserved), but in gem5 zero indicates
10811729Sar4jc@virginia.edu    // failure and one indicates success, so here we conform to that (it should
10911729Sar4jc@virginia.edu    // be switched in the instruction's implementation)
11011729Sar4jc@virginia.edu
11111729Sar4jc@virginia.edu    DPRINTF(LLSC, "[cid:%d]: locked_addrs empty? %s.\n", req->contextId(),
11213653Sqtt2@cornell.edu            locked_addr_stack.empty() ? "yes" : "no");
11313653Sqtt2@cornell.edu    if (!locked_addr_stack.empty()) {
11411729Sar4jc@virginia.edu        DPRINTF(LLSC, "[cid:%d]: addr = %x.\n", req->contextId(),
11511729Sar4jc@virginia.edu                req->getPaddr() & ~0xF);
11611729Sar4jc@virginia.edu        DPRINTF(LLSC, "[cid:%d]: last locked addr = %x.\n", req->contextId(),
11713653Sqtt2@cornell.edu                locked_addr_stack.top());
11811729Sar4jc@virginia.edu    }
11913653Sqtt2@cornell.edu    if (locked_addr_stack.empty()
12013653Sqtt2@cornell.edu            || locked_addr_stack.top() != ((req->getPaddr() & ~0xF))) {
12111729Sar4jc@virginia.edu        req->setExtraData(0);
12211729Sar4jc@virginia.edu        int stCondFailures = xc->readStCondFailures();
12311729Sar4jc@virginia.edu        xc->setStCondFailures(++stCondFailures);
12411729Sar4jc@virginia.edu        if (stCondFailures % WARN_FAILURE == 0) {
12511729Sar4jc@virginia.edu            warn("%i: context %d: %d consecutive SC failures.\n",
12611729Sar4jc@virginia.edu                    curTick(), xc->contextId(), stCondFailures);
12711729Sar4jc@virginia.edu        }
12811729Sar4jc@virginia.edu        return false;
12911729Sar4jc@virginia.edu    }
13011727Sar4jc@virginia.edu    if (req->isUncacheable()) {
13111727Sar4jc@virginia.edu        req->setExtraData(2);
13211727Sar4jc@virginia.edu    }
13311723Sar4jc@virginia.edu    return true;
13411723Sar4jc@virginia.edu}
13511723Sar4jc@virginia.edu
13612218Snikos.nikoleris@arm.comtemplate <class XC>
13712218Snikos.nikoleris@arm.cominline void
13812218Snikos.nikoleris@arm.comglobalClearExclusive(XC *xc)
13912218Snikos.nikoleris@arm.com{
14012218Snikos.nikoleris@arm.com    xc->getCpuPtr()->wakeup(xc->threadId());
14112218Snikos.nikoleris@arm.com}
14212218Snikos.nikoleris@arm.com
14311723Sar4jc@virginia.edu} // namespace RiscvISA
14411723Sar4jc@virginia.edu
14511723Sar4jc@virginia.edu#endif // __ARCH_RISCV_LOCKED_MEM_HH__
146