X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Frequest.hh;h=8d1697ad2b98da284df09ccb35c209d354111be7;hb=0b29c2d057d2d6f4f8b9b7853da91bcb283e805c;hp=dde68ca3734954c7c3e0ee9d8788bddb0a03058a;hpb=a1aba01a02a8c1261120de83d8fbfd6624f0cb17;p=gem5.git diff --git a/src/mem/request.hh b/src/mem/request.hh index dde68ca37..8d1697ad2 100644 --- a/src/mem/request.hh +++ b/src/mem/request.hh @@ -44,7 +44,7 @@ #include "base/fast_alloc.hh" #include "base/flags.hh" #include "base/misc.hh" -#include "sim/host.hh" +#include "base/types.hh" #include "sim/core.hh" class Request; @@ -53,16 +53,14 @@ typedef Request* RequestPtr; class Request : public FastAlloc { - friend class Packet; - public: typedef uint32_t FlagsType; typedef ::Flags Flags; /** ASI information for this request if it exists. */ static const FlagsType ASI_BITS = 0x000000FF; - /** The request is a Load locked/store conditional. */ - static const FlagsType LOCKED = 0x00000100; + /** The request was an instruction fetch. */ + static const FlagsType INST_FETCH = 0x00000100; /** The virtual address is also the physical address. */ static const FlagsType PHYSICAL = 0x00000200; /** The request is an ALPHA VPTE pal access (hw_ld). */ @@ -71,78 +69,99 @@ class Request : public FastAlloc static const FlagsType ALTMODE = 0x00000800; /** The request is to an uncacheable address. */ static const FlagsType UNCACHEABLE = 0x00001000; - /** The request should not cause a page fault. */ - static const FlagsType NO_FAULT = 0x00002000; + /** This request is to a memory mapped register. */ + static const FlagsType MMAPED_IPR = 0x00002000; + + /** The request should ignore unaligned access faults */ + static const FlagsType NO_ALIGN_FAULT = 0x00020000; + /** The request should ignore unaligned access faults */ + static const FlagsType NO_HALF_WORD_ALIGN_FAULT = 0x00040000; /** The request should not cause a memory access. */ - static const FlagsType NO_ACCESS = 0x00004000; + static const FlagsType NO_ACCESS = 0x00080000; + /** This request will lock or unlock the accessed memory. When used with + * a load, the access locks the particular chunk of memory. When used + * with a store, it unlocks. The rule is that locked accesses have to be + * made up of a locked load, some operation on the data, and then a locked + * store. + */ + static const FlagsType LOCKED = 0x00100000; + /** The request is a Load locked/store conditional. */ + static const FlagsType LLSC = 0x00200000; + /** This request is for a memory swap. */ + static const FlagsType MEM_SWAP = 0x00400000; + static const FlagsType MEM_SWAP_COND = 0x00800000; + + /** The request is a prefetch. */ + static const FlagsType PREFETCH = 0x01000000; /** The request should be prefetched into the exclusive state. */ - static const FlagsType PF_EXCLUSIVE = 0x00010000; + static const FlagsType PF_EXCLUSIVE = 0x02000000; /** The request should be marked as LRU. */ - static const FlagsType EVICT_NEXT = 0x00020000; - /** The request should ignore unaligned access faults */ - static const FlagsType NO_ALIGN_FAULT = 0x00040000; - /** The request was an instruction read. */ - static const FlagsType INST_READ = 0x00080000; - /** This request is for a memory swap. */ - static const FlagsType MEM_SWAP = 0x00100000; - static const FlagsType MEM_SWAP_COND = 0x00200000; - /** The request should ignore unaligned access faults */ - static const FlagsType NO_HALF_WORD_ALIGN_FAULT = 0x00400000; - /** This request is to a memory mapped register. */ - static const FlagsType MMAPED_IPR = 0x00800000; + static const FlagsType EVICT_NEXT = 0x04000000; + + /** These flags are *not* cleared when a Request object is reused + (assigned a new address). */ + static const FlagsType STICKY_FLAGS = INST_FETCH; private: - static const FlagsType PUBLIC_FLAGS = 0x00FF3FFF; - static const FlagsType PRIVATE_FLAGS = 0xFF000000; + typedef uint8_t PrivateFlagsType; + typedef ::Flags PrivateFlags; /** Whether or not the size is valid. */ - static const FlagsType VALID_SIZE = 0x01000000; + static const PrivateFlagsType VALID_SIZE = 0x00000001; /** Whether or not paddr is valid (has been written yet). */ - static const FlagsType VALID_PADDR = 0x02000000; + static const PrivateFlagsType VALID_PADDR = 0x00000002; /** Whether or not the vaddr & asid are valid. */ - static const FlagsType VALID_VADDR = 0x04000000; + static const PrivateFlagsType VALID_VADDR = 0x00000004; /** Whether or not the pc is valid. */ - static const FlagsType VALID_PC = 0x10000000; + static const PrivateFlagsType VALID_PC = 0x00000010; /** Whether or not the context ID is valid. */ - static const FlagsType VALID_CONTEXT_ID = 0x20000000; - static const FlagsType VALID_THREAD_ID = 0x40000000; + static const PrivateFlagsType VALID_CONTEXT_ID = 0x00000020; + static const PrivateFlagsType VALID_THREAD_ID = 0x00000040; /** Whether or not the sc result is valid. */ - static const FlagsType VALID_EXTRA_DATA = 0x80000000; + static const PrivateFlagsType VALID_EXTRA_DATA = 0x00000080; + + /** These flags are *not* cleared when a Request object is reused + (assigned a new address). */ + static const PrivateFlagsType STICKY_PRIVATE_FLAGS = + VALID_CONTEXT_ID | VALID_THREAD_ID; private: /** * The physical address of the request. Valid only if validPaddr * is set. */ - Addr paddr; + Addr _paddr; /** * The size of the request. This field must be set when vaddr or * paddr is written via setVirt() or setPhys(), so it is always * valid as long as one of the address fields is valid. */ - int size; + int _size; /** Flag structure for the request. */ - Flags flags; + Flags _flags; + + /** Private flags for field validity checking. */ + PrivateFlags privateFlags; /** * The time this request was started. Used to calculate * latencies. This field is set to curTick any time paddr or vaddr * is written. */ - Tick time; + Tick _time; /** The address space ID. */ - int asid; + int _asid; /** The virtual address of the request. */ - Addr vaddr; + Addr _vaddr; /** * Extra data for the request, such as the return value of * store conditional or the compare value for a CAS. */ - uint64_t extraData; + uint64_t _extraData; /** The context ID (for statistics, typically). */ int _contextId; @@ -150,10 +169,13 @@ class Request : public FastAlloc int _threadId; /** program counter of initiating access; for tracing/debugging */ - Addr pc; + Addr _pc; public: - /** Minimal constructor. No fields are initialized. */ + /** Minimal constructor. No fields are initialized. + * (Note that _flags and privateFlags are cleared by Flags + * default constructor.) + */ Request() {} @@ -167,11 +189,23 @@ class Request : public FastAlloc setPhys(paddr, size, flags); } + Request(Addr paddr, int size, Flags flags, Tick time) + { + setPhys(paddr, size, flags, time); + } + + Request(Addr paddr, int size, Flags flags, Tick time, Addr pc) + { + setPhys(paddr, size, flags, time); + privateFlags.set(VALID_PC); + _pc = pc; + } + Request(int asid, Addr vaddr, int size, Flags flags, Addr pc, - int cid, int tid) + int cid, ThreadID tid) { - setThreadContext(cid, tid); setVirt(asid, vaddr, size, flags, pc); + setThreadContext(cid, tid); } ~Request() {} // for FastAlloc @@ -180,11 +214,11 @@ class Request : public FastAlloc * Set up CPU and thread numbers. */ void - setThreadContext(int context_id, int thread_id) + setThreadContext(int context_id, ThreadID tid) { _contextId = context_id; - _threadId = thread_id; - flags.set(VALID_CONTEXT_ID|VALID_THREAD_ID); + _threadId = tid; + privateFlags.set(VALID_CONTEXT_ID|VALID_THREAD_ID); } /** @@ -192,16 +226,23 @@ class Request : public FastAlloc * allocated Request object. */ void - setPhys(Addr _paddr, int _size, Flags _flags) + setPhys(Addr paddr, int size, Flags flags, Tick time) { - assert(_size >= 0); - paddr = _paddr; - size = _size; - time = curTick; - - flags.set(VALID_PADDR|VALID_SIZE); - flags.clear(VALID_VADDR|VALID_PC|VALID_EXTRA_DATA|MMAPED_IPR); - flags.update(_flags, PUBLIC_FLAGS); + assert(size >= 0); + _paddr = paddr; + _size = size; + _time = time; + + _flags.clear(~STICKY_FLAGS); + _flags.set(flags); + privateFlags.clear(~STICKY_PRIVATE_FLAGS); + privateFlags.set(VALID_PADDR|VALID_SIZE); + } + + void + setPhys(Addr paddr, int size, Flags flags) + { + setPhys(paddr, size, flags, curTick); } /** @@ -209,18 +250,19 @@ class Request : public FastAlloc * allocated Request object. */ void - setVirt(int _asid, Addr _vaddr, int _size, Flags _flags, Addr _pc) + setVirt(int asid, Addr vaddr, int size, Flags flags, Addr pc) { - assert(_size >= 0); - asid = _asid; - vaddr = _vaddr; - size = _size; - pc = _pc; - time = curTick; - - flags.set(VALID_VADDR|VALID_SIZE|VALID_PC); - flags.clear(VALID_PADDR|VALID_EXTRA_DATA|MMAPED_IPR); - flags.update(_flags, PUBLIC_FLAGS); + assert(size >= 0); + _asid = asid; + _vaddr = vaddr; + _size = size; + _pc = pc; + _time = curTick; + + _flags.clear(~STICKY_FLAGS); + _flags.set(flags); + privateFlags.clear(~STICKY_PRIVATE_FLAGS); + privateFlags.set(VALID_VADDR|VALID_SIZE|VALID_PC); } /** @@ -230,11 +272,11 @@ class Request : public FastAlloc * to guarantee that the size and flags are also set. */ void - setPaddr(Addr _paddr) + setPaddr(Addr paddr) { - assert(flags.isSet(VALID_VADDR)); - paddr = _paddr; - flags.set(VALID_PADDR); + assert(privateFlags.isSet(VALID_VADDR)); + _paddr = paddr; + privateFlags.set(VALID_PADDR); } /** @@ -243,177 +285,142 @@ class Request : public FastAlloc */ void splitOnVaddr(Addr split_addr, RequestPtr &req1, RequestPtr &req2) { - assert(flags.isSet(VALID_VADDR)); - assert(flags.noneSet(VALID_PADDR)); - assert(split_addr > vaddr && split_addr < vaddr + size); + assert(privateFlags.isSet(VALID_VADDR)); + assert(privateFlags.noneSet(VALID_PADDR)); + assert(split_addr > _vaddr && split_addr < _vaddr + _size); req1 = new Request; *req1 = *this; req2 = new Request; *req2 = *this; - req1->size = split_addr - vaddr; - req2->vaddr = split_addr; - req2->size = size - req1->size; + req1->_size = split_addr - _vaddr; + req2->_vaddr = split_addr; + req2->_size = _size - req1->_size; } /** * Accessor for paddr. */ + bool + hasPaddr() + { + return privateFlags.isSet(VALID_PADDR); + } + Addr getPaddr() { - assert(flags.isSet(VALID_PADDR)); - return paddr; + assert(privateFlags.isSet(VALID_PADDR)); + return _paddr; } /** * Accessor for size. */ + bool + hasSize() + { + return privateFlags.isSet(VALID_SIZE); + } + int getSize() { - assert(flags.isSet(VALID_SIZE)); - return size; + assert(privateFlags.isSet(VALID_SIZE)); + return _size; } /** Accessor for time. */ Tick - getTime() + time() const { - assert(flags.isSet(VALID_PADDR|VALID_VADDR)); - return time; + assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR)); + return _time; } void - setTime(Tick when) + time(Tick time) { - assert(flags.isSet(VALID_PADDR|VALID_VADDR)); - time = when; + assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR)); + _time = time; } /** Accessor for flags. */ Flags getFlags() { - assert(flags.isSet(VALID_PADDR|VALID_VADDR)); - return flags & PUBLIC_FLAGS; + assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR)); + return _flags; } - Flags - anyFlags(Flags _flags) - { - assert(flags.isSet(VALID_PADDR|VALID_VADDR)); - assert(_flags.noneSet(~PUBLIC_FLAGS)); - return flags.isSet(_flags); - } - - Flags - allFlags(Flags _flags) - { - assert(flags.isSet(VALID_PADDR|VALID_VADDR)); - assert(_flags.noneSet(~PUBLIC_FLAGS)); - return flags.allSet(_flags); - } - - /** Accessor for flags. */ + /** Note that unlike other accessors, this function sets *specific + flags* (ORs them in); it does not assign its argument to the + _flags field. Thus this method should rightly be called + setFlags() and not just flags(). */ void - setFlags(Flags _flags) + setFlags(Flags flags) { - assert(flags.isSet(VALID_PADDR|VALID_VADDR)); - assert(_flags.noneSet(~PUBLIC_FLAGS)); - flags.set(_flags); - } - - void - clearFlags(Flags _flags) - { - assert(flags.isSet(VALID_PADDR|VALID_VADDR)); - assert(_flags.noneSet(~PUBLIC_FLAGS)); - flags.clear(_flags); - } - - void - clearFlags() - { - assert(flags.isSet(VALID_PADDR|VALID_VADDR)); - flags.clear(PUBLIC_FLAGS); + assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR)); + _flags.set(flags); } /** Accessor function for vaddr.*/ Addr getVaddr() { - assert(flags.isSet(VALID_VADDR)); - return vaddr; + assert(privateFlags.isSet(VALID_VADDR)); + return _vaddr; } /** Accessor function for asid.*/ int getAsid() { - assert(flags.isSet(VALID_VADDR)); - return asid; + assert(privateFlags.isSet(VALID_VADDR)); + return _asid; } /** Accessor function for asi.*/ uint8_t getAsi() { - assert(flags.isSet(VALID_VADDR)); - return flags & ASI_BITS; - } - - /** Accessor function for asi.*/ - void - setAsi(uint8_t a) - { - assert(flags.isSet(VALID_VADDR)); - flags.update(a, ASI_BITS); - } - - /** Accessor function for asi.*/ - bool - isMmapedIpr() - { - assert(flags.isSet(VALID_PADDR)); - return flags.isSet(MMAPED_IPR); - } - - /** Accessor function for asi.*/ - void - setMmapedIpr(bool r) - { - assert(VALID_VADDR); - flags.set(MMAPED_IPR); + assert(privateFlags.isSet(VALID_VADDR)); + return _flags & ASI_BITS; } /** Accessor function to check if sc result is valid. */ bool extraDataValid() { - return flags.isSet(VALID_EXTRA_DATA); + return privateFlags.isSet(VALID_EXTRA_DATA); } /** Accessor function for store conditional return value.*/ uint64_t getExtraData() const { - assert(flags.isSet(VALID_EXTRA_DATA)); - return extraData; + assert(privateFlags.isSet(VALID_EXTRA_DATA)); + return _extraData; } /** Accessor function for store conditional return value.*/ void - setExtraData(uint64_t _extraData) + setExtraData(uint64_t extraData) { - extraData = _extraData; - flags.set(VALID_EXTRA_DATA); + _extraData = extraData; + privateFlags.set(VALID_EXTRA_DATA); + } + + bool + hasContextId() const + { + return privateFlags.isSet(VALID_CONTEXT_ID); } /** Accessor function for context ID.*/ int contextId() const { - assert(flags.isSet(VALID_CONTEXT_ID)); + assert(privateFlags.isSet(VALID_CONTEXT_ID)); return _contextId; } @@ -421,44 +428,48 @@ class Request : public FastAlloc int threadId() const { - assert(flags.isSet(VALID_THREAD_ID)); + assert(privateFlags.isSet(VALID_THREAD_ID)); return _threadId; } - /** Accessor function for pc.*/ bool hasPC() const { - return flags.isSet(VALID_PC); + return privateFlags.isSet(VALID_PC); } + /** Accessor function for pc.*/ Addr getPC() const { - assert(flags.isSet(VALID_PC)); - return pc; + assert(privateFlags.isSet(VALID_PC)); + return _pc; } - /** Accessor Function to Check Cacheability. */ - bool isUncacheable() const { return flags.isSet(UNCACHEABLE); } - bool isInstRead() const { return flags.isSet(INST_READ); } - bool isLocked() const { return flags.isSet(LOCKED); } - bool isSwap() const { return flags.isSet(MEM_SWAP|MEM_SWAP_COND); } - bool isCondSwap() const { return flags.isSet(MEM_SWAP_COND); } + /** Accessor functions for flags. Note that these are for testing + only; setting flags should be done via setFlags(). */ + bool isUncacheable() const { return _flags.isSet(UNCACHEABLE); } + bool isInstFetch() const { return _flags.isSet(INST_FETCH); } + bool isPrefetch() const { return _flags.isSet(PREFETCH); } + bool isLLSC() const { return _flags.isSet(LLSC); } + bool isLocked() const { return _flags.isSet(LOCKED); } + bool isSwap() const { return _flags.isSet(MEM_SWAP|MEM_SWAP_COND); } + bool isCondSwap() const { return _flags.isSet(MEM_SWAP_COND); } + bool isMmapedIpr() const { return _flags.isSet(MMAPED_IPR); } bool isMisaligned() const { - if (flags.isSet(NO_ALIGN_FAULT)) + if (_flags.isSet(NO_ALIGN_FAULT)) return false; - if ((vaddr & 0x1)) + if ((_vaddr & 0x1)) return true; - if (flags.isSet(NO_HALF_WORD_ALIGN_FAULT)) + if (_flags.isSet(NO_HALF_WORD_ALIGN_FAULT)) return false; - if ((vaddr & 0x2)) + if ((_vaddr & 0x2)) return true; return false;