lsq_unit.hh revision 2307
16313Sgblack@eecs.umich.edu/* 212529Sgiacomo.travaglini@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 37093Sgblack@eecs.umich.edu * All rights reserved. 47093Sgblack@eecs.umich.edu * 57093Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 67093Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 77093Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 87093Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 97093Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 107093Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 117093Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 127093Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137093Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 146313Sgblack@eecs.umich.edu * this software without specific prior written permission. 156313Sgblack@eecs.umich.edu * 166313Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176313Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186313Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196313Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206313Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216313Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226313Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236313Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246313Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256313Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266313Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276313Sgblack@eecs.umich.edu */ 286313Sgblack@eecs.umich.edu 296313Sgblack@eecs.umich.edu#ifndef __CPU_O3_LSQ_UNIT_HH__ 306313Sgblack@eecs.umich.edu#define __CPU_O3_LSQ_UNIT_HH__ 316313Sgblack@eecs.umich.edu 326313Sgblack@eecs.umich.edu#include <map> 336313Sgblack@eecs.umich.edu#include <queue> 346313Sgblack@eecs.umich.edu#include <algorithm> 356313Sgblack@eecs.umich.edu 366313Sgblack@eecs.umich.edu#include "config/full_system.hh" 376313Sgblack@eecs.umich.edu#include "base/hashmap.hh" 386313Sgblack@eecs.umich.edu#include "cpu/inst_seq.hh" 396313Sgblack@eecs.umich.edu#include "mem/mem_interface.hh" 406313Sgblack@eecs.umich.edu//#include "mem/page_table.hh" 416313Sgblack@eecs.umich.edu#include "sim/debug.hh" 426313Sgblack@eecs.umich.edu#include "sim/sim_object.hh" 436313Sgblack@eecs.umich.edu#include "arch/faults.hh" 447404SAli.Saidi@ARM.com 456313Sgblack@eecs.umich.edu/** 4610461SAndreas.Sandberg@ARM.com * Class that implements the actual LQ and SQ for each specific thread. 4712479SCurtis.Dunham@arm.com * Both are circular queues; load entries are freed upon committing, while 486333Sgblack@eecs.umich.edu * store entries are freed once they writeback. The LSQUnit tracks if there 4910037SARM gem5 Developers * are memory ordering violations, and also detects partial load to store 507404SAli.Saidi@ARM.com * forwarding cases (a store only has part of a load's data) that requires 516313Sgblack@eecs.umich.edu * the load to wait until the store writes back. In the former case it 5212109SRekai.GonzalezAlberquilla@arm.com * holds onto the instruction until the dependence unit looks at it, and 538232Snate@binkert.org * in the latter it stalls the LSQ until the store writes back. At that 5412109SRekai.GonzalezAlberquilla@arm.com * point the load is replayed. 559384SAndreas.Sandberg@arm.com */ 5611165SRekai.GonzalezAlberquilla@arm.comtemplate <class Impl> 576313Sgblack@eecs.umich.educlass LSQUnit { 589384SAndreas.Sandberg@arm.com protected: 5910461SAndreas.Sandberg@ARM.com typedef TheISA::IntReg IntReg; 606333Sgblack@eecs.umich.edu public: 616313Sgblack@eecs.umich.edu typedef typename Impl::Params Params; 626313Sgblack@eecs.umich.edu typedef typename Impl::FullCPU FullCPU; 636313Sgblack@eecs.umich.edu typedef typename Impl::DynInstPtr DynInstPtr; 646313Sgblack@eecs.umich.edu typedef typename Impl::CPUPol::IEW IEW; 656313Sgblack@eecs.umich.edu typedef typename Impl::CPUPol::IssueStruct IssueStruct; 669384SAndreas.Sandberg@arm.com 676313Sgblack@eecs.umich.edu private: 686313Sgblack@eecs.umich.edu class StoreCompletionEvent : public Event { 6910037SARM gem5 Developers public: 7010037SARM gem5 Developers /** Constructs a store completion event. */ 7110037SARM gem5 Developers StoreCompletionEvent(int store_idx, Event *wb_event, LSQUnit *lsq_ptr); 7211165SRekai.GonzalezAlberquilla@arm.com 7311165SRekai.GonzalezAlberquilla@arm.com /** Processes the store completion event. */ 7412109SRekai.GonzalezAlberquilla@arm.com void process(); 7511165SRekai.GonzalezAlberquilla@arm.com 7610461SAndreas.Sandberg@ARM.com /** Returns the description of this event. */ 7710461SAndreas.Sandberg@ARM.com const char *description(); 7810461SAndreas.Sandberg@ARM.com 7910461SAndreas.Sandberg@ARM.com private: 8010461SAndreas.Sandberg@ARM.com /** The store index of the store being written back. */ 8110461SAndreas.Sandberg@ARM.com int storeIdx; 8210844Sandreas.sandberg@arm.com /** The writeback event for the store. Needed for store 8310844Sandreas.sandberg@arm.com * conditionals. 8410844Sandreas.sandberg@arm.com */ 8510037SARM gem5 Developers Event *wbEvent; 8611771SCurtis.Dunham@arm.com /** The pointer to the LSQ unit that issued the store. */ 8710037SARM gem5 Developers LSQUnit<Impl> *lsqPtr; 8810037SARM gem5 Developers }; 8910037SARM gem5 Developers 9013173Sgiacomo.travaglini@arm.com friend class StoreCompletionEvent; 9110037SARM gem5 Developers 9213114Sgiacomo.travaglini@arm.com public: 9310037SARM gem5 Developers /** Constructs an LSQ unit. init() must be called prior to use. */ 9412714Sgiacomo.travaglini@arm.com LSQUnit(); 9512714Sgiacomo.travaglini@arm.com 9612714Sgiacomo.travaglini@arm.com /** Initializes the LSQ unit with the specified number of entries. */ 9712714Sgiacomo.travaglini@arm.com void init(Params *params, unsigned maxLQEntries, 9812714Sgiacomo.travaglini@arm.com unsigned maxSQEntries, unsigned id); 9912714Sgiacomo.travaglini@arm.com 10012478SCurtis.Dunham@arm.com /** Returns the name of the LSQ unit. */ 10110037SARM gem5 Developers std::string name() const; 10212477SCurtis.Dunham@arm.com 10312477SCurtis.Dunham@arm.com /** Sets the CPU pointer. */ 10412478SCurtis.Dunham@arm.com void setCPU(FullCPU *cpu_ptr) 10512478SCurtis.Dunham@arm.com { cpu = cpu_ptr; } 10612478SCurtis.Dunham@arm.com 10712478SCurtis.Dunham@arm.com /** Sets the IEW stage pointer. */ 10812478SCurtis.Dunham@arm.com void setIEW(IEW *iew_ptr) 10912478SCurtis.Dunham@arm.com { iewStage = iew_ptr; } 11012478SCurtis.Dunham@arm.com 11112478SCurtis.Dunham@arm.com /** Sets the page table pointer. */ 11212478SCurtis.Dunham@arm.com// void setPageTable(PageTable *pt_ptr); 11312478SCurtis.Dunham@arm.com 11412478SCurtis.Dunham@arm.com void switchOut(); 11512478SCurtis.Dunham@arm.com 11612478SCurtis.Dunham@arm.com void takeOverFrom(); 11712478SCurtis.Dunham@arm.com 11812478SCurtis.Dunham@arm.com bool isSwitchedOut() { return switchedOut; } 11912478SCurtis.Dunham@arm.com 12010037SARM gem5 Developers /** Ticks the LSQ unit, which in this case only resets the number of 12110037SARM gem5 Developers * used cache ports. 12212477SCurtis.Dunham@arm.com * @todo: Move the number of used ports up to the LSQ level so it can 12312479SCurtis.Dunham@arm.com * be shared by all LSQ units. 12412477SCurtis.Dunham@arm.com */ 12512477SCurtis.Dunham@arm.com void tick() { usedPorts = 0; } 12612477SCurtis.Dunham@arm.com 12712479SCurtis.Dunham@arm.com /** Inserts an instruction. */ 12812477SCurtis.Dunham@arm.com void insert(DynInstPtr &inst); 12912477SCurtis.Dunham@arm.com /** Inserts a load instruction. */ 13012477SCurtis.Dunham@arm.com void insertLoad(DynInstPtr &load_inst); 13112477SCurtis.Dunham@arm.com /** Inserts a store instruction. */ 13212477SCurtis.Dunham@arm.com void insertStore(DynInstPtr &store_inst); 13312477SCurtis.Dunham@arm.com 13412477SCurtis.Dunham@arm.com /** Executes a load instruction. */ 13512478SCurtis.Dunham@arm.com Fault executeLoad(DynInstPtr &inst); 13612478SCurtis.Dunham@arm.com 13712478SCurtis.Dunham@arm.com Fault executeLoad(int lq_idx); 13812478SCurtis.Dunham@arm.com /** Executes a store instruction. */ 13912478SCurtis.Dunham@arm.com Fault executeStore(DynInstPtr &inst); 14012478SCurtis.Dunham@arm.com 14112478SCurtis.Dunham@arm.com /** Commits the head load. */ 14212478SCurtis.Dunham@arm.com void commitLoad(); 14312478SCurtis.Dunham@arm.com /** Commits a specific load, given by the sequence number. */ 14412478SCurtis.Dunham@arm.com void commitLoad(InstSeqNum &inst); 14512478SCurtis.Dunham@arm.com /** Commits loads older than a specific sequence number. */ 14612478SCurtis.Dunham@arm.com void commitLoads(InstSeqNum &youngest_inst); 14712478SCurtis.Dunham@arm.com 14812478SCurtis.Dunham@arm.com /** Commits stores older than a specific sequence number. */ 14912478SCurtis.Dunham@arm.com void commitStores(InstSeqNum &youngest_inst); 15012478SCurtis.Dunham@arm.com 15112479SCurtis.Dunham@arm.com /** Writes back stores. */ 15212479SCurtis.Dunham@arm.com void writebackStores(); 15312479SCurtis.Dunham@arm.com 15412479SCurtis.Dunham@arm.com // @todo: Include stats in the LSQ unit. 15512479SCurtis.Dunham@arm.com //void regStats(); 15612479SCurtis.Dunham@arm.com 15712479SCurtis.Dunham@arm.com /** Clears all the entries in the LQ. */ 15812479SCurtis.Dunham@arm.com void clearLQ(); 15912479SCurtis.Dunham@arm.com 16012479SCurtis.Dunham@arm.com /** Clears all the entries in the SQ. */ 16112479SCurtis.Dunham@arm.com void clearSQ(); 16212479SCurtis.Dunham@arm.com 16312479SCurtis.Dunham@arm.com /** Resizes the LQ to a given size. */ 16412479SCurtis.Dunham@arm.com void resizeLQ(unsigned size); 16512479SCurtis.Dunham@arm.com 16612479SCurtis.Dunham@arm.com /** Resizes the SQ to a given size. */ 16712479SCurtis.Dunham@arm.com void resizeSQ(unsigned size); 16812479SCurtis.Dunham@arm.com 16912479SCurtis.Dunham@arm.com /** Squashes all instructions younger than a specific sequence number. */ 17012479SCurtis.Dunham@arm.com void squash(const InstSeqNum &squashed_num); 17112479SCurtis.Dunham@arm.com 17212479SCurtis.Dunham@arm.com /** Returns if there is a memory ordering violation. Value is reset upon 17312479SCurtis.Dunham@arm.com * call to getMemDepViolator(). 17412479SCurtis.Dunham@arm.com */ 17512479SCurtis.Dunham@arm.com bool violation() { return memDepViolator; } 17612479SCurtis.Dunham@arm.com 17712479SCurtis.Dunham@arm.com /** Returns the memory ordering violator. */ 17812479SCurtis.Dunham@arm.com DynInstPtr getMemDepViolator(); 17912479SCurtis.Dunham@arm.com 18012479SCurtis.Dunham@arm.com /** Returns if a load became blocked due to the memory system. It clears 18112479SCurtis.Dunham@arm.com * the bool's value upon this being called. 18212479SCurtis.Dunham@arm.com */ 18312479SCurtis.Dunham@arm.com bool loadBlocked() 18412479SCurtis.Dunham@arm.com { return isLoadBlocked; } 18512479SCurtis.Dunham@arm.com 18612479SCurtis.Dunham@arm.com void clearLoadBlocked() 18712479SCurtis.Dunham@arm.com { isLoadBlocked = false; } 18812479SCurtis.Dunham@arm.com 18912479SCurtis.Dunham@arm.com bool isLoadBlockedHandled() 19012479SCurtis.Dunham@arm.com { return loadBlockedHandled; } 19112479SCurtis.Dunham@arm.com 19212479SCurtis.Dunham@arm.com void setLoadBlockedHandled() 19312479SCurtis.Dunham@arm.com { loadBlockedHandled = true; } 19412479SCurtis.Dunham@arm.com 19512479SCurtis.Dunham@arm.com /** Returns the number of free entries (min of free LQ and SQ entries). */ 19612479SCurtis.Dunham@arm.com unsigned numFreeEntries(); 19712479SCurtis.Dunham@arm.com 19812479SCurtis.Dunham@arm.com /** Returns the number of loads ready to execute. */ 19912479SCurtis.Dunham@arm.com int numLoadsReady(); 20012479SCurtis.Dunham@arm.com 20112479SCurtis.Dunham@arm.com /** Returns the number of loads in the LQ. */ 20212479SCurtis.Dunham@arm.com int numLoads() { return loads; } 20312479SCurtis.Dunham@arm.com 20412479SCurtis.Dunham@arm.com /** Returns the number of stores in the SQ. */ 20512479SCurtis.Dunham@arm.com int numStores() { return stores; } 20612479SCurtis.Dunham@arm.com 20712479SCurtis.Dunham@arm.com /** Returns if either the LQ or SQ is full. */ 20812479SCurtis.Dunham@arm.com bool isFull() { return lqFull() || sqFull(); } 20912668Sgiacomo.travaglini@arm.com 21012668Sgiacomo.travaglini@arm.com /** Returns if the LQ is full. */ 21112668Sgiacomo.travaglini@arm.com bool lqFull() { return loads >= (LQEntries - 1); } 21212668Sgiacomo.travaglini@arm.com 21312668Sgiacomo.travaglini@arm.com /** Returns if the SQ is full. */ 21412479SCurtis.Dunham@arm.com bool sqFull() { return stores >= (SQEntries - 1); } 21512479SCurtis.Dunham@arm.com 21612479SCurtis.Dunham@arm.com /** Debugging function to dump instructions in the LSQ. */ 21712479SCurtis.Dunham@arm.com void dumpInsts(); 21812479SCurtis.Dunham@arm.com 21912479SCurtis.Dunham@arm.com /** Returns the number of instructions in the LSQ. */ 22012479SCurtis.Dunham@arm.com unsigned getCount() { return loads + stores; } 22112479SCurtis.Dunham@arm.com 22212479SCurtis.Dunham@arm.com /** Returns if there are any stores to writeback. */ 22312479SCurtis.Dunham@arm.com bool hasStoresToWB() { return storesToWB; } 22412479SCurtis.Dunham@arm.com 22512479SCurtis.Dunham@arm.com /** Returns the number of stores to writeback. */ 22612479SCurtis.Dunham@arm.com int numStoresToWB() { return storesToWB; } 22712668Sgiacomo.travaglini@arm.com 22812668Sgiacomo.travaglini@arm.com /** Returns if the LSQ unit will writeback on this cycle. */ 22912668Sgiacomo.travaglini@arm.com bool willWB() { return storeQueue[storeWBIdx].canWB && 23012668Sgiacomo.travaglini@arm.com !storeQueue[storeWBIdx].completed && 23112668Sgiacomo.travaglini@arm.com !dcacheInterface->isBlocked(); } 23213395Sgiacomo.travaglini@arm.com 23313395Sgiacomo.travaglini@arm.com private: 23413395Sgiacomo.travaglini@arm.com /** Completes the store at the specified index. */ 23513395Sgiacomo.travaglini@arm.com void completeStore(int store_idx); 23613395Sgiacomo.travaglini@arm.com 23712479SCurtis.Dunham@arm.com /** Increments the given store index (circular queue). */ 23812479SCurtis.Dunham@arm.com inline void incrStIdx(int &store_idx); 23912479SCurtis.Dunham@arm.com /** Decrements the given store index (circular queue). */ 24012479SCurtis.Dunham@arm.com inline void decrStIdx(int &store_idx); 24112479SCurtis.Dunham@arm.com /** Increments the given load index (circular queue). */ 24212479SCurtis.Dunham@arm.com inline void incrLdIdx(int &load_idx); 24312479SCurtis.Dunham@arm.com /** Decrements the given load index (circular queue). */ 24412479SCurtis.Dunham@arm.com inline void decrLdIdx(int &load_idx); 24512479SCurtis.Dunham@arm.com 24612479SCurtis.Dunham@arm.com private: 24712479SCurtis.Dunham@arm.com /** Pointer to the CPU. */ 24812479SCurtis.Dunham@arm.com FullCPU *cpu; 24912479SCurtis.Dunham@arm.com 25012479SCurtis.Dunham@arm.com /** Pointer to the IEW stage. */ 25112479SCurtis.Dunham@arm.com IEW *iewStage; 25212479SCurtis.Dunham@arm.com 25312479SCurtis.Dunham@arm.com /** Pointer to the D-cache. */ 25412479SCurtis.Dunham@arm.com MemInterface *dcacheInterface; 25512479SCurtis.Dunham@arm.com 25612479SCurtis.Dunham@arm.com /** Pointer to the page table. */ 25712479SCurtis.Dunham@arm.com// PageTable *pTable; 25812479SCurtis.Dunham@arm.com 25912479SCurtis.Dunham@arm.com public: 26012479SCurtis.Dunham@arm.com struct SQEntry { 26112479SCurtis.Dunham@arm.com /** Constructs an empty store queue entry. */ 26212479SCurtis.Dunham@arm.com SQEntry() 26312479SCurtis.Dunham@arm.com : inst(NULL), req(NULL), size(0), data(0), 26412479SCurtis.Dunham@arm.com canWB(0), committed(0), completed(0) 26512479SCurtis.Dunham@arm.com { } 26612479SCurtis.Dunham@arm.com 26712479SCurtis.Dunham@arm.com /** Constructs a store queue entry for a given instruction. */ 26812479SCurtis.Dunham@arm.com SQEntry(DynInstPtr &_inst) 26912479SCurtis.Dunham@arm.com : inst(_inst), req(NULL), size(0), data(0), 27012479SCurtis.Dunham@arm.com canWB(0), committed(0), completed(0) 27112479SCurtis.Dunham@arm.com { } 27212479SCurtis.Dunham@arm.com 27312479SCurtis.Dunham@arm.com /** The store instruction. */ 27412479SCurtis.Dunham@arm.com DynInstPtr inst; 27512479SCurtis.Dunham@arm.com /** The memory request for the store. */ 27612479SCurtis.Dunham@arm.com MemReqPtr req; 27712479SCurtis.Dunham@arm.com /** The size of the store. */ 27812479SCurtis.Dunham@arm.com int size; 27912479SCurtis.Dunham@arm.com /** The store data. */ 28012479SCurtis.Dunham@arm.com IntReg data; 28112479SCurtis.Dunham@arm.com /** Whether or not the store can writeback. */ 28212479SCurtis.Dunham@arm.com bool canWB; 28312479SCurtis.Dunham@arm.com /** Whether or not the store is committed. */ 28412479SCurtis.Dunham@arm.com bool committed; 28512479SCurtis.Dunham@arm.com /** Whether or not the store is completed. */ 28612479SCurtis.Dunham@arm.com bool completed; 28712479SCurtis.Dunham@arm.com }; 28812479SCurtis.Dunham@arm.com/* 28912479SCurtis.Dunham@arm.com enum Status { 29012479SCurtis.Dunham@arm.com Running, 29112479SCurtis.Dunham@arm.com Idle, 29212479SCurtis.Dunham@arm.com DcacheMissStall, 29312479SCurtis.Dunham@arm.com DcacheMissSwitch 29412479SCurtis.Dunham@arm.com }; 29512479SCurtis.Dunham@arm.com*/ 29612479SCurtis.Dunham@arm.com private: 29712479SCurtis.Dunham@arm.com /** The LSQUnit thread id. */ 29812479SCurtis.Dunham@arm.com unsigned lsqID; 29912479SCurtis.Dunham@arm.com 30012479SCurtis.Dunham@arm.com /** The status of the LSQ unit. */ 30112479SCurtis.Dunham@arm.com// Status _status; 30212479SCurtis.Dunham@arm.com 30312479SCurtis.Dunham@arm.com /** The store queue. */ 30412479SCurtis.Dunham@arm.com std::vector<SQEntry> storeQueue; 30512479SCurtis.Dunham@arm.com 30612479SCurtis.Dunham@arm.com /** The load queue. */ 30712479SCurtis.Dunham@arm.com std::vector<DynInstPtr> loadQueue; 30812479SCurtis.Dunham@arm.com 30912479SCurtis.Dunham@arm.com // Consider making these 16 bits 31012479SCurtis.Dunham@arm.com /** The number of LQ entries. */ 31112479SCurtis.Dunham@arm.com unsigned LQEntries; 31212479SCurtis.Dunham@arm.com /** The number of SQ entries. */ 31312479SCurtis.Dunham@arm.com unsigned SQEntries; 31412479SCurtis.Dunham@arm.com 31512479SCurtis.Dunham@arm.com /** The number of load instructions in the LQ. */ 31612479SCurtis.Dunham@arm.com int loads; 31712479SCurtis.Dunham@arm.com /** The number of store instructions in the SQ (excludes those waiting to 31812479SCurtis.Dunham@arm.com * writeback). 31912479SCurtis.Dunham@arm.com */ 32012479SCurtis.Dunham@arm.com int stores; 32112479SCurtis.Dunham@arm.com /** The number of store instructions in the SQ waiting to writeback. */ 32212479SCurtis.Dunham@arm.com int storesToWB; 32312479SCurtis.Dunham@arm.com 32412479SCurtis.Dunham@arm.com /** The index of the head instruction in the LQ. */ 32512479SCurtis.Dunham@arm.com int loadHead; 32612479SCurtis.Dunham@arm.com /** The index of the tail instruction in the LQ. */ 32712479SCurtis.Dunham@arm.com int loadTail; 32812479SCurtis.Dunham@arm.com 32912479SCurtis.Dunham@arm.com /** The index of the head instruction in the SQ. */ 33012479SCurtis.Dunham@arm.com int storeHead; 33112479SCurtis.Dunham@arm.com /** The index of the first instruction that is ready to be written back, 33212479SCurtis.Dunham@arm.com * and has not yet been written back. 33312479SCurtis.Dunham@arm.com */ 33412479SCurtis.Dunham@arm.com int storeWBIdx; 33512479SCurtis.Dunham@arm.com /** The index of the tail instruction in the SQ. */ 33612479SCurtis.Dunham@arm.com int storeTail; 33712479SCurtis.Dunham@arm.com 33812479SCurtis.Dunham@arm.com /// @todo Consider moving to a more advanced model with write vs read ports 33912479SCurtis.Dunham@arm.com /** The number of cache ports available each cycle. */ 34012479SCurtis.Dunham@arm.com int cachePorts; 34112479SCurtis.Dunham@arm.com 34212479SCurtis.Dunham@arm.com /** The number of used cache ports in this cycle. */ 34312479SCurtis.Dunham@arm.com int usedPorts; 34412479SCurtis.Dunham@arm.com 34512479SCurtis.Dunham@arm.com bool switchedOut; 34612479SCurtis.Dunham@arm.com 34712479SCurtis.Dunham@arm.com //list<InstSeqNum> mshrSeqNums; 34812479SCurtis.Dunham@arm.com 34912479SCurtis.Dunham@arm.com //Stats::Scalar<> dcacheStallCycles; 35012479SCurtis.Dunham@arm.com Counter lastDcacheStall; 35112479SCurtis.Dunham@arm.com 35210037SARM gem5 Developers /** Wire to read information from the issue stage time queue. */ 35310037SARM gem5 Developers typename TimeBuffer<IssueStruct>::wire fromIssue; 35412477SCurtis.Dunham@arm.com 35512479SCurtis.Dunham@arm.com // Make these per thread? 35612479SCurtis.Dunham@arm.com /** Whether or not the LSQ is stalled. */ 35712477SCurtis.Dunham@arm.com bool stalled; 35810037SARM gem5 Developers /** The store that causes the stall due to partial store to load 35912477SCurtis.Dunham@arm.com * forwarding. 36010037SARM gem5 Developers */ 3616333Sgblack@eecs.umich.edu InstSeqNum stallingStoreIsn; 3626718Sgblack@eecs.umich.edu /** The index of the above store. */ 3636718Sgblack@eecs.umich.edu int stallingLoadIdx; 3646718Sgblack@eecs.umich.edu 3656718Sgblack@eecs.umich.edu /** Whether or not a load is blocked due to the memory system. It is 3666718Sgblack@eecs.umich.edu * cleared when this value is checked via loadBlocked(). 36710037SARM gem5 Developers */ 36810037SARM gem5 Developers bool isLoadBlocked; 36910037SARM gem5 Developers 37010037SARM gem5 Developers bool loadBlockedHandled; 37110037SARM gem5 Developers 37210037SARM gem5 Developers InstSeqNum blockedLoadSeqNum; 37310037SARM gem5 Developers 37410037SARM gem5 Developers /** The oldest faulting load instruction. */ 37510037SARM gem5 Developers DynInstPtr loadFaultInst; 37610037SARM gem5 Developers /** The oldest faulting store instruction. */ 37710037SARM gem5 Developers DynInstPtr storeFaultInst; 37810037SARM gem5 Developers 37910037SARM gem5 Developers /** The oldest load that caused a memory ordering violation. */ 38010037SARM gem5 Developers DynInstPtr memDepViolator; 38110037SARM gem5 Developers 38210037SARM gem5 Developers // Will also need how many read/write ports the Dcache has. Or keep track 38310037SARM gem5 Developers // of that in stage that is one level up, and only call executeLoad/Store 38410037SARM gem5 Developers // the appropriate number of times. 38510037SARM gem5 Developers/* 38610037SARM gem5 Developers // total number of loads forwaded from LSQ stores 38710037SARM gem5 Developers Stats::Vector<> lsq_forw_loads; 38810037SARM gem5 Developers 38910037SARM gem5 Developers // total number of loads ignored due to invalid addresses 39010037SARM gem5 Developers Stats::Vector<> inv_addr_loads; 39110037SARM gem5 Developers 39210037SARM gem5 Developers // total number of software prefetches ignored due to invalid addresses 39310037SARM gem5 Developers Stats::Vector<> inv_addr_swpfs; 39410037SARM gem5 Developers 39510037SARM gem5 Developers // total non-speculative bogus addresses seen (debug var) 39610037SARM gem5 Developers Counter sim_invalid_addrs; 39710037SARM gem5 Developers Stats::Vector<> fu_busy; //cumulative fu busy 39810037SARM gem5 Developers 3996718Sgblack@eecs.umich.edu // ready loads blocked due to memory disambiguation 4006718Sgblack@eecs.umich.edu Stats::Vector<> lsq_blocked_loads; 4016313Sgblack@eecs.umich.edu 40210844Sandreas.sandberg@arm.com Stats::Scalar<> lsqInversion; 40310037SARM gem5 Developers*/ 40410037SARM gem5 Developers public: 40510037SARM gem5 Developers /** Executes the load at the given index. */ 40610037SARM gem5 Developers template <class T> 40710037SARM gem5 Developers Fault read(MemReqPtr &req, T &data, int load_idx); 40810037SARM gem5 Developers 40910037SARM gem5 Developers /** Executes the store at the given index. */ 41010037SARM gem5 Developers template <class T> 41110037SARM gem5 Developers Fault write(MemReqPtr &req, T &data, int store_idx); 41210037SARM gem5 Developers 41310037SARM gem5 Developers /** Returns the index of the head load instruction. */ 41410037SARM gem5 Developers int getLoadHead() { return loadHead; } 41510037SARM gem5 Developers /** Returns the sequence number of the head load instruction. */ 4166313Sgblack@eecs.umich.edu InstSeqNum getLoadHeadSeqNum() 4177427Sgblack@eecs.umich.edu { 41813114Sgiacomo.travaglini@arm.com if (loadQueue[loadHead]) { 41913114Sgiacomo.travaglini@arm.com return loadQueue[loadHead]->seqNum; 42013393Sgiacomo.travaglini@arm.com } else { 42110037SARM gem5 Developers return 0; 42213114Sgiacomo.travaglini@arm.com } 42313114Sgiacomo.travaglini@arm.com 4246313Sgblack@eecs.umich.edu } 42513114Sgiacomo.travaglini@arm.com 42610035Sandreas.hansson@arm.com /** Returns the index of the head store instruction. */ 4277405SAli.Saidi@ARM.com int getStoreHead() { return storeHead; } 4287405SAli.Saidi@ARM.com /** Returns the sequence number of the head store instruction. */ 4297405SAli.Saidi@ARM.com InstSeqNum getStoreHeadSeqNum() 4306313Sgblack@eecs.umich.edu { 43112106SRekai.GonzalezAlberquilla@arm.com if (storeQueue[storeHead].inst) { 43212106SRekai.GonzalezAlberquilla@arm.com return storeQueue[storeHead].inst->seqNum; 43312106SRekai.GonzalezAlberquilla@arm.com } else { 43412106SRekai.GonzalezAlberquilla@arm.com return 0; 43512106SRekai.GonzalezAlberquilla@arm.com } 43612106SRekai.GonzalezAlberquilla@arm.com 43712106SRekai.GonzalezAlberquilla@arm.com } 43812106SRekai.GonzalezAlberquilla@arm.com 43912109SRekai.GonzalezAlberquilla@arm.com /** Returns whether or not the LSQ unit is stalled. */ 44012109SRekai.GonzalezAlberquilla@arm.com bool isStalled() { return stalled; } 44112109SRekai.GonzalezAlberquilla@arm.com}; 44212109SRekai.GonzalezAlberquilla@arm.com 44312106SRekai.GonzalezAlberquilla@arm.comtemplate <class Impl> 44412106SRekai.GonzalezAlberquilla@arm.comtemplate <class T> 44512106SRekai.GonzalezAlberquilla@arm.comFault 44612106SRekai.GonzalezAlberquilla@arm.comLSQUnit<Impl>::read(MemReqPtr &req, T &data, int load_idx) 44712106SRekai.GonzalezAlberquilla@arm.com{ 44812106SRekai.GonzalezAlberquilla@arm.com //Depending on issue2execute delay a squashed load could 44912106SRekai.GonzalezAlberquilla@arm.com //execute if it is found to be squashed in the same 45012106SRekai.GonzalezAlberquilla@arm.com //cycle it is scheduled to execute 4516313Sgblack@eecs.umich.edu assert(loadQueue[load_idx]); 45210035Sandreas.hansson@arm.com 4536313Sgblack@eecs.umich.edu if (loadQueue[load_idx]->isExecuted()) { 4546718Sgblack@eecs.umich.edu panic("Should not reach this point with split ops!"); 4556718Sgblack@eecs.umich.edu memcpy(&data,req->data,req->size); 4566718Sgblack@eecs.umich.edu 4576726Sgblack@eecs.umich.edu return NoFault; 4586726Sgblack@eecs.umich.edu } 45910037SARM gem5 Developers 46010037SARM gem5 Developers // Make sure this isn't an uncacheable access 46110037SARM gem5 Developers // A bit of a hackish way to get uncached accesses to work only if they're 46210037SARM gem5 Developers // at the head of the LSQ and are ready to commit (at the head of the ROB 46310037SARM gem5 Developers // too). 46410037SARM gem5 Developers // @todo: Fix uncached accesses. 46510037SARM gem5 Developers if (req->flags & UNCACHEABLE && 46610037SARM gem5 Developers (load_idx != loadHead || !loadQueue[load_idx]->reachedCommit)) { 46710037SARM gem5 Developers iewStage->rescheduleMemInst(loadQueue[load_idx]); 46811574SCurtis.Dunham@arm.com return TheISA::genMachineCheckFault(); 46911574SCurtis.Dunham@arm.com } 47010037SARM gem5 Developers 47110037SARM gem5 Developers // Check the SQ for any previous stores that might lead to forwarding 47210037SARM gem5 Developers int store_idx = loadQueue[load_idx]->sqIdx; 47310037SARM gem5 Developers 47410037SARM gem5 Developers int store_size = 0; 47510037SARM gem5 Developers 47613020Sshunhsingou@google.com DPRINTF(LSQUnit, "Read called, load idx: %i, store idx: %i, " 47710037SARM gem5 Developers "storeHead: %i addr: %#x\n", 4786718Sgblack@eecs.umich.edu load_idx, store_idx, storeHead, req->paddr); 47910037SARM gem5 Developers 4806718Sgblack@eecs.umich.edu#ifdef FULL_SYSTEM 4816313Sgblack@eecs.umich.edu if (req->flags & LOCKED) { 4826313Sgblack@eecs.umich.edu cpu->lockAddr = req->paddr; 4836313Sgblack@eecs.umich.edu cpu->lockFlag = true; 48410035Sandreas.hansson@arm.com } 4856313Sgblack@eecs.umich.edu#endif 48610338SCurtis.Dunham@arm.com 4876313Sgblack@eecs.umich.edu while (store_idx != -1) { 4886313Sgblack@eecs.umich.edu // End once we've reached the top of the LSQ 4896313Sgblack@eecs.umich.edu if (store_idx == storeWBIdx) { 4909920Syasuko.eckert@amd.com break; 49112109SRekai.GonzalezAlberquilla@arm.com } 49212109SRekai.GonzalezAlberquilla@arm.com 49312109SRekai.GonzalezAlberquilla@arm.com // Move the index to one younger 49412109SRekai.GonzalezAlberquilla@arm.com if (--store_idx < 0) 49512109SRekai.GonzalezAlberquilla@arm.com store_idx += SQEntries; 49612109SRekai.GonzalezAlberquilla@arm.com 49712109SRekai.GonzalezAlberquilla@arm.com assert(storeQueue[store_idx].inst); 49812109SRekai.GonzalezAlberquilla@arm.com 49912109SRekai.GonzalezAlberquilla@arm.com store_size = storeQueue[store_idx].size; 50012109SRekai.GonzalezAlberquilla@arm.com 50112109SRekai.GonzalezAlberquilla@arm.com if (store_size == 0) 50212109SRekai.GonzalezAlberquilla@arm.com continue; 50312109SRekai.GonzalezAlberquilla@arm.com 50412109SRekai.GonzalezAlberquilla@arm.com // Check if the store data is within the lower and upper bounds of 50510035Sandreas.hansson@arm.com // addresses that the request needs. 5069920Syasuko.eckert@amd.com bool store_has_lower_limit = 50710338SCurtis.Dunham@arm.com req->vaddr >= storeQueue[store_idx].inst->effAddr; 5089920Syasuko.eckert@amd.com bool store_has_upper_limit = 5099920Syasuko.eckert@amd.com (req->vaddr + req->size) <= (storeQueue[store_idx].inst->effAddr + 5109920Syasuko.eckert@amd.com store_size); 5117614Sminkyu.jeong@arm.com bool lower_load_has_store_part = 51210035Sandreas.hansson@arm.com req->vaddr < (storeQueue[store_idx].inst->effAddr + 5137614Sminkyu.jeong@arm.com store_size); 51410338SCurtis.Dunham@arm.com bool upper_load_has_store_part = 51510037SARM gem5 Developers (req->vaddr + req->size) > storeQueue[store_idx].inst->effAddr; 51610037SARM gem5 Developers 5177614Sminkyu.jeong@arm.com // If the store's data has all of the data needed, we can forward. 5187614Sminkyu.jeong@arm.com if (store_has_lower_limit && store_has_upper_limit) { 5197614Sminkyu.jeong@arm.com 52010037SARM gem5 Developers int shift_amt = req->vaddr & (store_size - 1); 52110037SARM gem5 Developers // Assumes byte addressing 52210037SARM gem5 Developers shift_amt = shift_amt << 3; 52310037SARM gem5 Developers 52410037SARM gem5 Developers // Cast this to type T? 52510037SARM gem5 Developers data = storeQueue[store_idx].data >> shift_amt; 52610037SARM gem5 Developers 52710037SARM gem5 Developers req->cmd = Read; 52810037SARM gem5 Developers assert(!req->completionEvent); 52910037SARM gem5 Developers req->completionEvent = NULL; 53010037SARM gem5 Developers req->time = curTick; 53110037SARM gem5 Developers assert(!req->data); 53210037SARM gem5 Developers req->data = new uint8_t[64]; 53310037SARM gem5 Developers 53410037SARM gem5 Developers memcpy(req->data, &data, req->size); 53510037SARM gem5 Developers 5367614Sminkyu.jeong@arm.com DPRINTF(LSQUnit, "Forwarding from store idx %i to load to " 5377614Sminkyu.jeong@arm.com "addr %#x, data %#x\n", 53810037SARM gem5 Developers store_idx, req->vaddr, *(req->data)); 5397614Sminkyu.jeong@arm.com 5407614Sminkyu.jeong@arm.com typename IEW::LdWritebackEvent *wb = 54110037SARM gem5 Developers new typename IEW::LdWritebackEvent(loadQueue[load_idx], 5427614Sminkyu.jeong@arm.com iewStage); 5437614Sminkyu.jeong@arm.com 54410037SARM gem5 Developers // We'll say this has a 1 cycle load-store forwarding latency 5457614Sminkyu.jeong@arm.com // for now. 5467614Sminkyu.jeong@arm.com // @todo: Need to make this a parameter. 54710037SARM gem5 Developers wb->schedule(curTick); 5487614Sminkyu.jeong@arm.com 5497614Sminkyu.jeong@arm.com // Should keep track of stat for forwarded data 55010037SARM gem5 Developers return NoFault; 5517614Sminkyu.jeong@arm.com } else if ((store_has_lower_limit && lower_load_has_store_part) || 5527614Sminkyu.jeong@arm.com (store_has_upper_limit && upper_load_has_store_part) || 55310037SARM gem5 Developers (lower_load_has_store_part && upper_load_has_store_part)) { 55410037SARM gem5 Developers // This is the partial store-load forwarding case where a store 55510037SARM gem5 Developers // has only part of the load's data. 55610037SARM gem5 Developers 5577614Sminkyu.jeong@arm.com // If it's already been written back, then don't worry about 5587614Sminkyu.jeong@arm.com // stalling on it. 55910037SARM gem5 Developers if (storeQueue[store_idx].completed) { 5607614Sminkyu.jeong@arm.com continue; 5617614Sminkyu.jeong@arm.com } 5627614Sminkyu.jeong@arm.com 5637614Sminkyu.jeong@arm.com // Must stall load and force it to retry, so long as it's the oldest 56410037SARM gem5 Developers // load that needs to do so. 5657614Sminkyu.jeong@arm.com if (!stalled || 5667614Sminkyu.jeong@arm.com (stalled && 56710037SARM gem5 Developers loadQueue[load_idx]->seqNum < 56810037SARM gem5 Developers loadQueue[stallingLoadIdx]->seqNum)) { 56910037SARM gem5 Developers stalled = true; 57010037SARM gem5 Developers stallingStoreIsn = storeQueue[store_idx].inst->seqNum; 57110037SARM gem5 Developers stallingLoadIdx = load_idx; 57210037SARM gem5 Developers } 57310037SARM gem5 Developers 57410037SARM gem5 Developers // Tell IQ/mem dep unit that this instruction will need to be 57510037SARM gem5 Developers // rescheduled eventually 57610037SARM gem5 Developers iewStage->rescheduleMemInst(loadQueue[load_idx]); 57710037SARM gem5 Developers 57810037SARM gem5 Developers // Do not generate a writeback event as this instruction is not 57910037SARM gem5 Developers // complete. 58010037SARM gem5 Developers 58110037SARM gem5 Developers DPRINTF(LSQUnit, "Load-store forwarding mis-match. " 58210037SARM gem5 Developers "Store idx %i to load addr %#x\n", 58310037SARM gem5 Developers store_idx, req->vaddr); 58410037SARM gem5 Developers 58510037SARM gem5 Developers return NoFault; 58610037SARM gem5 Developers } 58710037SARM gem5 Developers } 58810037SARM gem5 Developers 58910037SARM gem5 Developers 59010037SARM gem5 Developers // If there's no forwarding case, then go access memory 59110037SARM gem5 Developers DynInstPtr inst = loadQueue[load_idx]; 59210037SARM gem5 Developers 59310037SARM gem5 Developers DPRINTF(LSQUnit, "Doing functional access for inst PC %#x\n", 59410037SARM gem5 Developers loadQueue[load_idx]->readPC()); 59510037SARM gem5 Developers assert(!req->data); 59610037SARM gem5 Developers req->cmd = Read; 59710037SARM gem5 Developers req->completionEvent = NULL; 59810037SARM gem5 Developers req->time = curTick; 59910037SARM gem5 Developers req->data = new uint8_t[64]; 60010037SARM gem5 Developers Fault fault = cpu->read(req, data); 60110037SARM gem5 Developers memcpy(req->data, &data, sizeof(T)); 60210037SARM gem5 Developers 60310037SARM gem5 Developers ++usedPorts; 60410037SARM gem5 Developers 60510037SARM gem5 Developers // if we have a cache, do cache access too 60610037SARM gem5 Developers if (fault == NoFault && dcacheInterface) { 60710037SARM gem5 Developers if (dcacheInterface->isBlocked()) { 60810037SARM gem5 Developers // There's an older load that's already going to squash. 60910037SARM gem5 Developers if (isLoadBlocked && blockedLoadSeqNum < inst->seqNum) 61010037SARM gem5 Developers return NoFault; 61110037SARM gem5 Developers 61210037SARM gem5 Developers isLoadBlocked = true; 61310037SARM gem5 Developers loadBlockedHandled = false; 61410037SARM gem5 Developers blockedLoadSeqNum = inst->seqNum; 61510037SARM gem5 Developers // No fault occurred, even though the interface is blocked. 61610037SARM gem5 Developers return NoFault; 61711771SCurtis.Dunham@arm.com } 61810037SARM gem5 Developers DPRINTF(LSQUnit, "Doing timing access for inst PC %#x\n", 61910037SARM gem5 Developers loadQueue[load_idx]->readPC()); 62010037SARM gem5 Developers/* 62110037SARM gem5 Developers Addr debug_addr = ULL(0xfffffc0000be81a8); 6227614Sminkyu.jeong@arm.com if (req->vaddr == debug_addr) { 62310037SARM gem5 Developers debug_break(); 6247614Sminkyu.jeong@arm.com } 6257614Sminkyu.jeong@arm.com*/ 62611771SCurtis.Dunham@arm.com assert(!req->completionEvent); 62711771SCurtis.Dunham@arm.com req->completionEvent = 62811771SCurtis.Dunham@arm.com new typename IEW::LdWritebackEvent(loadQueue[load_idx], iewStage); 62911771SCurtis.Dunham@arm.com MemAccessResult result = dcacheInterface->access(req); 63011771SCurtis.Dunham@arm.com 63111771SCurtis.Dunham@arm.com assert(dcacheInterface->doEvents()); 63211771SCurtis.Dunham@arm.com 63311771SCurtis.Dunham@arm.com // Ugly hack to get an event scheduled *only* if the access is 63411771SCurtis.Dunham@arm.com // a miss. We really should add first-class support for this 63511771SCurtis.Dunham@arm.com // at some point. 63611771SCurtis.Dunham@arm.com if (result != MA_HIT) { 63711771SCurtis.Dunham@arm.com DPRINTF(LSQUnit, "LSQUnit: D-cache miss!\n"); 63811771SCurtis.Dunham@arm.com DPRINTF(Activity, "Activity: ld accessing mem miss [sn:%lli]\n", 63911771SCurtis.Dunham@arm.com inst->seqNum); 64011771SCurtis.Dunham@arm.com 64111771SCurtis.Dunham@arm.com lastDcacheStall = curTick; 64211771SCurtis.Dunham@arm.com 64311771SCurtis.Dunham@arm.com// _status = DcacheMissStall; 64411771SCurtis.Dunham@arm.com 64511771SCurtis.Dunham@arm.com } else { 64611771SCurtis.Dunham@arm.com DPRINTF(Activity, "Activity: ld accessing mem hit [sn:%lli]\n", 64710905Sandreas.sandberg@arm.com inst->seqNum); 6487733SAli.Saidi@ARM.com 6497733SAli.Saidi@ARM.com DPRINTF(LSQUnit, "LSQUnit: D-cache hit!\n"); 65012529Sgiacomo.travaglini@arm.com } 65110037SARM gem5 Developers } 65211771SCurtis.Dunham@arm.com#if 0 65310037SARM gem5 Developers // if we have a cache, do cache access too 65410037SARM gem5 Developers if (dcacheInterface) { 65510037SARM gem5 Developers if (dcacheInterface->isBlocked()) { 65610037SARM gem5 Developers isLoadBlocked = true; 65713114Sgiacomo.travaglini@arm.com // No fault occurred, even though the interface is blocked. 6587733SAli.Saidi@ARM.com return NoFault; 65910905Sandreas.sandberg@arm.com } 6607733SAli.Saidi@ARM.com 6617733SAli.Saidi@ARM.com DPRINTF(LSQUnit, "LSQUnit: D-cache: PC:%#x reading from paddr:%#x " 66212529Sgiacomo.travaglini@arm.com "vaddr:%#x flags:%i\n", 6637733SAli.Saidi@ARM.com inst->readPC(), req->paddr, req->vaddr, req->flags); 6647733SAli.Saidi@ARM.com 66510037SARM gem5 Developers // Setup MemReq pointer 66611771SCurtis.Dunham@arm.com req->cmd = Read; 66710037SARM gem5 Developers req->completionEvent = NULL; 66810037SARM gem5 Developers req->time = curTick; 66910037SARM gem5 Developers assert(!req->data); 67010037SARM gem5 Developers req->data = new uint8_t[64]; 67113114Sgiacomo.travaglini@arm.com 6727733SAli.Saidi@ARM.com assert(!req->completionEvent); 6736313Sgblack@eecs.umich.edu req->completionEvent = 67412972Sandreas.sandberg@arm.com new typename IEW::LdWritebackEvent(loadQueue[load_idx], iewStage); 6759461Snilay@cs.wisc.edu 67611165SRekai.GonzalezAlberquilla@arm.com // Do Cache Access 67711165SRekai.GonzalezAlberquilla@arm.com MemAccessResult result = dcacheInterface->access(req); 67812109SRekai.GonzalezAlberquilla@arm.com 67912109SRekai.GonzalezAlberquilla@arm.com // Ugly hack to get an event scheduled *only* if the access is 68012109SRekai.GonzalezAlberquilla@arm.com // a miss. We really should add first-class support for this 68112109SRekai.GonzalezAlberquilla@arm.com // at some point. 68212109SRekai.GonzalezAlberquilla@arm.com // @todo: Probably should support having no events 68312109SRekai.GonzalezAlberquilla@arm.com if (result != MA_HIT) { 6849553Sandreas.hansson@arm.com DPRINTF(LSQUnit, "LSQUnit: D-cache miss!\n"); 6859553Sandreas.hansson@arm.com DPRINTF(Activity, "Activity: ld accessing mem miss [sn:%lli]\n", 6869553Sandreas.hansson@arm.com inst->seqNum); 6879384SAndreas.Sandberg@arm.com 6887400SAli.Saidi@ARM.com lastDcacheStall = curTick; 6899384SAndreas.Sandberg@arm.com 6909384SAndreas.Sandberg@arm.com _status = DcacheMissStall; 6919384SAndreas.Sandberg@arm.com 6926313Sgblack@eecs.umich.edu } else { 6936313Sgblack@eecs.umich.edu DPRINTF(Activity, "Activity: ld accessing mem hit [sn:%lli]\n", 6946313Sgblack@eecs.umich.edu inst->seqNum); 69512109SRekai.GonzalezAlberquilla@arm.com 69612109SRekai.GonzalezAlberquilla@arm.com DPRINTF(LSQUnit, "LSQUnit: D-cache hit!\n"); 69712109SRekai.GonzalezAlberquilla@arm.com } 69812109SRekai.GonzalezAlberquilla@arm.com } else { 69912109SRekai.GonzalezAlberquilla@arm.com fatal("Must use D-cache with new memory system"); 70012109SRekai.GonzalezAlberquilla@arm.com } 70112109SRekai.GonzalezAlberquilla@arm.com#endif 70212109SRekai.GonzalezAlberquilla@arm.com 70312109SRekai.GonzalezAlberquilla@arm.com return fault; 70412109SRekai.GonzalezAlberquilla@arm.com} 70512109SRekai.GonzalezAlberquilla@arm.com 70612109SRekai.GonzalezAlberquilla@arm.comtemplate <class Impl> 70712109SRekai.GonzalezAlberquilla@arm.comtemplate <class T> 7086313Sgblack@eecs.umich.eduFault 709LSQUnit<Impl>::write(MemReqPtr &req, T &data, int store_idx) 710{ 711 assert(storeQueue[store_idx].inst); 712 713 DPRINTF(LSQUnit, "Doing write to store idx %i, addr %#x data %#x" 714 " | storeHead:%i [sn:%i]\n", 715 store_idx, req->paddr, data, storeHead, 716 storeQueue[store_idx].inst->seqNum); 717/* 718 if (req->flags & LOCKED) { 719 if (req->flags & UNCACHEABLE) { 720 req->result = 2; 721 } else { 722 req->result = 1; 723 } 724 } 725*/ 726 storeQueue[store_idx].req = req; 727 storeQueue[store_idx].size = sizeof(T); 728 storeQueue[store_idx].data = data; 729/* 730 Addr debug_addr = ULL(0xfffffc0000be81a8); 731 if (req->vaddr == debug_addr) { 732 debug_break(); 733 } 734*/ 735 // This function only writes the data to the store queue, so no fault 736 // can happen here. 737 return NoFault; 738} 739 740#endif // __CPU_O3_LSQ_UNIT_HH__ 741