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 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 --- |