1/*
2 * Copyright (c) 2014 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, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
8 */
9#include <stdio.h>
10#include <string.h>
11#include <stdlib.h>
12#include <limits.h>
13
14#include <barrelfish/barrelfish.h>
15#include <barrelfish/dispatch.h>
16#include <barrelfish/ump_chan.h>
17#include <bench/bench.h>
18#include <xeon_phi/xeon_phi.h>
19#include <xeon_phi/xeon_phi_client.h>
20
21#include "benchmark.h"
22#include "common.h"
23
24static void *local_buf;
25struct capref local_frame;
26static lpaddr_t local_base;
27static size_t local_frame_sz;
28
29static void *remote_buf;
30struct capref remote_frame;
31static lpaddr_t remote_base;
32static size_t remote_frame_sz;
33
34struct ump_chan xphi_uc;
35struct ump_chan xphi_uc_rev;
36
37static void *inbuf;
38static void *outbuf;
39
40static void *inbuf_rev;
41static void *outbuf_rev;
42
43xphi_dom_id_t domainid;
44
45volatile uint8_t connected = 0;
46
47static void init_buffer(void)
48{
49#ifdef __k1om__
50#if XPHI_BENCH_CHAN_SEPARATED
51    if (disp_xeon_phi_id()) {
52        debug_printf("buffer configuration: in=remote_buf; out=local_buf\n");
53        debug_printf("buffer configuration (reversed): in=local_buf; out=remote_buf\n");
54        inbuf = remote_buf;
55        outbuf = local_buf;
56        inbuf_rev = local_buf + XPHI_BENCH_MSG_CHAN_SIZE;
57        outbuf_rev = remote_buf + XPHI_BENCH_MSG_CHAN_SIZE;
58    } else {
59        debug_printf("buffer configuration: in=remote_buf; out=local_buf\n");
60        debug_printf("buffer configuration (reversed): in=local_buf; out=remote_buf\n");
61        inbuf = remote_buf;
62        outbuf = local_buf;
63        inbuf_rev = local_buf + XPHI_BENCH_MSG_CHAN_SIZE;
64        outbuf_rev = remote_buf + XPHI_BENCH_MSG_CHAN_SIZE;
65    }
66#else
67    if (disp_xeon_phi_id()) {
68        debug_printf("buffer configuration: in=local; out=local\n");
69        debug_printf("buffer configuration (reversed): in=remote; out=remote\n");
70        inbuf_rev = remote_buf;
71        outbuf_rev = remote_buf + XPHI_BENCH_MSG_CHAN_SIZE;
72        inbuf = local_buf;
73        outbuf = local_buf + XPHI_BENCH_MSG_CHAN_SIZE;
74    } else {
75        debug_printf("buffer configuration: in=remote; out=remote\n");
76        debug_printf("buffer configuration (reversed): in=local; out=local\n");
77        inbuf = remote_buf + XPHI_BENCH_MSG_CHAN_SIZE;
78        outbuf = remote_buf;
79        inbuf_rev = local_buf + XPHI_BENCH_MSG_CHAN_SIZE;
80        outbuf_rev = local_buf;
81    }
82#endif
83#else
84#if XPHI_BENCH_CHAN_SEPARATED
85    debug_printf("buffer configuration: in=remote; out=local\n");
86    debug_printf("buffer configuration (reversed): in=local; out=remote\n");
87    inbuf = remote_buf;
88    outbuf = local_buf;
89    inbuf_rev = local_buf + XPHI_BENCH_MSG_CHAN_SIZE;
90    outbuf_rev = remote_buf + XPHI_BENCH_MSG_CHAN_SIZE;
91#else
92    debug_printf("buffer configuration: in=remote; out=remote\n");
93    debug_printf("buffer configuration (reversed): in=local; out=local\n");
94    inbuf = remote_buf + XPHI_BENCH_MSG_CHAN_SIZE;
95    outbuf = remote_buf;
96    inbuf_rev = local_buf + XPHI_BENCH_MSG_CHAN_SIZE;
97    outbuf_rev = local_buf;
98#endif
99#endif
100}
101
102void wait_for_connection(void)
103{
104    while (!connected) {
105        messages_wait_and_handle_next();
106    }
107}
108
109void alloc_local(void)
110{
111    errval_t err;
112
113#ifndef __k1om__
114    uint64_t minbase, maxlimit;
115    ram_get_affinity(&minbase, &maxlimit);
116    ram_set_affinity(XPHI_BENCH_RAM_MINBASE, XPHI_BENCH_RAM_MAXLIMIT);
117#endif
118    size_t alloced_size = 0;
119    err = frame_alloc(&local_frame, XPHI_BENCH_MSG_FRAME_SIZE, &alloced_size);
120    EXPECT_SUCCESS(err, "frame_alloc");
121
122#ifndef __k1om__
123    ram_set_affinity(minbase, maxlimit);
124#endif
125
126    struct frame_identity id;
127    err = invoke_frame_identify(local_frame, &id);
128    EXPECT_SUCCESS(err, "invoke_frame_identify");
129
130    local_base = id.base;
131    local_frame_sz = alloced_size;
132
133    debug_printf("alloc_local | Frame base: %016lx, size=%lx\n", id.base,
134                 id.bytes);
135
136    err =  vspace_map_one_frame(&local_buf, alloced_size, local_frame, NULL, NULL);
137    EXPECT_SUCCESS(err, "vspace_map_one_frame");
138}
139
140static errval_t msg_open_cb(xphi_dom_id_t domain,
141                     uint64_t usrdata,
142                     struct capref msgframe,
143                     uint8_t type)
144{
145    errval_t err;
146
147    domainid = domain;
148
149    struct frame_identity id;
150    err = invoke_frame_identify(msgframe, &id);
151    EXPECT_SUCCESS(err, "frame identify");
152
153    debug_printf("msg_open_cb | Frame base: %016lx, size=%lx\n", id.base,
154                 id.bytes);
155
156    assert(id.bytes >= XPHI_BENCH_MSG_FRAME_SIZE);
157
158    err = vspace_map_one_frame(&remote_buf, XPHI_BENCH_MSG_FRAME_SIZE, msgframe,
159                               NULL, NULL);
160    EXPECT_SUCCESS(err, "vspace map frame");
161
162    remote_frame = msgframe;
163    remote_base = id.base;
164    remote_frame_sz = id.bytes;
165
166    init_buffer();
167
168    connected = 0x1;
169
170    debug_printf("Initializing UMP channel...\n");
171
172    err = ump_chan_init(&xphi_uc, inbuf, XPHI_BENCH_MSG_CHAN_SIZE, outbuf,
173                        XPHI_BENCH_MSG_CHAN_SIZE);
174    EXPECT_SUCCESS(err, "initialize ump channel");
175
176    err = ump_chan_init(&xphi_uc_rev, inbuf_rev, XPHI_BENCH_MSG_CHAN_SIZE, outbuf_rev,
177                        XPHI_BENCH_MSG_CHAN_SIZE);
178    EXPECT_SUCCESS(err, "initialize ump channel");
179
180    return SYS_ERR_OK;
181}
182
183struct xeon_phi_callbacks callbacks = {
184    .open = msg_open_cb
185};
186