1/* 2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * @OSF_COPYRIGHT@ 30 */ 31/* 32 * File: kern/ipc_clock.c 33 * Purpose: Routines to support ipc semantics of new kernel 34 * alarm clock facility. 35 */ 36 37#include <mach/message.h> 38#include <kern/host.h> 39#include <kern/processor.h> 40#include <kern/task.h> 41#include <kern/thread.h> 42#include <kern/ipc_host.h> 43#include <kern/ipc_kobject.h> 44#include <kern/clock.h> 45#include <kern/misc_protos.h> 46#include <ipc/ipc_port.h> 47#include <ipc/ipc_space.h> 48 49/* 50 * Routine: ipc_clock_init 51 * Purpose: 52 * Initialize ipc control of a clock. 53 */ 54void 55ipc_clock_init( 56 clock_t clock) 57{ 58 ipc_port_t port; 59 60 port = ipc_port_alloc_kernel(); 61 if (port == IP_NULL) 62 panic("ipc_clock_init"); 63 clock->cl_service = port; 64 65 port = ipc_port_alloc_kernel(); 66 if (port == IP_NULL) 67 panic("ipc_clock_init"); 68 clock->cl_control = port; 69} 70 71/* 72 * Routine: ipc_clock_enable 73 * Purpose: 74 * Enable ipc access to a clock. 75 */ 76void 77ipc_clock_enable( 78 clock_t clock) 79{ 80 ipc_kobject_set(clock->cl_service, 81 (ipc_kobject_t) clock, IKOT_CLOCK); 82 ipc_kobject_set(clock->cl_control, 83 (ipc_kobject_t) clock, IKOT_CLOCK_CTRL); 84} 85 86/* 87 * Routine: convert_port_to_clock 88 * Purpose: 89 * Convert from a port to a clock. 90 * Doesn't consume the port ref; produces a clock ref, 91 * which may be null. 92 * Conditions: 93 * Nothing locked. 94 */ 95clock_t 96convert_port_to_clock( 97 ipc_port_t port) 98{ 99 clock_t clock = CLOCK_NULL; 100 101 if (IP_VALID(port)) { 102 ip_lock(port); 103 if (ip_active(port) && 104 ((ip_kotype(port) == IKOT_CLOCK) || 105 (ip_kotype(port) == IKOT_CLOCK_CTRL))) { 106 clock = (clock_t) port->ip_kobject; 107 } 108 ip_unlock(port); 109 } 110 return (clock); 111} 112 113/* 114 * Routine: convert_port_to_clock_ctrl 115 * Purpose: 116 * Convert from a port to a clock. 117 * Doesn't consume the port ref; produces a clock ref, 118 * which may be null. 119 * Conditions: 120 * Nothing locked. 121 */ 122clock_t 123convert_port_to_clock_ctrl( 124 ipc_port_t port) 125{ 126 clock_t clock = CLOCK_NULL; 127 128 if (IP_VALID(port)) { 129 ip_lock(port); 130 if (ip_active(port) && 131 (ip_kotype(port) == IKOT_CLOCK_CTRL)) { 132 clock = (clock_t) port->ip_kobject; 133 } 134 ip_unlock(port); 135 } 136 return (clock); 137} 138 139/* 140 * Routine: convert_clock_to_port 141 * Purpose: 142 * Convert from a clock to a port. 143 * Produces a naked send right which may be invalid. 144 * Conditions: 145 * Nothing locked. 146 */ 147ipc_port_t 148convert_clock_to_port( 149 clock_t clock) 150{ 151 ipc_port_t port; 152 153 port = ipc_port_make_send(clock->cl_service); 154 return (port); 155} 156 157/* 158 * Routine: convert_clock_ctrl_to_port 159 * Purpose: 160 * Convert from a clock to a port. 161 * Produces a naked send right which may be invalid. 162 * Conditions: 163 * Nothing locked. 164 */ 165ipc_port_t 166convert_clock_ctrl_to_port( 167 clock_t clock) 168{ 169 ipc_port_t port; 170 171 port = ipc_port_make_send(clock->cl_control); 172 return (port); 173} 174 175/* 176 * Routine: port_name_to_clock 177 * Purpose: 178 * Convert from a clock name to a clock pointer. 179 */ 180clock_t 181port_name_to_clock( 182 mach_port_name_t clock_name) 183{ 184 clock_t clock = CLOCK_NULL; 185 ipc_space_t space; 186 ipc_port_t port; 187 188 if (clock_name == 0) 189 return (clock); 190 space = current_space(); 191 if (ipc_port_translate_send(space, clock_name, &port) != KERN_SUCCESS) 192 return (clock); 193 if (ip_active(port) && (ip_kotype(port) == IKOT_CLOCK)) 194 clock = (clock_t) port->ip_kobject; 195 ip_unlock(port); 196 return (clock); 197} 198