gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
generic_timer.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, 2015, 2017-2018, 2019 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  * Authors: Giacomo Gabrielli
38  * Andreas Sandberg
39  * Adrian Herrera
40  */
41 
42 #include "dev/arm/generic_timer.hh"
43 
44 #include "arch/arm/system.hh"
45 #include "debug/Timer.hh"
46 #include "dev/arm/base_gic.hh"
47 #include "mem/packet_access.hh"
48 #include "params/GenericTimer.hh"
49 #include "params/GenericTimerMem.hh"
50 
52  : _freqTable(freqs),
53  _resetTick(0),
54  _regCntkctl(0)
55 {
56  fatal_if(_freqTable.empty(), "SystemCounter::SystemCounter: Base "
57  "frequency not provided\n");
58  // Store the table end marker as a 32-bit zero word
59  _freqTable.push_back(0);
61  "SystemCounter::SystemCounter: Architecture states a maximum of 1004 "
62  "frequency table entries, limit surpassed\n");
63  // Set the active frequency to be the base
64  _freq = freqs.front();
65  _period = (1.0 / _freq) * SimClock::Frequency;
66 }
67 
68 void
70 {
71  if (_freq != 0) {
72  // Altering the frequency after boot shouldn't be done in practice.
73  warn_once("The frequency of the system counter has already been set");
74  }
75  _freq = freq;
76  _period = (1.0 / freq) * SimClock::Frequency;
77  _resetTick = curTick();
78 }
79 
80 void
82 {
88 }
89 
90 void
92 {
93  // We didn't handle CNTKCTL in this class before, assume it's zero
94  // if it isn't present.
96  _regCntkctl = 0;
98  _regCnthctl = 0;
102 }
103 
104 
105 
106 ArchTimer::ArchTimer(const std::string &name,
107  SimObject &parent,
108  SystemCounter &sysctr,
109  ArmInterruptPin *interrupt)
110  : _name(name), _parent(parent), _systemCounter(sysctr),
111  _interrupt(interrupt),
112  _control(0), _counterLimit(0), _offset(0),
113  _counterLimitReachedEvent([this]{ counterLimitReached(); }, name)
114 {
115 }
116 
117 void
119 {
120  _control.istatus = 1;
121 
122  if (!_control.enable)
123  return;
124 
125  DPRINTF(Timer, "Counter limit reached\n");
126  if (!_control.imask) {
127  if (scheduleEvents()) {
128  DPRINTF(Timer, "Causing interrupt\n");
129  _interrupt->raise();
130  } else {
131  DPRINTF(Timer, "Kvm mode; skipping simulated interrupt\n");
132  }
133  }
134 }
135 
136 void
138 {
141  if (value() >= _counterLimit) {
143  } else {
144  _control.istatus = 0;
145  if (scheduleEvents()) {
146  const auto period(_systemCounter.period());
148  curTick() + (_counterLimit - value()) * period);
149  }
150  }
151 }
152 
153 void
155 {
156  _counterLimit = val;
157  updateCounter();
158 }
159 
160 void
162 {
163  setCompareValue(value() + sext<32>(val));
164 }
165 
166 void
168 {
169  ArchTimerCtrl new_ctl = val;
170  if ((new_ctl.enable && !new_ctl.imask) &&
171  !(_control.enable && !_control.imask)) {
172  // Re-evalute the timer condition
173  if (_counterLimit >= value()) {
174  _control.istatus = 1;
175 
176  DPRINTF(Timer, "Causing interrupt in control\n");
177  //_interrupt.send();
178  }
179  }
180  _control.enable = new_ctl.enable;
181  _control.imask = new_ctl.imask;
182 }
183 
184 void
186 {
187  _offset = val;
188  updateCounter();
189 }
190 
191 uint64_t
193 {
194  return _systemCounter.value() - _offset;
195 }
196 
197 void
199 {
200  paramOut(cp, "control_serial", _control);
203 }
204 
205 void
207 {
208  paramIn(cp, "control_serial", _control);
209  // We didn't serialize an offset before we added support for the
210  // virtual timer. Consider it optional to maintain backwards
211  // compatibility.
213  _offset = 0;
214 
215  // We no longer schedule an event here because we may enter KVM
216  // emulation. The event creation is delayed until drainResume().
217 }
218 
221 {
224 
225  return DrainState::Drained;
226 }
227 
228 void
230 {
231  updateCounter();
232 }
233 
234 GenericTimer::GenericTimer(GenericTimerParams *p)
235  : ClockedObject(p),
236  systemCounter(p->freqs),
237  system(*p->system)
238 {
239  fatal_if(!p->system, "No system specified, can't instantiate timer.\n");
240  system.setGenericTimer(this);
241 }
242 
243 const GenericTimerParams *
245 {
246  return dynamic_cast<const GenericTimerParams *>(_params);
247 }
248 
249 void
251 {
252  paramOut(cp, "cpu_count", timers.size());
253 
254  systemCounter.serializeSection(cp, "sys_counter");
255 
256  for (int i = 0; i < timers.size(); ++i) {
257  const CoreTimers &core(*timers[i]);
258 
259  // This should really be phys_timerN, but we are stuck with
260  // arch_timer for backwards compatibility.
261  core.physNS.serializeSection(cp, csprintf("arch_timer%d", i));
262  core.physS.serializeSection(cp, csprintf("phys_s_timer%d", i));
263  core.virt.serializeSection(cp, csprintf("virt_timer%d", i));
264  core.hyp.serializeSection(cp, csprintf("hyp_timer%d", i));
265  }
266 }
267 
268 void
270 {
271  systemCounter.unserializeSection(cp, "sys_counter");
272 
273  // Try to unserialize the CPU count. Old versions of the timer
274  // model assumed a 8 CPUs, so we fall back to that if the field
275  // isn't present.
276  static const unsigned OLD_CPU_MAX = 8;
277  unsigned cpu_count;
278  if (!UNSERIALIZE_OPT_SCALAR(cpu_count)) {
279  warn("Checkpoint does not contain CPU count, assuming %i CPUs\n",
280  OLD_CPU_MAX);
281  cpu_count = OLD_CPU_MAX;
282  }
283 
284  for (int i = 0; i < cpu_count; ++i) {
285  CoreTimers &core(getTimers(i));
286  // This should really be phys_timerN, but we are stuck with
287  // arch_timer for backwards compatibility.
288  core.physNS.unserializeSection(cp, csprintf("arch_timer%d", i));
289  core.physS.unserializeSection(cp, csprintf("phys_s_timer%d", i));
290  core.virt.unserializeSection(cp, csprintf("virt_timer%d", i));
291  core.hyp.unserializeSection(cp, csprintf("hyp_timer%d", i));
292  }
293 }
294 
295 
298 {
299  if (cpu_id >= timers.size())
300  createTimers(cpu_id + 1);
301 
302  return *timers[cpu_id];
303 }
304 
305 void
307 {
308  assert(timers.size() < cpus);
309  auto p = static_cast<const GenericTimerParams *>(_params);
310 
311  const unsigned old_cpu_count(timers.size());
312  timers.resize(cpus);
313  for (unsigned i = old_cpu_count; i < cpus; ++i) {
314 
316 
317  timers[i].reset(
318  new CoreTimers(*this, system, i,
319  p->int_phys_s->get(tc),
320  p->int_phys_ns->get(tc),
321  p->int_virt->get(tc),
322  p->int_hyp->get(tc)));
323  }
324 }
325 
326 
327 void
329 {
330  CoreTimers &core(getTimers(cpu));
331 
332  switch (reg) {
333  case MISCREG_CNTFRQ:
334  case MISCREG_CNTFRQ_EL0:
335  systemCounter.setFreq(val);
336  return;
337 
338  case MISCREG_CNTKCTL:
339  case MISCREG_CNTKCTL_EL1:
341  return;
342 
343  case MISCREG_CNTHCTL:
344  case MISCREG_CNTHCTL_EL2:
346  return;
347 
348  // Physical timer (NS)
351  core.physNS.setCompareValue(val);
352  return;
353 
356  core.physNS.setTimerValue(val);
357  return;
358 
359  case MISCREG_CNTP_CTL_NS:
361  core.physNS.setControl(val);
362  return;
363 
364  // Count registers
365  case MISCREG_CNTPCT:
366  case MISCREG_CNTPCT_EL0:
367  case MISCREG_CNTVCT:
368  case MISCREG_CNTVCT_EL0:
369  warn("Ignoring write to read only count register: %s\n",
370  miscRegName[reg]);
371  return;
372 
373  // Virtual timer
374  case MISCREG_CNTVOFF:
375  case MISCREG_CNTVOFF_EL2:
376  core.virt.setOffset(val);
377  return;
378 
379  case MISCREG_CNTV_CVAL:
381  core.virt.setCompareValue(val);
382  return;
383 
384  case MISCREG_CNTV_TVAL:
386  core.virt.setTimerValue(val);
387  return;
388 
389  case MISCREG_CNTV_CTL:
391  core.virt.setControl(val);
392  return;
393 
394  // Physical timer (S)
395  case MISCREG_CNTP_CTL_S:
397  core.physS.setControl(val);
398  return;
399 
400  case MISCREG_CNTP_CVAL_S:
402  core.physS.setCompareValue(val);
403  return;
404 
405  case MISCREG_CNTP_TVAL_S:
407  core.physS.setTimerValue(val);
408  return;
409 
410  // Hyp phys. timer, non-secure
411  case MISCREG_CNTHP_CTL:
413  core.hyp.setControl(val);
414  return;
415 
416  case MISCREG_CNTHP_CVAL:
418  core.hyp.setCompareValue(val);
419  return;
420 
421  case MISCREG_CNTHP_TVAL:
423  core.hyp.setTimerValue(val);
424  return;
425 
426  default:
427  warn("Writing to unknown register: %s\n", miscRegName[reg]);
428  return;
429  }
430 }
431 
432 
433 RegVal
434 GenericTimer::readMiscReg(int reg, unsigned cpu)
435 {
436  CoreTimers &core(getTimers(cpu));
437 
438  switch (reg) {
439  case MISCREG_CNTFRQ:
440  case MISCREG_CNTFRQ_EL0:
441  return systemCounter.freq();
442 
443  case MISCREG_CNTKCTL:
444  case MISCREG_CNTKCTL_EL1:
446 
447  case MISCREG_CNTHCTL:
448  case MISCREG_CNTHCTL_EL2:
449  return systemCounter.getHypControl();
450 
451  // Physical timer
454  return core.physNS.compareValue();
455 
458  return core.physNS.timerValue();
459 
461  case MISCREG_CNTP_CTL_NS:
462  return core.physNS.control();
463 
464  case MISCREG_CNTPCT:
465  case MISCREG_CNTPCT_EL0:
466  return core.physNS.value();
467 
468 
469  // Virtual timer
470  case MISCREG_CNTVCT:
471  case MISCREG_CNTVCT_EL0:
472  return core.virt.value();
473 
474  case MISCREG_CNTVOFF:
475  case MISCREG_CNTVOFF_EL2:
476  return core.virt.offset();
477 
478  case MISCREG_CNTV_CVAL:
480  return core.virt.compareValue();
481 
482  case MISCREG_CNTV_TVAL:
484  return core.virt.timerValue();
485 
486  case MISCREG_CNTV_CTL:
488  return core.virt.control();
489 
490  // PL1 phys. timer, secure
491  case MISCREG_CNTP_CTL_S:
493  return core.physS.control();
494 
495  case MISCREG_CNTP_CVAL_S:
497  return core.physS.compareValue();
498 
499  case MISCREG_CNTP_TVAL_S:
501  return core.physS.timerValue();
502 
503  // HYP phys. timer (NS)
504  case MISCREG_CNTHP_CTL:
506  return core.hyp.control();
507 
508  case MISCREG_CNTHP_CVAL:
510  return core.hyp.compareValue();
511 
512  case MISCREG_CNTHP_TVAL:
514  return core.hyp.timerValue();
515 
516  default:
517  warn("Reading from unknown register: %s\n", miscRegName[reg]);
518  return 0;
519  }
520 }
521 
522 
523 void
525 {
526  DPRINTF(Timer, "Setting %s := 0x%x\n", miscRegName[reg], val);
527  parent.setMiscReg(reg, cpu, val);
528 }
529 
530 RegVal
532 {
533  RegVal value = parent.readMiscReg(reg, cpu);
534  DPRINTF(Timer, "Reading %s as 0x%x\n", miscRegName[reg], value);
535  return value;
536 }
537 
538 GenericTimerMem::GenericTimerMem(GenericTimerMemParams *p)
539  : PioDevice(p),
540  ctrlRange(RangeSize(p->base, sys->getPageBytes())),
541  timerRange(RangeSize(p->base + sys->getPageBytes(),
542  sys->getPageBytes())),
543  addrRanges{ctrlRange, timerRange},
544  systemCounter(p->freqs),
545  physTimer(csprintf("%s.phys_timer0", name()),
546  *this, systemCounter,
547  p->int_phys->get()),
548  virtTimer(csprintf("%s.virt_timer0", name()),
549  *this, systemCounter,
550  p->int_virt->get())
551 {
552 }
553 
554 void
556 {
557  paramOut(cp, "timer_count", 1);
558 
559  systemCounter.serializeSection(cp, "sys_counter");
560 
561  physTimer.serializeSection(cp, "phys_timer0");
562  virtTimer.serializeSection(cp, "virt_timer0");
563 }
564 
565 void
567 {
568  systemCounter.unserializeSection(cp, "sys_counter");
569 
570  unsigned timer_count;
571  UNSERIALIZE_SCALAR(timer_count);
572  // The timer count variable is just here for future versions where
573  // we support more than one set of timers.
574  if (timer_count != 1)
575  panic("Incompatible checkpoint: Only one set of timers supported");
576 
577  physTimer.unserializeSection(cp, "phys_timer0");
578  virtTimer.unserializeSection(cp, "virt_timer0");
579 }
580 
581 Tick
583 {
584  const unsigned size(pkt->getSize());
585  const Addr addr(pkt->getAddr());
586  uint64_t value;
587 
588  pkt->makeResponse();
589  if (ctrlRange.contains(addr)) {
590  value = ctrlRead(addr - ctrlRange.start(), size);
591  } else if (timerRange.contains(addr)) {
592  value = timerRead(addr - timerRange.start(), size);
593  } else {
594  panic("Invalid address: 0x%x\n", addr);
595  }
596 
597  DPRINTF(Timer, "Read 0x%x <- 0x%x(%i)\n", value, addr, size);
598 
599  if (size == 8) {
600  pkt->setLE<uint64_t>(value);
601  } else if (size == 4) {
602  pkt->setLE<uint32_t>(value);
603  } else {
604  panic("Unexpected access size: %i\n", size);
605  }
606 
607  return 0;
608 }
609 
610 Tick
612 {
613  const unsigned size(pkt->getSize());
614  if (size != 8 && size != 4)
615  panic("Unexpected access size\n");
616 
617  const Addr addr(pkt->getAddr());
618  const uint64_t value(size == 8 ?
619  pkt->getLE<uint64_t>() : pkt->getLE<uint32_t>());
620 
621  DPRINTF(Timer, "Write 0x%x -> 0x%x(%i)\n", value, addr, size);
622  if (ctrlRange.contains(addr)) {
623  ctrlWrite(addr - ctrlRange.start(), size, value);
624  } else if (timerRange.contains(addr)) {
625  timerWrite(addr - timerRange.start(), size, value);
626  } else {
627  panic("Invalid address: 0x%x\n", addr);
628  }
629 
630  pkt->makeResponse();
631  return 0;
632 }
633 
634 uint64_t
636 {
637  if (size == 4) {
638  switch (addr) {
639  case CTRL_CNTFRQ:
640  return systemCounter.freq();
641 
642  case CTRL_CNTTIDR:
643  return 0x3; // Frame 0 implemented with virtual timers
644 
645  case CTRL_CNTNSAR:
646  case CTRL_CNTACR_BASE:
647  warn("Reading from unimplemented control register (0x%x)\n", addr);
648  return 0;
649 
651  return virtTimer.offset();
652 
654  return virtTimer.offset() >> 32;
655 
656  default:
657  warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size);
658  return 0;
659  }
660  } else if (size == 8) {
661  switch (addr) {
663  return virtTimer.offset();
664 
665  default:
666  warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size);
667  return 0;
668  }
669  } else {
670  panic("Invalid access size: %i\n", size);
671  }
672 }
673 
674 void
675 GenericTimerMem::ctrlWrite(Addr addr, size_t size, uint64_t value)
676 {
677  if (size == 4) {
678  switch (addr) {
679  case CTRL_CNTFRQ:
680  case CTRL_CNTNSAR:
681  case CTRL_CNTTIDR:
682  case CTRL_CNTACR_BASE:
683  warn("Write to unimplemented control register (0x%x)\n", addr);
684  return;
685 
688  insertBits(virtTimer.offset(), 31, 0, value));
689  return;
690 
693  insertBits(virtTimer.offset(), 63, 32, value));
694  return;
695 
696  default:
697  warn("Ignoring write to unexpected address (0x%x:%i)\n",
698  addr, size);
699  return;
700  }
701  } else if (size == 8) {
702  switch (addr) {
704  virtTimer.setOffset(value);
705  return;
706 
707  default:
708  warn("Ignoring write to unexpected address (0x%x:%i)\n",
709  addr, size);
710  return;
711  }
712  } else {
713  panic("Invalid access size: %i\n", size);
714  }
715 }
716 
717 uint64_t
719 {
720  if (size == 4) {
721  switch (addr) {
722  case TIMER_CNTPCT_LO:
723  return physTimer.value();
724 
725  case TIMER_CNTPCT_HI:
726  return physTimer.value() >> 32;
727 
728  case TIMER_CNTVCT_LO:
729  return virtTimer.value();
730 
731  case TIMER_CNTVCT_HI:
732  return virtTimer.value() >> 32;
733 
734  case TIMER_CNTFRQ:
735  return systemCounter.freq();
736 
737  case TIMER_CNTEL0ACR:
738  warn("Read from unimplemented timer register (0x%x)\n", addr);
739  return 0;
740 
742  return virtTimer.offset();
743 
745  return virtTimer.offset() >> 32;
746 
747  case TIMER_CNTP_CVAL_LO:
748  return physTimer.compareValue();
749 
750  case TIMER_CNTP_CVAL_HI:
751  return physTimer.compareValue() >> 32;
752 
753  case TIMER_CNTP_TVAL:
754  return physTimer.timerValue();
755 
756  case TIMER_CNTP_CTL:
757  return physTimer.control();
758 
759  case TIMER_CNTV_CVAL_LO:
760  return virtTimer.compareValue();
761 
762  case TIMER_CNTV_CVAL_HI:
763  return virtTimer.compareValue() >> 32;
764 
765  case TIMER_CNTV_TVAL:
766  return virtTimer.timerValue();
767 
768  case TIMER_CNTV_CTL:
769  return virtTimer.control();
770 
771  default:
772  warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size);
773  return 0;
774  }
775  } else if (size == 8) {
776  switch (addr) {
777  case TIMER_CNTPCT_LO:
778  return physTimer.value();
779 
780  case TIMER_CNTVCT_LO:
781  return virtTimer.value();
782 
784  return virtTimer.offset();
785 
786  case TIMER_CNTP_CVAL_LO:
787  return physTimer.compareValue();
788 
789  case TIMER_CNTV_CVAL_LO:
790  return virtTimer.compareValue();
791 
792  default:
793  warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size);
794  return 0;
795  }
796  } else {
797  panic("Invalid access size: %i\n", size);
798  }
799 }
800 
801 void
802 GenericTimerMem::timerWrite(Addr addr, size_t size, uint64_t value)
803 {
804  if (size == 4) {
805  switch (addr) {
806  case TIMER_CNTEL0ACR:
807  warn("Unimplemented timer register (0x%x)\n", addr);
808  return;
809 
810  case TIMER_CNTP_CVAL_LO:
812  insertBits(physTimer.compareValue(), 31, 0, value));
813  return;
814 
815  case TIMER_CNTP_CVAL_HI:
817  insertBits(physTimer.compareValue(), 63, 32, value));
818  return;
819 
820  case TIMER_CNTP_TVAL:
821  physTimer.setTimerValue(value);
822  return;
823 
824  case TIMER_CNTP_CTL:
825  physTimer.setControl(value);
826  return;
827 
828  case TIMER_CNTV_CVAL_LO:
830  insertBits(virtTimer.compareValue(), 31, 0, value));
831  return;
832 
833  case TIMER_CNTV_CVAL_HI:
835  insertBits(virtTimer.compareValue(), 63, 32, value));
836  return;
837 
838  case TIMER_CNTV_TVAL:
839  virtTimer.setTimerValue(value);
840  return;
841 
842  case TIMER_CNTV_CTL:
843  virtTimer.setControl(value);
844  return;
845 
846  default:
847  warn("Unexpected address (0x%x:%i), ignoring write\n", addr, size);
848  return;
849  }
850  } else if (size == 8) {
851  switch (addr) {
852  case TIMER_CNTP_CVAL_LO:
853  return physTimer.setCompareValue(value);
854 
855  case TIMER_CNTV_CVAL_LO:
856  return virtTimer.setCompareValue(value);
857 
858  default:
859  warn("Unexpected address (0x%x:%i), ignoring write\n", addr, size);
860  return;
861  }
862  } else {
863  panic("Invalid access size: %i\n", size);
864  }
865 }
866 
867 GenericTimer *
868 GenericTimerParams::create()
869 {
870  return new GenericTimer(this);
871 }
872 
874 GenericTimerMemParams::create()
875 {
876  return new GenericTimerMem(this);
877 }
void unserialize(CheckpointIn &cp) override
Unserialize an object.
ArchTimer(const std::string &name, SimObject &parent, SystemCounter &sysctr, ArmInterruptPin *interrupt)
void setMiscReg(int misc_reg, RegVal val) override
Write to a system register belonging to this device.
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
#define DPRINTF(x,...)
Definition: trace.hh:229
EventFunctionWrapper _counterLimitReachedEvent
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:584
void setFreq(uint32_t freq)
Sets the counter frequency.
uint64_t offset() const
uint64_t _counterLimit
Programmed limit value for the upcounter ({CNTP/CNTHP/CNTV}_CVAL).
std::vector< uint32_t > _freqTable
Frequency modes table with all possible frequencies for the counter.
void setMiscReg(int misc_reg, unsigned cpu, RegVal val)
uint64_t ctrlRead(Addr addr, size_t size) const
GenericTimer(GenericTimerParams *p)
Bitfield< 5, 3 > reg
Definition: types.hh:89
void unserialize(CheckpointIn &cp) override
Unserialize an object.
static const Addr TIMER_CNTVCT_LO
static const Addr TIMER_CNTFRQ
CoreTimers & getTimers(int cpu_id)
const std::string & name()
Definition: trace.cc:54
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Definition: serialize.cc:176
Bitfield< 7 > i
This module implements the global system counter and the local per-CPU architected timers as specifie...
DrainState
Object drain/handover states.
Definition: drain.hh:71
static const Addr TIMER_CNTP_TVAL
DrainState drain() override
Notify an object that it needs to drain its state.
#define UNSERIALIZE_OPT_SCALAR(scalar)
Definition: serialize.hh:646
RegVal readMiscReg(int misc_reg, unsigned cpu)
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
Definition: serialize.cc:183
static const Addr TIMER_CNTV_CVAL_LO
uint32_t _regCntkctl
Kernel event stream control register.
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:406
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
ip6_addr_t addr
Definition: inet.hh:335
SystemCounter(std::vector< uint32_t > &freqs)
void timerWrite(Addr addr, size_t size, uint64_t value)
uint64_t RegVal
Definition: types.hh:168
uint64_t value() const
Returns the value of the counter which this timer relies on.
uint32_t freq() const
Returns the counter frequency.
const char *const miscRegName[]
Definition: miscregs.hh:1021
uint64_t value() const
Returns the current value of the physical counter.
Definition: cprintf.cc:42
GenericTimerMem(GenericTimerMemParams *p)
Tick Frequency
The simulated frequency of curTick(). (In ticks per second)
Definition: core.cc:49
ThreadContext is the external interface to all thread state for anything outside of the CPU...
ArmSystem & system
ARM system containing this timer.
void setTimerValue(uint32_t val)
Sets the TimerValue view of the timer.
void deschedule(Event &event)
Definition: eventq.hh:750
const GenericTimerParams * params() const
void setGenericTimer(GenericTimer *generic_timer)
Sets the pointer to the Generic Timer.
Definition: system.hh:202
Bitfield< 63 > val
Definition: misc.hh:771
ArchTimerCtrl _control
Value of the control register ({CNTP/CNTHP/CNTV}_CTL).
void setLE(T v)
Set the value in the data pointer to v as little endian.
static const Addr TIMER_CNTV_CTL
ThreadContext * getThreadContext(ContextID tid) const
Definition: system.hh:194
uint32_t getHypControl()
void counterLimitReached()
Called when the upcounter reaches the programmed value.
Tick _resetTick
Tick when the counter was reset.
Tick _period
Cached copy of the counter period (inverse of the frequency).
unsigned getSize() const
Definition: packet.hh:736
static const Addr CTRL_CNTVOFF_HI_BASE
uint64_t timerRead(Addr addr, size_t size) const
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:645
void setOffset(uint64_t val)
Tick curTick()
The current simulated tick.
Definition: core.hh:47
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:162
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:385
void serialize(CheckpointOut &cp) const override
Serialize an object.
const AddrRange ctrlRange
uint64_t Tick
Tick count type.
Definition: types.hh:63
SystemCounter systemCounter
System counter.
void createTimers(unsigned cpus)
void serialize(CheckpointOut &cp) const override
Serialize an object.
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
void paramOut(CheckpointOut &cp, const string &name, ExtMachInst const &machInst)
Definition: types.cc:40
void setCompareValue(uint64_t val)
Sets the CompareValue view of the timer.
Bitfield< 51, 12 > base
Definition: pagetable.hh:142
uint32_t getKernelControl()
static constexpr size_t MAX_FREQ_ENTRIES
Maximum architectural number of frequency table entries.
uint32_t _regCnthctl
Hypervisor event stream control register.
void setKernelControl(uint32_t val)
Addr getAddr() const
Definition: packet.hh:726
static const Addr CTRL_CNTACR_BASE
uint32_t timerValue() const
Returns the TimerValue view of the timer.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:203
void ctrlWrite(Addr addr, size_t size, uint64_t value)
T insertBits(T val, int first, int last, B bit_val)
Returns val with bits first to last set to the LSBs of bit_val.
Definition: bitfield.hh:132
ArchTimer physTimer
This device is the base class which all devices senstive to an address range inherit from...
Definition: io_device.hh:102
static const Addr TIMER_CNTEL0ACR
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Draining buffers pending serialization/handover.
virtual bool scheduleEvents()
virtual const std::string name() const
Definition: sim_object.hh:120
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:255
RegVal readMiscReg(int misc_reg) override
Read a system register belonging to this device.
#define warn_once(...)
Definition: logging.hh:216
Bitfield< 15 > system
Definition: misc.hh:999
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:643
ArchTimer virtTimer
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:937
std::string name() const
Returns the timer name.
Base class for ARM GIC implementations.
static const Addr TIMER_CNTPCT_LO
static const Addr CTRL_CNTTIDR
virtual void raise()=0
Signal an interrupt.
void serialize(CheckpointOut &cp) const override
Serialize an object.
std::ostream CheckpointOut
Definition: serialize.hh:68
static const Addr TIMER_CNTP_CTL
void serialize(CheckpointOut &cp) const override
Serialize an object.
static const Addr TIMER_CNTP_CVAL_LO
static const Addr TIMER_CNTV_TVAL
static const Addr TIMER_CNTP_CVAL_HI
void unserialize(CheckpointIn &cp) override
Unserialize an object.
const SimObjectParams * _params
Cached copy of the object parameters.
Definition: sim_object.hh:110
void unserialize(CheckpointIn &cp) override
Unserialize an object.
uint64_t compareValue() const
Returns the CompareValue view of the timer.
static const Addr CTRL_CNTNSAR
void schedule(Event &event, Tick when)
Definition: eventq.hh:744
void drainResume() override
Resume execution after a successful drain.
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
Definition: types.cc:71
SystemCounter systemCounter
System counter.
void setHypControl(uint32_t val)
ArmInterruptPin *const _interrupt
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
Addr start() const
Get the start address of the range.
Definition: addr_range.hh:297
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
void setControl(uint32_t val)
std::vector< std::unique_ptr< CoreTimers > > timers
Per-CPU physical architected timers.
#define warn(...)
Definition: logging.hh:212
const AddrRange timerRange
static const Addr TIMER_CNTV_CVAL_HI
static const Addr CTRL_CNTFRQ
SystemCounter & _systemCounter
static const Addr TIMER_CNTVCT_HI
uint32_t control() const
Sets the control register.
void updateCounter()
Timer settings or the offset has changed, re-evaluate trigger condition and raise interrupt if necess...
Global system counter.
Bitfield< 0 > p
static const Addr TIMER_CNTPCT_HI
Generic representation of an Arm interrupt pin.
Definition: base_gic.hh:178
Tick period() const
Returns the counter period.
Abstract superclass for simulation objects.
Definition: sim_object.hh:96
uint32_t _freq
Counter frequency (as specified by CNTFRQ).
uint64_t _offset
Offset relative to the physical timer (CNTVOFF)
static const Addr CTRL_CNTVOFF_LO_BASE
EndBitUnion(ArchTimerCtrl) const std SimObject & _parent
Name of this timer.

Generated on Fri Feb 28 2020 16:27:00 for gem5 by doxygen 1.8.13