timing.hh revision 7945
12623SN/A/* 22623SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 32623SN/A * All rights reserved. 42623SN/A * 52623SN/A * Redistribution and use in source and binary forms, with or without 62623SN/A * modification, are permitted provided that the following conditions are 72623SN/A * met: redistributions of source code must retain the above copyright 82623SN/A * notice, this list of conditions and the following disclaimer; 92623SN/A * redistributions in binary form must reproduce the above copyright 102623SN/A * notice, this list of conditions and the following disclaimer in the 112623SN/A * documentation and/or other materials provided with the distribution; 122623SN/A * neither the name of the copyright holders nor the names of its 132623SN/A * contributors may be used to endorse or promote products derived from 142623SN/A * this software without specific prior written permission. 152623SN/A * 162623SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172623SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182623SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192623SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202623SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212623SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222623SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232623SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242623SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252623SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262623SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Steve Reinhardt 292623SN/A */ 302623SN/A 312623SN/A#ifndef __CPU_SIMPLE_TIMING_HH__ 322623SN/A#define __CPU_SIMPLE_TIMING_HH__ 332623SN/A 342623SN/A#include "cpu/simple/base.hh" 352623SN/A#include "cpu/translation.hh" 365529Snate@binkert.org 375529Snate@binkert.org#include "params/TimingSimpleCPU.hh" 382623SN/A 392623SN/Aclass TimingSimpleCPU : public BaseSimpleCPU 402623SN/A{ 412623SN/A public: 425529Snate@binkert.org 432623SN/A TimingSimpleCPU(TimingSimpleCPUParams * params); 442623SN/A virtual ~TimingSimpleCPU(); 452623SN/A 462623SN/A virtual void init(); 472623SN/A 482839Sktlim@umich.edu public: 492798Sktlim@umich.edu Event *drainEvent; 502623SN/A 512623SN/A private: 525728Sgblack@eecs.umich.edu 535728Sgblack@eecs.umich.edu /* 545728Sgblack@eecs.umich.edu * If an access needs to be broken into fragments, currently at most two, 555728Sgblack@eecs.umich.edu * the the following two classes are used as the sender state of the 565728Sgblack@eecs.umich.edu * packets so the CPU can keep track of everything. In the main packet 575728Sgblack@eecs.umich.edu * sender state, there's an array with a spot for each fragment. If a 585728Sgblack@eecs.umich.edu * fragment has already been accepted by the CPU, aka isn't waiting for 595728Sgblack@eecs.umich.edu * a retry, it's pointer is NULL. After each fragment has successfully 605728Sgblack@eecs.umich.edu * been processed, the "outstanding" counter is decremented. Once the 615728Sgblack@eecs.umich.edu * count is zero, the entire larger access is complete. 625728Sgblack@eecs.umich.edu */ 635728Sgblack@eecs.umich.edu class SplitMainSenderState : public Packet::SenderState 645728Sgblack@eecs.umich.edu { 655728Sgblack@eecs.umich.edu public: 665728Sgblack@eecs.umich.edu int outstanding; 675728Sgblack@eecs.umich.edu PacketPtr fragments[2]; 685728Sgblack@eecs.umich.edu 695728Sgblack@eecs.umich.edu int 705728Sgblack@eecs.umich.edu getPendingFragment() 715728Sgblack@eecs.umich.edu { 725728Sgblack@eecs.umich.edu if (fragments[0]) { 735728Sgblack@eecs.umich.edu return 0; 745728Sgblack@eecs.umich.edu } else if (fragments[1]) { 755728Sgblack@eecs.umich.edu return 1; 765728Sgblack@eecs.umich.edu } else { 775728Sgblack@eecs.umich.edu return -1; 785728Sgblack@eecs.umich.edu } 795728Sgblack@eecs.umich.edu } 805728Sgblack@eecs.umich.edu }; 815728Sgblack@eecs.umich.edu 825728Sgblack@eecs.umich.edu class SplitFragmentSenderState : public Packet::SenderState 835728Sgblack@eecs.umich.edu { 845728Sgblack@eecs.umich.edu public: 855728Sgblack@eecs.umich.edu SplitFragmentSenderState(PacketPtr _bigPkt, int _index) : 865728Sgblack@eecs.umich.edu bigPkt(_bigPkt), index(_index) 875728Sgblack@eecs.umich.edu {} 885728Sgblack@eecs.umich.edu PacketPtr bigPkt; 895728Sgblack@eecs.umich.edu int index; 905728Sgblack@eecs.umich.edu 915728Sgblack@eecs.umich.edu void 925728Sgblack@eecs.umich.edu clearFromParent() 935728Sgblack@eecs.umich.edu { 945728Sgblack@eecs.umich.edu SplitMainSenderState * main_send_state = 955728Sgblack@eecs.umich.edu dynamic_cast<SplitMainSenderState *>(bigPkt->senderState); 965728Sgblack@eecs.umich.edu main_send_state->fragments[index] = NULL; 975728Sgblack@eecs.umich.edu } 985728Sgblack@eecs.umich.edu }; 995728Sgblack@eecs.umich.edu 1005728Sgblack@eecs.umich.edu class FetchTranslation : public BaseTLB::Translation 1015728Sgblack@eecs.umich.edu { 1025728Sgblack@eecs.umich.edu protected: 1035728Sgblack@eecs.umich.edu TimingSimpleCPU *cpu; 1045728Sgblack@eecs.umich.edu 1055728Sgblack@eecs.umich.edu public: 1065728Sgblack@eecs.umich.edu FetchTranslation(TimingSimpleCPU *_cpu) 1075728Sgblack@eecs.umich.edu : cpu(_cpu) 1085728Sgblack@eecs.umich.edu {} 1092623SN/A 1102623SN/A void 1112623SN/A markDelayed() 1122623SN/A { 1132948Ssaidi@eecs.umich.edu assert(cpu->_status == Running); 1142623SN/A cpu->_status = ITBWaitResponse; 1152623SN/A } 1162623SN/A 1172948Ssaidi@eecs.umich.edu void 1183401Sktlim@umich.edu finish(Fault fault, RequestPtr req, ThreadContext *tc, 1192623SN/A BaseTLB::Mode mode) 1202623SN/A { 1213647Srdreslin@umich.edu cpu->sendFetch(fault, req, tc); 1223647Srdreslin@umich.edu } 1232623SN/A }; 1242623SN/A FetchTranslation fetchTranslation; 1253349Sbinkertn@umich.edu 1262623SN/A void sendData(RequestPtr req, uint8_t *data, uint64_t *res, bool read); 1273349Sbinkertn@umich.edu void sendSplitData(RequestPtr req1, RequestPtr req2, RequestPtr req, 1282623SN/A uint8_t *data, bool read); 1292623SN/A 1302623SN/A void translationFault(Fault fault); 1312623SN/A 1324475Sstever@eecs.umich.edu void buildPacket(PacketPtr &pkt, RequestPtr req, bool read); 1334475Sstever@eecs.umich.edu void buildSplitPacket(PacketPtr &pkt1, PacketPtr &pkt2, 1342948Ssaidi@eecs.umich.edu RequestPtr req1, RequestPtr req2, RequestPtr req, 1352948Ssaidi@eecs.umich.edu uint8_t *data, bool read); 1362948Ssaidi@eecs.umich.edu 1373349Sbinkertn@umich.edu bool handleReadPacket(PacketPtr pkt); 1382948Ssaidi@eecs.umich.edu // This function always implicitly uses dcache_pkt. 1392948Ssaidi@eecs.umich.edu bool handleWritePacket(); 1405606Snate@binkert.org 1415336Shines@cs.fsu.edu class CpuPort : public Port 1423349Sbinkertn@umich.edu { 1432948Ssaidi@eecs.umich.edu protected: 1442948Ssaidi@eecs.umich.edu TimingSimpleCPU *cpu; 1452623SN/A Tick lat; 1462623SN/A 1472623SN/A public: 1482623SN/A 1492623SN/A CpuPort(const std::string &_name, TimingSimpleCPU *_cpu, Tick _lat) 1502623SN/A : Port(_name, _cpu), cpu(_cpu), lat(_lat), retryEvent(this) 1512948Ssaidi@eecs.umich.edu { } 1522948Ssaidi@eecs.umich.edu 1532623SN/A bool snoopRangeSent; 1542623SN/A 1552623SN/A protected: 1562623SN/A 1573349Sbinkertn@umich.edu virtual Tick recvAtomic(PacketPtr pkt); 1582623SN/A 1592657Ssaidi@eecs.umich.edu virtual void recvFunctional(PacketPtr pkt); 1602948Ssaidi@eecs.umich.edu 1612948Ssaidi@eecs.umich.edu virtual void recvStatusChange(Status status); 1622948Ssaidi@eecs.umich.edu 1632948Ssaidi@eecs.umich.edu virtual void getDeviceAddressRanges(AddrRangeList &resp, 1642948Ssaidi@eecs.umich.edu bool &snoop) 1652948Ssaidi@eecs.umich.edu { resp.clear(); snoop = false; } 1662948Ssaidi@eecs.umich.edu 1675336Shines@cs.fsu.edu struct TickEvent : public Event 1682948Ssaidi@eecs.umich.edu { 1692948Ssaidi@eecs.umich.edu PacketPtr pkt; 1702948Ssaidi@eecs.umich.edu TimingSimpleCPU *cpu; 1712948Ssaidi@eecs.umich.edu CpuPort *port; 1722623SN/A 1732623SN/A TickEvent(TimingSimpleCPU *_cpu) : cpu(_cpu) {} 1742623SN/A const char *description() const { return "Timing CPU tick"; } 1752623SN/A void schedule(PacketPtr _pkt, Tick t); 1762623SN/A }; 1772623SN/A 1782948Ssaidi@eecs.umich.edu EventWrapper<Port, &Port::sendRetry> retryEvent; 1792948Ssaidi@eecs.umich.edu }; 1802623SN/A 1812623SN/A class IcachePort : public CpuPort 1824192Sktlim@umich.edu { 1834192Sktlim@umich.edu public: 1842623SN/A 1852623SN/A IcachePort(TimingSimpleCPU *_cpu, Tick _lat) 1863349Sbinkertn@umich.edu : CpuPort(_cpu->name() + "-iport", _cpu, _lat), tickEvent(_cpu) 1872623SN/A { } 1882657Ssaidi@eecs.umich.edu 1892948Ssaidi@eecs.umich.edu protected: 1902948Ssaidi@eecs.umich.edu 1912948Ssaidi@eecs.umich.edu virtual bool recvTiming(PacketPtr pkt); 1922948Ssaidi@eecs.umich.edu 1932948Ssaidi@eecs.umich.edu virtual void recvRetry(); 1942948Ssaidi@eecs.umich.edu 1955336Shines@cs.fsu.edu struct ITickEvent : public TickEvent 1962948Ssaidi@eecs.umich.edu { 1972948Ssaidi@eecs.umich.edu 1982948Ssaidi@eecs.umich.edu ITickEvent(TimingSimpleCPU *_cpu) 1992948Ssaidi@eecs.umich.edu : TickEvent(_cpu) {} 2002623SN/A void process(); 2012623SN/A const char *description() const { return "Timing CPU icache tick"; } 2022623SN/A }; 2032623SN/A 2042623SN/A ITickEvent tickEvent; 2053349Sbinkertn@umich.edu 2063349Sbinkertn@umich.edu }; 2072623SN/A 2083222Sktlim@umich.edu class DcachePort : public CpuPort 2093170Sstever@eecs.umich.edu { 2102623SN/A public: 2112623SN/A 2122856Srdreslin@umich.edu DcachePort(TimingSimpleCPU *_cpu, Tick _lat) 2132856Srdreslin@umich.edu : CpuPort(_cpu->name() + "-dport", _cpu, _lat), tickEvent(_cpu) 2142623SN/A { } 2152623SN/A 2162623SN/A virtual void setPeer(Port *port); 2172901Ssaidi@eecs.umich.edu 2182798Sktlim@umich.edu protected: 2192798Sktlim@umich.edu 2202798Sktlim@umich.edu virtual bool recvTiming(PacketPtr pkt); 2212623SN/A 2222623SN/A virtual void recvRetry(); 2232623SN/A 2242623SN/A struct DTickEvent : public TickEvent 2252623SN/A { 2262623SN/A DTickEvent(TimingSimpleCPU *_cpu) 2272623SN/A : TickEvent(_cpu) {} 2282623SN/A void process(); 2295177Sgblack@eecs.umich.edu const char *description() const { return "Timing CPU dcache tick"; } 2305177Sgblack@eecs.umich.edu }; 2315177Sgblack@eecs.umich.edu 2322623SN/A DTickEvent tickEvent; 2332623SN/A 2342623SN/A }; 2355177Sgblack@eecs.umich.edu 2365177Sgblack@eecs.umich.edu IcachePort icachePort; 2375177Sgblack@eecs.umich.edu DcachePort dcachePort; 2382623SN/A 2393349Sbinkertn@umich.edu PacketPtr ifetch_pkt; 2403349Sbinkertn@umich.edu PacketPtr dcache_pkt; 2412644Sstever@eecs.umich.edu 2424471Sstever@eecs.umich.edu Tick previousTick; 2435315Sstever@gmail.com 2445315Sstever@gmail.com public: 2455315Sstever@gmail.com 2465315Sstever@gmail.com virtual Port *getPort(const std::string &if_name, int idx = -1); 2475315Sstever@gmail.com 2485315Sstever@gmail.com virtual void serialize(std::ostream &os); 2492798Sktlim@umich.edu virtual void unserialize(Checkpoint *cp, const std::string §ion); 2504471Sstever@eecs.umich.edu 2514471Sstever@eecs.umich.edu virtual unsigned int drain(Event *drain_event); 2525710Scws3k@cs.virginia.edu virtual void resume(); 2534471Sstever@eecs.umich.edu 2545103Ssaidi@eecs.umich.edu void switchOut(); 2555103Ssaidi@eecs.umich.edu void takeOverFrom(BaseCPU *oldCPU); 2565103Ssaidi@eecs.umich.edu 2575103Ssaidi@eecs.umich.edu virtual void activateContext(int thread_num, int delay); 2585103Ssaidi@eecs.umich.edu virtual void suspendContext(int thread_num); 2595336Shines@cs.fsu.edu 2605103Ssaidi@eecs.umich.edu template <class T> 2615103Ssaidi@eecs.umich.edu Fault read(Addr addr, T &data, unsigned flags); 2622839Sktlim@umich.edu 2632623SN/A Fault readBytes(Addr addr, uint8_t *data, unsigned size, unsigned flags); 2642623SN/A 2652623SN/A template <class T> 266 Fault write(T data, Addr addr, unsigned flags, uint64_t *res); 267 268 Fault writeBytes(uint8_t *data, unsigned size, 269 Addr addr, unsigned flags, uint64_t *res); 270 271 void fetch(); 272 void sendFetch(Fault fault, RequestPtr req, ThreadContext *tc); 273 void completeIfetch(PacketPtr ); 274 void completeDataAccess(PacketPtr pkt); 275 void advanceInst(Fault fault); 276 277 /** 278 * Print state of address in memory system via PrintReq (for 279 * debugging). 280 */ 281 void printAddr(Addr a); 282 283 /** 284 * Finish a DTB translation. 285 * @param state The DTB translation state. 286 */ 287 void finishTranslation(WholeTranslationState *state); 288 289 private: 290 291 // The backend for writeBytes and write. It's the same as writeBytes, but 292 // doesn't make a copy of data. 293 Fault writeTheseBytes(uint8_t *data, unsigned size, 294 Addr addr, unsigned flags, uint64_t *res); 295 296 typedef EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch> FetchEvent; 297 FetchEvent fetchEvent; 298 299 struct IprEvent : Event { 300 Packet *pkt; 301 TimingSimpleCPU *cpu; 302 IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu, Tick t); 303 virtual void process(); 304 virtual const char *description() const; 305 }; 306 307 void completeDrain(); 308}; 309 310#endif // __CPU_SIMPLE_TIMING_HH__ 311