xbar.hh revision 9090
12SN/A/*
21762SN/A * Copyright (c) 2011-2012 ARM Limited
32SN/A * All rights reserved
42SN/A *
52SN/A * The license below extends only to copyright in the software and shall
62SN/A * not be construed as granting a license to any other intellectual
72SN/A * property including but not limited to intellectual property relating
82SN/A * to a hardware implementation of the functionality of the software
92SN/A * licensed hereunder.  You may use the software subject to the license
102SN/A * terms below provided that you ensure that this notice is replicated
112SN/A * unmodified and in its entirety in all distributions of the software,
122SN/A * modified or unmodified, in source code or in binary form.
132SN/A *
142SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
152SN/A * All rights reserved.
162SN/A *
172SN/A * Redistribution and use in source and binary forms, with or without
182SN/A * modification, are permitted provided that the following conditions are
192SN/A * met: redistributions of source code must retain the above copyright
202SN/A * notice, this list of conditions and the following disclaimer;
212SN/A * redistributions in binary form must reproduce the above copyright
222SN/A * notice, this list of conditions and the following disclaimer in the
232SN/A * documentation and/or other materials provided with the distribution;
242SN/A * neither the name of the copyright holders nor the names of its
252SN/A * contributors may be used to endorse or promote products derived from
262SN/A * this software without specific prior written permission.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292665Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302665Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332623SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342623SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
364182Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
371354SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
381858SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
391717SN/A *
402683Sktlim@umich.edu * Authors: Ron Dreslinski
411354SN/A *          Ali Saidi
421354SN/A *          Andreas Hansson
432387SN/A *          William Wang
442387SN/A */
452387SN/A
4656SN/A/**
472SN/A * @file
482SN/A * Declaration of an abstract bus base class.
491858SN/A */
502SN/A
513453Sgblack@eecs.umich.edu#ifndef __MEM_BUS_HH__
523453Sgblack@eecs.umich.edu#define __MEM_BUS_HH__
533453Sgblack@eecs.umich.edu
543453Sgblack@eecs.umich.edu#include <list>
553453Sgblack@eecs.umich.edu#include <set>
562462SN/A
572SN/A#include "base/range.hh"
58715SN/A#include "base/range_map.hh"
59715SN/A#include "base/types.hh"
60715SN/A#include "mem/mem_object.hh"
61715SN/A#include "params/BaseBus.hh"
622SN/A
632SN/A/**
643960Sgblack@eecs.umich.edu * The base bus contains the common elements of the non-coherent and
653960Sgblack@eecs.umich.edu * coherent bus. It is an abstract class that does not have any of the
663960Sgblack@eecs.umich.edu * functionality relating to the actual reception and transmission of
674182Sgblack@eecs.umich.edu * packets, as this is left for the subclasses.
684182Sgblack@eecs.umich.edu *
694182Sgblack@eecs.umich.edu * The BaseBus is responsible for the basic flow control (busy or
704182Sgblack@eecs.umich.edu * not), the administration of retries, and the address decoding.
712680Sktlim@umich.edu */
72237SN/Aclass BaseBus : public MemObject
732SN/A{
742SN/A
752SN/A  protected:
762SN/A
772SN/A    /** the clock speed for the bus */
782420SN/A    int clock;
792623SN/A    /** cycles of overhead per transaction */
802SN/A    int headerCycles;
812107SN/A    /** the width of the bus in bytes */
822159SN/A    int width;
832455SN/A    /** the next tick at which the bus will be idle */
842455SN/A    Tick tickNextIdle;
852386SN/A
862623SN/A    Event * drainEvent;
872SN/A
881371SN/A    typedef range_map<Addr, PortID>::iterator PortMapIter;
892SN/A    typedef range_map<Addr, PortID>::const_iterator PortMapConstIter;
902SN/A    range_map<Addr, PortID> portMap;
912SN/A
922SN/A    AddrRangeList defaultRange;
932SN/A
942SN/A    /**
952SN/A     * Determine if the bus is to be considered occupied when being
962SN/A     * presented with a packet from a specific port. If so, the port
972SN/A     * in question is also added to the retry list.
982SN/A     *
992SN/A     * @param port Source port on the bus presenting the packet
1001400SN/A     *
1011400SN/A     * @return True if the bus is to be considered occupied
1021400SN/A     */
1031858SN/A    bool isOccupied(Port* port);
1043453Sgblack@eecs.umich.edu
1053453Sgblack@eecs.umich.edu    /**
1062SN/A     * Deal with a destination port accepting a packet by potentially
1071400SN/A     * removing the source port from the retry list (if retrying) and
1082SN/A     * occupying the bus accordingly.
1091400SN/A     *
1102623SN/A     * @param busy_time Time to spend as a result of a successful send
1112623SN/A     */
1122SN/A    void succeededTiming(Tick busy_time);
1131400SN/A
1142683Sktlim@umich.edu    /** Timing function called by port when it is once again able to process
1152683Sktlim@umich.edu     * requests. */
1162190SN/A    void recvRetry();
1172683Sktlim@umich.edu
1182683Sktlim@umich.edu    /**
1192683Sktlim@umich.edu     * Function called by the port when the bus is recieving a range change.
1202680Sktlim@umich.edu     *
1212SN/A     * @param master_port_id id of the port that received the change
1221858SN/A     */
1232SN/A    void recvRangeChange(PortID master_port_id);
1242SN/A
1252SN/A    /** Find which port connected to this bus (if any) should be given a packet
1262SN/A     * with this address.
1272SN/A     * @param addr Address to find port for.
1282SN/A     * @return id of port that the packet should be sent out of.
1294181Sgblack@eecs.umich.edu     */
1304181Sgblack@eecs.umich.edu    PortID findPort(Addr addr);
1314182Sgblack@eecs.umich.edu
1324182Sgblack@eecs.umich.edu    // Cache for the findPort function storing recently used ports from portMap
1332SN/A    struct PortCache {
1342566SN/A        bool valid;
1354040Ssaidi@eecs.umich.edu        PortID id;
1362566SN/A        Addr start;
1372107SN/A        Addr end;
1383276Sgblack@eecs.umich.edu    };
1391469SN/A
1402623SN/A    PortCache portCache[3];
1412662Sstever@eecs.umich.edu
1422623SN/A    // Checks the cache and returns the id of the port that has the requested
1432623SN/A    // address within its range
1442623SN/A    inline PortID checkPortCache(Addr addr) {
145180SN/A        if (portCache[0].valid && addr >= portCache[0].start &&
146393SN/A            addr < portCache[0].end) {
147393SN/A            return portCache[0].id;
1482SN/A        }
1492SN/A        if (portCache[1].valid && addr >= portCache[1].start &&
150334SN/A                   addr < portCache[1].end) {
151334SN/A            return portCache[1].id;
1522SN/A        }
1532SN/A        if (portCache[2].valid && addr >= portCache[2].start &&
1542SN/A            addr < portCache[2].end) {
155334SN/A            return portCache[2].id;
156729SN/A        }
157707SN/A
158707SN/A        return InvalidPortID;
159707SN/A    }
160707SN/A
161707SN/A    // Clears the earliest entry of the cache and inserts a new port entry
1622SN/A    inline void updatePortCache(short id, Addr start, Addr end) {
1632SN/A        portCache[2].valid = portCache[1].valid;
164729SN/A        portCache[2].id    = portCache[1].id;
1652SN/A        portCache[2].start = portCache[1].start;
166124SN/A        portCache[2].end   = portCache[1].end;
167124SN/A
168334SN/A        portCache[1].valid = portCache[0].valid;
169124SN/A        portCache[1].id    = portCache[0].id;
1702SN/A        portCache[1].start = portCache[0].start;
171729SN/A        portCache[1].end   = portCache[0].end;
172729SN/A
1732SN/A        portCache[0].valid = true;
1742390SN/A        portCache[0].id    = id;
175729SN/A        portCache[0].start = start;
1762SN/A        portCache[0].end   = end;
1772SN/A    }
1782390SN/A
1792390SN/A    // Clears the cache. Needs to be called in constructor.
1802390SN/A    inline void clearPortCache() {
1812390SN/A        portCache[2].valid = false;
1822390SN/A        portCache[1].valid = false;
183729SN/A        portCache[0].valid = false;
1842SN/A    }
1852SN/A
1862390SN/A    /**
1872390SN/A     * Return the address ranges the bus is responsible for.
1882390SN/A     *
1892390SN/A     * @return a list of non-overlapping address ranges
190217SN/A     */
191237SN/A    AddrRangeList getAddrRanges() const;
1922SN/A
1931371SN/A    /** Calculate the timing parameters for the packet.  Updates the
1941371SN/A     * firstWordTime and finishTime fields of the packet object.
1952623SN/A     * Returns the tick at which the packet header is completed (which
1963918Ssaidi@eecs.umich.edu     * will be all that is sent if the target rejects the packet).
1973918Ssaidi@eecs.umich.edu     */
1981371SN/A    Tick calcPacketTiming(PacketPtr pkt);
199581SN/A
2002SN/A    /** Occupy the bus until until */
2012SN/A    void occupyBus(Tick until);
2022SN/A
2032SN/A    /**
204753SN/A     * Release the bus after being occupied and return to an idle
2052SN/A     * state where we proceed to send a retry to any potential waiting
2062SN/A     * port, or drain if asked to do so.
2072SN/A     */
208594SN/A    void releaseBus();
209595SN/A
210594SN/A    /**
211595SN/A     * Send a retry to the port at the head of the retryList. The
212705SN/A     * caller must ensure that the list is not empty.
213726SN/A     */
214726SN/A    void retryWaiting();
215726SN/A
216726SN/A    /**
217726SN/A     * Ask everyone on the bus what their size is
218726SN/A     *
219726SN/A     * @return the max of all the sizes
220726SN/A     */
221726SN/A    unsigned findBlockSize();
222726SN/A
223705SN/A    // event used to schedule a release of the bus
2243735Sstever@eecs.umich.edu    EventWrapper<BaseBus, &BaseBus::releaseBus> busIdleEvent;
225726SN/A
2262683Sktlim@umich.edu    bool inRetry;
227726SN/A    std::set<PortID> inRecvRangeChange;
228705SN/A
2293735Sstever@eecs.umich.edu    /** The master and slave ports of the bus */
230726SN/A    std::vector<SlavePort*> slavePorts;
231726SN/A    std::vector<MasterPort*> masterPorts;
2322683Sktlim@umich.edu
233726SN/A    /** Convenience typedefs. */
234705SN/A    typedef std::vector<SlavePort*>::iterator SlavePortIter;
2353735Sstever@eecs.umich.edu    typedef std::vector<MasterPort*>::iterator MasterPortIter;
236726SN/A    typedef std::vector<SlavePort*>::const_iterator SlavePortConstIter;
237726SN/A    typedef std::vector<MasterPort*>::const_iterator MasterPortConstIter;
2382683Sktlim@umich.edu
239726SN/A    /** An array of pointers to ports that retry should be called on because the
240705SN/A     * original send failed for whatever reason.*/
2413735Sstever@eecs.umich.edu    std::list<Port*> retryList;
2423735Sstever@eecs.umich.edu
243726SN/A    void addToRetryList(Port* port)
244726SN/A    {
2452683Sktlim@umich.edu        if (!inRetry) {
2462455SN/A            // The device wasn't retrying a packet, or wasn't at an
2472455SN/A            // appropriate time.
2483735Sstever@eecs.umich.edu            retryList.push_back(port);
2492455SN/A        } else {
2502455SN/A            if (!retryList.empty() && port == retryList.front()) {
2512683Sktlim@umich.edu                // The device was retrying a packet. It didn't work,
252726SN/A                // so we'll leave it at the head of the retry list.
253705SN/A                inRetry = false;
2543735Sstever@eecs.umich.edu            } else {
255726SN/A                // We are in retry, but not for this port, put it at
2562683Sktlim@umich.edu                // the end.
257726SN/A                retryList.push_back(port);
258705SN/A            }
2593735Sstever@eecs.umich.edu        }
2603735Sstever@eecs.umich.edu    }
261726SN/A
262726SN/A    /** Port that handles requests that don't match any of the interfaces.*/
2632683Sktlim@umich.edu    PortID defaultPortID;
264726SN/A
265705SN/A    /** If true, use address range provided by default device.  Any
2663735Sstever@eecs.umich.edu       address not handled by another port and not in default device's
267726SN/A       range will cause a fatal error.  If false, just send all
268726SN/A       addresses not handled by another port to default device. */
2692683Sktlim@umich.edu    bool useDefaultRange;
270726SN/A
271726SN/A    unsigned defaultBlockSize;
2723735Sstever@eecs.umich.edu    unsigned cachedBlockSize;
2733735Sstever@eecs.umich.edu    bool cachedBlockSizeValid;
274726SN/A
275726SN/A    BaseBus(const BaseBusParams *p);
2762683Sktlim@umich.edu
2772455SN/A    virtual ~BaseBus();
2782455SN/A
2793735Sstever@eecs.umich.edu  public:
2803735Sstever@eecs.umich.edu
2812455SN/A    /** A function used to return the port associated with this bus object. */
2822455SN/A    virtual MasterPort& getMasterPort(const std::string& if_name, int idx = -1);
2832683Sktlim@umich.edu    virtual SlavePort& getSlavePort(const std::string& if_name, int idx = -1);
284726SN/A
285705SN/A    virtual void startup();
2862683Sktlim@umich.edu
2872683Sktlim@umich.edu    unsigned int drain(Event *de);
2882683Sktlim@umich.edu
2892447SN/A};
2902683Sktlim@umich.edu
2912683Sktlim@umich.edu#endif //__MEM_BUS_HH__
2922683Sktlim@umich.edu