1 /* 2 * Copyright (c) 2015-2016 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 /* 29 * File: kern/mach_node_link.h 30 * Author: Dean Reece 31 * Date: 2016 32 * 33 * This header provides definitions required by Mach Node Link (MNL) drivers. 34 * MNL drivers pass messages between nodes within a host. 35 * 36 * The constructs available at the node link level are very basic: 37 * Node IDs (mach_node_id_t) uniquely identify nodes within a host. 38 * MNL Info (mnl_node_info) describe the static characteristics of a node. 39 * MNL Names (mnl_name_t) uniquely identify abjects across all nodes. 40 * MNL Messages (mnl_msg) are passed between nodes (kernels) within a host. 41 */ 42 43 #ifndef _KERN_MACH_NODE_LINK_H_ 44 #define _KERN_MACH_NODE_LINK_H_ 45 46 #if KERNEL_PRIVATE 47 48 #include <sys/cdefs.h> 49 50 __BEGIN_DECLS 51 52 53 /*** Node Info Section ***/ 54 55 typedef int mach_node_id_t; // Used to uniquely identify a node 56 extern mach_node_id_t localnode_id; // This node's unique id. 57 58 /* An mnl_node struct describes static characteristcs of a node. The link 59 * driver requests this structure from the mach_node layer and fills out 60 * the fields. All fields must be filled in (non-zero) before both rx and tx 61 * links are brought up. 62 */ 63 typedef struct mnl_node_info { 64 mach_node_id_t node_id; // The node ID of this node 65 uint8_t datamodel; // 1==ILP32, 2==LP64 (matches dtrace) 66 uint8_t byteorder; // See libkern/OSByteOrder.h 67 uint32_t proto_vers_min;// Oldest MNL protocol vers node can accept 68 uint32_t proto_vers_max;// Newest MNL protocol vers node can accept 69 } __attribute__ ((aligned(8))) * mnl_node_info_t; 70 71 #define MNL_NODE_NULL ((mnl_node_info_t) 0UL) 72 #define MNL_NODE_VALID(n) ((n) != MNL_NODE_NULL) 73 #define MNL_PROTOCOL_V1 (1UL) // Current Node Link Protocol Version 74 75 /*** Mach Node Link Name Section 76 * 77 * A node link name (mnl_name_t) is an oqaque value guaranteed unique across 78 * kernel instances on all nodes. 79 */ 80 typedef uint64_t mnl_name_t; 81 82 /*** Mach Node Link Message Section ***/ 83 84 /* This structure is the header for an MNL Message buffer; the actual buffer 85 * is normally larger, and holds this header followed by the body of the 86 * message to be transmitted over the link. 87 * 88 * Note: The <node_id> and <size> fields are in host-native byte order when 89 * passed to mnl_msg_from_node() and from mnl_msg_to_node(). 90 * The byte order of these fields as sent over the link is left to the link 91 * specification. The link drivers on both sides must translate these fields 92 * between the link's byte order and host-native byte order. 93 * 94 * The body of the message, however, is treated as a byte-stream and passed 95 * to/from the mach_node layer without any introspection or byte reordering. 96 */ 97 typedef struct mnl_msg { 98 uint8_t sub; // 8b subsystem code 99 uint8_t cmd; // 8b command code 100 uint8_t qos; // 8b TODO: Doesn't do anything yet 101 uint8_t flags; // 8b Command-specific flag byte 102 uint32_t node_id;// 32b id of node that originated message 103 mnl_name_t object; // 64b object ref (use is determined by sub & cmd) 104 uint32_t options;// 32b Currently unused 105 uint32_t size; // 32b Number of bytes that follow mnl_msg header 106 } __attribute__((__packed__)) * mnl_msg_t; 107 108 109 /* Allocate a mnl_msg struct plus additional payload. Link drivers are not 110 * required to use this to allocate messages; any wired and mapped kernel 111 * memory is acceptable. 112 * 113 * Arguments: 114 * payload Number of additional bytes to allocate for message payload 115 * flags Currently unused; 0 should be passed 116 * 117 * Return values: 118 * MNL_MSG_NULL: Allocation failed 119 * *: Pointer to new mnl_msg struct of requested size 120 */ 121 mnl_msg_t mnl_msg_alloc(int payload, uint32_t flags); 122 123 124 /* Free a mnl_msg struct allocated by mnl_msg_alloc(). 125 * 126 * Arguments: 127 * msg Pointer to the message buffer to be freed 128 * flags Currently unused; 0 should be passed 129 */ 130 void mnl_msg_free(mnl_msg_t msg, uint32_t flags); 131 132 #define MNL_MSG_NULL ((mnl_msg_t) 0UL) 133 #define MNL_MSG_VALID(msg) ((msg) != MNL_MSG_NULL) 134 #define MNL_MSG_SIZE ((vm_offset_t)sizeof(struct mnl_msg)) 135 #define MNL_MSG_PAYLOAD(msg) ((vm_offset_t)(msg) + MNL_MSG_SIZE) 136 137 138 /*** Mach Node Link Driver Interface Section ***/ 139 140 /* The link driver calls this to setup a new (or restarted) node, and to get 141 * an mnl_node_info struct for use as a parameter to other mnl functions. 142 * If MNL_NODE_NULL is returned, the operation failed. Otherwise, a pointer 143 * to a new mnl_node struct is returned. The caller should set all fields 144 * in the structure, then call mnl_register() to complete node registration. 145 * 146 * Arguments: 147 * nid The id of the node to be instantiated 148 * flags Currently unused; 0 should be passed 149 * 150 * Return values: 151 * MNL_NODE_NULL: Operation failed 152 * *: Pointer to a new mnl_node struct 153 */ 154 mnl_node_info_t mnl_instantiate(mach_node_id_t nid, 155 uint32_t flags); 156 157 158 /* The link driver calls mnl_register() to complete the node registration 159 * process. KERN_SUCCESS is returned if registration succeeded, otherwise 160 * an error is returned. 161 * 162 * Arguments: 163 * node Pointer to the node's mnl_node structure 164 * flags Currently unused; 0 should be passed 165 * 166 * Return values: 167 * KERN_SUCCESS: Registration succeeded 168 * KERN_INVALID_ARGUMENT: Field(s) in <node> contained unacceptable values 169 * KERN_*: Values returned from underlying functions 170 */ 171 kern_return_t mnl_register(mnl_node_info_t node, 172 uint32_t flags); 173 174 175 /* The link driver calls this to report that the link has been raised in one 176 * or both directions. If the link is two uni-directional channels, each link 177 * driver will independently call this function, each only raising the link 178 * they are responsible for. The mach_node layer will not communicate with 179 * the remote node until both rx and tx links are up. 180 * 181 * Arguments: 182 * node Pointer to the node's mnl_node structure 183 * link Indicates which link(s) are up (see MNL_LINK_* defines) 184 * flags Currently unused; 0 should be passed 185 * 186 * Return values: 187 * KERN_SUCCESS: Link state changed successfully. 188 * KERN_INVALID_ARGUMENT: An argument value was not allowed. 189 * KERN_*: Values returned from underlying functions. 190 */ 191 kern_return_t mnl_set_link_state(mnl_node_info_t node, 192 int link, 193 uint32_t flags); 194 195 #define MNL_LINK_DOWN (0UL) 196 #define MNL_LINK_RX (1UL) 197 #define MNL_LINK_TX (2UL) 198 #define MNL_LINK_UP (MNL_LINK_RX|MNL_LINK_TX) 199 200 201 /* The link driver calls this to indicate a node has terminated and is no 202 * longer available for messaging. This may be due to a crash or an orderly 203 * shutdown, but either way the remote node no longer retains any state about 204 * the remaining nodes. References held on behalf of the terminated node 205 * will be cleaned up. After this is called, both the rx and tx links are 206 * marked as down. If the remote node restarts, the link driver can bring 207 * up the link using mnl_instantiate() again. 208 * 209 * Arguments: 210 * node Pointer to the node's mnl_node structure 211 * flags Currently unused; 0 should be passed 212 * 213 * Return values: 214 * KERN_SUCCESS: Node was terminated. 215 * KERN_INVALID_ARGUMENT: Node id was invalid or non-existant. 216 * KERN_*: Values returned from underlying functions. 217 */ 218 kern_return_t mnl_terminate(mnl_node_info_t node, 219 uint32_t flags); 220 221 222 /* The link driver calls this to deliver an incoming message. Note that the 223 * link driver must dispose of the memory pointed to by <msg> after the 224 * function call returns. 225 * 226 * Arguments: 227 * node Pointer to the node's mnl_node structure 228 * msg Pointer to the message buffer 229 * flags Currently unused; 0 should be passed 230 */ 231 void mnl_msg_from_node(mnl_node_info_t node, 232 mnl_msg_t msg, 233 uint32_t flags); 234 235 236 /* The link driver calls this to fetch the next message to transmit. 237 * This function will block until a message is available, or will return 238 * FLIPC_MSG_NULL if the link is to be terminated. After the caller has 239 * completed the transmission and no longer needs the msg buffer, it should 240 * call mnl_msg_complete(). 241 * 242 * Arguments: 243 * node Pointer to the node's mnl_node structure 244 * flags Currently unused; 0 should be passed 245 */ 246 mnl_msg_t mnl_msg_to_node(mnl_node_info_t node, 247 uint32_t flags); 248 249 250 /* The link driver calls this to indicate that the specified msg buffer has 251 * been sent over the link and can be deallocated. 252 * 253 * Arguments: 254 * node Pointer to the node's mnl_node structure 255 * msg Pointer to the message buffer 256 * flags Currently unused; 0 should be passed 257 */ 258 void mnl_msg_complete(mnl_node_info_t node, 259 mnl_msg_t msg, 260 uint32_t flags); 261 262 __END_DECLS 263 264 #endif /* KERNEL_PRIVATE */ 265 #endif /* _KERN_MACH_NODE_LINK_H_ */ 266