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

Generated on Tue Sep 21 2021 12:25:10 for gem5 by doxygen 1.8.17