|
L4Re Operating System Framework
Interface and Usage Documentation
|
Managed DMA Address Space. More...
#include <dma_space>
Public Types | |
| enum | Direction { Bidirectional , To_device , From_device , None } |
| Direction of the DMA transfers. More... | |
| enum | Attribute : unsigned { Search_addr = 1U << 0 , Partial_map = 1U << 1 , Reserve = 1U << 2 , Replace = 1U << 3 } |
| Attributes used for the memory region. More... | |
| enum | Unmap_flag : unsigned { Cancel_reservation = 1U << 0 } |
| Flags used by Dma_space::unmap(). More... | |
| typedef l4_uint64_t | Dma_addr |
| Data type for DMA addresses. | |
| using | Attributes = L4::Types::Flags_t<Attribute, unsigned> |
| Attributes for DMA mappings. | |
| using | Unmap_flags = L4::Types::Flags_t<Unmap_flag, unsigned> |
| Flags for Dma_space::unmap(). | |
Public Member Functions | |
| l4_ret_t | map (L4::Ipc::Cap< L4Re::Dataspace > src, L4Re::Dataspace::Offset offset, l4_size_t *size, Attributes attrs, Direction dir, Dma_addr *dma_addr) |
| Map the given part of this data space into the DMA address space. | |
| l4_ret_t | map (L4::Ipc::Cap< L4Re::Dataspace > src, L4Re::Dataspace::Offset offset, Dma_size *size, Dma_addr *dma_addr, Dma_addr dma_max=-1, Attributes attrs=Search_addr, unsigned char align=L4_SUPERPAGESHIFT) |
| Map the given part of this data space into the DMA address space. | |
| l4_ret_t | unmap (Dma_addr dma_addr, Dma_size size, Attributes attrs, Direction dir) |
| Unmap the given part of this data space from the DMA address space. | |
| l4_ret_t | unmap (Dma_addr dma_addr, Dma_size size, Unmap_flags flags=Unmap_flags()) |
| Unmap the given part of this data space from the DMA address space. | |
Managed DMA Address Space.
A managed Dma_space represents the L4Re abstraction of an DMA address space of one or several devices. Devices are assigned to a managed Dma_space by binding the Dma_space to the respective DMA domain (see L4vbus::Vbus::assign_dma_domain()), which might link the Dma_space with a kernel DMA space. Note that several DMA domains can be bound to the same Dma_space. Whenever a device needs direct access to parts of an L4Re::Dataspace, that part of the data space must be mapped to the managed Dma_space that is assigned to that device. Binding to DMA domains must happen before mapping. After the DMA accesses to the memory are finished the memory must be unmapped from the device's DMA address space.
Mapping to a managed DMA address space, using map(), makes the given parts of the data space visible to the associated device at the returned DMA address. As long as the memory is mapped into a DMA space it is 'pinned' and cannot be subject to dynamic memory management such as swapping.
unmap() is the reverse operation to map() and unmaps the given data-space part for the DMA address space.
| using L4Re::Dma_space::Attributes = L4::Types::Flags_t<Attribute, unsigned> |
| using L4Re::Dma_space::Unmap_flags = L4::Types::Flags_t<Unmap_flag, unsigned> |
| enum L4Re::Dma_space::Attribute : unsigned |
Attributes used for the memory region.
| Enumerator | |
|---|---|
| Search_addr | Search for suitable address. A spot for the whole mapping is searched, starting from the passed start address. Without this flag, the start address is taken literally. Can be combined with Attribute::Partial_map. If no address remapping is possible (i.e., the Dma_space was associated by Dma_space_mgr::associate_phys()), the flag has no effect. The Dma_space::map() call will always return the physical address. |
| Partial_map | Truncate mapping if it does not fit. If there is not enough room after the chosen start address, truncate the mapping instead of failing. |
| Reserve | Reserve a region instead of mapping pages. If set, the dataspace argument of Dma_space::map() is ignored. Use the Attribute::Replace flag to place dataspace mappings in a reserved region later. The reservation is released with Dma_space::unmap() carrying Unmap_flag::Cancel_reservation. If no address remapping is possible (i.e., the Dma_space was associated by Dma_space_mgr::associate_phys()), Dma_space::map() will always fail with -L4_EPERM if this flag is present. |
| Replace | Replace mappings. The pages in the map region are replaced with mappings from the dataspace. Without this flag, existing mappings cause Dma_space::map() to fail. Areas previously claimed by Dma_space_mgr::block_area() are never replaced and still cause Dma_space::map() to fail. If combined with Attribute::Reserve, no dataspace mapping is established. Instead, the reservation reference count is increased. Only after the matching number of Dma_space::unmap(Cancel_reservation) calls, the reservation is released. If no address remapping is possible (i.e., the Dma_space was associated by Dma_space_mgr::associate_phys()), the flag has no effect. The Dma_space::map() call will always return the physical address. Cannot be combined with Attribute::Search_addr or Attribute::Partial_map. |
Direction of the DMA transfers.
| Enumerator | |
|---|---|
| Bidirectional | device reads and writes to the memory |
| To_device | device reads the memory |
| From_device | device writes to the memory |
| None | device is coherently connected to the memory |
| enum L4Re::Dma_space::Unmap_flag : unsigned |
Flags used by Dma_space::unmap().
| Enumerator | |
|---|---|
| Cancel_reservation | Cancel a prior Attribute::Reserve claim instead of unmapping a dataspace mapping. Without this flag, unmap() releases one dataspace mapping that was previously established by map() (with or without Attribute::Replace). With this flag, unmap() releases one previous Attribute::Reserve claim and does not touch any active dataspace mappings in the range. |
|
inline |
Map the given part of this data space into the DMA address space.
| [in] | src | Source data space (that describes the memory). |
| [in] | offset | The offset (bytes) within src. Must be zero in case Attribute::Reserve is passed in attrs. |
| [in,out] | size | The size (bytes) of the region to be mapped for DMA, after successful mapping the size returned is the size mapped for DMA as a single block. This size might be smaller than the original input size, in this case the caller might call map() again with a new offset and the remaining size. |
| [in,out] | dma_addr | The DMA address to use for DMA with the associated device. Either taken literally (in which case it must be page aligned) or used as starting address if Attribute::Search_addr is passed. |
| [in] | dma_max | Highest allowed DMA address of the mapping (inclusive). |
| [in] | attrs | The attributes used for this DMA mapping (a combination of Dma_space::Attribute values). |
| [in] | align | Alignment of mapping (log2 based). Only used if Attribute::Search_addr is passed. |
| L4_EOK | Operation successful. |
| -L4_EADDRNOTAVAIL | The specified region overlaps an existing mapping/blocking or no space left in search area. |
| -L4_EPERM | Insufficient permissions; see precondition. |
| -L4_EINVAL | The capability src is invalid or does not refer to a valid dataspace. |
| -L4_ENOMEM | Not enough memory to allocate internal datastructures. |
| -L4_ERANGE | offset is larger than the size of the dataspace. |
The DMA mapping is created writable if capability src has the permission L4_CAP_FPAGE_W. Otherwise, a read-only DMA mapping is established.
If no address remapping is possible (i.e., the Dma_space was associated by Dma_space_mgr::associate_phys()), Dma_space::map() will always return the physical address. The caller should therefore be prepared that a desired DMA address is ignored.
Definition at line 260 of file dma_space.
References L4::Kobject_t< Derived, L4::Kobject, L4::PROTO_ANY, Type_info::Demand_t<> >::c(), L4_SUPERPAGESHIFT, and Search_addr.
|
inline |
Map the given part of this data space into the DMA address space.
A suitable address in the DMA task will be chosen automatically.
| [in] | src | Source data space (that describes the memory). |
| [in] | offset | The offset (bytes) within src. |
| [in,out] | size | The size (bytes) of the region to be mapped for DMA, after successful mapping the size returned is the size mapped for DMA as a single block. This size might be smaller than the original input size, in this case the caller might call map() again with a new offset and the remaining size. |
| [in] | attrs | The attributes used for this DMA mapping (a combination of Dma_space::Attribute values). The Search_addr attribute is forced by this overload! |
| [in] | dir | The direction of the DMA transfer issued with this mapping. The same value must later be passed to unmap(). (ignored) |
| [out] | dma_addr | The DMA address to use for DMA with the associated device. |
| L4_EOK | Operation successful. |
| -L4_EADDRNOTAVAIL | The specified region overlaps an existing mapping. |
| -L4_EINVAL | The capability src is invalid or does not refer to a valid dataspace. |
| -L4_ENOMEM | Not enough memory to allocate internal datastructures. |
| -L4_ERANGE | offset is larger than the size of the dataspace. |
The DMA mapping is created writable if capability src has the permission L4_CAP_FPAGE_W. Otherwise, a read-only DMA mapping is established.
Definition at line 190 of file dma_space.
References map(), and Search_addr.
Referenced by map().
|
inline |
Unmap the given part of this data space from the DMA address space.
The calls to map() and unmap() must be balanced. That is, each page of a mapping that was established by map() previously must be unmapped exactly once.
Sub-ranges that do not currently hold a mapping are silently skipped. That is, unmapping the same region too often, is not treated as an error.
| dma_addr | The DMA address (returned by Dma_space::map()). |
| size | The size (bytes) of the memory region to unmap. |
| attrs | The attributes for the unmap (currently none, ignored). |
| dir | The direction of the finished DMA operation (ignored). |
| L4_EOK | Operation successful. |
| -L4_ENOMEM | Not enough memory to allocate internal datastructures. |
Definition at line 326 of file dma_space.
References unmap().
Referenced by unmap().
|
inline |
Unmap the given part of this data space from the DMA address space.
The calls to map() and unmap() must be balanced. That is, each page of a mapping that was established by map() previously must be unmapped exactly once. Likewise, every Attribute::Reserve claim must be released by exactly one unmap() call carrying Unmap_flag::Cancel_reservation.
Sub-ranges that do not currently hold a claim of the requested kind are silently skipped. That is, unmapping the same region too often, is not treated as an error. This behaviour applies both to actual mappings, as well as reservations.
| dma_addr | The DMA address (returned by Dma_space::map()). |
| size | The size (bytes) of the memory region to unmap. |
| flags | A combination of Dma_space::Unmap_flag values. |
| L4_EOK | Operation successful. |
| -L4_EPERM | The range overlaps with a privileged Dma_space_mgr::block_area() claim. |
| -L4_EINVAL | Invalid arguments. Can be caused by unknown flags, size of 0 or an address overflow. |
| -L4_ENOMEM | Not enough memory to allocate internal datastructures. |
Definition at line 358 of file dma_space.
References L4::Kobject_t< Derived, L4::Kobject, L4::PROTO_ANY, Type_info::Demand_t<> >::c().