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