timing.hh revision 9095
11689SN/A/* 29444SAndreas.Sandberg@ARM.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 39444SAndreas.Sandberg@ARM.com * All rights reserved. 49444SAndreas.Sandberg@ARM.com * 59444SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without 69444SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are 79444SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright 89444SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer; 99444SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright 109444SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the 119444SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution; 129444SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its 139444SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from 142329SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271689SN/A * 281689SN/A * Authors: Steve Reinhardt 291689SN/A */ 301689SN/A 311689SN/A#ifndef __CPU_SIMPLE_TIMING_HH__ 321689SN/A#define __CPU_SIMPLE_TIMING_HH__ 331689SN/A 341689SN/A#include "cpu/simple/base.hh" 351689SN/A#include "cpu/translation.hh" 361689SN/A#include "params/TimingSimpleCPU.hh" 371689SN/A 381689SN/Aclass TimingSimpleCPU : public BaseSimpleCPU 392665Ssaidi@eecs.umich.edu{ 402665Ssaidi@eecs.umich.edu public: 412831Sksewell@umich.edu 421689SN/A TimingSimpleCPU(TimingSimpleCPUParams * params); 431689SN/A virtual ~TimingSimpleCPU(); 449944Smatt.horsnell@ARM.com 459944Smatt.horsnell@ARM.com virtual void init(); 469944Smatt.horsnell@ARM.com 476221Snate@binkert.org public: 486221Snate@binkert.org Event *drainEvent; 4913449Sgabeblack@google.com 501717SN/A private: 518232Snate@binkert.org 528232Snate@binkert.org /* 539954SFaissal.Sleiman@arm.com * If an access needs to be broken into fragments, currently at most two, 541060SN/A * the the following two classes are used as the sender state of the 556221Snate@binkert.org * packets so the CPU can keep track of everything. In the main packet 562292SN/A * sender state, there's an array with a spot for each fragment. If a 571061SN/A * fragment has already been accepted by the CPU, aka isn't waiting for 589954SFaissal.Sleiman@arm.com * a retry, it's pointer is NULL. After each fragment has successfully 5913562Snikos.nikoleris@arm.com * been processed, the "outstanding" counter is decremented. Once the 6013562Snikos.nikoleris@arm.com * count is zero, the entire larger access is complete. 619954SFaissal.Sleiman@arm.com */ 629954SFaissal.Sleiman@arm.com class SplitMainSenderState : public Packet::SenderState 631060SN/A { 649954SFaissal.Sleiman@arm.com public: 651060SN/A int outstanding; 662292SN/A PacketPtr fragments[2]; 6713562Snikos.nikoleris@arm.com 682292SN/A int 696221Snate@binkert.org getPendingFragment() 706221Snate@binkert.org { 712292SN/A if (fragments[0]) { 722292SN/A return 0; 7313562Snikos.nikoleris@arm.com } else if (fragments[1]) { 744329Sktlim@umich.edu return 1; 752292SN/A } else { 762292SN/A return -1; 772292SN/A } 782292SN/A } 792292SN/A }; 806221Snate@binkert.org 816221Snate@binkert.org class SplitFragmentSenderState : public Packet::SenderState 822292SN/A { 832292SN/A public: 8413562Snikos.nikoleris@arm.com SplitFragmentSenderState(PacketPtr _bigPkt, int _index) : 854329Sktlim@umich.edu bigPkt(_bigPkt), index(_index) 862292SN/A {} 879954SFaissal.Sleiman@arm.com PacketPtr bigPkt; 882292SN/A int index; 892292SN/A 906221Snate@binkert.org void 916221Snate@binkert.org clearFromParent() 922292SN/A { 932292SN/A SplitMainSenderState * main_send_state = 9413562Snikos.nikoleris@arm.com dynamic_cast<SplitMainSenderState *>(bigPkt->senderState); 9513453Srekai.gonzalezalberquilla@arm.com main_send_state->fragments[index] = NULL; 9613453Srekai.gonzalezalberquilla@arm.com } 9713453Srekai.gonzalezalberquilla@arm.com }; 981060SN/A 999444SAndreas.Sandberg@ARM.com class FetchTranslation : public BaseTLB::Translation 1009444SAndreas.Sandberg@ARM.com { 1019444SAndreas.Sandberg@ARM.com protected: 1029444SAndreas.Sandberg@ARM.com TimingSimpleCPU *cpu; 1039444SAndreas.Sandberg@ARM.com 1049444SAndreas.Sandberg@ARM.com public: 1059444SAndreas.Sandberg@ARM.com FetchTranslation(TimingSimpleCPU *_cpu) 10613453Srekai.gonzalezalberquilla@arm.com : cpu(_cpu) 1079444SAndreas.Sandberg@ARM.com {} 1086221Snate@binkert.org 1099444SAndreas.Sandberg@ARM.com void 11013453Srekai.gonzalezalberquilla@arm.com markDelayed() 1112292SN/A { 1129444SAndreas.Sandberg@ARM.com assert(cpu->_status == Running); 1131060SN/A cpu->_status = ITBWaitResponse; 1142292SN/A } 1152292SN/A 1162292SN/A void 1172292SN/A finish(Fault fault, RequestPtr req, ThreadContext *tc, 1182292SN/A BaseTLB::Mode mode) 1192292SN/A { 1202292SN/A cpu->sendFetch(fault, req, tc); 1214329Sktlim@umich.edu } 1224329Sktlim@umich.edu }; 1234329Sktlim@umich.edu FetchTranslation fetchTranslation; 1244329Sktlim@umich.edu 1254329Sktlim@umich.edu void sendData(RequestPtr req, uint8_t *data, uint64_t *res, bool read); 1264329Sktlim@umich.edu void sendSplitData(RequestPtr req1, RequestPtr req2, RequestPtr req, 1274329Sktlim@umich.edu uint8_t *data, bool read); 1282292SN/A 1296221Snate@binkert.org void translationFault(Fault fault); 1302292SN/A 1312292SN/A void buildPacket(PacketPtr &pkt, RequestPtr req, bool read); 1322292SN/A void buildSplitPacket(PacketPtr &pkt1, PacketPtr &pkt2, 1332292SN/A RequestPtr req1, RequestPtr req2, RequestPtr req, 1342292SN/A uint8_t *data, bool read); 1352307SN/A 1362307SN/A bool handleReadPacket(PacketPtr pkt); 1379444SAndreas.Sandberg@ARM.com // This function always implicitly uses dcache_pkt. 1382307SN/A bool handleWritePacket(); 1399444SAndreas.Sandberg@ARM.com 1409444SAndreas.Sandberg@ARM.com /** 1419444SAndreas.Sandberg@ARM.com * A TimingCPUPort overrides the default behaviour of the 1422307SN/A * recvTiming and recvRetry and implements events for the 1432307SN/A * scheduling of handling of incoming packets in the following 1442307SN/A * cycle. 1452307SN/A */ 1462307SN/A class TimingCPUPort : public CpuPort 1472307SN/A { 1489444SAndreas.Sandberg@ARM.com public: 1492307SN/A 1502292SN/A TimingCPUPort(const std::string& _name, TimingSimpleCPU* _cpu) 1512292SN/A : CpuPort(_name, _cpu), cpu(_cpu), retryEvent(this) 1522292SN/A { } 1532292SN/A 1542292SN/A protected: 15513562Snikos.nikoleris@arm.com 15614016SAndrea.Mondelli@ucf.edu /** 1572292SN/A * Snooping a coherence request, do nothing. 1586221Snate@binkert.org */ 1596221Snate@binkert.org virtual void recvTimingSnoopReq(PacketPtr pkt) { } 1602292SN/A 1613867Sbinkertn@umich.edu TimingSimpleCPU* cpu; 1626221Snate@binkert.org 1633867Sbinkertn@umich.edu struct TickEvent : public Event 16413562Snikos.nikoleris@arm.com { 1653867Sbinkertn@umich.edu PacketPtr pkt; 16613562Snikos.nikoleris@arm.com TimingSimpleCPU *cpu; 16713562Snikos.nikoleris@arm.com 1683867Sbinkertn@umich.edu TickEvent(TimingSimpleCPU *_cpu) : pkt(NULL), cpu(_cpu) {} 1692292SN/A const char *description() const { return "Timing CPU tick"; } 1702292SN/A void schedule(PacketPtr _pkt, Tick t); 1712292SN/A }; 1722292SN/A 1732292SN/A EventWrapper<MasterPort, &MasterPort::sendRetry> retryEvent; 1742292SN/A }; 1752292SN/A 1766221Snate@binkert.org class IcachePort : public TimingCPUPort 1772292SN/A { 17813562Snikos.nikoleris@arm.com public: 1792292SN/A 1802292SN/A IcachePort(TimingSimpleCPU *_cpu) 1812292SN/A : TimingCPUPort(_cpu->name() + ".icache_port", _cpu), 1822292SN/A tickEvent(_cpu) 1831060SN/A { } 1841060SN/A 1851061SN/A protected: 1861060SN/A 1871060SN/A virtual bool recvTimingResp(PacketPtr pkt); 1881060SN/A 1896221Snate@binkert.org virtual void recvRetry(); 1901061SN/A 1916221Snate@binkert.org struct ITickEvent : public TickEvent 1926221Snate@binkert.org { 1931060SN/A 1942292SN/A ITickEvent(TimingSimpleCPU *_cpu) 1952292SN/A : TickEvent(_cpu) {} 1961060SN/A void process(); 1972292SN/A const char *description() const { return "Timing CPU icache tick"; } 19814016SAndrea.Mondelli@ucf.edu }; 1996221Snate@binkert.org 2002292SN/A ITickEvent tickEvent; 2012292SN/A 2021060SN/A }; 2031060SN/A 2041061SN/A class DcachePort : public TimingCPUPort 2051060SN/A { 20613429Srekai.gonzalezalberquilla@arm.com public: 2071060SN/A 2081060SN/A DcachePort(TimingSimpleCPU *_cpu) 2091060SN/A : TimingCPUPort(_cpu->name() + ".dcache_port", _cpu), 2107897Shestness@cs.utexas.edu tickEvent(_cpu) 2117897Shestness@cs.utexas.edu { } 2127720Sgblack@eecs.umich.edu 2131060SN/A protected: 2141060SN/A 2151060SN/A virtual bool recvTimingResp(PacketPtr pkt); 2166221Snate@binkert.org 2171060SN/A virtual void recvRetry(); 2182292SN/A 2192292SN/A struct DTickEvent : public TickEvent 2202292SN/A { 2212292SN/A DTickEvent(TimingSimpleCPU *_cpu) 2222292SN/A : TickEvent(_cpu) {} 2232292SN/A void process(); 2241060SN/A const char *description() const { return "Timing CPU dcache tick"; } 2251060SN/A }; 2262292SN/A 2272292SN/A DTickEvent tickEvent; 2282292SN/A 2292292SN/A }; 2302292SN/A 2312292SN/A IcachePort icachePort; 2322292SN/A DcachePort dcachePort; 2332292SN/A 2342292SN/A PacketPtr ifetch_pkt; 2352292SN/A PacketPtr dcache_pkt; 2361060SN/A 2371060SN/A Tick previousTick; 2382292SN/A 2391060SN/A protected: 2401060SN/A 2412292SN/A /** Return a reference to the data port. */ 2422292SN/A virtual CpuPort &getDataPort() { return dcachePort; } 2436221Snate@binkert.org 2442292SN/A /** Return a reference to the instruction port. */ 2457897Shestness@cs.utexas.edu virtual CpuPort &getInstPort() { return icachePort; } 2467897Shestness@cs.utexas.edu 2471061SN/A public: 2481060SN/A 24913429Srekai.gonzalezalberquilla@arm.com virtual void serialize(std::ostream &os); 2502292SN/A virtual void unserialize(Checkpoint *cp, const std::string §ion); 2511060SN/A 25213429Srekai.gonzalezalberquilla@arm.com virtual unsigned int drain(Event *drain_event); 25313429Srekai.gonzalezalberquilla@arm.com virtual void resume(); 2541858SN/A 2551060SN/A void switchOut(); 2561060SN/A void takeOverFrom(BaseCPU *oldCPU); 25713831SAndrea.Mondelli@ucf.edu 25813831SAndrea.Mondelli@ucf.edu virtual void activateContext(ThreadID thread_num, int delay); 2591060SN/A virtual void suspendContext(ThreadID thread_num); 2601060SN/A 2611060SN/A Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags); 2622292SN/A 2631060SN/A Fault writeMem(uint8_t *data, unsigned size, 2642731Sktlim@umich.edu Addr addr, unsigned flags, uint64_t *res); 2652292SN/A 2662292SN/A void fetch(); 2672292SN/A void sendFetch(Fault fault, RequestPtr req, ThreadContext *tc); 2682292SN/A void completeIfetch(PacketPtr ); 2692292SN/A void completeDataAccess(PacketPtr pkt); 2702329SN/A void advanceInst(Fault fault); 2712329SN/A 2722329SN/A /** 2731681SN/A * Print state of address in memory system via PrintReq (for 2741060SN/A * debugging). 2752292SN/A */ 2762292SN/A void printAddr(Addr a); 2772292SN/A 2786221Snate@binkert.org /** 2792292SN/A * Finish a DTB translation. 2807897Shestness@cs.utexas.edu * @param state The DTB translation state. 2812292SN/A */ 2822292SN/A void finishTranslation(WholeTranslationState *state); 2832292SN/A 2842292SN/A private: 2852292SN/A 2862292SN/A typedef EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch> FetchEvent; 2872292SN/A FetchEvent fetchEvent; 2882292SN/A 2892292SN/A struct IprEvent : Event { 2902292SN/A Packet *pkt; 2912292SN/A TimingSimpleCPU *cpu; 2922292SN/A IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu, Tick t); 2936221Snate@binkert.org virtual void process(); 2946221Snate@binkert.org virtual const char *description() const; 2952292SN/A }; 2963867Sbinkertn@umich.edu 2976221Snate@binkert.org void completeDrain(); 2982292SN/A}; 2992292SN/A 3002292SN/A#endif // __CPU_SIMPLE_TIMING_HH__ 3012292SN/A