|
|
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.