gem5  v20.1.0.0
generic_timer.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, 2015, 2017-2018,2020 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 
38 #include "dev/arm/generic_timer.hh"
39 
40 #include <cmath>
41 
42 #include "arch/arm/system.hh"
43 #include "arch/arm/utility.hh"
44 #include "cpu/base.hh"
45 #include "debug/Timer.hh"
46 #include "dev/arm/base_gic.hh"
47 #include "mem/packet_access.hh"
48 #include "params/GenericTimer.hh"
49 #include "params/GenericTimerFrame.hh"
50 #include "params/GenericTimerMem.hh"
51 #include "params/SystemCounter.hh"
52 
53 using namespace ArmISA;
54 
55 SystemCounter::SystemCounter(SystemCounterParams *const p)
56  : SimObject(p),
57  _enabled(true),
58  _value(0),
59  _increment(1),
60  _freqTable(p->freqs),
61  _activeFreqEntry(0),
62  _updateTick(0),
63  _freqUpdateEvent([this]{ freqUpdateCallback(); }, name()),
64  _nextFreqEntry(0)
65 {
66  fatal_if(_freqTable.empty(), "SystemCounter::SystemCounter: Base "
67  "frequency not provided\n");
68  // Store the table end marker as a 32-bit zero word
69  _freqTable.push_back(0);
71  "SystemCounter::SystemCounter: Architecture states a maximum of 1004 "
72  "frequency table entries, limit surpassed\n");
73  // Set the active frequency to be the base
74  _freq = _freqTable.front();
75  _period = (1.0 / _freq) * SimClock::Frequency;
76 }
77 
78 void
80 {
81  fatal_if(!sys_cnt, "SystemCounter::validateCounterRef: No valid system "
82  "counter, can't instantiate system timers\n");
83 }
84 
85 void
87 {
88  DPRINTF(Timer, "SystemCounter::enable: Counter enabled\n");
89  _enabled = true;
90  updateTick();
91 }
92 
93 void
95 {
96  DPRINTF(Timer, "SystemCounter::disable: Counter disabled\n");
97  updateValue();
98  _enabled = false;
99 }
100 
101 uint64_t
103 {
104  if (_enabled)
105  updateValue();
106  return _value;
107 }
108 
109 void
111 {
112  uint64_t new_value =
114  if (new_value > _value) {
115  _value = new_value;
116  updateTick();
117  }
118 }
119 
120 void
121 SystemCounter::setValue(uint64_t new_value)
122 {
123  if (_enabled)
124  warn("Explicit value set with counter enabled, UNKNOWNN result\n");
125  _value = new_value;
126  updateTick();
127  notifyListeners();
128 }
129 
130 Tick
131 SystemCounter::whenValue(uint64_t cur_val, uint64_t target_val) const
132 {
133  Tick when = curTick();
134  if (target_val > cur_val) {
135  uint64_t num_cycles =
136  std::ceil((target_val - cur_val) / ((double) _increment));
137  // Take into account current cycle remaining ticks
138  Tick rem_ticks = _period - (curTick() % _period);
139  if (rem_ticks < _period) {
140  when += rem_ticks;
141  num_cycles -= 1;
142  }
143  when += num_cycles * _period;
144  }
145  return when;
146 }
147 
148 Tick
149 SystemCounter::whenValue(uint64_t target_val)
150 {
151  return whenValue(value(), target_val);
152 }
153 
154 void
156 {
157  _updateTick = curTick() - (curTick() % _period);
158 }
159 
160 void
161 SystemCounter::freqUpdateSchedule(size_t new_freq_entry)
162 {
163  if (new_freq_entry < _freqTable.size()) {
164  auto &new_freq = _freqTable[new_freq_entry];
165  if (new_freq != _freq) {
166  _nextFreqEntry = new_freq_entry;
167  // Wait until the value for which the lowest frequency increment
168  // is a exact divisor. This covers both high to low and low to
169  // high transitions
170  uint64_t new_incr = _freqTable[0] / new_freq;
171  uint64_t target_val = value();
172  target_val += target_val % std::max(_increment, new_incr);
173  reschedule(_freqUpdateEvent, whenValue(target_val), true);
174  }
175  }
176 }
177 
178 void
180 {
181  DPRINTF(Timer, "SystemCounter::freqUpdateCallback: Changing counter "
182  "frequency\n");
183  if (_enabled)
184  updateValue();
187  _increment = _freqTable[0] / _freq;
188  _period = (1.0 / _freq) * SimClock::Frequency;
189  notifyListeners();
190 }
191 
192 void
194 {
195  _listeners.push_back(listener);
196 }
197 
198 void
200 {
201  for (auto &listener : _listeners)
202  listener->notify();
203 }
204 
205 void
207 {
208  DPRINTF(Timer, "SystemCounter::serialize: Serializing\n");
216  bool pending_freq_update = _freqUpdateEvent.scheduled();
217  SERIALIZE_SCALAR(pending_freq_update);
218  if (pending_freq_update) {
219  Tick when_freq_update = _freqUpdateEvent.when();
220  SERIALIZE_SCALAR(when_freq_update);
221  }
223 }
224 
225 void
227 {
228  DPRINTF(Timer, "SystemCounter::unserialize: Unserializing\n");
236  bool pending_freq_update;
237  UNSERIALIZE_SCALAR(pending_freq_update);
238  if (pending_freq_update) {
239  Tick when_freq_update;
240  UNSERIALIZE_SCALAR(when_freq_update);
241  reschedule(_freqUpdateEvent, when_freq_update, true);
242  }
244 
245  _period = (1.0 / _freq) * SimClock::Frequency;
246 }
247 
248 ArchTimer::ArchTimer(const std::string &name,
249  SimObject &parent,
250  SystemCounter &sysctr,
251  ArmInterruptPin *interrupt)
252  : _name(name), _parent(parent), _systemCounter(sysctr),
253  _interrupt(interrupt),
254  _control(0), _counterLimit(0), _offset(0),
255  _counterLimitReachedEvent([this]{ counterLimitReached(); }, name)
256 {
257  _systemCounter.registerListener(this);
258 }
259 
260 void
262 {
263  if (!_control.enable)
264  return;
265 
266  DPRINTF(Timer, "Counter limit reached\n");
267  _control.istatus = 1;
268  if (!_control.imask) {
269  if (scheduleEvents()) {
270  DPRINTF(Timer, "Causing interrupt\n");
271  _interrupt->raise();
272  } else {
273  DPRINTF(Timer, "Kvm mode; skipping simulated interrupt\n");
274  }
275  }
276 }
277 
278 void
280 {
283  if (value() >= _counterLimit) {
285  } else {
286  // Clear the interurpt when timers conditions are not met
287  if (_interrupt->active()) {
288  DPRINTF(Timer, "Clearing interrupt\n");
289  _interrupt->clear();
290  }
291 
292  _control.istatus = 0;
293 
294  if (scheduleEvents()) {
297  }
298  }
299 }
300 
301 void
303 {
304  _counterLimit = val;
305  updateCounter();
306 }
307 
308 void
310 {
311  setCompareValue(value() + sext<32>(val));
312 }
313 
314 void
316 {
317  ArchTimerCtrl old_ctl = _control, new_ctl = val;
318  _control.enable = new_ctl.enable;
319  _control.imask = new_ctl.imask;
320  _control.istatus = old_ctl.istatus;
321  // Timer unmasked or enabled
322  if ((old_ctl.imask && !new_ctl.imask) ||
323  (!old_ctl.enable && new_ctl.enable))
324  updateCounter();
325  // Timer masked or disabled
326  else if ((!old_ctl.imask && new_ctl.imask) ||
327  (old_ctl.enable && !new_ctl.enable)) {
328 
329  if (_interrupt->active()) {
330  DPRINTF(Timer, "Clearing interrupt\n");
331  // We are clearing the interrupt but we are not
332  // setting istatus to 0 as we are doing
333  // in the updateCounter.
334  // istatus signals that Timer conditions are met.
335  // It shouldn't depend on masking.
336  // if enable is zero. istatus is unknown.
337  _interrupt->clear();
338  }
339  }
340 }
341 
342 void
344 {
345  _offset = val;
346  updateCounter();
347 }
348 
349 uint64_t
351 {
352  return _systemCounter.value() - _offset;
353 }
354 
355 void
357 {
358  updateCounter();
359 }
360 
361 void
363 {
364  paramOut(cp, "control_serial", _control);
367 }
368 
369 void
371 {
372  paramIn(cp, "control_serial", _control);
373  // We didn't serialize an offset before we added support for the
374  // virtual timer. Consider it optional to maintain backwards
375  // compatibility.
377  _offset = 0;
378 
379  // We no longer schedule an event here because we may enter KVM
380  // emulation. The event creation is delayed until drainResume().
381 }
382 
385 {
388 
389  return DrainState::Drained;
390 }
391 
392 void
394 {
395  updateCounter();
396 }
397 
398 GenericTimer::GenericTimer(GenericTimerParams *const p)
399  : SimObject(p),
400  systemCounter(*p->counter),
401  system(*p->system)
402 {
404  fatal_if(!p->system, "GenericTimer::GenericTimer: No system specified, "
405  "can't instantiate architected timers\n");
406  system.setGenericTimer(this);
407 }
408 
409 const GenericTimerParams *
411 {
412  return dynamic_cast<const GenericTimerParams *>(_params);
413 }
414 
415 void
417 {
418  paramOut(cp, "cpu_count", timers.size());
419 
420  for (int i = 0; i < timers.size(); ++i) {
421  const CoreTimers &core(*timers[i]);
422  core.serializeSection(cp, csprintf("pe_implementation%d", i));
423  }
424 }
425 
426 void
428 {
429  // Try to unserialize the CPU count. Old versions of the timer
430  // model assumed a 8 CPUs, so we fall back to that if the field
431  // isn't present.
432  static const unsigned OLD_CPU_MAX = 8;
433  unsigned cpu_count;
434  if (!UNSERIALIZE_OPT_SCALAR(cpu_count)) {
435  warn("Checkpoint does not contain CPU count, assuming %i CPUs\n",
436  OLD_CPU_MAX);
437  cpu_count = OLD_CPU_MAX;
438  }
439 
440  // We cannot assert for equality here because CPU timers are dynamically
441  // created on the first miscreg access. Therefore, if we take the checkpoint
442  // before any timer registers have been accessed, the number of counters
443  // is actually smaller than the total number of CPUs.
444  if (cpu_count > system.threads.size()) {
445  fatal("The simulated system has been initialized with %d CPUs, "
446  "but the Generic Timer checkpoint expects %d CPUs. Consider "
447  "restoring the checkpoint specifying %d CPUs.",
448  system.threads.size(), cpu_count, cpu_count);
449  }
450 
451  for (int i = 0; i < cpu_count; ++i) {
452  CoreTimers &core(getTimers(i));
453  core.unserializeSection(cp, csprintf("pe_implementation%d", i));
454  }
455 }
456 
459 {
460  if (cpu_id >= timers.size())
461  createTimers(cpu_id + 1);
462 
463  return *timers[cpu_id];
464 }
465 
466 void
468 {
469  assert(timers.size() < cpus);
470  auto p = static_cast<const GenericTimerParams *>(_params);
471 
472  const unsigned old_cpu_count(timers.size());
473  timers.resize(cpus);
474  for (unsigned i = old_cpu_count; i < cpus; ++i) {
475 
476  ThreadContext *tc = system.threads[i];
477 
478  timers[i].reset(
479  new CoreTimers(*this, system, i,
480  p->int_phys_s->get(tc),
481  p->int_phys_ns->get(tc),
482  p->int_virt->get(tc),
483  p->int_hyp->get(tc)));
484  }
485 }
486 
487 void
489  ArchTimer *timer, RegVal old_cnt_ctl, RegVal cnt_ctl)
490 {
491  uint64_t evnten = bits(cnt_ctl, 2);
492  uint64_t old_evnten = bits(old_cnt_ctl, 2);
493  uint8_t old_trans_to = ev_stream->transitionTo;
494  uint8_t old_trans_bit = ev_stream->transitionBit;
495  ev_stream->transitionTo = !bits(cnt_ctl, 3);
496  ev_stream->transitionBit = bits(cnt_ctl, 7, 4);
497  // Reschedule the Event Stream if enabled and any change in
498  // configuration
499  if (evnten && ((old_evnten != evnten) ||
500  (old_trans_to != ev_stream->transitionTo) ||
501  (old_trans_bit != ev_stream->transitionBit))) {
502 
503  Tick when = timer->whenValue(
504  ev_stream->eventTargetValue(timer->value()));
505  reschedule(ev_stream->event, when, true);
506  } else if (old_evnten && !evnten) {
507  // Event Stream generation disabled
508  if (ev_stream->event.scheduled())
509  deschedule(ev_stream->event);
510  }
511 }
512 
513 void
515 {
516  CoreTimers &core(getTimers(cpu));
517  ThreadContext *tc = system.threads[cpu];
518 
519  switch (reg) {
520  case MISCREG_CNTFRQ:
521  case MISCREG_CNTFRQ_EL0:
522  core.cntfrq = val;
523  warn_if(core.cntfrq != systemCounter.freq(), "CNTFRQ configured freq "
524  "does not match the system counter freq\n");
525  return;
526  case MISCREG_CNTKCTL:
527  case MISCREG_CNTKCTL_EL1:
528  {
529  if (ELIsInHost(tc, currEL(tc))) {
531  return;
532  }
533  RegVal old_cnt_ctl = core.cntkctl;
534  core.cntkctl = val;
535 
536  ArchTimer *timer = &core.virt;
537  CoreTimers::EventStream *ev_stream = &core.virtEvStream;
538 
539  handleStream(ev_stream, timer, old_cnt_ctl, val);
540  return;
541  }
542  case MISCREG_CNTHCTL:
543  case MISCREG_CNTHCTL_EL2:
544  {
545  RegVal old_cnt_ctl = core.cnthctl;
546  core.cnthctl = val;
547 
548  ArchTimer *timer = &core.physNS;
549  CoreTimers::EventStream *ev_stream = &core.physEvStream;
550 
551  handleStream(ev_stream, timer, old_cnt_ctl, val);
552  return;
553  }
554  // Physical timer (NS)
557  core.physNS.setCompareValue(val);
558  return;
559 
562  core.physNS.setTimerValue(val);
563  return;
564 
565  case MISCREG_CNTP_CTL_NS:
567  core.physNS.setControl(val);
568  return;
569 
570  // Count registers
571  case MISCREG_CNTPCT:
572  case MISCREG_CNTPCT_EL0:
573  case MISCREG_CNTVCT:
574  case MISCREG_CNTVCT_EL0:
575  warn("Ignoring write to read only count register: %s\n",
576  miscRegName[reg]);
577  return;
578 
579  // Virtual timer
580  case MISCREG_CNTVOFF:
581  case MISCREG_CNTVOFF_EL2:
582  core.virt.setOffset(val);
583  return;
584 
585  case MISCREG_CNTV_CVAL:
587  core.virt.setCompareValue(val);
588  return;
589 
590  case MISCREG_CNTV_TVAL:
592  core.virt.setTimerValue(val);
593  return;
594 
595  case MISCREG_CNTV_CTL:
597  core.virt.setControl(val);
598  return;
599 
600  // Physical timer (S)
601  case MISCREG_CNTP_CTL_S:
603  core.physS.setControl(val);
604  return;
605 
606  case MISCREG_CNTP_CVAL_S:
608  core.physS.setCompareValue(val);
609  return;
610 
611  case MISCREG_CNTP_TVAL_S:
613  core.physS.setTimerValue(val);
614  return;
615 
616  // Hyp phys. timer, non-secure
617  case MISCREG_CNTHP_CTL:
619  core.hyp.setControl(val);
620  return;
621 
622  case MISCREG_CNTHP_CVAL:
624  core.hyp.setCompareValue(val);
625  return;
626 
627  case MISCREG_CNTHP_TVAL:
629  core.hyp.setTimerValue(val);
630  return;
631 
632  default:
633  warn("Writing to unknown register: %s\n", miscRegName[reg]);
634  return;
635  }
636 }
637 
638 
639 RegVal
640 GenericTimer::readMiscReg(int reg, unsigned cpu)
641 {
642  CoreTimers &core(getTimers(cpu));
643 
644  switch (reg) {
645  case MISCREG_CNTFRQ:
646  case MISCREG_CNTFRQ_EL0:
647  return core.cntfrq;
648  case MISCREG_CNTKCTL:
649  case MISCREG_CNTKCTL_EL1:
650  return core.cntkctl & 0x00000000ffffffff;
651  case MISCREG_CNTHCTL:
652  case MISCREG_CNTHCTL_EL2:
653  return core.cnthctl & 0x00000000ffffffff;
654  // Physical timer
657  return core.physNS.compareValue();
658 
661  return core.physNS.timerValue();
662 
664  case MISCREG_CNTP_CTL_NS:
665  return core.physNS.control();
666 
667  case MISCREG_CNTPCT:
668  case MISCREG_CNTPCT_EL0:
669  return core.physNS.value();
670 
671 
672  // Virtual timer
673  case MISCREG_CNTVCT:
674  case MISCREG_CNTVCT_EL0:
675  return core.virt.value();
676 
677  case MISCREG_CNTVOFF:
678  case MISCREG_CNTVOFF_EL2:
679  return core.virt.offset();
680 
681  case MISCREG_CNTV_CVAL:
683  return core.virt.compareValue();
684 
685  case MISCREG_CNTV_TVAL:
687  return core.virt.timerValue();
688 
689  case MISCREG_CNTV_CTL:
691  return core.virt.control();
692 
693  // PL1 phys. timer, secure
694  case MISCREG_CNTP_CTL_S:
696  return core.physS.control();
697 
698  case MISCREG_CNTP_CVAL_S:
700  return core.physS.compareValue();
701 
702  case MISCREG_CNTP_TVAL_S:
704  return core.physS.timerValue();
705 
706  // HYP phys. timer (NS)
707  case MISCREG_CNTHP_CTL:
709  return core.hyp.control();
710 
711  case MISCREG_CNTHP_CVAL:
713  return core.hyp.compareValue();
714 
715  case MISCREG_CNTHP_TVAL:
717  return core.hyp.timerValue();
718 
719  default:
720  warn("Reading from unknown register: %s\n", miscRegName[reg]);
721  return 0;
722  }
723 }
724 
726  ArmSystem &system, unsigned cpu,
727  ArmInterruptPin *_irqPhysS, ArmInterruptPin *_irqPhysNS,
728  ArmInterruptPin *_irqVirt, ArmInterruptPin *_irqHyp)
729  : parent(_parent),
730  cntfrq(parent.params()->cntfrq),
731  threadContext(system.threads[cpu]),
732  irqPhysS(_irqPhysS),
733  irqPhysNS(_irqPhysNS),
734  irqVirt(_irqVirt),
735  irqHyp(_irqHyp),
736  physS(csprintf("%s.phys_s_timer%d", parent.name(), cpu),
737  system, parent, parent.systemCounter,
738  _irqPhysS),
739  // This should really be phys_timerN, but we are stuck with
740  // arch_timer for backwards compatibility.
741  physNS(csprintf("%s.arch_timer%d", parent.name(), cpu),
742  system, parent, parent.systemCounter,
743  _irqPhysNS),
744  virt(csprintf("%s.virt_timer%d", parent.name(), cpu),
745  system, parent, parent.systemCounter,
746  _irqVirt),
747  hyp(csprintf("%s.hyp_timer%d", parent.name(), cpu),
748  system, parent, parent.systemCounter,
749  _irqHyp),
750  physEvStream{
752  csprintf("%s.phys_event_gen%d", parent.name(), cpu)), 0, 0
753  },
754  virtEvStream{
755  EventFunctionWrapper([this]{ virtEventStreamCallback(); },
756  csprintf("%s.virt_event_gen%d", parent.name(), cpu)), 0, 0
757  }
758 {
759 }
760 
761 void
763 {
764  eventStreamCallback();
765  schedNextEvent(physEvStream, physNS);
766 }
767 
768 void
770 {
771  eventStreamCallback();
772  schedNextEvent(virtEvStream, virt);
773 }
774 
775 void
777 {
778  sendEvent(threadContext);
779  threadContext->getCpuPtr()->wakeup(threadContext->threadId());
780 }
781 
782 void
784  ArchTimer &timer)
785 {
786  parent.reschedule(ev_stream.event, timer.whenValue(
787  ev_stream.eventTargetValue(timer.value())), true);
788 }
789 
790 void
792 {
793  schedNextEvent(virtEvStream, virt);
794  schedNextEvent(physEvStream, physNS);
795 }
796 
797 void
799 {
800  SERIALIZE_SCALAR(cntfrq);
801  SERIALIZE_SCALAR(cntkctl);
802  SERIALIZE_SCALAR(cnthctl);
803 
804  const bool phys_ev_scheduled = physEvStream.event.scheduled();
805  SERIALIZE_SCALAR(phys_ev_scheduled);
806  if (phys_ev_scheduled) {
807  const Tick phys_ev_when = physEvStream.event.when();
808  SERIALIZE_SCALAR(phys_ev_when);
809  }
810  SERIALIZE_SCALAR(physEvStream.transitionTo);
811  SERIALIZE_SCALAR(physEvStream.transitionBit);
812 
813  const bool virt_ev_scheduled = virtEvStream.event.scheduled();
814  SERIALIZE_SCALAR(virt_ev_scheduled);
815  if (virt_ev_scheduled) {
816  const Tick virt_ev_when = virtEvStream.event.when();
817  SERIALIZE_SCALAR(virt_ev_when);
818  }
819  SERIALIZE_SCALAR(virtEvStream.transitionTo);
820  SERIALIZE_SCALAR(virtEvStream.transitionBit);
821 
822  physS.serializeSection(cp, "phys_s_timer");
823  physNS.serializeSection(cp, "phys_ns_timer");
824  virt.serializeSection(cp, "virt_timer");
825  hyp.serializeSection(cp, "hyp_timer");
826 }
827 
828 void
830 {
831  UNSERIALIZE_SCALAR(cntfrq);
832  UNSERIALIZE_SCALAR(cntkctl);
833  UNSERIALIZE_SCALAR(cnthctl);
834 
835  bool phys_ev_scheduled;
836  UNSERIALIZE_SCALAR(phys_ev_scheduled);
837  if (phys_ev_scheduled) {
838  Tick phys_ev_when;
839  UNSERIALIZE_SCALAR(phys_ev_when);
840  parent.reschedule(physEvStream.event, phys_ev_when, true);
841  }
842  UNSERIALIZE_SCALAR(physEvStream.transitionTo);
843  UNSERIALIZE_SCALAR(physEvStream.transitionBit);
844 
845  bool virt_ev_scheduled;
846  UNSERIALIZE_SCALAR(virt_ev_scheduled);
847  if (virt_ev_scheduled) {
848  Tick virt_ev_when;
849  UNSERIALIZE_SCALAR(virt_ev_when);
850  parent.reschedule(virtEvStream.event, virt_ev_when, true);
851  }
852  UNSERIALIZE_SCALAR(virtEvStream.transitionTo);
853  UNSERIALIZE_SCALAR(virtEvStream.transitionBit);
854 
855  physS.unserializeSection(cp, "phys_s_timer");
856  physNS.unserializeSection(cp, "phys_ns_timer");
857  virt.unserializeSection(cp, "virt_timer");
858  hyp.unserializeSection(cp, "hyp_timer");
859 }
860 
861 void
863 {
864  DPRINTF(Timer, "Setting %s := 0x%x\n", miscRegName[reg], val);
865  parent.setMiscReg(reg, cpu, val);
866 }
867 
868 RegVal
870 {
871  RegVal value = parent.readMiscReg(reg, cpu);
872  DPRINTF(Timer, "Reading %s as 0x%x\n", miscRegName[reg], value);
873  return value;
874 }
875 
876 GenericTimerFrame::GenericTimerFrame(GenericTimerFrameParams *const p)
877  : PioDevice(p),
878  timerRange(RangeSize(p->cnt_base, ArmSystem::PageBytes)),
879  addrRanges({timerRange}),
880  systemCounter(*p->counter),
881  physTimer(csprintf("%s.phys_timer", name()),
882  *this, systemCounter, p->int_phys->get()),
883  virtTimer(csprintf("%s.virt_timer", name()),
884  *this, systemCounter,
885  p->int_virt->get()),
886  accessBits(0x3f),
887  system(*dynamic_cast<ArmSystem *>(sys))
888 {
890  // Expose optional CNTEL0Base register frame
891  if (p->cnt_el0_base != MaxAddr) {
892  timerEl0Range = RangeSize(p->cnt_el0_base, ArmSystem::PageBytes);
893  accessBitsEl0 = 0x303;
894  addrRanges.push_back(timerEl0Range);
895  }
896  for (auto &range : addrRanges)
898 }
899 
900 void
902 {
903  SERIALIZE_SCALAR(accessBits);
904  if (hasEl0View())
905  SERIALIZE_SCALAR(accessBitsEl0);
907 
908  physTimer.serializeSection(cp, "phys_timer");
909  virtTimer.serializeSection(cp, "virt_timer");
910 }
911 
912 void
914 {
915  UNSERIALIZE_SCALAR(accessBits);
916  if (hasEl0View())
917  UNSERIALIZE_SCALAR(accessBitsEl0);
919 
920  physTimer.unserializeSection(cp, "phys_timer");
921  virtTimer.unserializeSection(cp, "virt_timer");
922 }
923 
924 uint64_t
926 {
927  return virtTimer.offset();
928 }
929 
930 void
932 {
933  virtTimer.setOffset(new_offset);
934 }
935 
936 bool
938 {
939  return timerEl0Range.valid();
940 }
941 
942 uint8_t
944 {
945  return accessBits;
946 }
947 
948 void
950 {
951  accessBits = data & 0x3f;
952 }
953 
954 bool
956 {
957  return nonSecureAccess;
958 }
959 
960 void
962 {
963  nonSecureAccess = true;
964 }
965 
966 bool
968 {
969  return accessBits.rvoff;
970 }
971 
974 {
975  return addrRanges;
976 }
977 
978 Tick
980 {
981  const Addr addr = pkt->getAddr();
982  const size_t size = pkt->getSize();
983  const bool is_sec = pkt->isSecure();
984  panic_if(size != 4 && size != 8,
985  "GenericTimerFrame::read: Invalid size %i\n", size);
986 
987  bool to_el0 = false;
988  uint64_t resp = 0;
989  Addr offset = 0;
990  if (timerRange.contains(addr)) {
991  offset = addr - timerRange.start();
992  } else if (hasEl0View() && timerEl0Range.contains(addr)) {
994  to_el0 = true;
995  } else {
996  panic("GenericTimerFrame::read: Invalid address: 0x%x\n", addr);
997  }
998 
999  resp = timerRead(offset, size, is_sec, to_el0);
1000 
1001  DPRINTF(Timer, "GenericTimerFrame::read: 0x%x<-0x%x(%i) [S = %u]\n", resp,
1002  addr, size, is_sec);
1003 
1004  pkt->setUintX(resp, ByteOrder::little);
1005  pkt->makeResponse();
1006  return 0;
1007 }
1008 
1009 Tick
1011 {
1012  const Addr addr = pkt->getAddr();
1013  const size_t size = pkt->getSize();
1014  const bool is_sec = pkt->isSecure();
1015  panic_if(size != 4 && size != 8,
1016  "GenericTimerFrame::write: Invalid size %i\n", size);
1017 
1018  bool to_el0 = false;
1019  const uint64_t data = pkt->getUintX(ByteOrder::little);
1020  Addr offset = 0;
1021  if (timerRange.contains(addr)) {
1022  offset = addr - timerRange.start();
1023  } else if (hasEl0View() && timerEl0Range.contains(addr)) {
1025  to_el0 = true;
1026  } else {
1027  panic("GenericTimerFrame::write: Invalid address: 0x%x\n", addr);
1028  }
1029 
1030  timerWrite(offset, size, data, is_sec, to_el0);
1031 
1032  DPRINTF(Timer, "GenericTimerFrame::write: 0x%x->0x%x(%i) [S = %u]\n", data,
1033  addr, size, is_sec);
1034 
1035  pkt->makeResponse();
1036  return 0;
1037 }
1038 
1039 uint64_t
1040 GenericTimerFrame::timerRead(Addr addr, size_t size, bool is_sec,
1041  bool to_el0) const
1042 {
1044  !nonSecureAccess)
1045  return 0;
1046 
1047  switch (addr) {
1048  case TIMER_CNTPCT_LO:
1049  if (!accessBits.rpct || (to_el0 && !accessBitsEl0.pcten))
1050  return 0;
1051  else
1052  return physTimer.value();
1053 
1054  case TIMER_CNTPCT_HI:
1055  if (!accessBits.rpct || (to_el0 && !accessBitsEl0.pcten))
1056  return 0;
1057  else
1058  return physTimer.value() >> 32;
1059 
1060  case TIMER_CNTFRQ:
1061  if ((!accessBits.rfrq) ||
1062  (to_el0 && (!accessBitsEl0.pcten && !accessBitsEl0.vcten)))
1063  return 0;
1064  else
1065  return systemCounter.freq();
1066 
1067  case TIMER_CNTEL0ACR:
1068  if (!hasEl0View() || to_el0)
1069  return 0;
1070  else
1071  return accessBitsEl0;
1072 
1073  case TIMER_CNTP_CVAL_LO:
1074  if (!accessBits.rwpt || (to_el0 && !accessBitsEl0.pten))
1075  return 0;
1076  else
1077  return physTimer.compareValue();
1078 
1079  case TIMER_CNTP_CVAL_HI:
1080  if (!accessBits.rwpt || (to_el0 && !accessBitsEl0.pten))
1081  return 0;
1082  else
1083  return physTimer.compareValue() >> 32;
1084 
1085  case TIMER_CNTP_TVAL:
1086  if (!accessBits.rwpt || (to_el0 && !accessBitsEl0.pten))
1087  return 0;
1088  else
1089  return physTimer.timerValue();
1090  case TIMER_CNTP_CTL:
1091  if (!accessBits.rwpt || (to_el0 && !accessBitsEl0.pten))
1092  return 0;
1093  else
1094  return physTimer.control();
1095 
1096  case TIMER_CNTVCT_LO:
1097  if (!accessBits.rvct || (to_el0 && !accessBitsEl0.vcten))
1098  return 0;
1099  else
1100  return virtTimer.value();
1101 
1102  case TIMER_CNTVCT_HI:
1103  if (!accessBits.rvct || (to_el0 && !accessBitsEl0.vcten))
1104  return 0;
1105  else
1106  return virtTimer.value() >> 32;
1107 
1108  case TIMER_CNTVOFF_LO:
1109  if (!accessBits.rvoff || (to_el0))
1110  return 0;
1111  else
1112  return virtTimer.offset();
1113 
1114  case TIMER_CNTVOFF_HI:
1115  if (!accessBits.rvoff || (to_el0))
1116  return 0;
1117  else
1118  return virtTimer.offset() >> 32;
1119 
1120  case TIMER_CNTV_CVAL_LO:
1121  if (!accessBits.rwvt || (to_el0 && !accessBitsEl0.vten))
1122  return 0;
1123  else
1124  return virtTimer.compareValue();
1125 
1126  case TIMER_CNTV_CVAL_HI:
1127  if (!accessBits.rwvt || (to_el0 && !accessBitsEl0.vten))
1128  return 0;
1129  else
1130  return virtTimer.compareValue() >> 32;
1131 
1132  case TIMER_CNTV_TVAL:
1133  if (!accessBits.rwvt || (to_el0 && !accessBitsEl0.vten))
1134  return 0;
1135  else
1136  return virtTimer.timerValue();
1137 
1138  case TIMER_CNTV_CTL:
1139  if (!accessBits.rwvt || (to_el0 && !accessBitsEl0.vten))
1140  return 0;
1141  else
1142  return virtTimer.control();
1143 
1144  default:
1145  warn("GenericTimerFrame::timerRead: Unexpected address (0x%x:%i), "
1146  "assuming RAZ\n", addr, size);
1147  return 0;
1148  }
1149 }
1150 
1151 void
1153  bool is_sec, bool to_el0)
1154 {
1156  !nonSecureAccess)
1157  return;
1158 
1159  switch (addr) {
1161  warn("GenericTimerFrame::timerWrite: RO reg (0x%x) [CNTPCT]\n",
1162  addr);
1163  return;
1164 
1165  case TIMER_CNTFRQ:
1166  warn("GenericTimerFrame::timerWrite: RO reg (0x%x) [CNTFRQ]\n",
1167  addr);
1168  return;
1169 
1170  case TIMER_CNTEL0ACR:
1171  if (!hasEl0View() || to_el0)
1172  return;
1173 
1174  insertBits(accessBitsEl0, 9, 8, data);
1175  insertBits(accessBitsEl0, 1, 0, data);
1176  return;
1177 
1178  case TIMER_CNTP_CVAL_LO:
1179  if ((!accessBits.rwpt) || (to_el0 && !accessBitsEl0.pten))
1180  return;
1181  data = size == 4 ? insertBits(physTimer.compareValue(),
1182  31, 0, data) : data;
1184  return;
1185 
1186  case TIMER_CNTP_CVAL_HI:
1187  if ((!accessBits.rwpt) || (to_el0 && !accessBitsEl0.pten))
1188  return;
1189  data = insertBits(physTimer.compareValue(), 63, 32, data);
1191  return;
1192 
1193  case TIMER_CNTP_TVAL:
1194  if ((!accessBits.rwpt) || (to_el0 && !accessBitsEl0.pten))
1195  return;
1197  return;
1198 
1199  case TIMER_CNTP_CTL:
1200  if ((!accessBits.rwpt) || (to_el0 && !accessBitsEl0.pten))
1201  return;
1203  return;
1204 
1206  warn("GenericTimerFrame::timerWrite: RO reg (0x%x) [CNTVCT]\n",
1207  addr);
1208  return;
1210  warn("GenericTimerFrame::timerWrite: RO reg (0x%x) [CNTVOFF]\n",
1211  addr);
1212  return;
1213 
1214  case TIMER_CNTV_CVAL_LO:
1215  if ((!accessBits.rwvt) || (to_el0 && !accessBitsEl0.vten))
1216  return;
1217  data = size == 4 ? insertBits(virtTimer.compareValue(),
1218  31, 0, data) : data;
1220  return;
1221 
1222  case TIMER_CNTV_CVAL_HI:
1223  if ((!accessBits.rwvt) || (to_el0 && !accessBitsEl0.vten))
1224  return;
1225  data = insertBits(virtTimer.compareValue(), 63, 32, data);
1227  return;
1228 
1229  case TIMER_CNTV_TVAL:
1230  if ((!accessBits.rwvt) || (to_el0 && !accessBitsEl0.vten))
1231  return;
1233  return;
1234 
1235  case TIMER_CNTV_CTL:
1236  if ((!accessBits.rwvt) || (to_el0 && !accessBitsEl0.vten))
1237  return;
1239  return;
1240 
1241  default:
1242  warn("GenericTimerFrame::timerWrite: Unexpected address (0x%x:%i), "
1243  "assuming WI\n", addr, size);
1244  }
1245 }
1246 
1247 GenericTimerMem::GenericTimerMem(GenericTimerMemParams *const p)
1248  : PioDevice(p),
1249  counterCtrlRange(RangeSize(p->cnt_control_base, ArmSystem::PageBytes)),
1250  counterStatusRange(RangeSize(p->cnt_read_base, ArmSystem::PageBytes)),
1251  timerCtrlRange(RangeSize(p->cnt_ctl_base, ArmSystem::PageBytes)),
1252  cnttidr(0x0),
1254  systemCounter(*p->counter),
1255  frames(p->frames),
1256  system(*dynamic_cast<ArmSystem *>(sys))
1257 {
1259  for (auto &range : addrRanges)
1261  fatal_if(frames.size() > MAX_TIMER_FRAMES,
1262  "GenericTimerMem::GenericTimerMem: Architecture states a maximum of "
1263  "8 memory-mapped timer frames, limit surpassed\n");
1264  // Initialize CNTTIDR with each frame's features
1265  for (int i = 0; i < frames.size(); i++) {
1266  uint32_t features = 0x1;
1267  features |= 0x2;
1268  if (frames[i]->hasEl0View())
1269  features |= 0x4;
1270  features <<= i * 4;
1271  replaceBits(cnttidr, (i + 1) * 4 - 1, i * 4, features);
1272  }
1273 }
1274 
1275 void
1277 {
1279  "GenericTimerMem::validateFrameRange: Architecture states each "
1280  "register frame should be in a separate memory page, specified "
1281  "range base address [0x%x] is not compliant\n");
1282 }
1283 
1284 bool
1286 {
1287  return !sys.haveSecurity() || is_sec;
1288 }
1289 
1292 {
1293  return addrRanges;
1294 }
1295 
1296 Tick
1298 {
1299  const Addr addr = pkt->getAddr();
1300  const size_t size = pkt->getSize();
1301  const bool is_sec = pkt->isSecure();
1302  panic_if(size != 4 && size != 8,
1303  "GenericTimerMem::read: Invalid size %i\n", size);
1304 
1305  uint64_t resp = 0;
1307  resp = counterCtrlRead(addr - counterCtrlRange.start(), size, is_sec);
1308  else if (counterStatusRange.contains(addr))
1309  resp = counterStatusRead(addr - counterStatusRange.start(), size);
1310  else if (timerCtrlRange.contains(addr))
1311  resp = timerCtrlRead(addr - timerCtrlRange.start(), size, is_sec);
1312  else
1313  panic("GenericTimerMem::read: Invalid address: 0x%x\n", addr);
1314 
1315  DPRINTF(Timer, "GenericTimerMem::read: 0x%x<-0x%x(%i) [S = %u]\n", resp,
1316  addr, size, is_sec);
1317 
1318  pkt->setUintX(resp, ByteOrder::little);
1319  pkt->makeResponse();
1320  return 0;
1321 }
1322 
1323 Tick
1325 {
1326  const Addr addr = pkt->getAddr();
1327  const size_t size = pkt->getSize();
1328  const bool is_sec = pkt->isSecure();
1329  panic_if(size != 4 && size != 8,
1330  "GenericTimerMem::write: Invalid size %i\n", size);
1331 
1332  const uint64_t data = pkt->getUintX(ByteOrder::little);
1334  counterCtrlWrite(addr - counterCtrlRange.start(), size, data, is_sec);
1335  else if (counterStatusRange.contains(addr))
1337  else if (timerCtrlRange.contains(addr))
1338  timerCtrlWrite(addr - timerCtrlRange.start(), size, data, is_sec);
1339  else
1340  panic("GenericTimerMem::write: Invalid address: 0x%x\n", addr);
1341 
1342  DPRINTF(Timer, "GenericTimerMem::write: 0x%x->0x%x(%i) [S = %u]\n", data,
1343  addr, size, is_sec);
1344 
1345  pkt->makeResponse();
1346  return 0;
1347 }
1348 
1349 uint64_t
1350 GenericTimerMem::counterCtrlRead(Addr addr, size_t size, bool is_sec) const
1351 {
1353  return 0;
1354  switch (addr) {
1355  case COUNTER_CTRL_CNTCR:
1356  {
1357  CNTCR cntcr = 0;
1358  cntcr.en = systemCounter.enabled();
1359  cntcr.fcreq = systemCounter.activeFreqEntry();
1360  return cntcr;
1361  }
1362  case COUNTER_CTRL_CNTSR:
1363  {
1364  CNTSR cntsr = 0;
1365  cntsr.fcack = systemCounter.activeFreqEntry();
1366  return cntsr;
1367  }
1368  case COUNTER_CTRL_CNTCV_LO: return systemCounter.value();
1369  case COUNTER_CTRL_CNTCV_HI: return systemCounter.value() >> 32;
1370  case COUNTER_CTRL_CNTSCR: return 0;
1371  case COUNTER_CTRL_CNTID: return 0;
1372  default:
1373  {
1374  auto &freq_table = systemCounter.freqTable();
1375  for (int i = 0; i < (freq_table.size() - 1); i++) {
1376  Addr offset = COUNTER_CTRL_CNTFID + (i * 0x4);
1377  if (addr == offset)
1378  return freq_table[i];
1379  }
1380  warn("GenericTimerMem::counterCtrlRead: Unexpected address "
1381  "(0x%x:%i), assuming RAZ\n", addr, size);
1382  return 0;
1383  }
1384  }
1385 }
1386 
1387 void
1389  bool is_sec)
1390 {
1392  return;
1393 
1394  switch (addr) {
1395  case COUNTER_CTRL_CNTCR:
1396  {
1397  CNTCR val = data;
1398  if (!systemCounter.enabled() && val.en)
1400  else if (systemCounter.enabled() && !val.en)
1402 
1403  if (val.hdbg)
1404  warn("GenericTimerMem::counterCtrlWrite: Halt-on-debug is not "
1405  "supported\n");
1406  if (val.scen)
1407  warn("GenericTimerMem::counterCtrlWrite: Counter Scaling is not "
1408  "supported\n");
1409  if (val.fcreq != systemCounter.activeFreqEntry())
1411  return;
1412  }
1413 
1414  case COUNTER_CTRL_CNTSR:
1415  warn("GenericTimerMem::counterCtrlWrite: RO reg (0x%x) [CNTSR]\n",
1416  addr);
1417  return;
1418 
1419  case COUNTER_CTRL_CNTCV_LO:
1420  data = size == 4 ? insertBits(systemCounter.value(), 31, 0, data)
1421  : data;
1423  return;
1424 
1425  case COUNTER_CTRL_CNTCV_HI:
1426  data = insertBits(systemCounter.value(), 63, 32, data);
1428  return;
1429 
1430  case COUNTER_CTRL_CNTSCR:
1431  return;
1432 
1433  case COUNTER_CTRL_CNTID:
1434  warn("GenericTimerMem::counterCtrlWrite: RO reg (0x%x) [CNTID]\n",
1435  addr);
1436  return;
1437 
1438  default:
1439  {
1440  auto &freq_table = systemCounter.freqTable();
1441  for (int i = 0; i < (freq_table.size() - 1); i++) {
1442  Addr offset = COUNTER_CTRL_CNTFID + (i * 0x4);
1443  if (addr == offset) {
1444  freq_table[i] = data;
1445  // This is changing the currently selected frequency
1446  if (i == systemCounter.activeFreqEntry()) {
1447  // We've changed the frequency in the table entry,
1448  // however the counter will still work with the
1449  // current one until transition is completed
1451  }
1452  return;
1453  }
1454  }
1455  warn("GenericTimerMem::counterCtrlWrite: Unexpected address "
1456  "(0x%x:%i), assuming WI\n", addr, size);
1457  }
1458  }
1459 }
1460 
1461 uint64_t
1463 {
1464  switch (addr) {
1466  case COUNTER_STATUS_CNTCV_HI: return systemCounter.value() >> 32;
1467  default:
1468  warn("GenericTimerMem::counterStatusRead: Unexpected address "
1469  "(0x%x:%i), assuming RAZ\n", addr, size);
1470  return 0;
1471  }
1472 }
1473 
1474 void
1476 {
1477  switch (addr) {
1479  warn("GenericTimerMem::counterStatusWrite: RO reg (0x%x) [CNTCV]\n",
1480  addr);
1481  return;
1482  default:
1483  warn("GenericTimerMem::counterStatusWrite: Unexpected address "
1484  "(0x%x:%i), assuming WI\n", addr, size);
1485  }
1486 }
1487 
1488 uint64_t
1489 GenericTimerMem::timerCtrlRead(Addr addr, size_t size, bool is_sec) const
1490 {
1491  switch (addr) {
1492  case TIMER_CTRL_CNTFRQ:
1493  if (!GenericTimerMem::validateAccessPerm(system, is_sec)) return 0;
1494  return systemCounter.freq();
1495  case TIMER_CTRL_CNTNSAR:
1496  {
1497  if (!GenericTimerMem::validateAccessPerm(system, is_sec)) return 0;
1498  uint32_t cntnsar = 0x0;
1499  for (int i = 0; i < frames.size(); i++) {
1500  if (frames[i]->hasNonSecureAccess())
1501  cntnsar |= 0x1 << i;
1502  }
1503  return cntnsar;
1504  }
1505  case TIMER_CTRL_CNTTIDR: return cnttidr;
1506  default:
1507  for (int i = 0; i < frames.size(); i++) {
1508  Addr cntacr_off = TIMER_CTRL_CNTACR + (i * 0x4);
1509  Addr cntvoff_lo_off = TIMER_CTRL_CNTVOFF_LO + (i * 0x4);
1510  Addr cntvoff_hi_off = TIMER_CTRL_CNTVOFF_HI + (i * 0x4);
1511  // CNTNSAR.NS determines if CNTACR/CNTVOFF are accessible from
1512  // normal world
1513  bool hit = addr == cntacr_off || addr == cntvoff_lo_off ||
1514  addr == cntvoff_hi_off;
1515  bool has_access =
1517  frames[i]->hasNonSecureAccess();
1518  if (hit && !has_access) return 0;
1519  if (addr == cntacr_off)
1520  return frames[i]->getAccessBits();
1521  if (addr == cntvoff_lo_off || addr == cntvoff_hi_off) {
1522  return addr == cntvoff_lo_off ? frames[i]->getVirtOffset()
1523  : frames[i]->getVirtOffset() >> 32;
1524  }
1525  }
1526  warn("GenericTimerMem::timerCtrlRead: Unexpected address (0x%x:%i), "
1527  "assuming RAZ\n", addr, size);
1528  return 0;
1529  }
1530 }
1531 
1532 void
1534  bool is_sec)
1535 {
1536  switch (addr) {
1537  case TIMER_CTRL_CNTFRQ:
1538  if (!GenericTimerMem::validateAccessPerm(system, is_sec)) return;
1540  "GenericTimerMem::timerCtrlWrite: CNTFRQ configured freq "
1541  "does not match the counter freq, ignoring\n");
1542  return;
1543  case TIMER_CTRL_CNTNSAR:
1544  if (!GenericTimerMem::validateAccessPerm(system, is_sec)) return;
1545  for (int i = 0; i < frames.size(); i++) {
1546  // Check if the CNTNSAR.NS bit is set for this frame
1547  if (data & (0x1 << i))
1548  frames[i]->setNonSecureAccess();
1549  }
1550  return;
1551  case TIMER_CTRL_CNTTIDR:
1552  warn("GenericTimerMem::timerCtrlWrite: RO reg (0x%x) [CNTTIDR]\n",
1553  addr);
1554  return;
1555  default:
1556  for (int i = 0; i < frames.size(); i++) {
1557  Addr cntacr_off = TIMER_CTRL_CNTACR + (i * 0x4);
1558  Addr cntvoff_lo_off = TIMER_CTRL_CNTVOFF_LO + (i * 0x4);
1559  Addr cntvoff_hi_off = TIMER_CTRL_CNTVOFF_HI + (i * 0x4);
1560  // CNTNSAR.NS determines if CNTACR/CNTVOFF are accessible from
1561  // normal world
1562  bool hit = addr == cntacr_off || addr == cntvoff_lo_off ||
1563  addr == cntvoff_hi_off;
1564  bool has_access =
1566  frames[i]->hasNonSecureAccess();
1567  if (hit && !has_access) return;
1568  if (addr == cntacr_off) {
1569  frames[i]->setAccessBits(data);
1570  return;
1571  }
1572  if (addr == cntvoff_lo_off || addr == cntvoff_hi_off) {
1573  if (addr == cntvoff_lo_off)
1574  data = size == 4 ? insertBits(frames[i]->getVirtOffset(),
1575  31, 0, data) : data;
1576  else
1577  data = insertBits(frames[i]->getVirtOffset(),
1578  63, 32, data);
1579  frames[i]->setVirtOffset(data);
1580  return;
1581  }
1582  }
1583  warn("GenericTimerMem::timerCtrlWrite: Unexpected address "
1584  "(0x%x:%i), assuming WI\n", addr, size);
1585  }
1586 }
1587 
1588 SystemCounter *
1589 SystemCounterParams::create()
1590 {
1591  return new SystemCounter(this);
1592 }
1593 
1594 GenericTimer *
1595 GenericTimerParams::create()
1596 {
1597  return new GenericTimer(this);
1598 }
1599 
1601 GenericTimerFrameParams::create()
1602 {
1603  return new GenericTimerFrame(this);
1604 }
1605 
1607 GenericTimerMemParams::create()
1608 {
1609  return new GenericTimerMem(this);
1610 }
Stats::_enabled
bool _enabled
Definition: statistics.cc:542
GenericTimerMem::TIMER_CTRL_CNTVOFF_LO
static const Addr TIMER_CTRL_CNTVOFF_LO
Definition: generic_timer.hh:560
ArmISA::sendEvent
void sendEvent(ThreadContext *tc)
Send an event (SEV) to a specific PE if there isn't already a pending event.
Definition: utility.cc:165
GenericTimerMem::getAddrRanges
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
Definition: generic_timer.cc:1291
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
SystemCounter
Global system counter.
Definition: generic_timer.hh:75
ArchTimer::setTimerValue
void setTimerValue(uint32_t val)
Sets the TimerValue view of the timer.
Definition: generic_timer.cc:309
GenericTimer::CoreTimers::EventStream::eventTargetValue
uint64_t eventTargetValue(uint64_t val) const
Definition: generic_timer.hh:333
SystemCounter::_increment
uint64_t _increment
Value increment in each counter cycle.
Definition: generic_timer.hh:85
ArmISA::ELIsInHost
bool ELIsInHost(ThreadContext *tc, ExceptionLevel el)
Returns true if the current exception level el is executing a Host OS or an application of a Host OS ...
Definition: utility.cc:392
GenericTimer::CoreTimers::EventStream::transitionBit
uint8_t transitionBit
Definition: generic_timer.hh:330
GenericTimer::handleStream
void handleStream(CoreTimers::EventStream *ev_stream, ArchTimer *timer, RegVal old_cnt_ctl, RegVal cnt_ctl)
Definition: generic_timer.cc:488
Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:460
GenericTimerMem::timerCtrlWrite
void timerCtrlWrite(Addr addr, size_t size, uint64_t data, bool is_sec)
Definition: generic_timer.cc:1533
Serializable::unserializeSection
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
Definition: serialize.cc:178
GenericTimer::CoreTimers::cntkctl
ArmISA::CNTKCTL cntkctl
Kernel control register.
Definition: generic_timer.hh:305
warn
#define warn(...)
Definition: logging.hh:239
replaceBits
void replaceBits(T &val, int first, int last, B bit_val)
A convenience function to replace bits first to last of val with bit_val in place.
Definition: bitfield.hh:179
ArmISA::MISCREG_CNTHP_CTL_EL2
@ MISCREG_CNTHP_CTL_EL2
Definition: miscregs.hh:766
ArmISA::MISCREG_CNTV_CTL
@ MISCREG_CNTV_CTL
Definition: miscregs.hh:419
GenericTimer::system
ArmSystem & system
ARM system containing this timer.
Definition: generic_timer.hh:372
SystemCounter::whenValue
Tick whenValue(uint64_t target_val)
Returns the tick at which a certain counter value is reached.
Definition: generic_timer.cc:149
SystemCounter::_listeners
std::vector< SystemCounterListener * > _listeners
Listeners to changes in counting speed.
Definition: generic_timer.hh:97
GenericTimerFrame::timerRange
const AddrRange timerRange
Definition: generic_timer.hh:440
data
const char data[]
Definition: circlebuf.test.cc:42
GenericTimerMem::cnttidr
uint32_t cnttidr
ID register for reporting features of implemented timer frames.
Definition: generic_timer.hh:554
GenericTimerMem::counterStatusRange
const AddrRange counterStatusRange
Definition: generic_timer.hh:543
ArmISA::MISCREG_CNTPCT
@ MISCREG_CNTPCT
Definition: miscregs.hh:408
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:797
Packet::getAddr
Addr getAddr() const
Definition: packet.hh:754
GenericTimerFrame::physTimer
ArchTimer physTimer
Physical and virtual timers.
Definition: generic_timer.hh:467
ArchTimer::_parent
EndBitUnion(ArchTimerCtrl) const std SimObject & _parent
Name of this timer.
Definition: generic_timer.hh:176
GenericTimerISA::readMiscReg
RegVal readMiscReg(int misc_reg) override
Read a system register belonging to this device.
Definition: generic_timer.cc:869
GenericTimerMem::COUNTER_CTRL_CNTID
static const Addr COUNTER_CTRL_CNTID
Definition: generic_timer.hh:537
SystemCounter::disable
void disable()
Disables the counter after a CNTCR.EN == 0.
Definition: generic_timer.cc:94
ArchTimer::ArchTimer
ArchTimer(const std::string &name, SimObject &parent, SystemCounter &sysctr, ArmInterruptPin *interrupt)
Definition: generic_timer.cc:248
GenericTimer::CoreTimers::physEvStream
EventStream physEvStream
Definition: generic_timer.hh:344
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
UNSERIALIZE_CONTAINER
#define UNSERIALIZE_CONTAINER(member)
Definition: serialize.hh:856
ArmISA::MISCREG_CNTFRQ_EL0
@ MISCREG_CNTFRQ_EL0
Definition: miscregs.hh:745
GenericTimer::CoreTimers::hyp
ArchTimerKvm hyp
Definition: generic_timer.hh:321
GenericTimerFrame::virtTimer
ArchTimer virtTimer
Definition: generic_timer.hh:468
GenericTimerFrame::TIMER_CNTP_TVAL
static const Addr TIMER_CNTP_TVAL
Definition: generic_timer.hh:453
EventManager::reschedule
void reschedule(Event &event, Tick when, bool always=false)
Definition: eventq.hh:1023
GenericTimerMem::COUNTER_CTRL_CNTCV_LO
static const Addr COUNTER_CTRL_CNTCV_LO
Definition: generic_timer.hh:534
ArmInterruptPin::clear
virtual void clear()=0
Clear a signalled interrupt.
GenericTimerFrame::hasReadableVoff
bool hasReadableVoff() const
Indicates if CNTVOFF is readable for this frame.
Definition: generic_timer.cc:967
GenericTimerFrame::setVirtOffset
void setVirtOffset(uint64_t new_offset)
Sets the virtual offset for this frame's virtual timer after a write to CNTVOFF.
Definition: generic_timer.cc:931
ArmISA::MISCREG_CNTP_TVAL_EL0
@ MISCREG_CNTP_TVAL_EL0
Definition: miscregs.hh:750
ArchTimer::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: generic_timer.cc:362
GenericTimerFrame::systemCounter
SystemCounter & systemCounter
System counter reference.
Definition: generic_timer.hh:464
SystemCounter::_freq
uint32_t _freq
Counter frequency (as specified by CNTFRQ).
Definition: generic_timer.hh:81
ArmISA::currEL
static ExceptionLevel currEL(const ThreadContext *tc)
Definition: utility.hh:143
base_gic.hh
SystemCounter::_nextFreqEntry
size_t _nextFreqEntry
Definition: generic_timer.hh:153
GenericTimer::CoreTimers::eventStreamCallback
void eventStreamCallback() const
Definition: generic_timer.cc:776
ArmISA::MISCREG_CNTV_CVAL_EL0
@ MISCREG_CNTV_CVAL_EL0
Definition: miscregs.hh:752
ArchTimer
Per-CPU architected timer.
Definition: generic_timer.hh:168
ArmISA::MISCREG_CNTPS_TVAL_EL1
@ MISCREG_CNTPS_TVAL_EL1
Definition: miscregs.hh:764
GenericTimerMem::counterStatusWrite
void counterStatusWrite(Addr addr, size_t size, uint64_t data)
Definition: generic_timer.cc:1475
GenericTimerFrame::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: generic_timer.cc:913
SystemCounter::freq
uint32_t freq() const
Returns the counter frequency.
Definition: generic_timer.hh:112
GenericTimer::CoreTimers::physS
ArchTimerKvm physS
Definition: generic_timer.hh:318
ArmInterruptPin::raise
virtual void raise()=0
Signal an interrupt.
GenericTimerFrame::hasEl0View
bool hasEl0View() const
Indicates if this frame implements a second EL0 view.
Definition: generic_timer.cc:937
ArmISA::MISCREG_CNTV_TVAL
@ MISCREG_CNTV_TVAL
Definition: miscregs.hh:421
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
SystemCounter::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: generic_timer.cc:226
ArmISA::MISCREG_CNTP_TVAL_NS
@ MISCREG_CNTP_TVAL_NS
Definition: miscregs.hh:417
ArmISA::MISCREG_CNTP_CTL_S
@ MISCREG_CNTP_CTL_S
Definition: miscregs.hh:412
SystemCounter::validateCounterRef
static void validateCounterRef(SystemCounter *sys_cnt)
Validates a System Counter reference.
Definition: generic_timer.cc:79
ArchTimer::_control
ArchTimerCtrl _control
Value of the control register ({CNTP/CNTHP/CNTV}_CTL).
Definition: generic_timer.hh:189
ArmISA::MISCREG_CNTV_TVAL_EL0
@ MISCREG_CNTV_TVAL_EL0
Definition: miscregs.hh:753
GenericTimerFrame::timerRead
uint64_t timerRead(Addr addr, size_t size, bool is_sec, bool to_el0) const
CNTBase/CNTEL0Base (Memory-mapped timer frame)
Definition: generic_timer.cc:1040
ArchTimer::updateCounter
void updateCounter()
Timer settings or the offset has changed, re-evaluate trigger condition and raise interrupt if necess...
Definition: generic_timer.cc:279
AddrRange::contains
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:435
GenericTimerFrame::write
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: generic_timer.cc:1010
GenericTimerFrame::TIMER_CNTEL0ACR
static const Addr TIMER_CNTEL0ACR
Definition: generic_timer.hh:448
ArchTimer::timerValue
uint32_t timerValue() const
Returns the TimerValue view of the timer.
Definition: generic_timer.hh:222
EventManager::deschedule
void deschedule(Event &event)
Definition: eventq.hh:1014
GenericTimer
Definition: generic_timer.hh:276
SystemCounter::activeFreqEntry
size_t activeFreqEntry() const
Returns the currently active frequency table entry.
Definition: generic_timer.hh:120
Packet::getSize
unsigned getSize() const
Definition: packet.hh:764
GenericTimerMem::COUNTER_STATUS_CNTCV_HI
static const Addr COUNTER_STATUS_CNTCV_HI
Definition: generic_timer.hh:546
GenericTimerMem::COUNTER_STATUS_CNTCV_LO
static const Addr COUNTER_STATUS_CNTCV_LO
Definition: generic_timer.hh:545
ArchTimer::setOffset
void setOffset(uint64_t val)
Definition: generic_timer.cc:343
system.hh
ArmISA::MISCREG_CNTV_CTL_EL0
@ MISCREG_CNTV_CTL_EL0
Definition: miscregs.hh:751
ArmISA::miscRegName
const char *const miscRegName[]
Definition: miscregs.hh:1159
GenericTimer::CoreTimers::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: generic_timer.cc:829
Serializable::serializeSection
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Definition: serialize.cc:171
Event::when
Tick when() const
Get the time that the event is scheduled.
Definition: eventq.hh:503
SystemCounter::_updateTick
Tick _updateTick
Counter cycle start Tick when the counter status affecting its value has been updated.
Definition: generic_timer.hh:94
GenericTimerMem::timerCtrlRange
const AddrRange timerCtrlRange
Definition: generic_timer.hh:551
SystemCounter::updateTick
void updateTick(void)
Updates the update tick, normalizes to the lower cycle start tick.
Definition: generic_timer.cc:155
ArmISA
Definition: ccregs.hh:41
MaxAddr
const Addr MaxAddr
Definition: types.hh:166
X86ISA::reg
Bitfield< 5, 3 > reg
Definition: types.hh:87
paramOut
void paramOut(CheckpointOut &cp, const string &name, ExtMachInst const &machInst)
Definition: types.cc:38
ArchTimer::notify
void notify(void) override
Called from the SystemCounter when a change in counting speed occurred Events should be rescheduled p...
Definition: generic_timer.cc:356
ArmISA::MISCREG_CNTP_TVAL_S
@ MISCREG_CNTP_TVAL_S
Definition: miscregs.hh:418
GenericTimerMem::counterCtrlRange
const AddrRange counterCtrlRange
Definition: generic_timer.hh:519
ArmISA::MISCREG_CNTVCT
@ MISCREG_CNTVCT
Definition: miscregs.hh:409
ArmISA::MISCREG_CNTFRQ
@ MISCREG_CNTFRQ
Definition: miscregs.hh:407
ArmISA::MISCREG_CNTP_CTL_NS
@ MISCREG_CNTP_CTL_NS
Definition: miscregs.hh:411
ArmISA::MISCREG_CNTKCTL_EL1
@ MISCREG_CNTKCTL_EL1
Definition: miscregs.hh:760
GenericTimerFrame::addrRanges
AddrRangeList addrRanges
All MMIO ranges GenericTimerFrame responds to.
Definition: generic_timer.hh:461
Packet::isSecure
bool isSecure() const
Definition: packet.hh:783
GenericTimer::CoreTimers::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: generic_timer.cc:798
GenericTimerMem::validateAccessPerm
static bool validateAccessPerm(ArmSystem &sys, bool is_sec)
Validates an MMIO access permissions.
Definition: generic_timer.cc:1285
GenericTimerFrame::TIMER_CNTPCT_LO
static const Addr TIMER_CNTPCT_LO
Definition: generic_timer.hh:443
GenericTimer::CoreTimers::schedNextEvent
void schedNextEvent(EventStream &ev_stream, ArchTimer &timer)
Definition: generic_timer.cc:783
SystemCounter::_period
Tick _period
Cached copy of the counter period (inverse of the frequency).
Definition: generic_timer.hh:91
SimClock::Frequency
Tick Frequency
The simulated frequency of curTick(). (In ticks per second)
Definition: core.cc:46
EventFunctionWrapper
Definition: eventq.hh:1101
ArmISA::MISCREG_CNTV_CVAL
@ MISCREG_CNTV_CVAL
Definition: miscregs.hh:420
PioDevice::sys
System * sys
Definition: io_device.hh:102
ArmISA::MISCREG_CNTP_CVAL_EL0
@ MISCREG_CNTP_CVAL_EL0
Definition: miscregs.hh:749
GenericTimer::CoreTimers::cnthctl
ArmISA::CNTHCTL cnthctl
Hypervisor control register.
Definition: generic_timer.hh:308
DrainState::Drained
@ Drained
Buffers drained, ready for serialization/handover.
SystemCounter::_freqTable
std::vector< uint32_t > _freqTable
Frequency modes table with all possible frequencies for the counter.
Definition: generic_timer.hh:87
GenericTimer::CoreTimers::physEventStreamCallback
void physEventStreamCallback()
Definition: generic_timer.cc:762
GenericTimerFrame::timerWrite
void timerWrite(Addr addr, size_t size, uint64_t data, bool is_sec, bool to_el0)
Definition: generic_timer.cc:1152
DrainState
DrainState
Object drain/handover states.
Definition: drain.hh:71
ArchTimer::setCompareValue
void setCompareValue(uint64_t val)
Sets the CompareValue view of the timer.
Definition: generic_timer.cc:302
GenericTimerMem::TIMER_CTRL_CNTNSAR
static const Addr TIMER_CTRL_CNTNSAR
Definition: generic_timer.hh:557
X86ISA::system
Bitfield< 15 > system
Definition: misc.hh:997
SystemCounter::freqUpdateCallback
void freqUpdateCallback()
Callback for the frequency update.
Definition: generic_timer.cc:179
SystemCounter::enable
void enable()
Enables the counter after a CNTCR.EN == 1.
Definition: generic_timer.cc:86
cp
Definition: cprintf.cc:40
PioDevice
This device is the base class which all devices senstive to an address range inherit from.
Definition: io_device.hh:99
EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1005
GenericTimerFrame::TIMER_CNTVOFF_HI
static const Addr TIMER_CNTVOFF_HI
Definition: generic_timer.hh:450
ArmISA::MISCREG_CNTKCTL
@ MISCREG_CNTKCTL
Definition: miscregs.hh:422
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
ArchTimer::drain
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
Definition: generic_timer.cc:384
GenericTimerFrame::TIMER_CNTP_CVAL_HI
static const Addr TIMER_CNTP_CVAL_HI
Definition: generic_timer.hh:452
AddrRange
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition: addr_range.hh:68
GenericTimerMem::counterStatusRead
uint64_t counterStatusRead(Addr addr, size_t size) const
CNTReadBase (System counter status frame)
Definition: generic_timer.cc:1462
GenericTimer::params
const GenericTimerParams * params() const
Definition: generic_timer.cc:410
Packet::getUintX
uint64_t getUintX(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness and zero-extended to 64 bits.
Definition: packet.cc:350
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
GenericTimer::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: generic_timer.cc:427
GenericTimer::CoreTimers::parent
GenericTimer & parent
Generic Timer parent reference.
Definition: generic_timer.hh:299
GenericTimerMem::frames
std::vector< GenericTimerFrame * > frames
Timer frame references.
Definition: generic_timer.hh:573
GenericTimerMem::COUNTER_CTRL_CNTCV_HI
static const Addr COUNTER_CTRL_CNTCV_HI
Definition: generic_timer.hh:535
GenericTimerFrame::TIMER_CNTP_CVAL_LO
static const Addr TIMER_CNTP_CVAL_LO
Definition: generic_timer.hh:451
ArchTimer::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: generic_timer.cc:370
GenericTimerFrame::TIMER_CNTP_CTL
static const Addr TIMER_CNTP_CTL
Definition: generic_timer.hh:454
ArmISA::MISCREG_CNTHP_CTL
@ MISCREG_CNTHP_CTL
Definition: miscregs.hh:424
GenericTimerFrame::TIMER_CNTV_TVAL
static const Addr TIMER_CNTV_TVAL
Definition: generic_timer.hh:457
ArchTimer::compareValue
uint64_t compareValue() const
Returns the CompareValue view of the timer.
Definition: generic_timer.hh:217
SystemCounter::_freqUpdateEvent
EventFunctionWrapper _freqUpdateEvent
Frequency update event handling.
Definition: generic_timer.hh:152
SystemCounter::registerListener
void registerListener(SystemCounterListener *listener)
Called from System Counter Listeners to register.
Definition: generic_timer.cc:193
GenericTimerMem::counterCtrlWrite
void counterCtrlWrite(Addr addr, size_t size, uint64_t data, bool is_sec)
Definition: generic_timer.cc:1388
GenericTimer::CoreTimers::notify
void notify(void) override
Called from the SystemCounter when a change in counting speed occurred Events should be rescheduled p...
Definition: generic_timer.cc:791
AddrRange::valid
bool valid() const
Determine if the range is valid.
Definition: addr_range.hh:307
GenericTimerFrame::getAddrRanges
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
Definition: generic_timer.cc:973
SystemCounter::SystemCounter
SystemCounter(SystemCounterParams *const p)
Definition: generic_timer.cc:55
GenericTimerMem::GenericTimerMem
GenericTimerMem(GenericTimerMemParams *const p)
Definition: generic_timer.cc:1247
GenericTimerFrame::TIMER_CNTFRQ
static const Addr TIMER_CNTFRQ
Definition: generic_timer.hh:447
GenericTimer::readMiscReg
RegVal readMiscReg(int misc_reg, unsigned cpu)
Definition: generic_timer.cc:640
RangeSize
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:638
GenericTimerMem::validateFrameRange
static void validateFrameRange(const AddrRange &range)
Validates a Generic Timer register frame address range.
Definition: generic_timer.cc:1276
UNSERIALIZE_OPT_SCALAR
#define UNSERIALIZE_OPT_SCALAR(scalar)
Definition: serialize.hh:804
GenericTimerFrame::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: generic_timer.cc:901
GenericTimer::CoreTimers::EventStream::event
EventFunctionWrapper event
Definition: generic_timer.hh:328
GenericTimer::getTimers
CoreTimers & getTimers(int cpu_id)
Definition: generic_timer.cc:458
Packet::setUintX
void setUintX(uint64_t w, ByteOrder endian)
Set the value in the word w after truncating it to the length of the packet and then byteswapping it ...
Definition: packet.cc:367
ArchTimer::value
uint64_t value() const
Returns the value of the counter which this timer relies on.
Definition: generic_timer.cc:350
GenericTimerMem::counterCtrlRead
uint64_t counterCtrlRead(Addr addr, size_t size, bool is_sec) const
CNTControlBase (System counter control frame)
Definition: generic_timer.cc:1350
ArmISA::evnten
Bitfield< 2 > evnten
Definition: generic_timer_miscregs_types.hh:53
GenericTimerFrame::read
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: generic_timer.cc:979
GenericTimerMem::system
ArmSystem & system
Definition: generic_timer.hh:575
System::Threads::size
int size() const
Definition: system.hh:204
GenericTimerFrame
Definition: generic_timer.hh:392
SystemCounter::MAX_FREQ_ENTRIES
static constexpr size_t MAX_FREQ_ENTRIES
Maximum architectural number of frequency table entries.
Definition: generic_timer.hh:100
ArmISA::MISCREG_CNTPS_CTL_EL1
@ MISCREG_CNTPS_CTL_EL1
Definition: miscregs.hh:762
SystemCounter::value
uint64_t value()
Updates and returns the counter value.
Definition: generic_timer.cc:102
SystemCounter::notifyListeners
void notifyListeners(void) const
Notifies counting speed changes to listeners.
Definition: generic_timer.cc:199
ArmISA::MISCREG_CNTVOFF_EL2
@ MISCREG_CNTVOFF_EL2
Definition: miscregs.hh:780
SystemCounter::enabled
bool enabled() const
Indicates if the counter is enabled.
Definition: generic_timer.hh:110
ArchTimer::_systemCounter
SystemCounter & _systemCounter
Definition: generic_timer.hh:184
GenericTimerFrame::TIMER_CNTVCT_HI
static const Addr TIMER_CNTVCT_HI
Definition: generic_timer.hh:446
ArchTimer::control
uint32_t control() const
Sets the control register.
Definition: generic_timer.hh:227
generic_timer.hh
X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:769
GenericTimerFrame::TIMER_CNTV_CVAL_HI
static const Addr TIMER_CNTV_CVAL_HI
Definition: generic_timer.hh:456
SystemCounterListener
Abstract class for elements whose events depend on the counting speed of the System Counter.
Definition: generic_timer.hh:65
GenericTimerMem::COUNTER_CTRL_CNTSR
static const Addr COUNTER_CTRL_CNTSR
Definition: generic_timer.hh:533
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Packet::makeResponse
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
Definition: packet.hh:1004
GenericTimerFrame::system
ArmSystem & system
Definition: generic_timer.hh:493
SystemCounter::_enabled
bool _enabled
Indicates if the counter is enabled.
Definition: generic_timer.hh:79
SystemCounter::setValue
void setValue(uint64_t new_value)
Sets the value explicitly from writes to CNTCR.CNTCV.
Definition: generic_timer.cc:121
ArmISA::MISCREG_CNTPCT_EL0
@ MISCREG_CNTPCT_EL0
Definition: miscregs.hh:746
name
const std::string & name()
Definition: trace.cc:50
GenericTimerFrame::timerEl0Range
AddrRange timerEl0Range
Definition: generic_timer.hh:441
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:790
ArmISA::MISCREG_CNTHP_TVAL_EL2
@ MISCREG_CNTHP_TVAL_EL2
Definition: miscregs.hh:768
packet_access.hh
utility.hh
ArmInterruptPin::active
bool active() const
True if interrupt pin is active, false otherwise.
Definition: base_gic.hh:197
GenericTimerFrame::getAccessBits
uint8_t getAccessBits() const
Returns the access bits for this frame.
Definition: generic_timer.cc:943
ArchTimer::counterLimitReached
void counterLimitReached()
Called when the upcounter reaches the programmed value.
Definition: generic_timer.cc:261
ArmISA::MISCREG_CNTHCTL_EL2
@ MISCREG_CNTHCTL_EL2
Definition: miscregs.hh:765
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:133
SystemCounter::_activeFreqEntry
size_t _activeFreqEntry
Currently selected entry in the table, its contents should match _freq.
Definition: generic_timer.hh:89
SystemCounter::updateValue
void updateValue(void)
Updates the counter value.
Definition: generic_timer.cc:110
ArmSystem
Definition: system.hh:59
GenericTimerMem::COUNTER_CTRL_CNTSCR
static const Addr COUNTER_CTRL_CNTSCR
Definition: generic_timer.hh:536
GenericTimer::CoreTimers::EventStream
Definition: generic_timer.hh:326
GenericTimerFrame::TIMER_CNTVCT_LO
static const Addr TIMER_CNTVCT_LO
Definition: generic_timer.hh:445
ArchTimer::drainResume
void drainResume() override
Resume execution after a successful drain.
Definition: generic_timer.cc:393
ArmISA::MISCREG_CNTHCTL
@ MISCREG_CNTHCTL
Definition: miscregs.hh:423
GenericTimer::CoreTimers::physNS
ArchTimerKvm physNS
Definition: generic_timer.hh:319
warn_if
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
Definition: logging.hh:263
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:197
System::threads
Threads threads
Definition: system.hh:309
ArchTimer::_interrupt
ArmInterruptPin *const _interrupt
Definition: generic_timer.hh:186
ArmISA::PageBytes
const Addr PageBytes
Definition: isa_traits.hh:52
ArchTimer::scheduleEvents
virtual bool scheduleEvents()
Definition: generic_timer.hh:205
ArmISA::MISCREG_CNTHP_CVAL_EL2
@ MISCREG_CNTHP_CVAL_EL2
Definition: miscregs.hh:767
GenericTimer::CoreTimers::virtEvStream
EventStream virtEvStream
Definition: generic_timer.hh:345
ArchTimer::setControl
void setControl(uint32_t val)
Definition: generic_timer.cc:315
AddrRange::start
Addr start() const
Get the start address of the range.
Definition: addr_range.hh:314
base.hh
GenericTimer::GenericTimer
GenericTimer(GenericTimerParams *const p)
Definition: generic_timer.cc:398
GenericTimerFrame::nonSecureAccess
bool nonSecureAccess
Reports whether non-secure accesses are allowed to this frame.
Definition: generic_timer.hh:491
ArmISA::MISCREG_CNTP_CVAL_S
@ MISCREG_CNTP_CVAL_S
Definition: miscregs.hh:415
SimObject::_params
const SimObjectParams * _params
Cached copy of the object parameters.
Definition: sim_object.hh:110
GenericTimer::CoreTimers::cntfrq
uint32_t cntfrq
System counter frequency as visible from this core.
Definition: generic_timer.hh:302
GenericTimerFrame::TIMER_CNTVOFF_LO
static const Addr TIMER_CNTVOFF_LO
Definition: generic_timer.hh:449
SERIALIZE_CONTAINER
#define SERIALIZE_CONTAINER(member)
Definition: serialize.hh:848
insertBits
T insertBits(T val, int first, int last, B bit_val)
Returns val with bits first to last set to the LSBs of bit_val.
Definition: bitfield.hh:147
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
GenericTimerMem::read
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: generic_timer.cc:1297
GenericTimer::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: generic_timer.cc:416
ArmInterruptPin
Generic representation of an Arm interrupt pin.
Definition: base_gic.hh:176
ThreadContext::setMiscReg
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
addr
ip6_addr_t addr
Definition: inet.hh:423
paramIn
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
Definition: types.cc:69
GenericTimerFrame::hasNonSecureAccess
bool hasNonSecureAccess() const
Indicates if non-secure accesses are allowed to this frame.
Definition: generic_timer.cc:955
GenericTimerISA::setMiscReg
void setMiscReg(int misc_reg, RegVal val) override
Write to a system register belonging to this device.
Definition: generic_timer.cc:862
SystemCounter::_value
uint64_t _value
Counter value (as specified in CNTCV).
Definition: generic_timer.hh:83
GenericTimer::CoreTimers::EventStream::transitionTo
uint8_t transitionTo
Definition: generic_timer.hh:329
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:63
GenericTimerMem::TIMER_CTRL_CNTTIDR
static const Addr TIMER_CTRL_CNTTIDR
Definition: generic_timer.hh:558
ArmSystem::setGenericTimer
void setGenericTimer(GenericTimer *generic_timer)
Sets the pointer to the Generic Timer.
Definition: system.hh:179
GenericTimer::CoreTimers
Definition: generic_timer.hh:291
GenericTimer::CoreTimers::CoreTimers
CoreTimers(GenericTimer &_parent, ArmSystem &system, unsigned cpu, ArmInterruptPin *_irqPhysS, ArmInterruptPin *_irqPhysNS, ArmInterruptPin *_irqVirt, ArmInterruptPin *_irqHyp)
Definition: generic_timer.cc:725
ArmISA::MISCREG_CNTP_CVAL_NS
@ MISCREG_CNTP_CVAL_NS
Definition: miscregs.hh:414
ArmISA::MISCREG_CNTVCT_EL0
@ MISCREG_CNTVCT_EL0
Definition: miscregs.hh:747
ArchTimer::_offset
uint64_t _offset
Offset relative to the physical timer (CNTVOFF)
Definition: generic_timer.hh:193
GenericTimerMem::write
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: generic_timer.cc:1324
ArmSystem::PageBytes
static constexpr Addr PageBytes
Definition: system.hh:145
SystemCounter::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: generic_timer.cc:206
GenericTimerMem
Definition: generic_timer.hh:496
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
ArmISA::MISCREG_CNTPS_CVAL_EL1
@ MISCREG_CNTPS_CVAL_EL1
Definition: miscregs.hh:763
std::list< AddrRange >
ArmISA::MISCREG_CNTP_CTL_EL0
@ MISCREG_CNTP_CTL_EL0
Definition: miscregs.hh:748
GenericTimer::CoreTimers::virt
ArchTimerKvm virt
Definition: generic_timer.hh:320
ArchTimer::_counterLimitReachedEvent
EventFunctionWrapper _counterLimitReachedEvent
Definition: generic_timer.hh:203
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:219
GenericTimer::systemCounter
SystemCounter & systemCounter
System counter reference.
Definition: generic_timer.hh:365
GenericTimerFrame::getVirtOffset
uint64_t getVirtOffset() const
Returns the virtual offset for this frame if a virtual timer is implemented.
Definition: generic_timer.cc:925
CheckpointIn
Definition: serialize.hh:67
GenericTimerMem::TIMER_CTRL_CNTACR
static const Addr TIMER_CTRL_CNTACR
Definition: generic_timer.hh:559
ArchTimer::offset
uint64_t offset() const
Definition: generic_timer.hh:230
GenericTimerFrame::setNonSecureAccess
void setNonSecureAccess()
Allows non-secure accesses after an enabling write to CNTCTLBase.CNTNSAR.
Definition: generic_timer.cc:961
ArchTimer::_counterLimit
uint64_t _counterLimit
Programmed limit value for the upcounter ({CNTP/CNTHP/CNTV}_CVAL).
Definition: generic_timer.hh:191
ArmISA::MISCREG_CNTHP_TVAL
@ MISCREG_CNTHP_TVAL
Definition: miscregs.hh:426
GenericTimer::CoreTimers::virtEventStreamCallback
void virtEventStreamCallback()
Definition: generic_timer.cc:769
GenericTimer::createTimers
void createTimers(unsigned cpus)
Definition: generic_timer.cc:467
GenericTimerFrame::GenericTimerFrame
GenericTimerFrame(GenericTimerFrameParams *const p)
Definition: generic_timer.cc:876
ArmISA::MISCREG_CNTVOFF
@ MISCREG_CNTVOFF
Definition: miscregs.hh:427
ArmISA::MISCREG_CNTHP_CVAL
@ MISCREG_CNTHP_CVAL
Definition: miscregs.hh:425
csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:158
ArchTimer::whenValue
Tick whenValue(uint64_t target_val)
Definition: generic_timer.hh:235
GenericTimerMem::TIMER_CTRL_CNTVOFF_HI
static const Addr TIMER_CTRL_CNTVOFF_HI
Definition: generic_timer.hh:561
GenericTimer::setMiscReg
void setMiscReg(int misc_reg, unsigned cpu, RegVal val)
Definition: generic_timer.cc:514
GenericTimerFrame::setAccessBits
void setAccessBits(uint8_t data)
Updates the access bits after a write to CNTCTLBase.CNTACR.
Definition: generic_timer.cc:949
RegVal
uint64_t RegVal
Definition: types.hh:168
GenericTimerMem::timerCtrlRead
uint64_t timerCtrlRead(Addr addr, size_t size, bool is_sec) const
CNTCTLBase (Memory-mapped timer global control frame)
Definition: generic_timer.cc:1489
GenericTimerFrame::TIMER_CNTV_CTL
static const Addr TIMER_CNTV_CTL
Definition: generic_timer.hh:458
GenericTimerMem::TIMER_CTRL_CNTFRQ
static const Addr TIMER_CTRL_CNTFRQ
Definition: generic_timer.hh:556
SystemCounter::freqUpdateSchedule
void freqUpdateSchedule(size_t new_freq_entry)
Schedules a counter frequency update after a CNTCR.FCREQ == 1 This complies with frequency transition...
Definition: generic_timer.cc:161
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
SystemCounter::freqTable
std::vector< uint32_t > & freqTable()
Returns a reference to the frequency modes table.
Definition: generic_timer.hh:118
GenericTimerFrame::TIMER_CNTV_CVAL_LO
static const Addr TIMER_CNTV_CVAL_LO
Definition: generic_timer.hh:455
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
GenericTimerMem::addrRanges
const AddrRangeList addrRanges
All MMIO ranges GenericTimerMem responds to.
Definition: generic_timer.hh:564
GenericTimer::timers
std::vector< std::unique_ptr< CoreTimers > > timers
Per-CPU physical architected timers.
Definition: generic_timer.hh:368
ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:153
GenericTimerMem::systemCounter
SystemCounter & systemCounter
System counter reference.
Definition: generic_timer.hh:567
bits
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:75
SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:92
GenericTimerFrame::TIMER_CNTPCT_HI
static const Addr TIMER_CNTPCT_HI
Definition: generic_timer.hh:444
GenericTimerMem::COUNTER_CTRL_CNTFID
static const Addr COUNTER_CTRL_CNTFID
Definition: generic_timer.hh:538

Generated on Wed Sep 30 2020 14:02:10 for gem5 by doxygen 1.8.17