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

Generated on Tue Mar 23 2021 19:41:25 for gem5 by doxygen 1.8.17