1 /* 2 * Copyright (c) 2007-2021 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 /* 29 * @OSF_COPYRIGHT@ 30 */ 31 32 #ifndef _ARM_MISC_PROTOS_H_ 33 #define _ARM_MISC_PROTOS_H_ 34 35 #include <kern/kern_types.h> 36 #include <arm/cpu_capabilities_public.h> 37 38 typedef struct boot_args boot_args; 39 /* The address of the end of the kernelcache. */ 40 extern vm_offset_t end_kern; 41 /* The lowest address in the kernelcache. */ 42 extern vm_offset_t segLOWEST; 43 44 45 extern void machine_startup(__unused boot_args *args) __attribute__((noinline)); 46 47 48 extern void arm_auxkc_init(void *mh, void *base); 49 50 extern void arm_vm_init(uint64_t memory_size, boot_args *args); 51 extern void arm_vm_prot_init(boot_args *args); 52 extern void arm_vm_prot_finalize(boot_args *args); 53 54 #if __arm64__ 55 void __attribute__((__noreturn__)) _was_in_userspace(void); 56 #endif /* __arm64__ */ 57 58 extern kern_return_t DebuggerXCallEnter(boolean_t, bool); 59 extern void DebuggerXCallReturn(void); 60 61 #if __arm64__ && DEBUG 62 extern void dump_kva_space(void); 63 #endif /* __arm64__ && DEBUG */ 64 65 extern void Load_context(thread_t); 66 extern void Idle_load_context(void) __attribute__((noreturn)); 67 extern thread_t Switch_context(thread_t, thread_continue_t, thread_t); 68 extern thread_t Shutdown_context(void (*doshutdown)(processor_t), processor_t processor); 69 extern void __dead2 Call_continuation(thread_continue_t, void *, wait_result_t, boolean_t enable_interrupts); 70 71 72 typedef enum { 73 ARM_SME_UNSUPPORTED = 0, 74 ARM_FEAT_SME, 75 ARM_FEAT_SME2, 76 ARM_SME_VERSION_MAX, 77 } arm_sme_version_t; 78 79 extern arm_sme_version_t arm_sme_version(void) __pure2; 80 #if HAS_ARM_FEAT_SME 81 extern void arm_sme_init(bool is_boot_cpu); 82 extern uint16_t arm_sme_svl_b(void); 83 extern void arm_save_sme_za(arm_sme_context_t *sme_ss, uint16_t svl_b); 84 extern void arm_load_sme_za(const arm_sme_context_t *sme_ss, uint16_t svl_b); 85 extern void arm_sme_trap_at_el0(bool trap_enabled); 86 extern boolean_t arm_sme_is_active(void); 87 #if HAS_ARM_FEAT_SME2 88 extern void arm_save_sme_zt0(arm_sme_context_t *sme_ss); 89 extern void arm_load_sme_zt0(const arm_sme_context_t *sme_ss); 90 #endif /* HAS_ARM_FEAT_SME2 */ 91 extern void arm_save_sme_za_zt0(arm_sme_context_t *sme_ss, uint16_t svl_b); 92 extern void arm_load_sme_za_zt0(const arm_sme_context_t *sme_ss, uint16_t svl_b); 93 #endif /* HAS_ARM_FEAT_SME */ 94 95 struct arm_matrix_cpu_state { 96 #if HAS_ARM_FEAT_SME 97 bool have_sme; 98 bool za_is_enabled; 99 bool sm_is_enabled; 100 #endif 101 }; 102 103 extern void arm_get_matrix_cpu_state(struct arm_matrix_cpu_state *cpu_state); 104 105 /** 106 * Indicate during a context-switch event that we have updated some CPU 107 * state which requires a later context-sync event. 108 * 109 * Sets a per-CPU flag indicating the processor context needs synchronizing. 110 * This is done to defer synchronization until returning from an exception. If 111 * synchronization is needed before that, call arm_context_switch_sync(). 112 */ 113 extern void arm_context_switch_requires_sync(void); 114 115 /** 116 * Synchronize context switch state immediately. Clears the dirty flag used by 117 * arm_context_switch_requires_sync(). If the context switch state has already 118 * been synchronized, does nothing. 119 */ 120 extern void arm_context_switch_sync(void); 121 122 #if __has_feature(ptrauth_calls) 123 extern boolean_t arm_user_jop_disabled(void); 124 #endif /* __has_feature(ptrauth_calls) */ 125 126 extern void DebuggerCall(unsigned int reason, void *ctx); 127 extern void DebuggerXCall(void *ctx); 128 129 extern int copyout_kern(const char *kernel_addr, user_addr_t user_addr, vm_size_t nbytes); 130 extern int copyin_kern(const user_addr_t user_addr, char *kernel_addr, vm_size_t nbytes); 131 132 extern void bcopy_phys(addr64_t from, addr64_t to, vm_size_t nbytes); 133 extern void bcopy_phys_with_options(addr64_t from, addr64_t to, vm_size_t nbytes, int options); 134 135 extern void dcache_incoherent_io_flush64(addr64_t pa, unsigned int count, unsigned int remaining, unsigned int *res); 136 extern void dcache_incoherent_io_store64(addr64_t pa, unsigned int count, unsigned int remaining, unsigned int *res); 137 138 #if defined(__arm64__) 139 extern void copy_legacy_debug_state(arm_legacy_debug_state_t * src, arm_legacy_debug_state_t *target, __unused boolean_t all); 140 extern void copy_debug_state32(arm_debug_state32_t * src, arm_debug_state32_t *target, __unused boolean_t all); 141 extern void copy_debug_state64(arm_debug_state64_t * src, arm_debug_state64_t *target, __unused boolean_t all); 142 143 extern boolean_t debug_legacy_state_is_valid(arm_legacy_debug_state_t *ds); 144 extern boolean_t debug_state_is_valid32(arm_debug_state32_t *ds); 145 extern boolean_t debug_state_is_valid64(arm_debug_state64_t *ds); 146 147 extern int copyio_check_user_addr(user_addr_t user_addr, vm_size_t nbytes); 148 149 /* 150 * Get a quick virtual mapping of a physical page and run a callback on that 151 * page's virtual address. 152 */ 153 extern int apply_func_phys(addr64_t src64, vm_size_t bytes, int (*func)(void * buffer, vm_size_t bytes, void * arg), void * arg); 154 155 #else /* !defined(__arm64__) */ 156 #error Unknown architecture. 157 #endif /* defined(__arm64__) */ 158 159 #endif /* _ARM_MISC_PROTOS_H_ */ 160