generic_timer.hh revision 10037:5cac77888310
1/*
2 * Copyright (c) 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 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Giacomo Gabrielli
38 */
39
40#ifndef __DEV_ARM_GENERIC_TIMER_HH__
41#define __DEV_ARM_GENERIC_TIMER_HH__
42
43#include "base/bitunion.hh"
44#include "params/GenericTimer.hh"
45#include "sim/core.hh"
46#include "sim/sim_object.hh"
47
48/// @file
49/// This module implements the global system counter and the local per-CPU
50/// architected timers as specified by the ARM Generic Timer extension (ARM
51/// ARM, Issue C, Chapter 17).
52
53class Checkpoint;
54class BaseGic;
55
56/// Wrapper around the actual counters and timers of the Generic Timer
57/// extension.
58class GenericTimer : public SimObject
59{
60  public:
61
62    /// Global system counter.  It is shared by the architected timers.
63    /// @todo: implement memory-mapped controls
64    class SystemCounter
65    {
66      protected:
67        /// Counter frequency (as specified by CNTFRQ).
68        uint64_t _freq;
69        /// Cached copy of the counter period (inverse of the frequency).
70        Tick _period;
71        /// Tick when the counter was reset.
72        Tick _resetTick;
73
74      public:
75        /// Ctor.
76        SystemCounter()
77            : _freq(0), _period(0), _resetTick(0)
78        {
79            setFreq(0x01800000);
80        }
81
82        /// Returns the current value of the physical counter.
83        uint64_t value() const
84        {
85            if (_freq == 0)
86                return 0;  // Counter is still off.
87            return (curTick() - _resetTick) / _period;
88        }
89
90        /// Returns the counter frequency.
91        uint64_t freq() const { return _freq; }
92        /// Sets the counter frequency.
93        /// @param freq frequency in Hz.
94        void setFreq(uint32_t freq);
95
96        /// Returns the counter period.
97        Tick period() const { return _period; }
98
99        void serialize(std::ostream &os);
100        void unserialize(Checkpoint *cp, const std::string &section);
101    };
102
103    /// Per-CPU architected timer.
104    class ArchTimer
105    {
106      protected:
107        /// Control register.
108        BitUnion32(ArchTimerCtrl)
109            Bitfield<0> enable;
110            Bitfield<1> imask;
111            Bitfield<2> istatus;
112        EndBitUnion(ArchTimerCtrl)
113
114        /// Name of this timer.
115        std::string _name;
116        /// Pointer to parent class.
117        GenericTimer *_parent;
118        /// Pointer to the global system counter.
119        SystemCounter *_counter;
120        /// ID of the CPU this timer is attached to.
121        int _cpuNum;
122        /// ID of the interrupt to be triggered.
123        int _intNum;
124        /// Cached value of the control register ({CNTP/CNTHP/CNTV}_CTL).
125        ArchTimerCtrl _control;
126        /// Programmed limit value for the upcounter ({CNTP/CNTHP/CNTV}_CVAL).
127        uint64_t _counterLimit;
128
129        /// Called when the upcounter reaches the programmed value.
130        void counterLimitReached();
131        EventWrapper<ArchTimer, &ArchTimer::counterLimitReached>
132            _counterLimitReachedEvent;
133
134        /// Returns the value of the counter which this timer relies on.
135        uint64_t counterValue() const { return _counter->value(); }
136
137      public:
138        /// Ctor.
139        ArchTimer()
140            : _control(0), _counterLimit(0), _counterLimitReachedEvent(this)
141        {}
142
143        /// Returns the timer name.
144        std::string name() const { return _name; }
145
146        /// Returns the CompareValue view of the timer.
147        uint64_t compareValue() const { return _counterLimit; }
148        /// Sets the CompareValue view of the timer.
149        void setCompareValue(uint64_t val);
150
151        /// Returns the TimerValue view of the timer.
152        uint32_t timerValue() const { return _counterLimit - counterValue(); }
153        /// Sets the TimerValue view of the timer.
154        void setTimerValue(uint32_t val);
155
156        /// Sets the control register.
157        uint32_t control() const { return _control; }
158        void setControl(uint32_t val);
159
160        virtual void serialize(std::ostream &os);
161        virtual void unserialize(Checkpoint *cp, const std::string &section);
162
163        friend class GenericTimer;
164    };
165
166  protected:
167
168    static const int CPU_MAX = 8;
169
170    /// Pointer to the GIC, needed to trigger timer interrupts.
171    BaseGic *_gic;
172    /// System counter.
173    SystemCounter _systemCounter;
174    /// Per-CPU architected timers.
175    // @todo: this would become a 2-dim. array with Security and Virt.
176    ArchTimer _archTimers[CPU_MAX];
177
178  public:
179    typedef GenericTimerParams Params;
180    const Params *
181    params() const
182    {
183        return dynamic_cast<const Params *>(_params);
184    }
185
186    /// Ctor.
187    GenericTimer(Params *p);
188
189    /// Returns a pointer to the system counter.
190    SystemCounter *getSystemCounter() { return &_systemCounter; }
191
192    /// Returns a pointer to the architected timer for cpu_id.
193    ArchTimer *getArchTimer(int cpu_id) { return &_archTimers[cpu_id]; }
194
195    virtual void serialize(std::ostream &os);
196    virtual void unserialize(Checkpoint *cp, const std::string &section);
197};
198
199#endif // __DEV_ARM_GENERIC_TIMER_HH__
200