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 <daniel.verkamp@intel.com>
This commit is contained in:
Daniel Verkamp 2015-12-29 11:10:58 -07:00
parent 777a06155c
commit 625fcb9ed3
3 changed files with 58 additions and 20 deletions

View File

@ -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__ */

View File

@ -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;

View File

@ -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;
};