1/* 2 * Copyright (c) 2021 Apple 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#ifndef _IOKIT_UIOEVENTLINK_H 30#define _IOKIT_UIOEVENTLINK_H 31 32#include <DriverKit/IODispatchQueue.iig> 33#include <DriverKit/IODispatchSource.iig> 34#include <DriverKit/IOUserClient.iig> 35 36enum { 37 kIOEventLinkMaxNameLength = 64, 38}; 39 40// IOEventLink::Associate() options 41enum { 42 kIOEventLinkAssociateCurrentThread = 0x00000000, 43 kIOEventLinkAssociateOnWait = 0x00000001, 44}; 45 46// Clock options 47enum { 48 kIOEventLinkClockMachAbsoluteTime = 0x0, 49}; 50 51/*! 52 * @class IOEventLink 53 * 54 * @abstract 55 * IOEventLink allows for fast IPC, suitable for 56 * realtime applications. 57 * 58 * @discussion 59 * 60 * Applications that open user clients to a DriverKit driver can set up an eventlink 61 * for fast signaling. 62 * 63 * To configure an eventlink, the application will have to first create an eventlink object 64 * with os_eventlink_create() (see <os/eventlink_private.h>). The application then has to extract 65 * the remote eventlink port with os_eventlink_extract_remote_port(). To send the remote eventlink port 66 * to the driver, use: 67 * 68 * const char * name = "Event Link Name"; // This must match the name the driver used in IOEventLink::Create(). 69 * kern_return_t ret = IOConnectTrap3(connect, // user client connection (io_connect_t) 70 * 0, // specifies event link configuration trap 71 * (uintptr_t)name, 72 * (uintptr_t)strlen(name), 73 * (uintptr_t)remotePort // port from os_eventlink_extract_remote_port 74 * ); 75 * 76 * Once the remote eventlink port has been sent to the driver, the driver should be notified with a user-defined external method 77 * or other existing signaling mechanism. The driver should handle this by activating the IOEventLink with Activate(). 78 */ 79class NATIVE KERNEL IOEventLink : public OSObject 80{ 81public: 82 83 virtual bool 84 init() override; 85 86 virtual void 87 free() override; 88 89 /*! 90 * @brief Create an IOEventLink. 91 * @param name User-specified name. If an IOEventLink with the same name already exists in the specified 92 * user client, the old IOEventLink will be replaced. 93 * @param userClient Userclient to create the eventlink in. The DriverKit runtime will retain the userclient, and will 94 * release it in Invalidate() or when the IOEventLink is freed. 95 * @param eventLink Created IOEventLink with +1 retain count to be released by the caller. 96 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 97 */ 98 static kern_return_t 99 Create(OSString * name, IOUserClient * userClient, IOEventLink ** eventLink) LOCAL; 100 101#if DRIVERKIT_PRIVATE 102 103 /*! 104 * @brief Set the port for this eventlink. 105 * @discussion This is not meant to be used directly. 106 * @param port Eventlink port 107 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 108 */ 109 virtual kern_return_t 110 SetEventlinkPort(mach_port_t port PORTCOPYSEND) LOCAL; 111 112#endif /* DRIVERKIT_PRIVATE */ 113 114 /* 115 * @brief Signal the eventlink. If a thread is waiting on the eventlink, this will wake up that thread. 116 * @discussion This API call is real time safe. 117 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 118 */ 119 kern_return_t 120 Signal() LOCALONLY; 121 122 /* 123 * @brief Wait on the eventlink. 124 * @discussion This API call is real time safe. 125 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 126 */ 127 kern_return_t 128 Wait(uint64_t * signalsConsumed) LOCALONLY; 129 130 /* 131 * @brief Signal the eventlink and wait. If a thread is waiting on the eventlink, this will wake up that thread. 132 * @discussion This API call is real time safe. 133 * @param signalsConsumed When the calling thread wakes up, the amount of signals consumed by the wait will be written here. 134 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 135 */ 136 kern_return_t 137 SignalAndWait(uint64_t * signalsConsumed) LOCALONLY; 138 139 /* 140 * @brief Signal the eventlink and wait with a timeout. If a thread is waiting on the eventlink, this will wake up that thread. 141 * @discussion This API call is real time safe. 142 * @param signalsConsumed When the calling thread wakes up, the amount of signals consumed by the wait will be written here. 143 * @param clockOptions Options for which clock to use. The only currently supported option is kIOEventLinkClockMachAbsoluteTime. 144 * @param timeout Timeout 145 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 146 */ 147 kern_return_t 148 SignalAndWaitUntil(uint64_t clockOptions, uint64_t timeout, uint64_t * signalsConsumed) LOCALONLY; 149 150 /* 151 * @brief Wait with a timeout. If a thread is waiting on the eventlink, this will wake up that thread. 152 * @discussion This API call is real time safe. 153 * @param signalsConsumed When the calling thread wakes up, the amount of signals consumed by the wait will be written here. 154 * @param clockOptions Options for which clock to use. The only currently supported option is kIOEventLinkClockMachAbsoluteTime. 155 * @param timeout Timeout 156 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 157 */ 158 kern_return_t 159 WaitUntil(uint64_t clockOptions, uint64_t timeout, uint64_t * signalsConsumed) LOCALONLY; 160 161 /*! 162 * @brief Cancel the event link. 163 * @discussion If a thread is waiting on the eventlink, cancellation will wake up that thread. 164 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 165 */ 166 kern_return_t 167 Cancel() LOCALONLY; 168 169 /*! 170 * @brief Activate the event link. 171 * @discussion The event link must be activated before it can be signaled or waited on. This is not real-time safe. 172 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 173 */ 174 kern_return_t 175 Activate() LOCALONLY; 176 177 /*! 178 * @brief Associate a thread with the eventlink. 179 * @discussion The eventlink should be activated before this call. This is not real-time safe. 180 * @param options Options for Associate(). Use kIOEventLinkAssociateCurrentThread or kIOEventLinkAssociateOnWait. 181 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 182 */ 183 kern_return_t 184 Associate(uint64_t options) LOCALONLY; 185 186 /*! 187 * @brief Disassociate the current thread from the eventlink. This is not real-time safe. 188 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 189 */ 190 kern_return_t 191 Disassociate() LOCALONLY; 192 193 /*! 194 * @brief Invalidate the IOEventLink. 195 * @discussion This releases the kernel reference to the IOEventLink, allowing the name to be used for a different 196 * IOEventLink. This method should be called after the client has configured the eventlink with the IOConnectTrap 197 * call. After invalidation, the IOEventLink can no longer be configured through the IOConnectTrap call. No other 198 * functionality is affected. 199 * @return kIOReturnSuccess on success. See IOReturn.h for error codes. 200 */ 201 kern_return_t 202 Invalidate() LOCALONLY; 203 204#if DRIVERKIT_PRIVATE 205 206 virtual kern_return_t 207 InvalidateKernel(IOUserClient * client); 208 209#endif /* DRIVERKIT_PRIVATE */ 210}; 211 212#endif /* ! _IOKIT_UIOEVENTLINK_H */ 213