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
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 /**
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;
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.)
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.
296 */
273 Request(Addr paddr, int size, Flags flags, MasterID mid)
297 Request(Addr paddr, unsigned size, Flags flags, MasterID mid)
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());
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)
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)
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,
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 /**
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);
400 req1 = new Request;
401 *req1 = *this;
402 req2 = new Request;
403 *req2 = *this;
400 req1 = new Request(*this);
401 req2 = new Request(*this);
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__