abstract_mem.hh revision 12492
12686Sksewell@umich.edu/*
22686Sksewell@umich.edu * Copyright (c) 2012 ARM Limited
32741Sksewell@umich.edu * All rights reserved
42706Sksewell@umich.edu *
52706Sksewell@umich.edu * The license below extends only to copyright in the software and shall
62706Sksewell@umich.edu * not be construed as granting a license to any other intellectual
72706Sksewell@umich.edu * property including but not limited to intellectual property relating
82706Sksewell@umich.edu * to a hardware implementation of the functionality of the software
92706Sksewell@umich.edu * licensed hereunder.  You may use the software subject to the license
102706Sksewell@umich.edu * terms below provided that you ensure that this notice is replicated
112706Sksewell@umich.edu * unmodified and in its entirety in all distributions of the software,
122706Sksewell@umich.edu * modified or unmodified, in source code or in binary form.
132706Sksewell@umich.edu *
142706Sksewell@umich.edu * Copyright (c) 2001-2005 The Regents of The University of Michigan
152706Sksewell@umich.edu * All rights reserved.
162706Sksewell@umich.edu *
172706Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without
182706Sksewell@umich.edu * modification, are permitted provided that the following conditions are
192706Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
202706Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
212706Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
222706Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
232706Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
242706Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
252706Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
262706Sksewell@umich.edu * this software without specific prior written permission.
272706Sksewell@umich.edu *
282706Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292706Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302706Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312686Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322686Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332686Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342686Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352686Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362686Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372686Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382741Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392686Sksewell@umich.edu *
404661Sksewell@umich.edu * Authors: Ron Dreslinski
412686Sksewell@umich.edu *          Andreas Hansson
422686Sksewell@umich.edu */
432686Sksewell@umich.edu
442686Sksewell@umich.edu/**
454661Sksewell@umich.edu * @file
464661Sksewell@umich.edu * AbstractMemory declaration
472686Sksewell@umich.edu */
482686Sksewell@umich.edu
492686Sksewell@umich.edu#ifndef __MEM_ABSTRACT_MEMORY_HH__
504661Sksewell@umich.edu#define __MEM_ABSTRACT_MEMORY_HH__
514661Sksewell@umich.edu
524661Sksewell@umich.edu#include "mem/mem_object.hh"
534661Sksewell@umich.edu#include "params/AbstractMemory.hh"
544661Sksewell@umich.edu#include "sim/stats.hh"
554661Sksewell@umich.edu
564661Sksewell@umich.edu
574661Sksewell@umich.educlass System;
584661Sksewell@umich.edu
594661Sksewell@umich.edu/**
604661Sksewell@umich.edu * Locked address class that represents a physical address and a
614661Sksewell@umich.edu * context id.
624661Sksewell@umich.edu */
634661Sksewell@umich.educlass LockedAddr {
644661Sksewell@umich.edu
654661Sksewell@umich.edu  private:
664661Sksewell@umich.edu
672686Sksewell@umich.edu    // on alpha, minimum LL/SC granularity is 16 bytes, so lower
682686Sksewell@umich.edu    // bits need to masked off.
692686Sksewell@umich.edu    static const Addr Addr_Mask = 0xf;
702686Sksewell@umich.edu
714661Sksewell@umich.edu  public:
724661Sksewell@umich.edu
734661Sksewell@umich.edu    // locked address
744661Sksewell@umich.edu    Addr addr;
754661Sksewell@umich.edu
764661Sksewell@umich.edu    // locking hw context
774661Sksewell@umich.edu    const ContextID contextId;
784661Sksewell@umich.edu
794661Sksewell@umich.edu    static Addr mask(Addr paddr) { return (paddr & ~Addr_Mask); }
804661Sksewell@umich.edu
814661Sksewell@umich.edu    // check for matching execution context
824661Sksewell@umich.edu    bool matchesContext(Request *req) const
834661Sksewell@umich.edu    {
844661Sksewell@umich.edu        return (contextId == req->contextId());
854661Sksewell@umich.edu    }
864661Sksewell@umich.edu
874661Sksewell@umich.edu    LockedAddr(Request *req) : addr(mask(req->getPaddr())),
884661Sksewell@umich.edu                               contextId(req->contextId())
894661Sksewell@umich.edu    {}
904661Sksewell@umich.edu
914661Sksewell@umich.edu    // constructor for unserialization use
924661Sksewell@umich.edu    LockedAddr(Addr _addr, int _cid) : addr(_addr), contextId(_cid)
934661Sksewell@umich.edu    {}
944661Sksewell@umich.edu};
954661Sksewell@umich.edu
964661Sksewell@umich.edu/**
974661Sksewell@umich.edu * An abstract memory represents a contiguous block of physical
984661Sksewell@umich.edu * memory, with an associated address range, and also provides basic
994661Sksewell@umich.edu * functionality for reading and writing this memory without any
1004661Sksewell@umich.edu * timing information. It is a MemObject since any subclass must have
1014661Sksewell@umich.edu * at least one slave port.
1024661Sksewell@umich.edu */
1034661Sksewell@umich.educlass AbstractMemory : public MemObject
1044661Sksewell@umich.edu{
1052686Sksewell@umich.edu  protected:
1064661Sksewell@umich.edu
1074661Sksewell@umich.edu    // Address range of this memory
1084661Sksewell@umich.edu    AddrRange range;
1094661Sksewell@umich.edu
1104661Sksewell@umich.edu    // Pointer to host memory used to implement this memory
1114661Sksewell@umich.edu    uint8_t* pmemAddr;
1124661Sksewell@umich.edu
1134661Sksewell@umich.edu    // Enable specific memories to be reported to the configuration table
1144661Sksewell@umich.edu    const bool confTableReported;
1154661Sksewell@umich.edu
1164661Sksewell@umich.edu    // Should the memory appear in the global address map
1174661Sksewell@umich.edu    const bool inAddrMap;
1184661Sksewell@umich.edu
1194661Sksewell@umich.edu    // Should KVM map this memory for the guest
1204661Sksewell@umich.edu    const bool kvmMap;
1214661Sksewell@umich.edu
1224661Sksewell@umich.edu    std::list<LockedAddr> lockedAddrList;
1234661Sksewell@umich.edu
1244661Sksewell@umich.edu    // helper function for checkLockedAddrs(): we really want to
1254661Sksewell@umich.edu    // inline a quick check for an empty locked addr list (hopefully
1264661Sksewell@umich.edu    // the common case), and do the full list search (if necessary) in
1274661Sksewell@umich.edu    // this out-of-line function
1284661Sksewell@umich.edu    bool checkLockedAddrList(PacketPtr pkt);
1294661Sksewell@umich.edu
1304661Sksewell@umich.edu    // Record the address of a load-locked operation so that we can
1314661Sksewell@umich.edu    // clear the execution context's lock flag if a matching store is
1324661Sksewell@umich.edu    // performed
1334661Sksewell@umich.edu    void trackLoadLocked(PacketPtr pkt);
1344661Sksewell@umich.edu
1354661Sksewell@umich.edu    // Compare a store address with any locked addresses so we can
1364661Sksewell@umich.edu    // clear the lock flag appropriately.  Return value set to 'false'
1374661Sksewell@umich.edu    // if store operation should be suppressed (because it was a
1384661Sksewell@umich.edu    // conditional store and the address was no longer locked by the
1394661Sksewell@umich.edu    // requesting execution context), 'true' otherwise.  Note that
1404661Sksewell@umich.edu    // this method must be called on *all* stores since even
1414661Sksewell@umich.edu    // non-conditional stores must clear any matching lock addresses.
1424661Sksewell@umich.edu    bool writeOK(PacketPtr pkt) {
1434661Sksewell@umich.edu        Request *req = pkt->req;
1444661Sksewell@umich.edu        if (lockedAddrList.empty()) {
1454661Sksewell@umich.edu            // no locked addrs: nothing to check, store_conditional fails
1464661Sksewell@umich.edu            bool isLLSC = pkt->isLLSC();
1472686Sksewell@umich.edu            if (isLLSC) {
1482686Sksewell@umich.edu                req->setExtraData(0);
1492686Sksewell@umich.edu            }
1504661Sksewell@umich.edu            return !isLLSC; // only do write if not an sc
1512686Sksewell@umich.edu        } else {
1522686Sksewell@umich.edu            // iterate over list...
1534661Sksewell@umich.edu            return checkLockedAddrList(pkt);
1544661Sksewell@umich.edu        }
1554661Sksewell@umich.edu    }
1562686Sksewell@umich.edu
1574661Sksewell@umich.edu    /** Number of total bytes read from this memory */
1584661Sksewell@umich.edu    Stats::Vector bytesRead;
1594661Sksewell@umich.edu    /** Number of instruction bytes read from this memory */
1604661Sksewell@umich.edu    Stats::Vector bytesInstRead;
1614661Sksewell@umich.edu    /** Number of bytes written to this memory */
1624661Sksewell@umich.edu    Stats::Vector bytesWritten;
1634661Sksewell@umich.edu    /** Number of read requests */
1644661Sksewell@umich.edu    Stats::Vector numReads;
1654661Sksewell@umich.edu    /** Number of write requests */
1664661Sksewell@umich.edu    Stats::Vector numWrites;
1674661Sksewell@umich.edu    /** Number of other requests */
1684661Sksewell@umich.edu    Stats::Vector numOther;
1694661Sksewell@umich.edu    /** Read bandwidth from this memory */
1704661Sksewell@umich.edu    Stats::Formula bwRead;
1714661Sksewell@umich.edu    /** Read bandwidth from this memory */
1724661Sksewell@umich.edu    Stats::Formula bwInstRead;
1734661Sksewell@umich.edu    /** Write bandwidth from this memory */
1744661Sksewell@umich.edu    Stats::Formula bwWrite;
1754661Sksewell@umich.edu    /** Total bandwidth from this memory */
1762686Sksewell@umich.edu    Stats::Formula bwTotal;
1772686Sksewell@umich.edu
1782686Sksewell@umich.edu    /** Pointor to the System object.
1792686Sksewell@umich.edu     * This is used for getting the number of masters in the system which is
1804661Sksewell@umich.edu     * needed when registering stats
1814661Sksewell@umich.edu     */
1824661Sksewell@umich.edu    System *_system;
1834661Sksewell@umich.edu
1844661Sksewell@umich.edu
1854661Sksewell@umich.edu  private:
1864661Sksewell@umich.edu
1874661Sksewell@umich.edu    // Prevent copying
1884661Sksewell@umich.edu    AbstractMemory(const AbstractMemory&);
1894661Sksewell@umich.edu
1904661Sksewell@umich.edu    // Prevent assignment
1912686Sksewell@umich.edu    AbstractMemory& operator=(const AbstractMemory&);
1922686Sksewell@umich.edu
1932686Sksewell@umich.edu  public:
1944661Sksewell@umich.edu
1952686Sksewell@umich.edu    typedef AbstractMemoryParams Params;
1964661Sksewell@umich.edu
1974661Sksewell@umich.edu    AbstractMemory(const Params* p);
1984661Sksewell@umich.edu    virtual ~AbstractMemory() {}
1994661Sksewell@umich.edu
2004661Sksewell@umich.edu    /**
2014661Sksewell@umich.edu     * Initialise this memory.
2024661Sksewell@umich.edu     */
2034661Sksewell@umich.edu    void init() override;
2044661Sksewell@umich.edu
2054661Sksewell@umich.edu    /**
2064661Sksewell@umich.edu     * See if this is a null memory that should never store data and
2074661Sksewell@umich.edu     * always return zero.
2084661Sksewell@umich.edu     *
2094661Sksewell@umich.edu     * @return true if null
2104661Sksewell@umich.edu     */
2114661Sksewell@umich.edu    bool isNull() const { return params()->null; }
2124661Sksewell@umich.edu
2134661Sksewell@umich.edu    /**
2144661Sksewell@umich.edu     * Set the host memory backing store to be used by this memory
2154661Sksewell@umich.edu     * controller.
2164661Sksewell@umich.edu     *
2174661Sksewell@umich.edu     * @param pmem_addr Pointer to a segment of host memory
2184661Sksewell@umich.edu     */
2194661Sksewell@umich.edu    void setBackingStore(uint8_t* pmem_addr);
2204661Sksewell@umich.edu
2214661Sksewell@umich.edu    /**
222     * Get the list of locked addresses to allow checkpointing.
223     */
224    const std::list<LockedAddr>& getLockedAddrList() const
225    { return lockedAddrList; }
226
227    /**
228     * Add a locked address to allow for checkpointing.
229     */
230    void addLockedAddr(LockedAddr addr) { lockedAddrList.push_back(addr); }
231
232    /** read the system pointer
233     * Implemented for completeness with the setter
234     * @return pointer to the system object */
235    System* system() const { return _system; }
236
237    /** Set the system pointer on this memory
238     * This can't be done via a python parameter because the system needs
239     * pointers to all the memories and the reverse would create a cycle in the
240     * object graph. An init() this is set.
241     * @param sys system pointer to set
242     */
243    void system(System *sys) { _system = sys; }
244
245    const Params *
246    params() const
247    {
248        return dynamic_cast<const Params *>(_params);
249    }
250
251    /**
252     * Get the address range
253     *
254     * @return a single contigous address range
255     */
256    AddrRange getAddrRange() const;
257
258    /**
259     * Get the memory size.
260     *
261     * @return the size of the memory
262     */
263    uint64_t size() const { return range.size(); }
264
265    /**
266     * Get the start address.
267     *
268     * @return the start address of the memory
269     */
270    Addr start() const { return range.start(); }
271
272    /**
273     *  Should this memory be passed to the kernel and part of the OS
274     *  physical memory layout.
275     *
276     * @return if this memory is reported
277     */
278    bool isConfReported() const { return confTableReported; }
279
280    /**
281     * Some memories are used as shadow memories or should for other
282     * reasons not be part of the global address map.
283     *
284     * @return if this memory is part of the address map
285     */
286    bool isInAddrMap() const { return inAddrMap; }
287
288    /**
289     * When shadow memories are in use, KVM may want to make one or the other,
290     * but cannot map both into the guest address space.
291     *
292     * @return if this memory should be mapped into the KVM guest address space
293     */
294    bool isKvmMap() const { return kvmMap; }
295
296    /**
297     * Perform an untimed memory access and update all the state
298     * (e.g. locked addresses) and statistics accordingly. The packet
299     * is turned into a response if required.
300     *
301     * @param pkt Packet performing the access
302     */
303    void access(PacketPtr pkt);
304
305    /**
306     * Perform an untimed memory read or write without changing
307     * anything but the memory itself. No stats are affected by this
308     * access. In addition to normal accesses this also facilitates
309     * print requests.
310     *
311     * @param pkt Packet performing the access
312     */
313    void functionalAccess(PacketPtr pkt);
314
315    /**
316     * Register Statistics
317     */
318    void regStats() override;
319
320};
321
322#endif //__MEM_ABSTRACT_MEMORY_HH__
323