direct_memory_update
interface must be implemented by
memory-user objects that use the direct_memory
interface.
The direct_memory_update
interface replaces the
memory_page_update
interface from Simics 4.8.
Accesses to memory are controlled by a handle that the memory-user object
requests by calling the get_handle method of the
direct_memory
interface. The object implementing the
direct_memory
interface through which the handle was
established is passed to the functions in
direct_memory_update
as target.
If the release method is called, the corresponding
handle and all the permissions and inhibit protections are
recalled. The memory-user object must stop using the handle and
associated data pointers and then call the acknowledge method
ack in the direct_memory
interface from
which the handle was granted.
A call to the update_permission method revokes earlier requested
rights for a handle. The lost_access argument recalls rights to
use the handle for the given access bits. This means that the handle needs
to be re-fetched (by a call to the lookup method of the
direct_memory_lookup
interface followed by a call to the
get_handle method of the direct_memory
interface)
before the handle can be used again for the particular access. This typically
happens if a new breakpoint is inserted or a remap of the memory system is
done. In case of a remap it is possible that the same handle will never be
returned again which means that any user data associated with the handle
should be reclaimed.
The lost_permission and the lost_inhibit arguments describe which permission rights and inhibit protection that are revoked. However, in contrast to the lost_access, the handle is still valid and can be used to re-request permission rights and inhibit protection.
A call to the conflicting_access method informs a memory-user object that a conflicting memory operation will be performed. Hence, if the memory-user object have some protected representation of memory (such as decoded instructions in an internal cache), that representation of memory has to be flushed (or written back to memory in case of dirty data). Note however that the memory-user object does not lose any permission rights or any inhibit protection.
There is no mechanism for locking simulated memory in host memory.
All methods in this interface receive a direct_memory_ack_id_t
value as an argument. The ack method of the
direct_memory
interface must be called with this
id as an argument when the corresponding operation has been
carried out. The ack method may be called after the
direct_memory_update
interface function has returned, which
allows for queueing of update requests. This may be valuable if multiple
simulator threads are used.
An exception to the allowed queueing of update requests is for update
requests that are received while calling request in the
direct_memory
interface. Such requests must be handled
immediately with ack being called before the return of the
direct_memory_update
interface function. This requirement
avoids a dead-lock that would otherwise happen if request would
wait for ack before returning, but ack is
queued to be handled at some time after request has returned.
SIM_INTERFACE(direct_memory_update) { void (*release)(conf_object_t *NOTNULL obj, conf_object_t *NOTNULL target, direct_memory_handle_t handle, direct_memory_ack_id_t id); void (*update_permission)(conf_object_t *NOTNULL obj, conf_object_t *NOTNULL target, direct_memory_handle_t handle, access_t lost_access, access_t lost_permission, access_t lost_inhibit, direct_memory_ack_id_t id); void (*conflicting_access)(conf_object_t *NOTNULL obj, conf_object_t *NOTNULL target, direct_memory_handle_t handle, access_t conflicting_permission, direct_memory_ack_id_t id); }; #define DIRECT_MEMORY_UPDATE_INTERFACE "direct_memory_update"