From 625fcb9ed352b8eac15040704646f0c181a28b1d Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Tue, 29 Dec 2015 11:10:58 -0700 Subject: [PATCH] ioat: add a union of all descriptor types The ioat library currently only supports DMA copy operations, but the hardware can do other types of transfers. Add a union of the hardware descriptor structures to enable support for the other operations in the future. Also add a generic hardware descriptor type to allow access to the parts of the descriptor that are common between all types. Change-Id: I3b54421ce771f58b78910e790b53026f311f918e Signed-off-by: Daniel Verkamp --- include/spdk/ioat_spec.h | 38 ++++++++++++++++++++++++++++++++++++++ lib/ioat/ioat.c | 38 +++++++++++++++++++------------------- lib/ioat/ioat_internal.h | 2 +- 3 files changed, 58 insertions(+), 20 deletions(-) diff --git a/include/spdk/ioat_spec.h b/include/spdk/ioat_spec.h index 280844bdd..e83e14f8d 100644 --- a/include/spdk/ioat_spec.h +++ b/include/spdk/ioat_spec.h @@ -94,6 +94,31 @@ struct ioat_registers { #define IOAT_CHANCMP_ALIGN 8 /* CHANCMP address must be 64-bit aligned */ +struct ioat_generic_hw_descriptor { + uint32_t size; + union { + uint32_t control_raw; + struct { + uint32_t int_enable: 1; + uint32_t src_snoop_disable: 1; + uint32_t dest_snoop_disable: 1; + uint32_t completion_update: 1; + uint32_t fence: 1; + uint32_t reserved2: 1; + uint32_t src_page_break: 1; + uint32_t dest_page_break: 1; + uint32_t bundle: 1; + uint32_t dest_dca: 1; + uint32_t hint: 1; + uint32_t reserved: 13; + uint32_t op: 8; + } control; + } u; + uint64_t src_addr; + uint64_t dest_addr; + uint64_t next; + uint64_t op_specific[4]; +}; struct ioat_dma_hw_descriptor { uint32_t size; @@ -265,4 +290,17 @@ struct ioat_raw_hw_descriptor { uint64_t field[8]; }; +union ioat_hw_descriptor { + struct ioat_raw_hw_descriptor raw; + struct ioat_generic_hw_descriptor generic; + struct ioat_dma_hw_descriptor dma; + struct ioat_fill_hw_descriptor fill; + struct ioat_xor_hw_descriptor xor; + struct ioat_xor_ext_hw_descriptor xor_ext; + struct ioat_pq_hw_descriptor pq; + struct ioat_pq_ext_hw_descriptor pq_ext; + struct ioat_pq_update_hw_descriptor pq_update; +}; +_Static_assert(sizeof(union ioat_hw_descriptor) == 64, "incorrect ioat_hw_descriptor layout"); + #endif /* __IOAT_SPEC_H__ */ diff --git a/lib/ioat/ioat.c b/lib/ioat/ioat.c index e5d028876..f4fa98f9f 100644 --- a/lib/ioat/ioat.c +++ b/lib/ioat/ioat.c @@ -208,7 +208,7 @@ ioat_get_ring_index(struct ioat_channel *ioat, uint32_t index) static void ioat_get_ring_entry(struct ioat_channel *ioat, uint32_t index, struct ioat_descriptor **desc, - struct ioat_dma_hw_descriptor **hw_desc) + union ioat_hw_descriptor **hw_desc) { uint32_t i = ioat_get_ring_index(ioat, index); @@ -220,7 +220,7 @@ static uint64_t ioat_get_desc_phys_addr(struct ioat_channel *ioat, uint32_t index) { return ioat->hw_ring_phys_addr + - ioat_get_ring_index(ioat, index) * sizeof(struct ioat_dma_hw_descriptor); + ioat_get_ring_index(ioat, index) * sizeof(union ioat_hw_descriptor); } static void @@ -239,7 +239,7 @@ static struct ioat_descriptor * ioat_prep_null(struct ioat_channel *ioat) { struct ioat_descriptor *desc; - struct ioat_dma_hw_descriptor *hw_desc; + union ioat_hw_descriptor *hw_desc; if (ioat_get_ring_space(ioat) < 1) { return NULL; @@ -247,14 +247,14 @@ ioat_prep_null(struct ioat_channel *ioat) ioat_get_ring_entry(ioat, ioat->head, &desc, &hw_desc); - hw_desc->u.control_raw = 0; - hw_desc->u.control.op = IOAT_OP_COPY; - hw_desc->u.control.null = 1; - hw_desc->u.control.completion_update = 1; + hw_desc->dma.u.control_raw = 0; + hw_desc->dma.u.control.op = IOAT_OP_COPY; + hw_desc->dma.u.control.null = 1; + hw_desc->dma.u.control.completion_update = 1; - hw_desc->size = 8; - hw_desc->src_addr = 0; - hw_desc->dest_addr = 0; + hw_desc->dma.size = 8; + hw_desc->dma.src_addr = 0; + hw_desc->dma.dest_addr = 0; desc->callback_fn = NULL; desc->callback_arg = NULL; @@ -269,7 +269,7 @@ ioat_prep_copy(struct ioat_channel *ioat, uint64_t dst, uint64_t src, uint32_t len) { struct ioat_descriptor *desc; - struct ioat_dma_hw_descriptor *hw_desc; + union ioat_hw_descriptor *hw_desc; ioat_assert(len <= ioat->max_xfer_size); @@ -279,13 +279,13 @@ ioat_prep_copy(struct ioat_channel *ioat, uint64_t dst, ioat_get_ring_entry(ioat, ioat->head, &desc, &hw_desc); - hw_desc->u.control_raw = 0; - hw_desc->u.control.op = IOAT_OP_COPY; - hw_desc->u.control.completion_update = 1; + hw_desc->dma.u.control_raw = 0; + hw_desc->dma.u.control.op = IOAT_OP_COPY; + hw_desc->dma.u.control.completion_update = 1; - hw_desc->size = len; - hw_desc->src_addr = src; - hw_desc->dest_addr = dst; + hw_desc->dma.size = len; + hw_desc->dma.src_addr = src; + hw_desc->dma.dest_addr = dst; desc->callback_fn = NULL; desc->callback_arg = NULL; @@ -449,14 +449,14 @@ ioat_channel_start(struct ioat_channel *ioat) return -1; } - ioat->hw_ring = ioat_zmalloc(NULL, num_descriptors * sizeof(struct ioat_dma_hw_descriptor), 64, + ioat->hw_ring = ioat_zmalloc(NULL, num_descriptors * sizeof(union ioat_hw_descriptor), 64, &ioat->hw_ring_phys_addr); if (!ioat->hw_ring) { return -1; } for (i = 0; i < num_descriptors; i++) { - ioat->hw_ring[i].next = ioat_get_desc_phys_addr(ioat, i + 1); + ioat->hw_ring[i].generic.next = ioat_get_desc_phys_addr(ioat, i + 1); } ioat->head = 0; diff --git a/lib/ioat/ioat_internal.h b/lib/ioat/ioat_internal.h index eea1d8a1a..82a84fa85 100644 --- a/lib/ioat/ioat_internal.h +++ b/lib/ioat/ioat_internal.h @@ -72,7 +72,7 @@ struct ioat_channel { uint64_t last_seen; struct ioat_descriptor *ring; - struct ioat_dma_hw_descriptor *hw_ring; + union ioat_hw_descriptor *hw_ring; uint64_t hw_ring_phys_addr; };