2 * Copyright (c) 2013 ARM Limited
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.
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.
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.
37 * Authors: Giacomo Gabrielli
40 #include "arch/arm/system.hh"
41 #include "debug/Checkpoint.hh"
42 #include "debug/Timer.hh"
43 #include "dev/arm/base_gic.hh"
44 #include "dev/arm/generic_timer.hh"
47 GenericTimer::SystemCounter::setFreq(uint32_t freq
)
50 // Altering the frequency after boot shouldn't be done in practice.
51 warn_once("The frequency of the system counter has already been set");
54 _period
= (1.0 / freq
) * SimClock::Frequency
;
55 _resetTick
= curTick();
59 GenericTimer::SystemCounter::serialize(std::ostream
&os
)
61 SERIALIZE_SCALAR(_freq
);
62 SERIALIZE_SCALAR(_period
);
63 SERIALIZE_SCALAR(_resetTick
);
67 GenericTimer::SystemCounter::unserialize(Checkpoint
*cp
,
68 const std::string
§ion
)
70 UNSERIALIZE_SCALAR(_freq
);
71 UNSERIALIZE_SCALAR(_period
);
72 UNSERIALIZE_SCALAR(_resetTick
);
76 GenericTimer::ArchTimer::counterLimitReached()
83 // DPRINTF(Timer, "Counter limit reached\n");
85 if (!_control
.imask
) {
86 // DPRINTF(Timer, "Causing interrupt\n");
87 _parent
->_gic
->sendPPInt(_intNum
, _cpuNum
);
92 GenericTimer::ArchTimer::setCompareValue(uint64_t val
)
95 if (_counterLimitReachedEvent
.scheduled())
96 _parent
->deschedule(_counterLimitReachedEvent
);
97 if (counterValue() >= _counterLimit
) {
98 counterLimitReached();
100 _control
.istatus
= 0;
101 _parent
->schedule(_counterLimitReachedEvent
,
102 curTick() + (_counterLimit
- counterValue()) * _counter
->period());
107 GenericTimer::ArchTimer::setTimerValue(uint32_t val
)
109 setCompareValue(counterValue() + sext
<32>(val
));
113 GenericTimer::ArchTimer::setControl(uint32_t val
)
115 ArchTimerCtrl new_ctl
= val
;
116 if ((new_ctl
.enable
&& !new_ctl
.imask
) &&
117 !(_control
.enable
&& !_control
.imask
)) {
118 // Re-evalute the timer condition
119 if (_counterLimit
>= counterValue()) {
120 _control
.istatus
= 1;
122 DPRINTF(Timer
, "Causing interrupt in control\n");
123 //_parent->_gic->sendPPInt(_intNum, _cpuNum);
126 _control
.enable
= new_ctl
.enable
;
127 _control
.imask
= new_ctl
.imask
;
131 GenericTimer::ArchTimer::serialize(std::ostream
&os
)
133 SERIALIZE_SCALAR(_cpuNum
);
134 SERIALIZE_SCALAR(_intNum
);
135 uint32_t control_serial
= _control
;
136 SERIALIZE_SCALAR(control_serial
);
137 SERIALIZE_SCALAR(_counterLimit
);
138 bool event_scheduled
= _counterLimitReachedEvent
.scheduled();
139 SERIALIZE_SCALAR(event_scheduled
);
141 if (event_scheduled
) {
142 event_time
= _counterLimitReachedEvent
.when();
143 SERIALIZE_SCALAR(event_time
);
148 GenericTimer::ArchTimer::unserialize(Checkpoint
*cp
, const std::string
§ion
)
150 UNSERIALIZE_SCALAR(_cpuNum
);
151 UNSERIALIZE_SCALAR(_intNum
);
152 uint32_t control_serial
;
153 UNSERIALIZE_SCALAR(control_serial
);
154 _control
= control_serial
;
155 bool event_scheduled
;
156 UNSERIALIZE_SCALAR(event_scheduled
);
158 if (event_scheduled
) {
159 UNSERIALIZE_SCALAR(event_time
);
160 _parent
->schedule(_counterLimitReachedEvent
, event_time
);
164 GenericTimer::GenericTimer(Params
*p
)
165 : SimObject(p
), _gic(p
->gic
)
167 for (int i
= 0; i
< CPU_MAX
; ++i
) {
168 std::stringstream oss
;
169 oss
<< name() << ".arch_timer" << i
;
170 _archTimers
[i
]._name
= oss
.str();
171 _archTimers
[i
]._parent
= this;
172 _archTimers
[i
]._counter
= &_systemCounter
;
173 _archTimers
[i
]._cpuNum
= i
;
174 _archTimers
[i
]._intNum
= p
->int_num
;
177 ((ArmSystem
*) p
->system
)->setGenericTimer(this);
181 GenericTimer::serialize(std::ostream
&os
)
183 nameOut(os
, csprintf("%s.sys_counter", name()));
184 _systemCounter
.serialize(os
);
185 for (int i
= 0; i
< CPU_MAX
; ++i
) {
186 nameOut(os
, csprintf("%s.arch_timer%d", name(), i
));
187 _archTimers
[i
].serialize(os
);
192 GenericTimer::unserialize(Checkpoint
*cp
, const std::string
§ion
)
194 _systemCounter
.unserialize(cp
, csprintf("%s.sys_counter", section
));
195 for (int i
= 0; i
< CPU_MAX
; ++i
) {
196 _archTimers
[i
].unserialize(cp
, csprintf("%s.arch_timer%d", section
, i
));
201 GenericTimerParams::create()
203 return new GenericTimer(this);