|
XenevaOS
|
#include <iosys-map.h>
Public Attributes | ||
| union { | ||
| void __iomem * vaddr_iomem | ||
| void * vaddr | ||
| }; | ||
| bool | is_iomem | |
DOC: overview
When accessing a memory region, depending on its location, users may have to access it with I/O operations or memory load/store operations. For example, copying to system memory could be done with memcpy(), copying to I/O memory would be done with memcpy_toio().
.. code-block:: c
void *vaddr = ...; // pointer to system memory memcpy(vaddr, src, len);
void *vaddr_iomem = ...; // pointer to I/O memory memcpy_toio(vaddr_iomem, src, len);
The user of such pointer may not have information about the mapping of that region or may want to have a single code path to handle operations on that buffer, regardless if it's located in system or IO memory. The type :c:type:struct iosys_map <iosys_map> and its helpers abstract that so the buffer can be passed around to other drivers or have separate duties inside the same driver for allocation, read and write operations.
Open-coding access to :c:type:struct iosys_map <iosys_map> is considered bad style. Rather than accessing its fields directly, use one of the provided helper functions, or implement your own. For example, instances of :c:type:struct iosys_map <iosys_map> can be initialized statically with IOSYS_MAP_INIT_VADDR(), or at runtime with iosys_map_set_vaddr(). These helpers will set an address in system memory.
.. code-block:: c
struct iosys_map map = IOSYS_MAP_INIT_VADDR(0xdeadbeaf);
iosys_map_set_vaddr(&map, 0xdeadbeaf);
To set an address in I/O memory, use IOSYS_MAP_INIT_VADDR_IOMEM() or iosys_map_set_vaddr_iomem().
.. code-block:: c
struct iosys_map map = IOSYS_MAP_INIT_VADDR_IOMEM(0xdeadbeaf);
iosys_map_set_vaddr_iomem(&map, 0xdeadbeaf);
Instances of struct iosys_map do not have to be cleaned up, but can be cleared to NULL with iosys_map_clear(). Cleared mappings always refer to system memory.
.. code-block:: c
iosys_map_clear(&map);
Test if a mapping is valid with either iosys_map_is_set() or iosys_map_is_null().
.. code-block:: c
if (iosys_map_is_set(&map) != iosys_map_is_null(&map)) // always true
Instances of :c:type:struct iosys_map <iosys_map> can be compared for equality with iosys_map_is_equal(). Mappings that point to different memory spaces, system or I/O, are never equal. That's even true if both spaces are located in the same address space, both mappings contain the same address value, or both mappings refer to NULL.
.. code-block:: c
struct iosys_map sys_map; // refers to system memory struct iosys_map io_map; // refers to I/O memory
if (iosys_map_is_equal(&sys_map, &io_map)) // always false
A set up instance of struct iosys_map can be used to access or manipulate the buffer memory. Depending on the location of the memory, the provided helpers will pick the correct operations. Data can be copied into the memory with iosys_map_memcpy_to(). The address can be manipulated with iosys_map_incr().
.. code-block:: c
const void *src = ...; // source buffer size_t len = ...; // length of src
iosys_map_memcpy_to(&map, src, len); iosys_map_incr(&map, len); // go to first byte after the memcpy struct iosys_map - Pointer to IO/system memory @vaddr_iomem: The buffer's address if in I/O memory @vaddr: The buffer's address if in system memory @is_iomem: True if the buffer is located in I/O memory, or false otherwise.
| union { ... } iosys_map |
| bool iosys_map::is_iomem |
| void* iosys_map::vaddr |
| void __iomem* iosys_map::vaddr_iomem |