port.hh revision 8711
12381SN/A/*
28711Sandreas.hansson@arm.com * Copyright (c) 2011 ARM Limited
38711Sandreas.hansson@arm.com * All rights reserved
48711Sandreas.hansson@arm.com *
58711Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
68711Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
78711Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
88711Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
98711Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
108711Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
118711Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
128711Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
138711Sandreas.hansson@arm.com *
142381SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
152381SN/A * All rights reserved.
162381SN/A *
172381SN/A * Redistribution and use in source and binary forms, with or without
182381SN/A * modification, are permitted provided that the following conditions are
192381SN/A * met: redistributions of source code must retain the above copyright
202381SN/A * notice, this list of conditions and the following disclaimer;
212381SN/A * redistributions in binary form must reproduce the above copyright
222381SN/A * notice, this list of conditions and the following disclaimer in the
232381SN/A * documentation and/or other materials provided with the distribution;
242381SN/A * neither the name of the copyright holders nor the names of its
252381SN/A * contributors may be used to endorse or promote products derived from
262381SN/A * this software without specific prior written permission.
272381SN/A *
282381SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292381SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302381SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312381SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322381SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332381SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342381SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352381SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362381SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372381SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382381SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392665Ssaidi@eecs.umich.edu *
402665Ssaidi@eecs.umich.edu * Authors: Ron Dreslinski
412381SN/A */
422381SN/A
432381SN/A/**
442381SN/A * @file
452982Sstever@eecs.umich.edu * Port Object Declaration. Ports are used to interface memory objects to
462381SN/A * each other.  They will always come in pairs, and we refer to the other
472381SN/A * port object as the peer.  These are used to make the design more
482381SN/A * modular so that a specific interface between every type of objcet doesn't
492381SN/A * have to be created.
502381SN/A */
512381SN/A
522381SN/A#ifndef __MEM_PORT_HH__
532381SN/A#define __MEM_PORT_HH__
542381SN/A
552381SN/A#include <list>
562381SN/A
572439SN/A#include "base/misc.hh"
582381SN/A#include "base/range.hh"
596215Snate@binkert.org#include "base/types.hh"
602381SN/A#include "mem/packet.hh"
612381SN/A#include "mem/request.hh"
622381SN/A
638711Sandreas.hansson@arm.com/** This typedef is used to clean up getAddrRanges(). It's declared
642407SN/A * outside the Port object since it's also used by some mem objects.
652407SN/A * Eventually we should move this typedef to wherever Addr is
662407SN/A * defined.
672407SN/A */
682407SN/A
692407SN/Atypedef std::list<Range<Addr> > AddrRangeList;
702521SN/Atypedef std::list<Range<Addr> >::iterator AddrRangeIter;
712407SN/A
723401Sktlim@umich.educlass MemObject;
733401Sktlim@umich.edu
742381SN/A/**
752381SN/A * Ports are used to interface memory objects to
762381SN/A * each other.  They will always come in pairs, and we refer to the other
772381SN/A * port object as the peer.  These are used to make the design more
782381SN/A * modular so that a specific interface between every type of objcet doesn't
792381SN/A * have to be created.
802381SN/A *
812381SN/A * Recv accesor functions are being called from the peer interface.
822381SN/A * Send accessor functions are being called from the device the port is
832381SN/A * associated with, and it will call the peer recv. accessor function.
842381SN/A */
858708Sandreas.hansson@arm.comclass Port
862381SN/A{
875476Snate@binkert.org  protected:
882640Sstever@eecs.umich.edu    /** Descriptive name (for DPRINTF output) */
892796Sktlim@umich.edu    mutable std::string portName;
902640Sstever@eecs.umich.edu
912661Sstever@eecs.umich.edu    /** A pointer to the peer port.  Ports always come in pairs, that way they
922661Sstever@eecs.umich.edu        can use a standardized interface to communicate between different
932661Sstever@eecs.umich.edu        memory objects. */
942661Sstever@eecs.umich.edu    Port *peer;
952661Sstever@eecs.umich.edu
963401Sktlim@umich.edu    /** A pointer to the MemObject that owns this port. This may not be set. */
973401Sktlim@umich.edu    MemObject *owner;
983401Sktlim@umich.edu
992381SN/A  public:
1002640Sstever@eecs.umich.edu    /**
1012640Sstever@eecs.umich.edu     * Constructor.
1022640Sstever@eecs.umich.edu     *
1032640Sstever@eecs.umich.edu     * @param _name Port name for DPRINTF output.  Should include name
1042640Sstever@eecs.umich.edu     * of memory system object to which the port belongs.
1053401Sktlim@umich.edu     * @param _owner Pointer to the MemObject that owns this port.
1065494Sstever@gmail.com     * Will not necessarily be set.
1072640Sstever@eecs.umich.edu     */
1085605Snate@binkert.org    Port(const std::string &_name, MemObject *_owner);
1092640Sstever@eecs.umich.edu
1102640Sstever@eecs.umich.edu    /** Return port name (for DPRINTF). */
1112640Sstever@eecs.umich.edu    const std::string &name() const { return portName; }
1122640Sstever@eecs.umich.edu
1135476Snate@binkert.org    virtual ~Port();
1142640Sstever@eecs.umich.edu
1155494Sstever@gmail.com    void setName(const std::string &name)
1165494Sstever@gmail.com    { portName = name; }
1175494Sstever@gmail.com
1183401Sktlim@umich.edu    /** Function to set the pointer for the peer port. */
1194192Sktlim@umich.edu    virtual void setPeer(Port *port);
1202381SN/A
1213401Sktlim@umich.edu    /** Function to get the pointer to the peer port. */
1222409SN/A    Port *getPeer() { return peer; }
1232408SN/A
1245494Sstever@gmail.com    /** Function to set the owner of this port. */
1255605Snate@binkert.org    void setOwner(MemObject *_owner);
1265494Sstever@gmail.com
1273401Sktlim@umich.edu    /** Function to return the owner of this port. */
1283401Sktlim@umich.edu    MemObject *getOwner() { return owner; }
1293401Sktlim@umich.edu
1308709Sandreas.hansson@arm.com    bool isConnected() { return peer != NULL; }
1314190Ssaidi@eecs.umich.edu
1322381SN/A  protected:
1332381SN/A
1342406SN/A    /** These functions are protected because they should only be
1352406SN/A     * called by a peer port, never directly by any outside object. */
1362406SN/A
1372381SN/A    /** Called to recive a timing call from the peer port. */
1383349Sbinkertn@umich.edu    virtual bool recvTiming(PacketPtr pkt) = 0;
1392381SN/A
1402381SN/A    /** Called to recive a atomic call from the peer port. */
1413349Sbinkertn@umich.edu    virtual Tick recvAtomic(PacketPtr pkt) = 0;
1422381SN/A
1432381SN/A    /** Called to recive a functional call from the peer port. */
1443349Sbinkertn@umich.edu    virtual void recvFunctional(PacketPtr pkt) = 0;
1452381SN/A
1468711Sandreas.hansson@arm.com    /** Called to recieve an address range change from the peer port. */
1478711Sandreas.hansson@arm.com    virtual void recvRangeChange() = 0;
1482381SN/A
1492381SN/A    /** Called by a peer port if the send was unsuccesful, and had to
1502381SN/A        wait.  This shouldn't be valid for response paths (IO Devices).
1512381SN/A        so it is set to panic if it isn't already defined.
1522381SN/A    */
1532657Ssaidi@eecs.umich.edu    virtual void recvRetry() { panic("??"); }
1542381SN/A
1552381SN/A    /** Called by a peer port in order to determine the block size of the
1562381SN/A        device connected to this port.  It sometimes doesn't make sense for
1574432Ssaidi@eecs.umich.edu        this function to be called, so it just returns 0. Anytthing that is
1584432Ssaidi@eecs.umich.edu        concerned with the size should just ignore that.
1592381SN/A    */
1606227Snate@binkert.org    virtual unsigned deviceBlockSize() const { return 0; }
1612381SN/A
1628711Sandreas.hansson@arm.com  public:
1632381SN/A
1648711Sandreas.hansson@arm.com    /**
1658711Sandreas.hansson@arm.com     * Get a list of the non-overlapping address ranges we are
1668711Sandreas.hansson@arm.com     * responsible for. The default implementation returns an empty
1678711Sandreas.hansson@arm.com     * list and thus no address ranges. Any slave port must override
1688711Sandreas.hansson@arm.com     * this function and return a populated list with at least one
1698711Sandreas.hansson@arm.com     * item.
1708711Sandreas.hansson@arm.com     *
1718711Sandreas.hansson@arm.com     * @return a list of ranges responded to
1728711Sandreas.hansson@arm.com     */
1738711Sandreas.hansson@arm.com    virtual AddrRangeList getAddrRanges()
1748711Sandreas.hansson@arm.com    { AddrRangeList ranges; return ranges; }
1758711Sandreas.hansson@arm.com
1768711Sandreas.hansson@arm.com    /**
1778711Sandreas.hansson@arm.com     * Determine if this port is snooping or not. The default
1788711Sandreas.hansson@arm.com     * implementation returns false and thus tells the neighbour we
1798711Sandreas.hansson@arm.com     * are not snooping. Any port that is to snoop (e.g. a cache
1808711Sandreas.hansson@arm.com     * connected to a bus) has to override this function.
1818711Sandreas.hansson@arm.com     *
1828711Sandreas.hansson@arm.com     * @return true if the port should be considered a snooper
1838711Sandreas.hansson@arm.com     */
1848711Sandreas.hansson@arm.com    virtual bool isSnooping()
1858711Sandreas.hansson@arm.com    { return false; }
1862381SN/A
1872381SN/A    /** Function called by associated memory device (cache, memory, iodevice)
1882381SN/A        in order to send a timing request to the port.  Simply calls the peer
1892381SN/A        port receive function.
1902381SN/A        @return This function returns if the send was succesful in it's
1912381SN/A        recieve. If it was a failure, then the port will wait for a recvRetry
1922657Ssaidi@eecs.umich.edu        at which point it can possibly issue a successful sendTiming.  This is used in
1932381SN/A        case a cache has a higher priority request come in while waiting for
1942381SN/A        the bus to arbitrate.
1952381SN/A    */
1963349Sbinkertn@umich.edu    bool sendTiming(PacketPtr pkt) { return peer->recvTiming(pkt); }
1972381SN/A
1982662Sstever@eecs.umich.edu    /** Function called by the associated device to send an atomic
1992662Sstever@eecs.umich.edu     *   access, an access in which the data is moved and the state is
2002662Sstever@eecs.umich.edu     *   updated in one cycle, without interleaving with other memory
2012662Sstever@eecs.umich.edu     *   accesses.  Returns estimated latency of access.
2022662Sstever@eecs.umich.edu     */
2033349Sbinkertn@umich.edu    Tick sendAtomic(PacketPtr pkt)
2042381SN/A        { return peer->recvAtomic(pkt); }
2052381SN/A
2062381SN/A    /** Function called by the associated device to send a functional access,
2072381SN/A        an access in which the data is instantly updated everywhere in the
2082520SN/A        memory system, without affecting the current state of any block or
2092520SN/A        moving the block.
2102381SN/A    */
2113349Sbinkertn@umich.edu    void sendFunctional(PacketPtr pkt)
2122381SN/A        { return peer->recvFunctional(pkt); }
2132381SN/A
2148711Sandreas.hansson@arm.com    /**
2158711Sandreas.hansson@arm.com     * Called by the associated device to send a status range to the
2168711Sandreas.hansson@arm.com     * peer interface.
2178711Sandreas.hansson@arm.com     */
2188711Sandreas.hansson@arm.com    void sendRangeChange() const { peer->recvRangeChange(); }
2192381SN/A
2202381SN/A    /** When a timing access doesn't return a success, some time later the
2212381SN/A        Retry will be sent.
2222381SN/A    */
2232657Ssaidi@eecs.umich.edu    void sendRetry() { return peer->recvRetry(); }
2242381SN/A
2252381SN/A    /** Called by the associated device if it wishes to find out the blocksize
2262381SN/A        of the device on attached to the peer port.
2272381SN/A    */
2286227Snate@binkert.org    unsigned peerBlockSize() const { return peer->deviceBlockSize(); }
2292381SN/A
2302461SN/A    /** This function is a wrapper around sendFunctional()
2312461SN/A        that breaks a larger, arbitrarily aligned access into
2322461SN/A        appropriate chunks.  The default implementation can use
2332461SN/A        getBlockSize() to determine the block size and go from there.
2342461SN/A    */
2352519SN/A    virtual void readBlob(Addr addr, uint8_t *p, int size);
2362381SN/A
2372381SN/A    /** This function is a wrapper around sendFunctional()
2382381SN/A        that breaks a larger, arbitrarily aligned access into
2392381SN/A        appropriate chunks.  The default implementation can use
2402381SN/A        getBlockSize() to determine the block size and go from there.
2412381SN/A    */
2422519SN/A    virtual void writeBlob(Addr addr, uint8_t *p, int size);
2432381SN/A
2442381SN/A    /** Fill size bytes starting at addr with byte value val.  This
2452381SN/A        should not need to be virtual, since it can be implemented in
2462461SN/A        terms of writeBlob().  However, it shouldn't be
2472381SN/A        performance-critical either, so it could be if we wanted to.
2482381SN/A    */
2492519SN/A    virtual void memsetBlob(Addr addr, uint8_t val, int size);
2502405SN/A
2515314Sstever@gmail.com    /** Inject a PrintReq for the given address to print the state of
2525314Sstever@gmail.com     * that address throughout the memory system.  For debugging.
2535314Sstever@gmail.com     */
2545314Sstever@gmail.com    void printAddr(Addr a);
2555314Sstever@gmail.com
2562405SN/A  private:
2572405SN/A
2582405SN/A    /** Internal helper function for read/writeBlob().
2592405SN/A     */
2604022Sstever@eecs.umich.edu    void blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd);
2612381SN/A};
2622381SN/A
2632381SN/A#endif //__MEM_PORT_HH__
264