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