tport.hh revision 3090
12914Ssaidi@eecs.umich.edu/* 22914Ssaidi@eecs.umich.edu * Copyright (c) 2006 The Regents of The University of Michigan 32914Ssaidi@eecs.umich.edu * All rights reserved. 42914Ssaidi@eecs.umich.edu * 52914Ssaidi@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 62914Ssaidi@eecs.umich.edu * modification, are permitted provided that the following conditions are 72914Ssaidi@eecs.umich.edu * met: redistributions of source code must retain the above copyright 82914Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 92914Ssaidi@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 102914Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 112914Ssaidi@eecs.umich.edu * documentation and/or other materials provided with the distribution; 122914Ssaidi@eecs.umich.edu * neither the name of the copyright holders nor the names of its 132914Ssaidi@eecs.umich.edu * contributors may be used to endorse or promote products derived from 142914Ssaidi@eecs.umich.edu * this software without specific prior written permission. 152914Ssaidi@eecs.umich.edu * 162914Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172914Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182914Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192914Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202914Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212914Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222914Ssaidi@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232914Ssaidi@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242914Ssaidi@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252914Ssaidi@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262914Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272914Ssaidi@eecs.umich.edu * 282914Ssaidi@eecs.umich.edu * Authors: Ali Saidi 292914Ssaidi@eecs.umich.edu */ 302914Ssaidi@eecs.umich.edu 312914Ssaidi@eecs.umich.edu/** 322914Ssaidi@eecs.umich.edu * @file 332914Ssaidi@eecs.umich.edu * Implement a port which adds simple support of a sendTiming() function that 342914Ssaidi@eecs.umich.edu * takes a delay. In this way the * device can immediatly call 352914Ssaidi@eecs.umich.edu * sendTiming(pkt, time) after processing a request and the request will be 362914Ssaidi@eecs.umich.edu * handled by the port even if the port bus the device connects to is blocked. 372914Ssaidi@eecs.umich.edu */ 382914Ssaidi@eecs.umich.edu 392914Ssaidi@eecs.umich.edu/** recvTiming and drain should be implemented something like this when this 402914Ssaidi@eecs.umich.edu * class is used. 412914Ssaidi@eecs.umich.edu 422914Ssaidi@eecs.umich.edubool 432914Ssaidi@eecs.umich.eduPioPort::recvTiming(Packet *pkt) 442914Ssaidi@eecs.umich.edu{ 452914Ssaidi@eecs.umich.edu if (pkt->result == Packet::Nacked) { 462914Ssaidi@eecs.umich.edu resendNacked(pkt); 472914Ssaidi@eecs.umich.edu } else { 482914Ssaidi@eecs.umich.edu Tick latency = device->recvAtomic(pkt); 492914Ssaidi@eecs.umich.edu // turn packet around to go back to requester 502914Ssaidi@eecs.umich.edu pkt->makeTimingResponse(); 512914Ssaidi@eecs.umich.edu sendTiming(pkt, latency); 522914Ssaidi@eecs.umich.edu } 532914Ssaidi@eecs.umich.edu return true; 542914Ssaidi@eecs.umich.edu} 552914Ssaidi@eecs.umich.edu 562914Ssaidi@eecs.umich.eduPioDevice::drain(Event *de) 572914Ssaidi@eecs.umich.edu{ 582914Ssaidi@eecs.umich.edu unsigned int count; 592914Ssaidi@eecs.umich.edu count = SimpleTimingPort->drain(de); 602914Ssaidi@eecs.umich.edu if (count) 612914Ssaidi@eecs.umich.edu changeState(Draining); 622914Ssaidi@eecs.umich.edu else 632914Ssaidi@eecs.umich.edu changeState(Drained); 642914Ssaidi@eecs.umich.edu return count; 652914Ssaidi@eecs.umich.edu} 662914Ssaidi@eecs.umich.edu*/ 672914Ssaidi@eecs.umich.edu 682914Ssaidi@eecs.umich.edu#ifndef __MEM_TPORT_HH__ 692914Ssaidi@eecs.umich.edu#define __MEM_TPORT_HH__ 702914Ssaidi@eecs.umich.edu 712914Ssaidi@eecs.umich.edu#include "mem/port.hh" 722914Ssaidi@eecs.umich.edu#include "sim/eventq.hh" 732914Ssaidi@eecs.umich.edu#include <list> 742914Ssaidi@eecs.umich.edu#include <string> 752914Ssaidi@eecs.umich.edu 762914Ssaidi@eecs.umich.educlass SimpleTimingPort : public Port 772914Ssaidi@eecs.umich.edu{ 782914Ssaidi@eecs.umich.edu protected: 793090Sstever@eecs.umich.edu /** A list of outgoing timing response packets that haven't been 803090Sstever@eecs.umich.edu * serviced yet. */ 812914Ssaidi@eecs.umich.edu std::list<Packet*> transmitList; 822914Ssaidi@eecs.umich.edu /** 833090Sstever@eecs.umich.edu * This class is used to implemented sendTiming() with a delay. When 843090Sstever@eecs.umich.edu * a delay is requested a new event is created. When the event time 853090Sstever@eecs.umich.edu * expires it attempts to send the packet. If it cannot, the packet 863090Sstever@eecs.umich.edu * is pushed onto the transmit list to be sent when recvRetry() is 873090Sstever@eecs.umich.edu * called. */ 882914Ssaidi@eecs.umich.edu class SendEvent : public Event 892914Ssaidi@eecs.umich.edu { 902914Ssaidi@eecs.umich.edu SimpleTimingPort *port; 912914Ssaidi@eecs.umich.edu Packet *packet; 922914Ssaidi@eecs.umich.edu 933090Sstever@eecs.umich.edu public: 942914Ssaidi@eecs.umich.edu SendEvent(SimpleTimingPort *p, Packet *pkt, Tick t) 952914Ssaidi@eecs.umich.edu : Event(&mainEventQueue), port(p), packet(pkt) 962914Ssaidi@eecs.umich.edu { setFlags(AutoDelete); schedule(curTick + t); } 972914Ssaidi@eecs.umich.edu 982914Ssaidi@eecs.umich.edu virtual void process(); 992914Ssaidi@eecs.umich.edu 1002914Ssaidi@eecs.umich.edu virtual const char *description() 1012914Ssaidi@eecs.umich.edu { return "Future scheduled sendTiming event"; } 1022914Ssaidi@eecs.umich.edu }; 1032914Ssaidi@eecs.umich.edu 1042914Ssaidi@eecs.umich.edu 1052914Ssaidi@eecs.umich.edu /** Number of timing requests that are emulating the device timing before 1062914Ssaidi@eecs.umich.edu * attempting to end up on the bus. 1072914Ssaidi@eecs.umich.edu */ 1082914Ssaidi@eecs.umich.edu int outTiming; 1092914Ssaidi@eecs.umich.edu 1102914Ssaidi@eecs.umich.edu /** If we need to drain, keep the drain event around until we're done 1112914Ssaidi@eecs.umich.edu * here.*/ 1122914Ssaidi@eecs.umich.edu Event *drainEvent; 1132914Ssaidi@eecs.umich.edu 1142914Ssaidi@eecs.umich.edu /** Schedule a sendTiming() event to be called in the future. */ 1152914Ssaidi@eecs.umich.edu void sendTiming(Packet *pkt, Tick time) 1162914Ssaidi@eecs.umich.edu { outTiming++; new SimpleTimingPort::SendEvent(this, pkt, time); } 1172914Ssaidi@eecs.umich.edu 1182914Ssaidi@eecs.umich.edu /** This function is notification that the device should attempt to send a 1192914Ssaidi@eecs.umich.edu * packet again. */ 1202914Ssaidi@eecs.umich.edu virtual void recvRetry(); 1212914Ssaidi@eecs.umich.edu 1222914Ssaidi@eecs.umich.edu void resendNacked(Packet *pkt); 1232914Ssaidi@eecs.umich.edu public: 1242914Ssaidi@eecs.umich.edu 1252914Ssaidi@eecs.umich.edu SimpleTimingPort(std::string pname) 1262914Ssaidi@eecs.umich.edu : Port(pname), outTiming(0), drainEvent(NULL) 1272914Ssaidi@eecs.umich.edu {} 1282914Ssaidi@eecs.umich.edu 1292914Ssaidi@eecs.umich.edu unsigned int drain(Event *de); 1302914Ssaidi@eecs.umich.edu}; 1312914Ssaidi@eecs.umich.edu 1322914Ssaidi@eecs.umich.edu#endif // __MEM_TPORT_HH__ 133