#include <debug.h>
#include <xpr_debug.h>
#include <mach_kdp.h>
#include <mach_host.h>
#include <norma_vm.h>
#include <mach/boolean.h>
#include <mach/machine.h>
#include <mach/thread_act.h>
#include <mach/task_special_ports.h>
#include <mach/vm_param.h>
#include <ipc/ipc_init.h>
#include <kern/assert.h>
#include <kern/misc_protos.h>
#include <kern/clock.h>
#include <kern/cpu_number.h>
#include <kern/ledger.h>
#include <kern/machine.h>
#include <kern/processor.h>
#include <kern/sched_prim.h>
#include <kern/startup.h>
#include <kern/task.h>
#include <kern/thread.h>
#include <kern/timer.h>
#include <kern/xpr.h>
#include <kern/zalloc.h>
#include <kern/locks.h>
#include <vm/vm_shared_memory_server.h>
#include <vm/vm_kern.h>
#include <vm/vm_init.h>
#include <vm/vm_map.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_pageout.h>
#include <machine/pmap.h>
#include <machine/commpage.h>
#include <libkern/version.h>
#ifdef __ppc__
#include <ppc/Firmware.h>
#include <ppc/mappings.h>
#include <ppc/serial_io.h>
#endif
static void kernel_bootstrap_thread(void);
static void load_context(
thread_t thread);
void
kernel_bootstrap(void)
{
kern_return_t result;
thread_t thread;
lck_mod_init();
sched_init();
vm_mem_bootstrap();
ipc_bootstrap();
vm_mem_init();
ipc_init();
PMAP_ACTIVATE_KERNEL(master_cpu);
mapping_free_prime();
machine_init();
kmod_init();
clock_init();
machine_info.memory_size = mem_size;
machine_info.max_mem = max_mem;
machine_info.major_version = version_major;
machine_info.minor_version = version_minor;
ledger_init();
task_init();
thread_init();
result = kernel_thread_create((thread_continue_t)kernel_bootstrap_thread, NULL, MAXPRI_KERNEL, &thread);
if (result != KERN_SUCCESS)
panic("kernel_bootstrap");
thread->state = TH_RUN;
thread_deallocate(thread);
load_context(thread);
}
static void
kernel_bootstrap_thread(void)
{
processor_t processor = current_processor();
thread_t self = current_thread();
idle_thread_create(processor);
sched_startup();
thread_bind(self, processor);
mapping_adjust();
clock_service_create();
device_service_create();
shared_file_boot_time_init(ENV_DEFAULT_ROOT, cpu_type());
#ifdef IOKIT
{
PE_init_iokit();
}
#endif
(void) spllo();
commpage_populate();
#ifdef MACH_BSD
{
bsd_init();
}
#endif
#if __ppc__
serial_keyboard_init();
#endif
thread_bind(self, PROCESSOR_NULL);
vm_pageout();
}
void
slave_main(void)
{
processor_t processor = current_processor();
thread_t thread;
if (processor->next_thread == THREAD_NULL) {
thread = processor->idle_thread;
thread->continuation = (thread_continue_t)processor_start_thread;
thread->parameter = NULL;
}
else {
thread = processor->next_thread;
processor->next_thread = THREAD_NULL;
}
load_context(thread);
}
void
processor_start_thread(void)
{
processor_t processor = current_processor();
thread_t self = current_thread();
slave_machine_init();
if (self == processor->idle_thread)
thread_block((thread_continue_t)idle_thread);
thread_terminate(self);
}
static void
load_context(
thread_t thread)
{
processor_t processor = current_processor();
machine_set_current_thread(thread);
processor_up(processor);
PMAP_ACTIVATE_KERNEL(PROCESSOR_DATA(processor, slot_num));
if (!thread->kernel_stack) {
if (!stack_alloc_try(thread))
panic("load_context");
}
if (!(thread->state & TH_IDLE))
pset_run_incr(thread->processor_set);
processor->active_thread = thread;
processor->current_pri = thread->sched_pri;
processor->deadline = UINT64_MAX;
thread->last_processor = processor;
processor->last_dispatch = mach_absolute_time();
timer_switch((uint32_t)processor->last_dispatch,
&PROCESSOR_DATA(processor, offline_timer));
PMAP_ACTIVATE_USER(thread, PROCESSOR_DATA(processor, slot_num));
machine_load_context(thread);
}