physical.hh revision 3751
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
372391SN/A#include "base/range.hh"
382462SN/A#include "mem/mem_object.hh"
392414SN/A#include "mem/packet.hh"
402914Ssaidi@eecs.umich.edu#include "mem/tport.hh"
412415SN/A#include "sim/eventq.hh"
422416SN/A#include <map>
432416SN/A#include <string>
442462SN/A
452391SN/A//
462391SN/A// Functional model for a contiguous block of physical memory. (i.e. RAM)
472391SN/A//
482462SN/Aclass PhysicalMemory : public MemObject
492391SN/A{
502914Ssaidi@eecs.umich.edu    class MemoryPort : public SimpleTimingPort
512413SN/A    {
522413SN/A        PhysicalMemory *memory;
532413SN/A
542413SN/A      public:
552413SN/A
562640Sstever@eecs.umich.edu        MemoryPort(const std::string &_name, PhysicalMemory *_memory);
572413SN/A
582413SN/A      protected:
592413SN/A
603349Sbinkertn@umich.edu        virtual Tick recvAtomic(PacketPtr pkt);
612413SN/A
623349Sbinkertn@umich.edu        virtual void recvFunctional(PacketPtr pkt);
632413SN/A
642413SN/A        virtual void recvStatusChange(Status status);
652413SN/A
662521SN/A        virtual void getDeviceAddressRanges(AddrRangeList &resp,
672521SN/A                                            AddrRangeList &snoop);
682413SN/A
692413SN/A        virtual int deviceBlockSize();
702413SN/A    };
712413SN/A
722416SN/A    int numPorts;
732416SN/A
742413SN/A
752391SN/A  private:
762391SN/A    // prevent copying of a MainMemory object
772391SN/A    PhysicalMemory(const PhysicalMemory &specmem);
782391SN/A    const PhysicalMemory &operator=(const PhysicalMemory &specmem);
792391SN/A
802391SN/A  protected:
813170Sstever@eecs.umich.edu
823170Sstever@eecs.umich.edu    class LockedAddr {
833170Sstever@eecs.umich.edu      public:
843170Sstever@eecs.umich.edu        // on alpha, minimum LL/SC granularity is 16 bytes, so lower
853170Sstever@eecs.umich.edu        // bits need to masked off.
863170Sstever@eecs.umich.edu        static const Addr Addr_Mask = 0xf;
873170Sstever@eecs.umich.edu
883170Sstever@eecs.umich.edu        static Addr mask(Addr paddr) { return (paddr & ~Addr_Mask); }
893170Sstever@eecs.umich.edu
903170Sstever@eecs.umich.edu        Addr addr; 	// locked address
913170Sstever@eecs.umich.edu        int cpuNum;	// locking CPU
923170Sstever@eecs.umich.edu        int threadNum;	// locking thread ID within CPU
933170Sstever@eecs.umich.edu
943170Sstever@eecs.umich.edu        // check for matching execution context
953170Sstever@eecs.umich.edu        bool matchesContext(Request *req)
963170Sstever@eecs.umich.edu        {
973170Sstever@eecs.umich.edu            return (cpuNum == req->getCpuNum() &&
983170Sstever@eecs.umich.edu                    threadNum == req->getThreadNum());
993170Sstever@eecs.umich.edu        }
1003170Sstever@eecs.umich.edu
1013170Sstever@eecs.umich.edu        LockedAddr(Request *req)
1023170Sstever@eecs.umich.edu            : addr(mask(req->getPaddr())),
1033170Sstever@eecs.umich.edu              cpuNum(req->getCpuNum()),
1043170Sstever@eecs.umich.edu              threadNum(req->getThreadNum())
1053170Sstever@eecs.umich.edu        {
1063170Sstever@eecs.umich.edu        }
1073170Sstever@eecs.umich.edu    };
1083170Sstever@eecs.umich.edu
1093170Sstever@eecs.umich.edu    std::list<LockedAddr> lockedAddrList;
1103170Sstever@eecs.umich.edu
1113170Sstever@eecs.umich.edu    // helper function for checkLockedAddrs(): we really want to
1123170Sstever@eecs.umich.edu    // inline a quick check for an empty locked addr list (hopefully
1133170Sstever@eecs.umich.edu    // the common case), and do the full list search (if necessary) in
1143170Sstever@eecs.umich.edu    // this out-of-line function
1153170Sstever@eecs.umich.edu    bool checkLockedAddrList(Request *req);
1163170Sstever@eecs.umich.edu
1173170Sstever@eecs.umich.edu    // Record the address of a load-locked operation so that we can
1183170Sstever@eecs.umich.edu    // clear the execution context's lock flag if a matching store is
1193170Sstever@eecs.umich.edu    // performed
1203170Sstever@eecs.umich.edu    void trackLoadLocked(Request *req);
1213170Sstever@eecs.umich.edu
1223170Sstever@eecs.umich.edu    // Compare a store address with any locked addresses so we can
1233170Sstever@eecs.umich.edu    // clear the lock flag appropriately.  Return value set to 'false'
1243170Sstever@eecs.umich.edu    // if store operation should be suppressed (because it was a
1253170Sstever@eecs.umich.edu    // conditional store and the address was no longer locked by the
1263170Sstever@eecs.umich.edu    // requesting execution context), 'true' otherwise.  Note that
1273170Sstever@eecs.umich.edu    // this method must be called on *all* stores since even
1283170Sstever@eecs.umich.edu    // non-conditional stores must clear any matching lock addresses.
1293170Sstever@eecs.umich.edu    bool writeOK(Request *req) {
1303170Sstever@eecs.umich.edu        if (lockedAddrList.empty()) {
1313170Sstever@eecs.umich.edu            // no locked addrs: nothing to check, store_conditional fails
1323170Sstever@eecs.umich.edu            bool isLocked = req->isLocked();
1333170Sstever@eecs.umich.edu            if (isLocked) {
1343170Sstever@eecs.umich.edu                req->setScResult(0);
1353170Sstever@eecs.umich.edu            }
1363170Sstever@eecs.umich.edu            return !isLocked; // only do write if not an sc
1373170Sstever@eecs.umich.edu        } else {
1383170Sstever@eecs.umich.edu            // iterate over list...
1393170Sstever@eecs.umich.edu            return checkLockedAddrList(req);
1403170Sstever@eecs.umich.edu        }
1413170Sstever@eecs.umich.edu    }
1423170Sstever@eecs.umich.edu
1433012Ssaidi@eecs.umich.edu    uint8_t *pmemAddr;
1442499SN/A    MemoryPort *port;
1453012Ssaidi@eecs.umich.edu    int pagePtr;
1462565SN/A    Tick lat;
1472391SN/A
1482391SN/A  public:
1492391SN/A    Addr new_page();
1503012Ssaidi@eecs.umich.edu    uint64_t size() { return params()->addrRange.size(); }
1513012Ssaidi@eecs.umich.edu
1523012Ssaidi@eecs.umich.edu    struct Params
1533012Ssaidi@eecs.umich.edu    {
1543012Ssaidi@eecs.umich.edu        std::string name;
1553012Ssaidi@eecs.umich.edu        Range<Addr> addrRange;
1563012Ssaidi@eecs.umich.edu        Tick latency;
1573751Sgblack@eecs.umich.edu        bool zero;
1583012Ssaidi@eecs.umich.edu    };
1593012Ssaidi@eecs.umich.edu
1603012Ssaidi@eecs.umich.edu  protected:
1613012Ssaidi@eecs.umich.edu    Params *_params;
1622391SN/A
1632391SN/A  public:
1643012Ssaidi@eecs.umich.edu    const Params *params() const { return _params; }
1653012Ssaidi@eecs.umich.edu    PhysicalMemory(Params *p);
1662391SN/A    virtual ~PhysicalMemory();
1672391SN/A
1682391SN/A  public:
1692415SN/A    int deviceBlockSize();
1702521SN/A    void getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop);
1712738Sstever@eecs.umich.edu    virtual Port *getPort(const std::string &if_name, int idx = -1);
1722541SN/A    void virtual init();
1732914Ssaidi@eecs.umich.edu    unsigned int drain(Event *de);
1742391SN/A
1753012Ssaidi@eecs.umich.edu  protected:
1763349Sbinkertn@umich.edu    void doFunctionalAccess(PacketPtr pkt);
1773349Sbinkertn@umich.edu    virtual Tick calculateLatency(PacketPtr pkt);
1782413SN/A    void recvStatusChange(Port::Status status);
1792391SN/A
1802391SN/A  public:
1812391SN/A    virtual void serialize(std::ostream &os);
1822391SN/A    virtual void unserialize(Checkpoint *cp, const std::string &section);
1832497SN/A
1842391SN/A};
1852391SN/A
1862391SN/A#endif //__PHYSICAL_MEMORY_HH__
187