fetch_impl.hh (12427:b0611f1ad833) fetch_impl.hh (12749:223c83ed9979)
1/*
2 * Copyright (c) 2010-2014 ARM Limited
3 * Copyright (c) 2012-2013 AMD
4 * All rights reserved.
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating

--- 374 unchanged lines hidden (view full) ---

383 DPRINTF(Fetch, "[tid:%u] Waking up from cache miss.\n", tid);
384 assert(!cpu->switchedOut());
385
386 // Only change the status if it's still waiting on the icache access
387 // to return.
388 if (fetchStatus[tid] != IcacheWaitResponse ||
389 pkt->req != memReq[tid]) {
390 ++fetchIcacheSquashes;
1/*
2 * Copyright (c) 2010-2014 ARM Limited
3 * Copyright (c) 2012-2013 AMD
4 * All rights reserved.
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating

--- 374 unchanged lines hidden (view full) ---

383 DPRINTF(Fetch, "[tid:%u] Waking up from cache miss.\n", tid);
384 assert(!cpu->switchedOut());
385
386 // Only change the status if it's still waiting on the icache access
387 // to return.
388 if (fetchStatus[tid] != IcacheWaitResponse ||
389 pkt->req != memReq[tid]) {
390 ++fetchIcacheSquashes;
391 delete pkt->req;
392 delete pkt;
393 return;
394 }
395
396 memcpy(fetchBuffer[tid], pkt->getConstPtr<uint8_t>(), fetchBufferSize);
397 fetchBufferValid[tid] = true;
398
399 // Wake up the CPU (if it went to sleep and was waiting on

--- 10 unchanged lines hidden (view full) ---

410 fetchStatus[tid] = Blocked;
411 } else {
412 fetchStatus[tid] = IcacheAccessComplete;
413 }
414
415 pkt->req->setAccessLatency();
416 cpu->ppInstAccessComplete->notify(pkt);
417 // Reset the mem req to NULL.
391 delete pkt;
392 return;
393 }
394
395 memcpy(fetchBuffer[tid], pkt->getConstPtr<uint8_t>(), fetchBufferSize);
396 fetchBufferValid[tid] = true;
397
398 // Wake up the CPU (if it went to sleep and was waiting on

--- 10 unchanged lines hidden (view full) ---

409 fetchStatus[tid] = Blocked;
410 } else {
411 fetchStatus[tid] = IcacheAccessComplete;
412 }
413
414 pkt->req->setAccessLatency();
415 cpu->ppInstAccessComplete->notify(pkt);
416 // Reset the mem req to NULL.
418 delete pkt->req;
419 delete pkt;
420 memReq[tid] = NULL;
421}
422
423template <class Impl>
424void
425DefaultFetch<Impl>::drainResume()
426{

--- 189 unchanged lines hidden (view full) ---

616 Addr fetchBufferBlockPC = fetchBufferAlignPC(vaddr);
617
618 DPRINTF(Fetch, "[tid:%i] Fetching cache line %#x for addr %#x\n",
619 tid, fetchBufferBlockPC, vaddr);
620
621 // Setup the memReq to do a read of the first instruction's address.
622 // Set the appropriate read size and flags as well.
623 // Build request here.
417 delete pkt;
418 memReq[tid] = NULL;
419}
420
421template <class Impl>
422void
423DefaultFetch<Impl>::drainResume()
424{

--- 189 unchanged lines hidden (view full) ---

614 Addr fetchBufferBlockPC = fetchBufferAlignPC(vaddr);
615
616 DPRINTF(Fetch, "[tid:%i] Fetching cache line %#x for addr %#x\n",
617 tid, fetchBufferBlockPC, vaddr);
618
619 // Setup the memReq to do a read of the first instruction's address.
620 // Set the appropriate read size and flags as well.
621 // Build request here.
624 RequestPtr mem_req =
625 new Request(tid, fetchBufferBlockPC, fetchBufferSize,
626 Request::INST_FETCH, cpu->instMasterId(), pc,
627 cpu->thread[tid]->contextId());
622 RequestPtr mem_req = std::make_shared<Request>(
623 tid, fetchBufferBlockPC, fetchBufferSize,
624 Request::INST_FETCH, cpu->instMasterId(), pc,
625 cpu->thread[tid]->contextId());
628
629 mem_req->taskId(cpu->taskId());
630
631 memReq[tid] = mem_req;
632
633 // Initiate translation of the icache block
634 fetchStatus[tid] = ItlbWait;
635 FetchTranslation *trans = new FetchTranslation(this);
636 cpu->itb->translateTiming(mem_req, cpu->thread[tid]->getTC(),
637 trans, BaseTLB::Execute);
638 return true;
639}
640
641template <class Impl>
642void
626
627 mem_req->taskId(cpu->taskId());
628
629 memReq[tid] = mem_req;
630
631 // Initiate translation of the icache block
632 fetchStatus[tid] = ItlbWait;
633 FetchTranslation *trans = new FetchTranslation(this);
634 cpu->itb->translateTiming(mem_req, cpu->thread[tid]->getTC(),
635 trans, BaseTLB::Execute);
636 return true;
637}
638
639template <class Impl>
640void
643DefaultFetch<Impl>::finishTranslation(const Fault &fault, RequestPtr mem_req)
641DefaultFetch::finishTranslation(const Fault &fault,
642 const RequestPtr &mem_req)
644{
645 ThreadID tid = cpu->contextToThread(mem_req->contextId());
646 Addr fetchBufferBlockPC = mem_req->getVaddr();
647
648 assert(!cpu->switchedOut());
649
650 // Wake up CPU if it was idle
651 cpu->wakeCPU();
652
653 if (fetchStatus[tid] != ItlbWait || mem_req != memReq[tid] ||
654 mem_req->getVaddr() != memReq[tid]->getVaddr()) {
655 DPRINTF(Fetch, "[tid:%i] Ignoring itlb completed after squash\n",
656 tid);
657 ++fetchTlbSquashes;
643{
644 ThreadID tid = cpu->contextToThread(mem_req->contextId());
645 Addr fetchBufferBlockPC = mem_req->getVaddr();
646
647 assert(!cpu->switchedOut());
648
649 // Wake up CPU if it was idle
650 cpu->wakeCPU();
651
652 if (fetchStatus[tid] != ItlbWait || mem_req != memReq[tid] ||
653 mem_req->getVaddr() != memReq[tid]->getVaddr()) {
654 DPRINTF(Fetch, "[tid:%i] Ignoring itlb completed after squash\n",
655 tid);
656 ++fetchTlbSquashes;
658 delete mem_req;
659 return;
660 }
661
662
663 // If translation was successful, attempt to read the icache block.
664 if (fault == NoFault) {
665 // Check that we're not going off into random memory
666 // If we have, just wait around for commit to squash something and put
667 // us on the right track
668 if (!cpu->system->isMemAddr(mem_req->getPaddr())) {
669 warn("Address %#x is outside of physical memory, stopping fetch\n",
670 mem_req->getPaddr());
671 fetchStatus[tid] = NoGoodAddr;
657 return;
658 }
659
660
661 // If translation was successful, attempt to read the icache block.
662 if (fault == NoFault) {
663 // Check that we're not going off into random memory
664 // If we have, just wait around for commit to squash something and put
665 // us on the right track
666 if (!cpu->system->isMemAddr(mem_req->getPaddr())) {
667 warn("Address %#x is outside of physical memory, stopping fetch\n",
668 mem_req->getPaddr());
669 fetchStatus[tid] = NoGoodAddr;
672 delete mem_req;
673 memReq[tid] = NULL;
674 return;
675 }
676
677 // Build packet here.
678 PacketPtr data_pkt = new Packet(mem_req, MemCmd::ReadReq);
679 data_pkt->dataDynamic(new uint8_t[fetchBufferSize]);
680

--- 31 unchanged lines hidden (view full) ---

712 finishTranslationEvent.setReq(mem_req);
713 cpu->schedule(finishTranslationEvent,
714 cpu->clockEdge(Cycles(1)));
715 return;
716 }
717 DPRINTF(Fetch, "[tid:%i] Got back req with addr %#x but expected %#x\n",
718 tid, mem_req->getVaddr(), memReq[tid]->getVaddr());
719 // Translation faulted, icache request won't be sent.
670 memReq[tid] = NULL;
671 return;
672 }
673
674 // Build packet here.
675 PacketPtr data_pkt = new Packet(mem_req, MemCmd::ReadReq);
676 data_pkt->dataDynamic(new uint8_t[fetchBufferSize]);
677

--- 31 unchanged lines hidden (view full) ---

709 finishTranslationEvent.setReq(mem_req);
710 cpu->schedule(finishTranslationEvent,
711 cpu->clockEdge(Cycles(1)));
712 return;
713 }
714 DPRINTF(Fetch, "[tid:%i] Got back req with addr %#x but expected %#x\n",
715 tid, mem_req->getVaddr(), memReq[tid]->getVaddr());
716 // Translation faulted, icache request won't be sent.
720 delete mem_req;
721 memReq[tid] = NULL;
722
723 // Send the fault to commit. This thread will not do anything
724 // until commit handles the fault. The only other way it can
725 // wake up is if a squash comes along and changes the PC.
726 TheISA::PCState fetchPC = pc[tid];
727
728 DPRINTF(Fetch, "[tid:%i]: Translation faulted, building noop.\n", tid);

--- 44 unchanged lines hidden (view full) ---

773 tid);
774 memReq[tid] = NULL;
775 }
776
777 // Get rid of the retrying packet if it was from this thread.
778 if (retryTid == tid) {
779 assert(cacheBlocked);
780 if (retryPkt) {
717 memReq[tid] = NULL;
718
719 // Send the fault to commit. This thread will not do anything
720 // until commit handles the fault. The only other way it can
721 // wake up is if a squash comes along and changes the PC.
722 TheISA::PCState fetchPC = pc[tid];
723
724 DPRINTF(Fetch, "[tid:%i]: Translation faulted, building noop.\n", tid);

--- 44 unchanged lines hidden (view full) ---

769 tid);
770 memReq[tid] = NULL;
771 }
772
773 // Get rid of the retrying packet if it was from this thread.
774 if (retryTid == tid) {
775 assert(cacheBlocked);
776 if (retryPkt) {
781 delete retryPkt->req;
782 delete retryPkt;
783 }
784 retryPkt = NULL;
785 retryTid = InvalidThreadID;
786 }
787
788 fetchStatus[tid] = Squashing;
789

--- 892 unchanged lines hidden ---
777 delete retryPkt;
778 }
779 retryPkt = NULL;
780 retryTid = InvalidThreadID;
781 }
782
783 fetchStatus[tid] = Squashing;
784

--- 892 unchanged lines hidden ---