1 /* 2 * Copyright (c) 2007-2023 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 33 #ifndef ARM_CPU_DATA_INTERNAL 34 #define ARM_CPU_DATA_INTERNAL 35 36 #include <mach_assert.h> 37 #include <kern/assert.h> 38 #include <kern/kern_types.h> 39 #include <kern/percpu.h> 40 #include <kern/processor.h> 41 #include <os/base.h> 42 #include <pexpert/pexpert.h> 43 #include <arm/dbgwrap.h> 44 #include <arm/machine_routines.h> 45 #include <arm64/proc_reg.h> 46 #include <arm/thread.h> 47 #include <arm/pmap.h> 48 #include <machine/monotonic.h> 49 #include <san/kcov_data.h> 50 51 #define NSEC_PER_HZ (NSEC_PER_SEC / 100) 52 53 typedef struct reset_handler_data { 54 vm_offset_t assist_reset_handler; /* Assist handler phys address */ 55 vm_offset_t cpu_data_entries; /* CpuDataEntries phys address */ 56 } reset_handler_data_t; 57 58 #if !CONFIG_SPTM 59 extern reset_handler_data_t ResetHandlerData; 60 #endif 61 62 /* Put the static check for cpumap_t here as it's defined in <kern/processor.h> */ 63 static_assert(sizeof(cpumap_t) * CHAR_BIT >= MAX_CPUS, "cpumap_t bitvector is too small for current MAX_CPUS value"); 64 65 #define CPUWINDOWS_BASE_MASK 0xFFFFFFFFFFD00000UL 66 #define CPUWINDOWS_BASE (VM_MAX_KERNEL_ADDRESS & CPUWINDOWS_BASE_MASK) 67 #define CPUWINDOWS_TOP (CPUWINDOWS_BASE + (MAX_CPUS * CPUWINDOWS_MAX * ARM_PGBYTES)) 68 69 static_assert((CPUWINDOWS_BASE >= VM_MIN_KERNEL_ADDRESS) && ((CPUWINDOWS_TOP - 1) <= VM_MAX_KERNEL_ADDRESS), 70 "CPU copy windows too large for CPUWINDOWS_BASE_MASK value"); 71 72 typedef struct cpu_data_entry { 73 void *cpu_data_paddr; /* Cpu data physical address */ 74 struct cpu_data *cpu_data_vaddr; /* Cpu data virtual address */ 75 #if !defined(__arm64__) 76 #error Check cpu_data_entry padding for this architecture 77 #endif 78 } cpu_data_entry_t; 79 80 81 typedef struct rtclock_timer { 82 mpqueue_head_t queue; 83 uint64_t deadline; 84 uint32_t is_set:1, 85 has_expired:1, 86 :0; 87 } rtclock_timer_t; 88 89 typedef struct { 90 /* 91 * The wake variants of these counters are reset to 0 when the CPU wakes. 92 */ 93 uint64_t irq_ex_cnt; 94 uint64_t irq_ex_cnt_wake; 95 uint64_t ipi_cnt; 96 uint64_t ipi_cnt_wake; 97 uint64_t timer_cnt; 98 #if CONFIG_CPU_COUNTERS 99 uint64_t pmi_cnt_wake; 100 #endif /* CONFIG_CPU_COUNTERS */ 101 uint64_t undef_ex_cnt; 102 uint64_t unaligned_cnt; 103 uint64_t vfp_cnt; 104 uint64_t data_ex_cnt; 105 uint64_t instr_ex_cnt; 106 } cpu_stat_t; 107 108 __options_closed_decl(cpu_flags_t, uint16_t, { 109 SleepState = 0x0800, 110 /* For the boot processor, StartedState means 'interrupts initialized' - it is already running */ 111 StartedState = 0x1000, 112 /* For the boot processor, InitState means 'cpu_data fully initialized' - it is already running */ 113 InitState = 0x2000, 114 }); 115 116 __options_closed_decl(cpu_signal_t, unsigned int, { 117 SIGPnop = 0x00000000U, /* Send IPI with no service */ 118 /* 0x1U unused */ 119 /* 0x2U unused */ 120 SIGPxcall = 0x00000004U, /* Call a function on a processor */ 121 SIGPast = 0x00000008U, /* Request AST check */ 122 SIGPdebug = 0x00000010U, /* Request Debug call */ 123 SIGPLWFlush = 0x00000020U, /* Request LWFlush call */ 124 SIGPLWClean = 0x00000040U, /* Request LWClean call */ 125 /* 0x80U unused */ 126 SIGPkppet = 0x00000100U, /* Request kperf PET handler */ 127 SIGPxcallImm = 0x00000200U, /* Send a cross-call, fail if already pending */ 128 SIGPTimerLocal = 0x00000400U, /* Update the decrementer via timer_queue_expire_local */ 129 SIGPdeferred = 0x00000800U, /* Scheduler deferred IPI to wake core */ 130 131 SIGPdisabled = 0x80000000U, /* Signal disabled */ 132 }); 133 134 typedef struct cpu_data { 135 unsigned short cpu_number; 136 _Atomic cpu_flags_t cpu_flags; 137 int cpu_type; 138 int cpu_subtype; 139 int cpu_threadtype; 140 141 void * XNU_PTRAUTH_SIGNED_PTR("cpu_data.istackptr") istackptr; 142 vm_offset_t intstack_top; 143 #if __arm64__ 144 void * XNU_PTRAUTH_SIGNED_PTR("cpu_data.excepstackptr") excepstackptr; 145 vm_offset_t excepstack_top; 146 #endif 147 thread_t cpu_active_thread; 148 vm_offset_t cpu_active_stack; 149 cpu_id_t cpu_id; 150 volatile cpu_signal_t cpu_signal; 151 ast_t cpu_pending_ast; 152 cache_dispatch_t cpu_cache_dispatch; 153 154 #if __arm64__ 155 uint64_t cpu_base_timebase; 156 uint64_t cpu_timebase; 157 #endif 158 bool cpu_hibernate; /* This cpu is currently hibernating the system */ 159 bool cpu_running; 160 bool cluster_master; 161 bool sync_on_cswitch; 162 /* true if processor_start() or processor_exit() is operating on this CPU */ 163 bool in_state_transition; 164 165 uint32_t cpu_decrementer; 166 get_decrementer_t cpu_get_decrementer_func; 167 set_decrementer_t cpu_set_decrementer_func; 168 fiq_handler_t cpu_get_fiq_handler; 169 170 void *cpu_tbd_hardware_addr; 171 void *cpu_tbd_hardware_val; 172 173 processor_idle_t cpu_idle_notify; 174 uint64_t cpu_idle_latency; 175 uint64_t cpu_idle_pop; 176 177 #if __ARM_KERNEL_PROTECT__ 178 vm_offset_t cpu_exc_vectors; 179 #endif /* __ARM_KERNEL_PROTECT__ */ 180 vm_offset_t cpu_reset_handler; 181 uintptr_t cpu_reset_assist; 182 uint32_t cpu_reset_type; 183 184 unsigned int interrupt_source; 185 void *cpu_int_state; 186 IOInterruptHandler interrupt_handler; 187 void *interrupt_nub; 188 void *interrupt_target; 189 void *interrupt_refCon; 190 191 idle_timer_t idle_timer_notify; 192 void *idle_timer_refcon; 193 uint64_t idle_timer_deadline; 194 195 uint64_t rtcPop; 196 rtclock_timer_t rtclock_timer; 197 struct _rtclock_data_ *rtclock_datap; 198 199 arm_debug_state_t *cpu_user_debug; /* Current debug state */ 200 vm_offset_t cpu_debug_interface_map; 201 202 volatile int debugger_active; 203 volatile int PAB_active; /* Tells the console if we are dumping backtraces */ 204 205 void *cpu_xcall_p0; 206 void *cpu_xcall_p1; 207 void *cpu_imm_xcall_p0; 208 void *cpu_imm_xcall_p1; 209 210 211 #if __arm64__ 212 vm_offset_t coresight_base[CORESIGHT_REGIONS]; 213 #endif 214 215 216 /* CCC ARMv8 registers */ 217 uint64_t cpu_regmap_paddr; 218 219 uint32_t cpu_phys_id; 220 platform_error_handler_t platform_error_handler; 221 222 int cpu_mcount_off; 223 224 #define ARM_CPU_ON_SLEEP_PATH 0x50535553UL 225 volatile unsigned int cpu_sleep_token; 226 unsigned int cpu_sleep_token_last; 227 228 cluster_type_t cpu_cluster_type; 229 uint32_t cpu_cluster_id; 230 uint32_t cpu_l2_id; 231 uint32_t cpu_l2_size; 232 uint32_t cpu_l3_id; 233 uint32_t cpu_l3_size; 234 235 enum { 236 CPU_NOT_HALTED = 0, 237 CPU_HALTED, 238 CPU_HALTED_WITH_STATE 239 } halt_status; 240 #if defined(HAS_APPLE_PAC) 241 uint64_t rop_key; 242 uint64_t jop_key; 243 #endif /* defined(HAS_APPLE_PAC) */ 244 245 /* large structs with large alignment requirements */ 246 247 /* double-buffered performance counter data */ 248 uint64_t *cpu_kpc_buf[2]; 249 /* PMC shadow and reload value buffers */ 250 uint64_t *cpu_kpc_shadow; 251 uint64_t *cpu_kpc_reload; 252 253 #if CONFIG_CPU_COUNTERS 254 struct mt_cpu cpu_monotonic; 255 #endif /* CONFIG_CPU_COUNTERS */ 256 257 cpu_stat_t cpu_stat; 258 #if !XNU_MONITOR 259 struct pmap_cpu_data cpu_pmap_cpu_data; 260 #endif 261 dbgwrap_thread_state_t halt_state; 262 #if DEVELOPMENT || DEBUG 263 uint64_t wfe_count; 264 uint64_t wfe_deadline_checks; 265 uint64_t wfe_terminations; 266 #endif 267 #if CONFIG_KCOV 268 kcov_cpu_data_t cpu_kcov_data; 269 #endif 270 #if __arm64__ 271 /** 272 * Stash the state of the system when an IPI is received. This will be 273 * dumped in the case a panic is getting triggered. 274 */ 275 uint64_t ipi_pc; 276 uint64_t ipi_lr; 277 uint64_t ipi_fp; 278 279 /* Encoded data to store in TPIDR_EL0 on context switch */ 280 uint64_t cpu_tpidr_el0; 281 #endif 282 283 #ifdef APPLEEVEREST 284 /* PAs used to apply pio locks in early boot. */ 285 uint64_t cpu_reg_paddr; 286 uint64_t acc_reg_paddr; 287 uint64_t cpm_reg_paddr; 288 #endif 289 290 } cpu_data_t; 291 292 extern cpu_data_entry_t CpuDataEntries[MAX_CPUS]; 293 PERCPU_DECL(cpu_data_t, cpu_data); 294 #define BootCpuData __PERCPU_NAME(cpu_data) 295 extern boot_args *BootArgs; 296 297 #if __arm64__ 298 extern unsigned int LowResetVectorBase; 299 extern unsigned int LowResetVectorEnd; 300 #if WITH_CLASSIC_S2R 301 extern uint8_t SleepToken[8]; 302 #endif 303 extern unsigned int LowExceptionVectorBase; 304 #else 305 #error Unknown arch 306 #endif 307 308 extern cpu_data_t *cpu_datap(int cpu); 309 extern cpu_data_t *cpu_data_alloc(boolean_t is_boot); 310 extern void cpu_stack_alloc(cpu_data_t*); 311 extern void cpu_data_init(cpu_data_t *cpu_data_ptr); 312 extern void cpu_data_register(cpu_data_t *cpu_data_ptr); 313 extern cpu_data_t *processor_to_cpu_datap( processor_t processor); 314 315 #if __arm64__ 316 typedef struct sysreg_restore { 317 uint64_t tcr_el1; 318 } sysreg_restore_t; 319 320 extern sysreg_restore_t sysreg_restore; 321 #endif /* __arm64__ */ 322 323 #endif /* ARM_CPU_DATA_INTERNAL */ 324