1/*
2 * Copyright (c) 2014, ETH Zurich. All rights reserved.
3 *
4 * This file is distributed under the terms in the attached LICENSE file.
5 * If you do not find this file, copies can be found by writing to:
6 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
7 */
8/*
9 *
10 *
11 */
12#include <stdio.h>
13#include <string.h>
14
15#include <barrelfish/barrelfish.h>
16#include <barrelfish/waitset.h>
17#include <barrelfish/nameservice_client.h>
18
19#include <dma/dma.h>
20#include <dma/dma_request.h>
21#include <dma/client/dma_client_device.h>
22#include <dma/dma_manager_client.h>
23
24#define DMA_BUFFER_SIZE  16
25#define DMA_BUFFER_COUNT 4
26
27#define EXPECT_SUCCESS(err, msg) if (err_is_fail(err)) {USER_PANIC_ERR(err, msg);}
28
29static struct capref frame;
30static size_t frame_size;
31static lpaddr_t frame_addr;
32static void *frame_virt;
33static uint8_t *buffers[DMA_BUFFER_COUNT];
34static lpaddr_t phys[DMA_BUFFER_COUNT];
35
36static void done_cb(errval_t err, dma_req_id_t id, void *arg)
37{
38    debug_printf("done_cb: %016lx, %s\n",id, err_getstring(err));
39    assert(memcmp(buffers[0], buffers[1], (DMA_BUFFER_SIZE << 20)) == 0);
40}
41
42static void prepare(void)
43{
44    errval_t err;
45
46    debug_printf("Preparing resources...\n");
47
48    err = frame_alloc(&frame, DMA_BUFFER_COUNT * (DMA_BUFFER_SIZE << 20),
49                      &frame_size);
50    EXPECT_SUCCESS(err, "allocating frame");
51
52    struct frame_identity id;
53    err = invoke_frame_identify(frame, &id);
54    EXPECT_SUCCESS(err, "Frame identify");
55
56    assert(frame_size == id.bytes);
57    frame_addr = id.base;
58
59    err = vspace_map_one_frame(&frame_virt, frame_size, frame, NULL, NULL);
60    EXPECT_SUCCESS(err, "Mapping of frame");
61
62    uint8_t *b = frame_virt;
63    lpaddr_t p = frame_addr;
64    for (uint32_t i = 0; i < DMA_BUFFER_COUNT; ++i) {
65        buffers[i] = b;
66        phys[i] = p;
67        b += ((DMA_BUFFER_SIZE << 20));
68        p += ((DMA_BUFFER_SIZE << 20));
69    }
70
71    debug_printf("preparation done.\n");
72}
73
74int main(int argc,
75         char *argv[])
76{
77    errval_t err;
78
79    debug_printf("DMA Test domain started\n");
80
81    prepare();
82
83#if 0
84    char svc_name[30];
85    uint8_t numa_node = (disp_get_core_id() >= 20);
86    snprintf(svc_name, 30, "ioat_dma_svc.%u", numa_node);
87    iref_t iref;
88    err = nameservice_blocking_lookup(svc_name, &iref);
89#endif
90
91    err = dma_manager_wait_for_driver(DMA_DEV_TYPE_IOAT, 0);
92    EXPECT_SUCCESS(err, "waiting for driver");
93
94    struct dma_client_info info = {
95        .type = DMA_CLIENT_INFO_TYPE_NAME,
96        .device_type = DMA_DEV_TYPE_IOAT,
97        .args = {
98            .name = "ioat_dma_svc.0"
99        }
100    };
101
102    struct dma_client_device *dev;
103    err = dma_client_device_init(&info, &dev);
104
105    err = dma_register_memory((struct dma_device *)dev, frame);
106    EXPECT_SUCCESS(err, "registering memory\n");
107
108    memset(buffers[0], 0x5A, (DMA_BUFFER_SIZE << 20));
109    memset(buffers[1], 0, (DMA_BUFFER_SIZE << 20));
110    assert(memcmp(buffers[0], buffers[1], (DMA_BUFFER_SIZE << 20)) != 0);
111
112    dma_req_id_t id;
113
114    struct dma_req_setup setup = {
115        .done_cb = done_cb,
116        .cb_arg = NULL,
117        .args =  {
118            .memcpy = {
119                .src = phys[0],
120                .dst = phys[1],
121                .bytes = (DMA_BUFFER_SIZE << 20)
122            }
123        }
124    };
125
126
127    uint32_t count = 0x1F;
128    while(count--) {
129
130        printf("\n\n=============================================\n\n");
131
132        err = dma_request_memcpy((struct dma_device *)dev, &setup, &id);
133        EXPECT_SUCCESS(err, "memcpy memory");
134        err = event_dispatch_non_block(get_default_waitset());
135        if (err_no(err) == LIB_ERR_NO_EVENT) {
136            err = SYS_ERR_OK;
137        }
138        EXPECT_SUCCESS(err, "event dispatch");
139    }
140    while (1) {
141        messages_wait_and_handle_next();
142    }
143
144    debug_printf("I/O AT DMA driver terminated\n");
145
146    return 0;
147}
148
149