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
55typedef int mach_node_id_t; // Used to uniquely identify a node
56extern 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 */
63typedef 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 */
80typedef 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 */
97typedef 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 */
121mnl_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 */
130void 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 */
154mnl_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 */
171kern_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 */
191kern_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 */
218kern_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 */
231void 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 */
246mnl_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 */
258void 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