X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Frequest.hh;h=f6406e2c5ee42f679465e0b1fbd8ef5a866b2b45;hb=6721b3e325139fb4ace99d858f0bdec44ec6af1b;hp=dde68ca3734954c7c3e0ee9d8788bddb0a03058a;hpb=a1aba01a02a8c1261120de83d8fbfd6624f0cb17;p=gem5.git diff --git a/src/mem/request.hh b/src/mem/request.hh index dde68ca37..f6406e2c5 100644 --- a/src/mem/request.hh +++ b/src/mem/request.hh @@ -40,29 +40,28 @@ #define __MEM_REQUEST_HH__ #include +#include -#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; typedef Request* RequestPtr; +typedef uint16_t MasterID; -class Request : public FastAlloc +class Request { - 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 +70,118 @@ 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 MMAPPED_IPR = 0x00002000; + /** This request is a clear exclusive. */ + static const FlagsType CLEAR_LL = 0x00004000; + /** 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; + + /** Request Ids that are statically allocated + * @{*/ + /** This request id is used for writeback requests by the caches */ + static const MasterID wbMasterId = 0; + /** This request id is used for functional requests that don't come from a + * particular device + */ + static const MasterID funcMasterId = 1; + /** This request id is used for message signaled interrupts */ + static const MasterID intMasterId = 2; + /** Invalid request id for assertion checking only. It is invalid behavior + * to ever send this id as part of a request. + * @todo C++1x replace with numeric_limits when constexpr is added */ + static const MasterID invldMasterId = USHRT_MAX; + /** @} */ 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; + + /** The requestor ID which is unique in the system for all ports + * that are capable of issuing a transaction + */ + MasterID _masterId; /** 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 + * 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,41 +189,56 @@ 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() {} /** * Constructor for physical (e.g. device) requests. Initializes - * just physical address, size, flags, and timestamp (to curTick). + * just physical address, size, flags, and timestamp (to curTick()). * These fields are adequate to perform a request. */ - Request(Addr paddr, int size, Flags flags) + Request(Addr paddr, int size, Flags flags, MasterID mid) + { + setPhys(paddr, size, flags, mid); + } + + Request(Addr paddr, int size, Flags flags, MasterID mid, Tick time) + { + setPhys(paddr, size, flags, mid, time); + } + + Request(Addr paddr, int size, Flags flags, MasterID mid, Tick time, Addr pc) { - setPhys(paddr, size, flags); + setPhys(paddr, size, flags, mid, time); + privateFlags.set(VALID_PC); + _pc = pc; } - Request(int asid, Addr vaddr, int size, Flags flags, Addr pc, - int cid, int tid) + Request(int asid, Addr vaddr, int size, Flags flags, MasterID mid, Addr pc, + int cid, ThreadID tid) { + setVirt(asid, vaddr, size, flags, mid, pc); setThreadContext(cid, tid); - setVirt(asid, vaddr, size, flags, pc); } - ~Request() {} // for FastAlloc + ~Request() {} /** * 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 +246,23 @@ class Request : public FastAlloc * allocated Request object. */ void - setPhys(Addr _paddr, int _size, Flags _flags) + setPhys(Addr paddr, int size, Flags flags, MasterID mid, Tick time) + { + assert(size >= 0); + _paddr = paddr; + _size = size; + _time = time; + _masterId = mid; + _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, MasterID mid) { - 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); + setPhys(paddr, size, flags, mid, curTick()); } /** @@ -209,18 +270,20 @@ 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, MasterID mid, 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; + _masterId = mid; + _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 +293,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 +306,156 @@ 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; - } - - 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. */ - void - setFlags(Flags _flags) - { - assert(flags.isSet(VALID_PADDR|VALID_VADDR)); - assert(_flags.noneSet(~PUBLIC_FLAGS)); - flags.set(_flags); + assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR)); + return _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 - clearFlags(Flags _flags) + setFlags(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() + /** Accesssor for the requestor id. */ + MasterID + masterId() { - assert(flags.isSet(VALID_VADDR)); - return asid; + return _masterId; } - /** Accessor function for asi.*/ - uint8_t - getAsi() + /** Accessor function for asid.*/ + int + getAsid() { - assert(flags.isSet(VALID_VADDR)); - return flags & ASI_BITS; + assert(privateFlags.isSet(VALID_VADDR)); + return _asid; } - /** Accessor function for asi.*/ + /** Accessor function for asid.*/ void - setAsi(uint8_t a) - { - assert(flags.isSet(VALID_VADDR)); - flags.update(a, ASI_BITS); - } - - /** Accessor function for asi.*/ - bool - isMmapedIpr() + setAsid(int asid) { - assert(flags.isSet(VALID_PADDR)); - return flags.isSet(MMAPED_IPR); + _asid = asid; } /** Accessor function for asi.*/ - void - setMmapedIpr(bool r) + uint8_t + getAsi() { - 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; + privateFlags.set(VALID_EXTRA_DATA); + } + + bool + hasContextId() const { - extraData = _extraData; - flags.set(VALID_EXTRA_DATA); + 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,48 +463,35 @@ 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); } - - bool - isMisaligned() const - { - if (flags.isSet(NO_ALIGN_FAULT)) - return false; - - if ((vaddr & 0x1)) - return true; - - if (flags.isSet(NO_HALF_WORD_ALIGN_FAULT)) - return false; - - if ((vaddr & 0x2)) - return true; - - return false; - } + /** 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 isMmappedIpr() const { return _flags.isSet(MMAPPED_IPR); } + bool isClearLL() const { return _flags.isSet(CLEAR_LL); } }; #endif // __MEM_REQUEST_HH__