#include <debug.h>
#include <xpr_debug.h>
#include <mach_kdp.h>
#include <cpus.h>
#include <mach_host.h>
#include <norma_vm.h>
#include <etap.h>
#include <mach/boolean.h>
#include <mach/machine.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/etap_macros.h>
#include <kern/machine.h>
#include <kern/processor.h>
#include <kern/sched_prim.h>
#include <kern/mk_sp.h>
#include <kern/startup.h>
#include <kern/task.h>
#include <kern/thread.h>
#include <kern/timer.h>
#include <kern/timer_call.h>
#include <kern/xpr.h>
#include <kern/zalloc.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 <sys/version.h>
#ifdef __ppc__
#include <ppc/Firmware.h>
#include <ppc/mappings.h>
#endif
extern void rtclock_reset(void);
void cpu_launch_first_thread(
thread_t thread);
void start_kernel_threads(void);
void swapin_thread();
void
setup_main(void)
{
thread_t startup_thread;
sched_init();
vm_mem_bootstrap();
ipc_bootstrap();
vm_mem_init();
ipc_init();
PMAP_ACTIVATE_KERNEL(master_cpu);
#ifdef __ppc__
mapping_free_prime();
#endif
machine_init();
kmod_init();
clock_init();
init_timers();
timer_call_initialize();
machine_info.max_cpus = NCPUS;
machine_info.memory_size = mem_size;
machine_info.avail_cpus = 0;
machine_info.major_version = KERNEL_MAJOR_VERSION;
machine_info.minor_version = KERNEL_MINOR_VERSION;
ledger_init();
task_init();
act_init();
thread_init();
subsystem_init();
etap_init_phase2();
startup_thread = kernel_thread_with_priority(
kernel_task, MAXPRI_KERNEL,
start_kernel_threads, TRUE, FALSE);
startup_thread->state = TH_RUN;
(void) thread_resume(startup_thread->top_act);
cpu_launch_first_thread(startup_thread);
panic("cpu_launch_first_thread returns!");
}
void
start_kernel_threads(void)
{
register int i;
thread_bind(current_thread(), cpu_to_processor(cpu_number()));
for (i = 0; i < NCPUS; i++) {
processor_t processor = cpu_to_processor(i);
thread_t thread;
spl_t s;
thread = kernel_thread_with_priority(
kernel_task, MAXPRI_KERNEL,
idle_thread, TRUE, FALSE);
s = splsched();
thread_lock(thread);
thread_bind_locked(thread, processor);
processor->idle_thread = thread;
thread->ref_count++;
thread->state |= TH_IDLE;
thread_go_locked(thread, THREAD_AWAKENED);
thread_unlock(thread);
splx(s);
}
swapin_init();
sched_tick_init();
thread_call_initialize();
#if __ppc__
mapping_adjust();
#endif
thread_reaper();
clock_service_create();
device_service_create();
shared_file_boot_time_init();
#ifdef IOKIT
{
PE_init_iokit();
}
#endif
(void) spllo();
#ifdef MACH_BSD
{
extern void bsd_init(void);
bsd_init();
}
#endif
thread_bind(current_thread(), PROCESSOR_NULL);
vm_pageout();
}
void
slave_main(void)
{
processor_t myprocessor = current_processor();
thread_t thread;
thread = myprocessor->next_thread;
myprocessor->next_thread = THREAD_NULL;
if (thread == THREAD_NULL) {
thread = machine_wake_thread;
machine_wake_thread = THREAD_NULL;
thread_bind(thread, myprocessor);
}
cpu_launch_first_thread(thread);
panic("slave_main");
}
void
start_cpu_thread(void)
{
processor_t processor;
processor = cpu_to_processor(cpu_number());
slave_machine_init();
if (processor->processor_self == IP_NULL) {
ipc_processor_init(processor);
ipc_processor_enable(processor);
}
(void) thread_terminate(current_act());
}
void
cpu_launch_first_thread(
thread_t thread)
{
register int mycpu = cpu_number();
cpu_data[mycpu].preemption_level = 1;
cpu_up(mycpu);
start_timer(&kernel_timer[mycpu]);
clock_get_uptime(&cpu_to_processor(mycpu)->last_dispatch);
if (thread == THREAD_NULL) {
thread = cpu_to_processor(mycpu)->idle_thread;
if (thread == THREAD_NULL)
panic("cpu_launch_first_thread");
}
rtclock_reset();
PMAP_ACTIVATE_KERNEL(mycpu);
thread_machine_set_current(thread);
thread_lock(thread);
thread->state &= ~TH_UNINT;
_mk_sp_thread_begin(thread);
thread_unlock(thread);
timer_switch(&thread->system_timer);
PMAP_ACTIVATE_USER(thread->top_act, mycpu);
load_context(thread);
}