/ duct-tape / xnu / osfmk / kern / mach_node_link.h
mach_node_link.h
  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_ */