translate
interface is implemented by objects
that bridge between memory spaces.
translator
interface
which is a more restricted version
of the translate
interface and should be used when possible.
It allows for better control of memory operations in the Simics core and can
therefore allow optimizations in the memory handling. NULL
, then the access
is translated to the default target provided in the configuration
(in a memory-space object, this is the 6th index,
target, of an entry in the map attribute).
If the translator marks mem_op as ignored before returning
NULL
(using the function SIM_set_mem_op_ignore), then
the return value is ignored, and the transaction is instead terminated in
the translator and handled as an ordinary I/O access.
During a translation, the translator may modify the physical address of mem_op, but may have no other side-effects. This is because the caller can choose to cache the translation, in which case the translator is bypassed in subsequent accesses.
The translator can use SIM_mem_op_ensure_future_visibility to inhibit caching. Inhibiting caching can be useful for debugging, but typically comes with a significant performance cost if there is RAM behind the translator.
The addition of the direct_memory
interface in Simics 5
results in new typical access patterns for the translate
interface. Where previously non-inquiry accesses of any size would result in
caching in initiating CPU objects, with the use of
direct_memory
no such implicit caching ever takes
place. Instead, caching requests are separate and fed through the
translate method as inquiry accesses of the size that is intended
to be cached. This means that for a translate
object to work
properly in a configuration with CPUs using direct_memory
,
inquiry accesses must be properly handled. Routing such inquiry accesses to
non-memory, terminating them in the translator (which is not an allowed
behavior for a translate
object), or calling
SIM_mem_op_ensure_future_visibility on them results in the
requesting CPU not being able to cache the requested memory region.
Using the translate
interface in models is error prone
and usually not recommended unless all alternatives have been
exhausted. Explicit map and demap operations in a memory space avoid the
problems with translate
interface implementation
correctness.
The usage of the translate
interface is by necessity
less optimal than the usage of the memory-space class as
a call out from the simulation kernel should be made. That said when
the translate() method is called the transaction may be cached
in the STC if the user code does not explicitly block such caching, though
depending on a number of factors it may not always be cached. If the
translation is cached in the STC then performance is the same as with a
memory-space.
There are two reasons to use the translate interface rather than a simple memory-space: 1) To implement something that the memory-space does not support, such as different read and write translations, or manipulation of the transaction, or 2) the translation is accessed infrequently, but updated on most accesses.
SIM_INTERFACE(translate) { conf_object_t *(*translate)(conf_object_t *NOTNULL obj, generic_transaction_t *NOTNULL mem_op, map_info_t mapinfo); }; #define TRANSLATE_INTERFACE "translate"