1/** 2 * \file 3 * \brief Driver for booting the Xeon Phi Coprocessor card on a Barrelfish Host 4 */ 5 6/* 7 * Copyright (c) 2014 ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <stdio.h> 16#include <string.h> 17#include <barrelfish/barrelfish.h> 18 19#include <if/octopus_defs.h> 20#include <if/octopus_thc.h> 21 22#include <octopus/octopus.h> 23#include <octopus/trigger.h> 24 25#include "xeon_phi_internal.h" 26#include "domain.h" 27#include "interphi.h" 28 29struct wait_state 30{ 31 void *usr_state; 32 struct xnode *node; 33 octopus_trigger_id_t tid; 34}; 35 36static void domain_wait_trigger_handler(octopus_mode_t mode, 37 const char* record, 38 void* state) 39{ 40 errval_t err; 41 42 struct wait_state *ws = state; 43 44 oct_remove_trigger(ws->tid); 45 46 xphi_dom_id_t domid = 0; 47 err = oct_read(record, "_ { domid: %d }", &domid); 48 if (err_is_fail(err) || domid == 0) { 49 err = err_push(err, XEON_PHI_ERR_CLIENT_DOMAIN_VOID); 50 } 51 52 interphi_domain_wait_reply(ws->node, err, ws->usr_state, domid); 53 54 free(state); 55} 56 57/** 58 * \brief Non-blocking name service lookup 59 * 60 * \param iface Name of the domain 61 * \param retdomid returns the Xeon Phi Domain ID 62 */ 63errval_t domain_lookup(const char *iface, 64 xphi_dom_id_t *retdomid) 65{ 66 errval_t err; 67 68 struct octopus_binding *r = get_octopus_binding(); 69 if (r == NULL) { 70 return LIB_ERR_NAMESERVICE_NOT_BOUND; 71 } 72 73 struct octopus_get_response__rx_args reply; 74 err = r->rpc_tx_vtbl.get(r, iface, NOP_TRIGGER, reply.output, &reply.tid, 75 &reply.error_code); 76 if (err_is_fail(err)) { 77 goto out; 78 } 79 err = reply.error_code; 80 if (err_is_fail(err)) { 81 if (err_no(err) == OCT_ERR_NO_RECORD) { 82 err = err_push(err, XEON_PHI_ERR_CLIENT_DOMAIN_VOID); 83 } 84 goto out; 85 } 86 87 xphi_dom_id_t domid = 0; 88 err = oct_read(reply.output, "_ { domid: %d }", &domid); 89 if (err_is_fail(err) || domid == 0) { 90 err = err_push(err, XEON_PHI_ERR_CLIENT_DOMAIN_VOID); 91 goto out; 92 } 93 94 if (retdomid != NULL) { 95 *retdomid = domid; 96 } 97 98 out: 99 return err; 100} 101 102/** 103 * \brief looks up the name and registers a callback 104 * 105 * \param iface Name of the domain 106 * \param retdomid returns the Xeon Phi Domain ID 107 */ 108errval_t domain_wait(const char *iface, 109 struct xnode *node, 110 void *state, 111 xphi_dom_id_t *retdom) 112{ 113 errval_t err; 114 115 struct octopus_thc_client_binding_t* c = oct_get_thc_client(); 116 if (c == NULL) { 117 return LIB_ERR_NAMESERVICE_NOT_BOUND; 118 } 119 120 struct wait_state *ws = malloc(sizeof(*ws)); 121 if (ws == NULL) { 122 return LIB_ERR_MALLOC_FAIL; 123 } 124 125 ws->usr_state = state; 126 ws->node = node; 127 128 octopus_mode_t m = OCT_ON_SET; 129 octopus_trigger_t iface_set_trigger = oct_mktrigger( 130 OCT_ERR_NO_RECORD, octopus_BINDING_EVENT, m, 131 domain_wait_trigger_handler, ws); 132 133 struct octopus_get_response__rx_args reply; 134 135 assert(!"FIXME"); 136 err = c->call_seq.get(c, iface, iface_set_trigger, NULL, &ws->tid, 137 &reply.error_code); 138 139 if (err_is_fail(err)) { 140 return err; 141 } 142 143 if (err_is_fail(reply.error_code)) { 144 return reply.error_code; 145 } 146 147 free(ws); 148 149 xphi_dom_id_t domid = 0; 150 err = oct_read(reply.output, "_ { domid: %d }", &domid); 151 if (err_is_fail(err) || domid == 0) { 152 err = err_push(err, XEON_PHI_ERR_CLIENT_DOMAIN_VOID); 153 return err; 154 } 155 156 if (retdom) { 157 *retdom = domid; 158 } 159 160 return err; 161} 162 163/** 164 * \brief Register with name service 165 * 166 * \param iface Name of the domain 167 * \param retdomid returns the Xeon Phi Domain ID 168 */ 169errval_t domain_register(const char *iface, 170 xphi_dom_id_t domid) 171{ 172 errval_t err = SYS_ERR_OK; 173 174 struct octopus_binding *r = get_octopus_binding(); 175 if (r == NULL) { 176 return LIB_ERR_NAMESERVICE_NOT_BOUND; 177 } 178 179 // Format record 180 static const char* format = "%s { domid: %"PRIu64" }"; 181 size_t len = snprintf(NULL, 0, format, iface, domid); 182 char* record = malloc(len + 1); 183 if (record == NULL) { 184 return LIB_ERR_MALLOC_FAIL; 185 } 186 snprintf(record, len + 1, format, iface, domid); 187 188 octopus_trigger_id_t tid; 189 errval_t error_code; 190 err = r->rpc_tx_vtbl.set(r, record, 0, NOP_TRIGGER, 0, NULL, &tid, &error_code); 191 if (err_is_fail(err)) { 192 goto out; 193 } 194 err = error_code; 195 196 out: free(record); 197 198 return err; 199} 200