port.hh revision 2520
12381SN/A/*
22381SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
32381SN/A * All rights reserved.
42381SN/A *
52381SN/A * Redistribution and use in source and binary forms, with or without
62381SN/A * modification, are permitted provided that the following conditions are
72381SN/A * met: redistributions of source code must retain the above copyright
82381SN/A * notice, this list of conditions and the following disclaimer;
92381SN/A * redistributions in binary form must reproduce the above copyright
102381SN/A * notice, this list of conditions and the following disclaimer in the
112381SN/A * documentation and/or other materials provided with the distribution;
122381SN/A * neither the name of the copyright holders nor the names of its
132381SN/A * contributors may be used to endorse or promote products derived from
142381SN/A * this software without specific prior written permission.
152381SN/A *
162381SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172381SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182381SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192381SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202381SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212381SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222381SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232381SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242381SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252381SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262381SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272381SN/A */
282381SN/A
292381SN/A/**
302381SN/A * @file
312381SN/A * Port Object Decleration. Ports are used to interface memory objects to
322381SN/A * each other.  They will always come in pairs, and we refer to the other
332381SN/A * port object as the peer.  These are used to make the design more
342381SN/A * modular so that a specific interface between every type of objcet doesn't
352381SN/A * have to be created.
362381SN/A */
372381SN/A
382381SN/A#ifndef __MEM_PORT_HH__
392381SN/A#define __MEM_PORT_HH__
402381SN/A
412381SN/A#include <string>
422381SN/A#include <list>
432381SN/A#include <inttypes.h>
442439SN/A
452381SN/A#include "base/misc.hh"
462381SN/A#include "base/range.hh"
472381SN/A#include "mem/packet.hh"
482381SN/A#include "mem/request.hh"
492407SN/A
502407SN/A/** This typedef is used to clean up the parameter list of
512407SN/A * getDeviceAddressRanges() and getPeerAddressRanges().  It's declared
522407SN/A * outside the Port object since it's also used by some mem objects.
532407SN/A * Eventually we should move this typedef to wherever Addr is
542407SN/A * defined.
552407SN/A */
562407SN/A
572521SN/Atypedef std::list<Range<Addr> > AddrRangeList;
582407SN/A
592381SN/A/**
602381SN/A * Ports are used to interface memory objects to
612381SN/A * each other.  They will always come in pairs, and we refer to the other
622381SN/A * port object as the peer.  These are used to make the design more
632381SN/A * modular so that a specific interface between every type of objcet doesn't
642381SN/A * have to be created.
652381SN/A *
662381SN/A * Recv accesor functions are being called from the peer interface.
672381SN/A * Send accessor functions are being called from the device the port is
682381SN/A * associated with, and it will call the peer recv. accessor function.
692381SN/A */
702381SN/Aclass Port
712381SN/A{
722640Sstever@eecs.umich.edu  public:
732640Sstever@eecs.umich.edu
742640Sstever@eecs.umich.edu    virtual ~Port() {};
752640Sstever@eecs.umich.edu    // mey be better to use subclasses & RTTI?
762640Sstever@eecs.umich.edu    /** Holds the ports status.  Keeps track if it is blocked, or has
772661Sstever@eecs.umich.edu        calculated a range change. */
782661Sstever@eecs.umich.edu    enum Status {
792661Sstever@eecs.umich.edu        Blocked,
802661Sstever@eecs.umich.edu        Unblocked,
812661Sstever@eecs.umich.edu        RangeChange
822381SN/A    };
832381SN/A
842640Sstever@eecs.umich.edu  private:
852640Sstever@eecs.umich.edu
862640Sstever@eecs.umich.edu    /** A pointer to the peer port.  Ports always come in pairs, that way they
872640Sstever@eecs.umich.edu        can use a standardized interface to communicate between different
882640Sstever@eecs.umich.edu        memory objects. */
892640Sstever@eecs.umich.edu    Port *peer;
902640Sstever@eecs.umich.edu
912661Sstever@eecs.umich.edu  public:
922640Sstever@eecs.umich.edu
932640Sstever@eecs.umich.edu    /** Function to set the pointer for the peer port.
942640Sstever@eecs.umich.edu        @todo should be called by the configuration stuff (python).
952640Sstever@eecs.umich.edu    */
962640Sstever@eecs.umich.edu    void setPeer(Port *port) { peer = port; }
972474SN/A
982640Sstever@eecs.umich.edu        /** Function to set the pointer for the peer port.
992381SN/A        @todo should be called by the configuration stuff (python).
1002657Ssaidi@eecs.umich.edu    */
1012657Ssaidi@eecs.umich.edu    Port *getPeer() { return peer; }
1022381SN/A
1032381SN/A  protected:
1042381SN/A
1052381SN/A    /** These functions are protected because they should only be
1062381SN/A     * called by a peer port, never directly by any outside object. */
1072381SN/A
1082381SN/A    /** Called to recive a timing call from the peer port. */
1092642Sstever@eecs.umich.edu    virtual bool recvTiming(Packet &pkt) = 0;
1102381SN/A
1112642Sstever@eecs.umich.edu    /** Called to recive a atomic call from the peer port. */
1122408SN/A    virtual Tick recvAtomic(Packet &pkt) = 0;
1132408SN/A
1142409SN/A    /** Called to recive a functional call from the peer port. */
1152408SN/A    virtual void recvFunctional(Packet &pkt) = 0;
1162381SN/A
1172381SN/A    /** Called to recieve a status change from the peer port. */
1182406SN/A    virtual void recvStatusChange(Status status) = 0;
1192406SN/A
1202406SN/A    /** Called by a peer port if the send was unsuccesful, and had to
1212381SN/A        wait.  This shouldn't be valid for response paths (IO Devices).
1222630SN/A        so it is set to panic if it isn't already defined.
1232381SN/A    */
1242381SN/A    virtual Packet *recvRetry() { panic("??"); }
1252630SN/A
1262381SN/A    /** Called by a peer port in order to determine the block size of the
1272381SN/A        device connected to this port.  It sometimes doesn't make sense for
1282630SN/A        this function to be called, a DMA interface doesn't really have a
1292381SN/A        block size, so it is defaulted to a panic.
1302381SN/A    */
1312381SN/A    virtual int deviceBlockSize() { panic("??"); }
1322381SN/A
1332381SN/A    /** The peer port is requesting us to reply with a list of the ranges we
1342381SN/A        are responsible for.
1352381SN/A        @param owner is an output param that, if set, indicates that the
1362381SN/A        port is the owner of the specified ranges (i.e., slave, default
1372657Ssaidi@eecs.umich.edu        responder, etc.).  If 'owner' is false, the interface is
1382381SN/A        interested in the specified ranges for snooping purposes.  If
1392381SN/A        an object wants to own some ranges and snoop on others, it will
1402381SN/A        need to use two different ports.
1412381SN/A    */
1422381SN/A    virtual void getDeviceAddressRanges(AddrRangeList &range_list,
1432381SN/A                                        bool &owner)
1442406SN/A    { panic("??"); }
1452381SN/A
1462381SN/A  public:
1472381SN/A
1482521SN/A    /** Function called by associated memory device (cache, memory, iodevice)
1492521SN/A        in order to send a timing request to the port.  Simply calls the peer
1502381SN/A        port receive function.
1512521SN/A        @return This function returns if the send was succesful in it's
1522521SN/A        recieve. If it was a failure, then the port will wait for a recvRetry
1532407SN/A        at which point it can issue a successful sendTiming.  This is used in
1542381SN/A        case a cache has a higher priority request come in while waiting for
1552381SN/A        the bus to arbitrate.
1562381SN/A    */
1572381SN/A    bool sendTiming(Packet &pkt) { return peer->recvTiming(pkt); }
1582381SN/A
1592381SN/A    /** Function called by the associated device to send an atomic access,
1602381SN/A        an access in which the data is moved and the state is updated in one
1612381SN/A        cycle, without interleaving with other memory accesses.
1622657Ssaidi@eecs.umich.edu    */
1632381SN/A    Tick sendAtomic(Packet &pkt)
1642381SN/A        { return peer->recvAtomic(pkt); }
1652381SN/A
1662630SN/A    /** Function called by the associated device to send a functional access,
1672381SN/A        an access in which the data is instantly updated everywhere in the
1682381SN/A        memory system, without affecting the current state of any block or
1692381SN/A        moving the block.
1702381SN/A    */
1712381SN/A    void sendFunctional(Packet &pkt)
1722630SN/A        { return peer->recvFunctional(pkt); }
1732381SN/A
1742381SN/A    /** Called by the associated device to send a status change to the device
1752381SN/A        connected to the peer interface.
1762381SN/A    */
1772520SN/A    void sendStatusChange(Status status) {peer->recvStatusChange(status); }
1782520SN/A
1792381SN/A    /** When a timing access doesn't return a success, some time later the
1802630SN/A        Retry will be sent.
1812381SN/A    */
1822381SN/A    Packet *sendRetry() { return peer->recvRetry(); }
1832381SN/A
1842381SN/A    /** Called by the associated device if it wishes to find out the blocksize
1852381SN/A        of the device on attached to the peer port.
1862381SN/A    */
1872381SN/A    int peerBlockSize() { return peer->deviceBlockSize(); }
1882381SN/A
1892381SN/A    /** Called by the associated device if it wishes to find out the address
1902381SN/A        ranges connected to the peer ports devices.
1912657Ssaidi@eecs.umich.edu    */
1922381SN/A    void getPeerAddressRanges(AddrRangeList &range_list, bool &owner)
1932381SN/A    { peer->getDeviceAddressRanges(range_list, owner); }
1942381SN/A
1952381SN/A    /** This function is a wrapper around sendFunctional()
1962406SN/A        that breaks a larger, arbitrarily aligned access into
1972381SN/A        appropriate chunks.  The default implementation can use
1982381SN/A        getBlockSize() to determine the block size and go from there.
1992381SN/A    */
2002381SN/A    virtual void readBlob(Addr addr, uint8_t *p, int size);
2012521SN/A
2022521SN/A    /** This function is a wrapper around sendFunctional()
2032381SN/A        that breaks a larger, arbitrarily aligned access into
2042461SN/A        appropriate chunks.  The default implementation can use
2052461SN/A        getBlockSize() to determine the block size and go from there.
2062461SN/A    */
2072461SN/A    virtual void writeBlob(Addr addr, uint8_t *p, int size);
2082461SN/A
2092519SN/A    /** Fill size bytes starting at addr with byte value val.  This
2102381SN/A        should not need to be virtual, since it can be implemented in
2112381SN/A        terms of writeBlob().  However, it shouldn't be
2122381SN/A        performance-critical either, so it could be if we wanted to.
2132381SN/A    */
2142381SN/A    virtual void memsetBlob(Addr addr, uint8_t val, int size);
2152381SN/A
2162519SN/A  private:
2172381SN/A
2182381SN/A    /** Internal helper function for read/writeBlob().
2192381SN/A     */
2202461SN/A    void blobHelper(Addr addr, uint8_t *p, int size, Command cmd);
2212381SN/A};
2222381SN/A
2232519SN/A/** A simple functional port that is only meant for one way communication to
2242405SN/A * physical memory. It is only meant to be used to load data into memory before
2252405SN/A * the simulation begins.
2262405SN/A */
2272405SN/A
2282405SN/Aclass FunctionalPort : public Port
2292641Sstever@eecs.umich.edu{
2302381SN/A  public:
2312381SN/A    virtual bool recvTiming(Packet &pkt) { panic("FuncPort is UniDir"); }
2322520SN/A    virtual Tick recvAtomic(Packet &pkt) { panic("FuncPort is UniDir"); }
2332520SN/A    virtual void recvFunctional(Packet &pkt) { panic("FuncPort is UniDir"); }
2342520SN/A    virtual void recvStatusChange(Status status) {panic("FuncPort is UniDir");}
2352520SN/A};
2362520SN/A
2372520SN/A
2382520SN/A#endif //__MEM_PORT_HH__
2392520SN/A