2 * Copyright (c) 2015-2016 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * File: kern/mach_node_link.h
33 * This header provides definitions required by Mach Node Link (MNL) drivers.
34 * MNL drivers pass messages between nodes within a host.
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.
43 #ifndef _KERN_MACH_NODE_LINK_H_
44 #define _KERN_MACH_NODE_LINK_H_
48 #include <sys/cdefs.h>
53 /*** Node Info Section ***/
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.
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.
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
;
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
75 /*** Mach Node Link Name Section
77 * A node link name (mnl_name_t) is an oqaque value guaranteed unique across
78 * kernel instances on all nodes.
80 typedef uint64_t mnl_name_t
;
82 /*** Mach Node Link Message Section ***/
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.
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.
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.
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
;
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.
114 * payload Number of additional bytes to allocate for message payload
115 * flags Currently unused; 0 should be passed
118 * MNL_MSG_NULL: Allocation failed
119 * *: Pointer to new mnl_msg struct of requested size
121 mnl_msg_t
mnl_msg_alloc(int payload
, uint32_t flags
);
124 /* Free a mnl_msg struct allocated by mnl_msg_alloc().
127 * msg Pointer to the message buffer to be freed
128 * flags Currently unused; 0 should be passed
130 void mnl_msg_free(mnl_msg_t msg
, uint32_t flags
);
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)
138 /*** Mach Node Link Driver Interface Section ***/
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.
147 * nid The id of the node to be instantiated
148 * flags Currently unused; 0 should be passed
151 * MNL_NODE_NULL: Operation failed
152 * *: Pointer to a new mnl_node struct
154 mnl_node_info_t
mnl_instantiate(mach_node_id_t nid
,
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.
163 * node Pointer to the node's mnl_node structure
164 * flags Currently unused; 0 should be passed
167 * KERN_SUCCESS: Registration succeeded
168 * KERN_INVALID_ARGUMENT: Field(s) in <node> contained unacceptable values
169 * KERN_*: Values returned from underlying functions
171 kern_return_t
mnl_register(mnl_node_info_t node
,
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.
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
187 * KERN_SUCCESS: Link state changed successfully.
188 * KERN_INVALID_ARGUMENT: An argument value was not allowed.
189 * KERN_*: Values returned from underlying functions.
191 kern_return_t
mnl_set_link_state(mnl_node_info_t node
,
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)
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.
210 * node Pointer to the node's mnl_node structure
211 * flags Currently unused; 0 should be passed
214 * KERN_SUCCESS: Node was terminated.
215 * KERN_INVALID_ARGUMENT: Node id was invalid or non-existant.
216 * KERN_*: Values returned from underlying functions.
218 kern_return_t
mnl_terminate(mnl_node_info_t node
,
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.
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
231 void mnl_msg_from_node(mnl_node_info_t node
,
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().
243 * node Pointer to the node's mnl_node structure
244 * flags Currently unused; 0 should be passed
246 mnl_msg_t
mnl_msg_to_node(mnl_node_info_t node
,
250 /* The link driver calls this to indicate that the specified msg buffer has
251 * been sent over the link and can be deallocated.
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
258 void mnl_msg_complete(mnl_node_info_t node
,
264 #endif /* KERNEL_PRIVATE */
265 #endif /* _KERN_MACH_NODE_LINK_H_ */