コード例 #1
1
ファイル: MacRISC2CPU.cpp プロジェクト: AzerTyQsdF/osx
void MacRISC2CPU::quiesceCPU(void)
{
    if (bootCPU)
    {
        if (processorSpeedChange) {
            // Send PMU command to speed the system
            pmu->callPlatformFunction("setSpeedNow", false, (void *)currentProcessorSpeed, 0, 0, 0);
        } else {
			// Send PMU command to shutdown system before io is turned off

			if (!gPHibernateState || !*gPHibernateState)
				pmu->callPlatformFunction("sleepNow", false, 0, 0, 0, 0);
	
			// Disables the interrupts for this CPU.
			if (!haveSleptMPIC && (macRISC2PE->getMachineType() == kMacRISC2TypePowerMac))
			{
				haveSleptMPIC = true;
				kprintf("MacRISC2CPU::quiesceCPU %ld -> mpic->setUpForSleep off", getCPUNumber());
				mpic->callPlatformFunction(mpic_setUpForSleep, false, (void *)true, (void *)getCPUNumber(), 0, 0);
			}
	
			kprintf("MacRISC2CPU::quiesceCPU %ld -> keyLargo->saveRegisterState()\n", getCPUNumber());
			// Save KeyLargo's register state.
			keyLargo->callPlatformFunction(keyLargo_saveRegisterState, false, 0, 0, 0, 0);
	
			// Turn Off all KeyLargo I/O.
			if (!gPHibernateState || !*gPHibernateState)
			{
			    kprintf("MacRISC2CPU::quiesceCPU %ld -> keyLargo->turnOffIO\n", getCPUNumber());
				keyLargo->callPlatformFunction(keyLargo_turnOffIO, false, (void *)false, 0, 0, 0);
			}
        }
        
        kprintf("MacRISC2CPU::quiesceCPU %ld -> here\n", getCPUNumber());

        // Set the wake vector to point to the reset vector
        ml_phys_write(0x0080, 0x100);

        uniN->callPlatformFunction (uniN_setPowerState, false, 
                (void *)(kUniNSave),
                (void *)0, (void *)0, (void *)0);

        if (processorSpeedChange || (!gPHibernateState || !*gPHibernateState)) {
        	// Set the sleeping state for HWInit.
			// Tell Uni-N to enter normal mode.
			uniN->callPlatformFunction (uniN_setPowerState, false, 
				(void *)(processorSpeedChange ? kUniNIdle2 : kUniNSleep),
				(void *)0, (void *)0, (void *)0);
		}
    }

    ml_ppc_sleep();
}
コード例 #2
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);
	}
}
コード例 #3
0
/*
 *	Routine:	cpu_sleep
 *	Function:
 */
void
cpu_sleep(
	void)
{
	struct per_proc_info	*proc_info;
	unsigned int			i;
	unsigned int			wait_ncpus_sleep, ncpus_sleep;
	facility_context		*fowner;

	proc_info = getPerProc();

	proc_info->running = FALSE;

	fowner = proc_info->FPU_owner;					/* Cache this */
	if(fowner) /* If anyone owns FPU, save it */
		fpu_save(fowner);
	proc_info->FPU_owner = NULL;						/* Set no fpu owner now */

	fowner = proc_info->VMX_owner;					/* Cache this */
	if(fowner) vec_save(fowner);					/* If anyone owns vectors, save it */
	proc_info->VMX_owner = NULL;						/* Set no vector owner now */

	if (proc_info->cpu_number == master_cpu)  {
		proc_info->cpu_flags &= BootDone;
		proc_info->interrupts_enabled = 0;
		proc_info->pending_ast = AST_NONE;

		if (proc_info->start_paddr == EXCEPTION_VECTOR(T_RESET)) {
			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[master_cpu]);

			__asm__ volatile("sync");
			__asm__ volatile("isync");
		}