Пример #1
0
/*
 * Start secondary processors in motion.
 */
void
cpu_boot_secondary_processors()
{
	int i, pstate;
	struct cpu_info *ci;

	sparc64_ipi_init();

	for (ci = cpus; ci != NULL; ci = ci->ci_next) {
		if (ci->ci_cpuid == CPU_UPAID)
			continue;

		cpu_pmap_prepare(ci, false);
		cpu_args->cb_node = ci->ci_node;
		cpu_args->cb_cpuinfo = ci->ci_paddr;
		membar_sync();

		/* Disable interrupts and start another CPU. */
		pstate = getpstate();
		setpstate(PSTATE_KERN);

		prom_startcpu(ci->ci_node, (void *)cpu_spinup_trampoline, 0);

		for (i = 0; i < 2000; i++) {
			membar_sync();
			if (CPUSET_HAS(cpus_active, ci->ci_index))
				break;
			delay(10000);
		}
		setpstate(pstate);

		if (!CPUSET_HAS(cpus_active, ci->ci_index))
			printf("cpu%d: startup failed\n", ci->ci_cpuid);
	}
}
Пример #2
0
/*
 * Internal cpu startup sequencer
 * The sequence is as follows:
 *
 * MASTER	SLAVE
 * -------	----------
 * assume the kernel data is initialized
 * clear the proxy bit
 * start the slave cpu
 * wait for the slave cpu to set the proxy
 *
 *		the slave runs slave_startup and then sets the proxy
 *		the slave waits for the master to add slave to the ready set
 *
 * the master finishes the initialization and
 * adds the slave to the ready set
 *
 *		the slave exits the startup thread and is running
 */
void
start_cpu(int cpuid, void(*flag_func)(int))
{
	extern void cpu_startup(int);
	int timout;

	ASSERT(MUTEX_HELD(&cpu_lock));

	/*
	 * Before we begin the dance, tell DTrace that we're about to start
	 * a CPU.
	 */
	if (dtrace_cpustart_init != NULL)
		(*dtrace_cpustart_init)();

	/* start the slave cpu */
	CPUSET_DEL(proxy_ready_set, cpuid);
	if (prom_test("SUNW,start-cpu-by-cpuid") == 0) {
		(void) prom_startcpu_bycpuid(cpuid, (caddr_t)&cpu_startup,
		    cpuid);
	} else {
		/* "by-cpuid" interface didn't exist.  Do it the old way */
		pnode_t nodeid = cpunodes[cpuid].nodeid;

		ASSERT(nodeid != (pnode_t)0);
		(void) prom_startcpu(nodeid, (caddr_t)&cpu_startup, cpuid);
	}

	/* wait for the slave cpu to check in. */
	for (timout = CPU_WAKEUP_GRACE_MSEC; timout; timout--) {
		if (CPU_IN_SET(proxy_ready_set, cpuid))
			break;
		DELAY(1000);
	}
	if (timout == 0) {
		panic("cpu%d failed to start (2)", cpuid);
	}

	/*
	 * The slave has started; we can tell DTrace that it's safe again.
	 */
	if (dtrace_cpustart_fini != NULL)
		(*dtrace_cpustart_fini)();

	/* run the master side of stick synchronization for the slave cpu */
	sticksync_master();

	/*
	 * deal with the cpu flags in a phase-specific manner
	 * for various reasons, this needs to run after the slave
	 * is checked in but before the slave is released.
	 */
	(*flag_func)(cpuid);

	/* release the slave */
	CPUSET_ADD(cpu_ready_set, cpuid);
}
Пример #3
0
/*
 * Start secondary processors in motion.
 */
void
cpu_boot_secondary_processors(void)
{
	int i, pstate;
	struct cpu_info *ci;

	sync_tick = 0;

	sparc64_ipi_init();

	if (boothowto & RB_MD1) {
		cpus[0].ci_next = NULL;
		sparc_ncpus = ncpu = ncpuonline = 1;
		return;
	}

	for (ci = cpus; ci != NULL; ci = ci->ci_next) {
		if (ci->ci_cpuid == CPU_UPAID)
			continue;

		cpu_pmap_prepare(ci, false);
		cpu_args->cb_node = ci->ci_node;
		cpu_args->cb_cpuinfo = ci->ci_paddr;
		membar_Sync();

		/* Disable interrupts and start another CPU. */
		pstate = getpstate();
		setpstate(PSTATE_KERN);

		prom_startcpu(ci->ci_node, (void *)cpu_spinup_trampoline, 0);

		for (i = 0; i < 2000; i++) {
			membar_Sync();
			if (CPUSET_HAS(cpus_active, ci->ci_index))
				break;
			delay(10000);
		}

		/* synchronize %tick ( to some degree at least ) */
		delay(1000);
		sync_tick = 1;
		membar_Sync();
		settick(0);
		if (ci->ci_system_clockrate[0] != 0)
			setstick(0);

		setpstate(pstate);

		if (!CPUSET_HAS(cpus_active, ci->ci_index))
			printf("cpu%d: startup failed\n", ci->ci_cpuid);
	}
}