|
|
udi_pio_map(3udi)
Map device memory/registers for access
#include <udi.h>void udi_pio_map ( udi_pio_map_call_t *callback, udi_cb_t *gcb, udi_ubit32_t regset_idx, udi_ubit32_t base_offset, udi_ubit32_t length, udi_pio_trans_t *trans_list, udi_ubit16_t list_length, udi_ubit16_t pio_attributes, udi_ubit32_t pace, udi_index_t serialization_domain ); typedef void udi_pio_map_call_t ( udi_cb_t *gcb, udi_pio_handle_t new_pio_handle ); /* Values for pio_attributes */#define UDI_PIO_STRICTORDER (1U<<0) #define UDI_PIO_UNORDERED_OK (1U<<1) #define UDI_PIO_MERGING_OK (1U<<2) #define UDI_PIO_LOADCACHING_OK (1U<<3) #define UDI_PIO_STORECACHING_OK (1U<<4) #define UDI_PIO_BIG_ENDIAN (1U<<5) #define UDI_PIO_LITTLE_ENDIAN (1U<<6) #define UDI_PIO_NEVERSWAP (1U<<7) #define UDI_PIO_UNALIGNED (1U<<8)ARGUMENTS callback, gcb are standard arguments described in the "Asynchronous Service Calls" section of "Standard Calling Sequences" in the UDI Core Specification.
regset_idx is the index to the specified register set within a given address space. The definition of regset_idx is bus and device dependent, and must be determined by the driver via the bus_type instance attribute (see Chapter 15, "Instance Attribute Management" in the UDI Core Specification) in conjunction with the corresponding UDI bus bindings (see "Section 3: Bus Bindings"). For example, if bus_type is "pci" then the settings would be based on the definitions in the UDI PCI Bus Binding Specification.
base_offset is the offset into the selected register address space at which this mapping is to start. This offset must be a multiple of all transaction sizes used to access device addresses through this handle, unless UDI_PIO_UNALIGNED is set in pio_attributes.
length is the length to be mapped in bytes.
trans_list is a list of one or more PIO transactions to apply to this device when using udi_pio_trans with this PIO handle. The memory pointed to by trans_list must be in a module-global (and thus read-only) variable.
list_length is the number of elements in the trans_list list.
pio_attributes are attribute flags that specify the data translation and ordering requirements of accesses to the device memory.
Attribute flags specifying the data translation requirements of the device are mutually exclusive. At most one must be used in a given handle allocation. The default is UDI_PIO_NEVERSWAP if no data translation flags are specified.
The following data translation flags are defined:
UDI_PIO_BIG_ENDIAN - access data in big endian format.
UDI_PIO_LITTLE_ENDIAN - access data in little endian format.
UDI_PIO_NEVERSWAP - access data with no byte swapping (appropriate for character data). Device transactions greater than one byte in size are illegal if this flag is set.
Attribute flags specifying the data ordering requirements for the device may be used in combination. With the exception of UDI_PIO_STRICTORDER these values are advisory, not mandatory. For example, data can be ordered without being merged or cached, even though a driver permits unordered, merged and cached operation. Strict ordering may be required for certain I/O operations but can be very costly on high performance computers. For unordered execution, merging or caching, the UDI_PIO_SYNC operation (see udi_pio_trans) can provide more specific and efficient synchronization.
The default is UDI_PIO_STRICTORDER if no ordering flags are specified. If pace is non-zero, pio_attributes must not include any data ordering flags other than UDI_PIO_STRICTORDER.
The following data ordering flags are defined:
UDI_PIO_STRICTORDER - the CPU must issue the references in order, as the programmer specified. Strict ordering is the default if no other data ordering flags are set. UDI_PIO_STRICTORDER must not be combined with any other data ordering flags.
UDI_PIO_UNORDERED_OK - the CPU may reorder both load and store references to the mapped area.
UDI_PIO_MERGING_OK - merging and batching: the CPU may merge individual stores to consecutive locations (for example, turn two consecutive byte stores into one halfword store), and it may batch individual loads (for example, turn two consecutive byte loads into one halfword load). If UDI_PIO_MERGING_OK is set, UDI_PIO_UNORDERED_OK is treated as if it were set, even if it isn't actually set.
UDI_PIO_LOADCACHING_OK - load caching: the CPU may cache the data it fetches and reuse it until another store occurs. The default is to fetch new data on every load. If UDI_PIO_LOADCACHING_OK is set, UDI_PIO_MERGING_OK is treated as if it were set, even if it isn't actually set.
UDI_PIO_STORECACHING_OK - store caching: the CPU may keep the data in the cache and push it to the device (perhaps with other data) at a later time. The default is to push data immediately to the device. If UDI_PIO_STORECACHING_OK is set, UDI_PIO_LOADCACHING_OK is treated as if it were set, even if it isn't actually set.
UDI_PIO_UNALIGNED - unaligned accesses allowed: if this flag is set, there are no restrictions on base_offset and on PIO offsets for individual transactions; otherwise, both of these must be multiples of all transaction sizes used in trans_list. If this flag is set, none of the transactions using this handle are guaranteed to be atomic.
pace is the PIO pacing time, in microseconds, for this handle. The environment will guarantee that any device access that occurs using this PIO handle will be followed by at least pace microseconds before another access occurs to the same device register set (via any handle). If non-zero, the UDI_PIO_STRICTORDER attribute must be specified.
PIO transactions may be posted/cached for future completion, so the apparent execution time of PIO operation calls may vary from the driver's perspective, but there will be at least pace microseconds between them from the hardware's perspective1.
serialization_domain is a numeric value indicating the serialization domain for this PIO handle. Transaction lists for a given device with the same serialization domain are serialized with respect to each other, and will further be executed in FIFO order with respect to udi_pio_trans calls from a given region. See the ordering definitions on page 4-1 for additional details.
new_pio_handle is an opaque data type containing the addressing, endian translation, and access constraint information required to access the associated device memory.
DESCRIPTION udi_pio_map initializes a handle through which a driver instance may access its device using PIO access routines. The regset_idx, base_offset, and length arguments select the range of device memory to be made accessible; the pio_attributes argument specifies the ways in which it may be accessed.
Note that the driver is allowed to map the same piece of device memory multiple times for different access requirements. For example, if the driver wants to do both strongly-ordered and weakly ordered accesses to a given register set it can map the register set once with UDI_PIO_STRICTORDER (strongly ordered accesses) and once with UDI_PIO_UNORDERED_OK (weakly ordered accesses). The driver would then use the "strong" PIO handle when it wants to do a strongly ordered access, and the "weak" handle otherwise. Similarly, multiple handles to a given register set could be used for zero pacing vs. various nonzero pacing values, and for other variations in attributes, offset, length, or trans list.
REFERENCES udi_pio_handle_t, udi_pio_unmap, udi_pio_trans
1The PIO pacing delay may be implemented in hardware or software by the environment, but represents a potential inline delay in region execution. The driver writer is strongly advised to use only the delays required for their device, as excessive use can have adverse effects on the driver and the rest of the system.