gem5/src/mem/bridge.hh

223 lines
6.7 KiB
C++
Raw Normal View History

/*
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Ali Saidi
* Steve Reinhardt
*/
/**
* @file
* Declaration of a simple bus bridge object with no buffering
*/
#ifndef __MEM_BRIDGE_HH__
#define __MEM_BRIDGE_HH__
#include <string>
#include <list>
#include <inttypes.h>
#include <queue>
#include "mem/mem_object.hh"
#include "mem/packet.hh"
#include "mem/port.hh"
#include "sim/eventq.hh"
class Bridge : public MemObject
{
protected:
/** Declaration of the buses port type, one will be instantiated for each
of the interfaces connecting to the bus. */
class BridgePort : public Port
{
/** A pointer to the bridge to which this port belongs. */
Bridge *bridge;
/**
* Pointer to the port on the other side of the bridge
* (connected to the other bus).
*/
BridgePort *otherPort;
/** Minimum delay though this bridge. */
Tick delay;
/** Min delay to respond to a nack. */
Tick nackDelay;
bool fixPartialWrite;
class PacketBuffer : public Packet::SenderState {
public:
Tick ready;
PacketPtr pkt;
Packet::SenderState *origSenderState;
short origSrc;
bool expectResponse;
PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false)
: ready(t), pkt(_pkt),
origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
expectResponse(_pkt->needsResponse() && !nack)
{
if (!pkt->isResponse() && !nack && !pkt->wasNacked())
Add a very poor implementation of dealing with retries on timing requests. It is especially slow with tracing on since it ends up being O(N^2). But it's probably going to have to change for the real bus anyway, so it should be rewritten then Change recvRetry() to not accept a packet. Sendtiming should be called again (and can respond with false or true) Removed Port Blocked/Unblocked and replaced with sendRetry(). Remove possibility of packet mangling if packet is going to be refused anyway in bridge src/cpu/simple/atomic.cc: src/cpu/simple/atomic.hh: src/cpu/simple/timing.cc: src/cpu/simple/timing.hh: Change recvRetry() to not accept a packet. Sendtiming should be called again (and can respond with false or true) src/dev/io_device.cc: src/dev/io_device.hh: Make DMA Timing requests/responses work. Change recvRetry() to not accept a packet. Sendtiming should be called again (and can respond with false or true) src/mem/bridge.cc: src/mem/bridge.hh: Change recvRetry() to not accept a packet. Sendtiming should be called again (and can respond with false or true) Removed Port Blocked/Unblocked and replaced with sendRetry(). Remove posibility of packet mangling if packet is going to be refused anyway. src/mem/bus.cc: src/mem/bus.hh: Add a very poor implementation of dealing with retries on timing requests. It is especially slow with tracing on since it ends up being O(N^2). But it's probably going to have to change for the real bus anyway, so it should be rewritten then src/mem/port.hh: Change recvRetry() to not accept a packet. Sendtiming should be called again (and can respond with false or true) Removed Blocked/Unblocked port status, their functionality is really duplicated in the recvRetry() method --HG-- extra : convert_revision : fab613404be54bfa7a4c67572bae7b559169e573
2006-05-31 00:57:42 +02:00
pkt->senderState = this;
}
void fixResponse(PacketPtr pkt)
{
assert(pkt->senderState == this);
pkt->setDest(origSrc);
pkt->senderState = origSenderState;
}
};
/**
* Outbound packet queue. Packets are held in this queue for a
* specified delay to model the processing delay of the
* bridge.
*/
std::list<PacketBuffer*> sendQueue;
int outstandingResponses;
int queuedRequests;
/** If we're waiting for a retry to happen.*/
bool inRetry;
/** Max queue size for outbound packets */
int reqQueueLimit;
/** Max queue size for reserved responses. */
int respQueueLimit;
/**
* Is this side blocked from accepting outbound packets?
*/
bool respQueueFull();
bool reqQueueFull();
void queueForSendTiming(PacketPtr pkt);
void finishSend(PacketBuffer *buf);
void nackRequest(PacketPtr pkt);
/**
* Handle send event, scheduled when the packet at the head of
* the outbound queue is ready to transmit (for timing
* accesses only).
*/
void trySend();
class SendEvent : public Event
{
BridgePort *port;
public:
SendEvent(BridgePort *p)
: Event(&mainEventQueue), port(p) {}
virtual void process() { port->trySend(); }
virtual const char *description() { return "bridge send event"; }
};
SendEvent sendEvent;
public:
/** Constructor for the BusPort.*/
BridgePort(const std::string &_name, Bridge *_bridge,
BridgePort *_otherPort, int _delay, int _nack_delay,
int _req_limit, int _resp_limit, bool fix_partial_write);
protected:
/** When receiving a timing request from the peer port,
pass it to the bridge. */
virtual bool recvTiming(PacketPtr pkt);
/** When receiving a retry request from the peer port,
pass it to the bridge. */
Add a very poor implementation of dealing with retries on timing requests. It is especially slow with tracing on since it ends up being O(N^2). But it's probably going to have to change for the real bus anyway, so it should be rewritten then Change recvRetry() to not accept a packet. Sendtiming should be called again (and can respond with false or true) Removed Port Blocked/Unblocked and replaced with sendRetry(). Remove possibility of packet mangling if packet is going to be refused anyway in bridge src/cpu/simple/atomic.cc: src/cpu/simple/atomic.hh: src/cpu/simple/timing.cc: src/cpu/simple/timing.hh: Change recvRetry() to not accept a packet. Sendtiming should be called again (and can respond with false or true) src/dev/io_device.cc: src/dev/io_device.hh: Make DMA Timing requests/responses work. Change recvRetry() to not accept a packet. Sendtiming should be called again (and can respond with false or true) src/mem/bridge.cc: src/mem/bridge.hh: Change recvRetry() to not accept a packet. Sendtiming should be called again (and can respond with false or true) Removed Port Blocked/Unblocked and replaced with sendRetry(). Remove posibility of packet mangling if packet is going to be refused anyway. src/mem/bus.cc: src/mem/bus.hh: Add a very poor implementation of dealing with retries on timing requests. It is especially slow with tracing on since it ends up being O(N^2). But it's probably going to have to change for the real bus anyway, so it should be rewritten then src/mem/port.hh: Change recvRetry() to not accept a packet. Sendtiming should be called again (and can respond with false or true) Removed Blocked/Unblocked port status, their functionality is really duplicated in the recvRetry() method --HG-- extra : convert_revision : fab613404be54bfa7a4c67572bae7b559169e573
2006-05-31 00:57:42 +02:00
virtual void recvRetry();
/** When receiving a Atomic requestfrom the peer port,
pass it to the bridge. */
virtual Tick recvAtomic(PacketPtr pkt);
/** When receiving a Functional request from the peer port,
pass it to the bridge. */
virtual void recvFunctional(PacketPtr pkt);
/** When receiving a status changefrom the peer port,
pass it to the bridge. */
virtual void recvStatusChange(Status status);
/** When receiving a address range request the peer port,
pass it to the bridge. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
bool &snoop);
};
BridgePort portA, portB;
/** If this bridge should acknowledge writes. */
bool ackWrites;
public:
struct Params
{
std::string name;
int req_size_a;
int req_size_b;
int resp_size_a;
int resp_size_b;
Tick delay;
Tick nack_delay;
bool write_ack;
bool fix_partial_write_a;
bool fix_partial_write_b;
};
protected:
Params *_params;
public:
const Params *params() const { return _params; }
/** A function used to return the port associated with this bus object. */
Move SimObject creation and Port connection loops into Python. Add Port and VectorPort objects and support for specifying port connections via assignment. The whole C++ ConfigNode hierarchy is gone now, as are C++ Connector objects. configs/test/fs.py: configs/test/test.py: Rewrite for new port connector syntax. src/SConscript: Remove unneeded files: - mem/connector.* - sim/config* src/dev/io_device.hh: src/mem/bridge.cc: src/mem/bridge.hh: src/mem/bus.cc: src/mem/bus.hh: src/mem/mem_object.hh: src/mem/physical.cc: src/mem/physical.hh: Allow getPort() to take an optional index to support vector ports (eventually). src/python/m5/__init__.py: Move SimObject construction and port connection operations into Python (with C++ calls). src/python/m5/config.py: Move SimObject construction and port connection operations into Python (with C++ calls). Add support for declaring and connecting MemObject ports in Python. src/python/m5/objects/Bus.py: src/python/m5/objects/PhysicalMemory.py: Add port declaration. src/sim/builder.cc: src/sim/builder.hh: src/sim/serialize.cc: src/sim/serialize.hh: ConfigNodes are gone; builder just gets the name of a .ini file section now. src/sim/main.cc: Move SimObject construction and port connection operations into Python (with C++ calls). Split remaining initialization operations into two parts, loadIniFile() and finalInit(). src/sim/param.cc: src/sim/param.hh: SimObject resolution done globally in Python now (not via ConfigNode hierarchy). src/sim/sim_object.cc: Remove unneeded #include. --HG-- extra : convert_revision : 2fa4001eaaec0c9a4231ef6e854f8e156d930dfe
2006-06-14 05:19:28 +02:00
virtual Port *getPort(const std::string &if_name, int idx = -1);
virtual void init();
Bridge(Params *p);
};
#endif //__MEM_BUS_HH__