2 * Copyright (c) 2007 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <mach/mach_types.h>
30 #include <mach/kern_return.h>
31 #include <mach/thread_status.h>
32 #include <kern/thread.h>
33 #include <kern/kalloc.h>
34 #include <arm/vmparam.h>
35 #include <arm/cpu_data_internal.h>
36 #include <arm64/proc_reg.h>
38 struct arm_vfpv2_state
45 typedef struct arm_vfpv2_state arm_vfpv2_state_t
;
47 #define ARM_VFPV2_STATE_COUNT ((mach_msg_type_number_t) \
48 (sizeof (arm_vfpv2_state_t)/sizeof(uint32_t)))
53 void thread_set_child(thread_t child
, int pid
);
54 void thread_set_parent(thread_t parent
, int pid
);
57 * Maps state flavor to number of words in the state:
59 /* __private_extern__ */
60 unsigned int _MachineStateCount
[] = {
62 ARM_UNIFIED_THREAD_STATE_COUNT
,
64 ARM_EXCEPTION_STATE_COUNT
,
65 ARM_DEBUG_STATE_COUNT
,
66 /* THREAD_STATE_NONE (legacy) */ 0,
67 ARM_THREAD_STATE64_COUNT
,
68 ARM_EXCEPTION_STATE64_COUNT
,
69 /* THREAD_STATE_LAST (legacy) */ 0,
70 ARM_THREAD_STATE32_COUNT
,
75 ARM_DEBUG_STATE32_COUNT
,
76 ARM_DEBUG_STATE64_COUNT
,
78 ARM_NEON_STATE64_COUNT
,
81 /* ARM_SAVED_STATE32_COUNT */ 0,
82 /* ARM_SAVED_STATE64_COUNT */ 0,
83 /* ARM_NEON_SAVED_STATE32_COUNT */ 0,
84 /* ARM_NEON_SAVED_STATE64_COUNT */ 0,
87 extern zone_t ads_zone
;
91 * Copy values from saved_state to ts64.
94 saved_state_to_thread_state64(const arm_saved_state_t
*saved_state
, arm_thread_state64_t
*ts64
)
98 assert(is_saved_state64(saved_state
));
100 ts64
->fp
= get_saved_state_fp(saved_state
);
101 ts64
->lr
= get_saved_state_lr(saved_state
);
102 ts64
->sp
= get_saved_state_sp(saved_state
);
103 ts64
->pc
= get_saved_state_pc(saved_state
);
104 ts64
->cpsr
= get_saved_state_cpsr(saved_state
);
105 for (i
= 0; i
< 29; i
++)
106 ts64
->x
[i
] = get_saved_state_reg(saved_state
, i
);
110 * Copy values from ts64 to saved_state
113 thread_state64_to_saved_state(const arm_thread_state64_t
*ts64
, arm_saved_state_t
*saved_state
)
117 assert(is_saved_state64(saved_state
));
119 set_saved_state_fp(saved_state
, ts64
->fp
);
120 set_saved_state_lr(saved_state
, ts64
->lr
);
121 set_saved_state_sp(saved_state
, ts64
->sp
);
122 set_saved_state_pc(saved_state
, ts64
->pc
);
123 set_saved_state_cpsr(saved_state
, (ts64
->cpsr
& ~PSR64_MODE_MASK
) | PSR64_MODE_RW_64
);
124 for (i
= 0; i
< 29; i
++)
125 set_saved_state_reg(saved_state
, i
, ts64
->x
[i
]);
130 handle_get_arm32_thread_state(
131 thread_state_t tstate
,
132 mach_msg_type_number_t
* count
,
133 const arm_saved_state_t
*saved_state
)
135 if (*count
< ARM_THREAD_STATE32_COUNT
)
136 return (KERN_INVALID_ARGUMENT
);
137 if (!is_saved_state32(saved_state
))
138 return (KERN_INVALID_ARGUMENT
);
140 (void)saved_state_to_thread_state32(saved_state
, (arm_thread_state32_t
*)tstate
);
141 *count
= ARM_THREAD_STATE32_COUNT
;
146 handle_get_arm64_thread_state(
147 thread_state_t tstate
,
148 mach_msg_type_number_t
* count
,
149 const arm_saved_state_t
*saved_state
)
151 if (*count
< ARM_THREAD_STATE64_COUNT
)
152 return (KERN_INVALID_ARGUMENT
);
153 if (!is_saved_state64(saved_state
))
154 return (KERN_INVALID_ARGUMENT
);
156 (void)saved_state_to_thread_state64(saved_state
, (arm_thread_state64_t
*)tstate
);
157 *count
= ARM_THREAD_STATE64_COUNT
;
163 handle_get_arm_thread_state(
164 thread_state_t tstate
,
165 mach_msg_type_number_t
* count
,
166 const arm_saved_state_t
*saved_state
)
168 /* In an arm64 world, this flavor can be used to retrieve the thread
169 * state of a 32-bit or 64-bit thread into a unified structure, but we
170 * need to support legacy clients who are only aware of 32-bit, so
171 * check the count to see what the client is expecting.
173 if (*count
< ARM_UNIFIED_THREAD_STATE_COUNT
) {
174 return handle_get_arm32_thread_state(tstate
, count
, saved_state
);
177 arm_unified_thread_state_t
*unified_state
= (arm_unified_thread_state_t
*) tstate
;
178 bzero(unified_state
, sizeof(*unified_state
));
180 if (is_saved_state64(saved_state
)) {
181 unified_state
->ash
.flavor
= ARM_THREAD_STATE64
;
182 unified_state
->ash
.count
= ARM_THREAD_STATE64_COUNT
;
183 (void)saved_state_to_thread_state64(saved_state
, thread_state64(unified_state
));
187 unified_state
->ash
.flavor
= ARM_THREAD_STATE32
;
188 unified_state
->ash
.count
= ARM_THREAD_STATE32_COUNT
;
189 (void)saved_state_to_thread_state32(saved_state
, thread_state32(unified_state
));
191 *count
= ARM_UNIFIED_THREAD_STATE_COUNT
;
192 return (KERN_SUCCESS
);
196 handle_set_arm32_thread_state(
197 const thread_state_t tstate
,
198 mach_msg_type_number_t count
,
199 arm_saved_state_t
*saved_state
)
201 if (count
!= ARM_THREAD_STATE32_COUNT
)
202 return (KERN_INVALID_ARGUMENT
);
204 (void)thread_state32_to_saved_state((const arm_thread_state32_t
*)tstate
, saved_state
);
209 handle_set_arm64_thread_state(
210 const thread_state_t tstate
,
211 mach_msg_type_number_t count
,
212 arm_saved_state_t
*saved_state
)
214 if (count
!= ARM_THREAD_STATE64_COUNT
)
215 return (KERN_INVALID_ARGUMENT
);
217 (void)thread_state64_to_saved_state((const arm_thread_state64_t
*)tstate
, saved_state
);
223 handle_set_arm_thread_state(
224 const thread_state_t tstate
,
225 mach_msg_type_number_t count
,
226 arm_saved_state_t
*saved_state
)
228 /* In an arm64 world, this flavor can be used to set the thread state of a
229 * 32-bit or 64-bit thread from a unified structure, but we need to support
230 * legacy clients who are only aware of 32-bit, so check the count to see
231 * what the client is expecting.
233 if (count
< ARM_UNIFIED_THREAD_STATE_COUNT
) {
234 if (!is_saved_state32(saved_state
)) {
235 return (KERN_INVALID_ARGUMENT
);
237 return handle_set_arm32_thread_state(tstate
, count
, saved_state
);
240 const arm_unified_thread_state_t
*unified_state
= (const arm_unified_thread_state_t
*) tstate
;
242 if (is_thread_state64(unified_state
)) {
243 if (!is_saved_state64(saved_state
)) {
244 return (KERN_INVALID_ARGUMENT
);
246 (void)thread_state64_to_saved_state(const_thread_state64(unified_state
), saved_state
);
250 if (!is_saved_state32(saved_state
)) {
251 return (KERN_INVALID_ARGUMENT
);
253 (void)thread_state32_to_saved_state(const_thread_state32(unified_state
), saved_state
);
256 return (KERN_SUCCESS
);
260 * Translate thread state arguments to userspace representation
264 machine_thread_state_convert_to_user(
266 thread_flavor_t flavor
,
267 thread_state_t tstate
,
268 mach_msg_type_number_t
*count
)
270 // No conversion to userspace representation on this platform
271 (void)thread
; (void)flavor
; (void)tstate
; (void)count
;
276 * Translate thread state arguments from userspace representation
280 machine_thread_state_convert_from_user(
282 thread_flavor_t flavor
,
283 thread_state_t tstate
,
284 mach_msg_type_number_t count
)
286 // No conversion from userspace representation on this platform
287 (void)thread
; (void)flavor
; (void)tstate
; (void)count
;
292 * Translate signal context data pointer to userspace representation
296 machine_thread_siguctx_pointer_convert_to_user(
297 __assert_only thread_t thread
,
300 // No conversion to userspace representation on this platform
301 (void)thread
; (void)uctxp
;
306 * Translate array of function pointer syscall arguments from userspace representation
310 machine_thread_function_pointers_convert_from_user(
311 __assert_only thread_t thread
,
315 // No conversion from userspace representation on this platform
316 (void)thread
; (void)fptrs
; (void)count
;
321 * Routine: machine_thread_get_state
325 machine_thread_get_state(
327 thread_flavor_t flavor
,
328 thread_state_t tstate
,
329 mach_msg_type_number_t
* count
)
332 case THREAD_STATE_FLAVOR_LIST
:
334 return (KERN_INVALID_ARGUMENT
);
336 tstate
[0] = ARM_THREAD_STATE
;
337 tstate
[1] = ARM_VFP_STATE
;
338 tstate
[2] = ARM_EXCEPTION_STATE
;
339 tstate
[3] = ARM_DEBUG_STATE
;
343 case THREAD_STATE_FLAVOR_LIST_NEW
:
345 return (KERN_INVALID_ARGUMENT
);
347 tstate
[0] = ARM_THREAD_STATE
;
348 tstate
[1] = ARM_VFP_STATE
;
349 tstate
[2] = thread_is_64bit_data(thread
) ? ARM_EXCEPTION_STATE64
: ARM_EXCEPTION_STATE
;
350 tstate
[3] = thread_is_64bit_data(thread
) ? ARM_DEBUG_STATE64
: ARM_DEBUG_STATE32
;
354 case ARM_THREAD_STATE
:
356 kern_return_t rn
= handle_get_arm_thread_state(tstate
, count
, thread
->machine
.upcb
);
360 case ARM_THREAD_STATE32
:
362 if (thread_is_64bit_data(thread
))
363 return KERN_INVALID_ARGUMENT
;
365 kern_return_t rn
= handle_get_arm32_thread_state(tstate
, count
, thread
->machine
.upcb
);
370 case ARM_THREAD_STATE64
:
372 if (!thread_is_64bit_data(thread
))
373 return KERN_INVALID_ARGUMENT
;
375 kern_return_t rn
= handle_get_arm64_thread_state(tstate
, count
, thread
->machine
.upcb
);
380 case ARM_EXCEPTION_STATE
:{
381 struct arm_exception_state
*state
;
382 struct arm_saved_state32
*saved_state
;
384 if (*count
< ARM_EXCEPTION_STATE_COUNT
)
385 return (KERN_INVALID_ARGUMENT
);
386 if (thread_is_64bit_data(thread
))
387 return (KERN_INVALID_ARGUMENT
);
389 state
= (struct arm_exception_state
*) tstate
;
390 saved_state
= saved_state32(thread
->machine
.upcb
);
392 state
->exception
= saved_state
->exception
;
393 state
->fsr
= saved_state
->esr
;
394 state
->far
= saved_state
->far
;
396 *count
= ARM_EXCEPTION_STATE_COUNT
;
399 case ARM_EXCEPTION_STATE64
:{
400 struct arm_exception_state64
*state
;
401 struct arm_saved_state64
*saved_state
;
403 if (*count
< ARM_EXCEPTION_STATE64_COUNT
)
404 return (KERN_INVALID_ARGUMENT
);
405 if (!thread_is_64bit_data(thread
))
406 return (KERN_INVALID_ARGUMENT
);
408 state
= (struct arm_exception_state64
*) tstate
;
409 saved_state
= saved_state64(thread
->machine
.upcb
);
411 state
->exception
= saved_state
->exception
;
412 state
->far
= saved_state
->far
;
413 state
->esr
= saved_state
->esr
;
415 *count
= ARM_EXCEPTION_STATE64_COUNT
;
418 case ARM_DEBUG_STATE
:{
419 arm_legacy_debug_state_t
*state
;
420 arm_debug_state32_t
*thread_state
;
422 if (*count
< ARM_LEGACY_DEBUG_STATE_COUNT
)
423 return (KERN_INVALID_ARGUMENT
);
425 if (thread_is_64bit_data(thread
))
426 return (KERN_INVALID_ARGUMENT
);
428 state
= (arm_legacy_debug_state_t
*) tstate
;
429 thread_state
= find_debug_state32(thread
);
431 if (thread_state
== NULL
)
432 bzero(state
, sizeof(arm_legacy_debug_state_t
));
434 bcopy(thread_state
, state
, sizeof(arm_legacy_debug_state_t
));
436 *count
= ARM_LEGACY_DEBUG_STATE_COUNT
;
439 case ARM_DEBUG_STATE32
:{
440 arm_debug_state32_t
*state
;
441 arm_debug_state32_t
*thread_state
;
443 if (*count
< ARM_DEBUG_STATE32_COUNT
)
444 return (KERN_INVALID_ARGUMENT
);
446 if (thread_is_64bit_data(thread
))
447 return (KERN_INVALID_ARGUMENT
);
449 state
= (arm_debug_state32_t
*) tstate
;
450 thread_state
= find_debug_state32(thread
);
452 if (thread_state
== NULL
)
453 bzero(state
, sizeof(arm_debug_state32_t
));
455 bcopy(thread_state
, state
, sizeof(arm_debug_state32_t
));
457 *count
= ARM_DEBUG_STATE32_COUNT
;
461 case ARM_DEBUG_STATE64
:{
462 arm_debug_state64_t
*state
;
463 arm_debug_state64_t
*thread_state
;
465 if (*count
< ARM_DEBUG_STATE64_COUNT
)
466 return (KERN_INVALID_ARGUMENT
);
468 if (!thread_is_64bit_data(thread
))
469 return (KERN_INVALID_ARGUMENT
);
471 state
= (arm_debug_state64_t
*) tstate
;
472 thread_state
= find_debug_state64(thread
);
474 if (thread_state
== NULL
)
475 bzero(state
, sizeof(arm_debug_state64_t
));
477 bcopy(thread_state
, state
, sizeof(arm_debug_state64_t
));
479 *count
= ARM_DEBUG_STATE64_COUNT
;
484 struct arm_vfp_state
*state
;
485 arm_neon_saved_state32_t
*thread_state
;
488 if (*count
< ARM_VFP_STATE_COUNT
) {
489 if (*count
< ARM_VFPV2_STATE_COUNT
)
490 return (KERN_INVALID_ARGUMENT
);
492 *count
= ARM_VFPV2_STATE_COUNT
;
495 if (*count
== ARM_VFPV2_STATE_COUNT
)
500 state
= (struct arm_vfp_state
*) tstate
;
501 thread_state
= neon_state32(thread
->machine
.uNeon
);
502 /* ARM64 TODO: set fpsr and fpcr from state->fpscr */
504 bcopy(thread_state
, state
, (max
+ 1)*sizeof(uint32_t));
508 case ARM_NEON_STATE
:{
509 arm_neon_state_t
*state
;
510 arm_neon_saved_state32_t
*thread_state
;
512 if (*count
< ARM_NEON_STATE_COUNT
)
513 return (KERN_INVALID_ARGUMENT
);
515 if (thread_is_64bit_data(thread
))
516 return (KERN_INVALID_ARGUMENT
);
518 state
= (arm_neon_state_t
*)tstate
;
519 thread_state
= neon_state32(thread
->machine
.uNeon
);
521 assert(sizeof(*thread_state
) == sizeof(*state
));
522 bcopy(thread_state
, state
, sizeof(arm_neon_state_t
));
524 *count
= ARM_NEON_STATE_COUNT
;
529 case ARM_NEON_STATE64
:{
530 arm_neon_state64_t
*state
;
531 arm_neon_saved_state64_t
*thread_state
;
533 if (*count
< ARM_NEON_STATE64_COUNT
)
534 return (KERN_INVALID_ARGUMENT
);
536 if (!thread_is_64bit_data(thread
))
537 return (KERN_INVALID_ARGUMENT
);
539 state
= (arm_neon_state64_t
*)tstate
;
540 thread_state
= neon_state64(thread
->machine
.uNeon
);
542 /* For now, these are identical */
543 assert(sizeof(*state
) == sizeof(*thread_state
));
544 bcopy(thread_state
, state
, sizeof(arm_neon_state64_t
));
546 *count
= ARM_NEON_STATE64_COUNT
;
552 return (KERN_INVALID_ARGUMENT
);
554 return (KERN_SUCCESS
);
559 * Routine: machine_thread_get_kern_state
563 machine_thread_get_kern_state(
565 thread_flavor_t flavor
,
566 thread_state_t tstate
,
567 mach_msg_type_number_t
* count
)
570 * This works only for an interrupted kernel thread
572 if (thread
!= current_thread() || getCpuDatap()->cpu_int_state
== NULL
)
576 case ARM_THREAD_STATE
:
578 kern_return_t rn
= handle_get_arm_thread_state(tstate
, count
, getCpuDatap()->cpu_int_state
);
582 case ARM_THREAD_STATE32
:
584 kern_return_t rn
= handle_get_arm32_thread_state(tstate
, count
, getCpuDatap()->cpu_int_state
);
589 case ARM_THREAD_STATE64
:
591 kern_return_t rn
= handle_get_arm64_thread_state(tstate
, count
, getCpuDatap()->cpu_int_state
);
597 return (KERN_INVALID_ARGUMENT
);
599 return (KERN_SUCCESS
);
603 machine_thread_switch_addrmode(thread_t thread
)
605 if (task_has_64Bit_data(thread
->task
)) {
606 thread
->machine
.upcb
->ash
.flavor
= ARM_SAVED_STATE64
;
607 thread
->machine
.upcb
->ash
.count
= ARM_SAVED_STATE64_COUNT
;
608 thread
->machine
.uNeon
->nsh
.flavor
= ARM_NEON_SAVED_STATE64
;
609 thread
->machine
.uNeon
->nsh
.count
= ARM_NEON_SAVED_STATE64_COUNT
;
612 * Reinitialize the NEON state.
614 bzero(&thread
->machine
.uNeon
->uns
, sizeof(thread
->machine
.uNeon
->uns
));
615 thread
->machine
.uNeon
->ns_64
.fpcr
= FPCR_DEFAULT
;
617 thread
->machine
.upcb
->ash
.flavor
= ARM_SAVED_STATE32
;
618 thread
->machine
.upcb
->ash
.count
= ARM_SAVED_STATE32_COUNT
;
619 thread
->machine
.uNeon
->nsh
.flavor
= ARM_NEON_SAVED_STATE32
;
620 thread
->machine
.uNeon
->nsh
.count
= ARM_NEON_SAVED_STATE32_COUNT
;
623 * Reinitialize the NEON state.
625 bzero(&thread
->machine
.uNeon
->uns
, sizeof(thread
->machine
.uNeon
->uns
));
626 thread
->machine
.uNeon
->ns_32
.fpcr
= FPCR_DEFAULT_32
;
630 extern long long arm_debug_get(void);
633 * Routine: machine_thread_set_state
637 machine_thread_set_state(
639 thread_flavor_t flavor
,
640 thread_state_t tstate
,
641 mach_msg_type_number_t count
)
646 case ARM_THREAD_STATE
:
647 rn
= handle_set_arm_thread_state(tstate
, count
, thread
->machine
.upcb
);
651 case ARM_THREAD_STATE32
:
652 if (thread_is_64bit_data(thread
))
653 return (KERN_INVALID_ARGUMENT
);
655 rn
= handle_set_arm32_thread_state(tstate
, count
, thread
->machine
.upcb
);
660 case ARM_THREAD_STATE64
:
661 if (!thread_is_64bit_data(thread
))
662 return (KERN_INVALID_ARGUMENT
);
664 rn
= handle_set_arm64_thread_state(tstate
, count
, thread
->machine
.upcb
);
668 case ARM_EXCEPTION_STATE
:{
670 if (count
!= ARM_EXCEPTION_STATE_COUNT
)
671 return (KERN_INVALID_ARGUMENT
);
672 if (thread_is_64bit_data(thread
))
673 return (KERN_INVALID_ARGUMENT
);
677 case ARM_EXCEPTION_STATE64
:{
679 if (count
!= ARM_EXCEPTION_STATE64_COUNT
)
680 return (KERN_INVALID_ARGUMENT
);
681 if (!thread_is_64bit_data(thread
))
682 return (KERN_INVALID_ARGUMENT
);
686 case ARM_DEBUG_STATE
:
688 arm_legacy_debug_state_t
*state
;
689 boolean_t enabled
= FALSE
;
692 if (count
!= ARM_LEGACY_DEBUG_STATE_COUNT
)
693 return (KERN_INVALID_ARGUMENT
);
694 if (thread_is_64bit_data(thread
))
695 return (KERN_INVALID_ARGUMENT
);
697 state
= (arm_legacy_debug_state_t
*) tstate
;
699 for (i
= 0; i
< 16; i
++) {
700 /* do not allow context IDs to be set */
701 if (((state
->bcr
[i
] & ARM_DBGBCR_TYPE_MASK
) != ARM_DBGBCR_TYPE_IVA
)
702 || ((state
->bcr
[i
] & ARM_DBG_CR_LINKED_MASK
) != ARM_DBG_CR_LINKED_UNLINKED
)
703 || ((state
->wcr
[i
] & ARM_DBGBCR_TYPE_MASK
) != ARM_DBGBCR_TYPE_IVA
)
704 || ((state
->wcr
[i
] & ARM_DBG_CR_LINKED_MASK
) != ARM_DBG_CR_LINKED_UNLINKED
)) {
705 return KERN_PROTECTION_FAILURE
;
707 if ((((state
->bcr
[i
] & ARM_DBG_CR_ENABLE_MASK
) == ARM_DBG_CR_ENABLE_ENABLE
))
708 || ((state
->wcr
[i
] & ARM_DBG_CR_ENABLE_MASK
) == ARM_DBG_CR_ENABLE_ENABLE
)) {
715 arm_debug_state32_t
*thread_state
= find_debug_state32(thread
);
716 if (thread_state
!= NULL
) {
717 void *pTmp
= thread
->machine
.DebugData
;
718 thread
->machine
.DebugData
= NULL
;
719 zfree(ads_zone
, pTmp
);
722 arm_debug_state32_t
*thread_state
= find_debug_state32(thread
);
723 if (thread_state
== NULL
) {
724 thread
->machine
.DebugData
= zalloc(ads_zone
);
725 bzero(thread
->machine
.DebugData
, sizeof *(thread
->machine
.DebugData
));
726 thread
->machine
.DebugData
->dsh
.flavor
= ARM_DEBUG_STATE32
;
727 thread
->machine
.DebugData
->dsh
.count
= ARM_DEBUG_STATE32_COUNT
;
728 thread_state
= find_debug_state32(thread
);
730 assert(NULL
!= thread_state
);
732 for (i
= 0; i
< 16; i
++) {
733 /* set appropriate privilege; mask out unknown bits */
734 thread_state
->bcr
[i
] = (state
->bcr
[i
] & (ARM_DBG_CR_ADDRESS_MASK_MASK
735 | ARM_DBGBCR_MATCH_MASK
736 | ARM_DBG_CR_BYTE_ADDRESS_SELECT_MASK
737 | ARM_DBG_CR_ENABLE_MASK
))
738 | ARM_DBGBCR_TYPE_IVA
739 | ARM_DBG_CR_LINKED_UNLINKED
740 | ARM_DBG_CR_SECURITY_STATE_BOTH
741 | ARM_DBG_CR_MODE_CONTROL_USER
;
742 thread_state
->bvr
[i
] = state
->bvr
[i
] & ARM_DBG_VR_ADDRESS_MASK
;
743 thread_state
->wcr
[i
] = (state
->wcr
[i
] & (ARM_DBG_CR_ADDRESS_MASK_MASK
744 | ARM_DBGWCR_BYTE_ADDRESS_SELECT_MASK
745 | ARM_DBGWCR_ACCESS_CONTROL_MASK
746 | ARM_DBG_CR_ENABLE_MASK
))
747 | ARM_DBG_CR_LINKED_UNLINKED
748 | ARM_DBG_CR_SECURITY_STATE_BOTH
749 | ARM_DBG_CR_MODE_CONTROL_USER
;
750 thread_state
->wvr
[i
] = state
->wvr
[i
] & ARM_DBG_VR_ADDRESS_MASK
;
753 thread_state
->mdscr_el1
= 0ULL; // Legacy customers issuing ARM_DEBUG_STATE dont drive single stepping.
756 if (thread
== current_thread()) {
757 arm_debug_set32(thread
->machine
.DebugData
);
762 case ARM_DEBUG_STATE32
:
763 /* ARM64_TODO subtle bcr/wcr semantic differences e.g. wcr and ARM_DBGBCR_TYPE_IVA */
765 arm_debug_state32_t
*state
;
766 boolean_t enabled
= FALSE
;
769 if (count
!= ARM_DEBUG_STATE32_COUNT
)
770 return (KERN_INVALID_ARGUMENT
);
771 if (thread_is_64bit_data(thread
))
772 return (KERN_INVALID_ARGUMENT
);
774 state
= (arm_debug_state32_t
*) tstate
;
776 if (state
->mdscr_el1
& 0x1)
779 for (i
= 0; i
< 16; i
++) {
780 /* do not allow context IDs to be set */
781 if (((state
->bcr
[i
] & ARM_DBGBCR_TYPE_MASK
) != ARM_DBGBCR_TYPE_IVA
)
782 || ((state
->bcr
[i
] & ARM_DBG_CR_LINKED_MASK
) != ARM_DBG_CR_LINKED_UNLINKED
)
783 || ((state
->wcr
[i
] & ARM_DBGBCR_TYPE_MASK
) != ARM_DBGBCR_TYPE_IVA
)
784 || ((state
->wcr
[i
] & ARM_DBG_CR_LINKED_MASK
) != ARM_DBG_CR_LINKED_UNLINKED
)) {
785 return KERN_PROTECTION_FAILURE
;
787 if ((((state
->bcr
[i
] & ARM_DBG_CR_ENABLE_MASK
) == ARM_DBG_CR_ENABLE_ENABLE
))
788 || ((state
->wcr
[i
] & ARM_DBG_CR_ENABLE_MASK
) == ARM_DBG_CR_ENABLE_ENABLE
)) {
794 arm_debug_state32_t
*thread_state
= find_debug_state32(thread
);
795 if (thread_state
!= NULL
) {
796 void *pTmp
= thread
->machine
.DebugData
;
797 thread
->machine
.DebugData
= NULL
;
798 zfree(ads_zone
, pTmp
);
801 arm_debug_state32_t
*thread_state
= find_debug_state32(thread
);
802 if (thread_state
== NULL
) {
803 thread
->machine
.DebugData
= zalloc(ads_zone
);
804 bzero(thread
->machine
.DebugData
, sizeof *(thread
->machine
.DebugData
));
805 thread
->machine
.DebugData
->dsh
.flavor
= ARM_DEBUG_STATE32
;
806 thread
->machine
.DebugData
->dsh
.count
= ARM_DEBUG_STATE32_COUNT
;
807 thread_state
= find_debug_state32(thread
);
809 assert(NULL
!= thread_state
);
811 if (state
->mdscr_el1
& 0x1)
812 thread_state
->mdscr_el1
|= 0x1;
814 thread_state
->mdscr_el1
&= ~0x1;
816 for (i
= 0; i
< 16; i
++) {
817 /* set appropriate privilege; mask out unknown bits */
818 thread_state
->bcr
[i
] = (state
->bcr
[i
] & (ARM_DBG_CR_ADDRESS_MASK_MASK
819 | ARM_DBGBCR_MATCH_MASK
820 | ARM_DBG_CR_BYTE_ADDRESS_SELECT_MASK
821 | ARM_DBG_CR_ENABLE_MASK
))
822 | ARM_DBGBCR_TYPE_IVA
823 | ARM_DBG_CR_LINKED_UNLINKED
824 | ARM_DBG_CR_SECURITY_STATE_BOTH
825 | ARM_DBG_CR_MODE_CONTROL_USER
;
826 thread_state
->bvr
[i
] = state
->bvr
[i
] & ARM_DBG_VR_ADDRESS_MASK
;
827 thread_state
->wcr
[i
] = (state
->wcr
[i
] & (ARM_DBG_CR_ADDRESS_MASK_MASK
828 | ARM_DBGWCR_BYTE_ADDRESS_SELECT_MASK
829 | ARM_DBGWCR_ACCESS_CONTROL_MASK
830 | ARM_DBG_CR_ENABLE_MASK
))
831 | ARM_DBG_CR_LINKED_UNLINKED
832 | ARM_DBG_CR_SECURITY_STATE_BOTH
833 | ARM_DBG_CR_MODE_CONTROL_USER
;
834 thread_state
->wvr
[i
] = state
->wvr
[i
] & ARM_DBG_VR_ADDRESS_MASK
;
839 if (thread
== current_thread()) {
840 arm_debug_set32(thread
->machine
.DebugData
);
846 case ARM_DEBUG_STATE64
:
848 arm_debug_state64_t
*state
;
849 boolean_t enabled
= FALSE
;
852 if (count
!= ARM_DEBUG_STATE64_COUNT
)
853 return (KERN_INVALID_ARGUMENT
);
854 if (!thread_is_64bit_data(thread
))
855 return (KERN_INVALID_ARGUMENT
);
857 state
= (arm_debug_state64_t
*) tstate
;
859 if (state
->mdscr_el1
& 0x1)
862 for (i
= 0; i
< 16; i
++) {
863 /* do not allow context IDs to be set */
864 if (((state
->bcr
[i
] & ARM_DBGBCR_TYPE_MASK
) != ARM_DBGBCR_TYPE_IVA
)
865 || ((state
->bcr
[i
] & ARM_DBG_CR_LINKED_MASK
) != ARM_DBG_CR_LINKED_UNLINKED
)
866 || ((state
->wcr
[i
] & ARM_DBG_CR_LINKED_MASK
) != ARM_DBG_CR_LINKED_UNLINKED
)) {
867 return KERN_PROTECTION_FAILURE
;
869 if ((((state
->bcr
[i
] & ARM_DBG_CR_ENABLE_MASK
) == ARM_DBG_CR_ENABLE_ENABLE
))
870 || ((state
->wcr
[i
] & ARM_DBG_CR_ENABLE_MASK
) == ARM_DBG_CR_ENABLE_ENABLE
)) {
876 arm_debug_state64_t
*thread_state
= find_debug_state64(thread
);
877 if (thread_state
!= NULL
) {
878 void *pTmp
= thread
->machine
.DebugData
;
879 thread
->machine
.DebugData
= NULL
;
880 zfree(ads_zone
, pTmp
);
883 arm_debug_state64_t
*thread_state
= find_debug_state64(thread
);
884 if (thread_state
== NULL
) {
885 thread
->machine
.DebugData
= zalloc(ads_zone
);
886 bzero(thread
->machine
.DebugData
, sizeof *(thread
->machine
.DebugData
));
887 thread
->machine
.DebugData
->dsh
.flavor
= ARM_DEBUG_STATE64
;
888 thread
->machine
.DebugData
->dsh
.count
= ARM_DEBUG_STATE64_COUNT
;
889 thread_state
= find_debug_state64(thread
);
891 assert(NULL
!= thread_state
);
893 if (state
->mdscr_el1
& 0x1)
894 thread_state
->mdscr_el1
|= 0x1;
896 thread_state
->mdscr_el1
&= ~0x1;
898 for (i
= 0; i
< 16; i
++) {
899 /* set appropriate privilege; mask out unknown bits */
900 thread_state
->bcr
[i
] = (state
->bcr
[i
] & (0 /* Was ARM_DBG_CR_ADDRESS_MASK_MASK deprecated in v8 */
901 | 0 /* Was ARM_DBGBCR_MATCH_MASK, ignored in AArch64 state */
902 | ARM_DBG_CR_BYTE_ADDRESS_SELECT_MASK
903 | ARM_DBG_CR_ENABLE_MASK
))
904 | ARM_DBGBCR_TYPE_IVA
905 | ARM_DBG_CR_LINKED_UNLINKED
906 | ARM_DBG_CR_SECURITY_STATE_BOTH
907 | ARM_DBG_CR_MODE_CONTROL_USER
;
908 thread_state
->bvr
[i
] = state
->bvr
[i
] & ARM_DBG_VR_ADDRESS_MASK64
;
909 thread_state
->wcr
[i
] = (state
->wcr
[i
] & (ARM_DBG_CR_ADDRESS_MASK_MASK
910 | ARM_DBGWCR_BYTE_ADDRESS_SELECT_MASK
911 | ARM_DBGWCR_ACCESS_CONTROL_MASK
912 | ARM_DBG_CR_ENABLE_MASK
))
913 | ARM_DBG_CR_LINKED_UNLINKED
914 | ARM_DBG_CR_SECURITY_STATE_BOTH
915 | ARM_DBG_CR_MODE_CONTROL_USER
;
916 thread_state
->wvr
[i
] = state
->wvr
[i
] & ARM_DBG_VR_ADDRESS_MASK64
;
921 if (thread
== current_thread()) {
922 arm_debug_set64(thread
->machine
.DebugData
);
929 struct arm_vfp_state
*state
;
930 arm_neon_saved_state32_t
*thread_state
;
933 if (count
!= ARM_VFP_STATE_COUNT
&& count
!= ARM_VFPV2_STATE_COUNT
)
934 return (KERN_INVALID_ARGUMENT
);
936 if (count
== ARM_VFPV2_STATE_COUNT
)
941 state
= (struct arm_vfp_state
*) tstate
;
942 thread_state
= neon_state32(thread
->machine
.uNeon
);
943 /* ARM64 TODO: combine fpsr and fpcr into state->fpscr */
945 bcopy(state
, thread_state
, (max
+ 1)*sizeof(uint32_t));
947 thread
->machine
.uNeon
->nsh
.flavor
= ARM_NEON_SAVED_STATE32
;
948 thread
->machine
.uNeon
->nsh
.count
= ARM_NEON_SAVED_STATE32_COUNT
;
952 case ARM_NEON_STATE
:{
953 arm_neon_state_t
*state
;
954 arm_neon_saved_state32_t
*thread_state
;
956 if (count
!= ARM_NEON_STATE_COUNT
)
957 return (KERN_INVALID_ARGUMENT
);
959 if (thread_is_64bit_data(thread
))
960 return (KERN_INVALID_ARGUMENT
);
962 state
= (arm_neon_state_t
*)tstate
;
963 thread_state
= neon_state32(thread
->machine
.uNeon
);
965 assert(sizeof(*state
) == sizeof(*thread_state
));
966 bcopy(state
, thread_state
, sizeof(arm_neon_state_t
));
968 thread
->machine
.uNeon
->nsh
.flavor
= ARM_NEON_SAVED_STATE32
;
969 thread
->machine
.uNeon
->nsh
.count
= ARM_NEON_SAVED_STATE32_COUNT
;
974 case ARM_NEON_STATE64
:{
975 arm_neon_state64_t
*state
;
976 arm_neon_saved_state64_t
*thread_state
;
978 if (count
!= ARM_NEON_STATE64_COUNT
)
979 return (KERN_INVALID_ARGUMENT
);
981 if (!thread_is_64bit_data(thread
))
982 return (KERN_INVALID_ARGUMENT
);
984 state
= (arm_neon_state64_t
*)tstate
;
985 thread_state
= neon_state64(thread
->machine
.uNeon
);
987 assert(sizeof(*state
) == sizeof(*thread_state
));
988 bcopy(state
, thread_state
, sizeof(arm_neon_state64_t
));
990 thread
->machine
.uNeon
->nsh
.flavor
= ARM_NEON_SAVED_STATE64
;
991 thread
->machine
.uNeon
->nsh
.count
= ARM_NEON_SAVED_STATE64_COUNT
;
997 return (KERN_INVALID_ARGUMENT
);
999 return (KERN_SUCCESS
);
1003 * Routine: machine_thread_state_initialize
1007 machine_thread_state_initialize(
1010 arm_context_t
*context
= thread
->machine
.contextData
;
1013 * Should always be set up later. For a kernel thread, we don't care
1014 * about this state. For a user thread, we'll set the state up in
1015 * setup_wqthread, bsdthread_create, load_main(), or load_unixthread().
1018 if (context
!= NULL
) {
1019 bzero(&context
->ss
.uss
, sizeof(context
->ss
.uss
));
1020 bzero(&context
->ns
.uns
, sizeof(context
->ns
.uns
));
1022 if (context
->ns
.nsh
.flavor
== ARM_NEON_SAVED_STATE64
) {
1023 context
->ns
.ns_64
.fpcr
= FPCR_DEFAULT
;
1025 context
->ns
.ns_32
.fpcr
= FPCR_DEFAULT_32
;
1029 thread
->machine
.DebugData
= NULL
;
1032 return KERN_SUCCESS
;
1036 * Routine: machine_thread_dup
1043 __unused boolean_t is_corpse
)
1045 struct arm_saved_state
*self_saved_state
;
1046 struct arm_saved_state
*target_saved_state
;
1048 target
->machine
.cthread_self
= self
->machine
.cthread_self
;
1049 target
->machine
.cthread_data
= self
->machine
.cthread_data
;
1051 self_saved_state
= self
->machine
.upcb
;
1052 target_saved_state
= target
->machine
.upcb
;
1053 bcopy(self_saved_state
, target_saved_state
, sizeof(struct arm_saved_state
));
1055 return (KERN_SUCCESS
);
1059 * Routine: get_user_regs
1062 struct arm_saved_state
*
1066 return (thread
->machine
.upcb
);
1069 arm_neon_saved_state_t
*
1073 return (thread
->machine
.uNeon
);
1077 * Routine: find_user_regs
1080 struct arm_saved_state
*
1084 return (thread
->machine
.upcb
);
1088 * Routine: find_kern_regs
1091 struct arm_saved_state
*
1096 * This works only for an interrupted kernel thread
1098 if (thread
!= current_thread() || getCpuDatap()->cpu_int_state
== NULL
)
1099 return ((struct arm_saved_state
*) NULL
);
1101 return (getCpuDatap()->cpu_int_state
);
1105 arm_debug_state32_t
*
1109 if (thread
&& thread
->machine
.DebugData
)
1110 return &(thread
->machine
.DebugData
->uds
.ds32
);
1115 arm_debug_state64_t
*
1119 if (thread
&& thread
->machine
.DebugData
)
1120 return &(thread
->machine
.DebugData
->uds
.ds64
);
1126 * Routine: thread_userstack
1131 __unused thread_t thread
,
1133 thread_state_t tstate
,
1135 mach_vm_offset_t
* user_stack
,
1137 boolean_t is_64bit_data
1143 case ARM_THREAD_STATE
:
1144 if (count
== ARM_UNIFIED_THREAD_STATE_COUNT
) {
1146 if (is_64bit_data
) {
1147 sp
= ((arm_unified_thread_state_t
*)tstate
)->ts_64
.sp
;
1151 sp
= ((arm_unified_thread_state_t
*)tstate
)->ts_32
.sp
;
1157 /* INTENTIONAL FALL THROUGH (see machine_thread_set_state) */
1158 case ARM_THREAD_STATE32
:
1159 if (count
!= ARM_THREAD_STATE32_COUNT
)
1160 return (KERN_INVALID_ARGUMENT
);
1162 return (KERN_INVALID_ARGUMENT
);
1164 sp
= ((arm_thread_state32_t
*)tstate
)->sp
;
1167 case ARM_THREAD_STATE64
:
1168 if (count
!= ARM_THREAD_STATE64_COUNT
)
1169 return (KERN_INVALID_ARGUMENT
);
1171 return (KERN_INVALID_ARGUMENT
);
1173 sp
= ((arm_thread_state32_t
*)tstate
)->sp
;
1177 return (KERN_INVALID_ARGUMENT
);
1181 *user_stack
= CAST_USER_ADDR_T(sp
);
1185 *user_stack
= CAST_USER_ADDR_T(USRSTACK64
);
1190 return (KERN_SUCCESS
);
1194 * thread_userstackdefault:
1196 * Return the default stack location for the
1197 * thread, if otherwise unknown.
1200 thread_userstackdefault(
1201 mach_vm_offset_t
*default_user_stack
,
1205 *default_user_stack
= USRSTACK64
;
1207 *default_user_stack
= USRSTACK
;
1210 return (KERN_SUCCESS
);
1214 * Routine: thread_setuserstack
1218 thread_setuserstack(thread_t thread
, mach_vm_address_t user_stack
)
1220 struct arm_saved_state
*sv
;
1222 sv
= get_user_regs(thread
);
1224 set_saved_state_sp(sv
, user_stack
);
1230 * Routine: thread_adjuserstack
1234 thread_adjuserstack(thread_t thread
, int adjust
)
1236 struct arm_saved_state
*sv
;
1239 sv
= get_user_regs(thread
);
1241 sp
= get_saved_state_sp(sv
);
1243 set_saved_state_sp(sv
, sp
);;
1249 * Routine: thread_setentrypoint
1253 thread_setentrypoint(thread_t thread
, mach_vm_offset_t entry
)
1255 struct arm_saved_state
*sv
;
1257 sv
= get_user_regs(thread
);
1259 set_saved_state_pc(sv
, entry
);
1265 * Routine: thread_entrypoint
1270 __unused thread_t thread
,
1272 thread_state_t tstate
,
1273 unsigned int count __unused
,
1274 mach_vm_offset_t
* entry_point
1278 case ARM_THREAD_STATE
:
1280 struct arm_thread_state
*state
;
1282 state
= (struct arm_thread_state
*) tstate
;
1285 * If a valid entry point is specified, use it.
1288 *entry_point
= CAST_USER_ADDR_T(state
->pc
);
1290 *entry_point
= CAST_USER_ADDR_T(VM_MIN_ADDRESS
);
1295 case ARM_THREAD_STATE64
:
1297 struct arm_thread_state64
*state
;
1299 state
= (struct arm_thread_state64
*) tstate
;
1302 * If a valid entry point is specified, use it.
1305 *entry_point
= CAST_USER_ADDR_T(state
->pc
);
1307 *entry_point
= CAST_USER_ADDR_T(VM_MIN_ADDRESS
);
1313 return (KERN_INVALID_ARGUMENT
);
1316 return (KERN_SUCCESS
);
1321 * Routine: thread_set_child
1329 struct arm_saved_state
*child_state
;
1331 child_state
= get_user_regs(child
);
1333 set_saved_state_reg(child_state
, 0, pid
);
1334 set_saved_state_reg(child_state
, 1, 1ULL);
1339 * Routine: thread_set_parent
1347 struct arm_saved_state
*parent_state
;
1349 parent_state
= get_user_regs(parent
);
1351 set_saved_state_reg(parent_state
, 0, pid
);
1352 set_saved_state_reg(parent_state
, 1, 0);
1356 struct arm_act_context
{
1357 struct arm_unified_thread_state ss
;
1359 struct arm_neon_saved_state ns
;
1364 * Routine: act_thread_csave
1368 act_thread_csave(void)
1370 struct arm_act_context
*ic
;
1373 thread_t thread
= current_thread();
1375 ic
= (struct arm_act_context
*) kalloc(sizeof(struct arm_act_context
));
1376 if (ic
== (struct arm_act_context
*) NULL
)
1377 return ((void *) 0);
1379 val
= ARM_UNIFIED_THREAD_STATE_COUNT
;
1380 kret
= machine_thread_get_state(thread
, ARM_THREAD_STATE
, (thread_state_t
)&ic
->ss
, &val
);
1381 if (kret
!= KERN_SUCCESS
) {
1382 kfree(ic
, sizeof(struct arm_act_context
));
1383 return ((void *) 0);
1387 if (thread_is_64bit_data(thread
)) {
1388 val
= ARM_NEON_STATE64_COUNT
;
1389 kret
= machine_thread_get_state(thread
,
1391 (thread_state_t
) & ic
->ns
,
1394 val
= ARM_NEON_STATE_COUNT
;
1395 kret
= machine_thread_get_state(thread
,
1397 (thread_state_t
) & ic
->ns
,
1400 if (kret
!= KERN_SUCCESS
) {
1401 kfree(ic
, sizeof(struct arm_act_context
));
1402 return ((void *) 0);
1409 * Routine: act_thread_catt
1413 act_thread_catt(void *ctx
)
1415 struct arm_act_context
*ic
;
1417 thread_t thread
= current_thread();
1419 ic
= (struct arm_act_context
*) ctx
;
1420 if (ic
== (struct arm_act_context
*) NULL
)
1423 kret
= machine_thread_set_state(thread
, ARM_THREAD_STATE
, (thread_state_t
)&ic
->ss
, ARM_UNIFIED_THREAD_STATE_COUNT
);
1424 if (kret
!= KERN_SUCCESS
)
1428 if (thread_is_64bit_data(thread
)) {
1429 kret
= machine_thread_set_state(thread
,
1431 (thread_state_t
) & ic
->ns
,
1432 ARM_NEON_STATE64_COUNT
);
1434 kret
= machine_thread_set_state(thread
,
1436 (thread_state_t
) & ic
->ns
,
1437 ARM_NEON_STATE_COUNT
);
1439 if (kret
!= KERN_SUCCESS
)
1443 kfree(ic
, sizeof(struct arm_act_context
));
1447 * Routine: act_thread_catt
1451 act_thread_cfree(void *ctx
)
1453 kfree(ctx
, sizeof(struct arm_act_context
));
1457 thread_set_wq_state32(thread_t thread
, thread_state_t tstate
)
1459 arm_thread_state_t
*state
;
1460 struct arm_saved_state
*saved_state
;
1461 struct arm_saved_state32
*saved_state_32
;
1462 thread_t curth
= current_thread();
1465 assert(!thread_is_64bit_data(thread
));
1467 saved_state
= thread
->machine
.upcb
;
1468 saved_state_32
= saved_state32(saved_state
);
1470 state
= (arm_thread_state_t
*)tstate
;
1472 if (curth
!= thread
) {
1474 thread_lock(thread
);
1478 * do not zero saved_state, it can be concurrently accessed
1479 * and zero is not a valid state for some of the registers,
1482 thread_state32_to_saved_state(state
, saved_state
);
1483 saved_state_32
->cpsr
= PSR64_USER32_DEFAULT
;
1485 if (curth
!= thread
) {
1486 thread_unlock(thread
);
1490 return KERN_SUCCESS
;
1494 thread_set_wq_state64(thread_t thread
, thread_state_t tstate
)
1496 arm_thread_state64_t
*state
;
1497 struct arm_saved_state
*saved_state
;
1498 struct arm_saved_state64
*saved_state_64
;
1499 thread_t curth
= current_thread();
1502 assert(thread_is_64bit_data(thread
));
1504 saved_state
= thread
->machine
.upcb
;
1505 saved_state_64
= saved_state64(saved_state
);
1506 state
= (arm_thread_state64_t
*)tstate
;
1508 if (curth
!= thread
) {
1510 thread_lock(thread
);
1514 * do not zero saved_state, it can be concurrently accessed
1515 * and zero is not a valid state for some of the registers,
1518 thread_state64_to_saved_state(state
, saved_state
);
1519 set_saved_state_cpsr(saved_state
, PSR64_USER64_DEFAULT
);
1521 if (curth
!= thread
) {
1522 thread_unlock(thread
);
1526 return KERN_SUCCESS
;