The revamp of the GenericTimer was not taking into account:
* The name of the variable will be printed on the checkpoint to label the
data. It is not possible to use different variable names when
serializing/unserializing, and it is not possible to use the same
temporary variable to serialize/unserialize different values.
* the serializeSection is creating a new sub section in the
checkpoint. Doing the following:
void
GenericTimerFrame::serialize(CheckpointOut &cp) const
{
physTimer.serializeSection(cp, "phys_timer");
virtTimer.serializeSection(cp, "virt_timer");
SERIALIZE_SCALAR(accessBits);
}
will serialize the accessBits under the virt_timer subsection
rather than the parent generic_timer_frame.
JIRA: https://gem5.atlassian.net/projects/GEM5/issues/GEM5-426
Change-Id: I7676309965a33156789d2ef13e966c7a4ad88a71
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Ciro Santilli <ciro.santilli@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27708
Tested-by: kokoro <noreply+kokoro@google.com>
The GenericTimer specification includes a global component for
a universal view of time: the System Counter.
If both per-PE architected and memory-mapped timers are instantiated
in a system, they must both share the same counter. SystemCounter is
promoted to be an independent SimObject, which is now shared by
implementations.
The SystemCounter may be controlled/accessed through the memory-mapped
counter module in the system level implementation. This provides
control (CNTControlBase) and status (CNTReadBase) register frames. The
counter module is now implemented as part of GenericTimerMem.
Frequency changes occur through writes to an active CNTFID or to
CNTCR.EN as per the architecture. Low-high and high-low transitions are
delayed until suitable thresholds, where the counter value is a divisor
of the increment given the new frequency.
Due to changes in frequency, timers need to be notifies to be
rescheduled their counter limit events based on CompareValue/TimerValue.
A new SystemCounterListener interface is provided to achieve
correctness.
CNTFRQ is no longer able to modify the global frequency. PEs may
use this to modify their register view of the former, but they should
not affect the global value. These two should be consistent.
With frequency changes, counter value needs to be stored to track
contributions from different frequency epochs. This is now handled
on epoch change, counter disable and register access.
References to all GenericTimer model components are now provided as
part of the documentation.
VExpress_GEM5_Base is updated with the new model configuration.
Change-Id: I9a991836cacd84a5bc09e5d5275191fcae9ed84b
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/25306
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This value is just a cached inverse of _freq and can be recalculated
easily once the checkpoint is restored. The actual value of _period
actually depends on the global resolution of time (ie how much time a
Tick represents), and so saving the value of _period is also not
technically correct, even though in practice that will very rarely
cause a problem.
Change-Id: I21e63ba25ac4e189417905e532981f3d80723f19
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24390
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Architecture states the system counter has a fixed base frequency
provided in the first entry of the frequency modes table. Optionally,
other lower frequencies may be specified in consecutive entries.
This patch adds configurable frequencies to the GenericTimer model.
The default base frequency is kept as the one that was previously
hardcoded for backwards compatibility.
The table is not recommended to be updated once the system is running.
Change-Id: Icba0b340a0eb1cbb47dfe7d7e03b547af4570c60
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/22425
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
These types are IntReg, FloatReg, FloatRegBits, and MiscReg. There are
some remaining types, specifically the vector registers and the CCReg.
I'm less familiar with these new types of registers, and so will look
at getting rid of them at some later time.
Change-Id: Ide8f76b15c531286f61427330053b44074b8ac9b
Reviewed-on: https://gem5-review.googlesource.com/c/13624
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Within a device tree, the GenericTimer device needs to point (via phandle)
to a clock domain which is itself also an object in the device tree. Within
gem5, clock domains are managed by making all clocked SimObjects inherit
from ClockedObject rather than SimObject.
Without this change, the GenericTimer is unable to generate the appropriate
clock domain phandle, and will crash during DTB autogeneration.
Change-Id: I6d3fb6362847c6a01720b2f14b3d595d1e59f01f
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/4960
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
GCC 7.2 is much stricter than previous GCC versions. The following changes
are needed:
* There is now a warning if there is an implicit fallthrough between two
case statments. C++17 adds the [[fallthrough]]; declaration. However,
to support non C++17 standards (i.e., C++11), we use M5_FALLTHROUGH.
M5_FALLTHROUGH checks for [[fallthrough]] compliant C++17 compiler and
if that doesn't exist, it defaults to nothing (no older compilers
generate warnings).
* The above resulted in a couple of bugs that were found. This is noted
in the review request on gerrit.
* throw() for dynamic exception specification is deprecated
* There were a couple of new uninitialized variable warnings
* Can no longer perform bitwise operations on a bool.
* Must now include <functional> for std::function
* Compiler bug for void* lambda. Changed to auto as work around. See
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82878
Change-Id: I5d4c782a4e133fa4cdb119e35d9aff68c6e2958e
Signed-off-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-on: https://gem5-review.googlesource.com/5802
Reviewed-by: Gabe Black <gabeblack@google.com>
ISA devices typically run in the device event queue. Previously, we
assumed that devices would perform their own EQ migrations as
needed. This isn't ideal since it means we have different conventions
for IO devices and ISA devices. Switch to doing migrations in the KVM
CPU instead to make the behavior consistent.
Change-Id: I33b74480fb2126b0786dbdbfdcfa86083384250c
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/4288
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
The timer device exposed via the ARM ISA, also known as the
"CP15 timer" due to its legacy coprocessor encodings, is
implemented by the GenericTimerISA class. During Kvm
execution, however, this functionality is directly emulated
by the hardware.
This commit subclasses the GenericTimer, which is (solely)
used by GenericTimerISA, to facilitate Kvm in much the same
way as the prior GIC changes: the gem5 model is used as the
backing store for state, so checkpointing and CPU switching
work correctly, but isn't used during Kvm execution.
The added indirection prevents the timer device from creating
events when we're just updating its state, but not actually
using it for simulation.
Change-Id: I427540d11ccf049c334afe318f575146aa888672
Reviewed-on: https://gem5-review.googlesource.com/3542
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Having timer events stored in checkpoints complicates Kvm
execution. We change the timer behavior so that it always
deschedules any pending events on a drain() and recreates
them on a drainResume(), thus they will never appear in
checkpoints henceforth. This pattern of behavior makes
it simpler to handle Kvm execution, where the hardware
performs the timer function directly.
Change-Id: Ia218868c69350d96e923c640634d492b5c19cd3f
Reviewed-on: https://gem5-review.googlesource.com/3541
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
The generic timer sometimes needs to access global state. This can
lead to race conditions when simulating a multi-core KVM system where
each core lives in its own thread. In that case, the setMiscReg and
readMiscReg methods are called from the thread owning the CPU and not
the global device thread.
Change-Id: Ie3e982258648c8562cce0b30a0c122dfbfaf42cd
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Gabor Dozsa <gabor.dozsa@arm.com>
Reviewed-by: Curtis Dunham <curtis.dunham@arm.com>
Reviewed-by: Sascha Bischoff <sascha.bischoff@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/2460
Reviewed-by: Weiping Liao <weipingliao@google.com>
The generic timer needs a pointer to an ArmSystem to wire itself to the
system register handler. This was previously specified as an instance
of System that was later cast to ArmSystem. Make this more robust by
specifying it as an ArmSystem in the Python interface and add a check
to make sure that it is non-NULL.
Change-Id: I989455e666f4ea324df28124edbbadfd094b0d02
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Objects that are can be serialized are supposed to inherit from the
Serializable class. This class is meant to provide a unified API for
such objects. However, so far it has mainly been used by SimObjects
due to some fundamental design limitations. This changeset redesigns
to the serialization interface to make it more generic and hide the
underlying checkpoint storage. Specifically:
* Add a set of APIs to serialize into a subsection of the current
object. Previously, objects that needed this functionality would
use ad-hoc solutions using nameOut() and section name
generation. In the new world, an object that implements the
interface has the methods serializeSection() and
unserializeSection() that serialize into a named /subsection/ of
the current object. Calling serialize() serializes an object into
the current section.
* Move the name() method from Serializable to SimObject as it is no
longer needed for serialization. The fully qualified section name
is generated by the main serialization code on the fly as objects
serialize sub-objects.
* Add a scoped ScopedCheckpointSection helper class. Some objects
need to serialize data structures, that are not deriving from
Serializable, into subsections. Previously, this was done using
nameOut() and manual section name generation. To simplify this,
this changeset introduces a ScopedCheckpointSection() helper
class. When this class is instantiated, it adds a new /subsection/
and subsequent serialization calls during the lifetime of this
helper class happen inside this section (or a subsection in case
of nested sections).
* The serialize() call is now const which prevents accidental state
manipulation during serialization. Objects that rely on modifying
state can use the serializeOld() call instead. The default
implementation simply calls serialize(). Note: The old-style calls
need to be explicitly called using the
serializeOld()/serializeSectionOld() style APIs. These are used by
default when serializing SimObjects.
* Both the input and output checkpoints now use their own named
types. This hides underlying checkpoint implementation from
objects that need checkpointing and makes it easier to change the
underlying checkpoint storage code.
There are cases when we don't want to use a system register mapped
generic timer, but can't use the SP804. For example, when using KVM on
aarch64, we want to intercept accesses to the generic timer, but can't
do so if it is using the system register interface. In such cases,
we need to use a memory-mapped generic timer.
This changeset adds a device model that implements the memory mapped
generic timer interface. The current implementation only supports a
single frame (i.e., one virtual timer and one physical timer).
The generic timer model currently does not support virtual
counters. Virtual and physical counters both tick with the same
frequency. However, virtual timers allow a hypervisor to set an offset
that is subtracted from the counter when it is read. This enables the
hypervisor to present a time base that ticks with virtual time in the
VM (i.e., doesn't tick when the VM isn't running). Modern Linux
kernels generally assume that virtual counters exist and try to use
them by default.
This changeset cleans up the generic timer a bit and moves most of the
register juggling from the ISA code into a separate class in the same
source file as the rest of the generic timer. It also removes the
assumption that there is always 8 or fewer CPUs in the system. Instead
of having a fixed limit, we now instantiate per-core timers as they
are requested. This is all in preparation for other patches that add
support for virtual timers and a memory mapped interface.
Note: AArch64 and AArch32 interworking is not supported. If you use an AArch64
kernel you are restricted to AArch64 user-mode binaries. This will be addressed
in a later patch.
Note: Virtualization is only supported in AArch32 mode. This will also be fixed
in a later patch.
Contributors:
Giacomo Gabrielli (TrustZone, LPAE, system-level AArch64, AArch64 NEON, validation)
Thomas Grocutt (AArch32 Virtualization, AArch64 FP, validation)
Mbou Eyole (AArch64 NEON, validation)
Ali Saidi (AArch64 Linux support, code integration, validation)
Edmund Grimley-Evans (AArch64 FP)
William Wang (AArch64 Linux support)
Rene De Jong (AArch64 Linux support, performance opt.)
Matt Horsnell (AArch64 MP, validation)
Matt Evans (device models, code integration, validation)
Chris Adeniyi-Jones (AArch64 syscall-emulation)
Prakash Ramrakhyani (validation)
Dam Sunwoo (validation)
Chander Sudanthi (validation)
Stephan Diestelhorst (validation)
Andreas Hansson (code integration, performance opt.)
Eric Van Hensbergen (performance opt.)
Gabe Black