lsq_unit_impl.hh revision 2307
16019Shines@cs.fsu.edu/* 26019Shines@cs.fsu.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan 313120SEdmund.Grimley-Evans@arm.com * All rights reserved. 47178Sgblack@eecs.umich.edu * 57178Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 67178Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 77178Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 87178Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 97178Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 107178Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 117178Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 127178Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137178Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 147178Sgblack@eecs.umich.edu * this software without specific prior written permission. 156019Shines@cs.fsu.edu * 166019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276019Shines@cs.fsu.edu */ 286019Shines@cs.fsu.edu 296019Shines@cs.fsu.edu#include "cpu/o3/lsq_unit.hh" 306019Shines@cs.fsu.edu#include "base/str.hh" 316019Shines@cs.fsu.edu 326019Shines@cs.fsu.edutemplate <class Impl> 336019Shines@cs.fsu.eduLSQUnit<Impl>::StoreCompletionEvent::StoreCompletionEvent(int store_idx, 346019Shines@cs.fsu.edu Event *wb_event, 356019Shines@cs.fsu.edu LSQUnit<Impl> *lsq_ptr) 366019Shines@cs.fsu.edu : Event(&mainEventQueue), 376019Shines@cs.fsu.edu storeIdx(store_idx), 386019Shines@cs.fsu.edu wbEvent(wb_event), 396019Shines@cs.fsu.edu lsqPtr(lsq_ptr) 406019Shines@cs.fsu.edu{ 416019Shines@cs.fsu.edu this->setFlags(Event::AutoDelete); 426019Shines@cs.fsu.edu} 436019Shines@cs.fsu.edu 446019Shines@cs.fsu.edutemplate <class Impl> 456019Shines@cs.fsu.eduvoid 466019Shines@cs.fsu.eduLSQUnit<Impl>::StoreCompletionEvent::process() 476019Shines@cs.fsu.edu{ 487639Sgblack@eecs.umich.edu DPRINTF(LSQ, "Cache miss complete for store idx:%i\n", storeIdx); 497639Sgblack@eecs.umich.edu DPRINTF(Activity, "Activity: st writeback event idx:%i\n", storeIdx); 507639Sgblack@eecs.umich.edu 517639Sgblack@eecs.umich.edu //lsqPtr->removeMSHR(lsqPtr->storeQueue[storeIdx].inst->seqNum); 527639Sgblack@eecs.umich.edu 537639Sgblack@eecs.umich.edu if (lsqPtr->isSwitchedOut()) 547639Sgblack@eecs.umich.edu return; 557639Sgblack@eecs.umich.edu 567639Sgblack@eecs.umich.edu lsqPtr->cpu->wakeCPU(); 577639Sgblack@eecs.umich.edu if (wbEvent) 587639Sgblack@eecs.umich.edu wbEvent->process(); 597639Sgblack@eecs.umich.edu lsqPtr->completeStore(storeIdx); 607639Sgblack@eecs.umich.edu} 617639Sgblack@eecs.umich.edu 627639Sgblack@eecs.umich.edutemplate <class Impl> 637639Sgblack@eecs.umich.educonst char * 647639Sgblack@eecs.umich.eduLSQUnit<Impl>::StoreCompletionEvent::description() 657639Sgblack@eecs.umich.edu{ 667639Sgblack@eecs.umich.edu return "LSQ store completion event"; 677639Sgblack@eecs.umich.edu} 687639Sgblack@eecs.umich.edu 697639Sgblack@eecs.umich.edutemplate <class Impl> 707639Sgblack@eecs.umich.eduLSQUnit<Impl>::LSQUnit() 717639Sgblack@eecs.umich.edu : loads(0), stores(0), storesToWB(0), stalled(false), isLoadBlocked(false), 727639Sgblack@eecs.umich.edu loadBlockedHandled(false) 737639Sgblack@eecs.umich.edu{ 747639Sgblack@eecs.umich.edu} 757639Sgblack@eecs.umich.edu 767639Sgblack@eecs.umich.edutemplate<class Impl> 777639Sgblack@eecs.umich.eduvoid 787639Sgblack@eecs.umich.eduLSQUnit<Impl>::init(Params *params, unsigned maxLQEntries, 797639Sgblack@eecs.umich.edu unsigned maxSQEntries, unsigned id) 807639Sgblack@eecs.umich.edu 817639Sgblack@eecs.umich.edu{ 827639Sgblack@eecs.umich.edu DPRINTF(LSQUnit, "Creating LSQUnit%i object.\n",id); 837639Sgblack@eecs.umich.edu 847639Sgblack@eecs.umich.edu switchedOut = false; 857639Sgblack@eecs.umich.edu 867639Sgblack@eecs.umich.edu lsqID = id; 877639Sgblack@eecs.umich.edu 887639Sgblack@eecs.umich.edu LQEntries = maxLQEntries; 897639Sgblack@eecs.umich.edu SQEntries = maxSQEntries; 907639Sgblack@eecs.umich.edu 917639Sgblack@eecs.umich.edu loadQueue.resize(LQEntries); 927639Sgblack@eecs.umich.edu storeQueue.resize(SQEntries); 937639Sgblack@eecs.umich.edu 947356Sgblack@eecs.umich.edu 957356Sgblack@eecs.umich.edu // May want to initialize these entries to NULL 967356Sgblack@eecs.umich.edu 977435Sgblack@eecs.umich.edu loadHead = loadTail = 0; 987435Sgblack@eecs.umich.edu 997435Sgblack@eecs.umich.edu storeHead = storeWBIdx = storeTail = 0; 1007435Sgblack@eecs.umich.edu 1017435Sgblack@eecs.umich.edu usedPorts = 0; 1027435Sgblack@eecs.umich.edu cachePorts = params->cachePorts; 1037435Sgblack@eecs.umich.edu 1047435Sgblack@eecs.umich.edu dcacheInterface = params->dcacheInterface; 1057435Sgblack@eecs.umich.edu 1067435Sgblack@eecs.umich.edu loadFaultInst = storeFaultInst = memDepViolator = NULL; 1077435Sgblack@eecs.umich.edu 1087639Sgblack@eecs.umich.edu blockedLoadSeqNum = 0; 1097639Sgblack@eecs.umich.edu} 1107639Sgblack@eecs.umich.edu 1117435Sgblack@eecs.umich.edutemplate<class Impl> 1127639Sgblack@eecs.umich.edustd::string 1137639Sgblack@eecs.umich.eduLSQUnit<Impl>::name() const 1147639Sgblack@eecs.umich.edu{ 1157639Sgblack@eecs.umich.edu if (Impl::MaxThreads == 1) { 1167639Sgblack@eecs.umich.edu return iewStage->name() + ".lsq"; 1177639Sgblack@eecs.umich.edu } else { 1187639Sgblack@eecs.umich.edu return iewStage->name() + ".lsq.thread." + to_string(lsqID); 1197639Sgblack@eecs.umich.edu } 1207639Sgblack@eecs.umich.edu} 1217639Sgblack@eecs.umich.edu 1227639Sgblack@eecs.umich.edutemplate<class Impl> 1237639Sgblack@eecs.umich.eduvoid 1247639Sgblack@eecs.umich.eduLSQUnit<Impl>::clearLQ() 1257639Sgblack@eecs.umich.edu{ 1267639Sgblack@eecs.umich.edu loadQueue.clear(); 1277639Sgblack@eecs.umich.edu} 1287639Sgblack@eecs.umich.edu 1297639Sgblack@eecs.umich.edutemplate<class Impl> 1307639Sgblack@eecs.umich.eduvoid 1317639Sgblack@eecs.umich.eduLSQUnit<Impl>::clearSQ() 1327639Sgblack@eecs.umich.edu{ 13312595Ssiddhesh.poyarekar@gmail.com storeQueue.clear(); 1347639Sgblack@eecs.umich.edu} 1357639Sgblack@eecs.umich.edu 1367639Sgblack@eecs.umich.edu#if 0 1377639Sgblack@eecs.umich.edutemplate<class Impl> 1387639Sgblack@eecs.umich.eduvoid 1397639Sgblack@eecs.umich.eduLSQUnit<Impl>::setPageTable(PageTable *pt_ptr) 1407639Sgblack@eecs.umich.edu{ 1417639Sgblack@eecs.umich.edu DPRINTF(LSQUnit, "Setting the page table pointer.\n"); 1427639Sgblack@eecs.umich.edu pTable = pt_ptr; 1437639Sgblack@eecs.umich.edu} 1447639Sgblack@eecs.umich.edu#endif 1457639Sgblack@eecs.umich.edu 1468144SAli.Saidi@ARM.comtemplate<class Impl> 1477639Sgblack@eecs.umich.eduvoid 1487639Sgblack@eecs.umich.eduLSQUnit<Impl>::switchOut() 1497639Sgblack@eecs.umich.edu{ 1507639Sgblack@eecs.umich.edu switchedOut = true; 1517639Sgblack@eecs.umich.edu for (int i = 0; i < loadQueue.size(); ++i) 1527639Sgblack@eecs.umich.edu loadQueue[i] = NULL; 1537639Sgblack@eecs.umich.edu 15410037SARM gem5 Developers while (storesToWB > 0 && 1557639Sgblack@eecs.umich.edu storeWBIdx != storeTail && 1567639Sgblack@eecs.umich.edu storeQueue[storeWBIdx].inst && 1577639Sgblack@eecs.umich.edu storeQueue[storeWBIdx].canWB) { 1587639Sgblack@eecs.umich.edu 1597639Sgblack@eecs.umich.edu if (storeQueue[storeWBIdx].size == 0 || 1607639Sgblack@eecs.umich.edu storeQueue[storeWBIdx].inst->isDataPrefetch() || 1617639Sgblack@eecs.umich.edu storeQueue[storeWBIdx].committed || 1627639Sgblack@eecs.umich.edu storeQueue[storeWBIdx].req->flags & LOCKED) { 1637639Sgblack@eecs.umich.edu incrStIdx(storeWBIdx); 1647639Sgblack@eecs.umich.edu 1657639Sgblack@eecs.umich.edu continue; 16610037SARM gem5 Developers } 1677639Sgblack@eecs.umich.edu 1687639Sgblack@eecs.umich.edu assert(storeQueue[storeWBIdx].req); 1697639Sgblack@eecs.umich.edu assert(!storeQueue[storeWBIdx].committed); 1707639Sgblack@eecs.umich.edu 1717639Sgblack@eecs.umich.edu MemReqPtr req = storeQueue[storeWBIdx].req; 1727639Sgblack@eecs.umich.edu storeQueue[storeWBIdx].committed = true; 1737639Sgblack@eecs.umich.edu 1747639Sgblack@eecs.umich.edu req->cmd = Write; 17510037SARM gem5 Developers req->completionEvent = NULL; 1767639Sgblack@eecs.umich.edu req->time = curTick; 1777639Sgblack@eecs.umich.edu assert(!req->data); 17810037SARM gem5 Developers req->data = new uint8_t[64]; 1797639Sgblack@eecs.umich.edu memcpy(req->data, (uint8_t *)&storeQueue[storeWBIdx].data, req->size); 1807639Sgblack@eecs.umich.edu 18110037SARM gem5 Developers DPRINTF(LSQUnit, "D-Cache: Writing back store idx:%i PC:%#x " 1827591SAli.Saidi@ARM.com "to Addr:%#x, data:%#x [sn:%lli]\n", 1837639Sgblack@eecs.umich.edu storeWBIdx,storeQueue[storeWBIdx].inst->readPC(), 1847435Sgblack@eecs.umich.edu req->paddr, *(req->data), 1857435Sgblack@eecs.umich.edu storeQueue[storeWBIdx].inst->seqNum); 1867639Sgblack@eecs.umich.edu 18710037SARM gem5 Developers switch(storeQueue[storeWBIdx].size) { 1887639Sgblack@eecs.umich.edu case 1: 1897639Sgblack@eecs.umich.edu cpu->write(req, (uint8_t &)storeQueue[storeWBIdx].data); 1907639Sgblack@eecs.umich.edu break; 1917639Sgblack@eecs.umich.edu case 2: 1927639Sgblack@eecs.umich.edu cpu->write(req, (uint16_t &)storeQueue[storeWBIdx].data); 1937639Sgblack@eecs.umich.edu break; 1947639Sgblack@eecs.umich.edu case 4: 1957639Sgblack@eecs.umich.edu cpu->write(req, (uint32_t &)storeQueue[storeWBIdx].data); 1967639Sgblack@eecs.umich.edu break; 1977639Sgblack@eecs.umich.edu case 8: 1987639Sgblack@eecs.umich.edu cpu->write(req, (uint64_t &)storeQueue[storeWBIdx].data); 1997639Sgblack@eecs.umich.edu break; 2007639Sgblack@eecs.umich.edu default: 2017639Sgblack@eecs.umich.edu panic("Unexpected store size!\n"); 2027639Sgblack@eecs.umich.edu } 2037639Sgblack@eecs.umich.edu incrStIdx(storeWBIdx); 2047639Sgblack@eecs.umich.edu } 2057639Sgblack@eecs.umich.edu} 2067639Sgblack@eecs.umich.edu 2077639Sgblack@eecs.umich.edutemplate<class Impl> 2087639Sgblack@eecs.umich.eduvoid 2097639Sgblack@eecs.umich.eduLSQUnit<Impl>::takeOverFrom() 2107639Sgblack@eecs.umich.edu{ 2117639Sgblack@eecs.umich.edu switchedOut = false; 2127639Sgblack@eecs.umich.edu loads = stores = storesToWB = 0; 2137639Sgblack@eecs.umich.edu 2147639Sgblack@eecs.umich.edu loadHead = loadTail = 0; 2157639Sgblack@eecs.umich.edu 2167639Sgblack@eecs.umich.edu storeHead = storeWBIdx = storeTail = 0; 2177639Sgblack@eecs.umich.edu 2187639Sgblack@eecs.umich.edu usedPorts = 0; 2197639Sgblack@eecs.umich.edu 22010037SARM gem5 Developers loadFaultInst = storeFaultInst = memDepViolator = NULL; 2217591SAli.Saidi@ARM.com 2227591SAli.Saidi@ARM.com blockedLoadSeqNum = 0; 2237639Sgblack@eecs.umich.edu 2247639Sgblack@eecs.umich.edu stalled = false; 2257639Sgblack@eecs.umich.edu isLoadBlocked = false; 22610037SARM gem5 Developers loadBlockedHandled = false; 2277639Sgblack@eecs.umich.edu} 2287639Sgblack@eecs.umich.edu 2297639Sgblack@eecs.umich.edutemplate<class Impl> 2307639Sgblack@eecs.umich.eduvoid 2317639Sgblack@eecs.umich.eduLSQUnit<Impl>::resizeLQ(unsigned size) 2327639Sgblack@eecs.umich.edu{ 2337639Sgblack@eecs.umich.edu assert( size >= LQEntries); 2347639Sgblack@eecs.umich.edu 23510037SARM gem5 Developers if (size > LQEntries) { 2367639Sgblack@eecs.umich.edu while (size > loadQueue.size()) { 2377639Sgblack@eecs.umich.edu DynInstPtr dummy; 2387639Sgblack@eecs.umich.edu loadQueue.push_back(dummy); 23910037SARM gem5 Developers LQEntries++; 2407639Sgblack@eecs.umich.edu } 2417639Sgblack@eecs.umich.edu } else { 2427639Sgblack@eecs.umich.edu LQEntries = size; 2437435Sgblack@eecs.umich.edu } 2447435Sgblack@eecs.umich.edu 2457639Sgblack@eecs.umich.edu} 2467639Sgblack@eecs.umich.edu 2477639Sgblack@eecs.umich.edutemplate<class Impl> 2487639Sgblack@eecs.umich.eduvoid 2497639Sgblack@eecs.umich.eduLSQUnit<Impl>::resizeSQ(unsigned size) 2507639Sgblack@eecs.umich.edu{ 2517639Sgblack@eecs.umich.edu if (size > SQEntries) { 2527639Sgblack@eecs.umich.edu while (size > storeQueue.size()) { 25310037SARM gem5 Developers SQEntry dummy; 2547639Sgblack@eecs.umich.edu storeQueue.push_back(dummy); 25510037SARM gem5 Developers SQEntries++; 2567639Sgblack@eecs.umich.edu } 2577639Sgblack@eecs.umich.edu } else { 2587639Sgblack@eecs.umich.edu SQEntries = size; 2597639Sgblack@eecs.umich.edu } 2607639Sgblack@eecs.umich.edu} 2617639Sgblack@eecs.umich.edu 2627639Sgblack@eecs.umich.edutemplate <class Impl> 2637639Sgblack@eecs.umich.eduvoid 2647639Sgblack@eecs.umich.eduLSQUnit<Impl>::insert(DynInstPtr &inst) 2657639Sgblack@eecs.umich.edu{ 2667639Sgblack@eecs.umich.edu // Make sure we really have a memory reference. 2677639Sgblack@eecs.umich.edu assert(inst->isMemRef()); 2687639Sgblack@eecs.umich.edu 2697639Sgblack@eecs.umich.edu // Make sure it's one of the two classes of memory references. 2707639Sgblack@eecs.umich.edu assert(inst->isLoad() || inst->isStore()); 2717639Sgblack@eecs.umich.edu 2727639Sgblack@eecs.umich.edu if (inst->isLoad()) { 2737639Sgblack@eecs.umich.edu insertLoad(inst); 2747639Sgblack@eecs.umich.edu } else { 2757639Sgblack@eecs.umich.edu insertStore(inst); 2767639Sgblack@eecs.umich.edu } 2777639Sgblack@eecs.umich.edu 2787639Sgblack@eecs.umich.edu inst->setInLSQ(); 2797639Sgblack@eecs.umich.edu} 2807639Sgblack@eecs.umich.edu 2817639Sgblack@eecs.umich.edutemplate <class Impl> 2827639Sgblack@eecs.umich.eduvoid 2837639Sgblack@eecs.umich.eduLSQUnit<Impl>::insertLoad(DynInstPtr &load_inst) 2847639Sgblack@eecs.umich.edu{ 2857639Sgblack@eecs.umich.edu assert((loadTail + 1) % LQEntries != loadHead && loads < LQEntries); 2867639Sgblack@eecs.umich.edu 2877639Sgblack@eecs.umich.edu DPRINTF(LSQUnit, "Inserting load PC %#x, idx:%i [sn:%lli]\n", 2887639Sgblack@eecs.umich.edu load_inst->readPC(), loadTail, load_inst->seqNum); 2897639Sgblack@eecs.umich.edu 2907639Sgblack@eecs.umich.edu load_inst->lqIdx = loadTail; 2917639Sgblack@eecs.umich.edu 2927639Sgblack@eecs.umich.edu if (stores == 0) { 2937639Sgblack@eecs.umich.edu load_inst->sqIdx = -1; 2947639Sgblack@eecs.umich.edu } else { 2957639Sgblack@eecs.umich.edu load_inst->sqIdx = storeTail; 2967639Sgblack@eecs.umich.edu } 2977639Sgblack@eecs.umich.edu 2987639Sgblack@eecs.umich.edu loadQueue[loadTail] = load_inst; 2997639Sgblack@eecs.umich.edu 3007639Sgblack@eecs.umich.edu incrLdIdx(loadTail); 3017639Sgblack@eecs.umich.edu 3027639Sgblack@eecs.umich.edu ++loads; 3037639Sgblack@eecs.umich.edu} 3047639Sgblack@eecs.umich.edu 3057639Sgblack@eecs.umich.edutemplate <class Impl> 3067639Sgblack@eecs.umich.eduvoid 3077639Sgblack@eecs.umich.eduLSQUnit<Impl>::insertStore(DynInstPtr &store_inst) 3087639Sgblack@eecs.umich.edu{ 3097639Sgblack@eecs.umich.edu // Make sure it is not full before inserting an instruction. 3107639Sgblack@eecs.umich.edu assert((storeTail + 1) % SQEntries != storeHead); 3117639Sgblack@eecs.umich.edu assert(stores < SQEntries); 3127639Sgblack@eecs.umich.edu 3137639Sgblack@eecs.umich.edu DPRINTF(LSQUnit, "Inserting store PC %#x, idx:%i [sn:%lli]\n", 3147639Sgblack@eecs.umich.edu store_inst->readPC(), storeTail, store_inst->seqNum); 3157639Sgblack@eecs.umich.edu 3167639Sgblack@eecs.umich.edu store_inst->sqIdx = storeTail; 3177639Sgblack@eecs.umich.edu store_inst->lqIdx = loadTail; 3187639Sgblack@eecs.umich.edu 3197639Sgblack@eecs.umich.edu storeQueue[storeTail] = SQEntry(store_inst); 3207639Sgblack@eecs.umich.edu 3217435Sgblack@eecs.umich.edu incrStIdx(storeTail); 3227435Sgblack@eecs.umich.edu 3237639Sgblack@eecs.umich.edu ++stores; 3247639Sgblack@eecs.umich.edu 3257639Sgblack@eecs.umich.edu} 3267591SAli.Saidi@ARM.com 3277639Sgblack@eecs.umich.edutemplate <class Impl> 3287639Sgblack@eecs.umich.edutypename Impl::DynInstPtr 3297435Sgblack@eecs.umich.eduLSQUnit<Impl>::getMemDepViolator() 3307435Sgblack@eecs.umich.edu{ 3317639Sgblack@eecs.umich.edu DynInstPtr temp = memDepViolator; 3327639Sgblack@eecs.umich.edu 3337435Sgblack@eecs.umich.edu memDepViolator = NULL; 3347435Sgblack@eecs.umich.edu 3357591SAli.Saidi@ARM.com return temp; 3367435Sgblack@eecs.umich.edu} 3377435Sgblack@eecs.umich.edu 3387435Sgblack@eecs.umich.edutemplate <class Impl> 3397435Sgblack@eecs.umich.eduunsigned 3407435Sgblack@eecs.umich.eduLSQUnit<Impl>::numFreeEntries() 3417435Sgblack@eecs.umich.edu{ 3427435Sgblack@eecs.umich.edu unsigned free_lq_entries = LQEntries - loads; 3437435Sgblack@eecs.umich.edu unsigned free_sq_entries = SQEntries - stores; 3447435Sgblack@eecs.umich.edu 3457435Sgblack@eecs.umich.edu // Both the LQ and SQ entries have an extra dummy entry to differentiate 3467435Sgblack@eecs.umich.edu // empty/full conditions. Subtract 1 from the free entries. 3477639Sgblack@eecs.umich.edu if (free_lq_entries < free_sq_entries) { 3487639Sgblack@eecs.umich.edu return free_lq_entries - 1; 3497639Sgblack@eecs.umich.edu } else { 3507639Sgblack@eecs.umich.edu return free_sq_entries - 1; 3517639Sgblack@eecs.umich.edu } 3527639Sgblack@eecs.umich.edu} 3537639Sgblack@eecs.umich.edu 3547639Sgblack@eecs.umich.edutemplate <class Impl> 3557639Sgblack@eecs.umich.eduint 3567639Sgblack@eecs.umich.eduLSQUnit<Impl>::numLoadsReady() 3577639Sgblack@eecs.umich.edu{ 3587639Sgblack@eecs.umich.edu int load_idx = loadHead; 3597639Sgblack@eecs.umich.edu int retval = 0; 3607435Sgblack@eecs.umich.edu 3617435Sgblack@eecs.umich.edu while (load_idx != loadTail) { 3627435Sgblack@eecs.umich.edu assert(loadQueue[load_idx]); 3637639Sgblack@eecs.umich.edu 3647639Sgblack@eecs.umich.edu if (loadQueue[load_idx]->readyToIssue()) { 3657639Sgblack@eecs.umich.edu ++retval; 3667435Sgblack@eecs.umich.edu } 3677639Sgblack@eecs.umich.edu } 3687639Sgblack@eecs.umich.edu 3697435Sgblack@eecs.umich.edu return retval; 3707435Sgblack@eecs.umich.edu} 3717639Sgblack@eecs.umich.edu 3727639Sgblack@eecs.umich.edu#if 0 3737639Sgblack@eecs.umich.edutemplate <class Impl> 3747639Sgblack@eecs.umich.eduFault 3757435Sgblack@eecs.umich.eduLSQUnit<Impl>::executeLoad() 3767435Sgblack@eecs.umich.edu{ 3777435Sgblack@eecs.umich.edu Fault load_fault = NoFault; 3787639Sgblack@eecs.umich.edu DynInstPtr load_inst; 3797639Sgblack@eecs.umich.edu 3807435Sgblack@eecs.umich.edu assert(readyLoads.size() != 0); 3817435Sgblack@eecs.umich.edu 3827435Sgblack@eecs.umich.edu // Execute a ready load. 3837435Sgblack@eecs.umich.edu LdMapIt ready_it = readyLoads.begin(); 3847639Sgblack@eecs.umich.edu 3857639Sgblack@eecs.umich.edu load_inst = (*ready_it).second; 3867639Sgblack@eecs.umich.edu 3877639Sgblack@eecs.umich.edu // Execute the instruction, which is held in the data portion of the 3887639Sgblack@eecs.umich.edu // iterator. 3897435Sgblack@eecs.umich.edu load_fault = load_inst->execute(); 3907639Sgblack@eecs.umich.edu 3917639Sgblack@eecs.umich.edu // If it executed successfully, then switch it over to the executed 3927639Sgblack@eecs.umich.edu // loads list. 3937639Sgblack@eecs.umich.edu if (load_fault == NoFault) { 3947639Sgblack@eecs.umich.edu executedLoads[load_inst->seqNum] = load_inst; 3957435Sgblack@eecs.umich.edu 3967639Sgblack@eecs.umich.edu readyLoads.erase(ready_it); 3977639Sgblack@eecs.umich.edu } else { 3987639Sgblack@eecs.umich.edu loadFaultInst = load_inst; 3997639Sgblack@eecs.umich.edu } 4007639Sgblack@eecs.umich.edu 4017435Sgblack@eecs.umich.edu return load_fault; 4027639Sgblack@eecs.umich.edu} 4037639Sgblack@eecs.umich.edu#endif 4047639Sgblack@eecs.umich.edu 4057639Sgblack@eecs.umich.edutemplate <class Impl> 4067639Sgblack@eecs.umich.eduFault 40712595Ssiddhesh.poyarekar@gmail.comLSQUnit<Impl>::executeLoad(DynInstPtr &inst) 40812595Ssiddhesh.poyarekar@gmail.com{ 4097435Sgblack@eecs.umich.edu // Execute a specific load. 4107435Sgblack@eecs.umich.edu Fault load_fault = NoFault; 4117435Sgblack@eecs.umich.edu 4127435Sgblack@eecs.umich.edu DPRINTF(LSQUnit, "Executing load PC %#x, [sn:%lli]\n", 4137639Sgblack@eecs.umich.edu inst->readPC(),inst->seqNum); 4147639Sgblack@eecs.umich.edu 4157639Sgblack@eecs.umich.edu // Make sure it's really in the list. 4167639Sgblack@eecs.umich.edu // Normally it should always be in the list. However, 4177639Sgblack@eecs.umich.edu /* due to a syscall it may not be the list. 4187435Sgblack@eecs.umich.edu#ifdef DEBUG 4197639Sgblack@eecs.umich.edu int i = loadHead; 4207639Sgblack@eecs.umich.edu while (1) { 4217639Sgblack@eecs.umich.edu if (i == loadTail && !find(inst)) { 4227639Sgblack@eecs.umich.edu assert(0 && "Load not in the queue!"); 4237639Sgblack@eecs.umich.edu } else if (loadQueue[i] == inst) { 4247435Sgblack@eecs.umich.edu break; 4257639Sgblack@eecs.umich.edu } 4267639Sgblack@eecs.umich.edu 4277639Sgblack@eecs.umich.edu i = i + 1; 4287639Sgblack@eecs.umich.edu if (i >= LQEntries) { 4297435Sgblack@eecs.umich.edu i = 0; 4307639Sgblack@eecs.umich.edu } 4317639Sgblack@eecs.umich.edu } 4327639Sgblack@eecs.umich.edu#endif // DEBUG*/ 4337639Sgblack@eecs.umich.edu 4347639Sgblack@eecs.umich.edu// load_fault = inst->initiateAcc(); 4357639Sgblack@eecs.umich.edu load_fault = inst->execute(); 4367639Sgblack@eecs.umich.edu 4377639Sgblack@eecs.umich.edu // If the instruction faulted, then we need to send it along to commit 4387639Sgblack@eecs.umich.edu // without the instruction completing. 4397639Sgblack@eecs.umich.edu if (load_fault != NoFault) { 4407435Sgblack@eecs.umich.edu // Maybe just set it as can commit here, although that might cause 4417435Sgblack@eecs.umich.edu // some other problems with sending traps to the ROB too quickly. 4427435Sgblack@eecs.umich.edu iewStage->instToCommit(inst); 4437639Sgblack@eecs.umich.edu iewStage->activityThisCycle(); 4447639Sgblack@eecs.umich.edu } 4457639Sgblack@eecs.umich.edu 4467639Sgblack@eecs.umich.edu return load_fault; 4477639Sgblack@eecs.umich.edu} 4487639Sgblack@eecs.umich.edu 4497639Sgblack@eecs.umich.edutemplate <class Impl> 45012595Ssiddhesh.poyarekar@gmail.comFault 45112595Ssiddhesh.poyarekar@gmail.comLSQUnit<Impl>::executeLoad(int lq_idx) 4527435Sgblack@eecs.umich.edu{ 4537435Sgblack@eecs.umich.edu // Very hackish. Not sure the best way to check that this 4547435Sgblack@eecs.umich.edu // instruction is at the head of the ROB. I should have some sort 4557435Sgblack@eecs.umich.edu // of extra information here so that I'm not overloading the 4567435Sgblack@eecs.umich.edu // canCommit signal for 15 different things. 4577639Sgblack@eecs.umich.edu loadQueue[lq_idx]->setCanCommit(); 4587639Sgblack@eecs.umich.edu Fault ret_fault = executeLoad(loadQueue[lq_idx]); 4597639Sgblack@eecs.umich.edu loadQueue[lq_idx]->clearCanCommit(); 4607639Sgblack@eecs.umich.edu return ret_fault; 4617639Sgblack@eecs.umich.edu} 4627639Sgblack@eecs.umich.edu 4637639Sgblack@eecs.umich.edutemplate <class Impl> 4647435Sgblack@eecs.umich.eduFault 4657639Sgblack@eecs.umich.eduLSQUnit<Impl>::executeStore(DynInstPtr &store_inst) 4667639Sgblack@eecs.umich.edu{ 4677639Sgblack@eecs.umich.edu using namespace TheISA; 4687639Sgblack@eecs.umich.edu // Make sure that a store exists. 4697435Sgblack@eecs.umich.edu assert(stores != 0); 4707435Sgblack@eecs.umich.edu 4717435Sgblack@eecs.umich.edu int store_idx = store_inst->sqIdx; 4727639Sgblack@eecs.umich.edu 4737639Sgblack@eecs.umich.edu DPRINTF(LSQUnit, "Executing store PC %#x [sn:%lli]\n", 4747435Sgblack@eecs.umich.edu store_inst->readPC(), store_inst->seqNum); 4757639Sgblack@eecs.umich.edu 4767639Sgblack@eecs.umich.edu // Check the recently completed loads to see if any match this store's 4777435Sgblack@eecs.umich.edu // address. If so, then we have a memory ordering violation. 4787435Sgblack@eecs.umich.edu int load_idx = store_inst->lqIdx; 4797435Sgblack@eecs.umich.edu 4807639Sgblack@eecs.umich.edu Fault store_fault = store_inst->initiateAcc(); 4817639Sgblack@eecs.umich.edu// Fault store_fault = store_inst->execute(); 4827639Sgblack@eecs.umich.edu 4837639Sgblack@eecs.umich.edu // Store size should now be available. Use it to get proper offset for 4847639Sgblack@eecs.umich.edu // addr comparisons. 4857639Sgblack@eecs.umich.edu int size = storeQueue[store_idx].size; 4867639Sgblack@eecs.umich.edu 4877435Sgblack@eecs.umich.edu if (size == 0) { 4887639Sgblack@eecs.umich.edu DPRINTF(LSQUnit,"Fault on Store PC %#x, [sn:%lli],Size = 0\n", 4897639Sgblack@eecs.umich.edu store_inst->readPC(),store_inst->seqNum); 4907435Sgblack@eecs.umich.edu 4917435Sgblack@eecs.umich.edu return store_fault; 4927435Sgblack@eecs.umich.edu } 4937639Sgblack@eecs.umich.edu 4947639Sgblack@eecs.umich.edu assert(store_fault == NoFault); 4957639Sgblack@eecs.umich.edu 4967639Sgblack@eecs.umich.edu if (!storeFaultInst) { 4977639Sgblack@eecs.umich.edu if (store_fault != NoFault) { 4987639Sgblack@eecs.umich.edu panic("Fault in a store instruction!"); 4997639Sgblack@eecs.umich.edu storeFaultInst = store_inst; 5007435Sgblack@eecs.umich.edu } else if (store_inst->isNonSpeculative()) { 5017639Sgblack@eecs.umich.edu // Nonspeculative accesses (namely store conditionals) 5027639Sgblack@eecs.umich.edu // need to set themselves as able to writeback if we 5037435Sgblack@eecs.umich.edu // haven't had a fault by here. 5047435Sgblack@eecs.umich.edu storeQueue[store_idx].canWB = true; 5057435Sgblack@eecs.umich.edu 5067639Sgblack@eecs.umich.edu ++storesToWB; 5077639Sgblack@eecs.umich.edu } 5087435Sgblack@eecs.umich.edu } 5097639Sgblack@eecs.umich.edu 5107639Sgblack@eecs.umich.edu if (!memDepViolator) { 5117435Sgblack@eecs.umich.edu while (load_idx != loadTail) { 5127435Sgblack@eecs.umich.edu // Actually should only check loads that have actually executed 5137435Sgblack@eecs.umich.edu // Might be safe because effAddr is set to InvalAddr when the 5147639Sgblack@eecs.umich.edu // dyn inst is created. 5157639Sgblack@eecs.umich.edu 5167435Sgblack@eecs.umich.edu // Must actually check all addrs in the proper size range 5177435Sgblack@eecs.umich.edu // Which is more correct than needs to be. What if for now we just 5187639Sgblack@eecs.umich.edu // assume all loads are quad-word loads, and do the addr based 5197435Sgblack@eecs.umich.edu // on that. 5207435Sgblack@eecs.umich.edu // @todo: Fix this, magic number being used here 5217639Sgblack@eecs.umich.edu if ((loadQueue[load_idx]->effAddr >> 8) == 5227639Sgblack@eecs.umich.edu (store_inst->effAddr >> 8)) { 5237435Sgblack@eecs.umich.edu // A load incorrectly passed this store. Squash and refetch. 5247435Sgblack@eecs.umich.edu // For now return a fault to show that it was unsuccessful. 5257639Sgblack@eecs.umich.edu memDepViolator = loadQueue[load_idx]; 5267639Sgblack@eecs.umich.edu 5277435Sgblack@eecs.umich.edu return genMachineCheckFault(); 5287435Sgblack@eecs.umich.edu } 5297435Sgblack@eecs.umich.edu 5307435Sgblack@eecs.umich.edu incrLdIdx(load_idx); 5317435Sgblack@eecs.umich.edu } 5327639Sgblack@eecs.umich.edu 5337639Sgblack@eecs.umich.edu // If we've reached this point, there was no violation. 5347435Sgblack@eecs.umich.edu memDepViolator = NULL; 5357639Sgblack@eecs.umich.edu } 5367639Sgblack@eecs.umich.edu 5377435Sgblack@eecs.umich.edu return store_fault; 5387435Sgblack@eecs.umich.edu} 5397435Sgblack@eecs.umich.edu 5407639Sgblack@eecs.umich.edutemplate <class Impl> 5417639Sgblack@eecs.umich.eduvoid 5427435Sgblack@eecs.umich.eduLSQUnit<Impl>::commitLoad() 5437639Sgblack@eecs.umich.edu{ 5447639Sgblack@eecs.umich.edu assert(loadQueue[loadHead]); 5457435Sgblack@eecs.umich.edu 5467435Sgblack@eecs.umich.edu DPRINTF(LSQUnit, "Committing head load instruction, PC %#x\n", 5477435Sgblack@eecs.umich.edu loadQueue[loadHead]->readPC()); 5487435Sgblack@eecs.umich.edu 5497435Sgblack@eecs.umich.edu 5507639Sgblack@eecs.umich.edu loadQueue[loadHead] = NULL; 5517639Sgblack@eecs.umich.edu 5527435Sgblack@eecs.umich.edu incrLdIdx(loadHead); 5537639Sgblack@eecs.umich.edu 5547639Sgblack@eecs.umich.edu --loads; 5557435Sgblack@eecs.umich.edu} 5567435Sgblack@eecs.umich.edu 5577435Sgblack@eecs.umich.edutemplate <class Impl> 5587639Sgblack@eecs.umich.eduvoid 5597639Sgblack@eecs.umich.eduLSQUnit<Impl>::commitLoad(InstSeqNum &inst) 5607435Sgblack@eecs.umich.edu{ 5617639Sgblack@eecs.umich.edu // Hopefully I don't use this function too much 5627639Sgblack@eecs.umich.edu panic("Don't use this function!"); 5637435Sgblack@eecs.umich.edu 5647435Sgblack@eecs.umich.edu int i = loadHead; 5657435Sgblack@eecs.umich.edu while (1) { 5668607Sgblack@eecs.umich.edu if (i == loadTail) { 5678607Sgblack@eecs.umich.edu assert(0 && "Load not in the queue!"); 5687435Sgblack@eecs.umich.edu } else if (loadQueue[i]->seqNum == inst) { 5698607Sgblack@eecs.umich.edu break; 5708607Sgblack@eecs.umich.edu } 5717435Sgblack@eecs.umich.edu 5728607Sgblack@eecs.umich.edu ++i; 5738607Sgblack@eecs.umich.edu if (i >= LQEntries) { 5747435Sgblack@eecs.umich.edu i = 0; 5757435Sgblack@eecs.umich.edu } 5767435Sgblack@eecs.umich.edu } 5778607Sgblack@eecs.umich.edu 5787435Sgblack@eecs.umich.edu loadQueue[i]->removeInLSQ(); 5797435Sgblack@eecs.umich.edu loadQueue[i] = NULL; 5808607Sgblack@eecs.umich.edu --loads; 5818607Sgblack@eecs.umich.edu} 5827435Sgblack@eecs.umich.edu 5837435Sgblack@eecs.umich.edutemplate <class Impl> 5847435Sgblack@eecs.umich.eduvoid 5857639Sgblack@eecs.umich.eduLSQUnit<Impl>::commitLoads(InstSeqNum &youngest_inst) 5867639Sgblack@eecs.umich.edu{ 5877435Sgblack@eecs.umich.edu assert(loads == 0 || loadQueue[loadHead]); 5887639Sgblack@eecs.umich.edu 5897639Sgblack@eecs.umich.edu while (loads != 0 && loadQueue[loadHead]->seqNum <= youngest_inst) { 5907435Sgblack@eecs.umich.edu commitLoad(); 5917435Sgblack@eecs.umich.edu } 5927435Sgblack@eecs.umich.edu} 59310037SARM gem5 Developers 59410037SARM gem5 Developerstemplate <class Impl> 59510037SARM gem5 Developersvoid 59610037SARM gem5 DevelopersLSQUnit<Impl>::commitStores(InstSeqNum &youngest_inst) 59710037SARM gem5 Developers{ 59810037SARM gem5 Developers assert(stores == 0 || storeQueue[storeHead].inst); 59910037SARM gem5 Developers 60010037SARM gem5 Developers int store_idx = storeHead; 60110037SARM gem5 Developers 60210037SARM gem5 Developers while (store_idx != storeTail) { 60310037SARM gem5 Developers assert(storeQueue[store_idx].inst); 60410037SARM gem5 Developers if (!storeQueue[store_idx].canWB) { 60510037SARM gem5 Developers if (storeQueue[store_idx].inst->seqNum > youngest_inst) { 60610037SARM gem5 Developers break; 60710037SARM gem5 Developers } 60810037SARM gem5 Developers DPRINTF(LSQUnit, "Marking store as able to write back, PC " 60910037SARM gem5 Developers "%#x [sn:%lli]\n", 6107435Sgblack@eecs.umich.edu storeQueue[store_idx].inst->readPC(), 6117435Sgblack@eecs.umich.edu storeQueue[store_idx].inst->seqNum); 6127435Sgblack@eecs.umich.edu 6137435Sgblack@eecs.umich.edu storeQueue[store_idx].canWB = true; 6147435Sgblack@eecs.umich.edu 6157639Sgblack@eecs.umich.edu// --stores; 6167639Sgblack@eecs.umich.edu ++storesToWB; 6177639Sgblack@eecs.umich.edu } 6187639Sgblack@eecs.umich.edu 6197639Sgblack@eecs.umich.edu incrStIdx(store_idx); 6207435Sgblack@eecs.umich.edu } 6217435Sgblack@eecs.umich.edu} 6227435Sgblack@eecs.umich.edu 6237435Sgblack@eecs.umich.edutemplate <class Impl> 6247435Sgblack@eecs.umich.eduvoid 6257639Sgblack@eecs.umich.eduLSQUnit<Impl>::writebackStores() 6267639Sgblack@eecs.umich.edu{ 6277639Sgblack@eecs.umich.edu while (storesToWB > 0 && 6287639Sgblack@eecs.umich.edu storeWBIdx != storeTail && 6297639Sgblack@eecs.umich.edu storeQueue[storeWBIdx].inst && 6307435Sgblack@eecs.umich.edu storeQueue[storeWBIdx].canWB && 6317639Sgblack@eecs.umich.edu usedPorts < cachePorts) { 6327639Sgblack@eecs.umich.edu 6337639Sgblack@eecs.umich.edu if (storeQueue[storeWBIdx].size == 0) { 6347639Sgblack@eecs.umich.edu completeStore(storeWBIdx); 6357639Sgblack@eecs.umich.edu 6367435Sgblack@eecs.umich.edu incrStIdx(storeWBIdx); 6377435Sgblack@eecs.umich.edu 6387435Sgblack@eecs.umich.edu continue; 6397435Sgblack@eecs.umich.edu } 6407435Sgblack@eecs.umich.edu 6417639Sgblack@eecs.umich.edu if (dcacheInterface && dcacheInterface->isBlocked()) { 6427639Sgblack@eecs.umich.edu DPRINTF(LSQUnit, "Unable to write back any more stores, cache" 6437639Sgblack@eecs.umich.edu " is blocked!\n"); 6447639Sgblack@eecs.umich.edu break; 6457639Sgblack@eecs.umich.edu } 6467435Sgblack@eecs.umich.edu 6477639Sgblack@eecs.umich.edu ++usedPorts; 6487639Sgblack@eecs.umich.edu 6497639Sgblack@eecs.umich.edu if (storeQueue[storeWBIdx].inst->isDataPrefetch()) { 6507639Sgblack@eecs.umich.edu incrStIdx(storeWBIdx); 6517639Sgblack@eecs.umich.edu 6527435Sgblack@eecs.umich.edu continue; 6537435Sgblack@eecs.umich.edu } 6547435Sgblack@eecs.umich.edu 6557639Sgblack@eecs.umich.edu assert(storeQueue[storeWBIdx].req); 6567639Sgblack@eecs.umich.edu assert(!storeQueue[storeWBIdx].committed); 6577639Sgblack@eecs.umich.edu 6587639Sgblack@eecs.umich.edu MemReqPtr req = storeQueue[storeWBIdx].req; 6597639Sgblack@eecs.umich.edu storeQueue[storeWBIdx].committed = true; 6607435Sgblack@eecs.umich.edu 6617639Sgblack@eecs.umich.edu// Fault fault = cpu->translateDataWriteReq(req); 6627639Sgblack@eecs.umich.edu req->cmd = Write; 6637639Sgblack@eecs.umich.edu req->completionEvent = NULL; 6647639Sgblack@eecs.umich.edu req->time = curTick; 6657639Sgblack@eecs.umich.edu assert(!req->data); 6667435Sgblack@eecs.umich.edu req->data = new uint8_t[64]; 6677435Sgblack@eecs.umich.edu memcpy(req->data, (uint8_t *)&storeQueue[storeWBIdx].data, req->size); 6687435Sgblack@eecs.umich.edu 6697435Sgblack@eecs.umich.edu DPRINTF(LSQUnit, "D-Cache: Writing back store idx:%i PC:%#x " 6707435Sgblack@eecs.umich.edu "to Addr:%#x, data:%#x [sn:%lli]\n", 6717435Sgblack@eecs.umich.edu storeWBIdx,storeQueue[storeWBIdx].inst->readPC(), 6727435Sgblack@eecs.umich.edu req->paddr, *(req->data), 6737639Sgblack@eecs.umich.edu storeQueue[storeWBIdx].inst->seqNum); 6747639Sgblack@eecs.umich.edu 6757639Sgblack@eecs.umich.edu// if (fault != NoFault) { 6767639Sgblack@eecs.umich.edu //What should we do if there is a fault??? 6777639Sgblack@eecs.umich.edu //for now panic 6787435Sgblack@eecs.umich.edu// panic("Page Table Fault!!!!!\n"); 6797639Sgblack@eecs.umich.edu// } 6807639Sgblack@eecs.umich.edu switch(storeQueue[storeWBIdx].size) { 6817639Sgblack@eecs.umich.edu case 1: 6827639Sgblack@eecs.umich.edu cpu->write(req, (uint8_t &)storeQueue[storeWBIdx].data); 6837639Sgblack@eecs.umich.edu break; 6847435Sgblack@eecs.umich.edu case 2: 6857435Sgblack@eecs.umich.edu cpu->write(req, (uint16_t &)storeQueue[storeWBIdx].data); 6867435Sgblack@eecs.umich.edu break; 6877435Sgblack@eecs.umich.edu case 4: 6887435Sgblack@eecs.umich.edu cpu->write(req, (uint32_t &)storeQueue[storeWBIdx].data); 6897435Sgblack@eecs.umich.edu break; 6907435Sgblack@eecs.umich.edu case 8: 6917639Sgblack@eecs.umich.edu cpu->write(req, (uint64_t &)storeQueue[storeWBIdx].data); 6927639Sgblack@eecs.umich.edu break; 6937639Sgblack@eecs.umich.edu default: 6947639Sgblack@eecs.umich.edu panic("Unexpected store size!\n"); 6957639Sgblack@eecs.umich.edu } 6967435Sgblack@eecs.umich.edu 6977639Sgblack@eecs.umich.edu if (dcacheInterface) { 6987639Sgblack@eecs.umich.edu MemAccessResult result = dcacheInterface->access(req); 6997639Sgblack@eecs.umich.edu 7007639Sgblack@eecs.umich.edu if (isStalled() && 7017639Sgblack@eecs.umich.edu storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) { 7027435Sgblack@eecs.umich.edu DPRINTF(LSQUnit, "Unstalling, stalling store [sn:%lli] " 7037435Sgblack@eecs.umich.edu "load idx:%i\n", 7047435Sgblack@eecs.umich.edu stallingStoreIsn, stallingLoadIdx); 7057639Sgblack@eecs.umich.edu stalled = false; 7067639Sgblack@eecs.umich.edu stallingStoreIsn = 0; 7077639Sgblack@eecs.umich.edu iewStage->replayMemInst(loadQueue[stallingLoadIdx]); 7087639Sgblack@eecs.umich.edu } 7097639Sgblack@eecs.umich.edu 7107435Sgblack@eecs.umich.edu if (result != MA_HIT && dcacheInterface->doEvents()) { 7117435Sgblack@eecs.umich.edu typename IEW::LdWritebackEvent *wb = NULL; 7127435Sgblack@eecs.umich.edu if (req->flags & LOCKED) { 7137435Sgblack@eecs.umich.edu // Stx_C does not generate a system port transaction. 7147435Sgblack@eecs.umich.edu/* 7157435Sgblack@eecs.umich.edu if (cpu->lockFlag && cpu->lockAddr == req->paddr) { 7167435Sgblack@eecs.umich.edu req->result=1; 7177435Sgblack@eecs.umich.edu } else { 7187435Sgblack@eecs.umich.edu req->result = 0; 7197435Sgblack@eecs.umich.edu } 7207435Sgblack@eecs.umich.edu*/ 7217639Sgblack@eecs.umich.edu wb = new typename IEW::LdWritebackEvent(storeQueue[storeWBIdx].inst, 7227639Sgblack@eecs.umich.edu iewStage); 7237639Sgblack@eecs.umich.edu } 7247639Sgblack@eecs.umich.edu 7257639Sgblack@eecs.umich.edu DPRINTF(LSQUnit,"D-Cache Write Miss!\n"); 7267435Sgblack@eecs.umich.edu 7277639Sgblack@eecs.umich.edu DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n", 7287639Sgblack@eecs.umich.edu storeQueue[storeWBIdx].inst->seqNum); 7297639Sgblack@eecs.umich.edu 7307639Sgblack@eecs.umich.edu // Will stores need their own kind of writeback events? 7317639Sgblack@eecs.umich.edu // Do stores even need writeback events? 7327435Sgblack@eecs.umich.edu assert(!req->completionEvent); 7337435Sgblack@eecs.umich.edu req->completionEvent = new 7347435Sgblack@eecs.umich.edu StoreCompletionEvent(storeWBIdx, wb, this); 7357435Sgblack@eecs.umich.edu 7367435Sgblack@eecs.umich.edu lastDcacheStall = curTick; 7377639Sgblack@eecs.umich.edu 7387639Sgblack@eecs.umich.edu// _status = DcacheMissStall; 7397639Sgblack@eecs.umich.edu 7407639Sgblack@eecs.umich.edu //mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum); 7417639Sgblack@eecs.umich.edu 7427435Sgblack@eecs.umich.edu //DPRINTF(LSQUnit, "Added MSHR. count = %i\n",mshrSeqNums.size()); 7437639Sgblack@eecs.umich.edu 7447639Sgblack@eecs.umich.edu // Increment stat here or something 7457639Sgblack@eecs.umich.edu } else { 7467639Sgblack@eecs.umich.edu DPRINTF(LSQUnit,"D-Cache: Write Hit on idx:%i !\n", 7477639Sgblack@eecs.umich.edu storeWBIdx); 7487435Sgblack@eecs.umich.edu 7497435Sgblack@eecs.umich.edu DPRINTF(Activity, "Active st accessing mem hit [sn:%lli]\n", 7507435Sgblack@eecs.umich.edu storeQueue[storeWBIdx].inst->seqNum); 7517639Sgblack@eecs.umich.edu 7527639Sgblack@eecs.umich.edu 7537639Sgblack@eecs.umich.edu if (req->flags & LOCKED) { 7547639Sgblack@eecs.umich.edu // Stx_C does not generate a system port transaction. 7557639Sgblack@eecs.umich.edu/* 7567435Sgblack@eecs.umich.edu if (req->flags & UNCACHEABLE) { 7577639Sgblack@eecs.umich.edu req->result = 2; 7587639Sgblack@eecs.umich.edu } else { 7597639Sgblack@eecs.umich.edu if (cpu->lockFlag && cpu->lockAddr == req->paddr) { 7607639Sgblack@eecs.umich.edu req->result=1; 7617639Sgblack@eecs.umich.edu } else { 7627435Sgblack@eecs.umich.edu req->result = 0; 7637435Sgblack@eecs.umich.edu } 7647435Sgblack@eecs.umich.edu } 7657435Sgblack@eecs.umich.edu*/ 7667435Sgblack@eecs.umich.edu typename IEW::LdWritebackEvent *wb = 7677435Sgblack@eecs.umich.edu new typename IEW::LdWritebackEvent(storeQueue[storeWBIdx].inst, 7687435Sgblack@eecs.umich.edu iewStage); 7697435Sgblack@eecs.umich.edu wb->schedule(curTick); 7707435Sgblack@eecs.umich.edu } 7717435Sgblack@eecs.umich.edu 7727639Sgblack@eecs.umich.edu completeStore(storeWBIdx); 7737639Sgblack@eecs.umich.edu } 7747639Sgblack@eecs.umich.edu 7757639Sgblack@eecs.umich.edu incrStIdx(storeWBIdx); 7767435Sgblack@eecs.umich.edu } else { 7777639Sgblack@eecs.umich.edu panic("Must HAVE DCACHE!!!!!\n"); 7787639Sgblack@eecs.umich.edu } 7797639Sgblack@eecs.umich.edu } 7807639Sgblack@eecs.umich.edu 7817639Sgblack@eecs.umich.edu // Not sure this should set it to 0. 7827853SMatt.Horsnell@ARM.com usedPorts = 0; 7837853SMatt.Horsnell@ARM.com 7847853SMatt.Horsnell@ARM.com assert(stores >= 0 && storesToWB >= 0); 7857853SMatt.Horsnell@ARM.com} 7867853SMatt.Horsnell@ARM.com 7877853SMatt.Horsnell@ARM.com/*template <class Impl> 7887853SMatt.Horsnell@ARM.comvoid 7897853SMatt.Horsnell@ARM.comLSQUnit<Impl>::removeMSHR(InstSeqNum seqNum) 7907853SMatt.Horsnell@ARM.com{ 7917435Sgblack@eecs.umich.edu list<InstSeqNum>::iterator mshr_it = find(mshrSeqNums.begin(), 7927435Sgblack@eecs.umich.edu mshrSeqNums.end(), 7937435Sgblack@eecs.umich.edu seqNum); 7947639Sgblack@eecs.umich.edu 7957639Sgblack@eecs.umich.edu if (mshr_it != mshrSeqNums.end()) { 7967639Sgblack@eecs.umich.edu mshrSeqNums.erase(mshr_it); 7977639Sgblack@eecs.umich.edu DPRINTF(LSQUnit, "Removing MSHR. count = %i\n",mshrSeqNums.size()); 7987435Sgblack@eecs.umich.edu } 7997639Sgblack@eecs.umich.edu}*/ 8007639Sgblack@eecs.umich.edu 8017639Sgblack@eecs.umich.edutemplate <class Impl> 8027639Sgblack@eecs.umich.eduvoid 8037435Sgblack@eecs.umich.eduLSQUnit<Impl>::squash(const InstSeqNum &squashed_num) 8047435Sgblack@eecs.umich.edu{ 8057435Sgblack@eecs.umich.edu DPRINTF(LSQUnit, "Squashing until [sn:%lli]!" 8067639Sgblack@eecs.umich.edu "(Loads:%i Stores:%i)\n",squashed_num,loads,stores); 8077639Sgblack@eecs.umich.edu 8087639Sgblack@eecs.umich.edu int load_idx = loadTail; 8097639Sgblack@eecs.umich.edu decrLdIdx(load_idx); 8107639Sgblack@eecs.umich.edu 8117639Sgblack@eecs.umich.edu while (loads != 0 && loadQueue[load_idx]->seqNum > squashed_num) { 8127639Sgblack@eecs.umich.edu 8137639Sgblack@eecs.umich.edu // Clear the smart pointer to make sure it is decremented. 8147639Sgblack@eecs.umich.edu DPRINTF(LSQUnit,"Load Instruction PC %#x squashed, " 8157639Sgblack@eecs.umich.edu "[sn:%lli]\n", 8167639Sgblack@eecs.umich.edu loadQueue[load_idx]->readPC(), 8177639Sgblack@eecs.umich.edu loadQueue[load_idx]->seqNum); 8187639Sgblack@eecs.umich.edu 8197639Sgblack@eecs.umich.edu if (isStalled() && load_idx == stallingLoadIdx) { 8207639Sgblack@eecs.umich.edu stalled = false; 8217639Sgblack@eecs.umich.edu stallingStoreIsn = 0; 8227639Sgblack@eecs.umich.edu stallingLoadIdx = 0; 8237639Sgblack@eecs.umich.edu } 8247435Sgblack@eecs.umich.edu 8257435Sgblack@eecs.umich.edu loadQueue[load_idx]->squashed = true; 8267639Sgblack@eecs.umich.edu loadQueue[load_idx] = NULL; 8277639Sgblack@eecs.umich.edu --loads; 8287639Sgblack@eecs.umich.edu 8297639Sgblack@eecs.umich.edu // Inefficient! 8307435Sgblack@eecs.umich.edu loadTail = load_idx; 8317639Sgblack@eecs.umich.edu 8327639Sgblack@eecs.umich.edu decrLdIdx(load_idx); 8337639Sgblack@eecs.umich.edu } 8347639Sgblack@eecs.umich.edu 8357435Sgblack@eecs.umich.edu if (isLoadBlocked) { 8367435Sgblack@eecs.umich.edu if (squashed_num < blockedLoadSeqNum) { 8377435Sgblack@eecs.umich.edu isLoadBlocked = false; 8387435Sgblack@eecs.umich.edu loadBlockedHandled = false; 8397435Sgblack@eecs.umich.edu blockedLoadSeqNum = 0; 8407435Sgblack@eecs.umich.edu } 8417639Sgblack@eecs.umich.edu } 8427639Sgblack@eecs.umich.edu 8437639Sgblack@eecs.umich.edu int store_idx = storeTail; 8447639Sgblack@eecs.umich.edu decrStIdx(store_idx); 8457435Sgblack@eecs.umich.edu 8467639Sgblack@eecs.umich.edu while (stores != 0 && 8477639Sgblack@eecs.umich.edu storeQueue[store_idx].inst->seqNum > squashed_num) { 8487639Sgblack@eecs.umich.edu 8497639Sgblack@eecs.umich.edu if (storeQueue[store_idx].canWB) { 8507435Sgblack@eecs.umich.edu break; 8517435Sgblack@eecs.umich.edu } 8527435Sgblack@eecs.umich.edu 8537639Sgblack@eecs.umich.edu // Clear the smart pointer to make sure it is decremented. 8547639Sgblack@eecs.umich.edu DPRINTF(LSQUnit,"Store Instruction PC %#x squashed, " 8557639Sgblack@eecs.umich.edu "idx:%i [sn:%lli]\n", 8567639Sgblack@eecs.umich.edu storeQueue[store_idx].inst->readPC(), 8577435Sgblack@eecs.umich.edu store_idx, storeQueue[store_idx].inst->seqNum); 8587435Sgblack@eecs.umich.edu 8597639Sgblack@eecs.umich.edu // I don't think this can happen. It should have been cleared by the 8607639Sgblack@eecs.umich.edu // stalling load. 8617639Sgblack@eecs.umich.edu if (isStalled() && 8627639Sgblack@eecs.umich.edu storeQueue[store_idx].inst->seqNum == stallingStoreIsn) { 8637435Sgblack@eecs.umich.edu panic("Is stalled should have been cleared by stalling load!\n"); 8647639Sgblack@eecs.umich.edu stalled = false; 8657639Sgblack@eecs.umich.edu stallingStoreIsn = 0; 8667639Sgblack@eecs.umich.edu } 8677639Sgblack@eecs.umich.edu 8687435Sgblack@eecs.umich.edu storeQueue[store_idx].inst->squashed = true; 8697435Sgblack@eecs.umich.edu storeQueue[store_idx].inst = NULL; 8707435Sgblack@eecs.umich.edu storeQueue[store_idx].canWB = 0; 8717435Sgblack@eecs.umich.edu 8727435Sgblack@eecs.umich.edu if (storeQueue[store_idx].req) { 8737435Sgblack@eecs.umich.edu assert(!storeQueue[store_idx].req->completionEvent); 8747435Sgblack@eecs.umich.edu } 8757435Sgblack@eecs.umich.edu storeQueue[store_idx].req = NULL; 8767435Sgblack@eecs.umich.edu --stores; 8777435Sgblack@eecs.umich.edu 8787435Sgblack@eecs.umich.edu // Inefficient! 8797435Sgblack@eecs.umich.edu storeTail = store_idx; 8807435Sgblack@eecs.umich.edu 8817435Sgblack@eecs.umich.edu decrStIdx(store_idx); 8827639Sgblack@eecs.umich.edu } 8837639Sgblack@eecs.umich.edu} 8847639Sgblack@eecs.umich.edu 8857639Sgblack@eecs.umich.edutemplate <class Impl> 8867639Sgblack@eecs.umich.eduvoid 8877639Sgblack@eecs.umich.eduLSQUnit<Impl>::dumpInsts() 8887639Sgblack@eecs.umich.edu{ 8897639Sgblack@eecs.umich.edu cprintf("Load store queue: Dumping instructions.\n"); 8907639Sgblack@eecs.umich.edu cprintf("Load queue size: %i\n", loads); 8917639Sgblack@eecs.umich.edu cprintf("Load queue: "); 8927639Sgblack@eecs.umich.edu 8937639Sgblack@eecs.umich.edu int load_idx = loadHead; 8947639Sgblack@eecs.umich.edu 8957639Sgblack@eecs.umich.edu while (load_idx != loadTail && loadQueue[load_idx]) { 8967639Sgblack@eecs.umich.edu cprintf("%#x ", loadQueue[load_idx]->readPC()); 8977639Sgblack@eecs.umich.edu 8987639Sgblack@eecs.umich.edu incrLdIdx(load_idx); 8997639Sgblack@eecs.umich.edu } 9007639Sgblack@eecs.umich.edu 9017639Sgblack@eecs.umich.edu cprintf("Store queue size: %i\n", stores); 9027639Sgblack@eecs.umich.edu cprintf("Store queue: "); 9037639Sgblack@eecs.umich.edu 9047639Sgblack@eecs.umich.edu int store_idx = storeHead; 9057639Sgblack@eecs.umich.edu 9067639Sgblack@eecs.umich.edu while (store_idx != storeTail && storeQueue[store_idx].inst) { 9077639Sgblack@eecs.umich.edu cprintf("%#x ", storeQueue[store_idx].inst->readPC()); 9087435Sgblack@eecs.umich.edu 9097435Sgblack@eecs.umich.edu incrStIdx(store_idx); 9107435Sgblack@eecs.umich.edu } 9117639Sgblack@eecs.umich.edu 9127639Sgblack@eecs.umich.edu cprintf("\n"); 9137435Sgblack@eecs.umich.edu} 9147639Sgblack@eecs.umich.edu 9157639Sgblack@eecs.umich.edutemplate <class Impl> 9167435Sgblack@eecs.umich.eduvoid 9177639Sgblack@eecs.umich.eduLSQUnit<Impl>::completeStore(int store_idx) 9187639Sgblack@eecs.umich.edu{ 9197435Sgblack@eecs.umich.edu assert(storeQueue[store_idx].inst); 9207639Sgblack@eecs.umich.edu storeQueue[store_idx].completed = true; 9217639Sgblack@eecs.umich.edu --storesToWB; 9227435Sgblack@eecs.umich.edu // A bit conservative because a store completion may not free up entries, 9237435Sgblack@eecs.umich.edu // but hopefully avoids two store completions in one cycle from making 9247639Sgblack@eecs.umich.edu // the CPU tick twice. 9257639Sgblack@eecs.umich.edu cpu->activityThisCycle(); 9267435Sgblack@eecs.umich.edu 9277435Sgblack@eecs.umich.edu if (store_idx == storeHead) { 9287435Sgblack@eecs.umich.edu do { 9297435Sgblack@eecs.umich.edu incrStIdx(storeHead); 9307435Sgblack@eecs.umich.edu 9317639Sgblack@eecs.umich.edu --stores; 9327639Sgblack@eecs.umich.edu } while (storeQueue[storeHead].completed && 9337435Sgblack@eecs.umich.edu storeHead != storeTail); 9347639Sgblack@eecs.umich.edu 9357639Sgblack@eecs.umich.edu iewStage->updateLSQNextCycle = true; 9367435Sgblack@eecs.umich.edu } 9377435Sgblack@eecs.umich.edu 9387435Sgblack@eecs.umich.edu DPRINTF(LSQUnit, "Store head idx:%i\n", storeHead); 9397639Sgblack@eecs.umich.edu 9407639Sgblack@eecs.umich.edu if (isStalled() && 9417639Sgblack@eecs.umich.edu storeQueue[store_idx].inst->seqNum == stallingStoreIsn) { 9427639Sgblack@eecs.umich.edu DPRINTF(LSQUnit, "Unstalling, stalling store [sn:%lli] " 9437639Sgblack@eecs.umich.edu "load idx:%i\n", 9447639Sgblack@eecs.umich.edu stallingStoreIsn, stallingLoadIdx); 9457639Sgblack@eecs.umich.edu stalled = false; 9467639Sgblack@eecs.umich.edu stallingStoreIsn = 0; 9477639Sgblack@eecs.umich.edu iewStage->replayMemInst(loadQueue[stallingLoadIdx]); 9487639Sgblack@eecs.umich.edu } 9497639Sgblack@eecs.umich.edu} 9507639Sgblack@eecs.umich.edu 9517435Sgblack@eecs.umich.edutemplate <class Impl> 9527435Sgblack@eecs.umich.eduinline void 9537435Sgblack@eecs.umich.eduLSQUnit<Impl>::incrStIdx(int &store_idx) 9547435Sgblack@eecs.umich.edu{ 9557639Sgblack@eecs.umich.edu if (++store_idx >= SQEntries) 9567639Sgblack@eecs.umich.edu store_idx = 0; 9577435Sgblack@eecs.umich.edu} 9587639Sgblack@eecs.umich.edu 9597639Sgblack@eecs.umich.edutemplate <class Impl> 9607435Sgblack@eecs.umich.eduinline void 9617435Sgblack@eecs.umich.eduLSQUnit<Impl>::decrStIdx(int &store_idx) 9627435Sgblack@eecs.umich.edu{ 9637435Sgblack@eecs.umich.edu if (--store_idx < 0) 9647639Sgblack@eecs.umich.edu store_idx += SQEntries; 9657639Sgblack@eecs.umich.edu} 9667639Sgblack@eecs.umich.edu 9677435Sgblack@eecs.umich.edutemplate <class Impl> 9687639Sgblack@eecs.umich.eduinline void 9697639Sgblack@eecs.umich.eduLSQUnit<Impl>::incrLdIdx(int &load_idx) 9707435Sgblack@eecs.umich.edu{ 9717435Sgblack@eecs.umich.edu if (++load_idx >= LQEntries) 9727435Sgblack@eecs.umich.edu load_idx = 0; 9737435Sgblack@eecs.umich.edu} 9747435Sgblack@eecs.umich.edu 9757639Sgblack@eecs.umich.edutemplate <class Impl> 9767639Sgblack@eecs.umich.eduinline void 9777435Sgblack@eecs.umich.eduLSQUnit<Impl>::decrLdIdx(int &load_idx) 9787435Sgblack@eecs.umich.edu{ 9797639Sgblack@eecs.umich.edu if (--load_idx < 0) 9807639Sgblack@eecs.umich.edu load_idx += LQEntries; 9817639Sgblack@eecs.umich.edu} 9827639Sgblack@eecs.umich.edu