Example #1
1
/*
 *	Routine:	cpu_start
 *	Function:
 */
kern_return_t
cpu_start(
	int cpu)
{
	struct per_proc_info	*proc_info;
	kern_return_t			ret;
	mapping_t				*mp;

	proc_info = PerProcTable[cpu].ppe_vaddr;

	if (cpu == cpu_number()) {
 	  PE_cpu_machine_init(proc_info->cpu_id, !(proc_info->cpu_flags & BootDone));
	  ml_init_interrupt();
	  proc_info->cpu_flags |= BootDone|SignalReady;

	  return KERN_SUCCESS;
	} else {
		proc_info->cpu_flags &= BootDone;
		proc_info->interrupts_enabled = 0;
		proc_info->pending_ast = AST_NONE;
		proc_info->istackptr = proc_info->intstack_top_ss;
		proc_info->rtcPop = EndOfAllTime;
		proc_info->FPU_owner = NULL;
		proc_info->VMX_owner = NULL;
		proc_info->pms.pmsStamp = 0;									/* Dummy transition time */
		proc_info->pms.pmsPop = EndOfAllTime;							/* Set the pop way into the future */
		proc_info->pms.pmsState = pmsParked;							/* Park the stepper */
		proc_info->pms.pmsCSetCmd = pmsCInit;							/* Set dummy initial hardware state */
		mp = (mapping_t *)(&proc_info->ppUMWmp);
		mp->mpFlags = 0x01000000 | mpLinkage | mpPerm | 1;
		mp->mpSpace = invalSpace;

		if (proc_info->start_paddr == EXCEPTION_VECTOR(T_RESET)) {

			simple_lock(&rht_lock);
			while (rht_state & RHT_BUSY) {
				rht_state |= RHT_WAIT;
				thread_sleep_usimple_lock((event_t)&rht_state,
						    &rht_lock, THREAD_UNINT);
			}
			rht_state |= RHT_BUSY;
			simple_unlock(&rht_lock);

			ml_phys_write((vm_offset_t)&ResetHandler + 0,
					  RESET_HANDLER_START);
			ml_phys_write((vm_offset_t)&ResetHandler + 4,
					  (vm_offset_t)_start_cpu);
			ml_phys_write((vm_offset_t)&ResetHandler + 8,
					  (vm_offset_t)&PerProcTable[cpu]);
		}
/*
 *		Note: we pass the current time to the other processor here. He will load it
 *		as early as possible so that there is a chance that it is close to accurate.
 *		After the machine is up a while, we will officially resync the clocks so
 *		that all processors are the same.  This is just to get close.
 */

		ml_get_timebase((unsigned long long *)&proc_info->ruptStamp);
		
		__asm__ volatile("sync");				/* Commit to storage */
		__asm__ volatile("isync");				/* Wait a second */
		ret = PE_cpu_start(proc_info->cpu_id,
						   proc_info->start_paddr, (vm_offset_t)proc_info);

		if (ret != KERN_SUCCESS) {
			if (proc_info->start_paddr == EXCEPTION_VECTOR(T_RESET)) {
				simple_lock(&rht_lock);
				if (rht_state & RHT_WAIT)
					thread_wakeup(&rht_state);
				rht_state &= ~(RHT_BUSY|RHT_WAIT);
				simple_unlock(&rht_lock);
			};
		} else {
			simple_lock(&SignalReadyLock);
			if (!((*(volatile short *)&proc_info->cpu_flags) & SignalReady)) {
				(void)hw_atomic_or(&proc_info->ppXFlags, SignalReadyWait);
				thread_sleep_simple_lock((event_t)&proc_info->cpu_flags,
				                          &SignalReadyLock, THREAD_UNINT);
			}
			simple_unlock(&SignalReadyLock);

		}
		return(ret);
	}
}
Example #2
0
/*
 *	Routine:	cpu_machine_init
 *	Function:
 */
void
cpu_machine_init(
	void)
{
	struct per_proc_info			*proc_info;
	volatile struct per_proc_info	*mproc_info;


	proc_info = getPerProc();
	mproc_info = PerProcTable[master_cpu].ppe_vaddr;

	if (proc_info != mproc_info) {
		simple_lock(&rht_lock);
		if (rht_state & RHT_WAIT)
			thread_wakeup(&rht_state);
		rht_state &= ~(RHT_BUSY|RHT_WAIT);
		simple_unlock(&rht_lock);
	}

	PE_cpu_machine_init(proc_info->cpu_id, !(proc_info->cpu_flags & BootDone));

	if (proc_info->hibernate) {
		uint32_t	tbu, tbl;

		do {
			tbu = mftbu();
			tbl = mftb();
		} while (mftbu() != tbu);

	    proc_info->hibernate = 0;
	    hibernate_machine_init();

		// hibernate_machine_init() could take minutes and we don't want timeouts
		// to fire as soon as scheduling starts. Reset timebase so it appears
		// no time has elapsed, as it would for regular sleep.
		mttb(0);
		mttbu(tbu);
		mttb(tbl);
	}

	if (proc_info != mproc_info) {
	while (!((mproc_info->cpu_flags) & SignalReady)) 
			continue;
		cpu_sync_timebase();
	}

	ml_init_interrupt();
	if (proc_info != mproc_info)
		simple_lock(&SignalReadyLock);
	proc_info->cpu_flags |= BootDone|SignalReady;
	if (proc_info != mproc_info) {
		if (proc_info->ppXFlags & SignalReadyWait) {
			(void)hw_atomic_and(&proc_info->ppXFlags, ~SignalReadyWait);
			thread_wakeup(&proc_info->cpu_flags);
		}
		simple_unlock(&SignalReadyLock);
		pmsPark();						/* Timers should be cool now, park the power management stepper */
	}
}
Example #3
0
File: cpu.c Project: Bitesher/xnu
void
cpu_machine_init(
	void)
{
	cpu_data_t	*cdp = current_cpu_datap();

	PE_cpu_machine_init(cdp->cpu_id, !cdp->cpu_boot_complete);
	cdp->cpu_boot_complete = TRUE;
	cdp->cpu_running = TRUE;
	ml_init_interrupt();

#if CONFIG_VMX
	/* for every CPU, get the VT specs */
	vmx_get_specs();
#endif
}