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