xref: /xnu-10063.141.1/osfmk/mach/exclaves.h (revision d8b80295118ef25ac3a784134bcf95cd8e88109f)
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 
44 typedef uint64_t exclaves_id_t;
45 typedef uint64_t exclaves_tag_t;
46 typedef 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  */
61 OS_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 
67 OS_CLOSED_OPTIONS(exclaves_buffer_perm, uint32_t,
68     EXCLAVES_BUFFER_PERM_READ = 1,
69     EXCLAVES_BUFFER_PERM_WRITE = 2,
70     );
71 
72 OS_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 
81 OS_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  */
119 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
120 kern_return_t
121 exclaves_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  */
149 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
150 kern_return_t
151 exclaves_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  */
186 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
187 kern_return_t
188 exclaves_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  */
216 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
217 kern_return_t
218 exclaves_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  */
255 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
256 kern_return_t
257 exclaves_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  */
285 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
286 kern_return_t
287 exclaves_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  */
312 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
313 kern_return_t
314 exclaves_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  */
339 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
340 kern_return_t
341 exclaves_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  */
359 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
360 kern_return_t
361 exclaves_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  */
390 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
391 kern_return_t
392 exclaves_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  */
430 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
431 kern_return_t
432 exclaves_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  */
456 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
457 kern_return_t
458 exclaves_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  */
481 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
482 kern_return_t
483 exclaves_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  */
507 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
508 kern_return_t
509 exclaves_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  */
530 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
531 kern_return_t
532 exclaves_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  */
553 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
554 kern_return_t
555 exclaves_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  */
576 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
577 kern_return_t
578 exclaves_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  */
599 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
600 kern_return_t
601 exclaves_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  */
626 kern_return_t
627 exclaves_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  */
642 kern_return_t
643 exclaves_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  */
654 kern_return_t
655 exclaves_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  */
666 OS_CONST
667 void*
668 exclaves_get_ipc_buffer(void);
669 
670 /* For use by Tightbeam kernel runtime only */
671 
672 typedef 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  */
693 typedef 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  */
716 kern_return_t
717 exclaves_register_upcall_handler(exclaves_id_t upcall_id, void *upcall_context,
718     exclaves_upcall_handler_t upcall_handler);
719 
720 struct 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  */
731 void
732 exclaves_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  */
740 OS_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  */
768 kern_return_t
769 exclaves_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  */
792 kern_return_t
793 exclaves_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  */
812 kern_return_t
813 exclaves_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  */
831 kern_return_t
832 exclaves_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 
842 extern kern_return_t
843 exclaves_thread_terminate(thread_t thread);
844 
845 extern bool
846 exclaves_booted(void);
847 
848 extern size_t
849 exclaves_ipc_buffer_count(void);
850 
851 OS_ENUM(exclaves_clock_type, uint8_t,
852     EXCLAVES_CLOCK_ABSOLUTE = 0,
853     EXCLAVES_CLOCK_CONTINUOUS = 1,
854     );
855 
856 extern void
857 exclaves_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 
865 OS_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  */
897 typedef 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 
906 SPI_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
907 OS_NOT_TAIL_CALLED
908 kern_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  */
931 exclaves_status_t
932 exclaves_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  */
949 exclaves_boot_stage_t
950 exclaves_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  */
965 extern bool
966 exclaves_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  */
972 extern bool
973 exclaves_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. */
978 uint32_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