|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Mach Operating System
27: * Copyright (c) 1992,1991,1990,1989,1988 Carnegie Mellon University
28: * All Rights Reserved.
29: *
30: * Permission to use, copy, modify and distribute this software and its
31: * documentation is hereby granted, provided that both the copyright
32: * notice and this permission notice appear in all copies of the
33: * software, derivative works or modified versions, and any portions
34: * thereof, and that both notices appear in supporting documentation.
35: *
36: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
39: *
40: * Carnegie Mellon requests users of this software to return to
41: *
42: * Software Distribution Coordinator or [email protected]
43: * School of Computer Science
44: * Carnegie Mellon University
45: * Pittsburgh PA 15213-3890
46: *
47: * any improvements or extensions that they make and grant Carnegie Mellon
48: * the rights to redistribute these changes.
49: */
50:
51: /*
52: * kern/ipc_host.c
53: *
54: * Routines to implement host ports.
55: */
56:
57: #import <mach_ipc_compat.h>
58:
59: #include <mach/message.h>
60: #include <kern/host.h>
61: #include <kern/processor.h>
62: #include <kern/task.h>
63: #include <kern/thread.h>
64: #include <kern/ipc_host.h>
65: #include <kern/ipc_kobject.h>
66: #include <ipc/ipc_port.h>
67: #include <ipc/ipc_space.h>
68:
69: #include <machine/machspl.h> /* for spl */
70:
71:
72:
73: /*
74: * ipc_host_init: set up various things.
75: */
76:
77: void ipc_host_init(void)
78: {
79: ipc_port_t port;
80: /*
81: * Allocate and set up the two host ports.
82: */
83: port = ipc_port_alloc_kernel();
84: if (port == IP_NULL)
85: panic("ipc_host_init");
86:
87: ipc_kobject_set(port, (ipc_kobject_t) &realhost, IKOT_HOST);
88: realhost.host_self = port;
89:
90: port = ipc_port_alloc_kernel();
91: if (port == IP_NULL)
92: panic("ipc_host_init");
93:
94: ipc_kobject_set(port, (ipc_kobject_t) &realhost, IKOT_HOST_PRIV);
95: realhost.host_priv_self = port;
96:
97: /*
98: * Set up ipc for default processor set.
99: */
100: ipc_pset_init(&default_pset);
101: ipc_pset_enable(&default_pset);
102:
103: /*
104: * And for master processor
105: */
106: ipc_processor_init(master_processor);
107: }
108:
109: /*
110: * Routine: mach_host_self [mach trap]
111: * Purpose:
112: * Give the caller send rights for his own host port.
113: * Conditions:
114: * Nothing locked.
115: * Returns:
116: * MACH_PORT_NULL if there are any resource failures
117: * or other errors.
118: */
119:
120: mach_port_t
121: mach_host_self(void)
122: {
123: ipc_port_t sright;
124:
125: sright = ipc_port_make_send(realhost.host_self);
126: return ipc_port_copyout_send(sright, current_space());
127: }
128:
129: #if MACH_IPC_COMPAT
130:
131: /*
132: * Routine: host_self [mach trap]
133: * Purpose:
134: * Give the caller send rights for his own host port.
135: * If new, the send right is marked with IE_BITS_COMPAT.
136: * Conditions:
137: * Nothing locked.
138: * Returns:
139: * MACH_PORT_NULL if there are any resource failures
140: * or other errors.
141: */
142:
143: port_name_t
144: host_self(void)
145: {
146: ipc_port_t sright;
147:
148: sright = ipc_port_make_send(realhost.host_self);
149: return (port_name_t)
150: ipc_port_copyout_send_compat(sright, current_space());
151: }
152:
153: #endif MACH_IPC_COMPAT
154:
155: /*
156: * ipc_processor_init:
157: *
158: * Initialize ipc access to processor by allocating port.
159: * Enable ipc control of processor by setting port object.
160: */
161:
162: void
163: ipc_processor_init(
164: processor_t processor)
165: {
166: ipc_port_t port;
167:
168: port = ipc_port_alloc_kernel();
169: if (port == IP_NULL)
170: panic("ipc_processor_init");
171: processor->processor_self = port;
172: ipc_kobject_set(port, (ipc_kobject_t) processor, IKOT_PROCESSOR);
173: }
174:
175:
176: /*
177: * ipc_pset_init:
178: *
179: * Initialize ipc control of a processor set by allocating its ports.
180: */
181:
182: void
183: ipc_pset_init(
184: processor_set_t pset)
185: {
186: ipc_port_t port;
187:
188: port = ipc_port_alloc_kernel();
189: if (port == IP_NULL)
190: panic("ipc_pset_init");
191: pset->pset_self = port;
192:
193: port = ipc_port_alloc_kernel();
194: if (port == IP_NULL)
195: panic("ipc_pset_init");
196: pset->pset_name_self = port;
197: }
198:
199: /*
200: * ipc_pset_enable:
201: *
202: * Enable ipc access to a processor set.
203: */
204: void
205: ipc_pset_enable(
206: processor_set_t pset)
207: {
208: pset_lock(pset);
209: if (pset->active) {
210: ipc_kobject_set(pset->pset_self,
211: (ipc_kobject_t) pset, IKOT_PSET);
212: ipc_kobject_set(pset->pset_name_self,
213: (ipc_kobject_t) pset, IKOT_PSET_NAME);
214: pset_ref_lock(pset);
215: pset->ref_count += 2;
216: pset_ref_unlock(pset);
217: }
218: pset_unlock(pset);
219: }
220:
221: /*
222: * ipc_pset_disable:
223: *
224: * Disable ipc access to a processor set by clearing the port objects.
225: * Caller must hold pset lock and a reference to the pset. Ok to
226: * just decrement pset reference count as a result.
227: */
228: void
229: ipc_pset_disable(
230: processor_set_t pset)
231: {
232: ipc_kobject_set(pset->pset_self, IKO_NULL, IKOT_NONE);
233: ipc_kobject_set(pset->pset_name_self, IKO_NULL, IKOT_NONE);
234:
235: pset_ref_lock(pset);
236: pset->ref_count -= 2;
237: pset_ref_unlock(pset);
238: }
239:
240: /*
241: * ipc_pset_terminate:
242: *
243: * Processor set is dead. Deallocate the ipc control structures.
244: */
245: void
246: ipc_pset_terminate(
247: processor_set_t pset)
248: {
249: ipc_port_dealloc_kernel(pset->pset_self);
250: ipc_port_dealloc_kernel(pset->pset_name_self);
251: }
252:
253: /*
254: * processor_set_default, processor_set_default_priv:
255: *
256: * Return ports for manipulating default_processor set. MiG code
257: * differentiates between these two routines.
258: */
259: kern_return_t
260: processor_set_default(
261: host_t host,
262: processor_set_t *pset)
263: {
264: if (host == HOST_NULL)
265: return KERN_INVALID_ARGUMENT;
266:
267: *pset = &default_pset;
268: pset_reference(*pset);
269: return KERN_SUCCESS;
270: }
271:
272: kern_return_t
273: xxx_processor_set_default_priv(
274: host_t host,
275: processor_set_t *pset)
276: {
277: if (host == HOST_NULL)
278: return KERN_INVALID_ARGUMENT;
279:
280: *pset = &default_pset;
281: pset_reference(*pset);
282: return KERN_SUCCESS;
283: }
284:
285: /*
286: * Routine: convert_port_to_host
287: * Purpose:
288: * Convert from a port to a host.
289: * Doesn't consume the port ref; the host produced may be null.
290: * Conditions:
291: * Nothing locked.
292: */
293:
294: host_t
295: convert_port_to_host(ipc_port_t port)
296: {
297: host_t host = HOST_NULL;
298:
299: if (IP_VALID(port)) {
300: ip_lock(port);
301: if (ip_active(port) &&
302: ((ip_kotype(port) == IKOT_HOST) ||
303: (ip_kotype(port) == IKOT_HOST_PRIV)))
304: host = (host_t) port->ip_kobject;
305: ip_unlock(port);
306: }
307:
308: return host;
309: }
310:
311: /*
312: * Routine: convert_port_to_host_priv
313: * Purpose:
314: * Convert from a port to a host.
315: * Doesn't consume the port ref; the host produced may be null.
316: * Conditions:
317: * Nothing locked.
318: */
319:
320: host_t
321: convert_port_to_host_priv(ipc_port_t port)
322: {
323: host_t host = HOST_NULL;
324:
325: if (IP_VALID(port)) {
326: ip_lock(port);
327: if (ip_active(port) &&
328: (ip_kotype(port) == IKOT_HOST_PRIV))
329: host = (host_t) port->ip_kobject;
330: ip_unlock(port);
331: }
332:
333: return host;
334: }
335:
336: /*
337: * Routine: convert_port_to_processor
338: * Purpose:
339: * Convert from a port to a processor.
340: * Doesn't consume the port ref;
341: * the processor produced may be null.
342: * Conditions:
343: * Nothing locked.
344: */
345:
346: processor_t
347: convert_port_to_processor(ipc_port_t port)
348: {
349: processor_t processor = PROCESSOR_NULL;
350:
351: if (IP_VALID(port)) {
352: ip_lock(port);
353: if (ip_active(port) &&
354: (ip_kotype(port) == IKOT_PROCESSOR))
355: processor = (processor_t) port->ip_kobject;
356: ip_unlock(port);
357: }
358:
359: return processor;
360: }
361:
362: /*
363: * Routine: convert_port_to_pset
364: * Purpose:
365: * Convert from a port to a pset.
366: * Doesn't consume the port ref; produces a pset ref,
367: * which may be null.
368: * Conditions:
369: * Nothing locked.
370: */
371:
372: processor_set_t
373: convert_port_to_pset(ipc_port_t port)
374: {
375: processor_set_t pset = PROCESSOR_SET_NULL;
376:
377: if (IP_VALID(port)) {
378: ip_lock(port);
379: if (ip_active(port) &&
380: (ip_kotype(port) == IKOT_PSET)) {
381: pset = (processor_set_t) port->ip_kobject;
382: pset_reference(pset);
383: }
384: ip_unlock(port);
385: }
386:
387: return pset;
388: }
389:
390: /*
391: * Routine: convert_port_to_pset_name
392: * Purpose:
393: * Convert from a port to a pset.
394: * Doesn't consume the port ref; produces a pset ref,
395: * which may be null.
396: * Conditions:
397: * Nothing locked.
398: */
399:
400: processor_set_t
401: convert_port_to_pset_name(ipc_port_t port)
402: {
403: processor_set_t pset = PROCESSOR_SET_NULL;
404:
405: if (IP_VALID(port)) {
406: ip_lock(port);
407: if (ip_active(port) &&
408: ((ip_kotype(port) == IKOT_PSET) ||
409: (ip_kotype(port) == IKOT_PSET_NAME))) {
410: pset = (processor_set_t) port->ip_kobject;
411: pset_reference(pset);
412: }
413: ip_unlock(port);
414: }
415:
416: return pset;
417: }
418:
419: /*
420: * Routine: convert_host_to_port
421: * Purpose:
422: * Convert from a host to a port.
423: * Produces a naked send right which is always valid.
424: * Conditions:
425: * Nothing locked.
426: */
427:
428: ipc_port_t
429: convert_host_to_port(host_t host)
430: {
431: ipc_port_t port;
432:
433: port = ipc_port_make_send(host->host_self);
434:
435: return port;
436: }
437:
438: /*
439: * Routine: convert_processor_to_port
440: * Purpose:
441: * Convert from a processor to a port.
442: * Produces a naked send right which is always valid.
443: * Conditions:
444: * Nothing locked.
445: */
446:
447: ipc_port_t
448: convert_processor_to_port(processor_t processor)
449: {
450: ipc_port_t port;
451:
452: port = ipc_port_make_send(processor->processor_self);
453:
454: return port;
455: }
456:
457: /*
458: * Routine: convert_pset_to_port
459: * Purpose:
460: * Convert from a pset to a port.
461: * Consumes a pset ref; produces a naked send right
462: * which may be invalid.
463: * Conditions:
464: * Nothing locked.
465: */
466:
467: ipc_port_t
468: convert_pset_to_port(processor_set_t pset)
469: {
470: ipc_port_t port;
471:
472: pset_lock(pset);
473: if (pset->active)
474: port = ipc_port_make_send(pset->pset_self);
475: else
476: port = IP_NULL;
477: pset_unlock(pset);
478:
479: pset_deallocate(pset);
480: return port;
481: }
482:
483: /*
484: * Routine: convert_pset_name_to_port
485: * Purpose:
486: * Convert from a pset to a port.
487: * Consumes a pset ref; produces a naked send right
488: * which may be invalid.
489: * Conditions:
490: * Nothing locked.
491: */
492:
493: ipc_port_t
494: convert_pset_name_to_port(processor_set_t pset)
495: {
496: ipc_port_t port;
497:
498: pset_lock(pset);
499: if (pset->active)
500: port = ipc_port_make_send(pset->pset_name_self);
501: else
502: port = IP_NULL;
503: pset_unlock(pset);
504:
505: pset_deallocate(pset);
506: return port;
507: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.