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

Generated on Wed May 4 2022 12:13:55 for gem5 by doxygen 1.8.17