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#include <xeon_phi/xeon_phi_domain.h> 26 27uint32_t send_reply = 0x0; 28 29#include "benchmark.h" 30 31uint8_t connected = 0; 32 33static void *local_buf; 34static struct capref local_frame; 35static lpaddr_t local_base; 36static size_t local_frame_sz; 37 38static void *remote_buf; 39static struct capref remote_frame; 40static lpaddr_t remote_base; 41static size_t remote_frame_sz; 42 43static struct ump_chan uc; 44static struct ump_chan uc_rev; 45 46static void *inbuf; 47static void *outbuf; 48 49static void *inbuf_rev; 50static void *outbuf_rev; 51 52static struct bench_bufs bufs; 53static struct bench_bufs bufs_rev; 54 55static xphi_dom_id_t domid; 56 57static void init_buffer_c0(void) 58{ 59#ifdef XPHI_BENCH_CHAN_HOST 60 inbuf = local_buf + XPHI_BENCH_MSG_FRAME_SIZE; 61 outbuf = local_buf; 62 inbuf_rev = remote_buf + XPHI_BENCH_MSG_FRAME_SIZE;; 63 outbuf_rev = remote_buf; 64#endif 65 66#ifdef XPHI_BENCH_CHAN_CARD 67 inbuf = remote_buf; 68 outbuf = remote_buf + XPHI_BENCH_MSG_FRAME_SIZE; 69 inbuf_rev = local_buf; 70 outbuf_rev = local_buf + XPHI_BENCH_MSG_FRAME_SIZE; 71#endif 72 73#ifdef XPHI_BENCH_CHAN_DEFAULT 74 inbuf = remote_buf; 75 outbuf = local_buf; 76 inbuf_rev = outbuf + XPHI_BENCH_MSG_FRAME_SIZE; 77 outbuf_rev = inbuf + XPHI_BENCH_MSG_FRAME_SIZE; 78#endif 79 80#ifdef XPHI_BENCH_BUFFER_CARD 81 bufs.buf = remote_buf + 2 * XPHI_BENCH_MSG_FRAME_SIZE; 82 bufs_rev.buf = local_buf + 2 * XPHI_BENCH_MSG_FRAME_SIZE; 83#else 84 bufs.buf = local_buf + 2 * XPHI_BENCH_MSG_FRAME_SIZE; 85 bufs_rev.buf = remote_buf + 2 * XPHI_BENCH_MSG_FRAME_SIZE; 86#endif 87} 88 89static errval_t alloc_local(void) 90{ 91 errval_t err; 92 93 size_t frame_size = 0; 94 if (disp_xeon_phi_id() == 0) { 95 frame_size = XPHI_BENCH_FRAME_SIZE_HOST; 96 } else { 97 frame_size = XPHI_BENCH_FRAME_SIZE_CARD; 98 } 99 100 if (!frame_size) { 101 frame_size = 4096; 102 } 103 104 debug_printf("Allocating a frame of size: %lx\n", frame_size); 105 106 size_t alloced_size = 0; 107 err = frame_alloc(&local_frame, frame_size, &alloced_size); 108 assert(err_is_ok(err)); 109 assert(alloced_size >= frame_size); 110 111 struct frame_identity id; 112 err = frame_identify(local_frame, &id); 113 assert(err_is_ok(err)); 114 local_base = id.base; 115 local_frame_sz = alloced_size; 116 117 err = vspace_map_one_frame(&local_buf, alloced_size, local_frame, NULL, NULL); 118 119 return err; 120} 121 122static errval_t msg_open_cb(xphi_dom_id_t domain, 123 uint64_t usrdata, 124 struct capref msgframe, 125 uint8_t type) 126{ 127 errval_t err; 128 129 domid = domain; 130 131 struct frame_identity id; 132 err = frame_identify(msgframe, &id); 133 if (err_is_fail(err)) { 134 USER_PANIC_ERR(err, "could not identify the frame"); 135 } 136 137 debug_printf("msg_open_cb | Frame base: %016lx, size=%lx, ud:%lx\n", id.base, 138 id.bytes, usrdata); 139 140 remote_frame = msgframe; 141 142 remote_base = id.base; 143 144 remote_frame_sz = id.bytes; 145 146 err = vspace_map_one_frame(&remote_buf, remote_frame_sz, msgframe, 147 NULL, 148 NULL); 149 if (err_is_fail(err)) { 150 USER_PANIC_ERR(err, "Could not map the frame"); 151 } 152 153 init_buffer_c0(); 154 155 connected = 0x1; 156 157 return SYS_ERR_OK; 158} 159 160static struct xeon_phi_callbacks callbacks = { 161 .open = msg_open_cb 162}; 163 164int main(int argc, 165 char **argv) 166{ 167 errval_t err; 168 169 debug_printf("Xeon Phi Test started on the card %u.\n", disp_xeon_phi_id()); 170 171 debug_printf("Msg Buf Size = %lx, Buf Frame Size = %lx\n", 172 XPHI_BENCH_MSG_FRAME_SIZE, 173 XPHI_BENCH_BUF_FRAME_SIZE); 174 175 xeon_phi_client_set_callbacks(&callbacks); 176 177 err = xeon_phi_client_init(disp_xeon_phi_id()); 178 if (err_is_fail(err)) { 179 USER_PANIC_ERR(err, "could not init the service\n"); 180 } 181 182 err = alloc_local(); 183 assert(err_is_ok(err)); 184 185 if (disp_xeon_phi_id() == 0) { 186 char *iface = xeon_phi_domain_build_iface("xeon_phi_inter", 1, 2); 187 err = xeon_phi_domain_blocking_lookup(iface, &domid); 188 if (err_is_fail(err)) { 189 USER_PANIC_ERR(err, "looking up domain id\n"); 190 } 191 debug_printf("sending open message to %s on node 1\n", iface); 192 err = xeon_phi_client_chan_open(1, domid, 0xcafebabe, local_frame, 2); 193 if (err_is_fail(err)) { 194 USER_PANIC_ERR(err, "could not open channel"); 195 } 196 } 197 198 while (!connected) { 199 messages_wait_and_handle_next(); 200 } 201 202 debug_printf("Initializing UMP channel...\n"); 203 204 if (disp_xeon_phi_id() != 0) { 205 err = xeon_phi_client_chan_open(0, domid, 0xdeadbeef, local_frame, 2); 206 if (err_is_fail(err)) { 207 USER_PANIC_ERR(err, "could not open channel"); 208 } 209 } else { 210 debug_printf("Other node reply: %s\n", (char *) local_buf); 211 } 212 213 err = ump_chan_init(&uc, inbuf, 214 XPHI_BENCH_MSG_FRAME_SIZE, 215 outbuf, 216 XPHI_BENCH_MSG_FRAME_SIZE); 217 err = ump_chan_init(&uc_rev, inbuf_rev, 218 XPHI_BENCH_MSG_FRAME_SIZE, 219 outbuf_rev, 220 XPHI_BENCH_MSG_FRAME_SIZE); 221 222 if (err_is_fail(err)) { 223 USER_PANIC_ERR(err, "Could not initialize UMP"); 224 } 225 226 if (disp_xeon_phi_id() == 1) { 227#ifndef XPHI_BENCH_THROUGHPUT 228 debug_printf("---------------- normal run -----------------\n"); 229 xphi_bench_start_initator_rtt(&bufs, &uc); 230 debug_printf("---------------- reversed run -----------------\n"); 231 xphi_bench_start_initator_rtt(&bufs_rev, &uc_rev); 232#else 233#ifdef XPHI_BENCH_SEND_SYNC 234 debug_printf("---------------- normal run -----------------\n"); 235 xphi_bench_start_initator_sync(&bufs, &uc); 236 debug_printf("---------------- reversed run -----------------\n"); 237 xphi_bench_start_initator_sync(&bufs_rev, &uc_rev); 238#else 239 debug_printf("---------------- normal run -----------------\n"); 240 xphi_bench_start_initator_async(&bufs, &uc); 241 debug_printf("---------------- reversed run -----------------\n"); 242 xphi_bench_start_initator_async(&bufs_rev, &uc_rev); 243#endif 244#endif 245 } else { 246#ifndef XPHI_BENCH_THROUGHPUT 247 debug_printf("---------------- normal run -----------------\n"); 248 xphi_bench_start_echo(&bufs, &uc); 249 debug_printf("---------------- reversed run -----------------\n"); 250 xphi_bench_start_echo(&bufs_rev, &uc_rev); 251#else 252 debug_printf("---------------- normal run -----------------\n"); 253 xphi_bench_start_processor(&bufs, &uc); 254 debug_printf("---------------- reversed run -----------------\n"); 255 xphi_bench_start_processor(&bufs_rev, &uc_rev); 256#endif 257 } 258 259 err = dma_manager_wait_for_driver(DMA_DEV_TYPE_XEON_PHI, disp_xeon_phi_id()); 260 if (err_is_fail(err)) { 261 USER_PANIC_ERR(err, "waiting for drive"); 262 } 263 264 struct dma_client_info info = { 265 .type = DMA_CLIENT_INFO_TYPE_NAME, 266 .device_type = DMA_DEV_TYPE_XEON_PHI, 267 .args = { 268 .name = XEON_PHI_DMA_SERVICE_NAME 269 } 270 }; 271 272 struct dma_client_device *xdev; 273 err = dma_client_device_init(&info, &xdev); 274 if (err_is_fail(err)) { 275 USER_PANIC_ERR(err, "could not initialize client device"); 276 } 277 278 struct dma_device *dev = (struct dma_device *) xdev; 279 280 err = dma_register_memory((struct dma_device *) dev, local_frame); 281 if (err_is_fail(err)) { 282 USER_PANIC_ERR(err, "could not register memory"); 283 } 284 285 err = dma_register_memory((struct dma_device *) dev, remote_frame); 286 if (err_is_fail(err)) { 287 USER_PANIC_ERR(err, "could not register memory"); 288 } 289 290 if (disp_xeon_phi_id() == 1) { 291 debug_printf("+++++++ DMA / MEMCOPY Benchmark ++++++++\n"); 292 293 debug_printf("\n"); 294 debug_printf("========================================\n"); 295 debug_printf("\n"); 296 debug_printf("DMA-BENCH: LOCAL -> REMOTE \n"); 297 debug_printf("\n"); 298 debug_printf("========================================\n"); 299 debug_printf("\n"); 300 xphi_bench_memcpy(dev, remote_buf + 2 * XPHI_BENCH_MSG_FRAME_SIZE, 301 local_buf + 2 * XPHI_BENCH_MSG_FRAME_SIZE, 302 XPHI_BENCH_BUF_FRAME_SIZE / 2, 303 remote_base + 2 * XPHI_BENCH_MSG_FRAME_SIZE, 304 local_base + 2 * XPHI_BENCH_MSG_FRAME_SIZE); 305 306 debug_printf("\n"); 307 debug_printf("========================================\n"); 308 debug_printf("\n"); 309 debug_printf("DMA-BENCH: REMOTE -> LOCAL \n"); 310 debug_printf("\n"); 311 debug_printf("========================================\n"); 312 debug_printf("\n"); 313 xphi_bench_memcpy(dev, local_buf + 2 * XPHI_BENCH_MSG_FRAME_SIZE, 314 remote_buf + 2 * XPHI_BENCH_MSG_FRAME_SIZE, 315 XPHI_BENCH_BUF_FRAME_SIZE / 2, 316 local_base + 2 * XPHI_BENCH_MSG_FRAME_SIZE, 317 remote_base + 2 * XPHI_BENCH_MSG_FRAME_SIZE); 318 } 319 320 debug_printf("benchmark done."); 321 322 while (1) { 323 messages_wait_and_handle_next(); 324 } 325} 326