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