fetch1.cc revision 10713
110259SAndrew.Bardsley@arm.com/* 210259SAndrew.Bardsley@arm.com * Copyright (c) 2013-2014 ARM Limited 310259SAndrew.Bardsley@arm.com * All rights reserved 410259SAndrew.Bardsley@arm.com * 510259SAndrew.Bardsley@arm.com * The license below extends only to copyright in the software and shall 610259SAndrew.Bardsley@arm.com * not be construed as granting a license to any other intellectual 710259SAndrew.Bardsley@arm.com * property including but not limited to intellectual property relating 810259SAndrew.Bardsley@arm.com * to a hardware implementation of the functionality of the software 910259SAndrew.Bardsley@arm.com * licensed hereunder. You may use the software subject to the license 1010259SAndrew.Bardsley@arm.com * terms below provided that you ensure that this notice is replicated 1110259SAndrew.Bardsley@arm.com * unmodified and in its entirety in all distributions of the software, 1210259SAndrew.Bardsley@arm.com * modified or unmodified, in source code or in binary form. 1310259SAndrew.Bardsley@arm.com * 1410259SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without 1510259SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are 1610259SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright 1710259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer; 1810259SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright 1910259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the 2010259SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution; 2110259SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its 2210259SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from 2310259SAndrew.Bardsley@arm.com * this software without specific prior written permission. 2410259SAndrew.Bardsley@arm.com * 2510259SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610259SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710259SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810259SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910259SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010259SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110259SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210259SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310259SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410259SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510259SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610259SAndrew.Bardsley@arm.com * 3710259SAndrew.Bardsley@arm.com * Authors: Andrew Bardsley 3810259SAndrew.Bardsley@arm.com */ 3910259SAndrew.Bardsley@arm.com 4010259SAndrew.Bardsley@arm.com#include <cstring> 4110259SAndrew.Bardsley@arm.com#include <iomanip> 4210259SAndrew.Bardsley@arm.com#include <sstream> 4310259SAndrew.Bardsley@arm.com 4410259SAndrew.Bardsley@arm.com#include "base/cast.hh" 4510259SAndrew.Bardsley@arm.com#include "cpu/minor/fetch1.hh" 4610259SAndrew.Bardsley@arm.com#include "cpu/minor/pipeline.hh" 4710259SAndrew.Bardsley@arm.com#include "debug/Drain.hh" 4810259SAndrew.Bardsley@arm.com#include "debug/Fetch.hh" 4910259SAndrew.Bardsley@arm.com#include "debug/MinorTrace.hh" 5010259SAndrew.Bardsley@arm.com 5110259SAndrew.Bardsley@arm.comnamespace Minor 5210259SAndrew.Bardsley@arm.com{ 5310259SAndrew.Bardsley@arm.com 5410259SAndrew.Bardsley@arm.comFetch1::Fetch1(const std::string &name_, 5510259SAndrew.Bardsley@arm.com MinorCPU &cpu_, 5610259SAndrew.Bardsley@arm.com MinorCPUParams ¶ms, 5710259SAndrew.Bardsley@arm.com Latch<BranchData>::Output inp_, 5810259SAndrew.Bardsley@arm.com Latch<ForwardLineData>::Input out_, 5910259SAndrew.Bardsley@arm.com Latch<BranchData>::Output prediction_, 6010259SAndrew.Bardsley@arm.com Reservable &next_stage_input_buffer) : 6110259SAndrew.Bardsley@arm.com Named(name_), 6210259SAndrew.Bardsley@arm.com cpu(cpu_), 6310259SAndrew.Bardsley@arm.com inp(inp_), 6410259SAndrew.Bardsley@arm.com out(out_), 6510259SAndrew.Bardsley@arm.com prediction(prediction_), 6610259SAndrew.Bardsley@arm.com nextStageReserve(next_stage_input_buffer), 6710259SAndrew.Bardsley@arm.com icachePort(name_ + ".icache_port", *this, cpu_), 6810259SAndrew.Bardsley@arm.com lineSnap(params.fetch1LineSnapWidth), 6910259SAndrew.Bardsley@arm.com maxLineWidth(params.fetch1LineWidth), 7010259SAndrew.Bardsley@arm.com fetchLimit(params.fetch1FetchLimit), 7110259SAndrew.Bardsley@arm.com state(FetchWaitingForPC), 7210259SAndrew.Bardsley@arm.com pc(0), 7310259SAndrew.Bardsley@arm.com streamSeqNum(InstId::firstStreamSeqNum), 7410259SAndrew.Bardsley@arm.com predictionSeqNum(InstId::firstPredictionSeqNum), 7510259SAndrew.Bardsley@arm.com blocked(false), 7610259SAndrew.Bardsley@arm.com requests(name_ + ".requests", "lines", params.fetch1FetchLimit), 7710259SAndrew.Bardsley@arm.com transfers(name_ + ".transfers", "lines", params.fetch1FetchLimit), 7810259SAndrew.Bardsley@arm.com icacheState(IcacheRunning), 7910259SAndrew.Bardsley@arm.com lineSeqNum(InstId::firstLineSeqNum), 8010259SAndrew.Bardsley@arm.com numFetchesInMemorySystem(0), 8110259SAndrew.Bardsley@arm.com numFetchesInITLB(0) 8210259SAndrew.Bardsley@arm.com{ 8310259SAndrew.Bardsley@arm.com if (lineSnap == 0) { 8410259SAndrew.Bardsley@arm.com lineSnap = cpu.cacheLineSize(); 8510259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "lineSnap set to cache line size of: %d\n", 8610259SAndrew.Bardsley@arm.com lineSnap); 8710259SAndrew.Bardsley@arm.com } 8810259SAndrew.Bardsley@arm.com 8910259SAndrew.Bardsley@arm.com if (maxLineWidth == 0) { 9010259SAndrew.Bardsley@arm.com maxLineWidth = cpu.cacheLineSize(); 9110259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "maxLineWidth set to cache line size of: %d\n", 9210259SAndrew.Bardsley@arm.com maxLineWidth); 9310259SAndrew.Bardsley@arm.com } 9410259SAndrew.Bardsley@arm.com 9510259SAndrew.Bardsley@arm.com /* These assertions should be copied to the Python config. as well */ 9610259SAndrew.Bardsley@arm.com if ((lineSnap % sizeof(TheISA::MachInst)) != 0) { 9710259SAndrew.Bardsley@arm.com fatal("%s: fetch1LineSnapWidth must be a multiple " 9810259SAndrew.Bardsley@arm.com "of sizeof(TheISA::MachInst) (%d)\n", name_, 9910259SAndrew.Bardsley@arm.com sizeof(TheISA::MachInst)); 10010259SAndrew.Bardsley@arm.com } 10110259SAndrew.Bardsley@arm.com 10210259SAndrew.Bardsley@arm.com if (!(maxLineWidth >= lineSnap && 10310259SAndrew.Bardsley@arm.com (maxLineWidth % sizeof(TheISA::MachInst)) == 0)) 10410259SAndrew.Bardsley@arm.com { 10510259SAndrew.Bardsley@arm.com fatal("%s: fetch1LineWidth must be a multiple of" 10610259SAndrew.Bardsley@arm.com " sizeof(TheISA::MachInst)" 10710259SAndrew.Bardsley@arm.com " (%d), and >= fetch1LineSnapWidth (%d)\n", 10810259SAndrew.Bardsley@arm.com name_, sizeof(TheISA::MachInst), lineSnap); 10910259SAndrew.Bardsley@arm.com } 11010259SAndrew.Bardsley@arm.com 11110259SAndrew.Bardsley@arm.com if (fetchLimit < 1) { 11210259SAndrew.Bardsley@arm.com fatal("%s: fetch1FetchLimit must be >= 1 (%d)\n", name_, 11310259SAndrew.Bardsley@arm.com fetchLimit); 11410259SAndrew.Bardsley@arm.com } 11510259SAndrew.Bardsley@arm.com} 11610259SAndrew.Bardsley@arm.com 11710259SAndrew.Bardsley@arm.comvoid 11810259SAndrew.Bardsley@arm.comFetch1::fetchLine() 11910259SAndrew.Bardsley@arm.com{ 12010259SAndrew.Bardsley@arm.com /* If line_offset != 0, a request is pushed for the remainder of the 12110259SAndrew.Bardsley@arm.com * line. */ 12210259SAndrew.Bardsley@arm.com /* Use a lower, sizeof(MachInst) aligned address for the fetch */ 12310259SAndrew.Bardsley@arm.com Addr aligned_pc = pc.instAddr() & ~((Addr) lineSnap - 1); 12410259SAndrew.Bardsley@arm.com unsigned int line_offset = aligned_pc % lineSnap; 12510259SAndrew.Bardsley@arm.com unsigned int request_size = maxLineWidth - line_offset; 12610259SAndrew.Bardsley@arm.com 12710259SAndrew.Bardsley@arm.com /* Fill in the line's id */ 12810259SAndrew.Bardsley@arm.com InstId request_id(0 /* thread */, 12910259SAndrew.Bardsley@arm.com streamSeqNum, predictionSeqNum, 13010259SAndrew.Bardsley@arm.com lineSeqNum); 13110259SAndrew.Bardsley@arm.com 13210259SAndrew.Bardsley@arm.com FetchRequestPtr request = new FetchRequest(*this, request_id, pc); 13310259SAndrew.Bardsley@arm.com 13410259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Inserting fetch into the fetch queue " 13510259SAndrew.Bardsley@arm.com "%s addr: 0x%x pc: %s line_offset: %d request_size: %d\n", 13610259SAndrew.Bardsley@arm.com request_id, aligned_pc, pc, line_offset, request_size); 13710259SAndrew.Bardsley@arm.com 13810259SAndrew.Bardsley@arm.com request->request.setThreadContext(cpu.cpuId(), /* thread id */ 0); 13910259SAndrew.Bardsley@arm.com request->request.setVirt(0 /* asid */, 14010259SAndrew.Bardsley@arm.com aligned_pc, request_size, Request::INST_FETCH, cpu.instMasterId(), 14110259SAndrew.Bardsley@arm.com /* I've no idea why we need the PC, but give it */ 14210259SAndrew.Bardsley@arm.com pc.instAddr()); 14310259SAndrew.Bardsley@arm.com 14410259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Submitting ITLB request\n"); 14510259SAndrew.Bardsley@arm.com numFetchesInITLB++; 14610259SAndrew.Bardsley@arm.com 14710259SAndrew.Bardsley@arm.com request->state = FetchRequest::InTranslation; 14810259SAndrew.Bardsley@arm.com 14910259SAndrew.Bardsley@arm.com /* Reserve space in the queues upstream of requests for results */ 15010259SAndrew.Bardsley@arm.com transfers.reserve(); 15110259SAndrew.Bardsley@arm.com requests.push(request); 15210259SAndrew.Bardsley@arm.com 15310259SAndrew.Bardsley@arm.com /* Submit the translation request. The response will come 15410259SAndrew.Bardsley@arm.com * through finish/markDelayed on this request as it bears 15510259SAndrew.Bardsley@arm.com * the Translation interface */ 15610259SAndrew.Bardsley@arm.com cpu.threads[request->id.threadId]->itb->translateTiming( 15710259SAndrew.Bardsley@arm.com &request->request, 15810259SAndrew.Bardsley@arm.com cpu.getContext(request->id.threadId), 15910259SAndrew.Bardsley@arm.com request, BaseTLB::Execute); 16010259SAndrew.Bardsley@arm.com 16110259SAndrew.Bardsley@arm.com lineSeqNum++; 16210259SAndrew.Bardsley@arm.com 16310259SAndrew.Bardsley@arm.com /* Step the PC for the next line onto the line aligned next address. 16410259SAndrew.Bardsley@arm.com * Note that as instructions can span lines, this PC is only a 16510259SAndrew.Bardsley@arm.com * reliable 'new' PC if the next line has a new stream sequence number. */ 16610259SAndrew.Bardsley@arm.com#if THE_ISA == ALPHA_ISA 16710259SAndrew.Bardsley@arm.com /* Restore the low bits of the PC used as address space flags */ 16810259SAndrew.Bardsley@arm.com Addr pc_low_bits = pc.instAddr() & 16910259SAndrew.Bardsley@arm.com ((Addr) (1 << sizeof(TheISA::MachInst)) - 1); 17010259SAndrew.Bardsley@arm.com 17110259SAndrew.Bardsley@arm.com pc.set(aligned_pc + request_size + pc_low_bits); 17210259SAndrew.Bardsley@arm.com#else 17310259SAndrew.Bardsley@arm.com pc.set(aligned_pc + request_size); 17410259SAndrew.Bardsley@arm.com#endif 17510259SAndrew.Bardsley@arm.com} 17610259SAndrew.Bardsley@arm.com 17710259SAndrew.Bardsley@arm.comstd::ostream & 17810259SAndrew.Bardsley@arm.comoperator <<(std::ostream &os, Fetch1::IcacheState state) 17910259SAndrew.Bardsley@arm.com{ 18010259SAndrew.Bardsley@arm.com switch (state) { 18110259SAndrew.Bardsley@arm.com case Fetch1::IcacheRunning: 18210259SAndrew.Bardsley@arm.com os << "IcacheRunning"; 18310259SAndrew.Bardsley@arm.com break; 18410259SAndrew.Bardsley@arm.com case Fetch1::IcacheNeedsRetry: 18510259SAndrew.Bardsley@arm.com os << "IcacheNeedsRetry"; 18610259SAndrew.Bardsley@arm.com break; 18710259SAndrew.Bardsley@arm.com default: 18810259SAndrew.Bardsley@arm.com os << "IcacheState-" << static_cast<int>(state); 18910259SAndrew.Bardsley@arm.com break; 19010259SAndrew.Bardsley@arm.com } 19110259SAndrew.Bardsley@arm.com return os; 19210259SAndrew.Bardsley@arm.com} 19310259SAndrew.Bardsley@arm.com 19410259SAndrew.Bardsley@arm.comvoid 19510259SAndrew.Bardsley@arm.comFetch1::FetchRequest::makePacket() 19610259SAndrew.Bardsley@arm.com{ 19710259SAndrew.Bardsley@arm.com /* Make the necessary packet for a memory transaction */ 19810259SAndrew.Bardsley@arm.com packet = new Packet(&request, MemCmd::ReadReq); 19910259SAndrew.Bardsley@arm.com packet->allocate(); 20010259SAndrew.Bardsley@arm.com 20110259SAndrew.Bardsley@arm.com /* This FetchRequest becomes SenderState to allow the response to be 20210259SAndrew.Bardsley@arm.com * identified */ 20310259SAndrew.Bardsley@arm.com packet->pushSenderState(this); 20410259SAndrew.Bardsley@arm.com} 20510259SAndrew.Bardsley@arm.com 20610259SAndrew.Bardsley@arm.comvoid 20710379Sandreas.hansson@arm.comFetch1::FetchRequest::finish(const Fault &fault_, RequestPtr request_, 20810379Sandreas.hansson@arm.com ThreadContext *tc, BaseTLB::Mode mode) 20910259SAndrew.Bardsley@arm.com{ 21010259SAndrew.Bardsley@arm.com fault = fault_; 21110259SAndrew.Bardsley@arm.com 21210259SAndrew.Bardsley@arm.com state = Translated; 21310259SAndrew.Bardsley@arm.com fetch.handleTLBResponse(this); 21410259SAndrew.Bardsley@arm.com 21510259SAndrew.Bardsley@arm.com /* Let's try and wake up the processor for the next cycle */ 21610259SAndrew.Bardsley@arm.com fetch.cpu.wakeupOnEvent(Pipeline::Fetch1StageId); 21710259SAndrew.Bardsley@arm.com} 21810259SAndrew.Bardsley@arm.com 21910259SAndrew.Bardsley@arm.comvoid 22010259SAndrew.Bardsley@arm.comFetch1::handleTLBResponse(FetchRequestPtr response) 22110259SAndrew.Bardsley@arm.com{ 22210259SAndrew.Bardsley@arm.com numFetchesInITLB--; 22310259SAndrew.Bardsley@arm.com 22410259SAndrew.Bardsley@arm.com if (response->fault != NoFault) { 22510259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Fault in address ITLB translation: %s, " 22610259SAndrew.Bardsley@arm.com "paddr: 0x%x, vaddr: 0x%x\n", 22710259SAndrew.Bardsley@arm.com response->fault->name(), 22810259SAndrew.Bardsley@arm.com (response->request.hasPaddr() ? response->request.getPaddr() : 0), 22910259SAndrew.Bardsley@arm.com response->request.getVaddr()); 23010259SAndrew.Bardsley@arm.com 23110259SAndrew.Bardsley@arm.com if (DTRACE(MinorTrace)) 23210259SAndrew.Bardsley@arm.com minorTraceResponseLine(name(), response); 23310259SAndrew.Bardsley@arm.com } else { 23410259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Got ITLB response\n"); 23510259SAndrew.Bardsley@arm.com } 23610259SAndrew.Bardsley@arm.com 23710259SAndrew.Bardsley@arm.com response->state = FetchRequest::Translated; 23810259SAndrew.Bardsley@arm.com 23910259SAndrew.Bardsley@arm.com tryToSendToTransfers(response); 24010259SAndrew.Bardsley@arm.com} 24110259SAndrew.Bardsley@arm.com 24210259SAndrew.Bardsley@arm.comFetch1::FetchRequest::~FetchRequest() 24310259SAndrew.Bardsley@arm.com{ 24410259SAndrew.Bardsley@arm.com if (packet) 24510259SAndrew.Bardsley@arm.com delete packet; 24610259SAndrew.Bardsley@arm.com} 24710259SAndrew.Bardsley@arm.com 24810259SAndrew.Bardsley@arm.comvoid 24910259SAndrew.Bardsley@arm.comFetch1::tryToSendToTransfers(FetchRequestPtr request) 25010259SAndrew.Bardsley@arm.com{ 25110259SAndrew.Bardsley@arm.com if (!requests.empty() && requests.front() != request) { 25210259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Fetch not at front of requests queue, can't" 25310259SAndrew.Bardsley@arm.com " issue to memory\n"); 25410259SAndrew.Bardsley@arm.com return; 25510259SAndrew.Bardsley@arm.com } 25610259SAndrew.Bardsley@arm.com 25710259SAndrew.Bardsley@arm.com if (request->state == FetchRequest::InTranslation) { 25810259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Fetch still in translation, not issuing to" 25910259SAndrew.Bardsley@arm.com " memory\n"); 26010259SAndrew.Bardsley@arm.com return; 26110259SAndrew.Bardsley@arm.com } 26210259SAndrew.Bardsley@arm.com 26310259SAndrew.Bardsley@arm.com if (request->isDiscardable() || request->fault != NoFault) { 26410259SAndrew.Bardsley@arm.com /* Discarded and faulting requests carry on through transfers 26510259SAndrew.Bardsley@arm.com * as Complete/packet == NULL */ 26610259SAndrew.Bardsley@arm.com 26710259SAndrew.Bardsley@arm.com request->state = FetchRequest::Complete; 26810259SAndrew.Bardsley@arm.com moveFromRequestsToTransfers(request); 26910259SAndrew.Bardsley@arm.com 27010259SAndrew.Bardsley@arm.com /* Wake up the pipeline next cycle as there will be no event 27110259SAndrew.Bardsley@arm.com * for this queue->queue transfer */ 27210259SAndrew.Bardsley@arm.com cpu.wakeupOnEvent(Pipeline::Fetch1StageId); 27310259SAndrew.Bardsley@arm.com } else if (request->state == FetchRequest::Translated) { 27410259SAndrew.Bardsley@arm.com if (!request->packet) 27510259SAndrew.Bardsley@arm.com request->makePacket(); 27610259SAndrew.Bardsley@arm.com 27710259SAndrew.Bardsley@arm.com /* Ensure that the packet won't delete the request */ 27810259SAndrew.Bardsley@arm.com assert(request->packet->needsResponse()); 27910259SAndrew.Bardsley@arm.com 28010259SAndrew.Bardsley@arm.com if (tryToSend(request)) 28110259SAndrew.Bardsley@arm.com moveFromRequestsToTransfers(request); 28210259SAndrew.Bardsley@arm.com } else { 28310259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Not advancing line fetch\n"); 28410259SAndrew.Bardsley@arm.com } 28510259SAndrew.Bardsley@arm.com} 28610259SAndrew.Bardsley@arm.com 28710259SAndrew.Bardsley@arm.comvoid 28810259SAndrew.Bardsley@arm.comFetch1::moveFromRequestsToTransfers(FetchRequestPtr request) 28910259SAndrew.Bardsley@arm.com{ 29010259SAndrew.Bardsley@arm.com assert(!requests.empty() && requests.front() == request); 29110259SAndrew.Bardsley@arm.com 29210259SAndrew.Bardsley@arm.com requests.pop(); 29310259SAndrew.Bardsley@arm.com transfers.push(request); 29410259SAndrew.Bardsley@arm.com} 29510259SAndrew.Bardsley@arm.com 29610259SAndrew.Bardsley@arm.combool 29710259SAndrew.Bardsley@arm.comFetch1::tryToSend(FetchRequestPtr request) 29810259SAndrew.Bardsley@arm.com{ 29910259SAndrew.Bardsley@arm.com bool ret = false; 30010259SAndrew.Bardsley@arm.com 30110259SAndrew.Bardsley@arm.com if (icachePort.sendTimingReq(request->packet)) { 30210259SAndrew.Bardsley@arm.com /* Invalidate the fetch_requests packet so we don't 30310259SAndrew.Bardsley@arm.com * accidentally fail to deallocate it (or use it!) 30410259SAndrew.Bardsley@arm.com * later by overwriting it */ 30510259SAndrew.Bardsley@arm.com request->packet = NULL; 30610259SAndrew.Bardsley@arm.com request->state = FetchRequest::RequestIssuing; 30710259SAndrew.Bardsley@arm.com numFetchesInMemorySystem++; 30810259SAndrew.Bardsley@arm.com 30910259SAndrew.Bardsley@arm.com ret = true; 31010259SAndrew.Bardsley@arm.com 31110259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Issued fetch request to memory: %s\n", 31210259SAndrew.Bardsley@arm.com request->id); 31310259SAndrew.Bardsley@arm.com } else { 31410259SAndrew.Bardsley@arm.com /* Needs to be resent, wait for that */ 31510259SAndrew.Bardsley@arm.com icacheState = IcacheNeedsRetry; 31610259SAndrew.Bardsley@arm.com 31710259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Line fetch needs to retry: %s\n", 31810259SAndrew.Bardsley@arm.com request->id); 31910259SAndrew.Bardsley@arm.com } 32010259SAndrew.Bardsley@arm.com 32110259SAndrew.Bardsley@arm.com return ret; 32210259SAndrew.Bardsley@arm.com} 32310259SAndrew.Bardsley@arm.com 32410259SAndrew.Bardsley@arm.comvoid 32510259SAndrew.Bardsley@arm.comFetch1::stepQueues() 32610259SAndrew.Bardsley@arm.com{ 32710259SAndrew.Bardsley@arm.com IcacheState old_icache_state = icacheState; 32810259SAndrew.Bardsley@arm.com 32910259SAndrew.Bardsley@arm.com switch (icacheState) { 33010259SAndrew.Bardsley@arm.com case IcacheRunning: 33110259SAndrew.Bardsley@arm.com /* Move ITLB results on to the memory system */ 33210259SAndrew.Bardsley@arm.com if (!requests.empty()) { 33310259SAndrew.Bardsley@arm.com tryToSendToTransfers(requests.front()); 33410259SAndrew.Bardsley@arm.com } 33510259SAndrew.Bardsley@arm.com break; 33610259SAndrew.Bardsley@arm.com case IcacheNeedsRetry: 33710259SAndrew.Bardsley@arm.com break; 33810259SAndrew.Bardsley@arm.com } 33910259SAndrew.Bardsley@arm.com 34010259SAndrew.Bardsley@arm.com if (icacheState != old_icache_state) { 34110259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Step in state %s moving to state %s\n", 34210259SAndrew.Bardsley@arm.com old_icache_state, icacheState); 34310259SAndrew.Bardsley@arm.com } 34410259SAndrew.Bardsley@arm.com} 34510259SAndrew.Bardsley@arm.com 34610259SAndrew.Bardsley@arm.comvoid 34710259SAndrew.Bardsley@arm.comFetch1::popAndDiscard(FetchQueue &queue) 34810259SAndrew.Bardsley@arm.com{ 34910259SAndrew.Bardsley@arm.com if (!queue.empty()) { 35010259SAndrew.Bardsley@arm.com delete queue.front(); 35110259SAndrew.Bardsley@arm.com queue.pop(); 35210259SAndrew.Bardsley@arm.com } 35310259SAndrew.Bardsley@arm.com} 35410259SAndrew.Bardsley@arm.com 35510259SAndrew.Bardsley@arm.comunsigned int 35610259SAndrew.Bardsley@arm.comFetch1::numInFlightFetches() 35710259SAndrew.Bardsley@arm.com{ 35810259SAndrew.Bardsley@arm.com return requests.occupiedSpace() + 35910259SAndrew.Bardsley@arm.com transfers.occupiedSpace(); 36010259SAndrew.Bardsley@arm.com} 36110259SAndrew.Bardsley@arm.com 36210259SAndrew.Bardsley@arm.com/** Print the appropriate MinorLine line for a fetch response */ 36310259SAndrew.Bardsley@arm.comvoid 36410259SAndrew.Bardsley@arm.comFetch1::minorTraceResponseLine(const std::string &name, 36510259SAndrew.Bardsley@arm.com Fetch1::FetchRequestPtr response) const 36610259SAndrew.Bardsley@arm.com{ 36710259SAndrew.Bardsley@arm.com Request &request M5_VAR_USED = response->request; 36810259SAndrew.Bardsley@arm.com 36910259SAndrew.Bardsley@arm.com if (response->packet && response->packet->isError()) { 37010259SAndrew.Bardsley@arm.com MINORLINE(this, "id=F;%s vaddr=0x%x fault=\"error packet\"\n", 37110259SAndrew.Bardsley@arm.com response->id, request.getVaddr()); 37210259SAndrew.Bardsley@arm.com } else if (response->fault != NoFault) { 37310259SAndrew.Bardsley@arm.com MINORLINE(this, "id=F;%s vaddr=0x%x fault=\"%s\"\n", 37410259SAndrew.Bardsley@arm.com response->id, request.getVaddr(), response->fault->name()); 37510259SAndrew.Bardsley@arm.com } else { 37610259SAndrew.Bardsley@arm.com MINORLINE(this, "id=%s size=%d vaddr=0x%x paddr=0x%x\n", 37710259SAndrew.Bardsley@arm.com response->id, request.getSize(), 37810259SAndrew.Bardsley@arm.com request.getVaddr(), request.getPaddr()); 37910259SAndrew.Bardsley@arm.com } 38010259SAndrew.Bardsley@arm.com} 38110259SAndrew.Bardsley@arm.com 38210259SAndrew.Bardsley@arm.combool 38310259SAndrew.Bardsley@arm.comFetch1::recvTimingResp(PacketPtr response) 38410259SAndrew.Bardsley@arm.com{ 38510259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "recvTimingResp %d\n", numFetchesInMemorySystem); 38610259SAndrew.Bardsley@arm.com 38710259SAndrew.Bardsley@arm.com /* Only push the response if we didn't change stream? No, all responses 38810259SAndrew.Bardsley@arm.com * should hit the responses queue. It's the job of 'step' to throw them 38910259SAndrew.Bardsley@arm.com * away. */ 39010259SAndrew.Bardsley@arm.com FetchRequestPtr fetch_request = safe_cast<FetchRequestPtr> 39110259SAndrew.Bardsley@arm.com (response->popSenderState()); 39210259SAndrew.Bardsley@arm.com 39310259SAndrew.Bardsley@arm.com /* Fixup packet in fetch_request as this may have changed */ 39410259SAndrew.Bardsley@arm.com assert(!fetch_request->packet); 39510259SAndrew.Bardsley@arm.com fetch_request->packet = response; 39610259SAndrew.Bardsley@arm.com 39710259SAndrew.Bardsley@arm.com numFetchesInMemorySystem--; 39810259SAndrew.Bardsley@arm.com fetch_request->state = FetchRequest::Complete; 39910259SAndrew.Bardsley@arm.com 40010259SAndrew.Bardsley@arm.com if (DTRACE(MinorTrace)) 40110259SAndrew.Bardsley@arm.com minorTraceResponseLine(name(), fetch_request); 40210259SAndrew.Bardsley@arm.com 40310259SAndrew.Bardsley@arm.com if (response->isError()) { 40410259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Received error response packet: %s\n", 40510259SAndrew.Bardsley@arm.com fetch_request->id); 40610259SAndrew.Bardsley@arm.com } 40710259SAndrew.Bardsley@arm.com 40810259SAndrew.Bardsley@arm.com /* We go to idle even if there are more things to do on the queues as 40910259SAndrew.Bardsley@arm.com * it's the job of step to actually step us on to the next transaction */ 41010259SAndrew.Bardsley@arm.com 41110259SAndrew.Bardsley@arm.com /* Let's try and wake up the processor for the next cycle to move on 41210259SAndrew.Bardsley@arm.com * queues */ 41310259SAndrew.Bardsley@arm.com cpu.wakeupOnEvent(Pipeline::Fetch1StageId); 41410259SAndrew.Bardsley@arm.com 41510259SAndrew.Bardsley@arm.com /* Never busy */ 41610259SAndrew.Bardsley@arm.com return true; 41710259SAndrew.Bardsley@arm.com} 41810259SAndrew.Bardsley@arm.com 41910259SAndrew.Bardsley@arm.comvoid 42010713Sandreas.hansson@arm.comFetch1::recvReqRetry() 42110259SAndrew.Bardsley@arm.com{ 42210259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "recvRetry\n"); 42310259SAndrew.Bardsley@arm.com assert(icacheState == IcacheNeedsRetry); 42410259SAndrew.Bardsley@arm.com assert(!requests.empty()); 42510259SAndrew.Bardsley@arm.com 42610259SAndrew.Bardsley@arm.com FetchRequestPtr retryRequest = requests.front(); 42710259SAndrew.Bardsley@arm.com 42810259SAndrew.Bardsley@arm.com icacheState = IcacheRunning; 42910259SAndrew.Bardsley@arm.com 43010259SAndrew.Bardsley@arm.com if (tryToSend(retryRequest)) 43110259SAndrew.Bardsley@arm.com moveFromRequestsToTransfers(retryRequest); 43210259SAndrew.Bardsley@arm.com} 43310259SAndrew.Bardsley@arm.com 43410259SAndrew.Bardsley@arm.comstd::ostream & 43510259SAndrew.Bardsley@arm.comoperator <<(std::ostream &os, Fetch1::FetchState state) 43610259SAndrew.Bardsley@arm.com{ 43710259SAndrew.Bardsley@arm.com switch (state) { 43810259SAndrew.Bardsley@arm.com case Fetch1::FetchHalted: 43910259SAndrew.Bardsley@arm.com os << "FetchHalted"; 44010259SAndrew.Bardsley@arm.com break; 44110259SAndrew.Bardsley@arm.com case Fetch1::FetchWaitingForPC: 44210259SAndrew.Bardsley@arm.com os << "FetchWaitingForPC"; 44310259SAndrew.Bardsley@arm.com break; 44410259SAndrew.Bardsley@arm.com case Fetch1::FetchRunning: 44510259SAndrew.Bardsley@arm.com os << "FetchRunning"; 44610259SAndrew.Bardsley@arm.com break; 44710259SAndrew.Bardsley@arm.com default: 44810259SAndrew.Bardsley@arm.com os << "FetchState-" << static_cast<int>(state); 44910259SAndrew.Bardsley@arm.com break; 45010259SAndrew.Bardsley@arm.com } 45110259SAndrew.Bardsley@arm.com return os; 45210259SAndrew.Bardsley@arm.com} 45310259SAndrew.Bardsley@arm.com 45410259SAndrew.Bardsley@arm.comvoid 45510259SAndrew.Bardsley@arm.comFetch1::changeStream(const BranchData &branch) 45610259SAndrew.Bardsley@arm.com{ 45710259SAndrew.Bardsley@arm.com updateExpectedSeqNums(branch); 45810259SAndrew.Bardsley@arm.com 45910259SAndrew.Bardsley@arm.com /* Start fetching again if we were stopped */ 46010259SAndrew.Bardsley@arm.com switch (branch.reason) { 46110259SAndrew.Bardsley@arm.com case BranchData::SuspendThread: 46210259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Suspending fetch: %s\n", branch); 46310259SAndrew.Bardsley@arm.com state = FetchWaitingForPC; 46410259SAndrew.Bardsley@arm.com break; 46510259SAndrew.Bardsley@arm.com case BranchData::HaltFetch: 46610259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Halting fetch\n"); 46710259SAndrew.Bardsley@arm.com state = FetchHalted; 46810259SAndrew.Bardsley@arm.com break; 46910259SAndrew.Bardsley@arm.com default: 47010259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Changing stream on branch: %s\n", branch); 47110259SAndrew.Bardsley@arm.com state = FetchRunning; 47210259SAndrew.Bardsley@arm.com break; 47310259SAndrew.Bardsley@arm.com } 47410259SAndrew.Bardsley@arm.com pc = branch.target; 47510259SAndrew.Bardsley@arm.com} 47610259SAndrew.Bardsley@arm.com 47710259SAndrew.Bardsley@arm.comvoid 47810259SAndrew.Bardsley@arm.comFetch1::updateExpectedSeqNums(const BranchData &branch) 47910259SAndrew.Bardsley@arm.com{ 48010259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Updating streamSeqNum from: %d to %d," 48110259SAndrew.Bardsley@arm.com " predictionSeqNum from: %d to %d\n", 48210259SAndrew.Bardsley@arm.com streamSeqNum, branch.newStreamSeqNum, 48310259SAndrew.Bardsley@arm.com predictionSeqNum, branch.newPredictionSeqNum); 48410259SAndrew.Bardsley@arm.com 48510259SAndrew.Bardsley@arm.com /* Change the stream */ 48610259SAndrew.Bardsley@arm.com streamSeqNum = branch.newStreamSeqNum; 48710259SAndrew.Bardsley@arm.com /* Update the prediction. Note that it's possible for this to 48810259SAndrew.Bardsley@arm.com * actually set the prediction to an *older* value if new 48910259SAndrew.Bardsley@arm.com * predictions have been discarded by execute */ 49010259SAndrew.Bardsley@arm.com predictionSeqNum = branch.newPredictionSeqNum; 49110259SAndrew.Bardsley@arm.com} 49210259SAndrew.Bardsley@arm.com 49310259SAndrew.Bardsley@arm.comvoid 49410259SAndrew.Bardsley@arm.comFetch1::processResponse(Fetch1::FetchRequestPtr response, 49510259SAndrew.Bardsley@arm.com ForwardLineData &line) 49610259SAndrew.Bardsley@arm.com{ 49710259SAndrew.Bardsley@arm.com PacketPtr packet = response->packet; 49810259SAndrew.Bardsley@arm.com 49910259SAndrew.Bardsley@arm.com /* Pass the prefetch abort (if any) on to Fetch2 in a ForwardLineData 50010259SAndrew.Bardsley@arm.com * structure */ 50110259SAndrew.Bardsley@arm.com line.setFault(response->fault); 50210259SAndrew.Bardsley@arm.com /* Make sequence numbers valid in return */ 50310259SAndrew.Bardsley@arm.com line.id = response->id; 50410259SAndrew.Bardsley@arm.com /* Set PC to virtual address */ 50510259SAndrew.Bardsley@arm.com line.pc = response->pc; 50610259SAndrew.Bardsley@arm.com /* Set the lineBase, which is a sizeof(MachInst) aligned address <= 50710259SAndrew.Bardsley@arm.com * pc.instAddr() */ 50810259SAndrew.Bardsley@arm.com line.lineBaseAddr = response->request.getVaddr(); 50910259SAndrew.Bardsley@arm.com 51010259SAndrew.Bardsley@arm.com if (response->fault != NoFault) { 51110259SAndrew.Bardsley@arm.com /* Stop fetching if there was a fault */ 51210259SAndrew.Bardsley@arm.com /* Should probably try to flush the queues as well, but we 51310259SAndrew.Bardsley@arm.com * can't be sure that this fault will actually reach Execute, and we 51410259SAndrew.Bardsley@arm.com * can't (currently) selectively remove this stream from the queues */ 51510259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Stopping line fetch because of fault: %s\n", 51610259SAndrew.Bardsley@arm.com response->fault->name()); 51710259SAndrew.Bardsley@arm.com state = Fetch1::FetchWaitingForPC; 51810259SAndrew.Bardsley@arm.com } else { 51910259SAndrew.Bardsley@arm.com line.adoptPacketData(packet); 52010259SAndrew.Bardsley@arm.com /* Null the response's packet to prevent the response from trying to 52110259SAndrew.Bardsley@arm.com * deallocate the packet */ 52210259SAndrew.Bardsley@arm.com response->packet = NULL; 52310259SAndrew.Bardsley@arm.com } 52410259SAndrew.Bardsley@arm.com} 52510259SAndrew.Bardsley@arm.com 52610259SAndrew.Bardsley@arm.comvoid 52710259SAndrew.Bardsley@arm.comFetch1::evaluate() 52810259SAndrew.Bardsley@arm.com{ 52910259SAndrew.Bardsley@arm.com const BranchData &execute_branch = *inp.outputWire; 53010259SAndrew.Bardsley@arm.com const BranchData &fetch2_branch = *prediction.outputWire; 53110259SAndrew.Bardsley@arm.com ForwardLineData &line_out = *out.inputWire; 53210259SAndrew.Bardsley@arm.com 53310259SAndrew.Bardsley@arm.com assert(line_out.isBubble()); 53410259SAndrew.Bardsley@arm.com 53510259SAndrew.Bardsley@arm.com blocked = !nextStageReserve.canReserve(); 53610259SAndrew.Bardsley@arm.com 53710259SAndrew.Bardsley@arm.com /* Are we changing stream? Look to the Execute branches first, then 53810259SAndrew.Bardsley@arm.com * to predicted changes of stream from Fetch2 */ 53910259SAndrew.Bardsley@arm.com /* @todo, find better way to express ignoring branch predictions */ 54010259SAndrew.Bardsley@arm.com if (execute_branch.isStreamChange() && 54110259SAndrew.Bardsley@arm.com execute_branch.reason != BranchData::BranchPrediction) 54210259SAndrew.Bardsley@arm.com { 54310259SAndrew.Bardsley@arm.com if (state == FetchHalted) { 54410259SAndrew.Bardsley@arm.com if (execute_branch.reason == BranchData::WakeupFetch) { 54510259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Waking up fetch: %s\n", execute_branch); 54610259SAndrew.Bardsley@arm.com changeStream(execute_branch); 54710259SAndrew.Bardsley@arm.com } else { 54810259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Halted, ignoring branch: %s\n", 54910259SAndrew.Bardsley@arm.com execute_branch); 55010259SAndrew.Bardsley@arm.com } 55110259SAndrew.Bardsley@arm.com } else { 55210259SAndrew.Bardsley@arm.com changeStream(execute_branch); 55310259SAndrew.Bardsley@arm.com } 55410259SAndrew.Bardsley@arm.com 55510259SAndrew.Bardsley@arm.com if (!fetch2_branch.isBubble()) { 55610259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Ignoring simultaneous prediction: %s\n", 55710259SAndrew.Bardsley@arm.com fetch2_branch); 55810259SAndrew.Bardsley@arm.com } 55910259SAndrew.Bardsley@arm.com 56010259SAndrew.Bardsley@arm.com /* The streamSeqNum tagging in request/response ->req should handle 56110259SAndrew.Bardsley@arm.com * discarding those requests when we get to them. */ 56210259SAndrew.Bardsley@arm.com } else if (state != FetchHalted && fetch2_branch.isStreamChange()) { 56310259SAndrew.Bardsley@arm.com /* Handle branch predictions by changing the instruction source 56410259SAndrew.Bardsley@arm.com * if we're still processing the same stream (as set by streamSeqNum) 56510259SAndrew.Bardsley@arm.com * as the one of the prediction. 56610259SAndrew.Bardsley@arm.com */ 56710259SAndrew.Bardsley@arm.com if (fetch2_branch.newStreamSeqNum != streamSeqNum) { 56810259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Not changing stream on prediction: %s," 56910259SAndrew.Bardsley@arm.com " streamSeqNum mismatch\n", 57010259SAndrew.Bardsley@arm.com fetch2_branch); 57110259SAndrew.Bardsley@arm.com } else { 57210259SAndrew.Bardsley@arm.com changeStream(fetch2_branch); 57310259SAndrew.Bardsley@arm.com } 57410259SAndrew.Bardsley@arm.com } 57510259SAndrew.Bardsley@arm.com 57610259SAndrew.Bardsley@arm.com /* Can we fetch? */ 57710259SAndrew.Bardsley@arm.com /* The bare minimum requirements for initiating a fetch */ 57810259SAndrew.Bardsley@arm.com /* THREAD need to handle multiple threads */ 57910259SAndrew.Bardsley@arm.com if (state == FetchRunning && /* We are actually fetching */ 58010259SAndrew.Bardsley@arm.com !blocked && /* Space in the Fetch2 inputBuffer */ 58110259SAndrew.Bardsley@arm.com /* The thread we're going to fetch for (thread 0), is active */ 58210259SAndrew.Bardsley@arm.com cpu.getContext(0)->status() == ThreadContext::Active && 58310259SAndrew.Bardsley@arm.com numInFlightFetches() < fetchLimit) 58410259SAndrew.Bardsley@arm.com { 58510259SAndrew.Bardsley@arm.com fetchLine(); 58610259SAndrew.Bardsley@arm.com /* Take up a slot in the fetch queue */ 58710259SAndrew.Bardsley@arm.com nextStageReserve.reserve(); 58810259SAndrew.Bardsley@arm.com } 58910259SAndrew.Bardsley@arm.com 59010259SAndrew.Bardsley@arm.com /* Halting shouldn't prevent fetches in flight from being processed */ 59110259SAndrew.Bardsley@arm.com /* Step fetches through the icachePort queues and memory system */ 59210259SAndrew.Bardsley@arm.com stepQueues(); 59310259SAndrew.Bardsley@arm.com 59410259SAndrew.Bardsley@arm.com /* As we've thrown away early lines, if there is a line, it must 59510259SAndrew.Bardsley@arm.com * be from the right stream */ 59610259SAndrew.Bardsley@arm.com if (!transfers.empty() && 59710259SAndrew.Bardsley@arm.com transfers.front()->isComplete()) 59810259SAndrew.Bardsley@arm.com { 59910259SAndrew.Bardsley@arm.com Fetch1::FetchRequestPtr response = transfers.front(); 60010259SAndrew.Bardsley@arm.com 60110259SAndrew.Bardsley@arm.com if (response->isDiscardable()) { 60210259SAndrew.Bardsley@arm.com nextStageReserve.freeReservation(); 60310259SAndrew.Bardsley@arm.com 60410259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Discarding translated fetch at it's for" 60510259SAndrew.Bardsley@arm.com " an old stream\n"); 60610259SAndrew.Bardsley@arm.com 60710259SAndrew.Bardsley@arm.com /* Wake up next cycle just in case there was some other 60810259SAndrew.Bardsley@arm.com * action to do */ 60910259SAndrew.Bardsley@arm.com cpu.wakeupOnEvent(Pipeline::Fetch1StageId); 61010259SAndrew.Bardsley@arm.com } else { 61110259SAndrew.Bardsley@arm.com DPRINTF(Fetch, "Processing fetched line: %s\n", 61210259SAndrew.Bardsley@arm.com response->id); 61310259SAndrew.Bardsley@arm.com 61410259SAndrew.Bardsley@arm.com processResponse(response, line_out); 61510259SAndrew.Bardsley@arm.com } 61610259SAndrew.Bardsley@arm.com 61710259SAndrew.Bardsley@arm.com popAndDiscard(transfers); 61810259SAndrew.Bardsley@arm.com } 61910259SAndrew.Bardsley@arm.com 62010259SAndrew.Bardsley@arm.com /* If we generated output, and mark the stage as being active 62110259SAndrew.Bardsley@arm.com * to encourage that output on to the next stage */ 62210259SAndrew.Bardsley@arm.com if (!line_out.isBubble()) 62310259SAndrew.Bardsley@arm.com cpu.activityRecorder->activity(); 62410259SAndrew.Bardsley@arm.com 62510259SAndrew.Bardsley@arm.com /* Fetch1 has no inputBuffer so the only activity we can have is to 62610259SAndrew.Bardsley@arm.com * generate a line output (tested just above) or to initiate a memory 62710259SAndrew.Bardsley@arm.com * fetch which will signal activity when it returns/needs stepping 62810259SAndrew.Bardsley@arm.com * between queues */ 62910259SAndrew.Bardsley@arm.com} 63010259SAndrew.Bardsley@arm.com 63110259SAndrew.Bardsley@arm.combool 63210259SAndrew.Bardsley@arm.comFetch1::isDrained() 63310259SAndrew.Bardsley@arm.com{ 63410259SAndrew.Bardsley@arm.com DPRINTF(Drain, "isDrained %s %s%s%s\n", 63510259SAndrew.Bardsley@arm.com state == FetchHalted, 63610259SAndrew.Bardsley@arm.com (numInFlightFetches() == 0 ? "" : "inFlightFetches "), 63710259SAndrew.Bardsley@arm.com ((*out.inputWire).isBubble() ? "" : "outputtingLine")); 63810259SAndrew.Bardsley@arm.com 63910259SAndrew.Bardsley@arm.com return state == FetchHalted && 64010259SAndrew.Bardsley@arm.com numInFlightFetches() == 0 && 64110259SAndrew.Bardsley@arm.com (*out.inputWire).isBubble(); 64210259SAndrew.Bardsley@arm.com} 64310259SAndrew.Bardsley@arm.com 64410259SAndrew.Bardsley@arm.comvoid 64510259SAndrew.Bardsley@arm.comFetch1::FetchRequest::reportData(std::ostream &os) const 64610259SAndrew.Bardsley@arm.com{ 64710259SAndrew.Bardsley@arm.com os << id; 64810259SAndrew.Bardsley@arm.com} 64910259SAndrew.Bardsley@arm.com 65010259SAndrew.Bardsley@arm.combool Fetch1::FetchRequest::isDiscardable() const 65110259SAndrew.Bardsley@arm.com{ 65210259SAndrew.Bardsley@arm.com /* Can't discard lines in TLB/memory */ 65310259SAndrew.Bardsley@arm.com return state != InTranslation && state != RequestIssuing && 65410259SAndrew.Bardsley@arm.com (id.streamSeqNum != fetch.streamSeqNum || 65510259SAndrew.Bardsley@arm.com id.predictionSeqNum != fetch.predictionSeqNum); 65610259SAndrew.Bardsley@arm.com} 65710259SAndrew.Bardsley@arm.com 65810259SAndrew.Bardsley@arm.comvoid 65910259SAndrew.Bardsley@arm.comFetch1::minorTrace() const 66010259SAndrew.Bardsley@arm.com{ 66110259SAndrew.Bardsley@arm.com std::ostringstream data; 66210259SAndrew.Bardsley@arm.com 66310259SAndrew.Bardsley@arm.com if (blocked) 66410259SAndrew.Bardsley@arm.com data << 'B'; 66510259SAndrew.Bardsley@arm.com else 66610259SAndrew.Bardsley@arm.com (*out.inputWire).reportData(data); 66710259SAndrew.Bardsley@arm.com 66810259SAndrew.Bardsley@arm.com MINORTRACE("state=%s icacheState=%s in_tlb_mem=%s/%s" 66910259SAndrew.Bardsley@arm.com " streamSeqNum=%d lines=%s\n", state, icacheState, 67010259SAndrew.Bardsley@arm.com numFetchesInITLB, numFetchesInMemorySystem, 67110259SAndrew.Bardsley@arm.com streamSeqNum, data.str()); 67210259SAndrew.Bardsley@arm.com requests.minorTrace(); 67310259SAndrew.Bardsley@arm.com transfers.minorTrace(); 67410259SAndrew.Bardsley@arm.com} 67510259SAndrew.Bardsley@arm.com 67610259SAndrew.Bardsley@arm.com} 677