X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Fphysical.hh;h=97bea2ec43a9dfcbf9b87044c5ff4b041ec29445;hb=404b2a951d82bde00e607296c5e7de2997df8058;hp=b549c1f8bc48537db0db83b00c90b47fc7eb5bba;hpb=851f91f2457aabbce2527231b725abf306aa35ff;p=gem5.git diff --git a/src/mem/physical.hh b/src/mem/physical.hh index b549c1f8b..97bea2ec4 100644 --- a/src/mem/physical.hh +++ b/src/mem/physical.hh @@ -57,8 +57,6 @@ class PhysicalMemory : public MemObject protected: - virtual bool recvTiming(Packet *pkt); - virtual Tick recvAtomic(Packet *pkt); virtual void recvFunctional(Packet *pkt); @@ -80,19 +78,90 @@ class PhysicalMemory : public MemObject const PhysicalMemory &operator=(const PhysicalMemory &specmem); protected: - Addr base_addr; - Addr pmem_size; - uint8_t *pmem_addr; + + class LockedAddr { + public: + // on alpha, minimum LL/SC granularity is 16 bytes, so lower + // bits need to masked off. + static const Addr Addr_Mask = 0xf; + + static Addr mask(Addr paddr) { return (paddr & ~Addr_Mask); } + + Addr addr; // locked address + int cpuNum; // locking CPU + int threadNum; // locking thread ID within CPU + + // check for matching execution context + bool matchesContext(Request *req) + { + return (cpuNum == req->getCpuNum() && + threadNum == req->getThreadNum()); + } + + LockedAddr(Request *req) + : addr(mask(req->getPaddr())), + cpuNum(req->getCpuNum()), + threadNum(req->getThreadNum()) + { + } + }; + + std::list lockedAddrList; + + // helper function for checkLockedAddrs(): we really want to + // inline a quick check for an empty locked addr list (hopefully + // the common case), and do the full list search (if necessary) in + // this out-of-line function + bool checkLockedAddrList(Request *req); + + // Record the address of a load-locked operation so that we can + // clear the execution context's lock flag if a matching store is + // performed + void trackLoadLocked(Request *req); + + // Compare a store address with any locked addresses so we can + // clear the lock flag appropriately. Return value set to 'false' + // if store operation should be suppressed (because it was a + // conditional store and the address was no longer locked by the + // requesting execution context), 'true' otherwise. Note that + // this method must be called on *all* stores since even + // non-conditional stores must clear any matching lock addresses. + bool writeOK(Request *req) { + if (lockedAddrList.empty()) { + // no locked addrs: nothing to check, store_conditional fails + bool isLocked = req->isLocked(); + if (isLocked) { + req->setScResult(0); + } + return !isLocked; // only do write if not an sc + } else { + // iterate over list... + return checkLockedAddrList(req); + } + } + + uint8_t *pmemAddr; MemoryPort *port; - int page_ptr; + int pagePtr; Tick lat; public: Addr new_page(); - uint64_t size() { return pmem_size; } + uint64_t size() { return params()->addrRange.size(); } + + struct Params + { + std::string name; + Range addrRange; + Tick latency; + }; + + protected: + Params *_params; public: - PhysicalMemory(const std::string &n, Tick latency); + const Params *params() const { return _params; } + PhysicalMemory(Params *p); virtual ~PhysicalMemory(); public: @@ -102,9 +171,9 @@ class PhysicalMemory : public MemObject void virtual init(); unsigned int drain(Event *de); - private: - Tick doFunctionalAccess(Packet *pkt); - + protected: + void doFunctionalAccess(Packet *pkt); + virtual Tick calculateLatency(Packet *pkt); void recvStatusChange(Port::Status status); public: