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