diff options
Diffstat (limited to 'sys/dev/ioat')
-rw-r--r-- | sys/dev/ioat/ioat.c | 31 | ||||
-rw-r--r-- | sys/dev/ioat/ioat.h | 8 | ||||
-rw-r--r-- | sys/dev/ioat/ioat_test.c | 41 | ||||
-rw-r--r-- | sys/dev/ioat/ioat_test.h | 9 |
4 files changed, 85 insertions, 4 deletions
diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c index fed6e37d380e..b3939f89b0da 100644 --- a/sys/dev/ioat/ioat.c +++ b/sys/dev/ioat/ioat.c @@ -748,6 +748,37 @@ ioat_copy(bus_dmaengine_t dmaengine, bus_addr_t dst, return (&desc->bus_dmadesc); } +struct bus_dmadesc * +ioat_blockfill(bus_dmaengine_t dmaengine, bus_addr_t dst, uint64_t fillpattern, + bus_size_t len, bus_dmaengine_callback_t callback_fn, void *callback_arg, + uint32_t flags) +{ + struct ioat_fill_hw_descriptor *hw_desc; + struct ioat_descriptor *desc; + struct ioat_softc *ioat; + + CTR0(KTR_IOAT, __func__); + ioat = to_ioat_softc(dmaengine); + + if ((dst & (0xffffull << 48)) != 0) { + ioat_log_message(0, "%s: High 16 bits of dst invalid\n", + __func__); + return (NULL); + } + + desc = ioat_op_generic(ioat, IOAT_OP_FILL, len, fillpattern, dst, + callback_fn, callback_arg, flags); + if (desc == NULL) + return (NULL); + + hw_desc = desc->u.fill; + if (g_ioat_debug_level >= 3) + dump_descriptor(hw_desc); + + ioat_submit_single(ioat); + return (&desc->bus_dmadesc); +} + /* * Ring Management */ diff --git a/sys/dev/ioat/ioat.h b/sys/dev/ioat/ioat.h index 46f9769be824..e99714df275f 100644 --- a/sys/dev/ioat/ioat.h +++ b/sys/dev/ioat/ioat.h @@ -68,6 +68,14 @@ void ioat_put_dmaengine(bus_dmaengine_t dmaengine); void ioat_acquire(bus_dmaengine_t dmaengine); void ioat_release(bus_dmaengine_t dmaengine); +/* + * Issue a blockfill operation. The 64-bit pattern 'fillpattern' is written to + * 'len' physically contiguous bytes at 'dst'. + */ +struct bus_dmadesc *ioat_blockfill(bus_dmaengine_t dmaengine, bus_addr_t dst, + uint64_t fillpattern, bus_size_t len, bus_dmaengine_callback_t callback_fn, + void *callback_arg, uint32_t flags); + /* Issues the copy data operation */ struct bus_dmadesc *ioat_copy(bus_dmaengine_t dmaengine, bus_addr_t dst, bus_addr_t src, bus_size_t len, bus_dmaengine_callback_t callback_fn, diff --git a/sys/dev/ioat/ioat_test.c b/sys/dev/ioat/ioat_test.c index 215b0363e429..3f88ed98a689 100644 --- a/sys/dev/ioat/ioat_test.c +++ b/sys/dev/ioat/ioat_test.c @@ -123,11 +123,26 @@ test_transaction *ioat_test_transaction_create(unsigned num_buffers, static bool ioat_compare_ok(struct test_transaction *tx) { - uint32_t i; + struct ioat_test *test; + char *dst, *src; + uint32_t i, j; + + test = tx->test; for (i = 0; i < tx->depth; i++) { - if (memcmp(tx->buf[2*i], tx->buf[2*i+1], tx->length) != 0) - return (false); + dst = tx->buf[2 * i + 1]; + src = tx->buf[2 * i]; + + if (test->testkind == IOAT_TEST_FILL) { + for (j = 0; j < tx->length; j += sizeof(uint64_t)) { + if (memcmp(src, &dst[j], + MIN(sizeof(uint64_t), tx->length - j)) + != 0) + return (false); + } + } else if (test->testkind == IOAT_TEST_DMA) + if (memcmp(src, dst, tx->length) != 0) + return (false); } return (true); } @@ -208,8 +223,11 @@ ioat_test_submit_1_tx(struct ioat_test *test, bus_dmaengine_t dma) struct bus_dmadesc *desc; bus_dmaengine_callback_t cb; bus_addr_t src, dest; + uint64_t fillpattern; uint32_t i, flags; + desc = NULL; + IT_LOCK(); while (TAILQ_EMPTY(&test->free_q)) msleep(&test->free_q, &ioat_test_lk, 0, "test_submit", 0); @@ -232,7 +250,15 @@ ioat_test_submit_1_tx(struct ioat_test *test, bus_dmaengine_t dma) flags = 0; } - desc = ioat_copy(dma, src, dest, tx->length, cb, tx, flags); + if (test->testkind == IOAT_TEST_DMA) + desc = ioat_copy(dma, dest, src, tx->length, cb, tx, + flags); + else if (test->testkind == IOAT_TEST_FILL) { + fillpattern = *(uint64_t *)tx->buf[2*i]; + desc = ioat_blockfill(dma, dest, fillpattern, + tx->length, cb, tx, flags); + } + if (desc == NULL) panic("Failed to allocate a ring slot " "-- this shouldn't happen!"); @@ -279,6 +305,13 @@ ioat_dma_test(void *arg) return; } + if (test->testkind >= IOAT_NUM_TESTKINDS) { + ioat_test_log(0, "Invalid kind %u\n", + (unsigned)test->testkind); + test->status[IOAT_TEST_INVALID_INPUT]++; + return; + } + dmaengine = ioat_get_dmaengine(test->channel_index); if (dmaengine == NULL) { ioat_test_log(0, "Couldn't acquire dmaengine\n"); diff --git a/sys/dev/ioat/ioat_test.h b/sys/dev/ioat/ioat_test.h index 290d09b49017..ecfef7d5cb19 100644 --- a/sys/dev/ioat/ioat_test.h +++ b/sys/dev/ioat/ioat_test.h @@ -34,15 +34,24 @@ enum ioat_res { IOAT_TEST_NO_DMA_ENGINE, IOAT_TEST_NO_MEMORY, IOAT_TEST_MISCOMPARE, + IOAT_TEST_INVALID_INPUT, IOAT_NUM_RES }; +enum ioat_test_kind { + IOAT_TEST_FILL = 0, + IOAT_TEST_DMA, + IOAT_NUM_TESTKINDS +}; + struct test_transaction; struct ioat_test { volatile uint32_t status[IOAT_NUM_RES]; uint32_t channel_index; + enum ioat_test_kind testkind; + /* HW max of 1MB */ uint32_t buffer_size; uint32_t chain_depth; |