1/** 2 * \file 3 * \brief Prototypes for use by flounder-generated stubs 4 */ 5 6/* 7 * Copyright (c) 2010, 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, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#ifndef __FLOUNDER_SUPPORT_UMP_H 16#define __FLOUNDER_SUPPORT_UMP_H 17 18#include <sys/cdefs.h> 19 20#include <barrelfish/ump_chan.h> 21#include <flounder/flounder_support_caps.h> 22#include <trace/trace.h> 23 24__BEGIN_DECLS 25 26/// Number of bits available for the message type in the header 27#define FL_UMP_MSGTYPE_BITS (UMP_HEADER_BITS - UMP_INDEX_BITS) 28 29/// Special message types 30enum flounder_ump_msgtype { 31 FL_UMP_BIND = 0, 32 FL_UMP_BIND_REPLY = 1, 33 FL_UMP_CAP_ACK = (1 << FL_UMP_MSGTYPE_BITS) - 1, 34}; 35 36struct flounder_ump_state { 37 struct ump_chan chan; 38 39 struct flounder_cap_state capst; ///< State for indirect cap tx/rx machinery 40 uint32_t token; ///< Outgoing message's token 41}; 42 43void flounder_stub_ump_state_init(struct flounder_ump_state *s, void *binding); 44 45errval_t flounder_stub_ump_send_string(struct flounder_ump_state *s, 46 int msgnum, const char *str, 47 size_t *pos, size_t *len); 48 49errval_t flounder_stub_ump_recv_string(volatile struct ump_message *msg, 50 char *str, size_t *pos, size_t *len, 51 size_t maxsize); 52 53errval_t flounder_stub_ump_send_buf(struct flounder_ump_state *s, 54 int msgnum, const void *buf, 55 size_t len, size_t *pos); 56 57errval_t flounder_stub_ump_recv_buf(volatile struct ump_message *msg, 58 void *buf, size_t *len, size_t *pos, 59 size_t maxsize); 60 61 62#define ENABLE_MESSAGE_PASSING_TRACE 1 63/// Prepare a "control" word (header for each UMP message fragment) 64static inline void flounder_stub_ump_control_fill(struct flounder_ump_state *s, 65 struct ump_control *ctrl, 66 int msgtype) 67{ 68#if ENABLE_MESSAGE_PASSING_TRACE 69 trace_event_raw((((uint64_t)0xEA)<<56) | 70 ((uint64_t)s->chan.sendid << 12)); 71#endif // ENABLE_MESSAGE_PASSING_TRACE 72 assert(s->chan.sendid != 0); 73 assert(msgtype < (1 << FL_UMP_MSGTYPE_BITS)); // check for overflow 74 ctrl->header = ((uintptr_t)msgtype << UMP_INDEX_BITS); 75 ctrl->token = s->token; 76} 77 78/// Process a "control" word 79static inline int flounder_stub_ump_control_process(struct flounder_ump_state *s, 80 struct ump_control ctrl) 81{ 82#if ENABLE_MESSAGE_PASSING_TRACE 83 trace_event_raw( (((uint64_t)0xEB)<<56) | 84 ((uint64_t)s->chan.recvid << 12)); 85#endif // ENABLE_MESSAGE_PASSING_TRACE 86 return ctrl.header >> UMP_INDEX_BITS; 87} 88 89/// Emit memory barrier needed between writing UMP payload and header 90static inline void flounder_stub_ump_barrier(void) 91{ 92#if defined(__i386__) || defined(__x86_64__) 93 /* the x86 memory model ensures ordering of stores, so all we need to do 94 * is prevent the compiler from reordering the instructions */ 95 __asm volatile ("" : : : "memory"); 96#else 97 /* use conservative GCC intrinsic */ 98 __sync_synchronize(); 99#endif 100} 101 102/// Send a cap ACK (message that we are ready to receive caps) 103static inline void flounder_stub_ump_send_cap_ack(struct flounder_ump_state *s) 104{ 105 struct ump_control ctrl; 106 volatile struct ump_message *msg = ump_chan_get_next(&s->chan, &ctrl); 107 assert(msg); 108 flounder_stub_ump_control_fill(s, &ctrl, FL_UMP_CAP_ACK); 109 msg->header.control = ctrl; 110} 111 112__END_DECLS 113 114#endif // __FLOUNDER_SUPPORT_UMP_H 115