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.h
33 * Definitions for mach internode communication (used by flipc).
34 * This header is intended for use inside the kernel only.
37 #ifndef _KERN_MACH_NODE_H_
38 #define _KERN_MACH_NODE_H_
40 #if defined(MACH_KERNEL_PRIVATE) || defined(__APPLE_API_PRIVATE)
42 /*** Mach Node Name Server Section
43 * Definitions shared by the mach_node layer in the kernel and the
44 * node's bootstrap server (noded).
47 /* This structure describes messages sent from the mach_node layer to the
48 * node bootstrap server.
51 typedef struct mach_node_server_msg
{
52 mach_msg_header_t header
;
53 uint32_t identifier
; // See FLIPC_SM_* defines
54 uint32_t options
; // Currently unused
55 uint32_t node_id
; // Node number
56 } *mach_node_server_msg_t
;
59 /* This structure describes node registration messages sent from the mach_node
60 * layer to the node bootstrap server.
62 typedef struct mach_node_server_register_msg
{
63 struct mach_node_server_msg node_header
;
64 uint8_t datamodel
; // 1==ILP32, 2==LP64; matches dtrace
65 uint8_t byteorder
; // Uses defines from libkern/OSByteOrder.h
66 } *mach_node_server_register_msg_t
;
69 #define MACH_NODE_SERVER_MSG_ID (0x45444f4eUL) // msgh_id "NODE" for Node msgs
70 #define MACH_NODE_SM_REG_LOCAL (0UL) // Register the local node
71 #define MACH_NODE_SM_REG_REMOTE (1UL) // Register a remote node
74 #define LOCAL_DATA_MODEL (2) // Native data model is LP64
76 #define LOCAL_DATA_MODEL (1) // Native data model is ILP32
82 #if MACH_FLIPC && defined(MACH_KERNEL_PRIVATE)
84 #include <kern/mach_node_link.h>
85 #include <kern/queue.h>
87 #include <sys/cdefs.h>
91 #define MACH_NODES_MAX (2) // Must be a power-of-2
92 #define MACH_NODE_ID_VALID(nid) (((nid) >= 0) && ((nid) < MACH_NODES_MAX))
94 typedef struct flipc_node
*flipc_node_t
; // Defined in ipc/flipc.h
97 /*** Mach Node Section
99 * An instance of mach_node is allocated for each node known to mach.
100 * In-kernel interfaces use a pointer to this structure to refer to a node.
101 * External interfaces and protocols refer to node by id (mach_node_id_t).
103 typedef struct mach_node
*mach_node_t
;
106 /* Static node details, provided by the link driver at registration */
107 struct mnl_node_info info
;
109 lck_spin_t node_lock_data
;
111 /* Flags and status word */
112 uint32_t link
:2; // See MNL_LINK* defines
113 uint32_t published
:1; // True if node server has send-right
114 uint32_t active
:1; // True if node is up and ready
115 uint32_t suspended
:1; // True if node is active but sleeping
116 uint32_t dead
:1; // True if node is dead
117 uint32_t _reserved
:26; // Fill out the 32b flags field
120 ipc_space_t proxy_space
; // Kernel special space for proxy rights
121 ipc_pset_t proxy_port_set
; // All proxy ports are in this set
122 ipc_port_t bootstrap_port
; // Port for which "noded" holds rcv right
123 ipc_port_t control_port
; // For control & ack/nak messages
126 int proto_vers
; // Protocol version in use for this node
127 mach_node_t antecedent
; // Pointer to prior encarnation of this node id
130 extern mach_node_t localnode
; // This node's mach_node_t struct
132 #define MACH_NODE_NULL ((mach_node_t) 0UL)
133 #define MACH_NODE_SIZE ((vm_offset_t)sizeof(struct mach_node))
134 #define MACH_NODE_VALID(node) ((node) != MACH_NODE_NULL)
135 #define MACH_NODE_ALLOC() ((mach_node_t)kalloc(MACH_NODE_SIZE))
136 #define MACH_NODE_FREE(node) kfree(node, MACH_NODE_SIZE)
138 #define MACH_NODE_LOCK_INIT(np) lck_spin_init(&(np)->node_lock_data, \
139 &ipc_lck_grp, &ipc_lck_attr)
140 #define MACH_NODE_LOCK_DESTROY(np) lck_spin_destroy(&(np)->node_lock_data, \
142 #define MACH_NODE_LOCK(np) lck_spin_lock(&(np)->node_lock_data)
143 #define MACH_NODE_UNLOCK(np) lck_spin_unlock(&(np)->node_lock_data)
145 /* Gets or allocates a locked mach_node struct for the specified <node_id>.
146 * The current node is locked and returned if it is not dead, or if it is dead
147 * and <alloc_if_dead> is false. A new node struct is allocated, locked and
148 * returned if the node is dead and <alloc_if_dead> is true, or if the node
149 * is absent and <alloc_if_absent> is true. MACH_NODE_NULL is returned if
150 * the node is absent and <alloc_if_absent> is false. MACH_NODE_NULL is also
151 * returned if a new node structure was not able to be allocated.
154 mach_node_for_id_locked(mach_node_id_t node_id
,
155 boolean_t alloc_if_dead
,
156 boolean_t alloc_if_absent
);
159 /*** Mach Node Link Name Section
161 * A node link name (mnl_name_t) is an oqaque value guaranteed unique across
162 * kernel instances on all nodes. This guarantee requires that node ids not
165 * Names 0..(MACH_NODES_MAX-1) represent null (invalid) names
166 * Names MACH_NODES_MAX..(MACH_NODES_MAX*2-1) represent bootstrap names
167 * Names >=(MACH_NODES_MAX*2) represent normal names.
170 /* Allocate a new unique name and return it.
171 * Dispose of this with mnl_name_free().
172 * Returns MNL_NAME_NULL on failure.
174 extern mnl_name_t
mnl_name_alloc(void);
176 /* Deallocate a unique name that was allocated via mnl_name_alloc().
178 extern void mnl_name_free(mnl_name_t name
);
180 /* This macro is used to convert a node id to a bootstrap port name.
182 #define MNL_NAME_BOOTSTRAP(nid) ((mnl_name_t) MACH_NODES_MAX | (nid))
183 #define MNL_NAME_NULL ((mnl_name_t) 0UL)
184 #define MNL_NAME_VALID(obj) ((obj) >= MACH_NODES_MAX)
187 /* The mnl hash table may optionally be used by clients to associate mnl_names
188 * with objects. Objects to be stored in the hash table must start with an
189 * instance of struct mnk_obj. It is up to clients of the hash table to
190 * allocate and free the actual objects being stored.
192 typedef struct mnl_obj
{
193 queue_chain_t links
; // List of mnk_name_obj (See kern/queue.h "Method 1")
194 mnl_name_t name
; // Unique mnl_name
197 #define MNL_OBJ_NULL ((mnl_obj_t) 0UL)
198 #define MNL_OBJ_VALID(obj) ((obj) != MNL_OBJ_NULL)
201 /* Initialize the data structures in the mnl_obj structure at the head of the
202 * provided object. This should be called on an object before it is passed to
203 * any other mnl_obj* routine.
205 void mnl_obj_init(mnl_obj_t obj
);
207 /* Search the local node's hash table for the object associated with a
208 * mnl_name_t and return it. Returns MNL_NAME_NULL on failure.
210 mnl_obj_t
mnl_obj_lookup(mnl_name_t name
);
212 /* Search the local node's hash table for the object associated with a
213 * mnl_name_t and remove it. The pointer to the removed object is returned so
214 * that the caller can appropriately dispose of the object.
215 * Returns MNL_NAME_NULL on failure.
217 mnl_obj_t
mnl_obj_remove(mnl_name_t name
);
219 /* Insert an object into the locak node's hash table. If the name of the
220 * provided object is MNL_NAME_NULL then a new mnl_name is allocated and
221 * assigned to the object. Returns KERN_SUCCESS, or KERN_NAME_EXISTS if
222 * an object associated with that name is already in the hash table.
224 kern_return_t
mnl_obj_insert(mnl_obj_t obj
);
227 /*** Mach Node Link Message Section ***
229 * Struct mnl_msg is only the header for a mnl_msg buffer;
230 * the actual buffer is normally larger. The rest of the buffer
231 * holds the body of the message to be transmitted over the link.
233 * Note: A mnl_msg received over a link will be in the byte-order of the
234 * node that send it. fname and size must be corrected to the hosts' native
235 * byte order by the link driver before it is sent up to the flipc layer.
236 * However, the link driver should not attempt to adjust the data model or
237 * byte order of the payload that follows the mnl_msg header - that will
238 * be done by the flipc layer.
242 /* Values for mnl_msg.sub
244 #define MACH_NODE_SUB_INVALID (0) // Never sent
245 #define MACH_NODE_SUB_NODE (1) // MNL msg is for node management
246 #define MACH_NODE_SUB_FLIPC (2) // MNL msg is for FLIPC subsystem
247 #define MACH_NODE_SUB_VMSYS (3) // MNL msg is for VM subsystem
250 /* Called whenever the node special port changes
252 void mach_node_port_changed(void);
257 #endif // MACH_FLIPC && MACH_KERNEL_PRIVATE
258 #endif // _KERN_MACH_NODE_H_