port.hh revision 8709
12SN/A/*
21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Ron Dreslinski
292665Ssaidi@eecs.umich.edu */
302SN/A
312SN/A/**
325569Snate@binkert.org * @file
335569Snate@binkert.org * Port Object Declaration. Ports are used to interface memory objects to
342SN/A * each other.  They will always come in pairs, and we refer to the other
355569Snate@binkert.org * port object as the peer.  These are used to make the design more
363614Sgblack@eecs.umich.edu * modular so that a specific interface between every type of objcet doesn't
373614Sgblack@eecs.umich.edu * have to be created.
383614Sgblack@eecs.umich.edu */
392166SN/A
402147SN/A#ifndef __MEM_PORT_HH__
415569Snate@binkert.org#define __MEM_PORT_HH__
422167SN/A
432147SN/A#include <list>
442090SN/A
452222SN/A#include "base/misc.hh"
462090SN/A#include "base/range.hh"
472201SN/A#include "base/types.hh"
482201SN/A#include "mem/packet.hh"
492201SN/A#include "mem/request.hh"
502112SN/A
512174SN/A/** This typedef is used to clean up the parameter list of
522680Sktlim@umich.edu * getDeviceAddressRanges() and getPeerAddressRanges().  It's declared
532174SN/A * outside the Port object since it's also used by some mem objects.
542175SN/A * Eventually we should move this typedef to wherever Addr is
552222SN/A * defined.
562SN/A */
572SN/A
582203SN/Atypedef std::list<Range<Addr> > AddrRangeList;
592166SN/Atypedef std::list<Range<Addr> >::iterator AddrRangeIter;
602166SN/A
612203SN/Aclass MemObject;
622166SN/A
632222SN/A/**
645569Snate@binkert.org * Ports are used to interface memory objects to
652166SN/A * each other.  They will always come in pairs, and we refer to the other
664695Sgblack@eecs.umich.edu * port object as the peer.  These are used to make the design more
672166SN/A * modular so that a specific interface between every type of objcet doesn't
682222SN/A * have to be created.
694695Sgblack@eecs.umich.edu *
702166SN/A * Recv accesor functions are being called from the peer interface.
712166SN/A * Send accessor functions are being called from the device the port is
722203SN/A * associated with, and it will call the peer recv. accessor function.
732166SN/A */
742166SN/Aclass Port
752203SN/A{
762166SN/A  protected:
772222SN/A    /** Descriptive name (for DPRINTF output) */
785569Snate@binkert.org    mutable std::string portName;
792166SN/A
804695Sgblack@eecs.umich.edu    /** A pointer to the peer port.  Ports always come in pairs, that way they
812166SN/A        can use a standardized interface to communicate between different
822222SN/A        memory objects. */
834695Sgblack@eecs.umich.edu    Port *peer;
842166SN/A
852166SN/A    /** A pointer to the MemObject that owns this port. This may not be set. */
862166SN/A    MemObject *owner;
872166SN/A
882203SN/A  public:
892166SN/A    /**
902166SN/A     * Constructor.
912147SN/A     *
922090SN/A     * @param _name Port name for DPRINTF output.  Should include name
932147SN/A     * of memory system object to which the port belongs.
942147SN/A     * @param _owner Pointer to the MemObject that owns this port.
952147SN/A     * Will not necessarily be set.
962222SN/A     */
975569Snate@binkert.org    Port(const std::string &_name, MemObject *_owner);
982112SN/A
994695Sgblack@eecs.umich.edu    /** Return port name (for DPRINTF). */
1002147SN/A    const std::string &name() const { return portName; }
1012222SN/A
1022147SN/A    virtual ~Port();
1032090SN/A
1042147SN/A    // mey be better to use subclasses & RTTI?
1052090SN/A    /** Holds the ports status.  Currently just that a range recomputation needs
1062147SN/A     * to be done. */
1072147SN/A    enum Status {
1082147SN/A        RangeChange
1092222SN/A    };
1105569Snate@binkert.org
1115569Snate@binkert.org    void setName(const std::string &name)
1125569Snate@binkert.org    { portName = name; }
1135569Snate@binkert.org
1142112SN/A    /** Function to set the pointer for the peer port. */
1154695Sgblack@eecs.umich.edu    virtual void setPeer(Port *port);
1162147SN/A
1172222SN/A    /** Function to get the pointer to the peer port. */
1182203SN/A    Port *getPeer() { return peer; }
1192680Sktlim@umich.edu
1202203SN/A    /** Function to set the owner of this port. */
1212147SN/A    void setOwner(MemObject *_owner);
1222090SN/A
1232147SN/A    /** Function to return the owner of this port. */
1242090SN/A    MemObject *getOwner() { return owner; }
1252147SN/A
1262147SN/A    /** Inform the peer port to delete itself and notify it's owner about it's
1272147SN/A     * demise. */
1282222SN/A    void removeConn();
1295569Snate@binkert.org
1305569Snate@binkert.org    bool isConnected() { return peer != NULL; }
1315569Snate@binkert.org
1325569Snate@binkert.org  protected:
1332112SN/A
1344695Sgblack@eecs.umich.edu    /** These functions are protected because they should only be
1352147SN/A     * called by a peer port, never directly by any outside object. */
1362222SN/A
1372147SN/A    /** Called to recive a timing call from the peer port. */
1382090SN/A    virtual bool recvTiming(PacketPtr pkt) = 0;
1392502SN/A
1402502SN/A    /** Called to recive a atomic call from the peer port. */
1414997Sgblack@eecs.umich.edu    virtual Tick recvAtomic(PacketPtr pkt) = 0;
1425568Snate@binkert.org
1435736Snate@binkert.org    /** Called to recive a functional call from the peer port. */
1442502SN/A    virtual void recvFunctional(PacketPtr pkt) = 0;
1455569Snate@binkert.org
1462502SN/A    /** Called to recieve a status change from the peer port. */
1475736Snate@binkert.org    virtual void recvStatusChange(Status status) = 0;
1482502SN/A
1492502SN/A    /** Called by a peer port if the send was unsuccesful, and had to
1504695Sgblack@eecs.umich.edu        wait.  This shouldn't be valid for response paths (IO Devices).
1512502SN/A        so it is set to panic if it isn't already defined.
1522502SN/A    */
1532502SN/A    virtual void recvRetry() { panic("??"); }
1542680Sktlim@umich.edu
1552502SN/A    /** Called by a peer port in order to determine the block size of the
1562502SN/A        device connected to this port.  It sometimes doesn't make sense for
1572502SN/A        this function to be called, so it just returns 0. Anytthing that is
1582502SN/A        concerned with the size should just ignore that.
1592090SN/A    */
1602147SN/A    virtual unsigned deviceBlockSize() const { return 0; }
1612147SN/A
1622147SN/A    /** The peer port is requesting us to reply with a list of the ranges we
1632222SN/A        are responsible for.
1645569Snate@binkert.org        @param resp is a list of ranges responded to
1652112SN/A        @param snoop is a list of ranges snooped
1665736Snate@binkert.org    */
1672502SN/A    virtual void getDeviceAddressRanges(AddrRangeList &resp,
1682502SN/A                                        bool &snoop)
1694695Sgblack@eecs.umich.edu    { panic("??"); }
1702147SN/A
1712222SN/A  public:
1724997Sgblack@eecs.umich.edu
1734997Sgblack@eecs.umich.edu    /** Function called by associated memory device (cache, memory, iodevice)
1744997Sgblack@eecs.umich.edu        in order to send a timing request to the port.  Simply calls the peer
1752147SN/A        port receive function.
1762090SN/A        @return This function returns if the send was succesful in it's
1772502SN/A        recieve. If it was a failure, then the port will wait for a recvRetry
1782090SN/A        at which point it can possibly issue a successful sendTiming.  This is used in
1792147SN/A        case a cache has a higher priority request come in while waiting for
1802147SN/A        the bus to arbitrate.
1812147SN/A    */
1822222SN/A    bool sendTiming(PacketPtr pkt) { return peer->recvTiming(pkt); }
1835569Snate@binkert.org
1842112SN/A    /** Function called by the associated device to send an atomic
1855736Snate@binkert.org     *   access, an access in which the data is moved and the state is
1862502SN/A     *   updated in one cycle, without interleaving with other memory
1872502SN/A     *   accesses.  Returns estimated latency of access.
1884695Sgblack@eecs.umich.edu     */
1892147SN/A    Tick sendAtomic(PacketPtr pkt)
1902222SN/A        { return peer->recvAtomic(pkt); }
1912147SN/A
1922090SN/A    /** Function called by the associated device to send a functional access,
1932502SN/A        an access in which the data is instantly updated everywhere in the
1942090SN/A        memory system, without affecting the current state of any block or
1952147SN/A        moving the block.
1962147SN/A    */
1972147SN/A    void sendFunctional(PacketPtr pkt)
1982222SN/A        { return peer->recvFunctional(pkt); }
1995569Snate@binkert.org
2002112SN/A    /** Called by the associated device to send a status change to the device
2015736Snate@binkert.org        connected to the peer interface.
2022502SN/A    */
2032502SN/A    void sendStatusChange(Status status) {peer->recvStatusChange(status); }
2044695Sgblack@eecs.umich.edu
2052147SN/A    /** When a timing access doesn't return a success, some time later the
2062222SN/A        Retry will be sent.
2072147SN/A    */
2082090SN/A    void sendRetry() { return peer->recvRetry(); }
2092502SN/A
2102090SN/A    /** Called by the associated device if it wishes to find out the blocksize
2112147SN/A        of the device on attached to the peer port.
2122147SN/A    */
2132147SN/A    unsigned peerBlockSize() const { return peer->deviceBlockSize(); }
2142222SN/A
2155569Snate@binkert.org    /** Called by the associated device if it wishes to find out the address
2162112SN/A        ranges connected to the peer ports devices.
2175736Snate@binkert.org    */
2182502SN/A    void getPeerAddressRanges(AddrRangeList &resp, bool &snoop)
2192502SN/A    { peer->getDeviceAddressRanges(resp, snoop); }
2204695Sgblack@eecs.umich.edu
2212147SN/A    /** This function is a wrapper around sendFunctional()
2222222SN/A        that breaks a larger, arbitrarily aligned access into
2232147SN/A        appropriate chunks.  The default implementation can use
2242090SN/A        getBlockSize() to determine the block size and go from there.
2252502SN/A    */
2262090SN/A    virtual void readBlob(Addr addr, uint8_t *p, int size);
2272147SN/A
2282147SN/A    /** This function is a wrapper around sendFunctional()
2292147SN/A        that breaks a larger, arbitrarily aligned access into
2302222SN/A        appropriate chunks.  The default implementation can use
2315569Snate@binkert.org        getBlockSize() to determine the block size and go from there.
2322112SN/A    */
2335736Snate@binkert.org    virtual void writeBlob(Addr addr, uint8_t *p, int size);
2342502SN/A
2352502SN/A    /** Fill size bytes starting at addr with byte value val.  This
2364695Sgblack@eecs.umich.edu        should not need to be virtual, since it can be implemented in
2372147SN/A        terms of writeBlob().  However, it shouldn't be
2382222SN/A        performance-critical either, so it could be if we wanted to.
2392147SN/A    */
2402090SN/A    virtual void memsetBlob(Addr addr, uint8_t val, int size);
2412502SN/A
2422502SN/A    /** Inject a PrintReq for the given address to print the state of
2434997Sgblack@eecs.umich.edu     * that address throughout the memory system.  For debugging.
2442502SN/A     */
2455569Snate@binkert.org    void printAddr(Addr a);
2462502SN/A
2475569Snate@binkert.org  private:
2484695Sgblack@eecs.umich.edu
2492505SN/A    /** Internal helper function for read/writeBlob().
2502505SN/A     */
2512502SN/A    void blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd);
2522680Sktlim@umich.edu};
2532502SN/A
2542502SN/A#endif //__MEM_PORT_HH__
2552502SN/A