xref: /xnu-8792.61.2/osfmk/kern/mach_node_link.h (revision 42e220869062b56f8d7d0726fd4c88954f87902c)
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