request.hh (10568:e70523bd0d26) request.hh (10653:e3fc6bc7f97e)
1/*
2 * Copyright (c) 2012-2013 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Ron Dreslinski
41 * Steve Reinhardt
42 * Ali Saidi
43 */
44
45/**
46 * @file
47 * Declaration of a request, the overall memory request consisting of
48 the parts of the request that are persistent throughout the transaction.
49 */
50
51#ifndef __MEM_REQUEST_HH__
52#define __MEM_REQUEST_HH__
53
54#include <cassert>
55#include <climits>
56
57#include "base/flags.hh"
58#include "base/misc.hh"
59#include "base/types.hh"
60#include "sim/core.hh"
61
62/**
63 * Special TaskIds that are used for per-context-switch stats dumps
64 * and Cache Occupancy. Having too many tasks seems to be a problem
65 * with vector stats. 1024 seems to be a reasonable number that
66 * doesn't cause a problem with stats and is large enough to realistic
67 * benchmarks (Linux/Android boot, BBench, etc.)
68 */
69
70namespace ContextSwitchTaskId {
71 enum TaskId {
72 MaxNormalTaskId = 1021, /* Maximum number of normal tasks */
73 Prefetcher = 1022, /* For cache lines brought in by prefetcher */
74 DMA = 1023, /* Mostly Table Walker */
75 Unknown = 1024,
76 NumTaskId
77 };
78}
79
80class Request;
81
82typedef Request* RequestPtr;
83typedef uint16_t MasterID;
84
85class Request
86{
87 public:
88 typedef uint32_t FlagsType;
89 typedef uint8_t ArchFlagsType;
90 typedef ::Flags<FlagsType> Flags;
91
92 /**
93 * Architecture specific flags.
94 *
95 * These bits int the flag field are reserved for
96 * architecture-specific code. For example, SPARC uses them to
97 * represent ASIs.
98 */
99 static const FlagsType ARCH_BITS = 0x000000FF;
100 /** The request was an instruction fetch. */
101 static const FlagsType INST_FETCH = 0x00000100;
102 /** The virtual address is also the physical address. */
103 static const FlagsType PHYSICAL = 0x00000200;
104 /** The request is an ALPHA VPTE pal access (hw_ld). */
105 static const FlagsType VPTE = 0x00000400;
106 /** Use the alternate mode bits in ALPHA. */
107 static const FlagsType ALTMODE = 0x00000800;
108 /** The request is to an uncacheable address. */
109 static const FlagsType UNCACHEABLE = 0x00001000;
110 /** This request is to a memory mapped register. */
111 static const FlagsType MMAPPED_IPR = 0x00002000;
112 /** This request is a clear exclusive. */
113 static const FlagsType CLEAR_LL = 0x00004000;
114 /** This request is made in privileged mode. */
115 static const FlagsType PRIVILEGED = 0x00008000;
116
117 /** This is a write that is targeted and zeroing an entire cache block.
118 * There is no need for a read/modify/write
119 */
120 static const FlagsType CACHE_BLOCK_ZERO = 0x00010000;
121
122 /** The request should not cause a memory access. */
123 static const FlagsType NO_ACCESS = 0x00080000;
124 /** This request will lock or unlock the accessed memory. When used with
125 * a load, the access locks the particular chunk of memory. When used
126 * with a store, it unlocks. The rule is that locked accesses have to be
127 * made up of a locked load, some operation on the data, and then a locked
128 * store.
129 */
130 static const FlagsType LOCKED = 0x00100000;
131 /** The request is a Load locked/store conditional. */
132 static const FlagsType LLSC = 0x00200000;
133 /** This request is for a memory swap. */
134 static const FlagsType MEM_SWAP = 0x00400000;
135 static const FlagsType MEM_SWAP_COND = 0x00800000;
136
137 /** The request is a prefetch. */
138 static const FlagsType PREFETCH = 0x01000000;
139 /** The request should be prefetched into the exclusive state. */
140 static const FlagsType PF_EXCLUSIVE = 0x02000000;
141 /** The request should be marked as LRU. */
142 static const FlagsType EVICT_NEXT = 0x04000000;
143
144 /** The request should be handled by the generic IPR code (only
145 * valid together with MMAPPED_IPR) */
146 static const FlagsType GENERIC_IPR = 0x08000000;
147
148 /** The request targets the secure memory space. */
149 static const FlagsType SECURE = 0x10000000;
150 /** The request is a page table walk */
151 static const FlagsType PT_WALK = 0x20000000;
152
153 /** These flags are *not* cleared when a Request object is reused
154 (assigned a new address). */
155 static const FlagsType STICKY_FLAGS = INST_FETCH;
156
157 /** Request Ids that are statically allocated
158 * @{*/
159 /** This request id is used for writeback requests by the caches */
160 static const MasterID wbMasterId = 0;
161 /** This request id is used for functional requests that don't come from a
162 * particular device
163 */
164 static const MasterID funcMasterId = 1;
165 /** This request id is used for message signaled interrupts */
166 static const MasterID intMasterId = 2;
167 /** Invalid request id for assertion checking only. It is invalid behavior
168 * to ever send this id as part of a request.
169 * @todo C++1x replace with numeric_limits when constexpr is added */
170 static const MasterID invldMasterId = USHRT_MAX;
171 /** @} */
172
173 /** Invalid or unknown Pid. Possible when operating system is not present
174 * or has not assigned a pid yet */
175 static const uint32_t invldPid = UINT_MAX;
176
177 private:
178 typedef uint8_t PrivateFlagsType;
179 typedef ::Flags<PrivateFlagsType> PrivateFlags;
180
181 /** Whether or not the size is valid. */
182 static const PrivateFlagsType VALID_SIZE = 0x00000001;
183 /** Whether or not paddr is valid (has been written yet). */
184 static const PrivateFlagsType VALID_PADDR = 0x00000002;
185 /** Whether or not the vaddr & asid are valid. */
186 static const PrivateFlagsType VALID_VADDR = 0x00000004;
187 /** Whether or not the pc is valid. */
188 static const PrivateFlagsType VALID_PC = 0x00000010;
189 /** Whether or not the context ID is valid. */
190 static const PrivateFlagsType VALID_CONTEXT_ID = 0x00000020;
191 static const PrivateFlagsType VALID_THREAD_ID = 0x00000040;
192 /** Whether or not the sc result is valid. */
193 static const PrivateFlagsType VALID_EXTRA_DATA = 0x00000080;
194
195 /** These flags are *not* cleared when a Request object is reused
196 (assigned a new address). */
197 static const PrivateFlagsType STICKY_PRIVATE_FLAGS =
198 VALID_CONTEXT_ID | VALID_THREAD_ID;
199
200 private:
1/*
2 * Copyright (c) 2012-2013 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Ron Dreslinski
41 * Steve Reinhardt
42 * Ali Saidi
43 */
44
45/**
46 * @file
47 * Declaration of a request, the overall memory request consisting of
48 the parts of the request that are persistent throughout the transaction.
49 */
50
51#ifndef __MEM_REQUEST_HH__
52#define __MEM_REQUEST_HH__
53
54#include <cassert>
55#include <climits>
56
57#include "base/flags.hh"
58#include "base/misc.hh"
59#include "base/types.hh"
60#include "sim/core.hh"
61
62/**
63 * Special TaskIds that are used for per-context-switch stats dumps
64 * and Cache Occupancy. Having too many tasks seems to be a problem
65 * with vector stats. 1024 seems to be a reasonable number that
66 * doesn't cause a problem with stats and is large enough to realistic
67 * benchmarks (Linux/Android boot, BBench, etc.)
68 */
69
70namespace ContextSwitchTaskId {
71 enum TaskId {
72 MaxNormalTaskId = 1021, /* Maximum number of normal tasks */
73 Prefetcher = 1022, /* For cache lines brought in by prefetcher */
74 DMA = 1023, /* Mostly Table Walker */
75 Unknown = 1024,
76 NumTaskId
77 };
78}
79
80class Request;
81
82typedef Request* RequestPtr;
83typedef uint16_t MasterID;
84
85class Request
86{
87 public:
88 typedef uint32_t FlagsType;
89 typedef uint8_t ArchFlagsType;
90 typedef ::Flags<FlagsType> Flags;
91
92 /**
93 * Architecture specific flags.
94 *
95 * These bits int the flag field are reserved for
96 * architecture-specific code. For example, SPARC uses them to
97 * represent ASIs.
98 */
99 static const FlagsType ARCH_BITS = 0x000000FF;
100 /** The request was an instruction fetch. */
101 static const FlagsType INST_FETCH = 0x00000100;
102 /** The virtual address is also the physical address. */
103 static const FlagsType PHYSICAL = 0x00000200;
104 /** The request is an ALPHA VPTE pal access (hw_ld). */
105 static const FlagsType VPTE = 0x00000400;
106 /** Use the alternate mode bits in ALPHA. */
107 static const FlagsType ALTMODE = 0x00000800;
108 /** The request is to an uncacheable address. */
109 static const FlagsType UNCACHEABLE = 0x00001000;
110 /** This request is to a memory mapped register. */
111 static const FlagsType MMAPPED_IPR = 0x00002000;
112 /** This request is a clear exclusive. */
113 static const FlagsType CLEAR_LL = 0x00004000;
114 /** This request is made in privileged mode. */
115 static const FlagsType PRIVILEGED = 0x00008000;
116
117 /** This is a write that is targeted and zeroing an entire cache block.
118 * There is no need for a read/modify/write
119 */
120 static const FlagsType CACHE_BLOCK_ZERO = 0x00010000;
121
122 /** The request should not cause a memory access. */
123 static const FlagsType NO_ACCESS = 0x00080000;
124 /** This request will lock or unlock the accessed memory. When used with
125 * a load, the access locks the particular chunk of memory. When used
126 * with a store, it unlocks. The rule is that locked accesses have to be
127 * made up of a locked load, some operation on the data, and then a locked
128 * store.
129 */
130 static const FlagsType LOCKED = 0x00100000;
131 /** The request is a Load locked/store conditional. */
132 static const FlagsType LLSC = 0x00200000;
133 /** This request is for a memory swap. */
134 static const FlagsType MEM_SWAP = 0x00400000;
135 static const FlagsType MEM_SWAP_COND = 0x00800000;
136
137 /** The request is a prefetch. */
138 static const FlagsType PREFETCH = 0x01000000;
139 /** The request should be prefetched into the exclusive state. */
140 static const FlagsType PF_EXCLUSIVE = 0x02000000;
141 /** The request should be marked as LRU. */
142 static const FlagsType EVICT_NEXT = 0x04000000;
143
144 /** The request should be handled by the generic IPR code (only
145 * valid together with MMAPPED_IPR) */
146 static const FlagsType GENERIC_IPR = 0x08000000;
147
148 /** The request targets the secure memory space. */
149 static const FlagsType SECURE = 0x10000000;
150 /** The request is a page table walk */
151 static const FlagsType PT_WALK = 0x20000000;
152
153 /** These flags are *not* cleared when a Request object is reused
154 (assigned a new address). */
155 static const FlagsType STICKY_FLAGS = INST_FETCH;
156
157 /** Request Ids that are statically allocated
158 * @{*/
159 /** This request id is used for writeback requests by the caches */
160 static const MasterID wbMasterId = 0;
161 /** This request id is used for functional requests that don't come from a
162 * particular device
163 */
164 static const MasterID funcMasterId = 1;
165 /** This request id is used for message signaled interrupts */
166 static const MasterID intMasterId = 2;
167 /** Invalid request id for assertion checking only. It is invalid behavior
168 * to ever send this id as part of a request.
169 * @todo C++1x replace with numeric_limits when constexpr is added */
170 static const MasterID invldMasterId = USHRT_MAX;
171 /** @} */
172
173 /** Invalid or unknown Pid. Possible when operating system is not present
174 * or has not assigned a pid yet */
175 static const uint32_t invldPid = UINT_MAX;
176
177 private:
178 typedef uint8_t PrivateFlagsType;
179 typedef ::Flags<PrivateFlagsType> PrivateFlags;
180
181 /** Whether or not the size is valid. */
182 static const PrivateFlagsType VALID_SIZE = 0x00000001;
183 /** Whether or not paddr is valid (has been written yet). */
184 static const PrivateFlagsType VALID_PADDR = 0x00000002;
185 /** Whether or not the vaddr & asid are valid. */
186 static const PrivateFlagsType VALID_VADDR = 0x00000004;
187 /** Whether or not the pc is valid. */
188 static const PrivateFlagsType VALID_PC = 0x00000010;
189 /** Whether or not the context ID is valid. */
190 static const PrivateFlagsType VALID_CONTEXT_ID = 0x00000020;
191 static const PrivateFlagsType VALID_THREAD_ID = 0x00000040;
192 /** Whether or not the sc result is valid. */
193 static const PrivateFlagsType VALID_EXTRA_DATA = 0x00000080;
194
195 /** These flags are *not* cleared when a Request object is reused
196 (assigned a new address). */
197 static const PrivateFlagsType STICKY_PRIVATE_FLAGS =
198 VALID_CONTEXT_ID | VALID_THREAD_ID;
199
200 private:
201
201 /**
202 /**
203 * Set up a physical (e.g. device) request in a previously
204 * allocated Request object.
205 */
206 void
207 setPhys(Addr paddr, unsigned size, Flags flags, MasterID mid, Tick time)
208 {
209 assert(size >= 0);
210 _paddr = paddr;
211 _size = size;
212 _time = time;
213 _masterId = mid;
214 _flags.clear(~STICKY_FLAGS);
215 _flags.set(flags);
216 privateFlags.clear(~STICKY_PRIVATE_FLAGS);
217 privateFlags.set(VALID_PADDR|VALID_SIZE);
218 depth = 0;
219 accessDelta = 0;
220 //translateDelta = 0;
221 }
222
223 /**
202 * The physical address of the request. Valid only if validPaddr
203 * is set.
204 */
205 Addr _paddr;
206
207 /**
208 * The size of the request. This field must be set when vaddr or
209 * paddr is written via setVirt() or setPhys(), so it is always
210 * valid as long as one of the address fields is valid.
211 */
224 * The physical address of the request. Valid only if validPaddr
225 * is set.
226 */
227 Addr _paddr;
228
229 /**
230 * The size of the request. This field must be set when vaddr or
231 * paddr is written via setVirt() or setPhys(), so it is always
232 * valid as long as one of the address fields is valid.
233 */
212 int _size;
234 unsigned _size;
213
214 /** The requestor ID which is unique in the system for all ports
215 * that are capable of issuing a transaction
216 */
217 MasterID _masterId;
218
219 /** Flag structure for the request. */
220 Flags _flags;
221
222 /** Private flags for field validity checking. */
223 PrivateFlags privateFlags;
224
225 /**
226 * The time this request was started. Used to calculate
227 * latencies. This field is set to curTick() any time paddr or vaddr
228 * is written.
229 */
230 Tick _time;
231
232 /**
233 * The task id associated with this request
234 */
235 uint32_t _taskId;
236
237 /** The address space ID. */
238 int _asid;
239
240 /** The virtual address of the request. */
241 Addr _vaddr;
242
243 /**
244 * Extra data for the request, such as the return value of
245 * store conditional or the compare value for a CAS. */
246 uint64_t _extraData;
247
248 /** The context ID (for statistics, typically). */
249 int _contextId;
250 /** The thread ID (id within this CPU) */
251 int _threadId;
252
253 /** program counter of initiating access; for tracing/debugging */
254 Addr _pc;
255
256 public:
235
236 /** The requestor ID which is unique in the system for all ports
237 * that are capable of issuing a transaction
238 */
239 MasterID _masterId;
240
241 /** Flag structure for the request. */
242 Flags _flags;
243
244 /** Private flags for field validity checking. */
245 PrivateFlags privateFlags;
246
247 /**
248 * The time this request was started. Used to calculate
249 * latencies. This field is set to curTick() any time paddr or vaddr
250 * is written.
251 */
252 Tick _time;
253
254 /**
255 * The task id associated with this request
256 */
257 uint32_t _taskId;
258
259 /** The address space ID. */
260 int _asid;
261
262 /** The virtual address of the request. */
263 Addr _vaddr;
264
265 /**
266 * Extra data for the request, such as the return value of
267 * store conditional or the compare value for a CAS. */
268 uint64_t _extraData;
269
270 /** The context ID (for statistics, typically). */
271 int _contextId;
272 /** The thread ID (id within this CPU) */
273 int _threadId;
274
275 /** program counter of initiating access; for tracing/debugging */
276 Addr _pc;
277
278 public:
257 /** Minimal constructor. No fields are initialized.
258 * (Note that _flags and privateFlags are cleared by Flags
259 * default constructor.)
279
280 /**
281 * Minimal constructor. No fields are initialized. (Note that
282 * _flags and privateFlags are cleared by Flags default
283 * constructor.)
260 */
261 Request()
262 : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
263 _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
264 _extraData(0), _contextId(0), _threadId(0), _pc(0),
265 translateDelta(0), accessDelta(0), depth(0)
266 {}
267
268 /**
269 * Constructor for physical (e.g. device) requests. Initializes
270 * just physical address, size, flags, and timestamp (to curTick()).
284 */
285 Request()
286 : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
287 _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
288 _extraData(0), _contextId(0), _threadId(0), _pc(0),
289 translateDelta(0), accessDelta(0), depth(0)
290 {}
291
292 /**
293 * Constructor for physical (e.g. device) requests. Initializes
294 * just physical address, size, flags, and timestamp (to curTick()).
271 * These fields are adequate to perform a request.
295 * These fields are adequate to perform a request.
272 */
296 */
273 Request(Addr paddr, int size, Flags flags, MasterID mid)
297 Request(Addr paddr, unsigned size, Flags flags, MasterID mid)
274 : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
275 _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
276 _extraData(0), _contextId(0), _threadId(0), _pc(0),
277 translateDelta(0), accessDelta(0), depth(0)
278 {
298 : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
299 _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
300 _extraData(0), _contextId(0), _threadId(0), _pc(0),
301 translateDelta(0), accessDelta(0), depth(0)
302 {
279 setPhys(paddr, size, flags, mid);
303 setPhys(paddr, size, flags, mid, curTick());
280 }
281
304 }
305
282 Request(Addr paddr, int size, Flags flags, MasterID mid, Tick time)
306 Request(Addr paddr, unsigned size, Flags flags, MasterID mid, Tick time)
283 : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
284 _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
285 _extraData(0), _contextId(0), _threadId(0), _pc(0),
286 translateDelta(0), accessDelta(0), depth(0)
287 {
288 setPhys(paddr, size, flags, mid, time);
289 }
290
307 : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
308 _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
309 _extraData(0), _contextId(0), _threadId(0), _pc(0),
310 translateDelta(0), accessDelta(0), depth(0)
311 {
312 setPhys(paddr, size, flags, mid, time);
313 }
314
291 Request(Addr paddr, int size, Flags flags, MasterID mid, Tick time, Addr pc)
315 Request(Addr paddr, unsigned size, Flags flags, MasterID mid, Tick time,
316 Addr pc)
292 : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
293 _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
294 _extraData(0), _contextId(0), _threadId(0), _pc(0),
295 translateDelta(0), accessDelta(0), depth(0)
296 {
297 setPhys(paddr, size, flags, mid, time);
298 privateFlags.set(VALID_PC);
299 _pc = pc;
300 }
301
317 : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
318 _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
319 _extraData(0), _contextId(0), _threadId(0), _pc(0),
320 translateDelta(0), accessDelta(0), depth(0)
321 {
322 setPhys(paddr, size, flags, mid, time);
323 privateFlags.set(VALID_PC);
324 _pc = pc;
325 }
326
302 Request(int asid, Addr vaddr, int size, Flags flags, MasterID mid, Addr pc,
327 Request(int asid, Addr vaddr, unsigned size, Flags flags, MasterID mid,
328 Addr pc,
303 int cid, ThreadID tid)
304 : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
305 _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
306 _extraData(0), _contextId(0), _threadId(0), _pc(0),
307 translateDelta(0), accessDelta(0), depth(0)
308 {
309 setVirt(asid, vaddr, size, flags, mid, pc);
310 setThreadContext(cid, tid);
311 }
312
313 ~Request() {}
314
315 /**
316 * Set up CPU and thread numbers.
317 */
318 void
319 setThreadContext(int context_id, ThreadID tid)
320 {
321 _contextId = context_id;
322 _threadId = tid;
323 privateFlags.set(VALID_CONTEXT_ID|VALID_THREAD_ID);
324 }
325
326 /**
329 int cid, ThreadID tid)
330 : _paddr(0), _size(0), _masterId(invldMasterId), _time(0),
331 _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0),
332 _extraData(0), _contextId(0), _threadId(0), _pc(0),
333 translateDelta(0), accessDelta(0), depth(0)
334 {
335 setVirt(asid, vaddr, size, flags, mid, pc);
336 setThreadContext(cid, tid);
337 }
338
339 ~Request() {}
340
341 /**
342 * Set up CPU and thread numbers.
343 */
344 void
345 setThreadContext(int context_id, ThreadID tid)
346 {
347 _contextId = context_id;
348 _threadId = tid;
349 privateFlags.set(VALID_CONTEXT_ID|VALID_THREAD_ID);
350 }
351
352 /**
327 * Set up a physical (e.g. device) request in a previously
328 * allocated Request object.
329 */
330 void
331 setPhys(Addr paddr, int size, Flags flags, MasterID mid, Tick time)
332 {
333 assert(size >= 0);
334 _paddr = paddr;
335 _size = size;
336 _time = time;
337 _masterId = mid;
338 _flags.clear(~STICKY_FLAGS);
339 _flags.set(flags);
340 privateFlags.clear(~STICKY_PRIVATE_FLAGS);
341 privateFlags.set(VALID_PADDR|VALID_SIZE);
342 depth = 0;
343 accessDelta = 0;
344 //translateDelta = 0;
345 }
346
347 void
348 setPhys(Addr paddr, int size, Flags flags, MasterID mid)
349 {
350 setPhys(paddr, size, flags, mid, curTick());
351 }
352
353 /**
354 * Set up a virtual (e.g., CPU) request in a previously
355 * allocated Request object.
356 */
357 void
353 * Set up a virtual (e.g., CPU) request in a previously
354 * allocated Request object.
355 */
356 void
358 setVirt(int asid, Addr vaddr, int size, Flags flags, MasterID mid, Addr pc)
357 setVirt(int asid, Addr vaddr, unsigned size, Flags flags, MasterID mid,
358 Addr pc)
359 {
360 assert(size >= 0);
361 _asid = asid;
362 _vaddr = vaddr;
363 _size = size;
364 _masterId = mid;
365 _pc = pc;
366 _time = curTick();
367
368 _flags.clear(~STICKY_FLAGS);
369 _flags.set(flags);
370 privateFlags.clear(~STICKY_PRIVATE_FLAGS);
371 privateFlags.set(VALID_VADDR|VALID_SIZE|VALID_PC);
372 depth = 0;
373 accessDelta = 0;
374 translateDelta = 0;
375 }
376
377 /**
378 * Set just the physical address. This usually used to record the
379 * result of a translation. However, when using virtualized CPUs
380 * setPhys() is sometimes called to finalize a physical address
381 * without a virtual address, so we can't check if the virtual
382 * address is valid.
383 */
384 void
385 setPaddr(Addr paddr)
386 {
387 _paddr = paddr;
388 privateFlags.set(VALID_PADDR);
389 }
390
391 /**
392 * Generate two requests as if this request had been split into two
393 * pieces. The original request can't have been translated already.
394 */
395 void splitOnVaddr(Addr split_addr, RequestPtr &req1, RequestPtr &req2)
396 {
397 assert(privateFlags.isSet(VALID_VADDR));
398 assert(privateFlags.noneSet(VALID_PADDR));
399 assert(split_addr > _vaddr && split_addr < _vaddr + _size);
359 {
360 assert(size >= 0);
361 _asid = asid;
362 _vaddr = vaddr;
363 _size = size;
364 _masterId = mid;
365 _pc = pc;
366 _time = curTick();
367
368 _flags.clear(~STICKY_FLAGS);
369 _flags.set(flags);
370 privateFlags.clear(~STICKY_PRIVATE_FLAGS);
371 privateFlags.set(VALID_VADDR|VALID_SIZE|VALID_PC);
372 depth = 0;
373 accessDelta = 0;
374 translateDelta = 0;
375 }
376
377 /**
378 * Set just the physical address. This usually used to record the
379 * result of a translation. However, when using virtualized CPUs
380 * setPhys() is sometimes called to finalize a physical address
381 * without a virtual address, so we can't check if the virtual
382 * address is valid.
383 */
384 void
385 setPaddr(Addr paddr)
386 {
387 _paddr = paddr;
388 privateFlags.set(VALID_PADDR);
389 }
390
391 /**
392 * Generate two requests as if this request had been split into two
393 * pieces. The original request can't have been translated already.
394 */
395 void splitOnVaddr(Addr split_addr, RequestPtr &req1, RequestPtr &req2)
396 {
397 assert(privateFlags.isSet(VALID_VADDR));
398 assert(privateFlags.noneSet(VALID_PADDR));
399 assert(split_addr > _vaddr && split_addr < _vaddr + _size);
400 req1 = new Request;
401 *req1 = *this;
402 req2 = new Request;
403 *req2 = *this;
400 req1 = new Request(*this);
401 req2 = new Request(*this);
404 req1->_size = split_addr - _vaddr;
405 req2->_vaddr = split_addr;
406 req2->_size = _size - req1->_size;
407 }
408
409 /**
410 * Accessor for paddr.
411 */
412 bool
413 hasPaddr() const
414 {
415 return privateFlags.isSet(VALID_PADDR);
416 }
417
418 Addr
419 getPaddr() const
420 {
421 assert(privateFlags.isSet(VALID_PADDR));
422 return _paddr;
423 }
424
425 /**
426 * Time for the TLB/table walker to successfully translate this request.
427 */
428 Tick translateDelta;
429
430 /**
431 * Access latency to complete this memory transaction not including
432 * translation time.
433 */
434 Tick accessDelta;
435
436 /**
437 * Level of the cache hierachy where this request was responded to
438 * (e.g. 0 = L1; 1 = L2).
439 */
440 mutable int depth;
441
442 /**
443 * Accessor for size.
444 */
445 bool
446 hasSize() const
447 {
448 return privateFlags.isSet(VALID_SIZE);
449 }
450
451 int
452 getSize() const
453 {
454 assert(privateFlags.isSet(VALID_SIZE));
455 return _size;
456 }
457
458 /** Accessor for time. */
459 Tick
460 time() const
461 {
462 assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
463 return _time;
464 }
465
466 void
467 time(Tick time)
468 {
469 assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
470 _time = time;
471 }
472
473 /** Accessor for flags. */
474 Flags
475 getFlags()
476 {
477 assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
478 return _flags;
479 }
480
481 /** Note that unlike other accessors, this function sets *specific
482 flags* (ORs them in); it does not assign its argument to the
483 _flags field. Thus this method should rightly be called
484 setFlags() and not just flags(). */
485 void
486 setFlags(Flags flags)
487 {
488 assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
489 _flags.set(flags);
490 }
491
492 void
493 setArchFlags(Flags flags)
494 {
495 assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
496 _flags.set(flags & ARCH_BITS);
497 }
498
499 /** Accessor function for vaddr.*/
500 bool
501 hasVaddr() const
502 {
503 return privateFlags.isSet(VALID_VADDR);
504 }
505
506 Addr
507 getVaddr() const
508 {
509 assert(privateFlags.isSet(VALID_VADDR));
510 return _vaddr;
511 }
512
513 /** Accesssor for the requestor id. */
514 MasterID
515 masterId() const
516 {
517 return _masterId;
518 }
519
520 uint32_t
521 taskId() const
522 {
523 return _taskId;
524 }
525
526 void
527 taskId(uint32_t id) {
528 _taskId = id;
529 }
530
531 /** Accessor function for asid.*/
532 int
533 getAsid() const
534 {
535 assert(privateFlags.isSet(VALID_VADDR));
536 return _asid;
537 }
538
539 /** Accessor function for asid.*/
540 void
541 setAsid(int asid)
542 {
543 _asid = asid;
544 }
545
546 /** Accessor function for architecture-specific flags.*/
547 ArchFlagsType
548 getArchFlags() const
549 {
550 assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
551 return _flags & ARCH_BITS;
552 }
553
554 /** Accessor function to check if sc result is valid. */
555 bool
556 extraDataValid() const
557 {
558 return privateFlags.isSet(VALID_EXTRA_DATA);
559 }
560
561 /** Accessor function for store conditional return value.*/
562 uint64_t
563 getExtraData() const
564 {
565 assert(privateFlags.isSet(VALID_EXTRA_DATA));
566 return _extraData;
567 }
568
569 /** Accessor function for store conditional return value.*/
570 void
571 setExtraData(uint64_t extraData)
572 {
573 _extraData = extraData;
574 privateFlags.set(VALID_EXTRA_DATA);
575 }
576
577 bool
578 hasContextId() const
579 {
580 return privateFlags.isSet(VALID_CONTEXT_ID);
581 }
582
583 /** Accessor function for context ID.*/
584 int
585 contextId() const
586 {
587 assert(privateFlags.isSet(VALID_CONTEXT_ID));
588 return _contextId;
589 }
590
591 /** Accessor function for thread ID. */
592 int
593 threadId() const
594 {
595 assert(privateFlags.isSet(VALID_THREAD_ID));
596 return _threadId;
597 }
598
599 void
600 setPC(Addr pc)
601 {
602 privateFlags.set(VALID_PC);
603 _pc = pc;
604 }
605
606 bool
607 hasPC() const
608 {
609 return privateFlags.isSet(VALID_PC);
610 }
611
612 /** Accessor function for pc.*/
613 Addr
614 getPC() const
615 {
616 assert(privateFlags.isSet(VALID_PC));
617 return _pc;
618 }
619
620 /**
621 * Increment/Get the depth at which this request is responded to.
622 * This currently happens when the request misses in any cache level.
623 */
624 void incAccessDepth() const { depth++; }
625 int getAccessDepth() const { return depth; }
626
627 /**
628 * Set/Get the time taken for this request to be successfully translated.
629 */
630 void setTranslateLatency() { translateDelta = curTick() - _time; }
631 Tick getTranslateLatency() const { return translateDelta; }
632
633 /**
634 * Set/Get the time taken to complete this request's access, not including
635 * the time to successfully translate the request.
636 */
637 void setAccessLatency() { accessDelta = curTick() - _time - translateDelta; }
638 Tick getAccessLatency() const { return accessDelta; }
639
640 /** Accessor functions for flags. Note that these are for testing
641 only; setting flags should be done via setFlags(). */
642 bool isUncacheable() const { return _flags.isSet(UNCACHEABLE); }
643 bool isInstFetch() const { return _flags.isSet(INST_FETCH); }
644 bool isPrefetch() const { return _flags.isSet(PREFETCH); }
645 bool isLLSC() const { return _flags.isSet(LLSC); }
646 bool isPriv() const { return _flags.isSet(PRIVILEGED); }
647 bool isLocked() const { return _flags.isSet(LOCKED); }
648 bool isSwap() const { return _flags.isSet(MEM_SWAP|MEM_SWAP_COND); }
649 bool isCondSwap() const { return _flags.isSet(MEM_SWAP_COND); }
650 bool isMmappedIpr() const { return _flags.isSet(MMAPPED_IPR); }
651 bool isClearLL() const { return _flags.isSet(CLEAR_LL); }
652 bool isSecure() const { return _flags.isSet(SECURE); }
653 bool isPTWalk() const { return _flags.isSet(PT_WALK); }
654};
655
656#endif // __MEM_REQUEST_HH__
402 req1->_size = split_addr - _vaddr;
403 req2->_vaddr = split_addr;
404 req2->_size = _size - req1->_size;
405 }
406
407 /**
408 * Accessor for paddr.
409 */
410 bool
411 hasPaddr() const
412 {
413 return privateFlags.isSet(VALID_PADDR);
414 }
415
416 Addr
417 getPaddr() const
418 {
419 assert(privateFlags.isSet(VALID_PADDR));
420 return _paddr;
421 }
422
423 /**
424 * Time for the TLB/table walker to successfully translate this request.
425 */
426 Tick translateDelta;
427
428 /**
429 * Access latency to complete this memory transaction not including
430 * translation time.
431 */
432 Tick accessDelta;
433
434 /**
435 * Level of the cache hierachy where this request was responded to
436 * (e.g. 0 = L1; 1 = L2).
437 */
438 mutable int depth;
439
440 /**
441 * Accessor for size.
442 */
443 bool
444 hasSize() const
445 {
446 return privateFlags.isSet(VALID_SIZE);
447 }
448
449 int
450 getSize() const
451 {
452 assert(privateFlags.isSet(VALID_SIZE));
453 return _size;
454 }
455
456 /** Accessor for time. */
457 Tick
458 time() const
459 {
460 assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
461 return _time;
462 }
463
464 void
465 time(Tick time)
466 {
467 assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
468 _time = time;
469 }
470
471 /** Accessor for flags. */
472 Flags
473 getFlags()
474 {
475 assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
476 return _flags;
477 }
478
479 /** Note that unlike other accessors, this function sets *specific
480 flags* (ORs them in); it does not assign its argument to the
481 _flags field. Thus this method should rightly be called
482 setFlags() and not just flags(). */
483 void
484 setFlags(Flags flags)
485 {
486 assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
487 _flags.set(flags);
488 }
489
490 void
491 setArchFlags(Flags flags)
492 {
493 assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
494 _flags.set(flags & ARCH_BITS);
495 }
496
497 /** Accessor function for vaddr.*/
498 bool
499 hasVaddr() const
500 {
501 return privateFlags.isSet(VALID_VADDR);
502 }
503
504 Addr
505 getVaddr() const
506 {
507 assert(privateFlags.isSet(VALID_VADDR));
508 return _vaddr;
509 }
510
511 /** Accesssor for the requestor id. */
512 MasterID
513 masterId() const
514 {
515 return _masterId;
516 }
517
518 uint32_t
519 taskId() const
520 {
521 return _taskId;
522 }
523
524 void
525 taskId(uint32_t id) {
526 _taskId = id;
527 }
528
529 /** Accessor function for asid.*/
530 int
531 getAsid() const
532 {
533 assert(privateFlags.isSet(VALID_VADDR));
534 return _asid;
535 }
536
537 /** Accessor function for asid.*/
538 void
539 setAsid(int asid)
540 {
541 _asid = asid;
542 }
543
544 /** Accessor function for architecture-specific flags.*/
545 ArchFlagsType
546 getArchFlags() const
547 {
548 assert(privateFlags.isSet(VALID_PADDR|VALID_VADDR));
549 return _flags & ARCH_BITS;
550 }
551
552 /** Accessor function to check if sc result is valid. */
553 bool
554 extraDataValid() const
555 {
556 return privateFlags.isSet(VALID_EXTRA_DATA);
557 }
558
559 /** Accessor function for store conditional return value.*/
560 uint64_t
561 getExtraData() const
562 {
563 assert(privateFlags.isSet(VALID_EXTRA_DATA));
564 return _extraData;
565 }
566
567 /** Accessor function for store conditional return value.*/
568 void
569 setExtraData(uint64_t extraData)
570 {
571 _extraData = extraData;
572 privateFlags.set(VALID_EXTRA_DATA);
573 }
574
575 bool
576 hasContextId() const
577 {
578 return privateFlags.isSet(VALID_CONTEXT_ID);
579 }
580
581 /** Accessor function for context ID.*/
582 int
583 contextId() const
584 {
585 assert(privateFlags.isSet(VALID_CONTEXT_ID));
586 return _contextId;
587 }
588
589 /** Accessor function for thread ID. */
590 int
591 threadId() const
592 {
593 assert(privateFlags.isSet(VALID_THREAD_ID));
594 return _threadId;
595 }
596
597 void
598 setPC(Addr pc)
599 {
600 privateFlags.set(VALID_PC);
601 _pc = pc;
602 }
603
604 bool
605 hasPC() const
606 {
607 return privateFlags.isSet(VALID_PC);
608 }
609
610 /** Accessor function for pc.*/
611 Addr
612 getPC() const
613 {
614 assert(privateFlags.isSet(VALID_PC));
615 return _pc;
616 }
617
618 /**
619 * Increment/Get the depth at which this request is responded to.
620 * This currently happens when the request misses in any cache level.
621 */
622 void incAccessDepth() const { depth++; }
623 int getAccessDepth() const { return depth; }
624
625 /**
626 * Set/Get the time taken for this request to be successfully translated.
627 */
628 void setTranslateLatency() { translateDelta = curTick() - _time; }
629 Tick getTranslateLatency() const { return translateDelta; }
630
631 /**
632 * Set/Get the time taken to complete this request's access, not including
633 * the time to successfully translate the request.
634 */
635 void setAccessLatency() { accessDelta = curTick() - _time - translateDelta; }
636 Tick getAccessLatency() const { return accessDelta; }
637
638 /** Accessor functions for flags. Note that these are for testing
639 only; setting flags should be done via setFlags(). */
640 bool isUncacheable() const { return _flags.isSet(UNCACHEABLE); }
641 bool isInstFetch() const { return _flags.isSet(INST_FETCH); }
642 bool isPrefetch() const { return _flags.isSet(PREFETCH); }
643 bool isLLSC() const { return _flags.isSet(LLSC); }
644 bool isPriv() const { return _flags.isSet(PRIVILEGED); }
645 bool isLocked() const { return _flags.isSet(LOCKED); }
646 bool isSwap() const { return _flags.isSet(MEM_SWAP|MEM_SWAP_COND); }
647 bool isCondSwap() const { return _flags.isSet(MEM_SWAP_COND); }
648 bool isMmappedIpr() const { return _flags.isSet(MMAPPED_IPR); }
649 bool isClearLL() const { return _flags.isSet(CLEAR_LL); }
650 bool isSecure() const { return _flags.isSet(SECURE); }
651 bool isPTWalk() const { return _flags.isSet(PT_WALK); }
652};
653
654#endif // __MEM_REQUEST_HH__