mem: support for gpu-style RMWs in ruby
This patch adds support for GPU-style read-modify-write (RMW) operations in
ruby. Such atomic operations are traditionally executed at the memory controller
(instead of through an L1 cache using cache-line locking).
Currently, this patch works by propogating operation functors through the memory
system.
Just changes the metavar for --debug-start from TIME
to TICK in cset 72046b9b3323 and didn't notice that the
comment "must be in ticks" is now redundant.
For historical reasons, the ExecContext interface had a single
function, readMem(), that did two different things depending on
whether the ExecContext supported atomic memory mode (i.e.,
AtomicSimpleCPU) or timing memory mode (all the other models).
In the former case, it actually performed a memory read; in the
latter case, it merely initiated a read access, and the read
completion did not happen until later when a response packet
arrived from the memory system.
This led to some confusing things, including timing accesses
being required to provide a pointer for the return data even
though that pointer was only used in atomic mode.
This patch splits this interface, adding a new initiateMemRead()
function to the ExecContext interface to replace the timing-mode
use of readMem().
For consistency and clarity, the readMemTiming() helper function
in the ISA definitions is renamed to initiateMemRead() as well.
For x86, where the access size is passed in explicitly, we can
also get rid of the data parameter at this level. For other ISAs,
where the access size is determined from the type of the data
parameter, we have to keep the parameter for that purpose.
The read() function merely initiates a memory read operation; the
data doesn't arrive until the access completes and a response packet
is received from the memory system. Thus there's no need to provide
a data pointer; its existence is historical.
Getting this pointer out of this internal o3 interface sets the
stage for similar cleanup in the ExecContext interface. Also
found that we were pointlessly setting the contents at this pointer
on a store forward (the useful memcpy happens just a few lines
below the deleted one).
The readMemAtomic/writeMemAtomic helper functions were calling
readMemTiming/writeMemTiming respectively. This is functionally
correct, since the *Timing functions are doing the same access
initiation operation as the *Atomic functions (just that the
*Atomic versions also complete the access in line). It also
provides for some (very minimal) code reuse. Unfortunately,
it's potentially pretty confusing, since it makes it look like
the atomic accesses are somehow being converted to timing
accesses. It also gets in the way of specializing the timing
interface (as will be done in a future patch).
By ignoring SIG_TRAP, using --debug-break <N> when not connected to
a debugger becomes a no-op. Apparently this was intended to be a
feature, though the rationale is not clear.
If we don't ignore SIG_TRAP, then using --debug-break <N> when not
connected to a debugger causes the simulation process to terminate
at tick N. This is occasionally useful, e.g., if you just want to
collect a trace for a specific window of execution then you can combine
this with --debug-start to do exactly that.
In addition to not ignoring the signal, this patch also updates
the --debug-break help message and deletes a handful of unprotected
calls to Debug::breakpoint() that relied on the prior behavior.
The fs/80.solaris-boot/sparc/solaris/t1000-simple-atomic test was
broken for so long that, now that it's working again, the stats
output is out of date. This changeset updates the outputs, on
the assumption that the stats changes are all valid differences
due to other changes made while it was broken.
Add a platform with support for both aarch32 and aarch64. This
platform implements a subset of the devices in a real Versatile
Express and extends it with some gem5-specific functionality. It is in
many ways similar to the old VExpress_EMM64 platform, but supports the
following new features:
* Automatic PCI interrupt assignment
* PCI interrupts allocated in a contiguous range.
* Automatic boot loader selection (32-bit / 64-bit)
* Cleaner memory map where gem5-specific devices live in CS5 which
isn't used by current Versatile Express platforms.
* No fake devices. Devices that were previously faked will be
removed from the device tree instead.
* Support for 510 GiB contiguous memory
Add support for automatic PCI interrupt routing using a device's ID on
the PCI bus. Our current DTBs typically tell the kernel that we do
this or something similar when declaring the PCI controller. This
changeset adds an option to make the simulator behave in the same way.
Interrupt routing can be selected by setting the int_policy parameter
in the GenericArmPciHost. The following values are supported:
* ARM_PCI_INT_STATIC: Use the old static routing policy using the
interrupt line from a device's configurtion space.
* ARM_PCI_INT_DEV: Use device number on the PCI bus to map to an
interrupt in the GIC. The interrupt is computed as:
gic_int = int_base + (pci_dev % int_count)
* ARM_PCI_INT_PIN: Use device interrupt pin on the PCI bus to map to
an interrupt in the GIC. The PCI specification reserves pin ID 0
for devices without interrupts, the interrupt therefore computed
as:
gic_int = int_base + ((pin - 1) % int_count)
The new Packet::setRaw() method incorrectly still contained
an htog() conversion. As a result, calls to the old set()
method (now defined as setRaw(htog(v))) underwent two htog
conversions, which breaks things when htog() is not a no-op.
Interestingly the only test that caught this was a SPARC
boot test, where an IsaFake device with a non-zero return
value was getting swapped twice resulting in a register
getting loaded with 0x100000000000000 instead of 1.
(Good reason for keeping SPARC around, perhaps?)
This patch replaces the gzstream zlib wrapper with the iostream3
wrapper provided as part of zlib contributions. The main reason for
the switch is to avoid including LGPL in the default gem5
build. iostream3 is provided under a more permissive license:
The code is provided "as is", with the permission to use, copy,
modify, distribute and sell it for any purpose without fee.
Distributed gem5 (abbreviated dist-gem5) is the result of the
convergence effort between multi-gem5 and pd-gem5 (from Univ. of
Wisconsin). It relies on the base multi-gem5 infrastructure for packet
forwarding, synchronisation and checkpointing but combines those with
the elaborated network switch model from pd-gem5.
--HG--
rename : src/dev/net/multi_etherlink.cc => src/dev/net/dist_etherlink.cc
rename : src/dev/net/multi_etherlink.hh => src/dev/net/dist_etherlink.hh
rename : src/dev/net/multi_iface.cc => src/dev/net/dist_iface.cc
rename : src/dev/net/multi_iface.hh => src/dev/net/dist_iface.hh
rename : src/dev/net/multi_packet.hh => src/dev/net/dist_packet.hh
Some of the DPRINTFs added to the classic cache in cset 45df88079f04,
while useful to those unfamiliar with the cache code, end up being
noise when you're familiar with the code but are trying to debug tricky
protocol issues. (Particularly getting two messages from each cache
as it receives a snoop request then declares that there was no match.)
This patch introduces a CacheVerbose debug flag, and moves a subset of
the added DPRINTFs into that category, so that Cache by itself returns
to being a more succinct summary of cache activity.
Also added a CacheAll compound flag to turn on all the cache-related
debug flags (other than CacheTags, which you *really* have to want badly
to turn it on, IMO).
This patch removes the NeedsWritable flag for all responses, as it is
really only the request that needs a writable response. The response,
on the other hand, should in these cases always provide the line in a
writable state, as indicated by the hasSharers flag not being set.
When we send requests that has NeedsWritable set, the response will
always have the hasSharers flag not set. Additionally, there are cases
where the request did not have NeedsWritable set, and we still get a
writable response with the hasSharers flag not set. This never happens
on snoops, but is used by downstream caches to pass ownership
upstream.
As part of this patch, the affected response types are updated, and
the snoop filter is similarly modified to check only the hasSharers
flag (as it should). A sanity check is also added to the packet class,
asserting that we never look at the NeedsWritable flag for responses.
No regressions are affected.
This patch looks at the request and response command to determine if
either actually has any data payload, and if not, we do not allocate
any space for packet data.
The only tricky case is where the command type is changed as part of
the MSHR functionality. In these cases where the original packet had
no data, but the new packet does, we need to explicitly call
allocate().
This patch ensures we do not respond with a Modified (dirty and
writable) line if the request is uncacheable, and that the cache
responding retains the line without modifying the state (even if
responding).
This patch changes the name of a bunch of packet flags and MSHR member
functions and variables to make the coherency protocol easier to
understand. In addition the patch adds and updates lots of
descriptions, explicitly spelling out assumptions.
The following name changes are made:
* the packet memInhibit flag is renamed to cacheResponding
* the packet sharedAsserted flag is renamed to hasSharers
* the packet NeedsExclusive attribute is renamed to NeedsWritable
* the packet isSupplyExclusive is renamed responderHadWritable
* the MSHR pendingDirty is renamed to pendingModified
The cache states, Modified, Owned, Exclusive, Shared are also called
out in the cache and MSHR code to make it easier to understand.
This patch is imported from reviewboard patch 2551 by Nilay.
This patch moves from a dynamically defined MachineType to a statically
defined one. The need for this patch was felt since a dynamically defined
type prevents us from having types for which no machine definition may
exist.
The following changes have been made:
i. each machine definition now uses a type from the MachineType enumeration
instead of any random identifier. This required changing the grammar and the
*.sm files.
ii. MachineType enumeration defined statically in RubySlicc_Exports.sm.
* * *
normal protocol fixes for nilay's parser machine type fix
This patch is imported from reviewboard patch 2550 by Nilay.
It was possible to specify multiple machine types with a single state machine.
This seems unnecessary and is being removed.
A couple of the long regressions have been showing as CHANGED
since 11244:a2af58a06c4e despite the updates in 11245:1c5102c0a7a9.
The x86 regression looks like it was just missed, but it's not clear
why the ARM one is giving different results (perhaps a non-determinism
between zizzer and wherever the updated results were run?).
Add a sanity check to make it explicit that we currently do not allow
an I/O coherent agent to directly issue writes into the coherent part
of the memory system (it has to go via a cache, and get transformed
into a read ex, upgrade or invalidation).
This patch changes how the cache tracks which snoops are forwarded,
and which ones are created locally. Previously the identification was
based on an empty sender state of a specific class, but this method
fails to distinguish which cache actually attached the sender
state. Instead we use the same mechanism as the crossbar, and keep
track of the requests that have outstanding snoops.
This patch addresses a bug in how the cache attached the MSHR as a
sender state. Rather than overwriting any existing sender state it now
pushes a new one. The handling of upward snoops is also clarified.
Currently, the wire format of register values in g- and G-packets is
modelled using a union of uint8/16/32/64 arrays. The offset positions
of each register are expressed as a "register count" scaled according
to the width of the register in question. This results in counter-
intuitive and error-prone "register count arithmetic", and some
formats would even be altogether unrepresentable in such model, e.g.
a 64-bit register following a 32-bit one would have a fractional index
in the regs64 array.
Another difficulty is that the array is allocated before the actual
architecture of the workload is known (and therefore before the correct
size for the array can be calculated).
With this patch I propose a simpler mechanism for expressing the
register set structure. In the new code, GdbRegCache is an abstract
class; its subclasses contain straightforward structs reflecting the
register representation. The determination whether to use e.g. the
AArch32 vs. AArch64 register set (or SPARCv8 vs SPARCv9, etc.) is made
by polymorphically dispatching getregs() to the concrete subclass.
The subclass is not instantiated until it is needed for actual
g-/G-packet processing, when the mode is already known.
This patch is not meant to be merged in on its own, because it changes
the contract between src/base/remote_gdb.* and src/arch/*/remote_gdb.*,
so as it stands right now, it would break the other architectures.
In this patch only the base and the ARM code are provided for review;
once we agree on the structure, I will provide src/arch/*/remote_gdb.*
for the other architectures; those patches could then be merged in
together.
Review Request: http://reviews.gem5.org/r/3207/
Pushed by Joel Hestness <jthestness@gmail.com>
When adding an option to forward work items to the Python environment,
the new behavior was accidentally enabled by default. Set the value of
exit_on_work_items to False by default to revert to the old behavior
unless the simulation scripts explicitly requests work item
forwarding.
This patch fixes a corner case in the deferred snoop handling, where
requests ended up being used by multiple packets with different
lifetimes, and inadvertently got deleted while they were still in use.
There are cases where we want the Python world to handle work items
instead of the C++ world. However, that's currently not possible. This
changeset adds the forward_work_items option to the System class. Then
it is set to True, work items will generate workbegin/workend
simulation exists with the work item ID as the exit code and the old
C++ handling is completely bypassed.
--HG--
extra : rebase_source : 8de637a744fc4b6ff2bc763f00cdf8ddf2bff885
This patch allows the ruby random tester to use ruby ports that may only
support instr or data requests. This patch is similar to a previous changeset
(8932:1b2c17565ac8) that was unfortunately broken by subsequent changesets.
This current patch implements the support in a more straight-forward way.
Since retries are now tested when running the ruby random tester, this patch
splits up the retry and drain check behavior so that RubyPort children, such
as the GPUCoalescer, can perform those operations correctly without having to
duplicate code. Finally, the patch also includes better DPRINTFs for
debugging the tester.
Move pcidev.(hh|cc) to src/dev/pci/device.(hh|cc) and update existing
devices to use the new header location. This also renames the PCIDEV
debug flag to have a capitalization that is consistent with the PCI
host and other devices.
--HG--
rename : src/dev/Pci.py => src/dev/pci/PciDevice.py
rename : src/dev/pcidev.cc => src/dev/pci/device.cc
rename : src/dev/pcidev.hh => src/dev/pci/device.hh
rename : src/dev/pcireg.h => src/dev/pci/pcireg.h
The writefile pseudo instruction uses OutputDirectory::create and
OutputDirectory::openFile to create the output files. However, by
default these will check the file extention for .gz, and create a gzip
compressed stream if the file ending matches. When writing out files,
we want to write them out exactly as they are in the guest simulation,
and never want to compress them with gzio. Additionally, this causes
m5 writefile to fail when checking the error flags for the output
steam.
With this patch we add an additional no_gz argument to
OutputDirectory::create and OutputDirectory::openFile which allows us
to override the gzip compression. Therefore, for m5 writefile we
disable the filename check, and always create a standard ostream.