/*
+ * Copyright (c) 2012 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
#define __MEM_REQUEST_HH__
#include <cassert>
+#include <climits>
-#include "base/fast_alloc.hh"
#include "base/flags.hh"
#include "base/misc.hh"
#include "base/types.hh"
#include "sim/core.hh"
+/**
+ * Special TaskIds that are used for per-context-switch stats dumps
+ * and Cache Occupancy. Having too many tasks seems to be a problem
+ * with vector stats. 1024 seems to be a reasonable number that
+ * doesn't cause a problem with stats and is large enough to realistic
+ * benchmarks (Linux/Android boot, BBench, etc.)
+ */
+
+namespace ContextSwitchTaskId {
+ enum TaskId {
+ MaxNormalTaskId = 1021, /* Maximum number of normal tasks */
+ Prefetcher = 1022, /* For cache lines brought in by prefetcher */
+ DMA = 1023, /* Mostly Table Walker */
+ Unknown = 1024,
+ NumTaskId
+ };
+}
+
class Request;
typedef Request* RequestPtr;
+typedef uint16_t MasterID;
-class Request : public FastAlloc
+class Request
{
public:
typedef uint32_t FlagsType;
/** The request is to an uncacheable address. */
static const FlagsType UNCACHEABLE = 0x00001000;
/** This request is to a memory mapped register. */
- static const FlagsType MMAPED_IPR = 0x00002000;
+ static const FlagsType MMAPPED_IPR = 0x00002000;
/** This request is a clear exclusive. */
- static const FlagsType CLREX = 0x00004000;
+ static const FlagsType CLEAR_LL = 0x00004000;
- /** 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 = 0x00080000;
/** This request will lock or unlock the accessed memory. When used with
(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;
+ /** @} */
+
+ /** Invalid or unknown Pid. Possible when operating system is not present
+ * or has not assigned a pid yet */
+ static const uint32_t invldPid = UINT_MAX;
+
private:
typedef uint8_t PrivateFlagsType;
typedef ::Flags<PrivateFlagsType> PrivateFlags;
*/
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;
/**
* 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;
/**
* 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);
+ setPhys(paddr, size, flags, mid);
}
- Request(Addr paddr, int size, Flags flags, Tick time)
+ Request(Addr paddr, int size, Flags flags, MasterID mid, Tick time)
{
- setPhys(paddr, size, flags, time);
+ setPhys(paddr, size, flags, mid, time);
}
- Request(Addr paddr, int size, Flags flags, Tick time, Addr pc)
+ Request(Addr paddr, int size, Flags flags, MasterID mid, Tick time, Addr pc)
{
- setPhys(paddr, size, flags, time);
+ setPhys(paddr, size, flags, mid, time);
privateFlags.set(VALID_PC);
_pc = pc;
}
- Request(int asid, Addr vaddr, int size, Flags flags, Addr pc,
+ Request(int asid, Addr vaddr, int size, Flags flags, MasterID mid, Addr pc,
int cid, ThreadID tid)
{
- setVirt(asid, vaddr, size, flags, pc);
+ setVirt(asid, vaddr, size, flags, mid, pc);
setThreadContext(cid, tid);
}
- ~Request() {} // for FastAlloc
+ ~Request() {}
/**
* Set up CPU and thread numbers.
* allocated Request object.
*/
void
- setPhys(Addr paddr, int size, Flags flags, Tick time)
+ 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);
}
void
- setPhys(Addr paddr, int size, Flags flags)
+ setPhys(Addr paddr, int size, Flags flags, MasterID mid)
{
- setPhys(paddr, size, flags, curTick);
+ setPhys(paddr, size, flags, mid, curTick());
}
/**
* 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;
+ _masterId = mid;
_pc = pc;
- _time = curTick;
+ _time = curTick();
_flags.clear(~STICKY_FLAGS);
_flags.set(flags);
return _vaddr;
}
+ /** Accesssor for the requestor id. */
+ MasterID
+ masterId()
+ {
+ return _masterId;
+ }
+
/** Accessor function for asid.*/
int
getAsid()
return _asid;
}
+ /** Accessor function for asid.*/
+ void
+ setAsid(int asid)
+ {
+ _asid = asid;
+ }
+
/** Accessor function for asi.*/
uint8_t
getAsi()
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 isClrex() const { return _flags.isSet(CLREX); }
-
- 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;
- }
+ bool isMmappedIpr() const { return _flags.isSet(MMAPPED_IPR); }
+ bool isClearLL() const { return _flags.isSet(CLEAR_LL); }
};
#endif // __MEM_REQUEST_HH__