2  * Copyright (c) 2000-2012 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 <i386/machine_routines.h> 
  30 #include <i386/io_map_entries.h> 
  31 #include <i386/cpuid.h> 
  33 #include <mach/processor.h> 
  34 #include <kern/processor.h> 
  35 #include <kern/machine.h> 
  37 #include <kern/cpu_number.h> 
  38 #include <kern/thread.h> 
  39 #include <kern/thread_call.h> 
  40 #include <kern/policy_internal.h> 
  42 #include <prng/random.h> 
  43 #include <i386/machine_cpu.h> 
  44 #include <i386/lapic.h> 
  45 #include <i386/bit_routines.h> 
  46 #include <i386/mp_events.h> 
  47 #include <i386/pmCPU.h> 
  48 #include <i386/trap.h> 
  50 #include <i386/cpu_threads.h> 
  51 #include <i386/proc_reg.h> 
  52 #include <mach/vm_param.h> 
  53 #include <i386/pmap.h> 
  54 #include <i386/pmap_internal.h> 
  55 #include <i386/misc_protos.h> 
  56 #include <kern/timer_queue.h> 
  60 #include <architecture/i386/pio.h> 
  61 #include <i386/cpu_data.h> 
  63 #define DBG(x...)       kprintf("DBG: " x) 
  69 #include <kern/monotonic.h> 
  70 #endif /* MONOTONIC */ 
  72 extern void     wakeup(void *); 
  74 static int max_cpus_initialized 
= 0; 
  78 uint64_t        LockTimeOutTSC
; 
  79 uint32_t        LockTimeOutUsec
; 
  81 uint64_t        LastDebuggerEntryAllowance
; 
  82 uint64_t        delay_spin_threshold
; 
  84 extern uint64_t panic_restart_timeout
; 
  86 boolean_t virtualized 
= FALSE
; 
  88 decl_simple_lock_data(static,  ml_timer_evaluation_slock
); 
  89 uint32_t ml_timer_eager_evaluations
; 
  90 uint64_t ml_timer_eager_evaluation_max
; 
  91 static boolean_t ml_timer_evaluation_in_progress 
= FALSE
; 
  94 #define MAX_CPUS_SET    0x1 
  95 #define MAX_CPUS_WAIT   0x2 
  97 /* IO memory map services */ 
  99 /* Map memory map IO space */ 
 100 vm_offset_t 
ml_io_map( 
 101         vm_offset_t phys_addr
,  
 104         return(io_map(phys_addr
,size
,VM_WIMG_IO
)); 
 107 /* boot memory allocation */ 
 108 vm_offset_t 
ml_static_malloc( 
 109                              __unused vm_size_t size
) 
 111         return((vm_offset_t
)NULL
); 
 115 void ml_get_bouncepool_info(vm_offset_t 
*phys_addr
, vm_size_t 
*size
) 
 126 #if defined(__x86_64__) 
 127         return (vm_offset_t
)(((unsigned long) paddr
) | VM_MIN_KERNEL_ADDRESS
); 
 129         return (vm_offset_t
)((paddr
) | LINEAR_KERNEL_ADDRESS
); 
 135  *      Routine:        ml_static_mfree 
 145         uint32_t freed_pages 
= 0; 
 146         assert(vaddr 
>= VM_MIN_KERNEL_ADDRESS
); 
 148         assert((vaddr 
& (PAGE_SIZE
-1)) == 0); /* must be page aligned */ 
 150         for (vaddr_cur 
= vaddr
; 
 151              vaddr_cur 
< round_page_64(vaddr
+size
); 
 152              vaddr_cur 
+= PAGE_SIZE
) { 
 153                 ppn 
= pmap_find_phys(kernel_pmap
, vaddr_cur
); 
 154                 if (ppn 
!= (vm_offset_t
)NULL
) { 
 155                         kernel_pmap
->stats
.resident_count
++; 
 156                         if (kernel_pmap
->stats
.resident_count 
> 
 157                             kernel_pmap
->stats
.resident_max
) { 
 158                                 kernel_pmap
->stats
.resident_max 
= 
 159                                         kernel_pmap
->stats
.resident_count
; 
 161                         pmap_remove(kernel_pmap
, vaddr_cur
, vaddr_cur
+PAGE_SIZE
); 
 162                         assert(pmap_valid_page(ppn
)); 
 163                         if (IS_MANAGED_PAGE(ppn
)) { 
 164                                 vm_page_create(ppn
,(ppn
+1)); 
 169         vm_page_lockspin_queues(); 
 170         vm_page_wire_count 
-= freed_pages
; 
 171         vm_page_wire_count_initial 
-= freed_pages
; 
 172         vm_page_unlock_queues(); 
 175         kprintf("ml_static_mfree: Released 0x%x pages at VA %p, size:0x%llx, last ppn: 0x%x\n", freed_pages
, (void *)vaddr
, (uint64_t)size
, ppn
); 
 180 /* virtual to physical on wired pages */ 
 181 vm_offset_t 
ml_vtophys( 
 184         return  (vm_offset_t
)kvtophys(vaddr
); 
 188  *      Routine:        ml_nofault_copy 
 189  *      Function:       Perform a physical mode copy if the source and 
 190  *                      destination have valid translations in the kernel pmap. 
 191  *                      If translations are present, they are assumed to 
 192  *                      be wired; i.e. no attempt is made to guarantee that the 
 193  *                      translations obtained remained valid for 
 194  *                      the duration of the copy process. 
 197 vm_size_t 
ml_nofault_copy( 
 198         vm_offset_t virtsrc
, vm_offset_t virtdst
, vm_size_t size
) 
 200         addr64_t cur_phys_dst
, cur_phys_src
; 
 201         uint32_t count
, nbytes 
= 0; 
 204                 if (!(cur_phys_src 
= kvtophys(virtsrc
))) 
 206                 if (!(cur_phys_dst 
= kvtophys(virtdst
))) 
 208                 if (!pmap_valid_page(i386_btop(cur_phys_dst
)) || !pmap_valid_page(i386_btop(cur_phys_src
))) 
 210                 count 
= (uint32_t)(PAGE_SIZE 
- (cur_phys_src 
& PAGE_MASK
)); 
 211                 if (count 
> (PAGE_SIZE 
- (cur_phys_dst 
& PAGE_MASK
))) 
 212                         count 
= (uint32_t)(PAGE_SIZE 
- (cur_phys_dst 
& PAGE_MASK
)); 
 214                         count 
= (uint32_t)size
; 
 216                 bcopy_phys(cur_phys_src
, cur_phys_dst
, count
); 
 228  *      Routine:        ml_validate_nofault 
 229  *      Function: Validate that ths address range has a valid translations 
 230  *                      in the kernel pmap.  If translations are present, they are 
 231  *                      assumed to be wired; i.e. no attempt is made to guarantee 
 232  *                      that the translation persist after the check. 
 233  *  Returns: TRUE if the range is mapped and will not cause a fault, 
 237 boolean_t 
ml_validate_nofault( 
 238         vm_offset_t virtsrc
, vm_size_t size
) 
 240         addr64_t cur_phys_src
; 
 244                 if (!(cur_phys_src 
= kvtophys(virtsrc
))) 
 246                 if (!pmap_valid_page(i386_btop(cur_phys_src
))) 
 248                 count 
= (uint32_t)(PAGE_SIZE 
- (cur_phys_src 
& PAGE_MASK
)); 
 250                         count 
= (uint32_t)size
; 
 259 /* Interrupt handling */ 
 261 /* Initialize Interrupts */ 
 262 void ml_init_interrupt(void) 
 264         (void) ml_set_interrupts_enabled(TRUE
); 
 268 /* Get Interrupts Enabled */ 
 269 boolean_t 
ml_get_interrupts_enabled(void) 
 273   __asm__ 
volatile("pushf; pop  %0" :  "=r" (flags
)); 
 274   return (flags 
& EFL_IF
) != 0; 
 277 /* Set Interrupts Enabled */ 
 278 boolean_t 
ml_set_interrupts_enabled(boolean_t enable
) 
 283         __asm__ 
volatile("pushf; pop    %0" :  "=r" (flags
)); 
 285         assert(get_interrupt_level() ? (enable 
== FALSE
) : TRUE
); 
 287         istate 
= ((flags 
& EFL_IF
) != 0); 
 290                 __asm__ 
volatile("sti;nop"); 
 292                 if ((get_preemption_level() == 0) && (*ast_pending() & AST_URGENT
)) 
 293                         __asm__ 
volatile ("int %0" :: "N" (T_PREEMPT
)); 
 297                         __asm__ 
volatile("cli"); 
 303 /* Check if running at interrupt context */ 
 304 boolean_t 
ml_at_interrupt_context(void) 
 306         return get_interrupt_level() != 0; 
 309 void ml_get_power_state(boolean_t 
*icp
, boolean_t 
*pidlep
) { 
 310         *icp 
= (get_interrupt_level() != 0); 
 311         /* These will be technically inaccurate for interrupts that occur 
 312          * successively within a single "idle exit" event, but shouldn't 
 313          * matter statistically. 
 315         *pidlep 
= (current_cpu_datap()->lcpu
.package
->num_idle 
== topoParms
.nLThreadsPerPackage
); 
 318 /* Generate a fake interrupt */ 
 319 void ml_cause_interrupt(void) 
 321         panic("ml_cause_interrupt not defined yet on Intel"); 
 325  * TODO: transition users of this to kernel_thread_start_priority 
 326  * ml_thread_policy is an unsupported KPI 
 328 void ml_thread_policy( 
 330 __unused        
unsigned policy_id
, 
 331         unsigned policy_info
) 
 333         if (policy_info 
& MACHINE_NETWORK_WORKLOOP
) { 
 334                 thread_precedence_policy_data_t info
; 
 335                 __assert_only kern_return_t kret
; 
 339                 kret 
= thread_policy_set_internal(thread
, THREAD_PRECEDENCE_POLICY
, 
 340                                                                 (thread_policy_t
)&info
, 
 341                                                                 THREAD_PRECEDENCE_POLICY_COUNT
); 
 342                 assert(kret 
== KERN_SUCCESS
); 
 346 /* Initialize Interrupts */ 
 347 void ml_install_interrupt_handler( 
 351         IOInterruptHandler handler
, 
 354         boolean_t current_state
; 
 356         current_state 
= ml_set_interrupts_enabled(FALSE
); 
 358         PE_install_interrupt_handler(nub
, source
, target
, 
 359                                      (IOInterruptHandler
) handler
, refCon
); 
 361         (void) ml_set_interrupts_enabled(current_state
); 
 363         initialize_screen(NULL
, kPEAcquireScreen
); 
 369         processor_t processor
) 
 371         cpu_interrupt(processor
->cpu_id
); 
 375 machine_signal_idle_deferred( 
 376         __unused processor_t processor
) 
 378         panic("Unimplemented"); 
 382 machine_signal_idle_cancel( 
 383         __unused processor_t processor
) 
 385         panic("Unimplemented"); 
 391         processor_t     
*processor_out
, 
 395         cpu_data_t      
*this_cpu_datap
; 
 397         this_cpu_datap 
= cpu_data_alloc(boot_cpu
); 
 398         if (this_cpu_datap 
== NULL
) { 
 401         target_cpu 
= this_cpu_datap
->cpu_number
; 
 402         assert((boot_cpu 
&& (target_cpu 
== 0)) || 
 403               (!boot_cpu 
&& (target_cpu 
!= 0))); 
 405         lapic_cpu_map(lapic_id
, target_cpu
); 
 407         /* The cpu_id is not known at registration phase. Just do 
 410         this_cpu_datap
->cpu_phys_number 
= lapic_id
; 
 412         this_cpu_datap
->cpu_console_buf 
= console_cpu_alloc(boot_cpu
); 
 413         if (this_cpu_datap
->cpu_console_buf 
== NULL
) 
 416         this_cpu_datap
->cpu_chud 
= chudxnu_cpu_alloc(boot_cpu
); 
 417         if (this_cpu_datap
->cpu_chud 
== NULL
) 
 421         if (kpc_register_cpu(this_cpu_datap
) != TRUE
) 
 426                 cpu_thread_alloc(this_cpu_datap
->cpu_number
); 
 427                 if (this_cpu_datap
->lcpu
.core 
== NULL
) 
 430 #if NCOPY_WINDOWS > 0 
 431                 this_cpu_datap
->cpu_pmap 
= pmap_cpu_alloc(boot_cpu
); 
 432                 if (this_cpu_datap
->cpu_pmap 
== NULL
) 
 436                 this_cpu_datap
->cpu_processor 
= cpu_processor_alloc(boot_cpu
); 
 437                 if (this_cpu_datap
->cpu_processor 
== NULL
) 
 440                  * processor_init() deferred to topology start 
 441                  * because "slot numbers" a.k.a. logical processor numbers 
 442                  * are not yet finalized. 
 446         *processor_out 
= this_cpu_datap
->cpu_processor
; 
 451         cpu_processor_free(this_cpu_datap
->cpu_processor
); 
 452 #if NCOPY_WINDOWS > 0 
 453         pmap_cpu_free(this_cpu_datap
->cpu_pmap
); 
 455         chudxnu_cpu_free(this_cpu_datap
->cpu_chud
); 
 456         console_cpu_free(this_cpu_datap
->cpu_console_buf
); 
 458         kpc_unregister_cpu(this_cpu_datap
); 
 466 ml_processor_register( 
 469         processor_t     
*processor_out
, 
 473     static boolean_t done_topo_sort 
= FALSE
; 
 474     static uint32_t num_registered 
= 0; 
 476     /* Register all CPUs first, and track max */ 
 481         DBG( "registering CPU lapic id %d\n", lapic_id 
); 
 483         return register_cpu( lapic_id
, processor_out
, boot_cpu 
); 
 486     /* Sort by topology before we start anything */ 
 487     if( !done_topo_sort 
) 
 489         DBG( "about to start CPUs. %d registered\n", num_registered 
); 
 491         cpu_topology_sort( num_registered 
); 
 492         done_topo_sort 
= TRUE
; 
 495     /* Assign the cpu ID */ 
 496     uint32_t cpunum 
= -1; 
 497     cpu_data_t  
*this_cpu_datap 
= NULL
; 
 499     /* find cpu num and pointer */ 
 500     cpunum 
= ml_get_cpuid( lapic_id 
); 
 502     if( cpunum 
== 0xFFFFFFFF ) /* never heard of it? */ 
 503         panic( "trying to start invalid/unregistered CPU %d\n", lapic_id 
); 
 505     this_cpu_datap 
= cpu_datap(cpunum
); 
 508     this_cpu_datap
->cpu_id 
= cpu_id
; 
 510     /* allocate and initialize other per-cpu structures */ 
 512         mp_cpus_call_cpu_init(cpunum
); 
 513         prng_cpu_init(cpunum
); 
 517     *processor_out 
= this_cpu_datap
->cpu_processor
; 
 519     /* OK, try and start this CPU */ 
 520     return cpu_topology_start_cpu( cpunum 
); 
 525 ml_cpu_get_info(ml_cpu_info_t 
*cpu_infop
) 
 527         boolean_t       os_supports_sse
; 
 528         i386_cpu_info_t 
*cpuid_infop
; 
 530         if (cpu_infop 
== NULL
) 
 534          * Are we supporting MMX/SSE/SSE2/SSE3? 
 535          * As distinct from whether the cpu has these capabilities. 
 537         os_supports_sse 
= !!(get_cr4() & CR4_OSXMM
); 
 539         if (ml_fpu_avx_enabled()) 
 540                 cpu_infop
->vector_unit 
= 9; 
 541         else if ((cpuid_features() & CPUID_FEATURE_SSE4_2
) && os_supports_sse
) 
 542                 cpu_infop
->vector_unit 
= 8; 
 543         else if ((cpuid_features() & CPUID_FEATURE_SSE4_1
) && os_supports_sse
) 
 544                 cpu_infop
->vector_unit 
= 7; 
 545         else if ((cpuid_features() & CPUID_FEATURE_SSSE3
) && os_supports_sse
) 
 546                 cpu_infop
->vector_unit 
= 6; 
 547         else if ((cpuid_features() & CPUID_FEATURE_SSE3
) && os_supports_sse
) 
 548                 cpu_infop
->vector_unit 
= 5; 
 549         else if ((cpuid_features() & CPUID_FEATURE_SSE2
) && os_supports_sse
) 
 550                 cpu_infop
->vector_unit 
= 4; 
 551         else if ((cpuid_features() & CPUID_FEATURE_SSE
) && os_supports_sse
) 
 552                 cpu_infop
->vector_unit 
= 3; 
 553         else if (cpuid_features() & CPUID_FEATURE_MMX
) 
 554                 cpu_infop
->vector_unit 
= 2; 
 556                 cpu_infop
->vector_unit 
= 0; 
 558         cpuid_infop  
= cpuid_info(); 
 560         cpu_infop
->cache_line_size 
= cpuid_infop
->cache_linesize
;  
 562         cpu_infop
->l1_icache_size 
= cpuid_infop
->cache_size
[L1I
]; 
 563         cpu_infop
->l1_dcache_size 
= cpuid_infop
->cache_size
[L1D
]; 
 565         if (cpuid_infop
->cache_size
[L2U
] > 0) { 
 566             cpu_infop
->l2_settings 
= 1; 
 567             cpu_infop
->l2_cache_size 
= cpuid_infop
->cache_size
[L2U
]; 
 569             cpu_infop
->l2_settings 
= 0; 
 570             cpu_infop
->l2_cache_size 
= 0xFFFFFFFF; 
 573         if (cpuid_infop
->cache_size
[L3U
] > 0) { 
 574             cpu_infop
->l3_settings 
= 1; 
 575             cpu_infop
->l3_cache_size 
= cpuid_infop
->cache_size
[L3U
]; 
 577             cpu_infop
->l3_settings 
= 0; 
 578             cpu_infop
->l3_cache_size 
= 0xFFFFFFFF; 
 583 ml_init_max_cpus(unsigned long max_cpus
) 
 585         boolean_t current_state
; 
 587         current_state 
= ml_set_interrupts_enabled(FALSE
); 
 588         if (max_cpus_initialized 
!= MAX_CPUS_SET
) { 
 589                 if (max_cpus 
> 0 && max_cpus 
<= MAX_CPUS
) { 
 591                          * Note: max_cpus is the number of enabled processors 
 592                          * that ACPI found; max_ncpus is the maximum number 
 593                          * that the kernel supports or that the "cpus=" 
 594                          * boot-arg has set. Here we take int minimum. 
 596                         machine_info
.max_cpus 
= (integer_t
)MIN(max_cpus
, max_ncpus
); 
 598                 if (max_cpus_initialized 
== MAX_CPUS_WAIT
) 
 599                         wakeup((event_t
)&max_cpus_initialized
); 
 600                 max_cpus_initialized 
= MAX_CPUS_SET
; 
 602         (void) ml_set_interrupts_enabled(current_state
); 
 606 ml_get_max_cpus(void) 
 608         boolean_t current_state
; 
 610         current_state 
= ml_set_interrupts_enabled(FALSE
); 
 611         if (max_cpus_initialized 
!= MAX_CPUS_SET
) { 
 612                 max_cpus_initialized 
= MAX_CPUS_WAIT
; 
 613                 assert_wait((event_t
)&max_cpus_initialized
, THREAD_UNINT
); 
 614                 (void)thread_block(THREAD_CONTINUE_NULL
); 
 616         (void) ml_set_interrupts_enabled(current_state
); 
 617         return(machine_info
.max_cpus
); 
 621 ml_wants_panic_trap_to_debugger(void) 
 627 ml_panic_trap_to_debugger(__unused 
const char *panic_format_str
, 
 628                           __unused 
va_list *panic_args
, 
 629                           __unused 
unsigned int reason
, 
 631                           __unused 
uint64_t panic_options_mask
, 
 632                           __unused 
unsigned long panic_caller
) 
 638  *      Routine:        ml_init_lock_timeout 
 642 ml_init_lock_timeout(void) 
 646 #if DEVELOPMENT || DEBUG 
 647         uint64_t        default_timeout_ns 
= NSEC_PER_SEC
>>2; 
 649         uint64_t        default_timeout_ns 
= NSEC_PER_SEC
>>1; 
 654         if (PE_parse_boot_argn("slto_us", &slto
, sizeof (slto
))) 
 655                 default_timeout_ns 
= slto 
* NSEC_PER_USEC
; 
 658          * LockTimeOut is absolutetime, LockTimeOutTSC is in TSC ticks, 
 659          * and LockTimeOutUsec is in microseconds and it's 32-bits. 
 661         LockTimeOutUsec 
= (uint32_t) (default_timeout_ns 
/ NSEC_PER_USEC
); 
 662         nanoseconds_to_absolutetime(default_timeout_ns
, &abstime
); 
 663         LockTimeOut 
= abstime
; 
 664         LockTimeOutTSC 
= tmrCvt(abstime
, tscFCvtn2t
); 
 667          * TLBTimeOut dictates the TLB flush timeout period. It defaults to 
 668          * LockTimeOut but can be overriden separately. In particular, a 
 669          * zero value inhibits the timeout-panic and cuts a trace evnt instead 
 670          * - see pmap_flush_tlbs(). 
 672         if (PE_parse_boot_argn("tlbto_us", &slto
, sizeof (slto
))) { 
 673                 default_timeout_ns 
= slto 
* NSEC_PER_USEC
; 
 674                 nanoseconds_to_absolutetime(default_timeout_ns
, &abstime
); 
 675                 TLBTimeOut 
= (uint32_t) abstime
; 
 677                 TLBTimeOut 
= LockTimeOut
; 
 680 #if DEVELOPMENT || DEBUG 
 681         reportphyreaddelayabs 
= LockTimeOut 
>> 1; 
 683         if (PE_parse_boot_argn("phyreadmaxus", &slto
, sizeof (slto
))) { 
 684                 default_timeout_ns 
= slto 
* NSEC_PER_USEC
; 
 685                 nanoseconds_to_absolutetime(default_timeout_ns
, &abstime
); 
 686                 reportphyreaddelayabs 
= abstime
; 
 689         if (PE_parse_boot_argn("mtxspin", &mtxspin
, sizeof (mtxspin
))) { 
 690                 if (mtxspin 
> USEC_PER_SEC
>>4) 
 691                         mtxspin 
=  USEC_PER_SEC
>>4; 
 692                 nanoseconds_to_absolutetime(mtxspin
*NSEC_PER_USEC
, &abstime
); 
 694                 nanoseconds_to_absolutetime(10*NSEC_PER_USEC
, &abstime
); 
 696         MutexSpin 
= (unsigned int)abstime
; 
 698         nanoseconds_to_absolutetime(4ULL * NSEC_PER_SEC
, &LastDebuggerEntryAllowance
); 
 699         if (PE_parse_boot_argn("panic_restart_timeout", &prt
, sizeof (prt
))) 
 700                 nanoseconds_to_absolutetime(prt 
* NSEC_PER_SEC
, &panic_restart_timeout
); 
 702         virtualized 
= ((cpuid_features() & CPUID_FEATURE_VMM
) != 0); 
 706                 if (!PE_parse_boot_argn("vti", &vti
, sizeof (vti
))) 
 708                 printf("Timeouts adjusted for virtualization (<<%d)\n", vti
); 
 709                 kprintf("Timeouts adjusted for virtualization (<<%d):\n", vti
); 
 710 #define VIRTUAL_TIMEOUT_INFLATE64(_timeout)                     \ 
 712         kprintf("%24s: 0x%016llx ", #_timeout, _timeout);       \ 
 714         kprintf("-> 0x%016llx\n",  _timeout);                   \ 
 716 #define VIRTUAL_TIMEOUT_INFLATE32(_timeout)                     \ 
 718         kprintf("%24s:         0x%08x ", #_timeout, _timeout);  \ 
 719         if ((_timeout <<vti) >> vti == _timeout)                \ 
 722                 _timeout = ~0; /* cap rather than overflow */   \ 
 723         kprintf("-> 0x%08x\n",  _timeout);                      \ 
 725                 VIRTUAL_TIMEOUT_INFLATE32(LockTimeOutUsec
); 
 726                 VIRTUAL_TIMEOUT_INFLATE64(LockTimeOut
); 
 727                 VIRTUAL_TIMEOUT_INFLATE64(LockTimeOutTSC
); 
 728                 VIRTUAL_TIMEOUT_INFLATE64(TLBTimeOut
); 
 729                 VIRTUAL_TIMEOUT_INFLATE64(MutexSpin
); 
 730                 VIRTUAL_TIMEOUT_INFLATE64(reportphyreaddelayabs
); 
 733         interrupt_latency_tracker_setup(); 
 734         simple_lock_init(&ml_timer_evaluation_slock
, 0); 
 738  * Threshold above which we should attempt to block 
 739  * instead of spinning for clock_delay_until(). 
 743 ml_init_delay_spin_threshold(int threshold_us
) 
 745         nanoseconds_to_absolutetime(threshold_us 
* NSEC_PER_USEC
, &delay_spin_threshold
); 
 749 ml_delay_should_spin(uint64_t interval
) 
 751         return (interval 
< delay_spin_threshold
) ? TRUE 
: FALSE
; 
 755  * This is called from the machine-independent layer 
 756  * to perform machine-dependent info updates. Defer to cpu_thread_init(). 
 765  * This is called from the machine-independent layer 
 766  * to perform machine-dependent info updates. 
 771         i386_deactivate_cpu(); 
 777  * The following are required for parts of the kernel 
 778  * that cannot resolve these functions as inlines: 
 780 extern thread_t 
current_act(void); 
 784   return(current_thread_fast()); 
 787 #undef current_thread 
 788 extern thread_t 
current_thread(void); 
 792   return(current_thread_fast()); 
 796 boolean_t 
ml_is64bit(void) { 
 798         return (cpu_mode_is64bit()); 
 802 boolean_t 
ml_thread_is64bit(thread_t thread
) { 
 804         return (thread_is_64bit(thread
)); 
 808 boolean_t 
ml_state_is64bit(void *saved_state
) { 
 810         return is_saved_state64(saved_state
); 
 813 void ml_cpu_set_ldt(int selector
) 
 816          * Avoid loading the LDT 
 817          * if we're setting the KERNEL LDT and it's already set. 
 819         if (selector 
== KERNEL_LDT 
&& 
 820             current_cpu_datap()->cpu_ldt 
== KERNEL_LDT
) 
 824         current_cpu_datap()->cpu_ldt 
= selector
; 
 827 void ml_fp_setvalid(boolean_t value
) 
 832 uint64_t ml_cpu_int_event_time(void) 
 834         return current_cpu_datap()->cpu_int_event_time
; 
 837 vm_offset_t 
ml_stack_remaining(void) 
 839         uintptr_t local 
= (uintptr_t) &local
; 
 841         if (ml_at_interrupt_context() != 0) { 
 842             return (local 
- (current_cpu_datap()->cpu_int_stack_top 
- INTSTACK_SIZE
)); 
 844             return (local 
- current_thread()->kernel_stack
); 
 849 vm_offset_t 
ml_stack_base(void); 
 850 vm_size_t 
ml_stack_size(void); 
 855         if (ml_at_interrupt_context()) { 
 856                 return current_cpu_datap()->cpu_int_stack_top 
- INTSTACK_SIZE
; 
 858             return current_thread()->kernel_stack
; 
 865         if (ml_at_interrupt_context()) { 
 866             return INTSTACK_SIZE
; 
 868             return kernel_stack_size
; 
 874 kernel_preempt_check(void) 
 879         assert(get_preemption_level() == 0); 
 881         __asm__ 
volatile("pushf; pop    %0" :  "=r" (flags
)); 
 883         intr 
= ((flags 
& EFL_IF
) != 0); 
 885         if ((*ast_pending() & AST_URGENT
) && intr 
== TRUE
) { 
 887                  * can handle interrupts and preemptions  
 892                  * now cause the PRE-EMPTION trap 
 894                 __asm__ 
volatile ("int %0" :: "N" (T_PREEMPT
)); 
 898 boolean_t 
machine_timeout_suspended(void) { 
 899         return (pmap_tlb_flush_timeout 
|| spinlock_timed_out 
|| panic_active() || mp_recent_debugger_activity() || ml_recent_wake()); 
 902 /* Eagerly evaluate all pending timer and thread callouts 
 904 void ml_timer_evaluate(void) { 
 905         KERNEL_DEBUG_CONSTANT(DECR_TIMER_RESCAN
|DBG_FUNC_START
, 0, 0, 0, 0, 0); 
 907         uint64_t te_end
, te_start 
= mach_absolute_time(); 
 908         simple_lock(&ml_timer_evaluation_slock
); 
 909         ml_timer_evaluation_in_progress 
= TRUE
; 
 910         thread_call_delayed_timer_rescan_all(); 
 911         mp_cpus_call(CPUMASK_ALL
, ASYNC
, timer_queue_expire_rescan
, NULL
); 
 912         ml_timer_evaluation_in_progress 
= FALSE
; 
 913         ml_timer_eager_evaluations
++; 
 914         te_end 
= mach_absolute_time(); 
 915         ml_timer_eager_evaluation_max 
= MAX(ml_timer_eager_evaluation_max
, (te_end 
- te_start
)); 
 916         simple_unlock(&ml_timer_evaluation_slock
); 
 918         KERNEL_DEBUG_CONSTANT(DECR_TIMER_RESCAN
|DBG_FUNC_END
, 0, 0, 0, 0, 0); 
 922 ml_timer_forced_evaluation(void) { 
 923         return ml_timer_evaluation_in_progress
; 
 926 /* 32-bit right-rotate n bits */ 
 927 static inline uint32_t ror32(uint32_t val
, const unsigned int n
) 
 929         __asm__ 
volatile("rorl %%cl,%0" : "=r" (val
) : "0" (val
), "c" (n
)); 
 934 ml_entropy_collect(void) 
 936         uint32_t        tsc_lo
, tsc_hi
; 
 939         assert(cpu_number() == master_cpu
); 
 941         /* update buffer pointer cyclically */ 
 942         if (EntropyData
.index_ptr 
- EntropyData
.buffer 
== ENTROPY_BUFFER_SIZE
) 
 943                 ep 
= EntropyData
.index_ptr 
= EntropyData
.buffer
; 
 945                 ep 
= EntropyData
.index_ptr
++; 
 947         rdtsc_nofence(tsc_lo
, tsc_hi
); 
 948         *ep 
= ror32(*ep
, 9) ^ tsc_lo
; 
 952 ml_energy_stat(__unused thread_t t
) { 
 957 ml_gpu_stat_update(uint64_t gpu_ns_delta
) { 
 958         current_thread()->machine
.thread_gpu_ns 
+= gpu_ns_delta
; 
 962 ml_gpu_stat(thread_t t
) { 
 963         return t
->machine
.thread_gpu_ns
; 
 966 int plctrace_enabled 
= 0; 
 968 void _disable_preemption(void) { 
 969         disable_preemption_internal(); 
 972 void _enable_preemption(void) { 
 973         enable_preemption_internal(); 
 976 void plctrace_disable(void) { 
 977         plctrace_enabled 
= 0; 
 980 static boolean_t ml_quiescing
; 
 982 void ml_set_is_quiescing(boolean_t quiescing
) 
 984     assert(FALSE 
== ml_get_interrupts_enabled()); 
 985     ml_quiescing 
= quiescing
; 
 988 boolean_t 
ml_is_quiescing(void) 
 990     assert(FALSE 
== ml_get_interrupts_enabled()); 
 991     return (ml_quiescing
); 
 994 uint64_t ml_get_booter_memory_size(void)