1/*
2 * Copyright (c) 2007-12 ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#include <stdio.h>
11#include <string.h>
12#include <stdlib.h>
13
14#include <barrelfish/barrelfish.h>
15#include <barrelfish/dispatch.h>
16#include <barrelfish/ump_chan.h>
17
18#include <dma/xeon_phi/xeon_phi_dma.h>
19#include <dma/dma_request.h>
20#include <dma/client/dma_client_device.h>
21#include <dma/dma_manager_client.h>
22
23#include <xeon_phi/xeon_phi.h>
24#include <xeon_phi/xeon_phi_client.h>
25
26uint32_t send_reply = 0x0;
27
28#include "benchmark.h"
29
30uint8_t connected = 0;
31
32static void *card_buf;
33static struct capref card_frame;
34static lpaddr_t card_base;
35static size_t card_frame_sz;
36
37static void *host_buf;
38static struct capref host_frame;
39static lpaddr_t host_base;
40static size_t host_frame_sz;
41
42static struct bench_bufs bufs;
43static struct bench_bufs bufs_rev;
44
45static struct ump_chan uc;
46static struct ump_chan uc_rev;
47
48static void *inbuf;
49static void *outbuf;
50
51static void *inbuf_rev;
52static void *outbuf_rev;
53
54static xphi_dom_id_t domainid;
55
56#ifndef XPHI_BENCH_PROCESS_CARD
57
58static volatile uint8_t dma_completed;
59
60static void dma_done_cb(errval_t err,
61                        dma_req_id_t id,
62                        void *st)
63{
64    size_t size = (host_frame_sz < card_frame_sz ? host_frame_sz : card_frame_sz);
65    size = (size <= (1UL << 21) ? size : (1UL << 21));
66    debug_printf("DMA request %016lx executed...[%08x]-[%08x] result: %s\n", id,
67                 *((uint32_t *) host_buf), *((uint32_t *) card_buf),
68                 (memcmp(host_buf, card_buf, size) ? "FAIL" : "SUCCESS"));
69    dma_completed = 0x1;
70}
71
72static errval_t dma_test(struct dma_device *dev)
73{
74    errval_t err;
75
76    debug_printf("''''''''''''''''''''''''''''''''''''''''''''\n");
77    debug_printf("DMA TEST & Verification\n");
78    debug_printf(",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n");
79
80    dma_req_id_t id;
81
82    uint32_t test = 0xcafebabe;
83
84    size_t size = (host_frame_sz < card_frame_sz ? host_frame_sz : card_frame_sz);
85
86    size = (size <= (1UL << 21) ? size : (1UL << 21));
87
88    struct dma_req_setup setup = {
89        .done_cb = dma_done_cb,
90        .cb_arg = &test,
91        .args = {
92            .memcpy = {
93                .src = host_base,
94                .dst = card_base,
95                .bytes = size
96            }
97        }
98    };
99
100    memset(host_buf, 0xA5, size);
101
102    dma_completed = 0x0;
103    debug_printf("issuing first request. [%08x]-[%08x]\n", *((uint32_t *) host_buf), *((uint32_t *) card_buf));
104    err = dma_request_memcpy(dev, &setup, &id);
105    if (err_is_fail(err)) {
106        USER_PANIC_ERR(err, "could not exec the transfer");
107    }
108    debug_printf("request %016lx issued.\n", id);
109
110    while (!dma_completed) {
111        messages_wait_and_handle_next();
112    }
113
114    dma_completed = 0x0;
115
116    memset(card_buf, 0x5A, size);
117
118    setup.args.memcpy.src = card_base;
119    setup.args.memcpy.dst = host_base;
120    debug_printf("issuing second request. [%08x]-[%08x]\n", *((uint32_t *) host_buf), *((uint32_t *) card_buf));
121    err = dma_request_memcpy(dev, &setup, &id);
122    if (err_is_fail(err)) {
123        USER_PANIC_ERR(err, "could not exec the transfer");
124    }
125
126    debug_printf("request %016lx issued.\n", id);
127
128    while (!dma_completed) {
129        messages_wait_and_handle_next();
130    }
131
132    return SYS_ERR_OK;
133}
134#endif
135
136static void init_buffer_c0(void)
137{
138#ifdef XPHI_BENCH_CHAN_HOST
139    inbuf = host_buf + XPHI_BENCH_MSG_FRAME_SIZE;
140    outbuf = host_buf;
141    inbuf_rev = card_buf + XPHI_BENCH_MSG_FRAME_SIZE;;
142    outbuf_rev = card_buf;
143#endif
144
145#ifdef XPHI_BENCH_CHAN_CARD
146    inbuf = host_buf;
147    outbuf = host_buf + XPHI_BENCH_MSG_FRAME_SIZE;
148    inbuf_rev = card_buf;
149    outbuf_rev = card_buf + XPHI_BENCH_MSG_FRAME_SIZE;
150#endif
151
152#ifdef XPHI_BENCH_CHAN_DEFAULT
153    inbuf = host_buf;
154    outbuf = card_buf;
155    inbuf_rev = outbuf + XPHI_BENCH_MSG_FRAME_SIZE;
156    outbuf_rev = inbuf + XPHI_BENCH_MSG_FRAME_SIZE;
157#ifdef XPHI_BENCH_BUFFER_CARD
158    bufs.buf = card_buf + 2 * XPHI_BENCH_MSG_FRAME_SIZE;
159    bufs_rev.buf = host_buf + 2 * XPHI_BENCH_MSG_FRAME_SIZE;
160#else
161    bufs.buf = host_buf + 2 * XPHI_BENCH_MSG_FRAME_SIZE;
162    bufs_rev.buf = card_buf + 2 * XPHI_BENCH_MSG_FRAME_SIZE;
163#endif
164#endif
165}
166
167static errval_t alloc_local(void)
168{
169    errval_t err;
170
171    size_t frame_size = 0;
172
173    frame_size = XPHI_BENCH_FRAME_SIZE_CARD;
174
175    if (!frame_size) {
176        frame_size = 4096;
177    }
178
179    debug_printf("Allocating a frame of size: %lx\n", frame_size);
180
181    size_t alloced_size = 0;
182    err = frame_alloc(&card_frame, frame_size, &alloced_size);
183    assert(err_is_ok(err));
184    assert(alloced_size >= frame_size);
185
186    struct frame_identity id;
187    err = frame_identify(card_frame, &id);
188    assert(err_is_ok(err));
189    card_base = id.base;
190    card_frame_sz = alloced_size;
191
192    err = vspace_map_one_frame(&card_buf, alloced_size, card_frame, NULL, NULL);
193
194    return err;
195}
196
197static errval_t msg_open_cb(xphi_dom_id_t domain,
198                            uint64_t usrdata,
199                            struct capref msgframe,
200                            uint8_t type)
201{
202    errval_t err;
203
204    struct frame_identity id;
205    err = frame_identify(msgframe, &id);
206    if (err_is_fail(err)) {
207        USER_PANIC_ERR(err, "could not identify the frame");
208    }
209
210    debug_printf("msg_open_cb | Frame base: %016lx, size=%lx\n", id.base,
211                 id.bytes);
212
213    host_frame = msgframe;
214
215    host_base = id.base;
216
217    host_frame_sz = id.bytes;
218
219    err = vspace_map_one_frame(&host_buf, id.bytes, msgframe, NULL, NULL);
220    if (err_is_fail(err)) {
221        USER_PANIC_ERR(err, "Could not map the frame");
222    }
223
224    domainid = domain;
225
226    init_buffer_c0();
227
228    connected = 0x1;
229
230    return SYS_ERR_OK;
231}
232
233static struct xeon_phi_callbacks callbacks = {
234    .open = msg_open_cb
235};
236
237int main(int argc,
238         char **argv)
239{
240    errval_t err;
241
242    debug_printf("Xeon Phi Test started on the card.\n");
243
244    debug_printf("Msg Buf Size = %lx, Buf Frame Size = %lx\n",
245    XPHI_BENCH_MSG_FRAME_SIZE,
246                 XPHI_BENCH_BUF_FRAME_SIZE);
247
248    xeon_phi_client_set_callbacks(&callbacks);
249
250    err = alloc_local();
251    assert(err_is_ok(err));
252
253    xeon_phi_client_init(disp_xeon_phi_id());
254
255    while (!connected) {
256        messages_wait_and_handle_next();
257    }
258
259    char iface[30];
260    snprintf(iface, 30, "xeon_phi_test.%u", XPHI_BENCH_CORE_HOST);
261
262    err = xeon_phi_client_chan_open(0, domainid, 0, card_frame, 2);
263    if (err_is_fail(err)) {
264        USER_PANIC_ERR(err, "could not open channel");
265    }
266
267    debug_printf("Initializing UMP channel...\n");
268
269    err = ump_chan_init(&uc, inbuf,
270    XPHI_BENCH_MSG_FRAME_SIZE,
271                        outbuf,
272                        XPHI_BENCH_MSG_FRAME_SIZE);
273    err = ump_chan_init(&uc_rev, inbuf_rev,
274    XPHI_BENCH_MSG_FRAME_SIZE,
275                        outbuf_rev,
276                        XPHI_BENCH_MSG_FRAME_SIZE);
277
278#ifdef XPHI_BENCH_PROCESS_CARD
279    delay_ms(1000);
280#endif
281
282#ifdef XPHI_BENCH_PROCESS_CARD
283#ifndef XPHI_BENCH_THROUGHPUT
284    debug_printf("---------------- normal run -----------------\n");
285    xphi_bench_start_echo(&bufs, &uc);
286    debug_printf("---------------- reversed run -----------------\n");
287    xphi_bench_start_echo(&bufs_rev, &uc_rev);
288#else
289    debug_printf("---------------- normal run -----------------\n");
290    xphi_bench_start_processor(&bufs, &uc);
291    debug_printf("---------------- reversed run -----------------\n");
292    xphi_bench_start_processor(&bufs_rev, &uc_rev);
293#endif
294#else
295#ifndef XPHI_BENCH_THROUGHPUT
296    debug_printf("---------------- normal run -----------------\n");
297    xphi_bench_start_initator_rtt(&bufs, &uc);
298    debug_printf("---------------- reversed run -----------------\n");
299    xphi_bench_start_initator_rtt(&bufs_rev, &uc_rev);
300#else
301#ifdef XPHI_BENCH_SEND_SYNC
302    debug_printf("---------------- normal run -----------------\n");
303    xphi_bench_start_initator_sync(&bufs, &uc);
304    debug_printf("---------------- reversed run -----------------\n");
305    xphi_bench_start_initator_sync(&bufs-rev, &uc_rev);
306#else
307    debug_printf("---------------- normal run -----------------\n");
308    xphi_bench_start_initator_async(&bufs, &uc);
309    debug_printf("---------------- reversed run -----------------\n");
310    xphi_bench_start_initator_async(&bufs_rev, &uc_rev);
311#endif
312#endif
313#endif
314
315#ifndef XPHI_BENCH_PROCESS_CARD
316
317    err = dma_manager_wait_for_driver(DMA_DEV_TYPE_XEON_PHI, 0);
318    if (err_is_fail(err)) {
319        USER_PANIC_ERR(err, "waiting for drive");
320    }
321
322    struct dma_client_info info = {
323        .type = DMA_CLIENT_INFO_TYPE_NAME,
324        .device_type = DMA_DEV_TYPE_XEON_PHI,
325        .args = {
326            .name = XEON_PHI_DMA_SERVICE_NAME
327        }
328    };
329
330    struct dma_client_device *xdev;
331    err = dma_client_device_init(&info, &xdev);
332    if (err_is_fail(err)) {
333        USER_PANIC_ERR(err, "could not initialize client device");
334    }
335
336    struct dma_device *dev = (struct dma_device *)xdev;
337
338    err = dma_register_memory((struct dma_device *) dev, card_frame);
339    if (err_is_fail(err)) {
340        USER_PANIC_ERR(err, "could not register memory");
341    }
342
343    err = dma_register_memory((struct dma_device *) dev, host_frame);
344    if (err_is_fail(err)) {
345        USER_PANIC_ERR(err, "could not register memory");
346    }
347
348    debug_printf("+++++++ Verify DMA Functionality ++++++++\n");
349    dma_test(dev);
350
351    debug_printf("+++++++ DMA / MEMCOPY Benchmark ++++++++\n");
352
353    debug_printf("\n");
354    debug_printf("========================================\n");
355    debug_printf("\n");
356    debug_printf("MEMCPY-BENCH: CARD LOCAL \n");
357    debug_printf("\n");
358    debug_printf("========================================\n");
359    debug_printf("\n");
360
361    xphi_bench_memcpy((struct dma_device *) dev, card_buf + 2* XPHI_BENCH_MSG_FRAME_SIZE,
362                    card_buf + 2* XPHI_BENCH_MSG_FRAME_SIZE
363                    + (XPHI_BENCH_BUF_FRAME_SIZE / 2),
364                    XPHI_BENCH_BUF_FRAME_SIZE / 2,
365                    card_base + 2* XPHI_BENCH_MSG_FRAME_SIZE,
366                    card_base + 2* XPHI_BENCH_MSG_FRAME_SIZE
367                    + (XPHI_BENCH_BUF_FRAME_SIZE / 2));
368
369    debug_printf("\n");
370    debug_printf("========================================\n");
371    debug_printf("\n");
372    debug_printf("MEMCPY-BENCH: CARD -> HOST \n");
373    debug_printf("\n");
374    debug_printf("========================================\n");
375    debug_printf("\n");
376    xphi_bench_memcpy((struct dma_device *) dev,host_buf + 2* XPHI_BENCH_MSG_FRAME_SIZE,
377                    card_buf + 2* XPHI_BENCH_MSG_FRAME_SIZE,
378                    XPHI_BENCH_BUF_FRAME_SIZE / 2,
379                    host_base + 2* XPHI_BENCH_MSG_FRAME_SIZE,
380                    card_base + 2* XPHI_BENCH_MSG_FRAME_SIZE);
381    debug_printf("\n");
382
383    debug_printf("========================================\n");
384    debug_printf("\n");
385    debug_printf("MEMCPY-BENCH: HOST -> CARD \n");
386    debug_printf("\n");
387    debug_printf("========================================\n");
388    debug_printf("\n");
389
390    xphi_bench_memcpy((struct dma_device *) dev,card_buf + 2* XPHI_BENCH_MSG_FRAME_SIZE,
391                    host_buf + 2* XPHI_BENCH_MSG_FRAME_SIZE,
392                    XPHI_BENCH_BUF_FRAME_SIZE / 2,
393                    card_base + 2* XPHI_BENCH_MSG_FRAME_SIZE,
394                    host_base + 2* XPHI_BENCH_MSG_FRAME_SIZE);
395#endif
396}
397