/* * processor_up: * * Flag processor as up and running, and available * for scheduling. */ void processor_up( processor_t processor) { processor_set_t pset; spl_t s; s = splsched(); init_ast_check(processor); pset = processor->processor_set; pset_lock(pset); ++pset->online_processor_count; enqueue_tail(&pset->active_queue, (queue_entry_t)processor); processor->state = PROCESSOR_RUNNING; (void)hw_atomic_add(&processor_avail_count, 1); commpage_update_active_cpus(); pset_unlock(pset); ml_cpu_up(); splx(s); #if CONFIG_DTRACE if (dtrace_cpu_state_changed_hook) (*dtrace_cpu_state_changed_hook)(processor->cpu_id, TRUE); #endif }
/* * Called with interrupts disabled. */ void processor_doshutdown( processor_t processor) { thread_t old_thread, self = current_thread(); processor_t prev; processor_set_t pset; /* * Get onto the processor to shutdown */ prev = thread_bind(processor); thread_block(THREAD_CONTINUE_NULL); assert(processor->state == PROCESSOR_SHUTDOWN); #if CONFIG_DTRACE if (dtrace_cpu_state_changed_hook) (*dtrace_cpu_state_changed_hook)(processor->cpu_id, FALSE); #endif ml_cpu_down(); #if HIBERNATION if (processor_avail_count < 2) { hibernate_vm_lock(); hibernate_vm_unlock(); } #endif pset = processor->processor_set; pset_lock(pset); processor->state = PROCESSOR_OFF_LINE; --pset->online_processor_count; (void)hw_atomic_sub(&processor_avail_count, 1); commpage_update_active_cpus(); SCHED(processor_queue_shutdown)(processor); /* pset lock dropped */ /* * Continue processor shutdown in shutdown context. * * We save the current context in machine_processor_shutdown in such a way * that when this thread is next invoked it will return from here instead of * from the machine_switch_context() in thread_invoke like a normal context switch. * * As such, 'old_thread' is neither the idle thread nor the current thread - it's whatever * thread invoked back to this one. (Usually, it's another processor's idle thread.) * * TODO: Make this a real thread_run of the idle_thread, so we don't have to keep this in sync * with thread_invoke. */ thread_bind(prev); old_thread = machine_processor_shutdown(self, processor_offline, processor); thread_dispatch(old_thread, self); }
/* * Called with interrupts disabled. */ void processor_doshutdown( processor_t processor) { thread_t old_thread, self = current_thread(); processor_t prev; processor_set_t pset; /* * Get onto the processor to shutdown */ prev = thread_bind(processor); thread_block(THREAD_CONTINUE_NULL); assert(processor->state == PROCESSOR_SHUTDOWN); #if CONFIG_DTRACE if (dtrace_cpu_state_changed_hook) (*dtrace_cpu_state_changed_hook)(processor->cpu_id, FALSE); #endif ml_cpu_down(); #if HIBERNATION if (processor_avail_count < 2) { hibernate_vm_lock(); hibernate_vm_unlock(); } #endif pset = processor->processor_set; pset_lock(pset); processor->state = PROCESSOR_OFF_LINE; --pset->online_processor_count; (void)hw_atomic_sub(&processor_avail_count, 1); commpage_update_active_cpus(); SCHED(processor_queue_shutdown)(processor); /* pset lock dropped */ /* * Continue processor shutdown in shutdown context. */ thread_bind(prev); old_thread = machine_processor_shutdown(self, processor_offline, processor); thread_dispatch(old_thread, self); }
void commpage_populate( void ) { commpage_init_cpu_capabilities(); commpage_populate_one( commpage32_map, &commPagePtr32, _COMM_PAGE32_AREA_USED, _COMM_PAGE32_BASE_ADDRESS, &time_data32, "commpage 32-bit", VM_PROT_READ); #ifndef __LP64__ pmap_commpage32_init((vm_offset_t) commPagePtr32, _COMM_PAGE32_BASE_ADDRESS, _COMM_PAGE32_AREA_USED/INTEL_PGBYTES); #endif time_data64 = time_data32; /* if no 64-bit commpage, point to 32-bit */ if (_cpu_capabilities & k64Bit) { commpage_populate_one( commpage64_map, &commPagePtr64, _COMM_PAGE64_AREA_USED, _COMM_PAGE32_START_ADDRESS, /* commpage address are relative to 32-bit commpage placement */ &time_data64, "commpage 64-bit", VM_PROT_READ); #ifndef __LP64__ pmap_commpage64_init((vm_offset_t) commPagePtr64, _COMM_PAGE64_BASE_ADDRESS, _COMM_PAGE64_AREA_USED/INTEL_PGBYTES); #endif } simple_lock_init(&commpage_active_cpus_lock, 0); commpage_update_active_cpus(); commpage_mach_approximate_time_init(); commpage_mach_continuous_time_init(); commpage_boottime_init(); rtc_nanotime_init_commpage(); commpage_update_kdebug_state(); #if CONFIG_ATM commpage_update_atm_diagnostic_config(atm_get_diagnostic_config()); #endif }