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

