X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Fphysical.hh;h=045e6161272013925d84ec780c702a5e4cb6f606;hb=f720029e97358b2f69ea0ecaace89d5c2ccc6bfe;hp=50fa75ed3e865ec9803faab421419ab6fc3ae21b;hpb=185ec39f792386d8b30f3288f2c2e4eaf0b43d02;p=gem5.git diff --git a/src/mem/physical.hh b/src/mem/physical.hh index 50fa75ed3..045e61612 100644 --- a/src/mem/physical.hh +++ b/src/mem/physical.hh @@ -37,7 +37,7 @@ #include "base/range.hh" #include "mem/mem_object.hh" #include "mem/packet.hh" -#include "mem/port.hh" +#include "mem/tport.hh" #include "sim/eventq.hh" #include #include @@ -47,7 +47,7 @@ // class PhysicalMemory : public MemObject { - class MemoryPort : public Port + class MemoryPort : public SimpleTimingPort { PhysicalMemory *memory; @@ -57,11 +57,9 @@ class PhysicalMemory : public MemObject protected: - virtual bool recvTiming(Packet *pkt); + virtual Tick recvAtomic(PacketPtr pkt); - virtual Tick recvAtomic(Packet *pkt); - - virtual void recvFunctional(Packet *pkt); + virtual void recvFunctional(PacketPtr pkt); virtual void recvStatusChange(Status status); @@ -74,35 +72,96 @@ class PhysicalMemory : public MemObject int numPorts; - struct MemResponseEvent : public Event - { - Packet *pkt; - MemoryPort *memoryPort; - - MemResponseEvent(Packet *pkt, MemoryPort *memoryPort); - void process(); - const char *description(); - }; - private: // prevent copying of a MainMemory object PhysicalMemory(const PhysicalMemory &specmem); 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: @@ -110,14 +169,11 @@ class PhysicalMemory : public MemObject void getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop); virtual Port *getPort(const std::string &if_name, int idx = -1); void virtual init(); + unsigned int drain(Event *de); - // fast back-door memory access for vtophys(), remote gdb, etc. - // uint64_t phys_read_qword(Addr addr) const; - private: - bool doTimingAccess(Packet *pkt, MemoryPort *memoryPort); - Tick doAtomicAccess(Packet *pkt); - void doFunctionalAccess(Packet *pkt); - + protected: + void doFunctionalAccess(PacketPtr pkt); + virtual Tick calculateLatency(PacketPtr pkt); void recvStatusChange(Port::Status status); public: