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