1/*
2 * Copyright (c) 2022 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 _MACH_EXCLAVES_H
30#define _MACH_EXCLAVES_H
31
32#if defined(PRIVATE)
33
34#include <os/base.h>
35#include <mach/mach_types.h>
36#include <mach/mach_param.h>
37#if !defined(KERNEL)
38#include <AvailabilityInternalPrivate.h>
39#endif /* defined(KERNEL) */
40
41
42__BEGIN_DECLS
43
44typedef uint64_t exclaves_id_t;
45typedef uint64_t exclaves_tag_t;
46typedef uint64_t exclaves_error_t;
47
48/*!
49 * @enum exclaves_sensor_status_t
50 *
51 * @brief
52 * The status of an exclaves sensor.
53 *
54 * Indicates if data from this sensor can currently be accessed.
55 * If the data cannot be accessed, exclaves_sensor_start() must be
56 * called (with an accompanying exclaves_sensor_stop()).
57 *
58 * If the data cannot be accessed, then reading sensor data will
59 * only result in 0s.
60 */
61OS_ENUM(exclaves_sensor_status, uint32_t,
62 EXCLAVES_SENSOR_STATUS_ALLOWED = 1,
63 EXCLAVES_SENSOR_STATUS_DENIED = 2,
64 EXCLAVES_SENSOR_STATUS_CONTROL = 3,
65 );
66
67OS_CLOSED_OPTIONS(exclaves_buffer_perm, uint32_t,
68 EXCLAVES_BUFFER_PERM_READ = 1,
69 EXCLAVES_BUFFER_PERM_WRITE = 2,
70 );
71
72OS_ENUM(exclaves_boot_stage, uint32_t,
73 EXCLAVES_BOOT_STAGE_NONE = ~0u,
74 EXCLAVES_BOOT_STAGE_2 = 0,
75 EXCLAVES_BOOT_STAGE_EXCLAVEKIT = 100,
76
77 /* The EXCLAVEKIT boot stage failed in some way. */
78 EXCLAVES_BOOT_STAGE_FAILED = 200,
79 );
80
81OS_ENUM(exclaves_status, uint8_t,
82 EXCLAVES_STATUS_NOT_STARTED = 0x00, /* Obsolete. Never used. */
83 EXCLAVES_STATUS_AVAILABLE = 0x01,
84 EXCLAVES_STATUS_FAILED = 0xFE, /* Obsolete. Never used. */
85 EXCLAVES_STATUS_NOT_SUPPORTED = 0xFF,
86 );
87
88#define MAX_CONCLAVE_RESOURCE_NUM 50
89
90#if !defined(KERNEL)
91
92/*!
93 * @function exclaves_endpoint_call
94 *
95 * @abstract
96 * Perform RPC to an exclaves endpoint.
97 *
98 * @param port
99 * Reserved, must be MACH_PORT_NULL for now.
100 *
101 * @param endpoint_id
102 * Identifier of exclaves endpoint to send RPC to.
103 *
104 * @param msg_buffer
105 * Pointer to exclaves IPC buffer.
106 *
107 * @param size
108 * Size of specified exclaves IPC buffer.
109 *
110 * @param tag
111 * In-out parameter for exclaves IPC tag.
112 *
113 * @param error
114 * Out parameter for exclaves IPC error.
115 *
116 * @result
117 * KERN_SUCCESS or mach system call error code.
118 */
119SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
120kern_return_t
121exclaves_endpoint_call(mach_port_t port, exclaves_id_t endpoint_id,
122 mach_vm_address_t msg_buffer, mach_vm_size_t size, exclaves_tag_t *tag,
123 exclaves_error_t *error);
124
125/*!
126 * @function exclaves_outbound_buffer_create
127 *
128 * @abstract
129 * Setup access by xnu to a pre-defined exclaves outbound memory buffer and
130 * return a mach port for it. The buffer can only be read from.
131 *
132 * @param port
133 * Reserved, must be MACH_PORT_NULL for now.
134 *
135 * @param buffer_name
136 * String name of buffer to operate on.
137 *
138 * @param size
139 * Size of requested outbound buffer.
140 *
141 * @param outbound_buffer_port
142 * Out parameter filled in with mach port name for the newly created outbound
143 * buffer object, must be mach_port_deallocate()d to tear down the access to
144 * the outbound buffer.
145 *
146 * @result
147 * KERN_SUCCESS or mach system call error code.
148 */
149SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
150kern_return_t
151exclaves_outbound_buffer_create(mach_port_t port, const char *buffer_name,
152 mach_vm_size_t size, mach_port_t *outbound_buffer_port);
153
154/*!
155 * @function exclaves_outbound_buffer_copyout
156 *
157 * @abstract
158 * Copy out to specified userspace buffer from previously setup exclaves
159 * outbound memory buffer.
160 *
161 * Two size/offsets are provided to faciliate fast copy that wraps around a ring
162 * buffer that could be placed arbitrarily in the outbound memory region.
163 *
164 * @param outbound_buffer_port
165 * A outbound buffer port name returned from exclaves_outbound_buffer_create()
166 *
167 * @param dst_buffer
168 * Pointer to userspace buffer to copy out from outbound buffer.
169 *
170 * @param size1
171 * Number of bytes to copy (<= size of specified userspace buffer).
172 *
173 * @param offset1
174 * Offset in outbound memory buffer to start copy at.
175 *
176 * @param size2
177 * Number of bytes to copy (<= size of specified userspace buffer). Can be 0,
178 * in which case the 2nd range is not copied.
179 *
180 * @param offset2
181 * Offset in outbound memory buffer to start copy at.
182 *
183 * @result
184 * KERN_SUCCESS or mach system call error code.
185 */
186SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
187kern_return_t
188exclaves_outbound_buffer_copyout(mach_port_t outbound_buffer_port,
189 mach_vm_address_t dst_buffer, mach_vm_size_t size1, mach_vm_size_t offset1,
190 mach_vm_size_t size2, mach_vm_size_t offset2);
191
192/*!
193 * @function exclaves_inbound_buffer_create
194 *
195 * @abstract
196 * Setup access by xnu to a pre-defined exclaves inbound memory buffer and
197 * return a mach port for it. The buffer can be both read from and written to.
198 *
199 * @param port
200 * Reserved, must be MACH_PORT_NULL for now.
201 *
202 * @param buffer_name
203 * String name of buffer to operate on.
204 *
205 * @param size
206 * Size of requested inbound buffer.
207 *
208 * @param inbound_buffer_port
209 * Out parameter filled in with mach port name for the newly created inbound
210 * buffer object, must be mach_port_deallocate()d to tear down the access to
211 * the inbound buffer.
212 *
213 * @result
214 * KERN_SUCCESS or mach system call error code.
215 */
216SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
217kern_return_t
218exclaves_inbound_buffer_create(mach_port_t port, const char *buffer_name,
219 mach_vm_size_t size, mach_port_t *inbound_buffer_port);
220
221/*!
222 * @function exclaves_inbound_buffer_copyin
223 *
224 * @abstract
225 * Copy from specified userspace buffer into previously setup inbound exclaves
226 * inbound memory buffer.
227 *
228 * Two size/offsets are provided to faciliate fast copy that wraps around a ring
229 * buffer that could be placed arbitrarily in the inbound memory region.
230 *
231 * @param inbound_buffer_port
232 * An inbound buffer port name returned from exclaves_inbound_buffer_create()
233 *
234 * @param src_buffer
235 * Pointer to userspace buffer to copy into inbound buffer.
236 *
237 * @param size1
238 * Number of bytes to copy (<= size of specified userspace buffer).
239 *
240 * @param offset1
241 * Offset in inbound memory buffer to start copy at.
242 *
243 * @param size2
244 * Number of bytes to copy (<= size of specified userspace buffer). Can be 0,
245 * in which case the 2nd range is not copied.
246 *
247 * @param offset2
248 * Offset in inbound memory buffer to start copy at.
249 *
250 * @result
251 * KERN_SUCCESS or mach system call error code. Some buffers are read-only and
252 * calls to exclaves_inbound_buffer_copyin() will result in
253 * KERN_PROTECTION_FAILURE.
254 */
255SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
256kern_return_t
257exclaves_inbound_buffer_copyin(mach_port_t inbound_buffer_port,
258 mach_vm_address_t src_buffer, mach_vm_size_t size1, mach_vm_size_t offset1,
259 mach_vm_size_t size2, mach_vm_size_t offset2);
260
261/*!
262 * @function exclaves_named_buffer_create
263 *
264 * @abstract
265 * Setup access by xnu to a pre-defined named exclaves shared memory buffer
266 * and return a mach port for it.
267 *
268 * @param port
269 * Reserved, must be MACH_PORT_NULL for now.
270 *
271 * @param buffer_id
272 * Identifier of named buffer to operate on.
273 *
274 * @param size
275 * Size of requested named buffer.
276 *
277 * @param named_buffer_port
278 * Out parameter filled in with mach port name for the newly created named
279 * buffer object, must be mach_port_deallocate()d to tear down the access to
280 * the named buffer.
281 *
282 * @result
283 * KERN_SUCCESS or mach system call error code.
284 */
285SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
286kern_return_t
287exclaves_named_buffer_create(mach_port_t port, exclaves_id_t buffer_id,
288 mach_vm_size_t size, mach_port_t* named_buffer_port);
289
290/*!
291 * @function exclaves_named_buffer_copyin
292 *
293 * @abstract
294 * Copy from specified userspace buffer into previously setup named exclaves
295 * shared memory buffer.
296 *
297 * @param named_buffer_port
298 * A named buffer port name returned from exclaves_named_buffer_create()
299 *
300 * @param src_buffer
301 * Pointer to userspace buffer to copy into named buffer.
302 *
303 * @param size
304 * Number of bytes to copy (<= size of specified userspace buffer).
305 *
306 * @param offset
307 * Offset in shared memory buffer to start copy at.
308 *
309 * @result
310 * KERN_SUCCESS or mach system call error code.
311 */
312SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
313kern_return_t
314exclaves_named_buffer_copyin(mach_port_t named_buffer_port,
315 mach_vm_address_t src_buffer, mach_vm_size_t size, mach_vm_size_t offset);
316
317/*!
318 * @function exclaves_named_buffer_copyout
319 *
320 * @abstract
321 * Copy out to specified userspace buffer from previously setup named exclaves
322 * shared memory buffer.
323 *
324 * @param named_buffer_port
325 * A named buffer port name returned from exclaves_named_buffer_create()
326 *
327 * @param dst_buffer
328 * Pointer to userspace buffer to copy out from named buffer.
329 *
330 * @param size
331 * Number of bytes to copy (<= size of specified userspace buffer).
332 *
333 * @param offset
334 * Offset in shared memory buffer to start copy at.
335 *
336 * @result
337 * KERN_SUCCESS or mach system call error code.
338 */
339SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
340kern_return_t
341exclaves_named_buffer_copyout(mach_port_t named_buffer_port,
342 mach_vm_address_t dst_buffer, mach_vm_size_t size, mach_vm_size_t offset);
343
344/*!
345 * @function exclaves_boot
346 *
347 * @abstract
348 * Perform exclaves boot.
349 *
350 * @param port
351 * Reserved, must be MACH_PORT_NULL for now.
352 *
353 * @param boot_stage
354 * Stage of boot requested
355 *
356 * @result
357 * KERN_SUCCESS or mach system call error code.
358 */
359SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
360kern_return_t
361exclaves_boot(mach_port_t port, exclaves_boot_stage_t boot_stage);
362
363/*!
364 * @function exclaves_audio_buffer_create
365 *
366 * @abstract
367 * Setup access by xnu to a pre-defined named exclaves audio shared memory
368 * buffer and return a mach port for it.
369 *
370 * @param port
371 * Reserved, must be MACH_PORT_NULL for now.
372 *
373 * @param buffer_name
374 * String name of buffer to operate on.
375 *
376 * @param size
377 * Size of requested named buffer.
378 *
379 * @param audio_buffer_port
380 * Out parameter filled in with mach port name for the newly created named
381 * buffer object, must be mach_port_deallocate()d to tear down the access to
382 * the named buffer.
383 *
384 * Audio buffers are distiguished from general named buffers as shared memory
385 * is arbitrated by the EIC.
386 *
387 * @result
388 * KERN_SUCCESS or mach system call error code.
389 */
390SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
391kern_return_t
392exclaves_audio_buffer_create(mach_port_t port, const char * buffer_name,
393 mach_vm_size_t size, mach_port_t *audio_buffer_port);
394
395/*!
396 * @function exclaves_audio_buffer_copyout
397 *
398 * @abstract
399 * Copy out to specified userspace buffer from previously setup named exclaves
400 * audio shared memory buffer.
401 *
402 * Audio buffers are arbitrated via the EIC and copies will return 0's when
403 * access to the sensor is not granted.
404 *
405 * Two size/offsets are provided to faciliate fast copy that wraps around a
406 * ring buffer that could be placed arbitrarily in the shared memory region.
407 *
408 * @param audio_buffer_port
409 * A named buffer port name returned from exclaves_audio_buffer_create()
410 *
411 * @param dst_buffer
412 * Pointer to userspace buffer to copy out from named buffer.
413 *
414 * @param size1
415 * Number of bytes to copy (<= size of specified userspace buffer).
416 *
417 * @param offset1
418 * Offset in shared memory buffer to start copy at.
419 *
420 * @param size2
421 * Number of bytes to copy (<= size of specified userspace buffer). Can be 0,
422 * in which case the 2nd range is not copied.
423 *
424 * @param offset2
425 * Offset in shared memory buffer to start copy at.
426 *
427 * @result
428 * KERN_SUCCESS or mach system call error code.
429 */
430SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
431kern_return_t
432exclaves_audio_buffer_copyout(mach_port_t audio_buffer_port,
433 mach_vm_address_t dst_buffer, mach_vm_size_t size1, mach_vm_size_t offset1,
434 mach_vm_size_t size2, mach_vm_size_t offset2);
435
436/*!
437 * @function exclaves_sensor_create
438 *
439 * @abstract
440 * Setup access by xnu to a pre-defined named sensor
441 *
442 * @param port
443 * Reserved, must be MACH_PORT_NULL for now.
444 *
445 * @param sensor_name
446 * String name of sensor to operate on.
447 *
448 * @param sensor_port
449 * Out parameter filled in with mach port name for the newly created
450 * sensor object, must be mach_port_deallocate()d to tear down the access to
451 * the sensor.
452 *
453 * @result
454 * KERN_SUCCESS or mach system call error code.
455 */
456SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
457kern_return_t
458exclaves_sensor_create(mach_port_t port, const char *sensor_name, mach_port_t *sensor_port);
459
460/*!
461 * @function exclaves_sensor_start
462 *
463 * @abstract
464 * Start accessing a sensor and cause any indicators to display.
465 *
466 * If multiple clients start the same sensor, the sensor will only
467 * actually start on the first client.
468 *
469 * @param sensor_port
470 * A sensor buffer port name returned from exclaves_sensor_create()
471 * for the sensor.
472 *
473 * @param flags to pass to the implementation. Must be 0 for now.
474 *
475 * @param sensor_status
476 * Out parameter filled with the sensor status.
477 *
478 * @result
479 * KERN_SUCCESS or mach system call error code.
480 */
481SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
482kern_return_t
483exclaves_sensor_start(mach_port_t sensor_port, uint64_t flags,
484 exclaves_sensor_status_t *sensor_status);
485
486/*!
487 * @function exclaves_sensor_stop
488 *
489 * @abstract
490 * Stop accessing a sensor and cause any indicators to stop displaying access.
491 *
492 * If multiple clients are accessing the sensor, sensor access will
493 * continue to display until all clients have called this function.
494 *
495 * @param sensor_port
496 * A sensor buffer port name returned from exclaves_sensor_create()
497 * for the sensor.
498 *
499 * @param flags to pass to the implementation. Must be 0 for now.
500 *
501 * @param sensor_status
502 * Out parameter filled with the sensor status.
503 *
504 * @result
505 * KERN_SUCCESS or mach system call error code.
506 */
507SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
508kern_return_t
509exclaves_sensor_stop(mach_port_t sensor_port, uint64_t flags,
510 exclaves_sensor_status_t *sensor_status);
511
512/*!
513 * @function exclaves_sensor_status
514 *
515 * @abstract
516 * Get the status of access to a sensor
517 *
518 * @param sensor_port
519 * A sensor buffer port name returned from exclaves_sensor_create()
520 * for the sensor.
521 *
522 * @param flags to pass to the implementation. Must be 0 for now.
523 *
524 * @param sensor_status
525 * Out parameter filled with the sensor status.
526 *
527 * @result
528 * KERN_SUCCESS or mach system call error code.
529 */
530SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
531kern_return_t
532exclaves_sensor_status(mach_port_t sensor_port, uint64_t flags,
533 exclaves_sensor_status_t *sensor_status);
534
535/*!
536 * @function exclaves_launch_conclave
537 *
538 * @abstract
539 * Launch conclave.
540 *
541 * @param port
542 * Reserved, must be MACH_PORT_NULL for now.
543 *
544 * @param arg1
545 * Reserved, must be NULL for now.
546 *
547 * @param arg2
548 * Reserved, must be 0 for now.
549 *
550 * @result
551 * KERN_SUCCESS or mach system call error code.
552 */
553SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
554kern_return_t
555exclaves_launch_conclave(mach_port_t port, void *arg1,
556 uint64_t arg2);
557
558/*!
559 * @function exclaves_lookup_service
560 *
561 * @abstract
562 * Lookup Conclave Resource.
563 *
564 * @param port
565 * Reserved, must be MACH_PORT_NULL for now.
566 *
567 * @param name
568 * Name of exclave resource to lookup
569 *
570 * @param resource_id
571 * Out param for resource id
572 *
573 * @result
574 * KERN_SUCCESS or mach system call error code.
575 */
576SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
577kern_return_t
578exclaves_lookup_service(mach_port_t port, const char *name, exclaves_id_t *resource_id);
579
580/*!
581 * @function exclaves_notification_create
582 *
583 * @abstract
584 * Finds the exclave notification resource with the specified name and
585 * makes it available for use by the calling task.
586 *
587 * @param port
588 * Reserved, must be MACH_PORT_NULL for now.
589 *
590 * @param name
591 * Notification identifier.
592 *
593 * @param notification_id
594 * Out parameter filled in with the notification ID
595 *
596 * @result
597 * KERN_SUCCESS or mach system call error code.
598 */
599SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
600kern_return_t
601exclaves_notification_create(mach_port_t port, const char *name, uint64_t *notification_id);
602
603#else /* defined(KERNEL) */
604
605/*!
606 * @function exclaves_endpoint_call
607 *
608 * @abstract
609 * Perform RPC to an exclaves endpoint via per-thread exclaves IPC buffer.
610 *
611 * @param port
612 * Reserved, must be IPC_PORT_NULL for now.
613 *
614 * @param endpoint_id
615 * Identifier of exclaves endpoint to send RPC to.
616 *
617 * @param tag
618 * In-out parameter for exclaves IPC tag.
619 *
620 * @param error
621 * Out parameter for exclaves IPC error.
622 *
623 * @result
624 * KERN_SUCCESS or mach error code.
625 */
626kern_return_t
627exclaves_endpoint_call(ipc_port_t port, exclaves_id_t endpoint_id,
628 exclaves_tag_t *tag, exclaves_error_t *error);
629
630/*!
631 * @function exclaves_allocate_ipc_buffer
632 *
633 * @abstract
634 * If necessary, allocate per-thread exclaves IPC buffer.
635 *
636 * @param ipc_buffer
637 * Out parameter filled in with address of IPC buffer. Can be NULL.
638 *
639 * @result
640 * KERN_SUCCESS or mach error code.
641 */
642kern_return_t
643exclaves_allocate_ipc_buffer(void **ipc_buffer);
644
645/*!
646 * @function exclaves_free_ipc_buffer
647 *
648 * @abstract
649 * If necessary, free per-thread exclaves IPC buffer.
650 *
651 * @result
652 * KERN_SUCCESS or mach error code.
653 */
654kern_return_t
655exclaves_free_ipc_buffer(void);
656
657/*!
658 * @function exclaves_get_ipc_buffer
659 *
660 * @abstract
661 * Return per-thread exclaves IPC buffer.
662 *
663 * @result
664 * If allocated, pointer to per-thread exclaves IPC buffer, NULL otherwise.
665 */
666OS_CONST
667void*
668exclaves_get_ipc_buffer(void);
669
670/* For use by Tightbeam kernel runtime only */
671
672typedef uint64_t exclaves_badge_t;
673
674/*!
675 * @typedef exclaves_upcall_handler_t
676 *
677 * @abstract
678 * RPC message handler for upcalls from exclaves via per-thread exclaves IPC
679 * buffer.
680 *
681 * @param context
682 * Opaque context pointer specified at handler registration.
683 *
684 * @param tag
685 * In-out parameter for exclaves IPC tag.
686 *
687 * @param badge
688 * Badge value identifying upcall RPC message.
689 *
690 * @result
691 * KERN_SUCCESS or mach error code.
692 */
693typedef kern_return_t
694(*exclaves_upcall_handler_t)(void *context, exclaves_tag_t *tag,
695 exclaves_badge_t badge);
696
697/*!
698 * @function exclaves_register_upcall_handler
699 *
700 * @abstract
701 * One-time registration of exclaves upcall RPC handler for specified upcall ID.
702 * Must be called during Exclaves boot sequence, will assert otherwise.
703 *
704 * @param upcall_id
705 * Identifier of upcall to configure.
706 *
707 * @param upcall_context
708 * Opaque context pointer to pass to upcall RPC handler.
709 *
710 * @param upcall_handler
711 * Pointer to upcall RPC handler.
712 *
713 * @result
714 * KERN_SUCCESS or mach error code.
715 */
716kern_return_t
717exclaves_register_upcall_handler(exclaves_id_t upcall_id, void *upcall_context,
718 exclaves_upcall_handler_t upcall_handler);
719
720struct XrtHosted_Callbacks;
721
722/*!
723 * @function xrt_hosted_register_callbacks
724 *
725 * @abstract
726 * Exclaves XRT hosted kext interface.
727 *
728 * @param callbacks
729 * Pointer to callback function table.
730 */
731void
732exclaves_register_xrt_hosted_callbacks(struct XrtHosted_Callbacks *callbacks);
733
734/*!
735 * @enum exclaves_sensor_type_t
736 *
737 * @brief
738 * Identifier for an exclaves sensor
739 */
740OS_ENUM(exclaves_sensor_type, uint32_t,
741 EXCLAVES_SENSOR_CAM = 1,
742 EXCLAVES_SENSOR_MIC = 2,
743 EXCLAVES_SENSOR_CAM_ALT_FACEID = 3,
744 /* update max if more sensors added */
745 EXCLAVES_SENSOR_MAX = 3,
746 );
747
748/*!
749 * @function exclaves_sensor_start
750 *
751 * @abstract
752 * Start accessing a sensor and cause any indicators to display.
753 *
754 * If multiple clients start the same sensor, the sensor will only
755 * actually start on the first client.
756 *
757 * @param sensor_type
758 * type of sensor to operate on.
759 *
760 * @param flags to pass to the implementation. Must be 0 for now.
761 *
762 * @param sensor_status
763 * Out parameter filled with the sensor status.
764 *
765 * @result
766 * KERN_SUCCESS or mach system call error code.
767 */
768kern_return_t
769exclaves_sensor_start(exclaves_sensor_type_t sensor_type, uint64_t flags,
770 exclaves_sensor_status_t *sensor_status);
771
772/*!
773 * @function exclaves_sensor_stop
774 *
775 * @abstract
776 * Stop accessing a sensor and cause any indicators to stop displaying access.
777 *
778 * If multiple clients are accessing the sensor, sensor access will
779 * continue to display until all clients have called this function.
780 *
781 * @param sensor_type
782 * type of sensor to operate on.
783 *
784 * @param flags to pass to the implementation. Must be 0 for now.
785 *
786 * @param sensor_status
787 * Out parameter filled with the sensor status.
788 *
789 * @result
790 * KERN_SUCCESS or mach system call error code.
791 */
792kern_return_t
793exclaves_sensor_stop(exclaves_sensor_type_t sensor_type, uint64_t flags,
794 exclaves_sensor_status_t *sensor_status);
795/*!
796 * @function exclaves_sensor_status
797 *
798 * @abstract
799 * Get the status of access to a sensor
800 *
801 * @param sensor_type
802 * type of sensor to operate on.
803 *
804 * @param sensor_status
805 * Out parameter filled with the sensor status.
806 *
807 * @param flags to pass to the implementation. Must be 0 for now.
808 *
809 * @result
810 * KERN_SUCCESS or mach system call error code.
811 */
812kern_return_t
813exclaves_sensor_status(exclaves_sensor_type_t sensor_type, uint64_t flags,
814 exclaves_sensor_status_t *sensor_status);
815
816/*!
817 * @function exclaves_display_healthcheck_rate
818 *
819 * @abstract
820 * Update the rate of the display healthcheck based on the specified
821 * display update rate
822 *
823 * @param ns
824 * The rate in nanoseconds.
825 * Note: This value may be be rounded to the nearest rate supported and not used
826 * as-is.
827 *
828 * @result
829 * KERN_SUCCESS or mach system call error code.
830 */
831kern_return_t
832exclaves_display_healthcheck_rate(uint64_t ns);
833
834#endif /* defined(KERNEL) */
835
836#if defined(MACH_KERNEL_PRIVATE)
837
838/* -------------------------------------------------------------------------- */
839
840/* Internal kernel interface */
841
842extern kern_return_t
843exclaves_thread_terminate(thread_t thread);
844
845extern bool
846exclaves_booted(void);
847
848extern size_t
849exclaves_ipc_buffer_count(void);
850
851OS_ENUM(exclaves_clock_type, uint8_t,
852 EXCLAVES_CLOCK_ABSOLUTE = 0,
853 EXCLAVES_CLOCK_CONTINUOUS = 1,
854 );
855
856extern void
857exclaves_update_timebase(exclaves_clock_type_t type, uint64_t offset);
858
859#endif /* defined(MACH_KERNEL_PRIVATE) */
860
861/* -------------------------------------------------------------------------- */
862
863/* Private interface between Libsyscall and xnu */
864
865OS_ENUM(exclaves_ctl_op, uint8_t,
866 EXCLAVES_CTL_OP_ENDPOINT_CALL = 1,
867 EXCLAVES_CTL_OP_NAMED_BUFFER_CREATE = 2,
868 EXCLAVES_CTL_OP_NAMED_BUFFER_COPYIN = 3,
869 EXCLAVES_CTL_OP_NAMED_BUFFER_COPYOUT = 4,
870 EXCLAVES_CTL_OP_BOOT = 5,
871 EXCLAVES_CTL_OP_LAUNCH_CONCLAVE = 6,
872 EXCLAVES_CTL_OP_LOOKUP_SERVICES = 7,
873 EXCLAVES_CTL_OP_AUDIO_BUFFER_CREATE = 8,
874 EXCLAVES_CTL_OP_AUDIO_BUFFER_COPYOUT = 9,
875 EXCLAVES_CTL_OP_SENSOR_CREATE = 10,
876 EXCLAVES_CTL_OP_SENSOR_START = 11,
877 EXCLAVES_CTL_OP_SENSOR_STOP = 12,
878 EXCLAVES_CTL_OP_SENSOR_STATUS = 13,
879 EXCLAVES_CTL_OP_NOTIFICATION_RESOURCE_LOOKUP = 14,
880 EXCLAVES_CTL_OP_LAST,
881 );
882#define EXCLAVES_CTL_FLAGS_MASK (0xfffffful)
883#define EXCLAVES_CTL_OP_AND_FLAGS(op, flags) \
884 ((uint32_t)EXCLAVES_CTL_OP_##op << 24 | \
885 ((uint32_t)(flags) & EXCLAVES_CTL_FLAGS_MASK))
886#define EXCLAVES_CTL_OP(op_and_flags) \
887 ((uint8_t)((op_and_flags) >> 24))
888#define EXCLAVES_CTL_FLAGS(op_and_flags) \
889 ((uint32_t)(op_and_flags) & EXCLAVES_CTL_FLAGS_MASK)
890
891/*!
892 * @struct exclaves_resource_user
893 *
894 * @brief
895 * User representation of exclave resource
896 */
897typedef struct exclaves_resource_user {
898 char r_name[MAXCONCLAVENAME];
899 uint64_t r_type;
900 exclaves_id_t r_id;
901 mach_port_name_t r_port;
902} exclaves_resouce_user_t;
903
904#if !defined(KERNEL)
905
906SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
907OS_NOT_TAIL_CALLED
908kern_return_t
909_exclaves_ctl_trap(mach_port_name_t name, uint32_t operation_and_flags,
910 exclaves_id_t identifier, mach_vm_address_t buffer, mach_vm_size_t size,
911 mach_vm_size_t size2, mach_vm_size_t offset);
912
913#endif /* !defined(KERNEL) */
914
915/* -------------------------------------------------------------------------- */
916
917/* Sysctl interface */
918
919#if defined(KERNEL)
920
921/*!
922 * @function exclaves_get_status
923 *
924 * @abstract
925 * Return the current running status of exclaves. This function will block until
926 * exclaves has booted, failed to boot, or are known to be not available.
927 *
928 * @result
929 * The status of exclaves.
930 */
931exclaves_status_t
932exclaves_get_status(void);
933
934#endif /* defined(KERNEL) */
935
936#if defined(XNU_KERNEL_PRIVATE)
937
938/*!
939 * @function exclaves_get_boot_stage
940 *
941 * @abstract
942 * Return the current boot stage of exclaves. This function will not block.
943 * In general this shouldn't be used (other than for the sysctl).
944 * exclaves_boot_wait() is mostly what is wanted.
945 *
946 * @result
947 * The boot stage of exclaves.
948 */
949exclaves_boot_stage_t
950exclaves_get_boot_stage(void);
951
952/*
953 * Identifies exclaves privilege checks.
954 */
955__options_closed_decl(exclaves_priv_t, unsigned int, {
956 EXCLAVES_PRIV_CONCLAVE_HOST = 0x1, /* Can host conclaves. */
957 EXCLAVES_PRIV_CONCLAVE_SPAWN = 0x2, /* Can spawn conclaves. */
958 EXCLAVES_PRIV_KERNEL_DOMAIN = 0x4, /* Access to kernel resources. */
959 EXCLAVES_PRIV_BOOT = 0x8, /* Can boot exclaves. */
960});
961
962/*
963 * Check to see if the specified task has a privilege.
964 */
965extern bool
966exclaves_has_priv(task_t task, exclaves_priv_t priv);
967
968/*
969 * Check to see if the specified vnode has a privilege.
970 * Vnode argument is untyped as it's not available to osfmk.
971 */
972extern bool
973exclaves_has_priv_vnode(void *vnode, int64_t off, exclaves_priv_t priv);
974
975/* Return index of last xnu frame before secure world. Valid frame index is
976 * always in range <0, nframes-1>. When frame is not found, return nframes
977 * value. */
978uint32_t exclaves_stack_offset(uintptr_t * out_addr, size_t nframes, bool slid_addresses);
979
980#endif /* defined(XNU_KERNEL_PRIVATE) */
981
982__END_DECLS
983
984#endif /* defined(PRIVATE) */
985
986#endif /* _MACH_EXCLAVES_H */
987