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 <if/xeon_phi_manager_defs.h> 14 15#include "service.h" 16#include "cardmanager.h" 17 18#define XEON_PHI_MANAGER_SERVICE_NAME "xeon_phi_manager" 19 20#ifdef XEON_PHI_DEBUG_MANAGER 21#define DEBUG_SVC(x...) debug_printf(" svc | " x) 22#else 23#define DEBUG_SVC(x...) 24#endif 25 26#define PRINTF_SVC(x...) debug_printf(" svc | " x) 27 28 29/// enumeration of possible service state 30enum xpm_svc_state 31{ 32 XPM_SVC_STATE_INVALID = 0, 33 XPM_SVC_STATE_EXPORTING, 34 XPM_SVC_STATE_EXPORT_OK, 35 XPM_SVC_STATE_EXPORT_FAIL, 36 XPM_SVC_STATE_NS_REGISTERING, 37 XPM_SVC_STATE_NS_REGISTER_OK, 38 XPM_SVC_STATE_NS_REGISTER_FAIL, 39 XPM_SVC_STATE_RUNNING 40}; 41 42/// service state 43static enum xpm_svc_state svc_state = XPM_SVC_STATE_INVALID; 44 45/// our exported iref 46static iref_t manager_iref; 47 48/** 49 * -------------------------------------------------------------------------- 50 * Registration protocol 51 */ 52 53struct reg_data 54{ 55 errval_t err; 56 uint8_t id; 57 xeon_phi_manager_cards_t irefs; 58 struct xeon_phi_manager_binding *b; 59}; 60 61struct reg_data reg_data_fail = { 62 // TODO: ERROR CODE 63 .err = -1 64}; 65 66static void register_response_sent_cb(void *a) 67{ 68 if (a != ®_data_fail) { 69 free(a); 70 } 71} 72 73static void register_response_send(void *a) 74{ 75 errval_t err; 76 77 struct reg_data *rd = a; 78 79 DEBUG_SVC("Registration response: id=%u, #irefs=%u\n", rd->id, rd->irefs.num); 80 81 struct event_closure txcont = MKCONT(register_response_sent_cb, a); 82 83 err = xeon_phi_manager_register_driver_response__tx(rd->b, 84 txcont, 85 rd->id, 86 rd->irefs, 87 rd->err); 88 if (err_is_fail(err)) { 89 if (err_no(err) == FLOUNDER_ERR_TX_BUSY) { 90 txcont = MKCONT(register_response_send, a); 91 err = rd->b->register_send(rd->b, get_default_waitset(), txcont); 92 if (err_is_fail(err)) { 93 USER_PANIC_ERR(err, "register_send on binding failed!"); 94 } 95 } 96 } 97} 98 99static void register_call_recv(struct xeon_phi_manager_binding *_binding, 100 iref_t svc) 101{ 102 PRINTF_SVC("New registration request: iref=%u\n", svc); 103 104 struct reg_data *reply = malloc(sizeof(struct reg_data)); 105 if (!reply) { 106 reg_data_fail.err = LIB_ERR_MALLOC_FAIL; 107 reg_data_fail.b = _binding; 108 register_response_send(®_data_fail); 109 return; 110 } 111 reply->b = _binding; 112 reply->err = cm_new_xeon_phi(_binding, svc, &reply->id); 113 if (err_is_fail(reply->err)) { 114 register_response_send(reply); 115 return; 116 } 117 118 reply->err = cm_get_irefs(&reply->irefs.card0, &reply->irefs.num); 119 120 register_response_send(reply); 121} 122 123static struct xeon_phi_manager_rx_vtbl xpm_rx_vtbl = { 124 .register_driver_call = register_call_recv 125}; 126 127/* 128 * -------------------------------------------------------------------------- 129 * Export and Connect functions 130 */ 131 132static errval_t svc_connect_cb(void *st, 133 struct xeon_phi_manager_binding *b) 134{ 135 DEBUG_SVC("New connection from a Xeon Phi Driver\n"); 136 137 b->rx_vtbl = xpm_rx_vtbl; 138 139 return SYS_ERR_OK; 140} 141 142/** 143 * \brief 144 */ 145static void svc_export_cb(void *st, 146 errval_t err, 147 iref_t iref) 148{ 149 if (err_is_fail(err)) { 150 svc_state = XPM_SVC_STATE_EXPORT_FAIL; 151 return; 152 } 153 154 manager_iref = iref; 155 svc_state = XPM_SVC_STATE_NS_REGISTERING; 156 157 DEBUG_SVC("registering "XEON_PHI_MANAGER_SERVICE_NAME" with iref:%u\n", iref); 158 159 err = nameservice_register(XEON_PHI_MANAGER_SERVICE_NAME, iref); 160 if (err_is_fail(err)) { 161 svc_state = XPM_SVC_STATE_NS_REGISTER_FAIL; 162 } 163 svc_state = XPM_SVC_STATE_NS_REGISTER_OK; 164} 165 166/** 167 * \brief starts Xeon Phi manager service 168 * 169 * \returns SYS_ERR_OK on success 170 * errval on failure 171 * 172 * NOTE: this function should not return. 173 */ 174errval_t service_start(void) 175{ 176 errval_t err; 177 178 DEBUG_SVC("starting service {"XEON_PHI_MANAGER_SERVICE_NAME"}\n"); 179 180 err = xeon_phi_manager_export(NULL, 181 svc_export_cb, 182 svc_connect_cb, 183 get_default_waitset(), 184 IDC_EXPORT_FLAGS_DEFAULT); 185 if (err_is_fail(err)) { 186 return err; 187 } 188 189 while (svc_state == XPM_SVC_STATE_EXPORTING || svc_state 190 == XPM_SVC_STATE_NS_REGISTERING) { 191 messages_wait_and_handle_next(); 192 } 193 194 if (svc_state == XPM_SVC_STATE_EXPORT_FAIL) { 195 return FLOUNDER_ERR_BIND; 196 } else if (svc_state == XPM_SVC_STATE_NS_REGISTER_FAIL) { 197 return LIB_ERR_NAMESERVICE_CLIENT_INIT; 198 } 199 200 svc_state = XPM_SVC_STATE_RUNNING; 201 202 PRINTF_SVC("Xeon Phi Manager service up and running.\n"); 203 204 messages_handler_loop(); 205 206 USER_PANIC("Xeon Phi Manager service terminated!\n"); 207 208 return SYS_ERR_OK; 209} 210