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 10#include <barrelfish/barrelfish.h> 11#include <barrelfish/nameservice_client.h> 12 13#include <xeon_phi/xeon_phi.h> 14#include <xeon_phi/xeon_phi_manager_client.h> 15 16#include <if/xeon_phi_manager_defs.h> 17#include <if/xeon_phi_manager_defs.h> 18 19/// the name of the Xeon Phi Manager service 20#define XEON_PHI_MANAGER_SERVICE_NAME "xeon_phi_manager" 21 22/// Enabling the debug output of the Xeon Phi Manager client 23#ifdef XEON_PHI_DEBUG_MANAGER 24#define DEBUG_XPMC(x...) debug_printf(" [xpmc] " x) 25#else 26#define DEBUG_XPMC(x...) 27#endif 28 29/** 30 * represents the connection state of the Xeon Phi Manager client with the 31 * Xeon Phi Manager 32 */ 33enum xpm_state 34{ 35 XPM_STATE_INVALID = 0, 36 XPM_STATE_NSLOOKUP, 37 XPM_STATE_BINDING, 38 XPM_STATE_BIND_OK, 39 XPM_STATE_BIND_FAIL, 40 XPM_STATE_REGISTERING, 41 XPM_STATE_REGISTER_OK, 42 XPM_STATE_REGISTER_FAIL, 43 XPM_STATE_CONNECTED 44}; 45 46/// iref of the Xeon Phi manager service 47static iref_t xpm_iref = 0; 48 49/// Flounder binind go the Xeon Phi manager 50static struct xeon_phi_manager_binding *xpm_binding = NULL; 51 52/// connection state 53static enum xpm_state conn_state = XPM_STATE_INVALID; 54 55/* 56 * -------------------------------------------------------------------------- 57 * Registration Protocol 58 * ---------------------------------------------------------------------------- 59 */ 60 61/** 62 * contains the necessary data for the Xeon Phi manager connection 63 */ 64struct xpm_register_data 65{ 66 iref_t svc_iref; ///< our exported service iref 67 errval_t err; ///< error code of the registration 68 uint8_t id; ///< our own Xeon Phi ID. 69 xeon_phi_manager_cards_t irefs; ///< irefs to the other Xeon Phi drivers 70} xpm_reg_data; 71 72/* 73 * ---------------------------------------------------------------------------- 74 * Xeon Phi Manager binding functions 75 * ---------------------------------------------------------------------------- 76 */ 77 78/** 79 * \brief Flounder bind callback 80 * 81 * \param st state associated with the binding 82 * \param err error code of the binding attempt 83 * \param binding Xeon Phi Manager Flounder binding 84 */ 85static void xpm_bind_cb(void *st, 86 errval_t err, 87 struct xeon_phi_manager_binding *binding) 88{ 89 90 if (err_is_fail(err)) { 91 conn_state = XPM_STATE_BIND_FAIL; 92 xpm_reg_data.err = err; 93 return; 94 } 95 96 xpm_binding = binding; 97 98 conn_state = XPM_STATE_BIND_OK; 99 100 xeon_phi_manager_rpc_client_init(xpm_binding); 101 102 DEBUG_XPMC("binding to "XEON_PHI_MANAGER_SERVICE_NAME" succeeded\n"); 103} 104 105/** 106 * \brief binds to the Xeon Phi Manager service 107 * 108 * \returns SYS_ERR_OK on success 109 * FLOUNDER_ERR_* on failure 110 */ 111static errval_t xpm_bind(void) 112{ 113 errval_t err; 114 115 if (xpm_binding != NULL) { 116 return SYS_ERR_OK; 117 } 118 119 assert(conn_state == XPM_STATE_INVALID); 120 121 conn_state = XPM_STATE_NSLOOKUP; 122 123 DEBUG_XPMC("nameservice lookup: "XEON_PHI_MANAGER_SERVICE_NAME"\n"); 124 125 err = nameservice_blocking_lookup(XEON_PHI_MANAGER_SERVICE_NAME, &xpm_iref); 126 if (err_is_fail(err)) { 127 return err; 128 } 129 130 conn_state = XPM_STATE_BINDING; 131 132 DEBUG_XPMC("binding: "XEON_PHI_MANAGER_SERVICE_NAME" @ iref:%u\n", xpm_iref); 133 134 err = xeon_phi_manager_bind(xpm_iref, xpm_bind_cb, NULL, get_default_waitset(), 135 IDC_BIND_FLAGS_DEFAULT); 136 if (err_is_fail(err)) { 137 return err; 138 } 139 140 while (conn_state == XPM_STATE_BINDING) { 141 messages_wait_and_handle_next(); 142 } 143 144 if (conn_state == XPM_STATE_BIND_FAIL) { 145 return FLOUNDER_ERR_BIND; 146 } 147 148 return SYS_ERR_OK; 149} 150 151/* 152 * ---------------------------------------------------------------------------- 153 * Public Interface 154 * ---------------------------------------------------------------------------- 155 */ 156 157/** 158 * \brief registers the Xeon Phi driver card with the Xeon Phi Manager 159 * 160 * \param svc_iref iref of the own exported Xeon Phi driver interface 161 * \param id returns the assigned Xeon Phi card ID 162 * \param num returns the size of the cards array 163 * \param irefs returns array of irefs to the other cards 164 * 165 * NOTE: this is a blocking function. The function will only return after 166 * the Xeon Phi manager connection has been fully established and the 167 * registration protocol has been executed. 168 * 169 * \returns SYS_ERR_OK on success 170 * errval on failure 171 */ 172errval_t xeon_phi_manager_client_register(iref_t svc_iref, 173 uint8_t *id, 174 uint8_t *num, 175 iref_t **irefs) 176{ 177 errval_t err, msgerr; 178 179 if (strcmp(disp_name(), "xeon_phi") != 0) { 180 USER_PANIC("client register called on non xeon phi driver"); 181 return -1; 182 } 183 184 if (conn_state >= XPM_STATE_REGISTER_OK) { 185 return SYS_ERR_OK; 186 } 187 188 DEBUG_XPMC("Registration with Xeon Phi Manager service.\n"); 189 190 err = xpm_bind(); 191 if (err_is_fail(err)) { 192 return err; 193 } 194 195 xpm_reg_data.svc_iref = svc_iref; 196 197 xeon_phi_manager_cards_t cards; 198 199 err = xpm_binding->rpc_tx_vtbl.register_driver(xpm_binding, svc_iref, id, 200 &cards, &msgerr); 201 if (err_is_fail(err)) { 202 return err; 203 } 204 205 if (err_is_fail(msgerr)) { 206 return msgerr; 207 } 208 conn_state = XPM_STATE_REGISTER_OK; 209 210 iref_t *cardiref =calloc(cards.num, sizeof(iref_t)); 211 assert(cardiref); 212 for(uint32_t i = 0; i < cards.num; ++i) { 213 cardiref[i] = ((iref_t *)&cards.card0)[i]; 214 } 215 *irefs = cardiref; 216 *num = cards.num; 217 218 return SYS_ERR_OK; 219} 220 221/** 222 * \brief deregisters the Xeon Phi driver with the Xeon Phi Manager 223 * 224 * \return SYS_ERR_OK on success 225 */ 226errval_t xeon_phi_manager_client_deregister(void) 227{ 228 assert(!"NYI"); 229 return SYS_ERR_OK; 230} 231 232/** 233 * \brief looks up the iref of a Xeon Phi with the given id 234 * 235 * \param xid Xeon Phi ID 236 * \param svc_iref the returned svc_iref of the xeon phi 237 * 238 * \returns SYS_ERR_OK on success 239 */ 240errval_t xeon_phi_manager_lookup(xphi_id_t xid, 241 iref_t *svc_iref) 242{ 243 errval_t err, msgerr; 244 245 DEBUG_XPMC("Registration with Xeon Phi Manager service.\n"); 246 247 err = xpm_bind(); 248 if (err_is_fail(err)) { 249 return err; 250 } 251 252 err = xpm_binding->rpc_tx_vtbl.lookup(xpm_binding, xid, svc_iref, &msgerr); 253 if (err_is_fail(err)) { 254 return err; 255 } 256 257 return msgerr; 258} 259