Пример #1
0
/*
 *	load_context:
 *
 *	Start the first thread on a processor.
 */
static void
load_context(
	thread_t		thread)
{
	processor_t		processor = current_processor();


#define load_context_kprintf(x...) /* kprintf("load_context: " x) */

	load_context_kprintf("calling machine_set_current_thread\n");
	machine_set_current_thread(thread);

	load_context_kprintf("calling processor_up\n");
	processor_up(processor);

	PMAP_ACTIVATE_KERNEL(processor->cpu_id);

	/*
	 * Acquire a stack if none attached.  The panic
	 * should never occur since the thread is expected
	 * to have reserved stack.
	 */
	load_context_kprintf("thread %p, stack %lx, stackptr %lx\n", thread,
			     thread->kernel_stack, thread->machine.kstackptr);
	if (!thread->kernel_stack) {
		load_context_kprintf("calling stack_alloc_try\n");
		if (!stack_alloc_try(thread))
			panic("load_context");
	}

	/*
	 * The idle processor threads are not counted as
	 * running for load calculations.
	 */
	if (!(thread->state & TH_IDLE))
		sched_run_incr();

	processor->active_thread = thread;
	processor->current_pri = thread->sched_pri;
	processor->current_thmode = thread->sched_mode;
	processor->deadline = UINT64_MAX;
	thread->last_processor = processor;

	processor->last_dispatch = mach_absolute_time();
	timer_start(&thread->system_timer, processor->last_dispatch);
	PROCESSOR_DATA(processor, thread_timer) = PROCESSOR_DATA(processor, kernel_timer) = &thread->system_timer;

	timer_start(&PROCESSOR_DATA(processor, system_state), processor->last_dispatch);
	PROCESSOR_DATA(processor, current_state) = &PROCESSOR_DATA(processor, system_state);

	PMAP_ACTIVATE_USER(thread, processor->cpu_id);

	load_context_kprintf("calling machine_load_context\n");
	machine_load_context(thread);
	/*NOTREACHED*/
}
Пример #2
0
/*
 *	Start up the first thread on a CPU.
 *	First thread is specified for the master CPU.
 */
void
cpu_launch_first_thread(
	register thread_t	th)
{
	register int	mycpu;

	mycpu = cpu_number();

#if	MACH_ASSERT
	if (watchacts & WA_BOOT)
		printf("cpu_launch_first_thread(%x) cpu=%d\n", th, mycpu);
#endif	/* MACH_ASSERT */

	cpu_up(mycpu);

	start_timer(&kernel_timer[mycpu]);

	/*
	 * Block all interrupts for choose_thread.
	 */
	(void) splhigh();

	if (th == THREAD_NULL) {
	    th = cpu_to_processor(mycpu)->idle_thread;
		if (th == THREAD_NULL || !rem_runq(th))
		    panic("cpu_launch_first_thread");
	}

	rtclock_reset();		/* start realtime clock ticking */
	PMAP_ACTIVATE_KERNEL(mycpu);

	thread_machine_set_current(th);
	thread_lock(th);
	th->state &= ~TH_UNINT;
	thread_unlock(th);
	timer_switch(&th->system_timer);

	PMAP_ACTIVATE_USER(th->top_act, mycpu);

	assert(mycpu == cpu_number());

        /* The following is necessary to keep things balanced */
        disable_preemption();

	load_context(th);
	/*NOTREACHED*/
}
Пример #3
0
void
kernel_bootstrap(void)
{
    kern_return_t	result;
    thread_t	thread;
    char		namep[16];

    printf("%s\n", version); /* log kernel version */

#define kernel_bootstrap_kprintf(x...) /* kprintf("kernel_bootstrap: " x) */

    if (PE_parse_boot_argn("-l", namep, sizeof (namep))) /* leaks logging */
        turn_on_log_leaks = 1;

    PE_parse_boot_argn("trace", &new_nkdbufs, sizeof (new_nkdbufs));

    /* i386_vm_init already checks for this ; do it aagin anyway */
    if (PE_parse_boot_argn("serverperfmode", &serverperfmode, sizeof (serverperfmode))) {
        serverperfmode = 1;
    }
    scale_setup();

    kernel_bootstrap_kprintf("calling vm_mem_bootstrap\n");
    vm_mem_bootstrap();

    kernel_bootstrap_kprintf("calling vm_mem_init\n");
    vm_mem_init();

    machine_info.memory_size = (uint32_t)mem_size;
    machine_info.max_mem = max_mem;
    machine_info.major_version = version_major;
    machine_info.minor_version = version_minor;

    kernel_bootstrap_kprintf("calling sched_init\n");
    sched_init();

    kernel_bootstrap_kprintf("calling wait_queue_bootstrap\n");
    wait_queue_bootstrap();

    kernel_bootstrap_kprintf("calling ipc_bootstrap\n");
    ipc_bootstrap();

#if CONFIG_MACF
    mac_policy_init();
#endif
    kernel_bootstrap_kprintf("calling ipc_init\n");
    ipc_init();

    /*
     * As soon as the virtual memory system is up, we record
     * that this CPU is using the kernel pmap.
     */
    kernel_bootstrap_kprintf("calling PMAP_ACTIVATE_KERNEL\n");
    PMAP_ACTIVATE_KERNEL(master_cpu);

    kernel_bootstrap_kprintf("calling mapping_free_prime\n");
    mapping_free_prime();						/* Load up with temporary mapping blocks */

    kernel_bootstrap_kprintf("calling machine_init\n");
    machine_init();

    kernel_bootstrap_kprintf("calling clock_init\n");
    clock_init();

    ledger_init();

    /*
     *	Initialize the IPC, task, and thread subsystems.
     */
    kernel_bootstrap_kprintf("calling task_init\n");
    task_init();

    kernel_bootstrap_kprintf("calling thread_init\n");
    thread_init();

    /*
     *	Create a kernel thread to execute the kernel bootstrap.
     */
    kernel_bootstrap_kprintf("calling kernel_thread_create\n");
    result = kernel_thread_create((thread_continue_t)kernel_bootstrap_thread, NULL, MAXPRI_KERNEL, &thread);

    if (result != KERN_SUCCESS) panic("kernel_bootstrap: result = %08X\n", result);

    thread->state = TH_RUN;
    thread_deallocate(thread);

    kernel_bootstrap_kprintf("calling load_context - done\n");
    load_context(thread);
    /*NOTREACHED*/
}
Пример #4
0
void
kernel_bootstrap(void)
{
	kern_return_t	result;
	thread_t	thread;
	char		namep[16];

	printf("%s\n", version); /* log kernel version */

	if (PE_parse_boot_argn("-l", namep, sizeof (namep))) /* leaks logging */
		turn_on_log_leaks = 1;

	PE_parse_boot_argn("trace", &new_nkdbufs, sizeof (new_nkdbufs));
	PE_parse_boot_argn("trace_wake", &wake_nkdbufs, sizeof (wake_nkdbufs));
	PE_parse_boot_argn("trace_panic", &write_trace_on_panic, sizeof(write_trace_on_panic));
	PE_parse_boot_argn("trace_typefilter", &trace_typefilter, sizeof(trace_typefilter));

	scale_setup();

	kernel_bootstrap_log("vm_mem_bootstrap");
	vm_mem_bootstrap();

	kernel_bootstrap_log("cs_init");
	cs_init();

	kernel_bootstrap_log("vm_mem_init");
	vm_mem_init();

	machine_info.memory_size = (uint32_t)mem_size;
	machine_info.max_mem = max_mem;
	machine_info.major_version = version_major;
	machine_info.minor_version = version_minor;


#if CONFIG_TELEMETRY
	kernel_bootstrap_log("telemetry_init");
	telemetry_init();
#endif

#if CONFIG_CSR
	kernel_bootstrap_log("csr_init");
	csr_init();
#endif

	kernel_bootstrap_log("stackshot_lock_init");	
	stackshot_lock_init();

	kernel_bootstrap_log("sched_init");
	sched_init();

	kernel_bootstrap_log("waitq_bootstrap");
	waitq_bootstrap();

	kernel_bootstrap_log("ipc_bootstrap");
	ipc_bootstrap();

#if CONFIG_MACF
	kernel_bootstrap_log("mac_policy_init");
	mac_policy_init();
#endif

	kernel_bootstrap_log("ipc_init");
	ipc_init();

	/*
	 * As soon as the virtual memory system is up, we record
	 * that this CPU is using the kernel pmap.
	 */
	kernel_bootstrap_log("PMAP_ACTIVATE_KERNEL");
	PMAP_ACTIVATE_KERNEL(master_cpu);

	kernel_bootstrap_log("mapping_free_prime");
	mapping_free_prime();						/* Load up with temporary mapping blocks */

	kernel_bootstrap_log("machine_init");
	machine_init();

	kernel_bootstrap_log("clock_init");
	clock_init();

	ledger_init();

	/*
	 *	Initialize the IPC, task, and thread subsystems.
	 */
#if CONFIG_COALITIONS
	kernel_bootstrap_log("coalitions_init");
	coalitions_init();
#endif

	kernel_bootstrap_log("task_init");
	task_init();

	kernel_bootstrap_log("thread_init");
	thread_init();

#if CONFIG_ATM
	/* Initialize the Activity Trace Resource Manager. */
	kernel_bootstrap_log("atm_init");
	atm_init();
#endif

#if CONFIG_BANK
	/* Initialize the BANK Manager. */
	kernel_bootstrap_log("bank_init");
	bank_init();
#endif
	
	/* initialize the corpse config based on boot-args */
	corpses_init();

	/*
	 *	Create a kernel thread to execute the kernel bootstrap.
	 */
	kernel_bootstrap_log("kernel_thread_create");
	result = kernel_thread_create((thread_continue_t)kernel_bootstrap_thread, NULL, MAXPRI_KERNEL, &thread);

	if (result != KERN_SUCCESS) panic("kernel_bootstrap: result = %08X\n", result);

	thread->state = TH_RUN;
	thread->last_made_runnable_time = mach_absolute_time();
	thread_deallocate(thread);

	kernel_bootstrap_log("load_context - done");
	load_context(thread);
	/*NOTREACHED*/
}
Пример #5
0
/*
 *	Running in virtual memory, on the interrupt stack.
 *	Does not return.  Dispatches initial thread.
 *
 *	Assumes that master_cpu is set.
 */
void
setup_main(void)
{
	thread_t		startup_thread;

	printf_init();
	panic_init();

	sched_init();
	vm_mem_bootstrap();
	ipc_bootstrap();
	vm_mem_init();
	ipc_init();

	/*
	 * As soon as the virtual memory system is up, we record
	 * that this CPU is using the kernel pmap.
	 */
	PMAP_ACTIVATE_KERNEL(master_cpu);

	init_timers();
	timeout_init();

#if	CDLI > 0
	ns_init();	/* Initialize CDLI */
#endif	/* CDLI > 0 */

	dev_lookup_init();
	timeout_init();
	machine_init();

	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;

#if	XPR_DEBUG
	xprbootstrap();
#endif	/* XPR_DEBUG */

	/*
	 *	Initialize the IPC, task, and thread subsystems.
	 */
	clock_init();
	utime_init();
        ledger_init();
#if	THREAD_SWAPPER
	thread_swapper_init();
#endif	/* THREAD_SWAPPER */
#if	TASK_SWAPPER
	task_swapper_init();
#endif	/* TASK_SWAPPER */
	task_init();
	act_init();
	thread_init();
	subsystem_init();
#if	TASK_SWAPPER
	task_swappable(&realhost, kernel_task, FALSE);
#endif	/* TASK_SWAPPER */
#if	MACH_HOST
	pset_sys_init();
#endif	/* MACH_HOST */

	/*
	 *	Kick off the time-out driven routines by calling
	 *	them the first time.
	 */
	recompute_priorities();
	compute_mach_factor();

	/*
	 *	Initialize the Event Trace Analysis Package.
	 * 	Dynamic Phase: 2 of 2
	 */
	etap_init_phase2();
	
	/*
	 *	Create a kernel thread to start the other kernel
	 *	threads.  Thread_resume (from kernel_thread) calls
	 *	thread_setrun, which may look at current thread;
	 *	we must avoid this, since there is no current thread.
	 */

	/*
	 * Create the thread, and point it at the routine.
	 */
	(void) thread_create_at(kernel_task, &startup_thread,
							start_kernel_threads);
#if	NCPUS > 1 && PARAGON860
	thread_bind(startup_thread, cpu_to_processor(master_cpu));
#endif
	/*
	 * Pretend it is already running, and resume it.
	 * Since it looks as if it is running, thread_resume
	 * will not try to put it on the run queues.
	 *
	 * We can do all of this without locking, because nothing
	 * else is running yet.
	 */
	startup_thread->state |= TH_RUN;
	(void) thread_resume(startup_thread->top_act);

	/*
	 * Start the thread.
	 */
	cpu_launch_first_thread(startup_thread);
	/*NOTREACHED*/
	panic("cpu_launch_first_thread returns!");
}
Пример #6
0
/*
 *	Running in virtual memory, on the interrupt stack.
 *	Does not return.  Dispatches initial thread.
 *
 *	Assumes that master_cpu is set.
 */
void setup_main()
{
	thread_t		startup_thread;

	panic_init();
	printf_init();

	sched_init();
	vm_mem_bootstrap();
	ipc_bootstrap();
	vm_mem_init();
	ipc_init();

	/*
	 * As soon as the virtual memory system is up, we record
	 * that this CPU is using the kernel pmap.
	 */
	PMAP_ACTIVATE_KERNEL(master_cpu);

	init_timers();
	init_timeout();

#if	XPR_DEBUG
	xprbootstrap();
#endif	XPR_DEBUG

	timestamp_init();

	mapable_time_init();

	machine_init();

	machine_info.max_cpus = NCPUS;
	machine_info.memory_size = phys_last_addr - phys_first_addr; /* XXX mem_size */
	machine_info.avail_cpus = 0;
	machine_info.major_version = KERNEL_MAJOR_VERSION;
	machine_info.minor_version = KERNEL_MINOR_VERSION;

	/*
	 *	Initialize the IPC, task, and thread subsystems.
	 */
	task_init();
	thread_init();
	swapper_init();
#if	MACH_HOST
	pset_sys_init();
#endif	MACH_HOST

	/*
	 *	Kick off the time-out driven routines by calling
	 *	them the first time.
	 */
	recompute_priorities();
	compute_mach_factor();
	
	/*
	 *	Create a kernel thread to start the other kernel
	 *	threads.  Thread_resume (from kernel_thread) calls
	 *	thread_setrun, which may look at current thread;
	 *	we must avoid this, since there is no current thread.
	 */

	/*
	 * Create the thread, and point it at the routine.
	 */
	(void) thread_create(kernel_task, &startup_thread);
	thread_start(startup_thread, start_kernel_threads);

	/*
	 * Give it a kernel stack.
	 */
	thread_doswapin(startup_thread);

	/*
	 * Pretend it is already running, and resume it.
	 * Since it looks as if it is running, thread_resume
	 * will not try to put it on the run queues.
	 *
	 * We can do all of this without locking, because nothing
	 * else is running yet.
	 */
	startup_thread->state |= TH_RUN;
	(void) thread_resume(startup_thread);

	/*
	 * Start the thread.
	 */
	cpu_launch_first_thread(startup_thread);
	/*NOTREACHED*/
}