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