physical.hh revision 8719
12391SN/A/*
22391SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan
32391SN/A * All rights reserved.
42391SN/A *
52391SN/A * Redistribution and use in source and binary forms, with or without
62391SN/A * modification, are permitted provided that the following conditions are
72391SN/A * met: redistributions of source code must retain the above copyright
82391SN/A * notice, this list of conditions and the following disclaimer;
92391SN/A * redistributions in binary form must reproduce the above copyright
102391SN/A * notice, this list of conditions and the following disclaimer in the
112391SN/A * documentation and/or other materials provided with the distribution;
122391SN/A * neither the name of the copyright holders nor the names of its
132391SN/A * contributors may be used to endorse or promote products derived from
142391SN/A * this software without specific prior written permission.
152391SN/A *
162391SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172391SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182391SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192391SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202391SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212391SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222391SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232391SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242391SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252391SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262391SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Ron Dreslinski
292391SN/A */
302391SN/A
312391SN/A/* @file
322391SN/A */
332391SN/A
342391SN/A#ifndef __PHYSICAL_MEMORY_HH__
352391SN/A#define __PHYSICAL_MEMORY_HH__
362391SN/A
374762Snate@binkert.org#include <map>
384762Snate@binkert.org#include <string>
394762Snate@binkert.org
402391SN/A#include "base/range.hh"
418719SAli.Saidi@ARM.com#include "base/statistics.hh"
422462SN/A#include "mem/mem_object.hh"
432414SN/A#include "mem/packet.hh"
442914Ssaidi@eecs.umich.edu#include "mem/tport.hh"
454762Snate@binkert.org#include "params/PhysicalMemory.hh"
462415SN/A#include "sim/eventq.hh"
478719SAli.Saidi@ARM.com#include "sim/stats.hh"
482462SN/A
492391SN/A//
502391SN/A// Functional model for a contiguous block of physical memory. (i.e. RAM)
512391SN/A//
522462SN/Aclass PhysicalMemory : public MemObject
532391SN/A{
546107Ssteve.reinhardt@amd.com  protected:
556107Ssteve.reinhardt@amd.com
562914Ssaidi@eecs.umich.edu    class MemoryPort : public SimpleTimingPort
572413SN/A    {
582413SN/A        PhysicalMemory *memory;
592413SN/A
602413SN/A      public:
612413SN/A
622640Sstever@eecs.umich.edu        MemoryPort(const std::string &_name, PhysicalMemory *_memory);
632413SN/A
642413SN/A      protected:
652413SN/A
663349Sbinkertn@umich.edu        virtual Tick recvAtomic(PacketPtr pkt);
672413SN/A
683349Sbinkertn@umich.edu        virtual void recvFunctional(PacketPtr pkt);
692413SN/A
708711Sandreas.hansson@arm.com        virtual void recvRangeChange();
712413SN/A
728711Sandreas.hansson@arm.com        virtual AddrRangeList getAddrRanges();
732413SN/A
746227Snate@binkert.org        virtual unsigned deviceBlockSize() const;
752413SN/A    };
762413SN/A
772416SN/A    int numPorts;
782416SN/A
792413SN/A
802391SN/A  private:
812391SN/A    // prevent copying of a MainMemory object
822391SN/A    PhysicalMemory(const PhysicalMemory &specmem);
832391SN/A    const PhysicalMemory &operator=(const PhysicalMemory &specmem);
842391SN/A
852391SN/A  protected:
863170Sstever@eecs.umich.edu
873170Sstever@eecs.umich.edu    class LockedAddr {
883170Sstever@eecs.umich.edu      public:
893170Sstever@eecs.umich.edu        // on alpha, minimum LL/SC granularity is 16 bytes, so lower
903170Sstever@eecs.umich.edu        // bits need to masked off.
913170Sstever@eecs.umich.edu        static const Addr Addr_Mask = 0xf;
923170Sstever@eecs.umich.edu
933170Sstever@eecs.umich.edu        static Addr mask(Addr paddr) { return (paddr & ~Addr_Mask); }
943170Sstever@eecs.umich.edu
955543Ssaidi@eecs.umich.edu        Addr addr;      // locked address
965714Shsul@eecs.umich.edu        int contextId;     // locking hw context
973170Sstever@eecs.umich.edu
983170Sstever@eecs.umich.edu        // check for matching execution context
993170Sstever@eecs.umich.edu        bool matchesContext(Request *req)
1003170Sstever@eecs.umich.edu        {
1015714Shsul@eecs.umich.edu            return (contextId == req->contextId());
1023170Sstever@eecs.umich.edu        }
1033170Sstever@eecs.umich.edu
1043170Sstever@eecs.umich.edu        LockedAddr(Request *req)
1053170Sstever@eecs.umich.edu            : addr(mask(req->getPaddr())),
1065714Shsul@eecs.umich.edu              contextId(req->contextId())
1073170Sstever@eecs.umich.edu        {
1083170Sstever@eecs.umich.edu        }
1097733SAli.Saidi@ARM.com        // constructor for unserialization use
1107733SAli.Saidi@ARM.com        LockedAddr(Addr _addr, int _cid)
1117733SAli.Saidi@ARM.com            : addr(_addr), contextId(_cid)
1127733SAli.Saidi@ARM.com        {
1137733SAli.Saidi@ARM.com        }
1143170Sstever@eecs.umich.edu    };
1153170Sstever@eecs.umich.edu
1163170Sstever@eecs.umich.edu    std::list<LockedAddr> lockedAddrList;
1173170Sstever@eecs.umich.edu
1183170Sstever@eecs.umich.edu    // helper function for checkLockedAddrs(): we really want to
1193170Sstever@eecs.umich.edu    // inline a quick check for an empty locked addr list (hopefully
1203170Sstever@eecs.umich.edu    // the common case), and do the full list search (if necessary) in
1213170Sstever@eecs.umich.edu    // this out-of-line function
1224626Sstever@eecs.umich.edu    bool checkLockedAddrList(PacketPtr pkt);
1233170Sstever@eecs.umich.edu
1243170Sstever@eecs.umich.edu    // Record the address of a load-locked operation so that we can
1253170Sstever@eecs.umich.edu    // clear the execution context's lock flag if a matching store is
1263170Sstever@eecs.umich.edu    // performed
1274626Sstever@eecs.umich.edu    void trackLoadLocked(PacketPtr pkt);
1283170Sstever@eecs.umich.edu
1293170Sstever@eecs.umich.edu    // Compare a store address with any locked addresses so we can
1303170Sstever@eecs.umich.edu    // clear the lock flag appropriately.  Return value set to 'false'
1313170Sstever@eecs.umich.edu    // if store operation should be suppressed (because it was a
1323170Sstever@eecs.umich.edu    // conditional store and the address was no longer locked by the
1333170Sstever@eecs.umich.edu    // requesting execution context), 'true' otherwise.  Note that
1343170Sstever@eecs.umich.edu    // this method must be called on *all* stores since even
1353170Sstever@eecs.umich.edu    // non-conditional stores must clear any matching lock addresses.
1364626Sstever@eecs.umich.edu    bool writeOK(PacketPtr pkt) {
1374626Sstever@eecs.umich.edu        Request *req = pkt->req;
1383170Sstever@eecs.umich.edu        if (lockedAddrList.empty()) {
1393170Sstever@eecs.umich.edu            // no locked addrs: nothing to check, store_conditional fails
1406102Sgblack@eecs.umich.edu            bool isLLSC = pkt->isLLSC();
1416102Sgblack@eecs.umich.edu            if (isLLSC) {
1424040Ssaidi@eecs.umich.edu                req->setExtraData(0);
1433170Sstever@eecs.umich.edu            }
1446102Sgblack@eecs.umich.edu            return !isLLSC; // only do write if not an sc
1453170Sstever@eecs.umich.edu        } else {
1463170Sstever@eecs.umich.edu            // iterate over list...
1474626Sstever@eecs.umich.edu            return checkLockedAddrList(pkt);
1483170Sstever@eecs.umich.edu        }
1493170Sstever@eecs.umich.edu    }
1503170Sstever@eecs.umich.edu
1513012Ssaidi@eecs.umich.edu    uint8_t *pmemAddr;
1522565SN/A    Tick lat;
1535399Ssaidi@eecs.umich.edu    Tick lat_var;
1544467Sstever@eecs.umich.edu    std::vector<MemoryPort*> ports;
1554467Sstever@eecs.umich.edu    typedef std::vector<MemoryPort*>::iterator PortIterator;
1562391SN/A
1577730SAli.Saidi@ARM.com    uint64_t _size;
1587730SAli.Saidi@ARM.com    uint64_t _start;
1598719SAli.Saidi@ARM.com
1608719SAli.Saidi@ARM.com    /** Number of total bytes read from this memory */
1618719SAli.Saidi@ARM.com    Stats::Scalar bytesRead;
1628719SAli.Saidi@ARM.com    /** Number of instruction bytes read from this memory */
1638719SAli.Saidi@ARM.com    Stats::Scalar bytesInstRead;
1648719SAli.Saidi@ARM.com    /** Number of bytes written to this memory */
1658719SAli.Saidi@ARM.com    Stats::Scalar bytesWritten;
1668719SAli.Saidi@ARM.com    /** Number of read requests */
1678719SAli.Saidi@ARM.com    Stats::Scalar numReads;
1688719SAli.Saidi@ARM.com    /** Number of write requests */
1698719SAli.Saidi@ARM.com    Stats::Scalar numWrites;
1708719SAli.Saidi@ARM.com    /** Number of other requests */
1718719SAli.Saidi@ARM.com    Stats::Scalar numOther;
1728719SAli.Saidi@ARM.com    /** Read bandwidth from this memory */
1738719SAli.Saidi@ARM.com    Stats::Formula bwRead;
1748719SAli.Saidi@ARM.com    /** Read bandwidth from this memory */
1758719SAli.Saidi@ARM.com    Stats::Formula bwInstRead;
1768719SAli.Saidi@ARM.com    /** Write bandwidth from this memory */
1778719SAli.Saidi@ARM.com    Stats::Formula bwWrite;
1788719SAli.Saidi@ARM.com    /** Total bandwidth from this memory */
1798719SAli.Saidi@ARM.com    Stats::Formula bwTotal;
1808719SAli.Saidi@ARM.com
1812391SN/A  public:
1827730SAli.Saidi@ARM.com    uint64_t size() { return _size; }
1837730SAli.Saidi@ARM.com    uint64_t start() { return _start; }
1842391SN/A
1852391SN/A  public:
1864762Snate@binkert.org    typedef PhysicalMemoryParams Params;
1874762Snate@binkert.org    PhysicalMemory(const Params *p);
1882391SN/A    virtual ~PhysicalMemory();
1892391SN/A
1904762Snate@binkert.org    const Params *
1914762Snate@binkert.org    params() const
1924762Snate@binkert.org    {
1934762Snate@binkert.org        return dynamic_cast<const Params *>(_params);
1944762Snate@binkert.org    }
1954762Snate@binkert.org
1962391SN/A  public:
1976227Snate@binkert.org    unsigned deviceBlockSize() const;
1988711Sandreas.hansson@arm.com    AddrRangeList getAddrRanges();
1992738Sstever@eecs.umich.edu    virtual Port *getPort(const std::string &if_name, int idx = -1);
2002541SN/A    void virtual init();
2012914Ssaidi@eecs.umich.edu    unsigned int drain(Event *de);
2022391SN/A
2033012Ssaidi@eecs.umich.edu  protected:
2044626Sstever@eecs.umich.edu    Tick doAtomicAccess(PacketPtr pkt);
2053349Sbinkertn@umich.edu    void doFunctionalAccess(PacketPtr pkt);
2063349Sbinkertn@umich.edu    virtual Tick calculateLatency(PacketPtr pkt);
2072391SN/A
2082391SN/A  public:
2098719SAli.Saidi@ARM.com     /**
2108719SAli.Saidi@ARM.com     * Register Statistics
2118719SAli.Saidi@ARM.com     */
2128719SAli.Saidi@ARM.com    void regStats();
2138719SAli.Saidi@ARM.com
2142391SN/A    virtual void serialize(std::ostream &os);
2152391SN/A    virtual void unserialize(Checkpoint *cp, const std::string &section);
2162497SN/A
2172391SN/A};
2182391SN/A
2192391SN/A#endif //__PHYSICAL_MEMORY_HH__
220