The contextId is generally treated as (and should be) an opaque index
into the System objects threadContext array. When forcing it to
particular values, that introduces gaps in the threadContext array which
trips up other code which is expecting the array to have only valid
entries.
Change-Id: I4997e989b436a3008f65f348722dfb843b2f110a
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/57089
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Yu-hsin Wang <yuhsingw@google.com>
The default constructor for RegId would initialize it with the
IntRegClass and register index 0. This is arbitrary and
indistinguishable from a real ID to the first integer register.
Instead, add a new class type constant InvalidRegClass, and use that to
initialize an otherwise uninitialized RegId.
Also, fill out some enums that needed to handle that value to silence
compiler warnings.
Change-Id: I3b58559f41adc1da5f661121225dbd389230e3af
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49710
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Rather than constantly overwriting the "zero" register to return its
value to zero, just ignore writes to it.
We assume here that the "zero" register is a standard RegVal type
register (ie not bigger than 64 bits) and is accessed as such.
Change-Id: I06029b78103019c668647569c6037ca64a4d9c76
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49709
Maintainer: Gabe Black <gabe.black@gmail.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
The Request::NO_ACCESS flag instructs the cpu model to not issue
the request to the memory port.
While Atomic and Timing CPU models properly implement it [1], [2],
* MinorCPU is not looking at the flag
* O3CPU is looking at the flag only in case of a nested transaction
start/commit
This patch is extending NO_ACCESS support to all memory instructions.
This is achieved by using the localAccess callback in the Request object.
Handling of nested hardware transactions in the O3 LSQUnit is moved within
the local accessor callback
[1]: https://github.com/gem5/gem5/blob/v21.1.0.2/\
src/cpu/simple/timing.cc#L318
[2]: https://github.com/gem5/gem5/blob/v21.1.0.2/\
src/cpu/simple/atomic.cc#L396
Change-Id: Ifd5b388c53ead4fe358aa35d2197c12f1c5bb4f2
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/56591
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: ZHENGRONG WANG <seanyukigeek@gmail.com>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
If the size of the address range is smaller than the maximum number
of outstanding requests allowed downstream, the tester will get stuck
trying to find a unique address. This patch adds a check for this
condition and forces the tester to wait for responses before
trying to generate another request.
Change-Id: Ie894a074cc4f8c7ad3d875dc21e8eb4f04562d72
Signed-off-by: Tiago Mück <tiago.muck@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/56811
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
The tester currently assumes that one token per lane is needed when
checking if an action is ready to be issued. When actually issuing
requests, it is possible that a memory location is not valid for various
reasons. This was not being considered when checking for tokens causing
the tester to acquire more tokens than requests sent. Since tokens are
returned when requests are coalesced, this was causing some tokens never
to be returned, eventually depleting the token pool and causing a
deadlock.
Add a new method which determines the number of tokens needed for an
action. This is called by both the ready check method and the method to
issue the action to ensure they are aligned.
Change-Id: Ic1af72085c3b077539eb3fd129331e776ebdffbc
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/56450
Reviewed-by: Matt Sinclair <mattdsinclair@gmail.com>
Maintainer: Matt Sinclair <mattdsinclair@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Individual register files, like the ones for scalar integer, floating
point, or condition code registers, are now declared as vectors of their
actual type. Accessing them is simple, since the register you want can
be accessed simply by indexing into the vector.
Unfortunately, that means the code that sets up that storage has to know
what that underlying type is, and that means knowing (and hard coding)
information about the ISA being built.
Instead, this change makes the SimpleThread and O3 PhysRegFile classes
store registers as vectors of bytes, and offsets into those vectors
using computed offsets. Because the elements of the register files are
forced to be offset by powers of 2, computing the offsets can be done
with a shift rather than a multiplication.
The accessors which actually pull values in and out of these vectors are
still specific to each register type and need to know what the
underlying type is, but this change pulls that one level out of the CPUs
towards their peripheral APIs. Later changes will factor these uses out
as well.
Change-Id: I5e19d359a0e83e5827ae263d369999f90c7aa63d
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49105
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
By default, registers are the size of RegVal, the type often used to
store them. For some types of registers, like vector or vector predicate
registers, the size of each individual register is larger, and can't fit
in a primitive type.
To help facilitate storing even these outliers in a generalized way,
this change adds two fields to RegClassInfo to track the size of
individual registers. One tracks the raw size of the registers
themselves, and the other tracks the minimal shift necessary to find the
offset of a register in a contiguous(ish) array of bytes. By forcing
each register to be aligned to a power of two boundary, we avoid having
to do a multiplication to find their address even if the registers are
oddly sized. We can instead do a shift with a precomputed shift amount
which should be faster.
Change-Id: I035f1b4cb00ece4e8306d7953ea358af75a0d1de
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49104
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
The KvmVM will declare itself to the System object, instead of the other
way around. This way the System object can just keep an opaque KvmVM
pointer which does not depend on the KvmVM code even being compiled into
gem5. If there is a KvmVM object, that can more safely assume there is a
corresponding System object to attach itself to.
Also move use of the KvmVM pointer out of constructors, since the VM may
not have registered itself with the System object yet. Those uses can
happen in the init() method instead.
Change-Id: Ia0842612b101315bc1af0232d7f5ae2b55a15922
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/56187
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
These registers used to be accessed with a two dimensional index, with
one dimension specifying the register, and the second index specifying
the element within that register. This change linearizes that index down
to one dimension, where the elements of each register are laid out one
after the other in sequence.
Change-Id: I41110f57b505679a327108369db61c826d24922e
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49148
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
The BaseCPU type had been specializing itself based on the value of
TARGET_ISA, which is not compatible with building more than one ISA at a
time.
This change refactors the CPU models so that the BaseCPU is more
general, and the ISA specific components are added to the CPU when the
CPU types are fully specialized. For instance, The AtomicSimpleCPU has a
version called X86AtomicSimpleCPU which installs the X86 specific
aspects of the CPU.
This specialization is done in three ways.
1. The mmu parameter is assigned an instance of the architecture
specific MMU type. This provides a reasonable default, but also avoids
having having to use the ISA specific type when the parameter is
created.
2. The ISA specific types are made available as class attributes, and
the utility functions (including __init__!) in the BaseCPU class can
refer to them to get the types they need to set up the CPU at run time.
Because SimObjects have strange, unhelpful semantics as far as assigning
to their attributes, these types need to be set up in a non-SimObject
class, which is then brought in as a base of the actual SimObject type.
Because the metaclass of this other type is just "type", things work
like you would expect. The SimObject doesn't do any special processing
of base classes if they aren't also SimObjects, so these attributes
survive and are accessible using normal lookup in the BaseCPU class.
3. There are some methods like addCheckerCPU and properties like
needsTSO which have ISA specific values or behaviors. These are set in
the ISA specific subclass, where they are inherently specific to an ISA
and don't need to check TARGET_ISA.
Also, the DummyChecker which was set up for the BaseSimpleCPU which
doesn't actually do anything in either C++ or python was not carried
forward. The CPU type still exists, but it isn't installed in the
simple CPUs.
To provide backward compatibility, each ISA implements a .py file which
matches the original .py for a CPU, and the original is renamed with a
Base prefix. The ISA specific version creates an alias with the old CPU
name which maps to the ISA specific type. This way, old scripts which
refer to, for example, AtomicSimpleCPU, will get the X86AtomicSimpleCPU
if the x86 version was compiled in, the ArmAtomicSimpleCPU on arm, etc.
Unfortunately, because of how tags on PySource and by extension SimObjects
are implemented right now, if you set the tags on two SimObjects or
PySources which have the same module path, the later will overwrite the
former whether or not they both would be included. There are some
changes in review which would revamp this and make it work like you
would expect, without this central bookkeeping which has the conflict.
Since I can't use that here, I fell back to checking TARGET_ISA to
decide whether to tell SCons about those files at all.
In the long term, this mechanism should be revamped so that these
compatibility types are only available if there is exactly one ISA
compiled into gem5. After the configs have been updated and no longer
assume they can use AtomicSimpleCPU in all cases, then these types can
be deleted.
Also, because ISAs can now either provide subclasses for a CPU or not,
the CPU_MODELS variable has been removed, meaning the non-ISA
specialized versions of those CPU models will always be included in
gem5, except when building the NULL ISA.
In the future, a more granular config mechanism will hopefully be
implemented for *all* of gem5 and not just the CPUs, and these can be
conditional again in case you only need certain models, and want to
reduce build time or binary size by excluding the others.
Change-Id: I02fc3f645c551678ede46268bbea9f66c3f6c74b
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/52490
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Currently, an access to an invalid address will cause GEM5 to exit with
a `!pkt.isError()` assertion failure. I was seeing this assertion while
running a baremetal RISC-V binary that faulted before the trap vector
had been configured and therefore tried to jump to address zero. With
this change we now print the invalid address and the type of access
(ifetch/load/store/amo) which makes debugging such a problem much easier.
For example, my faulting program now prints the following:
`panic: Instruction fetch ([0:0x4]) failed: BadAddressError [0:3] IF`
I also saw this assertion with a program that was dereferencing a NULL
pointer, which now prints a more helpful message:
`panic: Data fetch ([0x10:0x11]) failed: BadAddressError [10:10]`
Change-Id: Id983b74bf4688711f47308c6c7c15f49662ac495
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/55203
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
If there really are no c++ sim_objects in the file, then sim_objects can
be set to [] which it used to default to.
This way, if someone hasn't remembered to update their SConscript files
for the new sim_objects and enums parameters, this will give them some
indication what's wrong, rather than the build just failing later.
Change-Id: Ic1933f7b9dfff7dd7e403c6c84f1f510c8ee8c72
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/54203
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Remove the line "For use for simulation and test purposes only" in files
were AMD is the only copyright holder listed in the header. This happens
to be the case for all files where this line exists, removing it
completely from gem5.
Change-Id: I623f266b002f564301b28774f49081099cfc60fd
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/53943
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>