|
|
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>
1.1.1.3 root 36: #include <kern/debug.h>
1.1 root 37: #include <kern/host.h>
38: #include <kern/processor.h>
39: #include <kern/task.h>
40: #include <kern/thread.h>
41: #include <kern/ipc_host.h>
42: #include <kern/ipc_kobject.h>
43: #include <ipc/ipc_port.h>
44: #include <ipc/ipc_space.h>
45:
46: #include <machine/machspl.h> /* for spl */
47:
48:
49:
50: /*
51: * ipc_host_init: set up various things.
52: */
53:
54: void ipc_host_init(void)
55: {
56: ipc_port_t port;
57: /*
58: * Allocate and set up the two host ports.
59: */
60: port = ipc_port_alloc_kernel();
61: if (port == IP_NULL)
62: panic("ipc_host_init");
63:
64: ipc_kobject_set(port, (ipc_kobject_t) &realhost, IKOT_HOST);
65: realhost.host_self = port;
66:
67: port = ipc_port_alloc_kernel();
68: if (port == IP_NULL)
69: panic("ipc_host_init");
70:
71: ipc_kobject_set(port, (ipc_kobject_t) &realhost, IKOT_HOST_PRIV);
72: realhost.host_priv_self = port;
73:
74: /*
75: * Set up ipc for default processor set.
76: */
77: ipc_pset_init(&default_pset);
78: ipc_pset_enable(&default_pset);
79:
80: /*
81: * And for master processor
82: */
83: ipc_processor_init(master_processor);
84: }
85:
86: /*
87: * Routine: mach_host_self [mach trap]
88: * Purpose:
89: * Give the caller send rights for his own host port.
90: * Conditions:
91: * Nothing locked.
92: * Returns:
93: * MACH_PORT_NULL if there are any resource failures
94: * or other errors.
95: */
96:
97: mach_port_t
98: mach_host_self(void)
99: {
100: ipc_port_t sright;
101:
102: sright = ipc_port_make_send(realhost.host_self);
103: return ipc_port_copyout_send(sright, current_space());
104: }
105:
106: /*
107: * ipc_processor_init:
108: *
109: * Initialize ipc access to processor by allocating port.
110: * Enable ipc control of processor by setting port object.
111: */
112:
113: void
114: ipc_processor_init(
115: processor_t processor)
116: {
117: ipc_port_t port;
118:
119: port = ipc_port_alloc_kernel();
120: if (port == IP_NULL)
121: panic("ipc_processor_init");
122: processor->processor_self = port;
123: ipc_kobject_set(port, (ipc_kobject_t) processor, IKOT_PROCESSOR);
124: }
125:
126:
127: /*
128: * ipc_pset_init:
129: *
130: * Initialize ipc control of a processor set by allocating its ports.
131: */
132:
133: void
134: ipc_pset_init(
135: processor_set_t pset)
136: {
137: ipc_port_t port;
138:
139: port = ipc_port_alloc_kernel();
140: if (port == IP_NULL)
141: panic("ipc_pset_init");
142: pset->pset_self = port;
143:
144: port = ipc_port_alloc_kernel();
145: if (port == IP_NULL)
146: panic("ipc_pset_init");
147: pset->pset_name_self = port;
148: }
149:
150: /*
151: * ipc_pset_enable:
152: *
153: * Enable ipc access to a processor set.
154: */
155: void
156: ipc_pset_enable(
157: processor_set_t pset)
158: {
159: pset_lock(pset);
160: if (pset->active) {
161: ipc_kobject_set(pset->pset_self,
162: (ipc_kobject_t) pset, IKOT_PSET);
163: ipc_kobject_set(pset->pset_name_self,
164: (ipc_kobject_t) pset, IKOT_PSET_NAME);
165: pset_ref_lock(pset);
166: pset->ref_count += 2;
167: pset_ref_unlock(pset);
168: }
169: pset_unlock(pset);
170: }
171:
172: /*
173: * ipc_pset_disable:
174: *
175: * Disable ipc access to a processor set by clearing the port objects.
176: * Caller must hold pset lock and a reference to the pset. Ok to
177: * just decrement pset reference count as a result.
178: */
179: void
180: ipc_pset_disable(
181: processor_set_t pset)
182: {
183: ipc_kobject_set(pset->pset_self, IKO_NULL, IKOT_NONE);
184: ipc_kobject_set(pset->pset_name_self, IKO_NULL, IKOT_NONE);
185: pset->ref_count -= 2;
186: }
187:
188: /*
189: * ipc_pset_terminate:
190: *
191: * Processor set is dead. Deallocate the ipc control structures.
192: */
193: void
194: ipc_pset_terminate(
195: processor_set_t pset)
196: {
197: ipc_port_dealloc_kernel(pset->pset_self);
198: ipc_port_dealloc_kernel(pset->pset_name_self);
199: }
200:
201: /*
1.1.1.3 root 202: * processor_set_default:
1.1 root 203: *
1.1.1.3 root 204: * Return ports for manipulating default_processor set.
1.1 root 205: */
206: kern_return_t
207: processor_set_default(
1.1.1.4 ! root 208: const host_t host,
1.1 root 209: processor_set_t *pset)
210: {
211: if (host == HOST_NULL)
212: return KERN_INVALID_ARGUMENT;
213:
214: *pset = &default_pset;
215: pset_reference(*pset);
216: return KERN_SUCCESS;
217: }
218:
219: /*
220: * Routine: convert_port_to_host
221: * Purpose:
222: * Convert from a port to a host.
223: * Doesn't consume the port ref; the host produced may be null.
224: * Conditions:
225: * Nothing locked.
226: */
227:
228: host_t
229: convert_port_to_host(
230: ipc_port_t port)
231: {
232: host_t host = HOST_NULL;
233:
234: if (IP_VALID(port)) {
235: ip_lock(port);
236: if (ip_active(port) &&
237: ((ip_kotype(port) == IKOT_HOST) ||
238: (ip_kotype(port) == IKOT_HOST_PRIV)))
239: host = (host_t) port->ip_kobject;
240: ip_unlock(port);
241: }
242:
243: return host;
244: }
245:
246: /*
247: * Routine: convert_port_to_host_priv
248: * Purpose:
249: * Convert from a port to a host.
250: * Doesn't consume the port ref; the host produced may be null.
251: * Conditions:
252: * Nothing locked.
253: */
254:
255: host_t
256: convert_port_to_host_priv(
257: ipc_port_t port)
258: {
259: host_t host = HOST_NULL;
260:
261: if (IP_VALID(port)) {
262: ip_lock(port);
263: if (ip_active(port) &&
264: (ip_kotype(port) == IKOT_HOST_PRIV))
265: host = (host_t) port->ip_kobject;
266: ip_unlock(port);
267: }
268:
269: return host;
270: }
271:
272: /*
273: * Routine: convert_port_to_processor
274: * Purpose:
275: * Convert from a port to a processor.
276: * Doesn't consume the port ref;
277: * the processor produced may be null.
278: * Conditions:
279: * Nothing locked.
280: */
281:
282: processor_t
283: convert_port_to_processor(
284: ipc_port_t port)
285: {
286: processor_t processor = PROCESSOR_NULL;
287:
288: if (IP_VALID(port)) {
289: ip_lock(port);
290: if (ip_active(port) &&
291: (ip_kotype(port) == IKOT_PROCESSOR))
292: processor = (processor_t) port->ip_kobject;
293: ip_unlock(port);
294: }
295:
296: return processor;
297: }
298:
299: /*
300: * Routine: convert_port_to_pset
301: * Purpose:
302: * Convert from a port to a pset.
303: * Doesn't consume the port ref; produces a pset ref,
304: * which may be null.
305: * Conditions:
306: * Nothing locked.
307: */
308:
309: processor_set_t
310: convert_port_to_pset(
311: ipc_port_t port)
312: {
313: processor_set_t pset = PROCESSOR_SET_NULL;
314:
315: if (IP_VALID(port)) {
316: ip_lock(port);
317: if (ip_active(port) &&
318: (ip_kotype(port) == IKOT_PSET)) {
319: pset = (processor_set_t) port->ip_kobject;
320: pset_reference(pset);
321: }
322: ip_unlock(port);
323: }
324:
325: return pset;
326: }
327:
328: /*
329: * Routine: convert_port_to_pset_name
330: * Purpose:
331: * Convert from a port to a pset.
332: * Doesn't consume the port ref; produces a pset ref,
333: * which may be null.
334: * Conditions:
335: * Nothing locked.
336: */
337:
338: processor_set_t
339: convert_port_to_pset_name(
340: ipc_port_t port)
341: {
342: processor_set_t pset = PROCESSOR_SET_NULL;
343:
344: if (IP_VALID(port)) {
345: ip_lock(port);
346: if (ip_active(port) &&
347: ((ip_kotype(port) == IKOT_PSET) ||
348: (ip_kotype(port) == IKOT_PSET_NAME))) {
349: pset = (processor_set_t) port->ip_kobject;
350: pset_reference(pset);
351: }
352: ip_unlock(port);
353: }
354:
355: return pset;
356: }
357:
358: /*
359: * Routine: convert_host_to_port
360: * Purpose:
361: * Convert from a host to a port.
362: * Produces a naked send right which may be invalid.
363: * Conditions:
364: * Nothing locked.
365: */
366:
367: ipc_port_t
368: convert_host_to_port(
369: host_t host)
370: {
371: ipc_port_t port;
372:
373: port = ipc_port_make_send(host->host_self);
374:
375: return port;
376: }
377:
378: /*
379: * Routine: convert_processor_to_port
380: * Purpose:
381: * Convert from a processor to a port.
382: * Produces a naked send right which is always valid.
383: * Conditions:
384: * Nothing locked.
385: */
386:
387: ipc_port_t
388: convert_processor_to_port(processor_t processor)
389: {
390: ipc_port_t port;
391:
392: port = ipc_port_make_send(processor->processor_self);
393:
394: return port;
395: }
396:
397: /*
398: * Routine: convert_pset_to_port
399: * Purpose:
400: * Convert from a pset to a port.
401: * Consumes a pset ref; produces a naked send right
402: * which may be invalid.
403: * Conditions:
404: * Nothing locked.
405: */
406:
407: ipc_port_t
408: convert_pset_to_port(
409: processor_set_t pset)
410: {
411: ipc_port_t port;
412:
413: pset_lock(pset);
414: if (pset->active)
415: port = ipc_port_make_send(pset->pset_self);
416: else
417: port = IP_NULL;
418: pset_unlock(pset);
419:
420: pset_deallocate(pset);
421: return port;
422: }
423:
424: /*
425: * Routine: convert_pset_name_to_port
426: * Purpose:
427: * Convert from a pset to a port.
428: * Consumes a pset ref; produces a naked send right
429: * which may be invalid.
430: * Conditions:
431: * Nothing locked.
432: */
433:
434: ipc_port_t
435: convert_pset_name_to_port(
436: processor_set_t pset)
437: {
438: ipc_port_t port;
439:
440: pset_lock(pset);
441: if (pset->active)
442: port = ipc_port_make_send(pset->pset_name_self);
443: else
444: port = IP_NULL;
445: pset_unlock(pset);
446:
447: pset_deallocate(pset);
448: return port;
449: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.