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); }
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); }
__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; }