The PVBusSlaveControl protocol enables you to access and modify the underlying memory that PVBusSlave controls.
setFillPattern(uint32_t fill1, uint32_t fill2)
- This sets a two-word alternating fill pattern to be used by uninitialized memory.
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) and
top(exclusive value) specify the address range to configure.
typeselects what types of bus access must be reconfigured. It can be one of:
modedefines 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
storagemust 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 memory contents.
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_handleto identify it.
The caller can then repeatedly call
iter_handle. If it finds a region, the behavior returns
trueand writes to the
infostruct 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
closeRegionIterHandle(). This deallocates the iterator, and further uses of the handle are invalid.