예제 #1
0
void MacRISC2CPU::haltCPU(void)
{
	OSIterator 		*childIterator;
	IORegistryEntry *childEntry, *childDriver;
	IOPCIBridge		*pciDriver;
	OSData			*deviceTypeString;
	UInt32			i;

  
    setCPUState(kIOCPUStateStopped);
  
    if (bootCPU)
    {
		// Some systems require special handling of Ultra-ATA at sleep.
		// Call UniN to prepare for that, if necessary
		uniN->callPlatformFunction ("setupUATAforSleep", false, (void *)0, (void *)0, (void *)0, (void *)0);

		// Notify our pci children to save their state
		if (!topLevelPCIBridgeCount) {
			// First build list of top level bridges - only need to do once as these don't change
			if ((childIterator = macRISC2PE->getChildIterator (gIOServicePlane)) != NULL) {
				while ((childEntry = (IORegistryEntry *)(childIterator->getNextObject ())) != NULL) {
					deviceTypeString = OSDynamicCast( OSData, childEntry->getProperty( "device_type" ));
					if (deviceTypeString) {
						if (!strcmp((const char *)deviceTypeString->getBytesNoCopy(), "pci")) {
							childDriver = childEntry->copyChildEntry(gIOServicePlane);
							if (childDriver) {
								pciDriver = OSDynamicCast( IOPCIBridge, childDriver );
								if (pciDriver)
									if (topLevelPCIBridgeCount < kMaxPCIBridges)
										// Remember this driver
										topLevelPCIBridges[topLevelPCIBridgeCount++] = pciDriver;
									else
										kprintf ("MacRISC2CPU::haltCPU - warning, more than %d PCI bridges - cannot save/restore them all\n", kMaxPCIBridges);
								childDriver->release();
							}
						}
					}
				}
				childIterator->release();
			}
		}
		for (i = 0; i < topLevelPCIBridgeCount; i++)
			if (pciDriver = topLevelPCIBridges[i]) {
				// Got the driver - send the message
				pciDriver->setDevicePowerState (NULL, 2);
			}
    }

   kprintf("MacRISC2CPU::haltCPU %ld Here!\n", getCPUNumber());

   processor_exit(machProcessor);
}
예제 #2
0
int
main(int argc, char **argv)
{
    kern_return_t          kr;
    host_priv_t            host_priv;
    processor_port_array_t processor_list;
    natural_t              processor_count;
    char                  *errmsg = PROGNAME;
   
    if (argc != 2) {
        fprintf(stderr,
                "usage: %s <cmd>, where <cmd> is \"exit\" or \"start\"\n",
                PROGNAME);
        exit(1);
    }
   
    kr = host_get_host_priv_port(mach_host_self(), &host_priv);
    EXIT_ON_MACH_ERROR("host_get_host_priv_port:", kr);   
   
    kr = host_processors(host_priv, &processor_list, &processor_count);
    EXIT_ON_MACH_ERROR("host_processors:", kr);
   
    // disable last processor on a multiprocessor system
    if (processor_count > 1) {
        if (*argv[1] == 'e') {
            kr = processor_exit(processor_list[processor_count - 1]);
            errmsg = "processor_exit:";
        } else if (*argv[1] == 's') {
            kr = processor_start(processor_list[processor_count - 1]);
            errmsg = "processor_start:";
        } else {
            kr = KERN_INVALID_ARGUMENT;
        }
    } else
        printf("Only one processor!\n");
   
    // this will deallocate while rounding up to page size
    (void)vm_deallocate(mach_task_self(), (vm_address_t)processor_list,
                        processor_count * sizeof(processor_t *));
    EXIT_ON_MACH_ERROR(errmsg, kr);
   
    fprintf(stderr, "%s successful\n", errmsg);
   
    exit(0);
}
예제 #3
0
__private_extern__
kern_return_t chudxnu_enable_cpu(int cpu, boolean_t enable)
{
    chudxnu_unbind_thread(current_thread(), 0);
	
    if(cpu < 0 || (unsigned int)cpu >= real_ncpus) // sanity check
        return KERN_FAILURE;
	
	if((cpu_data_ptr[cpu] != NULL) && cpu != master_cpu) {
		processor_t processor = cpu_to_processor(cpu);
		
		if(processor == master_processor) // don't mess with the boot processor
			return KERN_FAILURE;

        if(enable) {
            return processor_start(processor);
        } else {
            return processor_exit(processor);
        }
    }
    return KERN_FAILURE;
}