1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 18 unchanged lines hidden (view full) --- 27 */ 28 29#include "cpu/checker/cpu.hh" 30#include "cpu/o3/lsq_unit.hh" 31#include "base/str.hh" 32#include "mem/request.hh" 33 34template<class Impl> |
35LSQUnit<Impl>::WritebackEvent::WritebackEvent(DynInstPtr &_inst, PacketPtr _pkt, 36 LSQUnit *lsq_ptr) 37 : Event(&mainEventQueue), inst(_inst), pkt(_pkt), lsqPtr(lsq_ptr) |
38{ |
39 this->setFlags(Event::AutoDelete); 40} |
41 |
42template<class Impl> 43void 44LSQUnit<Impl>::WritebackEvent::process() 45{ 46 if (!lsqPtr->isSwitchedOut()) { 47 lsqPtr->writeback(inst, pkt); |
48 } |
49 delete pkt; 50} |
51 |
52template<class Impl> 53const char * 54LSQUnit<Impl>::WritebackEvent::description() 55{ 56 return "Store writeback event"; |
57} 58 59template<class Impl> 60void |
61LSQUnit<Impl>::completeDataAccess(PacketPtr pkt) |
62{ |
63 LSQSenderState *state = dynamic_cast<LSQSenderState *>(pkt->senderState); 64 DynInstPtr inst = state->inst; 65 DPRINTF(IEW, "Writeback event [sn:%lli]\n", inst->seqNum); 66// DPRINTF(Activity, "Activity: Ld Writeback event [sn:%lli]\n", inst->seqNum); |
67 |
68 //iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum); |
69 |
70 if (isSwitchedOut() || inst->isSquashed()) { 71 delete state; 72 delete pkt; |
73 return; |
74 } else { 75 if (!state->noWB) { 76 writeback(inst, pkt); 77 } 78 79 if (inst->isStore()) { 80 completeStore(state->idx); 81 } |
82 } 83 |
84 delete state; 85 delete pkt; |
86} 87 88template <class Impl> 89Tick 90LSQUnit<Impl>::DcachePort::recvAtomic(PacketPtr pkt) 91{ 92 panic("O3CPU model does not work with atomic mode!"); 93 return curTick; --- 39 unchanged lines hidden (view full) --- 133 cpu->_status = DcacheWaitResponse; 134 cpu->dcache_pkt = NULL; 135 } 136*/ 137} 138 139template <class Impl> 140LSQUnit<Impl>::LSQUnit() |
141 : loads(0), stores(0), storesToWB(0), stalled(false), 142 isStoreBlocked(false), isLoadBlocked(false), |
143 loadBlockedHandled(false) 144{ 145} 146 147template<class Impl> 148void 149LSQUnit<Impl>::init(Params *params, unsigned maxLQEntries, 150 unsigned maxSQEntries, unsigned id) --- 13 unchanged lines hidden (view full) --- 164 165 loadHead = loadTail = 0; 166 167 storeHead = storeWBIdx = storeTail = 0; 168 169 usedPorts = 0; 170 cachePorts = params->cachePorts; 171 |
172 mem = params->mem; |
173 174 memDepViolator = NULL; 175 176 blockedLoadSeqNum = 0; 177} 178 179template<class Impl> 180void 181LSQUnit<Impl>::setCPU(FullCPU *cpu_ptr) 182{ 183 cpu = cpu_ptr; 184 dcachePort = new DcachePort(cpu, this); |
185 186 Port *mem_dport = mem->getPort(""); 187 dcachePort->setPeer(mem_dport); 188 mem_dport->setPeer(dcachePort); |
189} 190 191template<class Impl> 192std::string 193LSQUnit<Impl>::name() const 194{ 195 if (Impl::MaxThreads == 1) { 196 return iewStage->name() + ".lsq"; --- 239 unchanged lines hidden (view full) --- 436 DPRINTF(LSQUnit, "Executing store PC %#x [sn:%lli]\n", 437 store_inst->readPC(), store_inst->seqNum); 438 439 // Check the recently completed loads to see if any match this store's 440 // address. If so, then we have a memory ordering violation. 441 int load_idx = store_inst->lqIdx; 442 443 Fault store_fault = store_inst->initiateAcc(); |
444 445 if (storeQueue[store_idx].size == 0) { 446 DPRINTF(LSQUnit,"Fault on Store PC %#x, [sn:%lli],Size = 0\n", 447 store_inst->readPC(),store_inst->seqNum); 448 449 return store_fault; 450 } 451 --- 99 unchanged lines hidden (view full) --- 551LSQUnit<Impl>::writebackStores() 552{ 553 while (storesToWB > 0 && 554 storeWBIdx != storeTail && 555 storeQueue[storeWBIdx].inst && 556 storeQueue[storeWBIdx].canWB && 557 usedPorts < cachePorts) { 558 |
559 if (isStoreBlocked) { 560 DPRINTF(LSQUnit, "Unable to write back any more stores, cache" 561 " is blocked!\n"); 562 break; 563 } 564 |
565 // Store didn't write any data so no need to write it back to 566 // memory. 567 if (storeQueue[storeWBIdx].size == 0) { 568 completeStore(storeWBIdx); 569 570 incrStIdx(storeWBIdx); 571 572 continue; 573 } |
574 |
575 ++usedPorts; 576 577 if (storeQueue[storeWBIdx].inst->isDataPrefetch()) { 578 incrStIdx(storeWBIdx); 579 580 continue; 581 } 582 583 assert(storeQueue[storeWBIdx].req); 584 assert(!storeQueue[storeWBIdx].committed); 585 586 DynInstPtr inst = storeQueue[storeWBIdx].inst; 587 588 Request *req = storeQueue[storeWBIdx].req; 589 storeQueue[storeWBIdx].committed = true; 590 591 assert(!inst->memData); 592 inst->memData = new uint8_t[64]; |
593 memcpy(inst->memData, (uint8_t *)&storeQueue[storeWBIdx].data, 594 req->getSize()); |
595 596 PacketPtr data_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast); 597 data_pkt->dataStatic(inst->memData); 598 |
599 LSQSenderState *state = new LSQSenderState; 600 state->isLoad = false; 601 state->idx = storeWBIdx; 602 state->inst = inst; 603 data_pkt->senderState = state; 604 |
605 DPRINTF(LSQUnit, "D-Cache: Writing back store idx:%i PC:%#x " 606 "to Addr:%#x, data:%#x [sn:%lli]\n", 607 storeWBIdx, storeQueue[storeWBIdx].inst->readPC(), 608 req->getPaddr(), *(inst->memData), 609 storeQueue[storeWBIdx].inst->seqNum); 610 611 if (!dcachePort->sendTiming(data_pkt)) { 612 // Need to handle becoming blocked on a store. |
613 isStoreBlocked = true; |
614 } else { |
615 if (isStalled() && 616 storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) { 617 DPRINTF(LSQUnit, "Unstalling, stalling store [sn:%lli] " 618 "load idx:%i\n", 619 stallingStoreIsn, stallingLoadIdx); 620 stalled = false; 621 stallingStoreIsn = 0; 622 iewStage->replayMemInst(loadQueue[stallingLoadIdx]); 623 } |
624 625 if (!(req->getFlags() & LOCKED)) { 626 assert(!storeQueue[storeWBIdx].inst->isStoreConditional()); 627 // Non-store conditionals do not need a writeback. 628 state->noWB = true; |
629 } |
630 |
631 if (data_pkt->result != Packet::Success) { 632 DPRINTF(LSQUnit,"D-Cache Write Miss on idx:%i!\n", 633 storeWBIdx); 634 635 DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n", 636 storeQueue[storeWBIdx].inst->seqNum); 637 638 //mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum); --- 110 unchanged lines hidden (view full) --- 749 storeTail = store_idx; 750 751 decrStIdx(store_idx); 752 } 753} 754 755template <class Impl> 756void |
757LSQUnit<Impl>::writeback(DynInstPtr &inst, PacketPtr pkt) 758{ 759 iewStage->wakeCPU(); 760 761 // Squashed instructions do not need to complete their access. 762 if (inst->isSquashed()) { 763 assert(!inst->isStore()); 764 return; 765 } 766 767 if (!inst->isExecuted()) { 768 inst->setExecuted(); 769 770 // Complete access to copy data to proper place. 771 inst->completeAcc(pkt); 772 } 773 774 // Need to insert instruction into queue to commit 775 iewStage->instToCommit(inst); 776 777 iewStage->activityThisCycle(); 778} 779 780template <class Impl> 781void |
782LSQUnit<Impl>::completeStore(int store_idx) 783{ 784 assert(storeQueue[store_idx].inst); 785 storeQueue[store_idx].completed = true; 786 --storesToWB; 787 // A bit conservative because a store completion may not free up entries, 788 // but hopefully avoids two store completions in one cycle from making 789 // the CPU tick twice. --- 98 unchanged lines hidden --- |