gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
generic_timer.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, 2015, 2017 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  */
40 
41 #include "dev/arm/generic_timer.hh"
42 
43 #include "arch/arm/system.hh"
44 #include "debug/Timer.hh"
45 #include "dev/arm/base_gic.hh"
46 #include "mem/packet_access.hh"
47 #include "params/GenericTimer.hh"
48 #include "params/GenericTimerMem.hh"
49 
51  : _freq(0), _period(0), _resetTick(0), _regCntkctl(0)
52 {
53  setFreq(0x01800000);
54 }
55 
56 void
57 SystemCounter::setFreq(uint32_t freq)
58 {
59  if (_freq != 0) {
60  // Altering the frequency after boot shouldn't be done in practice.
61  warn_once("The frequency of the system counter has already been set");
62  }
63  _freq = freq;
64  _period = (1.0 / freq) * SimClock::Frequency;
65  _resetTick = curTick();
66 }
67 
68 void
70 {
75 }
76 
77 void
79 {
80  // We didn't handle CNTKCTL in this class before, assume it's zero
81  // if it isn't present.
83  _regCntkctl = 0;
87 }
88 
89 
90 
91 ArchTimer::ArchTimer(const std::string &name,
92  SimObject &parent,
93  SystemCounter &sysctr,
94  const Interrupt &interrupt)
95  : _name(name), _parent(parent), _systemCounter(sysctr),
96  _interrupt(interrupt),
97  _control(0), _counterLimit(0), _offset(0),
98  _counterLimitReachedEvent(this)
99 {
100 }
101 
102 void
104 {
105  _control.istatus = 1;
106 
107  if (!_control.enable)
108  return;
109 
110  DPRINTF(Timer, "Counter limit reached\n");
111  if (!_control.imask) {
112  DPRINTF(Timer, "Causing interrupt\n");
113  _interrupt.send();
114  }
115 }
116 
117 void
119 {
122  if (value() >= _counterLimit) {
124  } else {
125  const auto period(_systemCounter.period());
126  _control.istatus = 0;
128  curTick() + (_counterLimit - value()) * period);
129  }
130 }
131 
132 void
134 {
135  _counterLimit = val;
136  updateCounter();
137 }
138 
139 void
141 {
142  setCompareValue(value() + sext<32>(val));
143 }
144 
145 void
147 {
148  ArchTimerCtrl new_ctl = val;
149  if ((new_ctl.enable && !new_ctl.imask) &&
150  !(_control.enable && !_control.imask)) {
151  // Re-evalute the timer condition
152  if (_counterLimit >= value()) {
153  _control.istatus = 1;
154 
155  DPRINTF(Timer, "Causing interrupt in control\n");
156  //_interrupt.send();
157  }
158  }
159  _control.enable = new_ctl.enable;
160  _control.imask = new_ctl.imask;
161 }
162 
163 void
165 {
166  _offset = val;
167  updateCounter();
168 }
169 
170 uint64_t
172 {
173  return _systemCounter.value() - _offset;
174 }
175 
176 void
178 {
179  paramOut(cp, "control_serial", _control);
182 
183  const bool event_scheduled(_counterLimitReachedEvent.scheduled());
184  SERIALIZE_SCALAR(event_scheduled);
185  if (event_scheduled) {
186  const Tick event_time(_counterLimitReachedEvent.when());
187  SERIALIZE_SCALAR(event_time);
188  }
189 }
190 
191 void
193 {
194  paramIn(cp, "control_serial", _control);
195  // We didn't serialize an offset before we added support for the
196  // virtual timer. Consider it optional to maintain backwards
197  // compatibility.
199  _offset = 0;
200  bool event_scheduled;
201  UNSERIALIZE_SCALAR(event_scheduled);
202  if (event_scheduled) {
203  Tick event_time;
204  UNSERIALIZE_SCALAR(event_time);
206  }
207 }
208 
209 void
211 {
212  if (_ppi) {
214  } else {
215  _gic.sendInt(_irq);
216  }
217 }
218 
219 
220 void
222 {
223  if (_ppi) {
224  _gic.clearPPInt(_irq, _cpu);
225  } else {
226  _gic.clearInt(_irq);
227  }
228 }
229 
230 
231 GenericTimer::GenericTimer(GenericTimerParams *p)
232  : SimObject(p),
233  gic(p->gic),
234  irqPhys(p->int_phys),
235  irqVirt(p->int_virt)
236 {
237  fatal_if(!p->system, "No system specified, can't instantiate timer.\n");
238  p->system->setGenericTimer(this);
239 }
240 
241 void
243 {
244  paramOut(cp, "cpu_count", timers.size());
245 
246  systemCounter.serializeSection(cp, "sys_counter");
247 
248  for (int i = 0; i < timers.size(); ++i) {
249  const CoreTimers &core(*timers[i]);
250 
251  // This should really be phys_timerN, but we are stuck with
252  // arch_timer for backwards compatibility.
253  core.phys.serializeSection(cp, csprintf("arch_timer%d", i));
254  core.virt.serializeSection(cp, csprintf("virt_timer%d", i));
255  }
256 }
257 
258 void
260 {
261  systemCounter.unserializeSection(cp, "sys_counter");
262 
263  // Try to unserialize the CPU count. Old versions of the timer
264  // model assumed a 8 CPUs, so we fall back to that if the field
265  // isn't present.
266  static const unsigned OLD_CPU_MAX = 8;
267  unsigned cpu_count;
268  if (!UNSERIALIZE_OPT_SCALAR(cpu_count)) {
269  warn("Checkpoint does not contain CPU count, assuming %i CPUs\n",
270  OLD_CPU_MAX);
271  cpu_count = OLD_CPU_MAX;
272  }
273 
274  for (int i = 0; i < cpu_count; ++i) {
275  CoreTimers &core(getTimers(i));
276  // This should really be phys_timerN, but we are stuck with
277  // arch_timer for backwards compatibility.
278  core.phys.unserializeSection(cp, csprintf("arch_timer%d", i));
279  core.virt.unserializeSection(cp, csprintf("virt_timer%d", i));
280  }
281 }
282 
283 
286 {
287  if (cpu_id >= timers.size())
288  createTimers(cpu_id + 1);
289 
290  return *timers[cpu_id];
291 }
292 
293 void
295 {
296  assert(timers.size() < cpus);
297 
298  const unsigned old_cpu_count(timers.size());
299  timers.resize(cpus);
300  for (unsigned i = old_cpu_count; i < cpus; ++i) {
301  timers[i].reset(
302  new CoreTimers(*this, i, irqPhys, irqVirt));
303  }
304 }
305 
306 
307 void
309 {
310  // This method might have been called from another context if we
311  // are running in multi-core KVM. Migrate to the SimObject's event
312  // queue to prevent surprising race conditions.
314 
315  CoreTimers &core(getTimers(cpu));
316 
317  switch (reg) {
318  case MISCREG_CNTFRQ:
319  case MISCREG_CNTFRQ_EL0:
320  systemCounter.setFreq(val);
321  return;
322 
323  case MISCREG_CNTKCTL:
324  case MISCREG_CNTKCTL_EL1:
326  return;
327 
328  // Physical timer
329  case MISCREG_CNTP_CVAL:
332  core.phys.setCompareValue(val);
333  return;
334 
335  case MISCREG_CNTP_TVAL:
338  core.phys.setTimerValue(val);
339  return;
340 
341  case MISCREG_CNTP_CTL:
342  case MISCREG_CNTP_CTL_NS:
344  core.phys.setControl(val);
345  return;
346 
347  // Count registers
348  case MISCREG_CNTPCT:
349  case MISCREG_CNTPCT_EL0:
350  case MISCREG_CNTVCT:
351  case MISCREG_CNTVCT_EL0:
352  warn("Ignoring write to read only count register: %s\n",
353  miscRegName[reg]);
354  return;
355 
356  // Virtual timer
357  case MISCREG_CNTVOFF:
358  case MISCREG_CNTVOFF_EL2:
359  core.virt.setOffset(val);
360  return;
361 
362  case MISCREG_CNTV_CVAL:
364  core.virt.setCompareValue(val);
365  return;
366 
367  case MISCREG_CNTV_TVAL:
369  core.virt.setTimerValue(val);
370  return;
371 
372  case MISCREG_CNTV_CTL:
374  core.virt.setControl(val);
375  return;
376 
377  // PL1 phys. timer, secure
378  case MISCREG_CNTP_CTL_S:
382  /* FALLTHROUGH */
383 
384  // PL2 phys. timer, non-secure
385  case MISCREG_CNTHCTL:
386  case MISCREG_CNTHCTL_EL2:
387  case MISCREG_CNTHP_CVAL:
389  case MISCREG_CNTHP_TVAL:
391  case MISCREG_CNTHP_CTL:
393  warn("Writing to unimplemented register: %s\n",
394  miscRegName[reg]);
395  return;
396 
397  default:
398  warn("Writing to unknown register: %s\n", miscRegName[reg]);
399  return;
400  }
401 }
402 
403 
404 MiscReg
405 GenericTimer::readMiscReg(int reg, unsigned cpu)
406 {
407  // This method might have been called from another context if we
408  // are running in multi-core KVM. Migrate to the SimObject's event
409  // queue to prevent surprising race conditions.
411 
412  CoreTimers &core(getTimers(cpu));
413 
414  switch (reg) {
415  case MISCREG_CNTFRQ:
416  case MISCREG_CNTFRQ_EL0:
417  return systemCounter.freq();
418 
419  case MISCREG_CNTKCTL:
420  case MISCREG_CNTKCTL_EL1:
422 
423  // Physical timer
424  case MISCREG_CNTP_CVAL:
426  return core.phys.compareValue();
427 
428  case MISCREG_CNTP_TVAL:
430  return core.phys.timerValue();
431 
432  case MISCREG_CNTP_CTL:
434  case MISCREG_CNTP_CTL_NS:
435  return core.phys.control();
436 
437  case MISCREG_CNTPCT:
438  case MISCREG_CNTPCT_EL0:
439  return core.phys.value();
440 
441 
442  // Virtual timer
443  case MISCREG_CNTVCT:
444  case MISCREG_CNTVCT_EL0:
445  return core.virt.value();
446 
447  case MISCREG_CNTVOFF:
448  case MISCREG_CNTVOFF_EL2:
449  return core.virt.offset();
450 
451  case MISCREG_CNTV_CVAL:
453  return core.virt.compareValue();
454 
455  case MISCREG_CNTV_TVAL:
457  return core.virt.timerValue();
458 
459  case MISCREG_CNTV_CTL:
461  return core.virt.control();
462 
463  // PL1 phys. timer, secure
464  case MISCREG_CNTP_CTL_S:
468  /* FALLTHROUGH */
469 
470  // PL2 phys. timer, non-secure
471  case MISCREG_CNTHCTL:
472  case MISCREG_CNTHCTL_EL2:
473  case MISCREG_CNTHP_CVAL:
475  case MISCREG_CNTHP_TVAL:
477  case MISCREG_CNTHP_CTL:
479  warn("Reading from unimplemented register: %s\n",
480  miscRegName[reg]);
481  return 0;
482 
483 
484  default:
485  warn("Reading from unknown register: %s\n", miscRegName[reg]);
486  return 0;
487  }
488 }
489 
490 
491 
492 GenericTimerMem::GenericTimerMem(GenericTimerMemParams *p)
493  : PioDevice(p),
494  ctrlRange(RangeSize(p->base, TheISA::PageBytes)),
495  timerRange(RangeSize(p->base + TheISA::PageBytes, TheISA::PageBytes)),
496  addrRanges{ctrlRange, timerRange},
497  systemCounter(),
498  physTimer(csprintf("%s.phys_timer0", name()),
499  *this, systemCounter,
500  ArchTimer::Interrupt(*p->gic, p->int_phys)),
501  virtTimer(csprintf("%s.virt_timer0", name()),
502  *this, systemCounter,
503  ArchTimer::Interrupt(*p->gic, p->int_virt))
504 {
505 }
506 
507 void
509 {
510  paramOut(cp, "timer_count", 1);
511 
512  systemCounter.serializeSection(cp, "sys_counter");
513 
514  physTimer.serializeSection(cp, "phys_timer0");
515  virtTimer.serializeSection(cp, "virt_timer0");
516 }
517 
518 void
520 {
521  systemCounter.unserializeSection(cp, "sys_counter");
522 
523  unsigned timer_count;
524  UNSERIALIZE_SCALAR(timer_count);
525  // The timer count variable is just here for future versions where
526  // we support more than one set of timers.
527  if (timer_count != 1)
528  panic("Incompatible checkpoint: Only one set of timers supported");
529 
530  physTimer.unserializeSection(cp, "phys_timer0");
531  virtTimer.unserializeSection(cp, "virt_timer0");
532 }
533 
534 Tick
536 {
537  const unsigned size(pkt->getSize());
538  const Addr addr(pkt->getAddr());
539  uint64_t value;
540 
541  pkt->makeResponse();
542  if (ctrlRange.contains(addr)) {
543  value = ctrlRead(addr - ctrlRange.start(), size);
544  } else if (timerRange.contains(addr)) {
545  value = timerRead(addr - timerRange.start(), size);
546  } else {
547  panic("Invalid address: 0x%x\n", addr);
548  }
549 
550  DPRINTF(Timer, "Read 0x%x <- 0x%x(%i)\n", value, addr, size);
551 
552  if (size == 8) {
553  pkt->set<uint64_t>(value);
554  } else if (size == 4) {
555  pkt->set<uint32_t>(value);
556  } else {
557  panic("Unexpected access size: %i\n", size);
558  }
559 
560  return 0;
561 }
562 
563 Tick
565 {
566  const unsigned size(pkt->getSize());
567  if (size != 8 && size != 4)
568  panic("Unexpected access size\n");
569 
570  const Addr addr(pkt->getAddr());
571  const uint64_t value(size == 8 ?
572  pkt->get<uint64_t>() : pkt->get<uint32_t>());
573 
574  DPRINTF(Timer, "Write 0x%x -> 0x%x(%i)\n", value, addr, size);
575  if (ctrlRange.contains(addr)) {
576  ctrlWrite(addr - ctrlRange.start(), size, value);
577  } else if (timerRange.contains(addr)) {
578  timerWrite(addr - timerRange.start(), size, value);
579  } else {
580  panic("Invalid address: 0x%x\n", addr);
581  }
582 
583  pkt->makeResponse();
584  return 0;
585 }
586 
587 uint64_t
589 {
590  if (size == 4) {
591  switch (addr) {
592  case CTRL_CNTFRQ:
593  return systemCounter.freq();
594 
595  case CTRL_CNTTIDR:
596  return 0x3; // Frame 0 implemented with virtual timers
597 
598  case CTRL_CNTNSAR:
599  case CTRL_CNTACR_BASE:
600  warn("Reading from unimplemented control register (0x%x)\n", addr);
601  return 0;
602 
604  return virtTimer.offset();
605 
607  return virtTimer.offset() >> 32;
608 
609  default:
610  warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size);
611  return 0;
612  }
613  } else if (size == 8) {
614  switch (addr) {
616  return virtTimer.offset();
617 
618  default:
619  warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size);
620  return 0;
621  }
622  } else {
623  panic("Invalid access size: %i\n", size);
624  }
625 }
626 
627 void
628 GenericTimerMem::ctrlWrite(Addr addr, size_t size, uint64_t value)
629 {
630  if (size == 4) {
631  switch (addr) {
632  case CTRL_CNTFRQ:
633  case CTRL_CNTNSAR:
634  case CTRL_CNTTIDR:
635  case CTRL_CNTACR_BASE:
636  warn("Write to unimplemented control register (0x%x)\n", addr);
637  return;
638 
641  insertBits(virtTimer.offset(), 31, 0, value));
642  return;
643 
646  insertBits(virtTimer.offset(), 63, 32, value));
647  return;
648 
649  default:
650  warn("Ignoring write to unexpected address (0x%x:%i)\n",
651  addr, size);
652  return;
653  }
654  } else if (size == 8) {
655  switch (addr) {
657  virtTimer.setOffset(value);
658  return;
659 
660  default:
661  warn("Ignoring write to unexpected address (0x%x:%i)\n",
662  addr, size);
663  return;
664  }
665  } else {
666  panic("Invalid access size: %i\n", size);
667  }
668 }
669 
670 uint64_t
672 {
673  if (size == 4) {
674  switch (addr) {
675  case TIMER_CNTPCT_LO:
676  return physTimer.value();
677 
678  case TIMER_CNTPCT_HI:
679  return physTimer.value() >> 32;
680 
681  case TIMER_CNTVCT_LO:
682  return virtTimer.value();
683 
684  case TIMER_CNTVCT_HI:
685  return virtTimer.value() >> 32;
686 
687  case TIMER_CNTFRQ:
688  return systemCounter.freq();
689 
690  case TIMER_CNTEL0ACR:
691  warn("Read from unimplemented timer register (0x%x)\n", addr);
692  return 0;
693 
695  return virtTimer.offset();
696 
698  return virtTimer.offset() >> 32;
699 
700  case TIMER_CNTP_CVAL_LO:
701  return physTimer.compareValue();
702 
703  case TIMER_CNTP_CVAL_HI:
704  return physTimer.compareValue() >> 32;
705 
706  case TIMER_CNTP_TVAL:
707  return physTimer.timerValue();
708 
709  case TIMER_CNTP_CTL:
710  return physTimer.control();
711 
712  case TIMER_CNTV_CVAL_LO:
713  return virtTimer.compareValue();
714 
715  case TIMER_CNTV_CVAL_HI:
716  return virtTimer.compareValue() >> 32;
717 
718  case TIMER_CNTV_TVAL:
719  return virtTimer.timerValue();
720 
721  case TIMER_CNTV_CTL:
722  return virtTimer.control();
723 
724  default:
725  warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size);
726  return 0;
727  }
728  } else if (size == 8) {
729  switch (addr) {
730  case TIMER_CNTPCT_LO:
731  return physTimer.value();
732 
733  case TIMER_CNTVCT_LO:
734  return virtTimer.value();
735 
737  return virtTimer.offset();
738 
739  case TIMER_CNTP_CVAL_LO:
740  return physTimer.compareValue();
741 
742  case TIMER_CNTV_CVAL_LO:
743  return virtTimer.compareValue();
744 
745  default:
746  warn("Unexpected address (0x%x:%i), assuming RAZ\n", addr, size);
747  return 0;
748  }
749  } else {
750  panic("Invalid access size: %i\n", size);
751  }
752 }
753 
754 void
755 GenericTimerMem::timerWrite(Addr addr, size_t size, uint64_t value)
756 {
757  if (size == 4) {
758  switch (addr) {
759  case TIMER_CNTEL0ACR:
760  warn("Unimplemented timer register (0x%x)\n", addr);
761  return;
762 
763  case TIMER_CNTP_CVAL_LO:
765  insertBits(physTimer.compareValue(), 31, 0, value));
766  return;
767 
768  case TIMER_CNTP_CVAL_HI:
770  insertBits(physTimer.compareValue(), 63, 32, value));
771  return;
772 
773  case TIMER_CNTP_TVAL:
774  physTimer.setTimerValue(value);
775  return;
776 
777  case TIMER_CNTP_CTL:
778  physTimer.setControl(value);
779  return;
780 
781  case TIMER_CNTV_CVAL_LO:
783  insertBits(virtTimer.compareValue(), 31, 0, value));
784  return;
785 
786  case TIMER_CNTV_CVAL_HI:
788  insertBits(virtTimer.compareValue(), 63, 32, value));
789  return;
790 
791  case TIMER_CNTV_TVAL:
792  virtTimer.setTimerValue(value);
793  return;
794 
795  case TIMER_CNTV_CTL:
796  virtTimer.setControl(value);
797  return;
798 
799  default:
800  warn("Unexpected address (0x%x:%i), ignoring write\n", addr, size);
801  return;
802  }
803  } else if (size == 8) {
804  switch (addr) {
805  case TIMER_CNTP_CVAL_LO:
806  return physTimer.setCompareValue(value);
807 
808  case TIMER_CNTV_CVAL_LO:
809  return virtTimer.setCompareValue(value);
810 
811  default:
812  warn("Unexpected address (0x%x:%i), ignoring write\n", addr, size);
813  return;
814  }
815  } else {
816  panic("Invalid access size: %i\n", size);
817  }
818 }
819 
820 GenericTimer *
821 GenericTimerParams::create()
822 {
823  return new GenericTimer(this);
824 }
825 
827 GenericTimerMemParams::create()
828 {
829  return new GenericTimerMem(this);
830 }
void unserialize(CheckpointIn &cp) override
Unserialize an object.
#define DPRINTF(x,...)
Definition: trace.hh:212
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:398
uint64_t timerRead(Addr addr, size_t size) const
void setFreq(uint32_t freq)
Sets the counter frequency.
uint64_t _counterLimit
Programmed limit value for the upcounter ({CNTP/CNTHP/CNTV}_CVAL).
const unsigned _irq
void set(T v, ByteOrder endian)
Set the value in the data pointer to v using the specified endianness.
Tick period() const
Returns the counter period.
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)
Addr start() const
Get the start address of the range.
Definition: addr_range.hh:227
const std::string & name()
Definition: trace.cc:49
Bitfield< 7 > i
Definition: miscregs.hh:1378
This module implements the global system counter and the local per-CPU architected timers as specifie...
#define panic(...)
Definition: misc.hh:153
static const Addr TIMER_CNTP_TVAL
uint64_t compareValue() const
Returns the CompareValue view of the timer.
#define UNSERIALIZE_OPT_SCALAR(scalar)
Definition: serialize.hh:146
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
Definition: serialize.cc:585
static const Addr TIMER_CNTV_CVAL_LO
uint32_t _regCntkctl
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
ip6_addr_t addr
Definition: inet.hh:335
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:381
void timerWrite(Addr addr, size_t size, uint64_t value)
uint64_t MiscReg
Definition: registers.hh:54
void setMiscReg(int misc_reg, unsigned cpu, ArmISA::MiscReg val)
#define warn_once(...)
Definition: misc.hh:226
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:328
const char *const miscRegName[]
Definition: miscregs.hh:739
GenericTimerMem(GenericTimerMemParams *p)
Tick Frequency
The simulated frequency of curTick(). (In ticks per second)
Definition: core.cc:47
const unsigned irqVirt
Virtual timer interrupt.
void setTimerValue(uint32_t val)
Sets the TimerValue view of the timer.
void deschedule(Event &event)
Definition: eventq.hh:734
T get(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness.
Bitfield< 63 > val
Definition: misc.hh:770
ArchTimerCtrl _control
Value of the control register ({CNTP/CNTHP/CNTV}_CTL).
static const Addr TIMER_CNTV_CTL
ArmISA::MiscReg readMiscReg(int misc_reg, unsigned cpu)
void counterLimitReached()
Called when the upcounter reaches the programmed value.
Tick _resetTick
Tick when the counter was reset.
#define warn(...)
Definition: misc.hh:219
Tick _period
Cached copy of the counter period (inverse of the frequency).
static const Addr CTRL_CNTVOFF_HI_BASE
uint64_t _freq
Counter frequency (as specified by CNTFRQ).
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:145
void setOffset(uint64_t val)
const unsigned _cpu
Tick curTick()
The current simulated tick.
Definition: core.hh:47
Temporarily migrate execution to a different event queue.
Definition: eventq.hh:546
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
EventWrapper< ArchTimer,&ArchTimer::counterLimitReached > _counterLimitReachedEvent
uint64_t value() const
Returns the current value of the physical counter.
void serialize(CheckpointOut &cp) const override
Serialize an object.
virtual void sendPPInt(uint32_t num, uint32_t cpu)=0
Interface call for private peripheral interrupts.
Tick when() const
Get the time that the event is scheduled.
Definition: eventq.hh:397
virtual void sendInt(uint32_t num)=0
Post an interrupt from a device that is connected to the GIC.
const unsigned irqPhys
Physical timer interrupt.
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.
uint32_t timerValue() const
Returns the TimerValue view of the timer.
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.
uint64_t ctrlRead(Addr addr, size_t size) const
Bitfield< 51, 12 > base
Definition: pagetable.hh:85
uint32_t getKernelControl()
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Definition: serialize.cc:578
void setKernelControl(uint32_t val)
static const Addr CTRL_CNTACR_BASE
void ctrlWrite(Addr addr, size_t size, uint64_t value)
T insertBits(T val, int first, int last, B bit_val)
Return val with bits first to last set to bit_val.
Definition: bitfield.hh:120
ArchTimer physTimer
This device is the base class which all devices senstive to an address range inherit from...
Definition: io_device.hh:84
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
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
EventQueue * eventQueue() const
Definition: eventq.hh:722
const Addr PageBytes
Definition: isa_traits.hh:52
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:143
Interrupt _interrupt
ArchTimer virtTimer
cbk_int func interrupt
Definition: gpu_nomali.cc:94
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:845
int size()
Definition: pagetable.hh:146
Base class for ARM GIC implementations.
static const Addr TIMER_CNTPCT_LO
static const Addr CTRL_CNTTIDR
void serialize(CheckpointOut &cp) const override
Serialize an object.
std::ostream CheckpointOut
Definition: serialize.hh:67
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.
uint64_t offset() const
void unserialize(CheckpointIn &cp) override
Unserialize an object.
static const Addr CTRL_CNTNSAR
void schedule(Event &event, Tick when)
Definition: eventq.hh:728
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
Definition: types.cc:71
SystemCounter systemCounter
System counter.
uint64_t value() const
Returns the value of the counter which this timer relies on.
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
uint32_t control() const
Sets the control register.
ArchTimer(const std::string &name, SimObject &parent, SystemCounter &sysctr, const Interrupt &interrupt)
void setControl(uint32_t val)
std::vector< std::unique_ptr< CoreTimers > > timers
Per-CPU physical architected timers.
const AddrRange timerRange
unsigned getSize() const
Definition: packet.hh:649
static const Addr TIMER_CNTV_CVAL_HI
static const Addr CTRL_CNTFRQ
SystemCounter & _systemCounter
fatal_if(p->js_features.size() > 16,"Too many job slot feature registers specified (%i)\n", p->js_features.size())
static const Addr TIMER_CNTVCT_HI
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
Abstract superclass for simulation objects.
Definition: sim_object.hh:94
uint64_t _offset
Offset relative to the physical timer (CNTVOFF)
Addr getAddr() const
Definition: packet.hh:639
static const Addr CTRL_CNTVOFF_LO_BASE
EndBitUnion(ArchTimerCtrl) const std SimObject & _parent
Name of this timer.
uint64_t freq() const
Returns the counter frequency.

Generated on Fri Jun 9 2017 13:03:45 for gem5 by doxygen 1.8.6