The PVBusSlaveControl protocol enables you to access and modify the underlying memory that PVBusSlave controls.
setFillPattern(uint32_t fill1, uint32_t fill2)
setAccess(pv::bus_addr_t base, pv::bus_addr_t top, pv::accessType type, pv::accessMode mode)
This reconfigures handling for a region of memory.
base (inclusive value)
top (exclusive value) specify the
address range to configure.
type selects what types
of bus access must be reconfigured. It can be one of:
mode defines how to
handle bus accesses. It can be one of:
getReadStorage(pv::bus_addr_t address, pv::bus_addr_t *limit) : const uint8_t *
getWriteStorage(pv::bus_addr_t address, pv::bus_addr_t *limit) : uint8_t *
These two methods permit you to access the underlying storage that PVBusSlave allocates to implement a region of memory.
The return value is a pointer to the byte that represents
the storage corresponding to the address of
The limit pointer returns the device address for the limit of the accessible memory.
The pointer value returned is not guaranteed to remain valid indefinitely. Bus activities, or other calls to the control port, might invalidate the pointer.
provideReadStorage(pv::bus_addr_t device_base, pv::bus_addr_t device_limit, const uint8_t *storage)
provideWriteStorage(pv::bus_addr_t device_base, pv::bus_addr_t device_limit, uint8_t *storage)
provideReadWriteStorage(pv::bus_addr_t device_base, pv::bus_addr_t device_limit, uint8_t *storage)
These methods enable you to allocate blocks of memory that the PVBusSlave can use to manage regions of RAM/ROM. Only use these methods when you require a high degree of control over memory, such as when you require a device to map specific regions of host memory into the simulation.
The memory region pointed to by
storage must be large enough to contain
(limit - base) bytes.
After these calls, PVBusSlave controls access to the
underlying memory. The owner must call
getWriteStorage() before modifying the memory contents and
getReadStorage() before reading the
provideReadStorageEx(pv::bus_addr_t device_base, pv::bus_addr_t device_limit, const uint8_t *storage, double latency)
provideWriteStorageEx(pv::bus_addr_t device_base, pv::bus_addr_t device_limit, const uint8_t *storage, double latency)
provideReadWriteStorageEx(pv::bus_addr_t device_base, pv::bus_addr_t device_limit, uint8_t *storage, double read_latency, double write_latency)
These methods take additional parameters to specify average latencies (in seconds) per byte, used when Timing Annotation is enabled.
In all other aspects they behave the same as
slave behavior getRegionIterHandle(): uint32_t;
slave behavior getNextRegionInfo(uint32_t iter_handle, pv::PVBusSlaveRegionInfo *info) : bool;
slave behavior closeRegionIterHandle(uint32_t iter_handle);
These methods form an iterator-like API that allows a PVBusSlave providing storage to report all the regions of the address space that have backing store.
The iteration begins by calling
getRegionIterHandle(). This allocates an iterator and if
successful returns a nonzero
iter_handle to identify it.
The caller can then repeatedly call
iter_handle. If it finds a region, the
true and writes to the
info struct if the pointer is
non-null. Access the data in the region using
The implementation can return regions in any order. They can be of any size or alignment, but must not overlap.
The implementation need not report allocated regions that are filled entirely with the default fill pattern, or allocated regions that contain only the data they had at simulation start.
On reaching the last region, the iterator closes
automatically. If the handle is invalid or there are no further regions,
the behavior returns
A caller can close an iterator opened by
getRegionIterHandle() at any time using
deallocates the iterator, and further uses of the handle are