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 <driverkit/iommu.h> 26 27#include <if/xomp_defs.h> 28 29 30#define HLINE debug_printf("========================================================\n"); 31#define hline debug_printf("--------------------------------------------------------\n"); 32#define PRINTF(x...) debug_printf("[HW Models] " x) 33#define TODO(x...) debug_printf("[HW Models] TODO: " x) 34 35#define DATA_SIZE (1UL << 30) 36#define MSG_CHANNEL_SIZE (1UL << 20) 37#define MSG_FRAME_SIZE (2 * MSG_CHANNEL_SIZE) 38 39static uint8_t finished = 0; 40 41static void do_work_rx(struct xomp_binding *_binding, uint64_t fn, uint64_t arg, 42 uint64_t tid, uint64_t flags) 43{ 44 errval_t err; 45 46 hline 47 PRINTF("Co-processor start doing work...\n"); 48 49 for(size_t i = 0; i < arg; i += sizeof(uint64_t)) { 50 uint64_t *p = (uint64_t *)(fn + i); 51 *p = *p + 1; 52 } 53 54 hline 55 PRINTF("Co-processor done doing work...\n"); 56 57 err = _binding->tx_vtbl.done_notify(_binding, NOP_CONT, 0, SYS_ERR_OK); 58 assert(err_is_ok(err)); 59} 60 61static void bind_cb(void *st, errval_t err, struct xomp_binding *_binding) 62{ 63 hline 64 PRINTF("Bind callback.\n"); 65 66 if (err_is_fail(err)) { 67 USER_PANIC_ERR(err, "failed to bind to host\n"); 68 } 69 70 _binding->rx_vtbl.do_work = do_work_rx; 71} 72 73static void message_passing_init(struct dmem *msgmem) 74{ 75 errval_t err; 76 77 hline 78 PRINTF("Initializing message passing\n"); 79 80 81 struct xomp_frameinfo fi = { 82 .sendbase = msgmem->devaddr + MSG_CHANNEL_SIZE, 83 .inbuf = (void *)(msgmem->vbase), 84 .inbufsize = MSG_CHANNEL_SIZE, 85 .outbuf = (void *)(msgmem->vbase + MSG_CHANNEL_SIZE), 86 .outbufsize = MSG_CHANNEL_SIZE, 87 }; 88 89 90 err = xomp_connect(&fi, bind_cb, NULL, get_default_waitset(), 91 IDC_BIND_FLAGS_DEFAULT); 92 if (err_is_fail(err)) { 93 USER_PANIC_ERR(err, "failed to connect"); 94 } 95 96} 97 98static errval_t msg_open_cb(xphi_dom_id_t domain, 99 uint64_t usrdata, 100 struct capref msgframe, 101 uint8_t type) 102{ 103 errval_t err; 104 105 hline 106 PRINTF("Co-processor handling msg_open_cb\n"); 107 108 struct frame_identity id; 109 err = frame_identify(msgframe, &id); 110 if (err_is_fail(err)) { 111 return err; 112 } 113 114 PRINTF("Obtained message cap: %lx..%lx\n", id.base, id.base + id.bytes - 1); 115 116 117 PRINTF("Mapping at address 0x%lx\n", usrdata); 118 119 err = vspace_map_one_frame_fixed(usrdata, id.bytes, msgframe, NULL, NULL); 120 if (err_is_fail(err)) { 121 DEBUG_ERR(err, "faield to map!"); 122 return err; 123 } 124 125 126 PRINTF("Setup successfull %s\n", err_getstring(err)); 127 128 return SYS_ERR_OK; 129} 130 131static struct xeon_phi_callbacks callbacks = { 132 .open = msg_open_cb 133}; 134 135 136int main(int argc, char **argv) 137{ 138 HLINE 139 PRINTF("Co-processor starts executing...\n"); 140 HLINE 141 142 /* set the connection */ 143 xeon_phi_client_init(disp_xeon_phi_id()); 144 145 /* set the callbacks */ 146 xeon_phi_client_set_callbacks(&callbacks); 147 148 /* */ 149 errval_t err; 150 151 struct cnoderef argcnref; 152 153 argcnref = build_cnoderef(cap_argcn, CNODE_TYPE_OTHER); 154 155 struct capref msgframe = { 156 .cnode = argcnref, 157 .slot = 0 158 }; 159 160 161 struct dmem dmem; 162 struct frame_identity id; 163 err = frame_identify(msgframe, &id); 164 if (err_is_fail(err)) { 165 USER_PANIC_ERR(err, "failed to invoke frame identify\n"); 166 } 167 168 PRINTF("Using messaging frame 0x%lx..0x%lx\n", id.base, id.base + id.bytes - 1); 169 170 171 172 dmem.devaddr = id.base; 173 dmem.mem = msgframe; 174 dmem.size = id.bytes; 175 176 err = vspace_map_one_frame((void **)&dmem.vbase, dmem.size, dmem.mem, NULL, NULL); 177 if (err_is_fail(err)) { 178 return err; 179 } 180 181 message_passing_init(&dmem); 182 183 PRINTF("Waiting for the commands...\n"); 184 185 while(!finished) { 186 messages_wait_and_handle_next(); 187 } 188 189 190 PRINTF("Co-processor terminated...\n"); 191} 192