Implementation (for linux generic) of the DMA descriptor and related methods.
Signed-off-by: Christophe Milard <christophe.mil...@linaro.org> --- platform/linux-generic/Makefile.am | 4 ++ platform/linux-generic/include/odp/dma.h | 36 ++++++++++ .../linux-generic/include/odp/plat/dma_types.h | 42 ++++++++++++ platform/linux-generic/include/odp_dma_internal.h | 67 +++++++++++++++++++ platform/linux-generic/odp_dma.c | 78 ++++++++++++++++++++++ 5 files changed, 227 insertions(+) create mode 100644 platform/linux-generic/include/odp/dma.h create mode 100644 platform/linux-generic/include/odp/plat/dma_types.h create mode 100644 platform/linux-generic/include/odp_dma_internal.h create mode 100644 platform/linux-generic/odp_dma.c diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 75ca703..d0938c9 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -24,6 +24,7 @@ odpinclude_HEADERS = \ $(srcdir)/include/odp/cpumask.h \ $(srcdir)/include/odp/crypto.h \ $(srcdir)/include/odp/debug.h \ + $(srcdir)/include/odp/dma.h \ $(srcdir)/include/odp/errno.h \ $(srcdir)/include/odp/event.h \ $(srcdir)/include/odp/hash.h \ @@ -63,6 +64,7 @@ odpplatinclude_HEADERS = \ $(srcdir)/include/odp/plat/classification_types.h \ $(srcdir)/include/odp/plat/cpumask_types.h \ $(srcdir)/include/odp/plat/crypto_types.h \ + $(srcdir)/include/odp/plat/dma_types.h \ $(srcdir)/include/odp/plat/event_types.h \ $(srcdir)/include/odp/plat/packet_types.h \ $(srcdir)/include/odp/plat/packet_io_types.h \ @@ -93,6 +95,7 @@ noinst_HEADERS = \ ${srcdir}/include/odp_classification_internal.h \ ${srcdir}/include/odp_crypto_internal.h \ ${srcdir}/include/odp_debug_internal.h \ + ${srcdir}/include/odp_dma_internal.h \ ${srcdir}/include/odp_forward_typedefs_internal.h \ ${srcdir}/include/odp_internal.h \ ${srcdir}/include/odp_name_table_internal.h \ @@ -122,6 +125,7 @@ __LIB__libodp_la_SOURCES = \ odp_cpumask.c \ odp_cpumask_task.c \ odp_crypto.c \ + odp_dma.c \ odp_errno.c \ odp_event.c \ odp_hash.c \ diff --git a/platform/linux-generic/include/odp/dma.h b/platform/linux-generic/include/odp/dma.h new file mode 100644 index 0000000..af7aaeb --- /dev/null +++ b/platform/linux-generic/include/odp/dma.h @@ -0,0 +1,36 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP dma interface + */ + +#include <odp/plat/dma_types.h> + +#ifndef ODP_PLAT_DMA_H_ +#define ODP_PLAT_DMA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @ingroup odp_dma + * @{ + */ + +/** + * @} + */ + +#include <odp/api/dma.h> + +#ifdef __cplusplus +} +#endif + +#endif /* ODP_PLAT_DMA_H_ */ diff --git a/platform/linux-generic/include/odp/plat/dma_types.h b/platform/linux-generic/include/odp/plat/dma_types.h new file mode 100644 index 0000000..8f180de --- /dev/null +++ b/platform/linux-generic/include/odp/plat/dma_types.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP dma interface + */ + +#ifndef ODP_DMA_TYPES_H_ +#define ODP_DMA_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/std_types.h> +#include <odp/plat/strong_types.h> + +/** @addtogroup odp_dma + * @{ + */ + +/** A address usable by a DMA (i.e. either physical or iova, if iommu ) */ +typedef uint64_t odp_dma_addr_t; + +/** DMA descriptor */ +typedef ODP_HANDLE_T(odp_dma_map_t); +#define ODP_DMA_REGION_INVALID _odp_cast_scalar(odp_dma_map_t, 0) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ODP_DMA_TYPES_H_ */ diff --git a/platform/linux-generic/include/odp_dma_internal.h b/platform/linux-generic/include/odp_dma_internal.h new file mode 100644 index 0000000..888ef3b --- /dev/null +++ b/platform/linux-generic/include/odp_dma_internal.h @@ -0,0 +1,67 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP dma interface - implementation internal + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ODP_DMA_INTERNAL_H_ +#define ODP_DMA_INTERNAL_H_ + +#include <odp/std_types.h> +#include <odp/debug.h> +#include <odp/align.h> +#include <odp_align_internal.h> +#include <odp/byteorder.h> + +/** @addtogroup odp_dma + * @{ + */ + +/** the linux implementation of a DMA map descriptor (odp_dma_map_t) */ +typedef struct dma_map_t dma_map_t; +typedef struct dma_map_t { + /**< address (virtual, in driver user space) of the region */ + void *addr; + /**< DMA address (either physical, or IO virtual if iommu) for region */ + odp_dma_addr_t dma_addr; + /**< size of the region, in bytes */ + uint64_t size; + /**< link to next dma region, or NULL for last */ + dma_map_t *next; +} dma_map_t; + +/** + * Returns a pointer to a linux DMA map descriptor from the related ODP + * handle. + */ +static inline dma_map_t *dma_map_handle_to_map(odp_dma_map_t map_hdl) +{ + return (dma_map_t *)map_hdl; +} + +/** + * Allocate a (not filled) DMA map structure. + */ +dma_map_t *_odp_dma_map_alloc(void); + +/** + * Link two DMA map descriptors (hence describing a scattered area) + * returns a pointer to the second structure (map2). + */ +dma_map_t *_odp_dma_map_link(dma_map_t *map1, dma_map_t *map2); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/odp_dma.c b/platform/linux-generic/odp_dma.c new file mode 100644 index 0000000..513e46f --- /dev/null +++ b/platform/linux-generic/odp_dma.c @@ -0,0 +1,78 @@ +/* Copyright (c) 2015, Linaro Limited + * Copyright (c) 2015, Nokia Solutions and Networks + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <odp/dma.h> +#include <odp_dma_internal.h> +#include <stdlib.h> +#include <odp/hints.h> + +/* operations on DMA map descriptors: */ + +/* + * allocate a single DMA region descriptor + */ +dma_map_t *_odp_dma_map_alloc(void) +{ + dma_map_t *dma_map = malloc(sizeof(dma_map_t)); + + if (!(dma_map)) + return NULL; + dma_map->next = NULL; + return dma_map; +} + +/* + * extend a DMA region descriptor list (link map2 to map1) + */ +dma_map_t *_odp_dma_map_link(dma_map_t *map1, dma_map_t *map2) +{ + if (odp_unlikely(map2 == NULL)) + return NULL; + + if (odp_unlikely(map1 == NULL)) + return map2; /*first of a chain */ + + map1->next = map2; + + return map2; +} + +void *odp_dma_map_get_addr(odp_dma_map_t map) +{ + return dma_map_handle_to_map(map)->addr; +} + +odp_dma_addr_t odp_dma_map_get_dma_addr(odp_dma_map_t map) +{ + return dma_map_handle_to_map(map)->dma_addr; +} + +int odp_dma_map_get_size(odp_dma_map_t map) +{ + return dma_map_handle_to_map(map)->size; +} + +odp_dma_map_t odp_dma_map_get_next(odp_dma_map_t map) +{ + dma_map_t *map_s = dma_map_handle_to_map(map)->next; + + if (map_s) + return (odp_dma_map_t)map_s; + else + return ODP_DMA_REGION_INVALID; +} + +void odp_dma_map_free(odp_dma_map_t map) +{ + dma_map_t *next; + dma_map_t *map_s = dma_map_handle_to_map(map); + + do { + next = map_s->next; + free(map); + } while (next != NULL); +} -- 2.1.4 _______________________________________________ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp