mem: Convert Request static const flags to enums

This patch fixes an issue which is very wide spread in the codebase,
causing sporadic linking failures. The issue is that we declare static
const class variables in the header, without any definition (as part
of a source file). In most cases the compiler propagates the value and
we have no issues. However, especially for less optimising builds such
as debug, we get sporadic linking failures due to undefined
references.

This patch fixes the Request class, by turning the static const flags
and master IDs into C++11 typed enums.
This commit is contained in:
Andreas Hansson 2015-07-03 10:14:36 -04:00
parent 359904194d
commit aa5bbe81f6

View file

@ -89,6 +89,7 @@ class Request
typedef uint8_t ArchFlagsType;
typedef ::Flags<FlagsType> Flags;
enum : FlagsType {
/**
* Architecture specific flags.
*
@ -96,11 +97,11 @@ class Request
* architecture-specific code. For example, SPARC uses them to
* represent ASIs.
*/
static const FlagsType ARCH_BITS = 0x000000FF;
ARCH_BITS = 0x000000FF,
/** The request was an instruction fetch. */
static const FlagsType INST_FETCH = 0x00000100;
INST_FETCH = 0x00000100,
/** The virtual address is also the physical address. */
static const FlagsType PHYSICAL = 0x00000200;
PHYSICAL = 0x00000200,
/**
* The request is to an uncacheable address.
*
@ -108,78 +109,89 @@ class Request
* STRICT_ORDER flag should be set if such reordering is
* undesirable.
*/
static const FlagsType UNCACHEABLE = 0x00000400;
UNCACHEABLE = 0x00000400,
/**
* The request is required to be strictly ordered by <i>CPU
* models</i> and is non-speculative.
*
* A strictly ordered request is guaranteed to never be re-ordered
* or executed speculatively by a CPU model. The memory system may
* still reorder requests in caches unless the UNCACHEABLE flag is
* set as well.
* A strictly ordered request is guaranteed to never be
* re-ordered or executed speculatively by a CPU model. The
* memory system may still reorder requests in caches unless
* the UNCACHEABLE flag is set as well.
*/
static const FlagsType STRICT_ORDER = 0x00000800;
STRICT_ORDER = 0x00000800,
/** This request is to a memory mapped register. */
static const FlagsType MMAPPED_IPR = 0x00002000;
MMAPPED_IPR = 0x00002000,
/** This request is a clear exclusive. */
static const FlagsType CLEAR_LL = 0x00004000;
CLEAR_LL = 0x00004000,
/** This request is made in privileged mode. */
static const FlagsType PRIVILEGED = 0x00008000;
PRIVILEGED = 0x00008000,
/** This is a write that is targeted and zeroing an entire cache block.
* There is no need for a read/modify/write
/**
* This is a write that is targeted and zeroing an entire
* cache block. There is no need for a read/modify/write
*/
static const FlagsType CACHE_BLOCK_ZERO = 0x00010000;
CACHE_BLOCK_ZERO = 0x00010000,
/** The request should not cause a memory access. */
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.
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_RMW = 0x00100000;
LOCKED_RMW = 0x00100000,
/** The request is a Load locked/store conditional. */
static const FlagsType LLSC = 0x00200000;
LLSC = 0x00200000,
/** This request is for a memory swap. */
static const FlagsType MEM_SWAP = 0x00400000;
static const FlagsType MEM_SWAP_COND = 0x00800000;
MEM_SWAP = 0x00400000,
MEM_SWAP_COND = 0x00800000,
/** The request is a prefetch. */
static const FlagsType PREFETCH = 0x01000000;
PREFETCH = 0x01000000,
/** The request should be prefetched into the exclusive state. */
static const FlagsType PF_EXCLUSIVE = 0x02000000;
PF_EXCLUSIVE = 0x02000000,
/** The request should be marked as LRU. */
static const FlagsType EVICT_NEXT = 0x04000000;
EVICT_NEXT = 0x04000000,
/** The request should be handled by the generic IPR code (only
* valid together with MMAPPED_IPR) */
static const FlagsType GENERIC_IPR = 0x08000000;
/**
* The request should be handled by the generic IPR code (only
* valid together with MMAPPED_IPR)
*/
GENERIC_IPR = 0x08000000,
/** The request targets the secure memory space. */
static const FlagsType SECURE = 0x10000000;
SECURE = 0x10000000,
/** The request is a page table walk */
static const FlagsType PT_WALK = 0x20000000;
PT_WALK = 0x20000000,
/** 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
/**
* These flags are *not* cleared when a Request object is
* reused (assigned a new address).
*/
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 = std::numeric_limits<MasterID>::max();
STICKY_FLAGS = INST_FETCH
};
/** Master Ids that are statically allocated
* @{*/
enum : MasterID {
/** This master id is used for writeback requests by the caches */
wbMasterId = 0,
/**
* This master id is used for functional requests that
* don't come from a particular device
*/
funcMasterId = 1,
/** This master id is used for message signaled interrupts */
intMasterId = 2,
/**
* Invalid master id for assertion checking only. It is
* invalid behavior to ever send this id as part of a request.
*/
invldMasterId = std::numeric_limits<MasterID>::max()
};
/** @} */
/** Invalid or unknown Pid. Possible when operating system is not present
@ -190,24 +202,27 @@ class Request
typedef uint8_t PrivateFlagsType;
typedef ::Flags<PrivateFlagsType> PrivateFlags;
enum : PrivateFlagsType {
/** Whether or not the size is valid. */
static const PrivateFlagsType VALID_SIZE = 0x00000001;
VALID_SIZE = 0x00000001,
/** Whether or not paddr is valid (has been written yet). */
static const PrivateFlagsType VALID_PADDR = 0x00000002;
VALID_PADDR = 0x00000002,
/** Whether or not the vaddr & asid are valid. */
static const PrivateFlagsType VALID_VADDR = 0x00000004;
VALID_VADDR = 0x00000004,
/** Whether or not the pc is valid. */
static const PrivateFlagsType VALID_PC = 0x00000010;
VALID_PC = 0x00000010,
/** Whether or not the context ID is valid. */
static const PrivateFlagsType VALID_CONTEXT_ID = 0x00000020;
static const PrivateFlagsType VALID_THREAD_ID = 0x00000040;
VALID_CONTEXT_ID = 0x00000020,
VALID_THREAD_ID = 0x00000040,
/** Whether or not the sc result is valid. */
static const PrivateFlagsType VALID_EXTRA_DATA = 0x00000080;
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;
/**
* These flags are *not* cleared when a Request object is reused
* (assigned a new address).
*/
STICKY_PRIVATE_FLAGS = VALID_CONTEXT_ID | VALID_THREAD_ID
};
private: