bridge.hh revision 5336:c7e21f4e5a2e
111308Santhony.gutierrez@amd.com/*
211308Santhony.gutierrez@amd.com * Copyright (c) 2006 The Regents of The University of Michigan
311308Santhony.gutierrez@amd.com * All rights reserved.
411308Santhony.gutierrez@amd.com *
511308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without
611308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are
711308Santhony.gutierrez@amd.com * met: redistributions of source code must retain the above copyright
811308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer;
911308Santhony.gutierrez@amd.com * redistributions in binary form must reproduce the above copyright
1011308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer in the
1111308Santhony.gutierrez@amd.com * documentation and/or other materials provided with the distribution;
1211308Santhony.gutierrez@amd.com * neither the name of the copyright holders nor the names of its
1311308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from
1411308Santhony.gutierrez@amd.com * this software without specific prior written permission.
1511308Santhony.gutierrez@amd.com *
1611308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711308Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811308Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011308Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2211308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2311308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611308Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711308Santhony.gutierrez@amd.com *
2811308Santhony.gutierrez@amd.com * Authors: Ali Saidi
2911308Santhony.gutierrez@amd.com *          Steve Reinhardt
3011308Santhony.gutierrez@amd.com */
3111308Santhony.gutierrez@amd.com
3211308Santhony.gutierrez@amd.com/**
3311308Santhony.gutierrez@amd.com * @file
3411308Santhony.gutierrez@amd.com * Declaration of a simple bus bridge object with no buffering
3511308Santhony.gutierrez@amd.com */
3611308Santhony.gutierrez@amd.com
3711308Santhony.gutierrez@amd.com#ifndef __MEM_BRIDGE_HH__
3811308Santhony.gutierrez@amd.com#define __MEM_BRIDGE_HH__
3911308Santhony.gutierrez@amd.com
4011308Santhony.gutierrez@amd.com#include <string>
4111308Santhony.gutierrez@amd.com#include <list>
4211308Santhony.gutierrez@amd.com#include <inttypes.h>
4311308Santhony.gutierrez@amd.com#include <queue>
4411308Santhony.gutierrez@amd.com
4511308Santhony.gutierrez@amd.com#include "mem/mem_object.hh"
4611308Santhony.gutierrez@amd.com#include "mem/packet.hh"
4711308Santhony.gutierrez@amd.com#include "mem/port.hh"
4811308Santhony.gutierrez@amd.com#include "params/Bridge.hh"
4911308Santhony.gutierrez@amd.com#include "sim/eventq.hh"
5011308Santhony.gutierrez@amd.com
5111308Santhony.gutierrez@amd.comclass Bridge : public MemObject
5211308Santhony.gutierrez@amd.com{
5311308Santhony.gutierrez@amd.com  protected:
5411308Santhony.gutierrez@amd.com    /** Declaration of the buses port type, one will be instantiated for each
5511308Santhony.gutierrez@amd.com        of the interfaces connecting to the bus. */
5611308Santhony.gutierrez@amd.com    class BridgePort : public Port
5711308Santhony.gutierrez@amd.com    {
5811308Santhony.gutierrez@amd.com        /** A pointer to the bridge to which this port belongs. */
5911308Santhony.gutierrez@amd.com        Bridge *bridge;
6011308Santhony.gutierrez@amd.com
6111308Santhony.gutierrez@amd.com        /**
6211308Santhony.gutierrez@amd.com         * Pointer to the port on the other side of the bridge
6311308Santhony.gutierrez@amd.com         * (connected to the other bus).
6411308Santhony.gutierrez@amd.com         */
6511308Santhony.gutierrez@amd.com        BridgePort *otherPort;
6611308Santhony.gutierrez@amd.com
6711308Santhony.gutierrez@amd.com        /** Minimum delay though this bridge. */
6811308Santhony.gutierrez@amd.com        Tick delay;
6911308Santhony.gutierrez@amd.com
7011308Santhony.gutierrez@amd.com        /** Min delay to respond to a nack. */
7111308Santhony.gutierrez@amd.com        Tick nackDelay;
7211308Santhony.gutierrez@amd.com
7311308Santhony.gutierrez@amd.com        /** Pass ranges from one side of the bridge to the other? */
7411308Santhony.gutierrez@amd.com        std::vector<Range<Addr> > filterRanges;
7511308Santhony.gutierrez@amd.com
7611308Santhony.gutierrez@amd.com        class PacketBuffer : public Packet::SenderState {
7711308Santhony.gutierrez@amd.com
7811308Santhony.gutierrez@amd.com          public:
7911308Santhony.gutierrez@amd.com            Tick ready;
8011308Santhony.gutierrez@amd.com            PacketPtr pkt;
8111308Santhony.gutierrez@amd.com            bool nackedHere;
8211308Santhony.gutierrez@amd.com            Packet::SenderState *origSenderState;
8311308Santhony.gutierrez@amd.com            short origSrc;
8411308Santhony.gutierrez@amd.com            bool expectResponse;
8511308Santhony.gutierrez@amd.com
8611308Santhony.gutierrez@amd.com            PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false)
8711308Santhony.gutierrez@amd.com                : ready(t), pkt(_pkt), nackedHere(nack),
8811308Santhony.gutierrez@amd.com                  origSenderState(_pkt->senderState),
8911308Santhony.gutierrez@amd.com                  origSrc(nack ? _pkt->getDest() : _pkt->getSrc() ),
9011308Santhony.gutierrez@amd.com                  expectResponse(_pkt->needsResponse() && !nack)
9111308Santhony.gutierrez@amd.com
9211308Santhony.gutierrez@amd.com            {
9311308Santhony.gutierrez@amd.com                if (!pkt->isResponse() && !nack)
9411308Santhony.gutierrez@amd.com                    pkt->senderState = this;
9511308Santhony.gutierrez@amd.com            }
9611308Santhony.gutierrez@amd.com
9711308Santhony.gutierrez@amd.com            void fixResponse(PacketPtr pkt)
9811308Santhony.gutierrez@amd.com            {
9911308Santhony.gutierrez@amd.com                assert(pkt->senderState == this);
10011308Santhony.gutierrez@amd.com                pkt->setDest(origSrc);
10111308Santhony.gutierrez@amd.com                pkt->senderState = origSenderState;
10211308Santhony.gutierrez@amd.com            }
10311308Santhony.gutierrez@amd.com        };
10411308Santhony.gutierrez@amd.com
10511308Santhony.gutierrez@amd.com        /**
10611308Santhony.gutierrez@amd.com         * Outbound packet queue.  Packets are held in this queue for a
10711308Santhony.gutierrez@amd.com         * specified delay to model the processing delay of the
10811308Santhony.gutierrez@amd.com         * bridge.
10911308Santhony.gutierrez@amd.com         */
11011308Santhony.gutierrez@amd.com        std::list<PacketBuffer*> sendQueue;
11111308Santhony.gutierrez@amd.com
11211308Santhony.gutierrez@amd.com        int outstandingResponses;
11311308Santhony.gutierrez@amd.com        int queuedRequests;
11411308Santhony.gutierrez@amd.com
11511308Santhony.gutierrez@amd.com        /** If we're waiting for a retry to happen.*/
11611308Santhony.gutierrez@amd.com        bool inRetry;
11711308Santhony.gutierrez@amd.com
11811308Santhony.gutierrez@amd.com        /** Max queue size for outbound packets */
11911308Santhony.gutierrez@amd.com        int reqQueueLimit;
12011308Santhony.gutierrez@amd.com
12111308Santhony.gutierrez@amd.com        /** Max queue size for reserved responses. */
12211308Santhony.gutierrez@amd.com        int respQueueLimit;
12311308Santhony.gutierrez@amd.com
12411308Santhony.gutierrez@amd.com        /**
12511308Santhony.gutierrez@amd.com         * Is this side blocked from accepting outbound packets?
12611308Santhony.gutierrez@amd.com         */
12711308Santhony.gutierrez@amd.com        bool respQueueFull();
12811308Santhony.gutierrez@amd.com        bool reqQueueFull();
12911308Santhony.gutierrez@amd.com
13011308Santhony.gutierrez@amd.com        void queueForSendTiming(PacketPtr pkt);
13111308Santhony.gutierrez@amd.com
13211308Santhony.gutierrez@amd.com        void finishSend(PacketBuffer *buf);
13311308Santhony.gutierrez@amd.com
13411308Santhony.gutierrez@amd.com        void nackRequest(PacketPtr pkt);
13511308Santhony.gutierrez@amd.com
13611308Santhony.gutierrez@amd.com        /**
13711308Santhony.gutierrez@amd.com         * Handle send event, scheduled when the packet at the head of
13811308Santhony.gutierrez@amd.com         * the outbound queue is ready to transmit (for timing
13911308Santhony.gutierrez@amd.com         * accesses only).
14011308Santhony.gutierrez@amd.com         */
14111308Santhony.gutierrez@amd.com        void trySend();
14211308Santhony.gutierrez@amd.com
14311308Santhony.gutierrez@amd.com        class SendEvent : public Event
14411308Santhony.gutierrez@amd.com        {
14511308Santhony.gutierrez@amd.com            BridgePort *port;
14611308Santhony.gutierrez@amd.com
14711308Santhony.gutierrez@amd.com          public:
14811308Santhony.gutierrez@amd.com            SendEvent(BridgePort *p)
14911308Santhony.gutierrez@amd.com                : Event(&mainEventQueue), port(p) {}
15011308Santhony.gutierrez@amd.com
15111308Santhony.gutierrez@amd.com            virtual void process() { port->trySend(); }
15211308Santhony.gutierrez@amd.com
15311308Santhony.gutierrez@amd.com            virtual const char *description() const { return "bridge send"; }
15411308Santhony.gutierrez@amd.com        };
15511308Santhony.gutierrez@amd.com
15611308Santhony.gutierrez@amd.com        SendEvent sendEvent;
15711308Santhony.gutierrez@amd.com
15811308Santhony.gutierrez@amd.com      public:
15911308Santhony.gutierrez@amd.com        /** Constructor for the BusPort.*/
16011308Santhony.gutierrez@amd.com        BridgePort(const std::string &_name, Bridge *_bridge,
16111308Santhony.gutierrez@amd.com                BridgePort *_otherPort, int _delay, int _nack_delay,
16211308Santhony.gutierrez@amd.com                int _req_limit, int _resp_limit,
16311308Santhony.gutierrez@amd.com                std::vector<Range<Addr> > filter_ranges);
16411308Santhony.gutierrez@amd.com
16511308Santhony.gutierrez@amd.com      protected:
16611308Santhony.gutierrez@amd.com
16711308Santhony.gutierrez@amd.com        /** When receiving a timing request from the peer port,
16811308Santhony.gutierrez@amd.com            pass it to the bridge. */
16911308Santhony.gutierrez@amd.com        virtual bool recvTiming(PacketPtr pkt);
17011308Santhony.gutierrez@amd.com
17111308Santhony.gutierrez@amd.com        /** When receiving a retry request from the peer port,
17211308Santhony.gutierrez@amd.com            pass it to the bridge. */
17311308Santhony.gutierrez@amd.com        virtual void recvRetry();
17411308Santhony.gutierrez@amd.com
17511308Santhony.gutierrez@amd.com        /** When receiving a Atomic requestfrom the peer port,
17611308Santhony.gutierrez@amd.com            pass it to the bridge. */
17711308Santhony.gutierrez@amd.com        virtual Tick recvAtomic(PacketPtr pkt);
17811308Santhony.gutierrez@amd.com
17911308Santhony.gutierrez@amd.com        /** When receiving a Functional request from the peer port,
18011308Santhony.gutierrez@amd.com            pass it to the bridge. */
18111308Santhony.gutierrez@amd.com        virtual void recvFunctional(PacketPtr pkt);
18211308Santhony.gutierrez@amd.com
18311308Santhony.gutierrez@amd.com        /** When receiving a status changefrom the peer port,
18411308Santhony.gutierrez@amd.com            pass it to the bridge. */
18511308Santhony.gutierrez@amd.com        virtual void recvStatusChange(Status status);
18611308Santhony.gutierrez@amd.com
18711308Santhony.gutierrez@amd.com        /** When receiving a address range request the peer port,
18811308Santhony.gutierrez@amd.com            pass it to the bridge. */
18911308Santhony.gutierrez@amd.com        virtual void getDeviceAddressRanges(AddrRangeList &resp,
19011308Santhony.gutierrez@amd.com                                            bool &snoop);
19111308Santhony.gutierrez@amd.com    };
19211308Santhony.gutierrez@amd.com
19311308Santhony.gutierrez@amd.com    BridgePort portA, portB;
19411308Santhony.gutierrez@amd.com
19511308Santhony.gutierrez@amd.com    /** If this bridge should acknowledge writes. */
19611308Santhony.gutierrez@amd.com    bool ackWrites;
19711308Santhony.gutierrez@amd.com
19811308Santhony.gutierrez@amd.com  public:
19911308Santhony.gutierrez@amd.com    typedef BridgeParams Params;
20011308Santhony.gutierrez@amd.com
20111308Santhony.gutierrez@amd.com  protected:
20211308Santhony.gutierrez@amd.com    Params *_params;
20311308Santhony.gutierrez@amd.com
20411308Santhony.gutierrez@amd.com  public:
20511308Santhony.gutierrez@amd.com    const Params *params() const { return _params; }
20611308Santhony.gutierrez@amd.com
20711308Santhony.gutierrez@amd.com    /** A function used to return the port associated with this bus object. */
20811308Santhony.gutierrez@amd.com    virtual Port *getPort(const std::string &if_name, int idx = -1);
20911308Santhony.gutierrez@amd.com
21011308Santhony.gutierrez@amd.com    virtual void init();
21111308Santhony.gutierrez@amd.com
21211308Santhony.gutierrez@amd.com    Bridge(Params *p);
21311308Santhony.gutierrez@amd.com};
21411308Santhony.gutierrez@amd.com
21511308Santhony.gutierrez@amd.com#endif //__MEM_BUS_HH__
21611308Santhony.gutierrez@amd.com