Loading...
iokit/Kernel/IOPMrootDomain.cpp xnu-12377.121.6 xnu-7195.141.2
--- xnu/xnu-12377.121.6/iokit/Kernel/IOPMrootDomain.cpp
+++ xnu/xnu-7195.141.2/iokit/Kernel/IOPMrootDomain.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2021 Apple Inc. All rights reserved.
+ * Copyright (c) 1998-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -28,7 +28,6 @@
 
 #define IOKIT_ENABLE_SHARED_PTR
 
-#include <libkern/c++/OSAllocation.h>
 #include <libkern/c++/OSKext.h>
 #include <libkern/c++/OSMetaClass.h>
 #include <libkern/OSAtomic.h>
@@ -54,14 +53,12 @@
 #include <IOKit/IOCatalogue.h>
 #include <IOKit/IOReportMacros.h>
 #include <IOKit/IOLib.h>
-#include <IOKit/IOKitKeysPrivate.h>
+#include <IOKit/IOKitKeys.h>
 #include <IOKit/IOUserServer.h>
-#include <IOKit/IOBSD.h>
 #include "IOKitKernelInternal.h"
 #if HIBERNATION
 #include <IOKit/IOHibernatePrivate.h>
 #endif /* HIBERNATION */
-#include <machine/machine_routines.h>
 #include <console/video_console.h>
 #include <sys/syslog.h>
 #include <sys/sysctl.h>
@@ -69,8 +66,6 @@
 #include <sys/vnode_internal.h>
 #include <sys/fcntl.h>
 #include <os/log.h>
-#include <os/log_private.h>
-#include <pexpert/device_tree.h>
 #include <pexpert/protos.h>
 #include <AssertMacros.h>
 
@@ -80,17 +75,11 @@
 
 #include <libkern/zlib.h>
 #include <os/cpp_util.h>
-#include <os/atomic_private.h>
 #include <libkern/c++/OSBoundedArrayRef.h>
-
-#if DEVELOPMENT || DEBUG
-#include <os/system_event_log.h>
-#endif /* DEVELOPMENT || DEBUG */
 
 __BEGIN_DECLS
 #include <mach/shared_region.h>
 #include <kern/clock.h>
-#include <vm/vm_pageout_xnu.h>
 __END_DECLS
 
 #if defined(__i386__) || defined(__x86_64__)
@@ -99,8 +88,6 @@
 const char *processor_to_datastring(const char *prefix, processor_t target_processor);
 __END_DECLS
 #endif
-
-#define ARRAY_LEN(x) (sizeof (x) / sizeof (x[0]))
 
 #define kIOPMrootDomainClass    "IOPMrootDomain"
 #define LOG_PREFIX              "PMRD: "
@@ -124,7 +111,7 @@
 
 #define DLOG(x...)  do { \
     if (kIOLogPMRootDomain & gIOKitDebug) \
-	IOLog(LOG_PREFIX x); \
+	kprintf(LOG_PREFIX x); \
     else \
 	os_log(OS_LOG_DEFAULT, LOG_PREFIX x); \
 } while (false)
@@ -193,8 +180,7 @@
 	kPowerEventPublishSleepWakeUUID,           // 13
 	kPowerEventSetDisplayPowerOn,              // 14
 	kPowerEventPublishWakeType,                // 15
-	kPowerEventAOTEvaluate,                    // 16
-	kPowerEventRunModeRequest                  // 17
+	kPowerEventAOTEvaluate                     // 16
 };
 
 // For evaluatePolicy()
@@ -319,16 +305,7 @@
 	                   | kIOPMSupportedOnUPS)
 
 #define kLocalEvalClamshellCommand  (1 << 15)
-#define kIdleSleepRetryInterval     (3 * 60 * 1000)
-
-// Minimum time in milliseconds after AP wake that we allow idle timer to expire.
-// We impose this minimum to avoid race conditions in the AP wake path where
-// userspace clients are not able to acquire power assertions before the idle timer expires.
-#if XNU_TARGET_OS_IOS
-#define kMinimumTimeBeforeIdleSleep     3000
-#else
-#define kMinimumTimeBeforeIdleSleep     1000
-#endif
+#define kIdleSleepRetryInterval     (3 * 60)
 
 #define DISPLAY_WRANGLER_PRESENT    (!NO_KERNEL_HID)
 
@@ -337,6 +314,15 @@
 	kWranglerPowerStateSleep = 2,
 	kWranglerPowerStateDim   = 3,
 	kWranglerPowerStateMax   = 4
+};
+
+enum {
+	OFF_STATE           = 0,
+	RESTART_STATE       = 1,
+	SLEEP_STATE         = 2,
+	AOT_STATE           = 3,
+	ON_STATE            = 4,
+	NUM_POWER_STATES
 };
 
 const char *
@@ -481,7 +467,6 @@
 	kPMChildPreventSystemSleep,
 	kPMCPUAssertion,
 	kPMPCIUnsupported,
-	kPMDKNotReady,
 };
 
 const char *
@@ -495,7 +480,6 @@
 		SYSTEM_SLEEP_PREVENTER( kPMChildPreventSystemSleep ),
 		SYSTEM_SLEEP_PREVENTER( kPMCPUAssertion ),
 		SYSTEM_SLEEP_PREVENTER( kPMPCIUnsupported ),
-		SYSTEM_SLEEP_PREVENTER( kPMDKNotReady ),
 		{ 0, NULL }
 	};
 	return IOFindNameForValue(preventer, systemSleepPreventers);
@@ -552,7 +536,7 @@
 #if defined(XNU_TARGET_OS_OSX)
 #if DISPLAY_WRANGLER_PRESENT
 static uint32_t         gDarkWakeFlags = kDarkWakeFlagPromotionNone;
-#elif defined(__arm64__)
+#elif CONFIG_ARROW
 // Enable temporary full wake promotion workarounds
 static uint32_t         gDarkWakeFlags = kDarkWakeFlagUserWakeWorkaround;
 #else
@@ -620,7 +604,6 @@
 static char gWakeReasonString[128];
 static char gBootReasonString[80];
 static char gShutdownReasonString[80];
-static uint64_t gShutdownTime;
 static bool gWakeReasonSysctlRegistered = false;
 static bool gBootReasonSysctlRegistered = false;
 static bool gShutdownReasonSysctlRegistered = false;
@@ -696,7 +679,7 @@
 	IOPMSettingControllerCallback   func;
 	OSObject                        *target;
 	uintptr_t                       refcon;
-	OSDataAllocation<uint32_t>      publishedFeatureID;
+	uint32_t                        *publishedFeatureID;
 	uint32_t                        settingCount;
 	bool                            disabled;
 
@@ -769,90 +752,6 @@
 	uint8_t                     coreGraphicsData;
 };
 
-struct IOPMAssertionLog {
-	IOPMAssertionLogData data;
-
-	mach_port_t  notificationPort;
-	uint64_t     notificationThreshold;
-
-public:
-	IOReturn
-	setNotificationThreshold(uint64_t threshold)
-	{
-		if (threshold > ARRAY_LEN(data.intervals)) {
-			return kIOReturnBadArgument;
-		}
-		notificationThreshold = threshold;
-		return kIOReturnSuccess;
-	}
-
-	IOReturn
-	setNotificationPort(mach_port_t port)
-	{
-		if (port != MACH_PORT_NULL && notificationPort != MACH_PORT_NULL) {
-			return kIOReturnExclusiveAccess;
-		}
-
-		notificationPort = port;
-		return kIOReturnSuccess;
-	}
-
-	void
-	notify()
-	{
-		if (notificationPort == MACH_PORT_NULL) {
-			return;
-		}
-
-		mach_msg_header_t msg;
-		msg.msgh_bits         = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_COPY_SEND, 0, 0, 0);
-		msg.msgh_id           = 0;
-		msg.msgh_size         = sizeof(mach_msg_header_t);
-		msg.msgh_local_port   = MACH_PORT_NULL;
-		msg.msgh_remote_port  = notificationPort;
-		(void)mach_msg_send_from_kernel_with_options(&msg, msg.msgh_size, MACH64_SEND_TIMEOUT, MACH_MSG_TIMEOUT_NONE);
-	}
-
-	void
-	addInterval(IOPMDriverAssertionID id, uint64_t create_timestamp, uint64_t delete_timestamp)
-	{
-		IOPMAssertionLogData::Interval& interval = data.intervals[data.intervals_pos++ % ARRAY_LEN(data.intervals)];
-		interval.id = id;
-		interval.create_timestamp = create_timestamp;
-		interval.delete_timestamp = delete_timestamp;
-
-		if (notificationPort && notificationThreshold == (data.intervals_pos % ARRAY_LEN(data.intervals))) {
-			notify();
-		}
-	}
-
-	void
-	addName(IOPMDriverAssertionID id, const char *name)
-	{
-		IOPMAssertionLogData::Properties& prop = data.props[data.props_pos++ % ARRAY_LEN(data.props)];
-		prop.id = id;
-		strlcpy(prop.name, name, sizeof(prop.name));
-	}
-};
-
-/*
- * this should be treated as POD, as it's byte-copied around
- * and we cannot rely on d'tor firing at the right time
- */
-struct PMAssertStruct {
-	IOPMDriverAssertionID       id;
-	IOPMDriverAssertionType     assertionBits;
-	uint64_t                    createdTime;
-	uint64_t                    modifiedTime;
-	const OSSymbol              *ownerString;
-	IOService                   *ownerService;
-	uint64_t                    registryEntryID;
-	IOPMDriverAssertionLevel    level;
-	uint64_t                    assertCPUStartTime;
-	uint64_t                    assertCPUDuration;
-};
-OSDefineValueObjectForDependentType(PMAssertStruct)
-
 /*
  * PMAssertionsTracker
  * Tracks kernel and user space PM assertions
@@ -872,21 +771,38 @@
 	IOPMDriverAssertionType     getActivatedAssertions(void);
 	IOPMDriverAssertionLevel    getAssertionLevel(IOPMDriverAssertionType);
 
-	IOReturn                    handleCreateAssertion(OSValueObject<PMAssertStruct> *);
+	IOReturn                    handleCreateAssertion(OSData *);
 	IOReturn                    handleReleaseAssertion(IOPMDriverAssertionID);
 	IOReturn                    handleSetAssertionLevel(IOPMDriverAssertionID, IOPMDriverAssertionLevel);
 	IOReturn                    handleSetUserAssertionLevels(void * arg0);
 	void                        publishProperties(void);
 	void                        reportCPUBitAccounting(void);
-	PMAssertStruct              *detailsForID(IOPMDriverAssertionID, int *);
 
 private:
+	/*
+	 * this should be treated as POD, as it's byte-copied around
+	 * and we cannot rely on d'tor firing at the right time
+	 */
+	typedef struct {
+		IOPMDriverAssertionID       id;
+		IOPMDriverAssertionType     assertionBits;
+		uint64_t                    createdTime;
+		uint64_t                    modifiedTime;
+		const OSSymbol              *ownerString;
+		IOService                   *ownerService;
+		uint64_t                    registryEntryID;
+		IOPMDriverAssertionLevel    level;
+		uint64_t                    assertCPUStartTime;
+		uint64_t                    assertCPUDuration;
+	} PMAssertStruct;
+
 	uint32_t                    tabulateProducerCount;
 	uint32_t                    tabulateConsumerCount;
 
 	uint64_t                    maxAssertCPUDuration;
 	uint64_t                    maxAssertCPUEntryId;
 
+	PMAssertStruct              *detailsForID(IOPMDriverAssertionID, int *);
 	void                        tabulate(void);
 	void                        updateCPUBitAccounting(PMAssertStruct * assertStruct);
 
@@ -897,10 +813,6 @@
 	IOPMDriverAssertionType     assertionsKernel;
 	IOPMDriverAssertionType     assertionsUser;
 	IOPMDriverAssertionType     assertionsCombined;
-
-	IOPMAssertionLog            assertionsLog;
-
-	friend class IOPMrootDomain;
 };
 
 OSDefineMetaClassAndFinalStructors(PMAssertionsTracker, OSObject);
@@ -1050,7 +962,7 @@
 extern  uint32_t                           gFSState;
 
 extern "C" void
-IOSystemShutdownNotification(int howto, int stage)
+IOSystemShutdownNotification(int stage)
 {
 	uint64_t startTime;
 
@@ -1071,7 +983,7 @@
 	if (kIOSystemShutdownNotificationTerminateDEXTs == stage) {
 		uint64_t nano, millis;
 		startTime = mach_absolute_time();
-		IOServicePH::systemHalt(howto);
+		IOServicePH::systemHalt();
 		absolutetime_to_nanoseconds(mach_absolute_time() - startTime, &nano);
 		millis = nano / NSEC_PER_MSEC;
 		if (true || (gHaltTimeMaxLog && (millis >= gHaltTimeMaxLog))) {
@@ -1084,7 +996,7 @@
 
 	IOLockLock(gHaltLogLock);
 	if (!gHaltLog) {
-		gHaltLog = IONewData(char, (vm_size_t)kHaltLogSize);
+		gHaltLog = IONew(char, kHaltLogSize);
 		gHaltStartTime = mach_absolute_time();
 		if (gHaltLog) {
 			halt_log_putc('\n');
@@ -1180,30 +1092,23 @@
 IOPMrootDomain::updateConsoleUsers(void)
 {
 	IOService::updateConsoleUsers(NULL, kIOMessageSystemHasPoweredOn);
-	updateTasksSuspend(kTasksSuspendUnsuspended, kTasksSuspendNoChange);
-}
-
-bool
-IOPMrootDomain::updateTasksSuspend(int newTasksSuspended, int newAOTTasksSuspended)
+	if (tasksSuspended) {
+		tasksSuspended = FALSE;
+		updateTasksSuspend();
+	}
+}
+
+void
+IOPMrootDomain::updateTasksSuspend(void)
 {
 	bool newSuspend;
 
-	WAKEEVENT_LOCK();
-	if (newTasksSuspended != kTasksSuspendNoChange) {
-		tasksSuspended = (newTasksSuspended != kTasksSuspendUnsuspended);
-	}
-	if (newAOTTasksSuspended != kTasksSuspendNoChange) {
-		_aotTasksSuspended = (newAOTTasksSuspended != kTasksSuspendUnsuspended);
-	}
 	newSuspend = (tasksSuspended || _aotTasksSuspended);
 	if (newSuspend == tasksSuspendState) {
-		WAKEEVENT_UNLOCK();
-		return false;
+		return;
 	}
 	tasksSuspendState = newSuspend;
-	WAKEEVENT_UNLOCK();
 	tasks_system_suspend(newSuspend);
-	return true;
 }
 
 //******************************************************************************
@@ -1424,7 +1329,7 @@
 }
 
 SYSCTL_PROC(_kern, OID_AUTO, bootreason,
-    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
+    CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
     NULL, 0, sysctl_bootreason, "A", "");
 
 static int
@@ -1446,26 +1351,6 @@
     CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
     NULL, 0, sysctl_shutdownreason, "A", "shutdownreason");
 
-// This value is meant to represent the last time the device shut down
-// in a unit of the PMU driver's choosing see rdar://138590268 for details
-static int
-sysctl_shutdowntime SYSCTL_HANDLER_ARGS
-{
-	uint64_t shutdownTime = 0;
-
-	if (gRootDomain && gShutdownReasonSysctlRegistered) {
-		gRootDomain->copyShutdownTime(&shutdownTime);
-	} else {
-		return ENOENT;
-	}
-
-	return SYSCTL_OUT(req, &shutdownTime, sizeof(shutdownTime));
-}
-
-SYSCTL_PROC(_kern, OID_AUTO, shutdowntime,
-    CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
-    NULL, 0, sysctl_shutdowntime, "Q", "shutdowntime");
-
 static int
 sysctl_targettype SYSCTL_HANDLER_ARGS
 {
@@ -1487,69 +1372,6 @@
 SYSCTL_PROC(_hw, OID_AUTO, targettype,
     CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
     NULL, 0, sysctl_targettype, "A", "targettype");
-
-static SECURITY_READ_ONLY_LATE(char*) jetsam_properties_product_type_string = NULL;
-static SECURITY_READ_ONLY_LATE(size_t) jetsam_properties_product_type_string_len = 0;
-
-/*
- * SecureDTLookupEntry() is only guaranteed to work before PE_init_iokit(),
- * so we load the jetsam_properties_product_type string (if available) in a startup handler.
- */
-__startup_func
-static void
-sysctl_load_jetsam_properties_product_type(void)
-{
-	DTEntry node;
-	void const *value = NULL;
-	unsigned int size = 0;
-
-	if (kSuccess != SecureDTLookupEntry(nullptr, "/product", &node)) {
-		return;
-	}
-
-	if (kSuccess != SecureDTGetProperty(node, "jetsam-properties-product-type", (void const **) &value, &size)) {
-		return;
-	}
-
-	if (size == 0) {
-		return;
-	}
-
-	jetsam_properties_product_type_string = (char *) zalloc_permanent(size, ZALIGN_NONE);
-	if (jetsam_properties_product_type_string == NULL) {
-		return;
-	}
-
-	memcpy(jetsam_properties_product_type_string, value, size);
-	jetsam_properties_product_type_string_len = size;
-}
-STARTUP(SYSCTL, STARTUP_RANK_MIDDLE, sysctl_load_jetsam_properties_product_type);
-
-static int
-sysctl_jetsam_properties_product_type SYSCTL_HANDLER_ARGS
-{
-	if (jetsam_properties_product_type_string != NULL) {
-		return SYSCTL_OUT(req, jetsam_properties_product_type_string, jetsam_properties_product_type_string_len);
-	}
-
-	IOService * root;
-	OSSharedPtr<OSObject>  obj;
-	OSData *    data;
-	char        tt[32];
-
-	tt[0] = '\0';
-	root = IOService::getServiceRoot();
-	if (root && (obj = root->copyProperty(gIODTTargetTypeKey))) {
-		if ((data = OSDynamicCast(OSData, obj.get()))) {
-			strlcpy(tt, (const char *) data->getBytesNoCopy(), sizeof(tt));
-		}
-	}
-	return sysctl_io_string(req, tt, 0, 0, NULL);
-}
-
-SYSCTL_PROC(_hw, OID_AUTO, jetsam_properties_product_type,
-    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
-    NULL, 0, sysctl_jetsam_properties_product_type, "A", "jetsam_properties_product_type");
 
 static SYSCTL_INT(_debug, OID_AUTO, noidle, CTLFLAG_RW, &gNoIdleFlag, 0, "");
 static SYSCTL_INT(_debug, OID_AUTO, swd_sleep_timeout, CTLFLAG_RW, &gSwdSleepTimeout, 0, "");
@@ -1574,14 +1396,11 @@
 		return ENOENT;
 	}
 	if (NULL == gRootDomain->_aotMetrics) {
-		IOPMAOTMetrics nullMetrics = {};
-		return sysctl_io_opaque(req, &nullMetrics, sizeof(IOPMAOTMetrics), NULL);
+		return ENOENT;
 	}
 	return sysctl_io_opaque(req, gRootDomain->_aotMetrics, sizeof(IOPMAOTMetrics), NULL);
 }
 
-TUNABLE_DT_WRITEABLE(uint32_t, gAOTMode, "/product/iopm",
-    "aot-mode", "aot_mode", 0, TUNABLE_DT_NONE);
 static SYSCTL_PROC(_kern, OID_AUTO, aotmetrics,
     CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED | CTLFLAG_ANYBODY,
     NULL, 0, sysctl_aotmetrics, "S,IOPMAOTMetrics", "");
@@ -1599,7 +1418,10 @@
 		unsigned int oldCount;
 
 		if (mode && !gRootDomain->_aotMetrics) {
-		        gRootDomain->_aotMetrics = IOMallocType(IOPMAOTMetrics);
+		        gRootDomain->_aotMetrics = IONewZero(IOPMAOTMetrics, 1);
+		        if (!gRootDomain->_aotMetrics) {
+		                return ENOMEM;
+			}
 		}
 
 		oldCount = gRootDomain->idleSleepPreventersCount();
@@ -1656,15 +1478,6 @@
 static SYSCTL_PROC(_kern, OID_AUTO, aotmode,
     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED | CTLFLAG_ANYBODY,
     NULL, 0, sysctl_aotmode, "I", "");
-
-TUNABLE_DT(uint32_t, gAOTLingerTimeMS, "/product/iopm",
-    "aot-linger-time-ms", "aot_linger_time_ms", 800, TUNABLE_DT_NONE);
-
-// Low Power Wake tunables
-TUNABLE_DT_WRITEABLE(uint64_t, gLPWFlags, "/product/iopm",
-    "low-power-wake", "low_power_wake", false, TUNABLE_DT_NONE);
-static SYSCTL_QUAD(_kern, OID_AUTO, lowpowerwake, CTLFLAG_RW | CTLFLAG_LOCKED,
-    &gLPWFlags, "Low Power Wake");
 
 //******************************************************************************
 
@@ -1686,7 +1499,7 @@
 //
 //******************************************************************************
 
-#define kRootDomainSettingsCount           21
+#define kRootDomainSettingsCount           20
 #define kRootDomainNoPublishSettingsCount  4
 
 bool
@@ -1732,7 +1545,6 @@
 		gIOPMSettingDebugPowerRelativeKey,
 		OSSymbol::withCString(kIOPMSettingWakeOnRingKey),
 		OSSymbol::withCString(kIOPMSettingRestartOnPowerLossKey),
-		OSSymbol::withCString(kIOPMSettingRestartOnPowerConnectKey),
 		OSSymbol::withCString(kIOPMSettingWakeOnClamshellKey),
 		OSSymbol::withCString(kIOPMSettingWakeOnACChangeKey),
 		OSSymbol::withCString(kIOPMSettingTimeZoneOffsetKey),
@@ -1768,15 +1580,6 @@
 	PE_parse_boot_argn("haltmspanic", &gHaltTimeMaxPanic, sizeof(gHaltTimeMaxPanic));
 	PE_parse_boot_argn("haltmslog", &gHaltTimeMaxLog, sizeof(gHaltTimeMaxLog));
 
-	_aotMode = gAOTMode;
-	_aotLingerTime = gAOTLingerTimeMS;
-	_aotMetrics = _aotMode ? IOMallocType(IOPMAOTMetrics) : NULL;
-
-	// read noidle setting from Device Tree
-	if (PE_get_default("no-idle", &gNoIdleFlag, sizeof(gNoIdleFlag))) {
-		DLOG("Setting gNoIdleFlag to %u from device tree\n", gNoIdleFlag);
-	}
-
 	queue_init(&aggressivesQueue);
 	aggressivesThreadCall = thread_call_allocate(handleAggressivesFunction, this);
 	aggressivesData = OSData::withCapacity(
@@ -1826,7 +1629,6 @@
 	userDisabledAllSleep = false;
 	systemBooting = true;
 	idleSleepEnabled = false;
-	idleSleepRevertible = true;
 	sleepSlider = 0;
 	idleSleepTimerPending = false;
 	wrangler = NULL;
@@ -1908,9 +1710,6 @@
 	PMinit(); // creates gIOPMWorkLoop
 	gIOPMWorkLoop = getIOPMWorkloop();
 
-	commandGate = IOCommandGate::commandGate(gIOPMWorkLoop);
-	gIOPMWorkLoop->addEventSource(commandGate.get());
-
 	// Create IOPMPowerStateQueue used to queue external power
 	// events, and to handle those events on the PM work loop.
 	pmPowerStateQueue = IOPMPowerStateQueue::PMPowerStateQueue(
@@ -1918,14 +1717,11 @@
 		&IOPMrootDomain::dispatchPowerEvent));
 	gIOPMWorkLoop->addEventSource(pmPowerStateQueue);
 
+	_aotMode = 0;
 	_aotTimerES = IOTimerEventSource::timerEventSource(this,
 	    OSMemberFunctionCast(IOTimerEventSource::Action,
 	    this, &IOPMrootDomain::aotEvaluate));
 	gIOPMWorkLoop->addEventSource(_aotTimerES.get());
-
-	// Avoid publishing service early so gIOPMWorkLoop is
-	// guaranteed to be initialized by rootDomain.
-	publishPMRootDomain();
 
 	// create our power parent
 	gPatriarch = new IORootParent;
@@ -1984,6 +1780,8 @@
 	gWillShutdownSysctlRegistered = true;
 
 #if HIBERNATION
+#if defined(__arm64__)
+#endif /* defined(__arm64__) */
 	IOHibernateSystemInit(this);
 #endif
 
@@ -2055,7 +1853,6 @@
 	OSSharedPtr<const OSSymbol> stall_halt_string                   = OSSymbol::withCString("StallSystemAtHalt");
 	OSSharedPtr<const OSSymbol> battery_warning_disabled_string     = OSSymbol::withCString("BatteryWarningsDisabled");
 	OSSharedPtr<const OSSymbol> idle_seconds_string                 = OSSymbol::withCString("System Idle Seconds");
-	OSSharedPtr<const OSSymbol> idle_milliseconds_string            = OSSymbol::withCString("System Idle Milliseconds");
 	OSSharedPtr<const OSSymbol> sleepdisabled_string                = OSSymbol::withCString("SleepDisabled");
 	OSSharedPtr<const OSSymbol> ondeck_sleepwake_uuid_string        = OSSymbol::withCString(kIOPMSleepWakeUUIDKey);
 	OSSharedPtr<const OSSymbol> loginwindow_progress_string         = OSSymbol::withCString(kIOPMLoginWindowProgressKey);
@@ -2094,12 +1891,7 @@
 		} else if (key->isEqualTo(idle_seconds_string.get())) {
 			if ((n = OSDynamicCast(OSNumber, obj))) {
 				setProperty(key, n);
-				idleMilliSeconds = n->unsigned32BitValue() * 1000;
-			}
-		} else if (key->isEqualTo(idle_milliseconds_string.get())) {
-			if ((n = OSDynamicCast(OSNumber, obj))) {
-				setProperty(key, n);
-				idleMilliSeconds = n->unsigned32BitValue();
+				idleSeconds = n->unsigned32BitValue();
 			}
 		} else if (key->isEqualTo(boot_complete_string.get())) {
 			pmPowerStateQueue->submitPowerEvent(kPowerEventSystemBootCompleted);
@@ -2216,79 +2008,6 @@
 	return return_value;
 }
 
-#if HIBERNATION
-// MARK: -
-// MARK: setLockdownModeHibernation
-// ***************************************************************************
-void
-IOPMrootDomain::setLockdownModeHibernation(uint32_t status)
-{
-	if (!gIOPMWorkLoop->inGate()) {
-		gIOPMWorkLoop->runAction(
-			OSMemberFunctionCast(IOWorkLoop::Action, this,
-			&IOPMrootDomain::setLockdownModeHibernation),
-			this, (void *)(uintptr_t) status);
-		return;
-	}
-
-	ldmHibernateDisable = status;
-	DLOG("ldmHibernateDisable %d\n", status);
-	setProperty("IOPMLDMHibernationDisable", status);
-}
-#endif
-
-IOReturn
-IOPMrootDomain::getAssertionLog(IOPMAssertionLogData *outLog)
-{
-	if (!gIOPMWorkLoop->inGate()) {
-		return gIOPMWorkLoop->runAction(
-			OSMemberFunctionCast(IOWorkLoop::Action, this,
-			&IOPMrootDomain::getAssertionLog),
-			this, (void *)(uintptr_t) outLog);
-	}
-
-	if (!pmAssertions) {
-		return kIOReturnNotFound;
-	}
-
-	*outLog = pmAssertions->assertionsLog.data;
-	return kIOReturnSuccess;
-}
-
-IOReturn
-IOPMrootDomain::setAssertionLogNotificationPort(mach_port_t port)
-{
-	if (!gIOPMWorkLoop->inGate()) {
-		return gIOPMWorkLoop->runAction(
-			OSMemberFunctionCast(IOWorkLoop::Action, this,
-			&IOPMrootDomain::setAssertionLogNotificationPort),
-			this, (void *)(uintptr_t) port);
-	}
-
-	if (!pmAssertions) {
-		return kIOReturnNotFound;
-	}
-
-	return pmAssertions->assertionsLog.setNotificationPort(port);
-}
-
-IOReturn
-IOPMrootDomain::setAssertionLogNotificationThreshold(uint64_t threshold)
-{
-	if (!gIOPMWorkLoop->inGate()) {
-		return gIOPMWorkLoop->runAction(
-			OSMemberFunctionCast(IOWorkLoop::Action, this,
-			&IOPMrootDomain::setAssertionLogNotificationThreshold),
-			this, (void *)(uintptr_t) threshold);
-	}
-
-	if (!pmAssertions) {
-		return kIOReturnNotFound;
-	}
-
-	return pmAssertions->assertionsLog.setNotificationThreshold(threshold);
-}
-
 // MARK: -
 // MARK: Aggressiveness
 
@@ -2331,7 +2050,12 @@
 		    (uint32_t) options, getAggressivenessTypeString((uint32_t) type), (uint32_t) value);
 	}
 
-	request = IOMallocType(AggressivesRequest);
+	request = IONew(AggressivesRequest, 1);
+	if (!request) {
+		return kIOReturnNoMemory;
+	}
+
+	memset(request, 0, sizeof(*request));
 	request->options  = options;
 	request->dataType = kAggressivesRequestTypeRecord;
 	request->data.record.type  = (uint32_t) type;
@@ -2369,7 +2093,7 @@
 	AGGRESSIVES_UNLOCK();
 
 	if (found) {
-		IOFreeType(request, AggressivesRequest);
+		IODelete(request, AggressivesRequest, 1);
 	}
 
 	if (options & kAggressivesOptionSynchronous) {
@@ -2475,7 +2199,12 @@
 
 	DEBUG_LOG("joinAggressiveness %s %p\n", service->getName(), OBFUSCATE(service));
 
-	request = IOMallocType(AggressivesRequest);
+	request = IONew(AggressivesRequest, 1);
+	if (!request) {
+		return kIOReturnNoMemory;
+	}
+
+	memset(request, 0, sizeof(*request));
 	request->dataType = kAggressivesRequestTypeService;
 	request->data.service.reset(service, OSRetain); // released by synchronizeAggressives()
 
@@ -2582,7 +2311,7 @@
 						DLOG("disk spindown accelerated\n");
 					}
 
-					aggressivesData->appendValue(newRecord);
+					aggressivesData->appendBytes(&newRecord, sizeof(newRecord));
 
 					// OSData may have switched to another (larger) buffer.
 					count = aggressivesData->getLength() / sizeof(AggressivesRecord);
@@ -2591,7 +2320,7 @@
 				}
 
 				// Finished processing the request, release it.
-				IOFreeType(request, AggressivesRequest);
+				IODelete(request, AggressivesRequest, 1);
 				break;
 
 			case kAggressivesRequestTypeService:
@@ -2600,7 +2329,7 @@
 				break;
 
 			default:
-				panic("bad aggressives request type %x", request->dataType);
+				panic("bad aggressives request type %x\n", request->dataType);
 				break;
 			}
 		} while (!queue_empty(&aggressivesQueue));
@@ -2675,7 +2404,7 @@
 			service.reset();
 		}
 
-		IOFreeType(request, AggressivesRequest);
+		IODelete(request, AggressivesRequest, 1);
 		request = NULL;
 
 		if (service) {
@@ -2787,7 +2516,7 @@
 //******************************************************************************
 
 void
-IOPMrootDomain::startIdleSleepTimer( uint32_t inMilliSeconds )
+IOPMrootDomain::startIdleSleepTimer( uint32_t inSeconds )
 {
 	AbsoluteTime deadline;
 
@@ -2796,37 +2525,14 @@
 		DLOG("idle timer not set (noidle=%d)\n", gNoIdleFlag);
 		return;
 	}
-	if (inMilliSeconds) {
-		if (inMilliSeconds < kMinimumTimeBeforeIdleSleep) {
-			AbsoluteTime    now;
-			uint64_t        nsec_since_wake;
-			uint64_t                msec_since_wake;
-
-			// Adjust idle timer so it will not expire until atleast kMinimumTimeBeforeIdleSleep milliseconds
-			// after the most recent AP wake.
-			clock_get_uptime(&now);
-			SUB_ABSOLUTETIME(&now, &gIOLastWakeAbsTime);
-			absolutetime_to_nanoseconds(now, &nsec_since_wake);
-			msec_since_wake = nsec_since_wake / NSEC_PER_MSEC;
-
-			if (msec_since_wake < kMinimumTimeBeforeIdleSleep) {
-				uint32_t newIdleTimer = kMinimumTimeBeforeIdleSleep - (uint32_t)msec_since_wake;
-
-				// Ensure that our new idle timer is not less than inMilliSeconds,
-				// as we should only be increasing the timer duration, not decreasing it
-				if (newIdleTimer > inMilliSeconds) {
-					DLOG("startIdleSleepTimer increasing timeout from %u to %u\n", inMilliSeconds, newIdleTimer);
-					inMilliSeconds = newIdleTimer;
-				}
-			}
-		}
-		clock_interval_to_deadline(inMilliSeconds, kMillisecondScale, &deadline);
+	if (inSeconds) {
+		clock_interval_to_deadline(inSeconds, kSecondScale, &deadline);
 		thread_call_enter_delayed(extraSleepTimer, deadline);
 		idleSleepTimerPending = true;
 	} else {
 		thread_call_enter(extraSleepTimer);
 	}
-	DLOG("idle timer set for %u milliseconds\n", inMilliSeconds);
+	DLOG("idle timer set for %u seconds\n", inSeconds);
 }
 
 //******************************************************************************
@@ -2898,7 +2604,7 @@
 //******************************************************************************
 // getTimeToIdleSleep
 //
-// Returns number of milliseconds left before going into idle sleep.
+// Returns number of seconds left before going into idle sleep.
 // Caller has to make sure that idle sleep is allowed at the time of calling
 // this function
 //******************************************************************************
@@ -2947,7 +2653,7 @@
 	DLOG("user inactive %u min, time to idle sleep %u min\n",
 	    minutesSinceUserInactive, sleepDelay);
 
-	return sleepDelay * 60 * 1000;
+	return sleepDelay * 60;
 }
 
 //******************************************************************************
@@ -3069,19 +2775,6 @@
 	notifierThread = current_thread();
 	switch (getPowerState()) {
 	case SLEEP_STATE: {
-#if defined(__arm64__) && HIBERNATION
-		if (kIOHibernateStateInactive == gIOHibernateState)
-#endif /* defined(__arm64__) && HIBERNATION */
-		{
-			if (kIOPMDriverAssertionLevelOn == getPMAssertionLevel(kIOPMDriverAssertionForceWakeupBit)) {
-				IOLog("accelerate wake for assertion\n");
-				setWakeTime(mach_continuous_time());
-			}
-			if (kIOPMDriverAssertionLevelOn == getPMAssertionLevel(kIOPMDriverAssertionForceFullWakeupBit)) {
-				// Note: The scheduled RTC wakeup will trigger a full wake.
-				scheduleImmediateDebugWake();
-			}
-		}
 		if (kPMCalendarTypeInvalid != _aotWakeTimeCalendar.selector) {
 			secs = 0;
 			microsecs = 0;
@@ -3091,7 +2784,7 @@
 			if ((kIOPMAOTModeRespectTimers & _aotMode) && (_calendarWakeAlarmUTC < _aotWakeTimeUTC)) {
 				IOLog("use _calendarWakeAlarmUTC\n");
 				adjWakeTime = _calendarWakeAlarmUTC;
-			} else if (kIOPMWakeEventAOTExitFlags & _aotPendingFlags) {
+			} else if (_aotExit || (kIOPMWakeEventAOTExitFlags & _aotPendingFlags)) {
 				IOLog("accelerate _aotWakeTime for exit\n");
 				adjWakeTime = secs;
 			} else if (kIOPMDriverAssertionLevelOn == getPMAssertionLevel(kIOPMDriverAssertionCPUBit)) {
@@ -3150,6 +2843,7 @@
 		if (!_aotLastWakeTime) {
 			gIOLastUserSleepTime = gIOLastSleepTime;
 		}
+
 		gIOLastWakeTime.tv_sec = 0;
 		gIOLastWakeTime.tv_usec = 0;
 		gIOLastSleepAbsTime = now;
@@ -3169,23 +2863,12 @@
 		}
 #if HIBERNATION
 		LOG("System %sSleep\n", gIOHibernateState ? "Safe" : "");
-#if (DEVELOPMENT || DEBUG)
-		record_system_event(SYSTEM_EVENT_TYPE_INFO,
-		    SYSTEM_EVENT_SUBSYSTEM_PMRD,
-		    "System State",
-		    gIOHibernateState ? "Enter Hibernate" : "Enter Sleep"
-		    );
-#endif /* DEVELOPMENT || DEBUG */
+
 		IOHibernateSystemHasSlept();
 
 		evaluateSystemSleepPolicyFinal();
 #else
 		LOG("System Sleep\n");
-#if (DEVELOPMENT || DEBUG)
-		record_system_event(SYSTEM_EVENT_TYPE_INFO,
-		    SYSTEM_EVENT_SUBSYSTEM_PMRD,
-		    "System State", "Enter Sleep");
-#endif /* DEVELOPMENT || DEBUG */
 #endif
 		if (thermalWarningState) {
 			OSSharedPtr<const OSSymbol> event = OSSymbol::withCString(kIOPMThermalLevelWarningKey);
@@ -3221,12 +2904,6 @@
 
 		clock_get_uptime(&gIOLastWakeAbsTime);
 		IOLog("gIOLastWakeAbsTime: %lld\n", gIOLastWakeAbsTime);
-#if DEVELOPMENT || DEBUG
-		record_system_event(SYSTEM_EVENT_TYPE_INFO,
-		    SYSTEM_EVENT_SUBSYSTEM_PMRD,
-		    "System State", "Waking Up"
-		    );
-#endif /* DEVELOPMENT || DEBUG */
 		_highestCapability = 0;
 
 #if HIBERNATION
@@ -3261,11 +2938,9 @@
 
 			if (_aotTestTime) {
 				if (_aotWakeTimeUTC <= secs) {
-					_aotTestTime = mach_continuous_time() + _aotTestInterval;
+					_aotTestTime = _aotTestTime + _aotTestInterval;
 				}
-				if (_aotTestTime < _aotEndTime) {
-					_setWakeTime(_aotTestTime);
-				}
+				setWakeTime(_aotTestTime);
 			}
 		}
 
@@ -3293,7 +2968,6 @@
 		isRTCAlarmWake          = false;
 		clamshellIgnoreClose    = false;
 		fullWakeReason = kFullWakeReasonNone;
-		idleSleepRevertible     = true;
 
 #if defined(__i386__) || defined(__x86_64__)
 		kdebugTrace(kPMLogSystemWake, 0, 0, 0);
@@ -3413,27 +3087,13 @@
 		}
 
 		// stay awake for at least 30 seconds
-		startIdleSleepTimer(30 * 1000);
+		startIdleSleepTimer(30);
 #endif
 		sleepCnt++;
 
 		thread_call_enter(updateConsoleUsersEntry);
 
-		// Skip AOT_STATE if we are waking up from an RTC timer.
-		// This check needs to be done after the epoch change is processed
-		// and before the changePowerStateWithTagToPriv() call below.
-		WAKEEVENT_LOCK();
-		aotShouldExit(false);
-		unsigned long newState = getRUN_STATE();
-		if (AOT_STATE == newState) {
-			if (gLPWFlags) {
-				_aotRunMode = gLPWFlags | _aotWakeEventRunMode;
-			}
-			IOLog("_aotRunMode = 0x%llx|0x%llx\n", gLPWFlags, _aotWakeEventRunMode);
-		}
-		WAKEEVENT_UNLOCK();
-
-		changePowerStateWithTagToPriv(newState, kCPSReasonWake);
+		changePowerStateWithTagToPriv(getRUN_STATE(), kCPSReasonWake);
 		break;
 	}
 #if !__i386__ && !__x86_64__
@@ -3900,7 +3560,7 @@
 #if defined(XNU_TARGET_OS_OSX) && !DISPLAY_WRANGLER_PRESENT
 			startIdleSleepTimer(kIdleSleepRetryInterval);
 #else
-			startIdleSleepTimer(idleMilliSeconds);
+			startIdleSleepTimer(idleSeconds);
 #endif
 		} else if (!userIsActive) {
 			// Manually start the idle sleep timer besides waiting for
@@ -3911,7 +3571,6 @@
 
 	preventTransitionToUserActive(false);
 	IOService::setAdvisoryTickleEnable( true );
-	idleSleepRevertible = true;
 
 	// After idle revert and cancel, send a did-change message to powerd
 	// to balance the previous will-change message. Kernel clients do not
@@ -4012,11 +3671,6 @@
 
 		tracePoint( kIOPMTracePointWakeApplications );
 		tellClients( kIOMessageSystemHasPoweredOn );
-	} else if (stateNum == AOT_STATE) {
-		if (getPowerState() == AOT_STATE) {
-			// Sleep was cancelled by idle cancel or revert
-			startIdleSleepTimer(idleMilliSeconds);
-		}
 	}
 }
 
@@ -4419,124 +4073,82 @@
 }
 
 //******************************************************************************
-// scheduleImmediateDebugWake
+// willNotifyPowerChildren
 //
-// Schedule a wake with RTC to wake us back up immediately after we sleep.
-// Useful when a cancel request comes in past the revert point on the sleep path
+// Called after all interested drivers have all acknowledged the power change,
+// but before any power children is informed. Dispatched though a thread call,
+// so it is safe to perform work that might block on a sleeping disk. PM state
+// machine (not thread) will block w/o timeout until this function returns.
 //******************************************************************************
 
 void
-IOPMrootDomain::scheduleImmediateDebugWake( void )
-{
-	OSSharedPtr<OSDictionary> dict = OSDictionary::withCapacity(1);
-	OSSharedPtr<OSNumber> secs = OSNumber::withNumber(1, 32);
-
-	if (dict && secs) {
-		dict->setObject(gIOPMSettingDebugWakeRelativeKey.get(), secs.get());
-		gRootDomain->setProperties(dict.get());
-		MSG("Reverting sleep with relative wake\n");
-	}
-}
-
-//******************************************************************************
-// willNotifyInterest
-//
-// Called after all priority clients have all acknowledged the power change,
-// but before any interested drivers and any power children are informed.
-// Dispatched though a thread call, so it is safe to perform work that might block on a
-// sleeping disk. PM state machine (not thread) will block w/o timeout until this function returns.
-//******************************************************************************
-
-void
-IOPMrootDomain::willNotifyInterested( IOPMPowerStateIndex newPowerState )
-{
+IOPMrootDomain::willNotifyPowerChildren( IOPMPowerStateIndex newPowerState )
+{
+	OSSharedPtr<OSDictionary> dict;
+	OSSharedPtr<OSNumber> secs;
+
 	if (SLEEP_STATE == newPowerState) {
+		notifierThread = current_thread();
+		if (!tasksSuspended) {
+			AbsoluteTime deadline;
+			tasksSuspended = TRUE;
+			updateTasksSuspend();
+
+			clock_interval_to_deadline(10, kSecondScale, &deadline);
+#if defined(XNU_TARGET_OS_OSX)
+			vm_pageout_wait(AbsoluteTime_to_scalar(&deadline));
+#endif /* defined(XNU_TARGET_OS_OSX) */
+		}
+
 		_aotReadyToFullWake = false;
 #if 0
 		if (_aotLingerTime) {
-			uint64_t interval, deadline;
+			uint64_t deadline;
 			IOLog("aot linger no return\n");
-			nanoseconds_to_absolutetime(_aotLingerTime * NSEC_PER_MSEC, &interval);
-			clock_absolutetime_interval_to_deadline(interval, &deadline);
+			clock_absolutetime_interval_to_deadline(_aotLingerTime, &deadline);
 			clock_delay_until(deadline);
 		}
 #endif
 		if (!_aotMode) {
 			_aotTestTime = 0;
 			_aotWakeTimeCalendar.selector = kPMCalendarTypeInvalid;
-			_aotLastWakeTime = 0;
 			if (_aotMetrics) {
 				bzero(_aotMetrics, sizeof(IOPMAOTMetrics));
 			}
 		} else if (!_aotNow && !_debugWakeSeconds) {
 			_aotNow            = true;
+			_aotExit           = false;
 			_aotPendingFlags   = 0;
 			_aotTasksSuspended = true;
 			_aotLastWakeTime   = 0;
 			bzero(_aotMetrics, sizeof(IOPMAOTMetrics));
 			if (kIOPMAOTModeCycle & _aotMode) {
-				clock_interval_to_absolutetime_interval(10, kSecondScale, &_aotTestInterval);
+				clock_interval_to_absolutetime_interval(60, kSecondScale, &_aotTestInterval);
 				_aotTestTime = mach_continuous_time() + _aotTestInterval;
-				AbsoluteTime endInterval;
-				clock_interval_to_absolutetime_interval(60, kSecondScale, &endInterval);
-				_aotEndTime = mach_continuous_time() + endInterval;
-				_setWakeTime(_aotTestTime);
-			}
+				setWakeTime(_aotTestTime);
+			}
+			uint32_t lingerSecs;
+			if (!PE_parse_boot_argn("aotlinger", &lingerSecs, sizeof(lingerSecs))) {
+				lingerSecs = 0;
+			}
+			clock_interval_to_absolutetime_interval(lingerSecs, kSecondScale, &_aotLingerTime);
 			clock_interval_to_absolutetime_interval(2000, kMillisecondScale, &_aotWakePreWindow);
 			clock_interval_to_absolutetime_interval(1100, kMillisecondScale, &_aotWakePostWindow);
 		}
 
-		if (updateTasksSuspend(kTasksSuspendSuspended, kTasksSuspendNoChange)) {
-			IOLog("PMRD: tasks suspend\n");
-			AbsoluteTime deadline;
-
-			clock_interval_to_deadline(10, kSecondScale, &deadline);
-#if defined(XNU_TARGET_OS_OSX)
-			vm_pageout_wait(AbsoluteTime_to_scalar(&deadline));
-#endif /* defined(XNU_TARGET_OS_OSX) */
-		}
-	}
-}
-
-//******************************************************************************
-// willNotifyPowerChildren
-//
-// Called after all interested drivers have all acknowledged the power change,
-// but before any power children are informed.
-// Dispatched though a thread call, so it is safe to perform work that might block on a
-// sleeping disk. PM state machine (not thread) will block w/o timeout until this function returns.
-//******************************************************************************
-
-void
-IOPMrootDomain::willNotifyPowerChildren( IOPMPowerStateIndex newPowerState )
-{
-	if (SLEEP_STATE == newPowerState) {
-		notifierThread = current_thread();
-
 #if HIBERNATION
-		// Adjust watchdog for IOHibernateSystemSleep
-		int defaultTimeout = getWatchdogTimeout();
-		int timeout = defaultTimeout > WATCHDOG_HIBERNATION_TIMEOUT ?
-		    defaultTimeout : WATCHDOG_HIBERNATION_TIMEOUT;
-		reset_watchdog_timer(timeout);
-
 		IOHibernateSystemSleep();
 		IOHibernateIOKitSleep();
 #endif
-#if defined(__arm64__) && HIBERNATION
-		if (gIOHibernateState == kIOHibernateStateInactive) {
-			setProperty(kIOPMSystemSleepTypeKey, kIOPMSleepTypeDeepIdle, 32);
-		}
-		// On AS, hibernation cannot be aborted. Resetting RTC to 1s during hibernation upon detecting
-		// user activity is pointless (we are likely to spend >1s hibernating). It also clears existing
-		// alarms, which can mess with cycler tools.
-		if (gRootDomain->activitySinceSleep() && gIOHibernateState == kIOHibernateStateInactive) {
-#else /* defined(__arm64__) && HIBERNATION */
-		// On non-AS, hibernation can be aborted if user activity is detected. So continue to reset the
-		// RTC alarm (even during hibernation) so we can immediately wake from regular S2R if needed.
 		if (gRootDomain->activitySinceSleep()) {
-#endif /* defined(__arm64__) && HIBERNATION */
-			scheduleImmediateDebugWake();
+			dict = OSDictionary::withCapacity(1);
+			secs = OSNumber::withNumber(1, 32);
+
+			if (dict && secs) {
+				dict->setObject(gIOPMSettingDebugWakeRelativeKey.get(), secs.get());
+				gRootDomain->setProperties(dict.get());
+				MSG("Reverting sleep with relative wake\n");
+			}
 		}
 
 		notifierThread = NULL;
@@ -5639,7 +5251,11 @@
 		IOReturn    result;
 
 		if (!gSleepPolicyVars) {
-			gSleepPolicyVars = IOMallocType(IOPMSystemSleepPolicyVariables);
+			gSleepPolicyVars = IONew(IOPMSystemSleepPolicyVariables, 1);
+			if (!gSleepPolicyVars) {
+				goto done;
+			}
+			bzero(gSleepPolicyVars, sizeof(*gSleepPolicyVars));
 		}
 		gSleepPolicyVars->signature = kIOPMSystemSleepPolicySignature;
 		gSleepPolicyVars->version   = kIOPMSystemSleepPolicyVersion;
@@ -5868,7 +5484,7 @@
 			resetTimers = false;
 		}
 
-		paramsData = OSData::withValue(params);
+		paramsData = OSData::withBytes(&params, sizeof(params));
 		if (paramsData) {
 			setProperty(kIOPMSystemSleepParametersKey, paramsData.get());
 		}
@@ -6068,7 +5684,6 @@
 {
 	AbsoluteTime                startTime, elapsedTime;
 	uint32_t                    deltaTime;
-	bool                        nvramSync = false;
 
 	memset(&gHaltRestartCtx, 0, sizeof(gHaltRestartCtx));
 	gHaltRestartCtx.RootDomain = this;
@@ -6080,14 +5695,12 @@
 		gHaltRestartCtx.PowerState  = OFF_STATE;
 		gHaltRestartCtx.MessageType = kIOMessageSystemWillPowerOff;
 		gHaltRestartCtx.LogString   = "PowerOff";
-		nvramSync = true;
 		break;
 
 	case kPERestartCPU:
 		gHaltRestartCtx.PowerState  = RESTART_STATE;
 		gHaltRestartCtx.MessageType = kIOMessageSystemWillRestart;
 		gHaltRestartCtx.LogString   = "Restart";
-		nvramSync = true;
 		break;
 
 	case kPEPagingOff:
@@ -6104,10 +5717,6 @@
 		return;
 	}
 
-	if (nvramSync) {
-		PESyncNVRAM();
-	}
-
 	gHaltRestartCtx.phase = kNotifyPriorityClients;
 	// Notify legacy clients
 	applyToInterested(gIOPriorityPowerStateInterest, platformHaltRestartApplier, &gHaltRestartCtx);
@@ -6279,6 +5888,17 @@
 	}
 	if (service->propertyExists("IOPMUnattendedWakePowerState")) {
 		flags |= kPMActionsFlagIsAudioDriver;
+	}
+
+	OSSharedPtr<OSObject> prop = service->copyProperty(kIOPMDarkWakeMaxPowerStateKey);
+	if (prop) {
+		OSNumber * num = OSDynamicCast(OSNumber, prop.get());
+		if (num) {
+			actions->darkWakePowerState = num->unsigned32BitValue();
+			if (actions->darkWakePowerState < maxPowerState) {
+				flags |= kPMActionsFlagHasDarkWakePowerState;
+			}
+		}
 	}
 
 	// Find the power connection object that is a child of the PCI host
@@ -6309,18 +5929,6 @@
 			parent = child->getParentEntry(gIOPowerPlane);
 		}
 	}
-
-	OSSharedPtr<OSObject> prop = service->copyProperty(kIOPMDarkWakeMaxPowerStateKey);
-	if (prop) {
-		OSNumber * num = OSDynamicCast(OSNumber, prop.get());
-		if (num) {
-			actions->darkWakePowerState = num->unsigned32BitValue();
-			if (actions->darkWakePowerState < maxPowerState) {
-				flags |= kPMActionsFlagHasDarkWakePowerState;
-			}
-		}
-	}
-
 
 	if (flags) {
 		DLOG("%s tag flags %x\n", service->getName(), flags);
@@ -6443,17 +6051,6 @@
 		return;
 	}
 
-#if HIBERNATION && defined(__arm64__)
-	if (lowBatteryCondition && (desiredPowerState < currentPowerState)) {
-		if (!ml_is_secure_hib_supported() || ldmHibernateDisable) {
-			// If hibernation is unsupported, reject sleep requests to avoid
-			// racing with system shutdown.
-			*inOutChangeFlags |= kIOPMNotDone;
-			return;
-		}
-	}
-#endif /* HIBERNATION && defined(__arm64__) */
-
 	if (desiredPowerState < currentPowerState) {
 		if (CAP_CURRENT(kIOPMSystemCapabilityGraphics)) {
 			// Root domain is dropping power state from ON->SLEEP.
@@ -6527,22 +6124,21 @@
 	if (changeFlags & kIOPMSynchronize) {
 		if (newPowerState == ON_STATE) {
 			if (changeFlags & kIOPMSyncNoChildNotify) {
-				setSystemTransitionTypeGated(kSystemTransitionNewCapClient);
+				_systemTransitionType = kSystemTransitionNewCapClient;
 			} else {
-				setSystemTransitionTypeGated(kSystemTransitionCapability);
+				_systemTransitionType = kSystemTransitionCapability;
 			}
 		}
 	}
 	// 2. Going to sleep (cancellation still possible).
 	else if (newPowerState < currentPowerState) {
-		setSystemTransitionTypeGated(kSystemTransitionSleep);
+		_systemTransitionType = kSystemTransitionSleep;
 	}
 	// 3. Woke from (idle or demand) sleep.
 	else if (!systemBooting &&
 	    (changeFlags & kIOPMSelfInitiated) &&
 	    (newPowerState > currentPowerState)) {
-		setSystemTransitionTypeGated(kSystemTransitionWake);
-
+		_systemTransitionType = kSystemTransitionWake;
 		_desiredCapability = kIOPMSystemCapabilityCPU | kIOPMSystemCapabilityNetwork;
 
 		// Early exit from dark wake to full (e.g. LID open)
@@ -6584,7 +6180,7 @@
 		if ((kSystemTransitionCapability == _systemTransitionType) &&
 		    (_pendingCapability == _currentCapability)) {
 			// Cancel the PM state change.
-			setSystemTransitionTypeGated(kSystemTransitionNone);
+			_systemTransitionType = kSystemTransitionNone;
 			*inOutChangeFlags |= kIOPMNotDone;
 		}
 		if (__builtin_popcount(_pendingCapability) <
@@ -6693,12 +6289,7 @@
 		// Clear stats about sleep
 
 		if (AOT_STATE == newPowerState) {
-			// Temporarily increase the capacity of the log subsystem to buffer logs in AOT.
-			os_log_adjust_buffering_capacity(LOG_BUFFERING_CAPACITY_MAX);
-			_pendingCapability = kIOPMSystemCapabilityAOT;
-		} else {
-			// Restore the maximum capacity of the log subsystem once waking to full wake.
-			os_log_adjust_buffering_capacity(LOG_BUFFERING_CAPACITY_DEFAULT);
+			_pendingCapability = 0;
 		}
 
 		if (AOT_STATE == currentPowerState) {
@@ -6737,12 +6328,6 @@
 		uint32_t reasonIndex = sleepReason - kIOPMSleepReasonClamshell;
 		if (reasonIndex < sizeof(IOPMSleepReasons) / sizeof(IOPMSleepReasons[0])) {
 			DLOG("sleep reason %s\n", IOPMSleepReasons[reasonIndex]);
-#if DEVELOPMENT || DEBUG
-			record_system_event(SYSTEM_EVENT_TYPE_INFO,
-			    SYSTEM_EVENT_SUBSYSTEM_PMRD,
-			    "Sleep Reason", "%s\n", IOPMSleepReasons[reasonIndex]
-			    );
-#endif /* DEVELOPMENT || DEBUG */
 			setProperty(kRootDomainSleepReasonKey, IOPMSleepReasons[reasonIndex]);
 		}
 	}
@@ -6758,23 +6343,6 @@
 		    _currentCapability, _pendingCapability,
 		    *inOutChangeFlags, _systemStateGeneration, _systemMessageClientMask,
 		    requestTag);
-#if DEVELOPMENT || DEBUG
-		if (currentPowerState != (uint32_t) newPowerState) {
-			record_system_event(SYSTEM_EVENT_TYPE_INFO,
-			    SYSTEM_EVENT_SUBSYSTEM_PMRD,
-			    "Start Power State Trans.",
-			    "(%s->%s, %x->%x, 0x%x) gen %u, msg %x, tag %x\n",
-			    getPowerStateString(currentPowerState),
-			    getPowerStateString((uint32_t) newPowerState),
-			    _currentCapability,
-			    _pendingCapability,
-			    *inOutChangeFlags,
-			    _systemStateGeneration,
-			    _systemMessageClientMask,
-			    requestTag
-			    );
-		}
-#endif /* DEVELOPMENT || DEBUG */
 	}
 
 	if ((AOT_STATE == newPowerState) && (SLEEP_STATE != currentPowerState)) {
@@ -6782,41 +6350,9 @@
 	}
 	if (_aotNow && (ON_STATE == newPowerState)) {
 		WAKEEVENT_LOCK();
-		aotShouldExit(true);
+		aotShouldExit(false, true);
 		WAKEEVENT_UNLOCK();
 		aotExit(false);
-	}
-}
-
-void
-IOPMrootDomain::setSystemTransitionTypeGated(SystemTransitionType type)
-{
-	assert(gIOPMWorkLoop->inGate());
-	_systemTransitionType = type;
-	commandGate->commandWakeup(&_systemTransitionType);
-}
-
-void
-IOPMrootDomain::waitForSystemTransitionToMinPowerState(IOPMRootDomainPowerState state)
-{
-	while (true) {
-		IOReturn ret = gIOPMWorkLoop->runActionBlock(^{
-			// Block until all in progress transitions have completed.
-			while (_systemTransitionType != kSystemTransitionNone) {
-			        commandGate->commandSleep(&_systemTransitionType);
-			}
-
-			// Check the current power state.
-			if (getPowerState() >= state) {
-			        return kIOReturnSuccess;
-			}
-
-			return kIOReturnError;
-		});
-
-		if (ret == kIOReturnSuccess) {
-			break;
-		}
 	}
 }
 
@@ -6829,7 +6365,7 @@
 	IOPMPowerChangeFlags    changeFlags )
 {
 	if (kSystemTransitionNewCapClient == _systemTransitionType) {
-		setSystemTransitionTypeGated(kSystemTransitionNone);
+		_systemTransitionType = kSystemTransitionNone;
 		return;
 	}
 
@@ -6923,24 +6459,6 @@
 			}
 		}
 
-#if DEVELOPMENT || DEBUG
-		if (currentPowerState != (uint32_t) oldPowerState) {
-			record_system_event(SYSTEM_EVENT_TYPE_INFO,
-			    SYSTEM_EVENT_SUBSYSTEM_PMRD,
-			    "Finish Power State Trans.",
-			    "(%s->%s, %x->%x, 0x%x) gen %u, msg %x, tag %x\n",
-			    getPowerStateString((uint32_t)oldPowerState),
-			    getPowerStateString(currentPowerState),
-			    _currentCapability,
-			    _pendingCapability,
-			    changeFlags,
-			    _systemStateGeneration,
-			    _systemMessageClientMask,
-			    request->getTag()
-			    );
-		}
-#endif /* DEVELOPMENT || DEBUG */
-
 		DLOG("=== FINISH (%s->%s, %x->%x, 0x%x) gen %u, msg %x, tag %x\n",
 		    getPowerStateString((uint32_t) oldPowerState), getPowerStateString(currentPowerState),
 		    _currentCapability, _pendingCapability,
@@ -6994,8 +6512,7 @@
 			tracePoint( kIOPMTracePointSystemUp );
 		}
 
-		setSystemTransitionTypeGated(kSystemTransitionNone);
-
+		_systemTransitionType = kSystemTransitionNone;
 		_systemMessageClientMask = 0;
 		toldPowerdCapWillChange  = false;
 
@@ -7323,8 +6840,7 @@
 
 protected:
 	uint32_t        ackTimeoutCnt;
-	uint32_t        msgType;    // Last type seen by the message filter
-	uint32_t        lastSleepWakeMsgType;
+	uint32_t        msgType;        // Message pending ack
 	uint32_t        msgIndex;
 	uint32_t        maxMsgDelayMS;
 	uint32_t        maxAckDelayMS;
@@ -7367,7 +6883,6 @@
 		rc  = super::registerInterestForNotifier(notifier, typeOfInterest, handler, target, ref);
 	}
 	if (rc != kIOReturnSuccess) {
-		OSSafeReleaseNULL(notifier);
 		return NULL;
 	}
 
@@ -7423,36 +6938,31 @@
 {
 	const IOPMInterestContext * context = (const IOPMInterestContext *) arg1;
 	bool  isCapMsg = (context->messageType == kIOMessageSystemCapabilityChange);
-	bool  isCapPowerd = (object == (void *) systemCapabilityNotifier.get());
 	bool  isCapClient = false;
 	bool  allow = false;
-	OSBoolean **waitForReply = (typeof(waitForReply))arg3;
 	IOPMServiceInterestNotifier *notifier;
 
 	notifier = OSDynamicCast(IOPMServiceInterestNotifier, (OSObject *)object);
 
 	do {
-		// When powerd and kernel priority clients register capability interest,
-		// the power tree is sync'ed to inform those clients about the current
-		// system capability. Only allow capability change messages during sync.
 		if ((kSystemTransitionNewCapClient == _systemTransitionType) &&
 		    (!isCapMsg || !_joinedCapabilityClients ||
 		    !_joinedCapabilityClients->containsObject((OSObject *) object))) {
 			break;
 		}
 
-		// Capability change message for powerd and kernel clients
+		// Capability change message for app and kernel clients.
+
 		if (isCapMsg) {
-			// Kernel priority clients
+			// Kernel clients
 			if ((context->notifyType == kNotifyPriority) ||
 			    (context->notifyType == kNotifyCapabilityChangePriority)) {
 				isCapClient = true;
 			}
 
-			// powerd will maintain two client registrations with root domain.
-			// isCapPowerd will be TRUE for any message targeting the powerd
-			// exclusive (capability change) interest registration.
-			if (isCapPowerd && (context->notifyType == kNotifyCapabilityChangeApps)) {
+			// powerd's systemCapabilityNotifier
+			if ((context->notifyType == kNotifyCapabilityChangeApps) &&
+			    (object == (void *) systemCapabilityNotifier.get())) {
 				isCapClient = true;
 			}
 		}
@@ -7475,105 +6985,91 @@
 					capArgs->changeFlags = kIOPMSystemCapabilityDidChange;
 				}
 
-				if (isCapPowerd && context->isPreChange) {
+				if ((object == (void *) systemCapabilityNotifier.get()) &&
+				    context->isPreChange) {
 					toldPowerdCapWillChange = true;
 				}
 			}
 
-			// App level capability change messages must only go to powerd.
+			// Capability change messages only go to the PM configd plugin.
 			// Wait for response post-change if capabilitiy is increasing.
 			// Wait for response pre-change if capability is decreasing.
 
-			if ((context->notifyType == kNotifyCapabilityChangeApps) && waitForReply &&
+			if ((context->notifyType == kNotifyCapabilityChangeApps) && arg3 &&
 			    ((capabilityLoss && context->isPreChange) ||
 			    (!capabilityLoss && !context->isPreChange))) {
-				*waitForReply = kOSBooleanTrue;
+				// app has not replied yet, wait for it
+				*((OSObject **) arg3) = kOSBooleanFalse;
 			}
 
 			allow = true;
 			break;
 		}
 
-		// powerd will always receive CanSystemSleep, even for a demand sleep.
-		// It will also have a final chance to veto sleep after all clients
-		// have responded to SystemWillSleep
+		// Capability client will always see kIOMessageCanSystemSleep,
+		// even for demand sleep. It will also have a chance to veto
+		// sleep one last time after all clients have responded to
+		// kIOMessageSystemWillSleep
 
 		if ((kIOMessageCanSystemSleep == context->messageType) ||
 		    (kIOMessageSystemWillNotSleep == context->messageType)) {
-			if (isCapPowerd) {
+			if (object == (OSObject *) systemCapabilityNotifier.get()) {
 				allow = true;
 				break;
 			}
 
-			// Demand sleep, don't ask apps for permission
+			// Not idle sleep, don't ask apps.
 			if (context->changeFlags & kIOPMSkipAskPowerDown) {
 				break;
 			}
 		}
 
 		if (kIOPMMessageLastCallBeforeSleep == context->messageType) {
-			if (isCapPowerd && CAP_HIGHEST(kIOPMSystemCapabilityGraphics) &&
+			if ((object == (OSObject *) systemCapabilityNotifier.get()) &&
+			    CAP_HIGHEST(kIOPMSystemCapabilityGraphics) &&
 			    (fullToDarkReason == kIOPMSleepReasonIdle)) {
 				allow = true;
 			}
 			break;
 		}
 
-		// Drop capability change messages for legacy clients.
-		// Drop legacy system sleep messages for powerd capability interest.
-		if (isCapMsg || isCapPowerd) {
+		// Reject capability change messages for legacy clients.
+		// Reject legacy system sleep messages for capability client.
+
+		if (isCapMsg || (object == (OSObject *) systemCapabilityNotifier.get())) {
 			break;
 		}
 
-		// Not a capability change message.
-		// Perform message filtering based on _systemMessageClientMask.
+		// Filter system sleep messages.
 
 		if ((context->notifyType == kNotifyApps) &&
 		    (_systemMessageClientMask & kSystemMessageClientLegacyApp)) {
-			if (!notifier) {
-				break;
-			}
-
-			if ((notifier->lastSleepWakeMsgType == context->messageType) &&
-			    (notifier->lastSleepWakeMsgType == kIOMessageSystemWillPowerOn)) {
-				break; // drop any duplicate WillPowerOn for AOT devices
-			}
-
 			allow = true;
 
-			if (waitForReply) {
-				if (notifier->ackTimeoutCnt >= 3) {
-					*waitForReply = kOSBooleanFalse;
-				} else {
-					*waitForReply = kOSBooleanTrue;
+			if (notifier) {
+				if (arg3) {
+					if (notifier->ackTimeoutCnt >= 3) {
+						*((OSObject **) arg3) = kOSBooleanFalse;
+					} else {
+						*((OSObject **) arg3) = kOSBooleanTrue;
+					}
 				}
 			}
 		} else if ((context->notifyType == kNotifyPriority) &&
 		    (_systemMessageClientMask & kSystemMessageClientKernel)) {
 			allow = true;
 		}
-
-		// Check sleep/wake message ordering
-		if (allow) {
-			if (context->messageType == kIOMessageSystemWillSleep ||
-			    context->messageType == kIOMessageSystemWillPowerOn ||
-			    context->messageType == kIOMessageSystemHasPoweredOn) {
-				notifier->lastSleepWakeMsgType = context->messageType;
-			}
-		}
-	} while (false);
+	}while (false);
 
 	if (allow && isCapMsg && _joinedCapabilityClients) {
 		_joinedCapabilityClients->removeObject((OSObject *) object);
 		if (_joinedCapabilityClients->getCount() == 0) {
-			DMSG("destroyed capability client set %p\n",
+			DLOG("destroyed capability client set %p\n",
 			    OBFUSCATE(_joinedCapabilityClients.get()));
 			_joinedCapabilityClients.reset();
 		}
 	}
 	if (notifier) {
-		// Record the last seen message type even if the message is dropped
-		// for traceFilteredNotification().
 		notifier->msgType = context->messageType;
 	}
 
@@ -7596,7 +7092,7 @@
 		return kIOReturnBadArgument;
 	}
 
-	data = OSData::withValue(*calendar);
+	data = OSData::withBytes((void *) calendar, sizeof(*calendar));
 	if (!data) {
 		return kIOReturnNoMemory;
 	}
@@ -7837,29 +7333,6 @@
 		break;
 #endif
 
-		if (_driverKitMatchingAssertionCount != 0 || _driverKitSyncedAssertionCount != 0) {
-			err = kPMCPUAssertion;
-			break;
-		}
-
-		// Check for any dexts currently being added to the PM tree. Sleeping while
-		// this is in flight can cause IOServicePH to timeout.
-		if (!IOServicePH::checkPMReady()) {
-#if !defined(XNU_TARGET_OS_OSX)
-			if (!(lowBatteryCondition || thermalWarningState || thermalEmergencyState)) {
-				// 116893363: kPMDKNotReady sleep cancellations often leaves embedded devices
-				// in dark wake for long periods of time, which causes issues as apps were
-				// already informed of sleep during the f->9 transition. As a temporary
-				// measure, always full wake if we hit this specific condition.
-				pmPowerStateQueue->submitPowerEvent(
-					kPowerEventPolicyStimulus,
-					(void *) kStimulusDarkWakeActivityTickle);
-			}
-#endif
-			err = kPMDKNotReady;
-			break;
-		}
-
 		if (lowBatteryCondition || thermalWarningState || thermalEmergencyState) {
 			break; // always sleep on low battery or when in thermal warning/emergency state
 		}
@@ -7872,7 +7345,6 @@
 			err = kPMChildPreventSystemSleep; // 4. child prevent system sleep clamp
 			break;
 		}
-
 
 		if (getPMAssertionLevel( kIOPMDriverAssertionCPUBit ) ==
 		    kIOPMDriverAssertionLevelOn) {
@@ -7951,106 +7423,6 @@
 }
 
 //******************************************************************************
-// checkSystemCanAbortIdleSleep
-//******************************************************************************
-
-bool
-IOPMrootDomain::checkSystemCanAbortIdleSleep( void )
-{
-	bool abortableSleepType =  ((lastSleepReason == kIOPMSleepReasonIdle)
-	    || (lastSleepReason == 0));
-	return idleSleepRevertible && abortableSleepType;
-}
-
-//******************************************************************************
-// considerRunMode
-// consider the driver for AOT power on via the runmode mask
-//******************************************************************************
-
-int32_t
-IOPMrootDomain::considerRunMode(IOService * service, uint64_t pmDriverClass)
-{
-	int32_t promote;
-
-	if ((0 == _aotRunMode) || (service == this)) {
-		// neutral
-		return 0;
-	}
-	if (pmDriverClass) {
-		IOLog("considerRunMode: %s 0x%llx 0x%llx\n", service->getName(), pmDriverClass, _aotRunMode);
-	}
-	promote = (0 != (_aotRunMode & pmDriverClass)) ? 1 : -1;
-	if (promote > 0) {
-		IOLog("IOPMRD: %s 0x%llx runmode to %s\n", service->getName(), pmDriverClass, (promote < 0) ? "OFF" : "ON");
-	}
-	return promote;
-}
-
-void
-IOPMrootDomain::handleRegisterPowerDriver(IOService * child)
-{
-	OSNumber * num;
-	IOService * userServer;
-	uint64_t driverClassFlags;
-	OSSharedPtr<OSObject> prop = child->copyProperty(kIOPMAOTAllowKey);
-
-	if (!prop || (NULL == (num = OSDynamicCast(OSNumber, prop.get())))) {
-		return;
-	}
-	driverClassFlags = num->unsigned64BitValue();
-
-	userServer = NULL;
-	if (child->reserved->uvars && (userServer = child->reserved->uvars->userServer)) {
-		WAKEEVENT_LOCK();
-		_aotWakeEventRunModeImpliesStorage |= driverClassFlags;
-		WAKEEVENT_UNLOCK();
-	}
-
-	IOLog("addPMDriverClass %s %llx\n", child->getName(), driverClassFlags);
-	if (driverClassFlags) {
-		child->addPMDriverClass(driverClassFlags);
-		if (userServer) {
-			userServer->addPMDriverClass(driverClassFlags);
-		}
-	}
-}
-
-//******************************************************************************
-// attemptIdleSleepAbort
-//******************************************************************************
-
-bool
-IOPMrootDomain::attemptIdleSleepAbort( void )
-{
-	if (!gIOPMWorkLoop->inGate()) {
-		bool ret = gIOPMWorkLoop->runAction(
-			OSMemberFunctionCast(IOWorkLoop::Action, this,
-			&IOPMrootDomain::attemptIdleSleepAbort),
-			this);
-		return ret;
-	}
-
-	bool canAbort = checkSystemCanAbortIdleSleep();
-	if (canAbort) {
-		cancelIdlePowerDownSync();
-	} else if (lastSleepReason == kIOPMSleepReasonIdle) {
-		scheduleImmediateDebugWake();
-	}
-
-	return canAbort;
-}
-
-//******************************************************************************
-// setIdleSleepRevertible
-//******************************************************************************
-
-void
-IOPMrootDomain::setIdleSleepRevertible( bool revertible )
-{
-	idleSleepRevertible = revertible;
-}
-
-//******************************************************************************
 // mustHibernate
 //******************************************************************************
 
@@ -8183,7 +7555,7 @@
 unsigned long
 IOPMrootDomain::getRUN_STATE(void)
 {
-	return (_aotNow && !(kIOPMWakeEventAOTExitFlags & _aotPendingFlags)) ? AOT_STATE : ON_STATE;
+	return _aotNow ? AOT_STATE : ON_STATE;
 }
 
 bool
@@ -8192,50 +7564,12 @@
 	return _aotNow;
 }
 
-bool
-IOPMrootDomain::isLPWMode()
-{
-	return gLPWFlags && currentOrPendingPowerState(AOT_STATE);
-}
-
-bool
-IOPMIsAOTMode(void)
-{
-	return gIOPMRootDomain && gIOPMRootDomain->isAOTMode();
-}
-bool
-IOPMIsLPWMode(void)
-{
-	return gIOPMRootDomain && gIOPMRootDomain->isLPWMode();
-}
-
-void
-IOPMNetworkStackFullWake(uint64_t flags, const char * reason)
-{
-	assert(kIOPMNetworkStackFullWakeFlag == flags);
-	assert(gIOPMRootDomain);
-	gIOPMRootDomain->claimSystemWakeEvent(gIOPMRootDomain, kIOPMWakeEventAOTExit, reason, NULL);
-}
-
 IOReturn
 IOPMrootDomain::setWakeTime(uint64_t wakeContinuousTime)
-{
-	if (kIOPMAOTModeCycle & _aotMode) {
-		return kIOReturnSuccess;
-	}
-	return _setWakeTime(wakeContinuousTime);
-}
-
-IOReturn
-IOPMrootDomain::_setWakeTime(uint64_t wakeContinuousTime)
 {
 	clock_sec_t     nowsecs, wakesecs;
 	clock_usec_t    nowmicrosecs, wakemicrosecs;
 	uint64_t        nowAbs, wakeAbs;
-
-	if (!_aotMode) {
-		return kIOReturnNotReady;
-	}
 
 	clock_gettimeofday_and_absolute_time(&nowsecs, &nowmicrosecs, &nowAbs);
 	wakeAbs = continuoustime_to_absolutetime(wakeContinuousTime);
@@ -8270,34 +7604,35 @@
 
 // assumes WAKEEVENT_LOCK
 bool
-IOPMrootDomain::aotShouldExit(bool software)
-{
-	bool exitNow = false;
+IOPMrootDomain::aotShouldExit(bool checkTimeSet, bool software)
+{
+	bool exitNow;
 	const char * reason = "";
 
-	if (!_aotNow) {
-		return false;
-	}
-
 	if (software) {
-		exitNow = true;
+		_aotExit = true;
 		_aotMetrics->softwareRequestCount++;
 		reason = "software request";
 	} else if (kIOPMWakeEventAOTExitFlags & _aotPendingFlags) {
-		exitNow = true;
+		_aotExit = true;
 		reason = gWakeReasonString;
+	} else if (checkTimeSet && (kPMCalendarTypeInvalid == _aotWakeTimeCalendar.selector)) {
+		_aotExit = true;
+		_aotMetrics->noTimeSetCount++;
+		reason = "flipbook expired";
 	} else if ((kIOPMAOTModeRespectTimers & _aotMode) && _calendarWakeAlarmUTC) {
 		clock_sec_t     sec;
 		clock_usec_t    usec;
 		clock_get_calendar_microtime(&sec, &usec);
 		if (_calendarWakeAlarmUTC <= sec) {
-			exitNow = true;
+			_aotExit = true;
 			_aotMetrics->rtcAlarmsCount++;
 			reason = "user alarm";
 		}
 	}
+	exitNow = (_aotNow && _aotExit);
 	if (exitNow) {
-		_aotPendingFlags |= kIOPMWakeEventAOTExit;
+		_aotNow = false;
 		IOLog(LOG_PREFIX "AOT exit for %s, sc %d po %d, cp %d, rj %d, ex %d, nt %d, rt %d\n",
 		    reason,
 		    _aotMetrics->sleepCount,
@@ -8317,14 +7652,13 @@
 	uint32_t savedMessageMask;
 
 	ASSERT_GATED();
-	_aotNow = false;
-	_aotRunMode = 0;
+	_aotTasksSuspended  = false;
 	_aotReadyToFullWake = false;
 	if (_aotTimerScheduled) {
 		_aotTimerES->cancelTimeout();
 		_aotTimerScheduled = false;
 	}
-	updateTasksSuspend(kTasksSuspendNoChange, kTasksSuspendUnsuspended);
+	updateTasksSuspend();
 
 	_aotMetrics->totalTime += mach_absolute_time() - _aotLastWakeTime;
 	_aotLastWakeTime = 0;
@@ -8358,7 +7692,7 @@
 	IOLog("aotEvaluate(%d) 0x%x\n", (timer != NULL), _aotPendingFlags);
 
 	WAKEEVENT_LOCK();
-	exitNow = aotShouldExit(false);
+	exitNow = aotShouldExit(false, false);
 	if (timer != NULL) {
 		_aotTimerScheduled = false;
 	}
@@ -8391,8 +7725,8 @@
 void
 IOPMrootDomain::adjustPowerState( bool sleepASAP )
 {
-	DEBUG_LOG("adjustPowerState %s, asap %d, idleSleepEnabled %d, _aotNow %d\n",
-	    getPowerStateString((uint32_t) getPowerState()), sleepASAP, idleSleepEnabled, _aotNow);
+	DEBUG_LOG("adjustPowerState %s, asap %d, idleSleepEnabled %d\n",
+	    getPowerStateString((uint32_t) getPowerState()), sleepASAP, idleSleepEnabled);
 
 	ASSERT_GATED();
 
@@ -8403,12 +7737,16 @@
 			return;
 		}
 		WAKEEVENT_LOCK();
-		exitNow = aotShouldExit(false);
+		exitNow = aotShouldExit(true, false);
 		if (!exitNow
 		    && !_aotTimerScheduled
 		    && (kIOPMWakeEventAOTPossibleExit == (kIOPMWakeEventAOTPossibleFlags & _aotPendingFlags))) {
 			_aotTimerScheduled = true;
-			_aotTimerES->setTimeout(_aotLingerTime, kMillisecondScale);
+			if (_aotLingerTime) {
+				_aotTimerES->setTimeout(_aotLingerTime);
+			} else {
+				_aotTimerES->setTimeout(800, kMillisecondScale);
+			}
 		}
 		WAKEEVENT_UNLOCK();
 		if (exitNow) {
@@ -8416,12 +7754,6 @@
 		} else {
 			_aotReadyToFullWake = true;
 			if (!_aotTimerScheduled) {
-				if (kIOPMDriverAssertionLevelOn == getPMAssertionLevel(kIOPMDriverAssertionCPUBit)) {
-					// Don't try to force sleep during AOT while IOMobileFramebuffer is holding a power assertion.
-					// Doing so will result in the sleep being cancelled anyway,
-					// but this check avoids unnecessary thrashing in the power state engine.
-					return;
-				}
 				privateSleepSystem(kIOPMSleepReasonSoftware);
 			}
 		}
@@ -8469,8 +7801,6 @@
 	}
 }
 
-TUNABLE(bool, test_sleep_in_vm, "test_sleep_in_vm", false);
-
 //******************************************************************************
 // dispatchPowerEvent
 //
@@ -8499,14 +7829,13 @@
 		if (systemBooting) {
 			systemBooting = false;
 
+			// read noidle setting from Device Tree
+			if (PE_get_default("no-idle", &gNoIdleFlag, sizeof(gNoIdleFlag))) {
+				DLOG("Setting gNoIdleFlag to %u from device tree\n", gNoIdleFlag);
+			}
 			if (PE_get_default("sleep-disabled", &gSleepDisabledFlag, sizeof(gSleepDisabledFlag))) {
 				DLOG("Setting gSleepDisabledFlag to %u from device tree\n", gSleepDisabledFlag);
-				if (test_sleep_in_vm && gSleepDisabledFlag) {
-					DLOG("Clearing gSleepDisabledFlag due to test_sleep_in_vm boot-arg\n");
-					gSleepDisabledFlag = 0;
-				}
-			}
-
+			}
 			if (lowBatteryCondition || thermalEmergencyState) {
 				if (lowBatteryCondition) {
 					privateSleepSystem(kIOPMSleepReasonLowPower);
@@ -8591,7 +7920,7 @@
 	case kPowerEventAssertionCreate:
 		DMSG("power event %u args %p 0x%llx\n", event, OBFUSCATE(arg0), arg1);
 		if (pmAssertions) {
-			pmAssertions->handleCreateAssertion((OSValueObject<PMAssertStruct> *)arg0);
+			pmAssertions->handleCreateAssertion((OSData *)arg0);
 		}
 		break;
 
@@ -8641,9 +7970,7 @@
 				requestUserActive(this, "WakeTypeUser");
 				wakeType = kIOPMRootDomainWakeTypeUser;
 			} else if (arg0 == gIOPMSettingDebugWakeRelativeKey) {
-				if (!(gDarkWakeFlags & kDarkWakeFlagAlarmIsDark)) {
-					requestUserActive(this, "WakeTypeAlarm");
-				}
+				requestUserActive(this, "WakeTypeAlarm");
 				wakeType = kIOPMRootDomainWakeTypeAlarm;
 			} else if (arg0 == gIOPMSettingSleepServiceWakeCalendarKey) {
 				darkWakeSleepService = true;
@@ -8663,11 +7990,6 @@
 		if (_aotReadyToFullWake) {
 			aotEvaluate(NULL);
 		}
-		break;
-	case kPowerEventRunModeRequest:
-		DLOG("power event %u args %p 0x%llx\n", event, OBFUSCATE(arg0), arg1);
-		// arg1 == runModeMask
-		handleRequestRunMode(arg1);
 		break;
 	}
 }
@@ -8864,28 +8186,8 @@
 	 */
 	if (msg & kIOPMPowerEmergency) {
 		DLOG("Received kIOPMPowerEmergency");
-#if HIBERNATION && defined(__arm64__)
-		if (!ml_is_secure_hib_supported() || ldmHibernateDisable) {
-			// Wait for the next low battery notification if the system state is
-			// in transition.
-			if ((_systemTransitionType == kSystemTransitionNone) &&
-			    CAP_CURRENT(kIOPMSystemCapabilityCPU) &&
-			    !systemBooting && !systemShutdown && !gWillShutdown) {
-				// Setting lowBatteryCondition will prevent system sleep
-				lowBatteryCondition = true;
-
-				// Notify userspace to initiate system shutdown
-				DLOG("Initiating userspace shutdown ml_is_secure_hib_supported %d lockdownMode %d", ml_is_secure_hib_supported(), ldmHibernateDisable);
-				messageClients(kIOPMMessageRequestSystemShutdown);
-			}
-		} else {
-			lowBatteryCondition = true;
-			privateSleepSystem(kIOPMSleepReasonLowPower);
-		}
-#else  /* HIBERNATION && defined(__arm64__) */
 		lowBatteryCondition = true;
 		privateSleepSystem(kIOPMSleepReasonLowPower);
-#endif /* HIBERNATION && defined(__arm64__) */
 	}
 
 	/*
@@ -8986,8 +8288,6 @@
 
 		sendClientClamshellNotification();
 
-		IOUserServer::powerSourceChanged(acAdaptorConnected);
-
 		// Re-evaluate the lid state
 		eval_clamshell = true;
 
@@ -9186,8 +8486,8 @@
 		DLOG("aggressiveness changed: system %u->%u, display %u\n",
 		    sleepSlider, minutesToIdleSleep, minutesToDisplayDim);
 
-		DLOG("idle time -> %d ms (ena %d)\n",
-		    idleMilliSeconds, (minutesToIdleSleep != 0));
+		DLOG("idle time -> %d secs (ena %d)\n",
+		    idleSeconds, (minutesToIdleSleep != 0));
 
 		// How long to wait before sleeping the system once
 		// the displays turns off is indicated by 'extraSleepDelay'.
@@ -9208,7 +8508,7 @@
 		}
 #if !defined(XNU_TARGET_OS_OSX)
 		if (0x7fffffff == minutesToIdleSleep) {
-			minutesToIdleSleep = idleMilliSeconds / 1000;
+			minutesToIdleSleep = idleSeconds;
 		}
 #endif /* !defined(XNU_TARGET_OS_OSX) */
 
@@ -9400,7 +8700,7 @@
 			startIdleSleepTimer(getTimeToIdleSleep());
 #else
 			changePowerStateWithTagToPriv(getRUN_STATE(), kCPSReasonIdleSleepEnabled);
-			startIdleSleepTimer( idleMilliSeconds );
+			startIdleSleepTimer( idleSeconds );
 #endif
 		} else {
 			// Start idle timer if prefs now allow system sleep
@@ -9425,20 +8725,18 @@
 
 		if (!systemBooting && (0 == idleSleepPreventersCount())) {
 			if (!wrangler) {
-				if (kStimulusNoIdleSleepPreventers != stimulus) {
-					changePowerStateWithTagToPriv(getRUN_STATE(), kCPSReasonEvaluatePolicy);
-				}
+				changePowerStateWithTagToPriv(getRUN_STATE(), kCPSReasonEvaluatePolicy);
 				if (idleSleepEnabled) {
 #if defined(XNU_TARGET_OS_OSX) && !DISPLAY_WRANGLER_PRESENT
-					if (!extraSleepDelay && !idleSleepTimerPending && !gNoIdleFlag) {
+					if (!extraSleepDelay && !idleSleepTimerPending) {
 						sleepASAP = true;
 					}
 #else
-					// stay awake for at least idleMilliSeconds
-					startIdleSleepTimer(idleMilliSeconds);
+					// stay awake for at least idleSeconds
+					startIdleSleepTimer(idleSeconds);
 #endif
 				}
-			} else if (!extraSleepDelay && !idleSleepTimerPending && !systemDarkWake && !gNoIdleFlag) {
+			} else if (!extraSleepDelay && !idleSleepTimerPending && !systemDarkWake) {
 				sleepASAP = true;
 			}
 		}
@@ -9735,7 +9033,7 @@
 			delta = gPMStats.hibRead.stop - gPMStats.hibRead.start;
 			IOLog("PMStats: Hibernate read took %qd ms\n", delta / NSEC_PER_MSEC);
 
-			publishPMStats = OSData::withValue(gPMStats);
+			publishPMStats = OSData::withBytes(&gPMStats, sizeof(gPMStats));
 			setProperty(kIOPMSleepStatisticsKey, publishPMStats.get());
 			bzero(&gPMStats, sizeof(gPMStats));
 		}
@@ -9819,9 +9117,11 @@
 		if (!id && notify) {
 			id = notify->uuid0;
 		}
-		pidNum = OSNumber::withNumber(id, 64);
-		if (pidNum) {
-			responseDescription->setObject(_statsPIDKey.get(), pidNum.get());
+		if (id != 0) {
+			pidNum = OSNumber::withNumber(id, 64);
+			if (pidNum) {
+				responseDescription->setObject(_statsPIDKey.get(), pidNum.get());
+			}
 		}
 
 		delayNum = OSNumber::withNumber(delay_ms, 32);
@@ -10210,10 +9510,11 @@
 		}
 
 		reportSize = HISTREPORT_BUFSIZE(bktCnt);
-		*report = IOMallocZeroData(reportSize);
+		*report = IOMalloc(reportSize);
 		if (*report == NULL) {
 			break;
 		}
+		bzero(*report, reportSize);
 		HISTREPORT_INIT((uint16_t)bktCnt, bktSize, *report, reportSize,
 		    getRegistryEntryID(), channel_id, kIOReportCategoryPower);
 
@@ -10228,7 +9529,7 @@
 			break;
 		}
 		if (*clientCnt == 1) {
-			IOFreeData(*report, HISTREPORT_BUFSIZE(bktCnt));
+			IOFree(*report, HISTREPORT_BUFSIZE(bktCnt));
 			*report = NULL;
 		}
 		(*clientCnt)--;
@@ -10419,7 +9720,7 @@
 		IOLockLock(l);
 		IOLockLock(l);
 	}
-#endif /* DEVELOPMENT || DEBUG */
+#endif
 }
 
 int
@@ -11023,19 +10324,6 @@
 	ret = pmAssertions->createAssertion(whichAssertionBits, assertionLevel, ownerService, ownerDescription, &newAssertion);
 
 	if (kIOReturnSuccess == ret) {
-#if (DEVELOPMENT || DEBUG)
-		if (_aotNow || (kIOLogPMRootDomain & gIOKitDebug)) {
-			const char *serviceName = (ownerService && ownerService->reserved) ? ownerService->getName() : NULL;
-			OSReportWithBacktrace("PMRD: createPMAssertion(0x%qx) %s (%s)", newAssertion,
-			    serviceName, ownerDescription);
-		}
-#endif /* (DEVELOPMENT || DEBUG) */
-
-		const bool waitForWakeup = (whichAssertionBits & kIOPMDriverAssertionForceWakeupBit);
-		if (waitForWakeup) {
-			waitForSystemTransitionToMinPowerState(AOT_STATE);
-		}
-
 		return newAssertion;
 	} else {
 		return 0;
@@ -11045,22 +10333,10 @@
 IOReturn
 IOPMrootDomain::releasePMAssertion(IOPMDriverAssertionID releaseAssertion)
 {
-#if (DEVELOPMENT || DEBUG)
-	if (_aotNow || (kIOLogPMRootDomain & gIOKitDebug)) {
-		PMAssertStruct *details = pmAssertions->detailsForID(releaseAssertion, NULL);
-		if (details) {
-			const char *serviceName = (details->ownerService && details->ownerService->reserved) ?
-			    details->ownerService->getName() : NULL;
-			const char *ownerString = details->ownerString ? details->ownerString->getCStringNoCopy() : NULL;
-			OSReportWithBacktrace("PMRD: releasePMAssertion(0x%qx) %s (%s)", releaseAssertion, serviceName, ownerString);
-		} else {
-			OSReportWithBacktrace("PMRD: releasePMAssertion(0x%qx)", releaseAssertion);
-		}
-	}
-#endif /* (DEVELOPMENT || DEBUG) */
 	if (!pmAssertions) {
 		return kIOReturnInternalError;
 	}
+
 	return pmAssertions->releaseAssertion(releaseAssertion);
 }
 
@@ -11101,119 +10377,6 @@
 	}
 
 	return pmAssertions->setUserAssertionLevels(inLevels);
-}
-
-IOReturn
-IOPMrootDomain::acquireDriverKitMatchingAssertion()
-{
-	return gIOPMWorkLoop->runActionBlock(^{
-		if (_driverKitMatchingAssertionCount != 0) {
-		        _driverKitMatchingAssertionCount++;
-		        return kIOReturnSuccess;
-		} else {
-		        if (kSystemTransitionSleep == _systemTransitionType && !idleSleepRevertible) {
-		                // system going to sleep
-		                return kIOReturnBusy;
-			} else {
-		                // createPMAssertion is asynchronous.
-		                // we must also set _driverKitMatchingAssertionCount under the PM workloop lock so that we can cancel sleep immediately
-		                // The assertion is used so that on release, we reevaluate all assertions
-		                _driverKitMatchingAssertion = createPMAssertion(kIOPMDriverAssertionCPUBit, kIOPMDriverAssertionLevelOn, this, "DK matching");
-		                if (_driverKitMatchingAssertion != kIOPMUndefinedDriverAssertionID) {
-		                        _driverKitMatchingAssertionCount = 1;
-		                        return kIOReturnSuccess;
-				} else {
-		                        return kIOReturnBusy;
-				}
-			}
-		}
-	});
-}
-
-void
-IOPMrootDomain::releaseDriverKitMatchingAssertion()
-{
-	gIOPMWorkLoop->runActionBlock(^{
-		if (_driverKitMatchingAssertionCount != 0) {
-		        _driverKitMatchingAssertionCount--;
-		        if (_driverKitMatchingAssertionCount == 0) {
-		                releasePMAssertion(_driverKitMatchingAssertion);
-		                _driverKitMatchingAssertion = kIOPMUndefinedDriverAssertionID;
-			}
-		} else {
-		        panic("Over-release of driverkit matching assertion");
-		}
-		return kIOReturnSuccess;
-	});
-}
-
-IOReturn
-IOPMrootDomain::acquireDriverKitSyncedAssertion(IOService * from, IOPMDriverAssertionID * assertionID)
-{
-	return gIOPMWorkLoop->runActionBlock(^{
-		if (kSystemTransitionSleep == _systemTransitionType && !idleSleepRevertible) {
-		        // system going to sleep
-		        return kIOReturnBusy;
-		}
-		// createPMAssertion is asynchronous.
-		// we must also set _driverKitSyncedAssertionCount under the PM workloop lock so that we can cancel sleep immediately
-		// only kIOPMDriverAssertionCPUBit is used for "synced" assertion
-		*assertionID = createPMAssertion(kIOPMDriverAssertionCPUBit, kIOPMDriverAssertionLevelOn, this, from->getName());
-		if (*assertionID != kIOPMUndefinedDriverAssertionID) {
-		        _driverKitSyncedAssertionCount++;
-		        return kIOReturnSuccess;
-		} else {
-		        return kIOReturnBusy;
-		}
-	});
-}
-
-void
-IOPMrootDomain::releaseDriverKitSyncedAssertion(IOPMDriverAssertionID assertionID)
-{
-	gIOPMWorkLoop->runActionBlock(^{
-		if (_driverKitSyncedAssertionCount != 0) {
-		        _driverKitSyncedAssertionCount--;
-		        releasePMAssertion(assertionID);
-		} else {
-		        panic("Over-release of driverkit synced assertion");
-		}
-		return kIOReturnSuccess;
-	});
-}
-
-
-IOReturn
-IOPMrootDomain::createPMAssertionSafe(
-	IOPMDriverAssertionID *assertionID,
-	IOPMDriverAssertionType whichAssertionBits,
-	IOPMDriverAssertionLevel assertionLevel,
-	IOService *ownerService,
-	const char *ownerDescription)
-{
-	IOReturn ret;
-	IOPMDriverAssertionID __block id;
-
-	if (!assertionID) {
-		return kIOReturnBadArgument;
-	}
-
-	// Grab workloop to check current transition
-	ret = gIOPMWorkLoop->runActionBlock(^{
-		if (_systemTransitionType == kSystemTransitionSleep) {
-		        return kIOReturnBusy;
-		}
-		id = createPMAssertion(whichAssertionBits, assertionLevel, ownerService, ownerDescription);
-		return id ? kIOReturnSuccess : kIOReturnError;
-	});
-
-	if (ret == kIOReturnSuccess) {
-		*assertionID = id;
-	} else if (ret == kIOReturnBusy && (kIOLogPMRootDomain & gIOKitDebug)) {
-		DLOG("assertion denied due to ongoing sleep transition (%s)\n", ownerDescription);
-	}
-
-	return ret;
 }
 
 bool
@@ -11344,14 +10507,6 @@
 	WAKEEVENT_UNLOCK();
 }
 
-void
-IOPMrootDomain::copyShutdownTime( uint64_t * time )
-{
-	WAKEEVENT_LOCK();
-	*time = gShutdownTime;
-	WAKEEVENT_UNLOCK();
-}
-
 //******************************************************************************
 // acceptSystemWakeEvents
 //
@@ -11377,7 +10532,6 @@
 				_systemWakeEventsArray->flushCollection();
 			}
 		}
-		_aotWakeEventRunMode = 0;
 
 		// Remove stale WakeType property before system sleep
 		removeProperty(kIOPMRootDomainWakeTypeKey);
@@ -11407,7 +10561,7 @@
 				}
 			}
 			if (i >= strlen(gWakeReasonString)) {
-				panic("Wake reason is empty");
+				panic("Wake reason is empty\n");
 			}
 		}
 #endif /* DEVELOPMENT */
@@ -11460,21 +10614,29 @@
 
 	pmEventTimeStamp(&timestamp);
 
-	uint64_t args[3] = {};
-	strlcpy((char *)args, reason, sizeof(args));
-	kdebugTrace(kPMLogClaimSystemWake, args[0], args[1], args[2], device->getRegistryEntryID());
-
 	IOOptionBits        aotFlags = 0;
 	bool                needAOTEvaluate = FALSE;
 
-	if ((kIOPMAOTModeAddEventFlags & _aotMode) && (!flags || (flags == kIOPMWakeEventSource))) {
-		flags |= kIOPMWakeEventAOTExit;
-
-		// Only allow lingering in AOT_STATE for the two wake reasons used for the wrist raise gesture.
-		if (!strcmp("AOP.OutboxNotEmpty", reason) || !strcmp("spu_gesture", reason)) {
-			flags &= ~kIOPMWakeEventAOTExit;
-		}
-	}
+	if (kIOPMAOTModeAddEventFlags & _aotMode) {
+		if (!strcmp("hold", reason)
+		    || !strcmp("help", reason)
+		    || !strcmp("menu", reason)
+		    || !strcmp("stockholm", reason)
+		    || !strcmp("ringer", reason)
+		    || !strcmp("ringerab", reason)
+		    || !strcmp("smc0", reason)
+		    || !strcmp("AOP.RTPWakeupAP", reason)
+		    || !strcmp("BT.OutboxNotEmpty", reason)
+		    || !strcmp("WL.OutboxNotEmpty", reason)) {
+			flags |= kIOPMWakeEventAOTExit;
+		}
+	}
+
+#if DEVELOPMENT || DEBUG
+	if (_aotLingerTime && !strcmp("rtc", reason)) {
+		flags |= kIOPMWakeEventAOTPossibleExit;
+	}
+#endif /* DEVELOPMENT || DEBUG */
 
 #if defined(XNU_TARGET_OS_OSX) && !DISPLAY_WRANGLER_PRESENT
 	// Publishing the WakeType is serialized by the PM work loop
@@ -11495,7 +10657,7 @@
 	deviceName   = device->copyName(gIOServicePlane);
 	deviceRegId  = OSNumber::withNumber(device->getRegistryEntryID(), 64);
 	claimTime    = OSNumber::withNumber(timestamp, 64);
-	flagsData    = OSData::withValue(flags);
+	flagsData    = OSData::withBytes(&flags, sizeof(flags));
 	reasonString = OSString::withCString(reason);
 	dict = OSDictionary::withCapacity(5 + (details ? 1 : 0));
 	if (!dict || !deviceName || !deviceRegId || !claimTime || !flagsData || !reasonString) {
@@ -11541,20 +10703,6 @@
 	    reason, (int)flags, deviceName->getCStringNoCopy(), device->getRegistryEntryID(),
 	    _aotNow, pmTracer->getTracePhase(), addWakeReason);
 
-#if DEVELOPMENT || DEBUG
-	if (addWakeReason) {
-		record_system_event(SYSTEM_EVENT_TYPE_INFO,
-		    SYSTEM_EVENT_SUBSYSTEM_PMRD,
-		    "Report System Wake Event",
-		    "Reason: %s Flags: 0x%x Device: %s, DeviceRegEntry: 0x%llx\n",
-		    reason,
-		    (int)flags,
-		    deviceName->getCStringNoCopy(),
-		    device->getRegistryEntryID()
-		    );
-	}
-#endif /* DEVELOPMENT || DEBUG */
-
 	if (!gWakeReasonSysctlRegistered) {
 		// Lazy registration until the platform driver stops registering
 		// the same name.
@@ -11566,17 +10714,6 @@
 			strlcat(gWakeReasonString, " ", sizeof(gWakeReasonString));
 		}
 		strlcat(gWakeReasonString, reason, sizeof(gWakeReasonString));
-	}
-
-	if (_aotNow && _acceptSystemWakeEvents) {
-		uint64_t runModeBits = (kIOPMAOTModeRunModeMask & flags) >> kIOPMAOTModeRunModeShift;
-		if (runModeBits) {
-			if (_aotWakeEventRunModeImpliesStorage & runModeBits) {
-				runModeBits |= kIOPMDriverClassStorage;
-			}
-			IOLog("AOT wake event %s -> mode 0x%llx\n", reasonString->getCStringNoCopy(), runModeBits);
-			_aotWakeEventRunMode |= runModeBits;
-		}
 	}
 
 	WAKEEVENT_UNLOCK();
@@ -11608,16 +10745,6 @@
 	}
 
 	DEBUG_LOG("claimSystemBootEvent(%s, %s, 0x%x)\n", reason, device->getName(), (uint32_t) flags);
-#if DEVELOPMENT || DEBUG
-	record_system_event(SYSTEM_EVENT_TYPE_INFO,
-	    SYSTEM_EVENT_SUBSYSTEM_PMRD,
-	    "Report System Boot Device",
-	    "Reason: %s Flags: 0x%x Device: %s",
-	    reason,
-	    (int)flags,
-	    device->getName()
-	    );
-#endif /* DEVELOPMENT || DEBUG */
 	WAKEEVENT_LOCK();
 	if (!gBootReasonSysctlRegistered) {
 		// Lazy sysctl registration after setting gBootReasonString
@@ -11638,78 +10765,21 @@
 	IOService *              device,
 	IOOptionBits             flags,
 	const char *             reason,
-	OSObject *               details )
+	__unused OSObject *      details )
 {
 	if (!device || !reason) {
 		return;
 	}
 
 	DEBUG_LOG("claimSystemShutdownEvent(%s, %s, 0x%x)\n", reason, device->getName(), (uint32_t) flags);
-#if DEVELOPMENT || DEBUG
-	record_system_event(SYSTEM_EVENT_TYPE_INFO,
-	    SYSTEM_EVENT_SUBSYSTEM_PMRD,
-	    "Report System Shutdown Cause From Previous Boot",
-	    "Reason: %s Flags: 0x%x Device: %s",
-	    reason,
-	    (int)flags,
-	    device->getName()
-	    );
-#endif /* DEVELOPMENT || DEBUG */
 	WAKEEVENT_LOCK();
 	if (gShutdownReasonString[0] != '\0') {
 		strlcat(gShutdownReasonString, " ", sizeof(gShutdownReasonString));
 	}
 	strlcat(gShutdownReasonString, reason, sizeof(gShutdownReasonString));
 
-	if (details) {
-		OSDictionary *dict = OSDynamicCast(OSDictionary, details);
-		if (dict) {
-			OSSharedPtr<OSString> sharedKey = OSString::withCString(kIOPMRootDomainShutdownTime);
-			if (sharedKey) {
-				OSNumber *num = OSDynamicCast(OSNumber, dict->getObject(sharedKey.get()));
-				if (num) {
-					gShutdownTime = (uint64_t)(num->unsigned64BitValue());
-				}
-			}
-		}
-	}
-
 	gShutdownReasonSysctlRegistered = true;
 	WAKEEVENT_UNLOCK();
-}
-
-//******************************************************************************
-// requestRunMode
-//
-// For clients to request a LPW run mode. Only full wake is supported currently.
-//******************************************************************************
-
-IOReturn
-IOPMrootDomain::requestRunMode(uint64_t runModeMask)
-{
-	// We only support requesting full wake at the moment
-	if (runModeMask == kIOPMRunModeFullWake) {
-		pmPowerStateQueue->submitPowerEvent(kPowerEventRunModeRequest, NULL, runModeMask);
-		return kIOReturnSuccess;
-	}
-	return kIOReturnUnsupported;
-}
-
-IOReturn
-IOPMrootDomain::handleRequestRunMode(uint64_t runModeMask)
-{
-	// TODO: Replace with run mode logic when implemented
-	IOReturn ret = kIOReturnUnsupported;
-
-	// We only support requesting full wake at the moment
-	if (runModeMask == kIOPMRunModeFullWake) {
-		// A simple CPS should suffice for now
-		changePowerStateWithTagToPriv(ON_STATE, kCPSReasonEvaluatePolicy);
-		ret = kIOReturnSuccess;
-	}
-
-	DLOG("%s: mask %llx ret %x\n", __func__, runModeMask, ret);
-	return ret;
 }
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -11787,7 +10857,7 @@
 	pmsh->pmso = pmso;
 	pmso->pmsh = pmsh;
 
-	pmso->publishedFeatureID = OSDataAllocation<uint32_t>(settingCount, OSAllocateMemory);
+	pmso->publishedFeatureID = (uint32_t *)IOMalloc(sizeof(uint32_t) * settingCount);
 	if (pmso->publishedFeatureID) {
 		for (unsigned int i = 0; i < settingCount; i++) {
 			// Since there is now at least one listener to this setting, publish
@@ -11814,13 +10884,13 @@
 PMSettingObject::free( void )
 {
 	if (publishedFeatureID) {
-		for (const auto& featureID : publishedFeatureID) {
-			if (featureID) {
-				parent->removePublishedFeature( featureID );
-			}
-		}
-
-		publishedFeatureID = {};
+		for (uint32_t i = 0; i < settingCount; i++) {
+			if (publishedFeatureID[i]) {
+				parent->removePublishedFeature( publishedFeatureID[i] );
+			}
+		}
+
+		IOFree(publishedFeatureID, sizeof(uint32_t) * settingCount);
 	}
 
 	super::free();
@@ -11869,7 +10939,6 @@
 	me->assertionsCombined = 0;
 	me->assertionsArrayLock = IOLockAlloc();
 	me->tabulateProducerCount = me->tabulateConsumerCount = 0;
-	bzero(&me->assertionsLog, sizeof(me->assertionsLog));
 
 	assert(me->assertionsArray);
 	assert(me->assertionsArrayLock);
@@ -11887,8 +10956,8 @@
 {
 	int i;
 	int count;
-	const PMAssertStruct *_a = nullptr;
-	OSValueObject<PMAssertStruct> *_d = nullptr;
+	PMAssertStruct      *_a = NULL;
+	OSData              *_d = NULL;
 
 	IOPMDriverAssertionType oldKernel = assertionsKernel;
 	IOPMDriverAssertionType oldCombined = assertionsCombined;
@@ -11904,9 +10973,9 @@
 
 	if ((count = assertionsArray->getCount())) {
 		for (i = 0; i < count; i++) {
-			_d = OSDynamicCast(OSValueObject<PMAssertStruct>, assertionsArray->getObject(i));
+			_d = OSDynamicCast(OSData, assertionsArray->getObject(i));
 			if (_d) {
-				_a = _d->getBytesNoCopy();
+				_a = (PMAssertStruct *)_d->getBytesNoCopy();
 				if (_a && (kIOPMDriverAssertionLevelOn == _a->level)) {
 					assertionsKernel |= _a->assertionBits;
 				}
@@ -11926,7 +10995,7 @@
 void
 PMAssertionsTracker::updateCPUBitAccounting( PMAssertStruct *assertStruct )
 {
-	AbsoluteTime now, elapsed;
+	AbsoluteTime now;
 	uint64_t     nsec;
 
 	if (((assertStruct->assertionBits & kIOPMDriverAssertionCPUBit) == 0) ||
@@ -11934,11 +11003,9 @@
 		return;
 	}
 
-	now = mach_continuous_time();
-	assertionsLog.addInterval(assertStruct->id, assertStruct->assertCPUStartTime, now);
-
-	elapsed = now - assertStruct->assertCPUStartTime;
-	absolutetime_to_nanoseconds(elapsed, &nsec);
+	now = mach_absolute_time();
+	SUB_ABSOLUTETIME(&now, &assertStruct->assertCPUStartTime);
+	absolutetime_to_nanoseconds(now, &nsec);
 	assertStruct->assertCPUDuration += nsec;
 	assertStruct->assertCPUStartTime = 0;
 
@@ -11951,8 +11018,8 @@
 void
 PMAssertionsTracker::reportCPUBitAccounting( void )
 {
-	const PMAssertStruct *_a = nullptr;
-	OSValueObject<PMAssertStruct> *_d = nullptr;
+	PMAssertStruct *_a;
+	OSData         *_d;
 	int            i, count;
 	AbsoluteTime   now;
 	uint64_t       nsec;
@@ -11964,9 +11031,9 @@
 		now = mach_absolute_time();
 		if ((count = assertionsArray->getCount())) {
 			for (i = 0; i < count; i++) {
-				_d = OSDynamicCast(OSValueObject<PMAssertStruct>, assertionsArray->getObject(i));
+				_d = OSDynamicCast(OSData, assertionsArray->getObject(i));
 				if (_d) {
-					_a = _d->getBytesNoCopy();
+					_a = (PMAssertStruct *)_d->getBytesNoCopy();
 					if ((_a->assertionBits & kIOPMDriverAssertionCPUBit) &&
 					    (_a->level == kIOPMDriverAssertionLevelOn) &&
 					    (_a->assertCPUStartTime != 0)) {
@@ -12021,11 +11088,11 @@
 	}
 }
 
-PMAssertStruct *
+PMAssertionsTracker::PMAssertStruct *
 PMAssertionsTracker::detailsForID(IOPMDriverAssertionID _id, int *index)
 {
 	PMAssertStruct      *_a = NULL;
-	OSValueObject<PMAssertStruct> *_d = nullptr;
+	OSData              *_d = NULL;
 	int                 found = -1;
 	int                 count = 0;
 	int                 i = 0;
@@ -12033,9 +11100,9 @@
 	if (assertionsArray
 	    && (count = assertionsArray->getCount())) {
 		for (i = 0; i < count; i++) {
-			_d = OSDynamicCast(OSValueObject<PMAssertStruct>, assertionsArray->getObject(i));
+			_d = OSDynamicCast(OSData, assertionsArray->getObject(i));
 			if (_d) {
-				_a = _d->getMutableBytesNoCopy();
+				_a = (PMAssertStruct *)_d->getBytesNoCopy();
 				if (_a && (_id == _a->id)) {
 					found = i;
 					break;
@@ -12058,23 +11125,19 @@
  * Perform assertion work on the PM workloop. Do not call directly.
  */
 IOReturn
-PMAssertionsTracker::handleCreateAssertion(OSValueObject<PMAssertStruct> *newAssertion)
-{
-	PMAssertStruct *assertStruct = nullptr;
+PMAssertionsTracker::handleCreateAssertion(OSData *newAssertion)
+{
+	PMAssertStruct *assertStruct;
 
 	ASSERT_GATED();
 
 	if (newAssertion) {
-		assertStruct = newAssertion->getMutableBytesNoCopy();
-
+		IOLockLock(assertionsArrayLock);
+		assertStruct = (PMAssertStruct *) newAssertion->getBytesNoCopy();
 		if ((assertStruct->assertionBits & kIOPMDriverAssertionCPUBit) &&
 		    (assertStruct->level == kIOPMDriverAssertionLevelOn)) {
-			assertStruct->assertCPUStartTime = mach_continuous_time();
-		}
-
-		assertionsLog.addName(assertStruct->id, assertStruct->ownerString->getCStringNoCopy());
-
-		IOLockLock(assertionsArrayLock);
+			assertStruct->assertCPUStartTime = mach_absolute_time();
+		}
 		assertionsArray->setObject(newAssertion);
 		IOLockUnlock(assertionsArrayLock);
 		newAssertion->release();
@@ -12096,7 +11159,7 @@
 	const char *whoItIs,
 	IOPMDriverAssertionID *outID)
 {
-	OSSharedPtr<OSValueObject<PMAssertStruct> > dataStore;
+	OSSharedPtr<OSData>         dataStore;
 	PMAssertStruct  track;
 
 	// Warning: trillions and trillions of created assertions may overflow the unique ID.
@@ -12114,7 +11177,7 @@
 	track.assertCPUStartTime = 0;
 	track.assertCPUDuration = 0;
 
-	dataStore = OSValueObjectWithValue(track);
+	dataStore = OSData::withBytes(&track, sizeof(PMAssertStruct));
 	if (!dataStore) {
 		if (track.ownerString) {
 			track.ownerString->release();
@@ -12203,7 +11266,7 @@
 	if ((assertStruct->assertionBits & kIOPMDriverAssertionCPUBit) &&
 	    (assertStruct->level != _level)) {
 		if (_level == kIOPMDriverAssertionLevelOn) {
-			assertStruct->assertCPUStartTime = mach_continuous_time();
+			assertStruct->assertCPUStartTime = mach_absolute_time();
 		} else {
 			updateCPUBitAccounting(assertStruct);
 		}
@@ -12280,12 +11343,12 @@
 	}
 
 	for (i = 0; i < count; i++) {
-		const PMAssertStruct *_a = nullptr;
-		OSValueObject<PMAssertStruct> *_d = nullptr;
+		PMAssertStruct  *_a = NULL;
+		OSData          *_d = NULL;
 		OSSharedPtr<OSDictionary>    details;
 
-		_d = OSDynamicCast(OSValueObject<PMAssertStruct>, assertionsArray->getObject(i));
-		if (_d && (_a = _d->getBytesNoCopy())) {
+		_d = OSDynamicCast(OSData, assertionsArray->getObject(i));
+		if (_d && (_a = (PMAssertStruct *)_d->getBytesNoCopy())) {
 			OSSharedPtr<OSNumber>        _n;
 
 			details = OSDictionary::withCapacity(7);
@@ -12393,8 +11456,8 @@
 
 static IOPMPowerState patriarchPowerStates[2] =
 {
-	{.version = kIOPMPowerStateVersion1, .outputPowerCharacter = ON_POWER },
-	{.version = kIOPMPowerStateVersion1, .outputPowerCharacter = ON_POWER }
+	{1, 0, ON_POWER, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{1, 0, ON_POWER, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 };
 
 void
@@ -12820,20 +11883,18 @@
 
 	const void *            callMethod = NULL;
 	const char *            objectName = NULL;
+	uint32_t                timeout = getWatchdogTimeout();
 	const char *            phaseString = NULL;
 	const char *            phaseDescription = NULL;
-	uint64_t                delta;
 
 	IOPMServiceInterestNotifier *notifier = OSDynamicCast(IOPMServiceInterestNotifier, notifierObject.get());
 	uint32_t tracePhase = pmTracer->getTracePhase();
 
 	*thread = NULL;
-
-	delta = get_watchdog_elapsed_time();
 	if ((tracePhase < kIOPMTracePointSystemSleep) || (tracePhase == kIOPMTracePointDarkWakeEntry)) {
-		snprintf(failureStr, strLen, "Sleep transition timed out after %qd seconds", delta);
+		snprintf(failureStr, strLen, "Sleep transition timed out after %d seconds", timeout);
 	} else {
-		snprintf(failureStr, strLen, "Wake transition timed out after %qd seconds", delta);
+		snprintf(failureStr, strLen, "Wake transition timed out after %d seconds", timeout);
 	}
 	tracePhase2String(tracePhase, &phaseString, &phaseDescription);
 
@@ -13086,7 +12147,7 @@
 {
 	swd_hdr *                hdr = NULL;
 	int                      cnt = 0;
-	int                      max_cnt;
+	int                      max_cnt = 2;
 	pid_t                    pid = 0;
 	kern_return_t            kr = KERN_SUCCESS;
 	uint64_t                 flags;
@@ -13143,16 +12204,13 @@
 	bufSize = hdr->alloc_size;
 
 	dstAddr = (char*)hdr + hdr->spindump_offset;
-	flags = STACKSHOT_KCDATA_FORMAT | STACKSHOT_NO_IO_STATS | STACKSHOT_SAVE_KEXT_LOADINFO | STACKSHOT_ACTIVE_KERNEL_THREADS_ONLY | STACKSHOT_THREAD_WAITINFO | STACKSHOT_INCLUDE_DRIVER_THREADS_IN_KERNEL;
-
+	flags = STACKSHOT_KCDATA_FORMAT | STACKSHOT_NO_IO_STATS | STACKSHOT_SAVE_KEXT_LOADINFO | STACKSHOT_ACTIVE_KERNEL_THREADS_ONLY | STACKSHOT_THREAD_WAITINFO;
 	/* If not wdogTrigger only take kernel tasks stackshot
 	 */
 	if (wdogTrigger) {
 		pid = -1;
-		max_cnt = 3;
 	} else {
 		pid = 0;
-		max_cnt = 2;
 	}
 
 	/* Attempt to take stackshot with all ACTIVE_KERNEL_THREADS
@@ -13170,8 +12228,6 @@
 		if (kr == KERN_INSUFFICIENT_BUFFER_SIZE) {
 			if (pid == -1) {
 				pid = 0;
-			} else if (flags & STACKSHOT_INCLUDE_DRIVER_THREADS_IN_KERNEL) {
-				flags = flags & ~STACKSHOT_INCLUDE_DRIVER_THREADS_IN_KERNEL;
 			} else {
 				LOG("Insufficient buffer size for only kernel task\n");
 				break;
@@ -13219,12 +12275,9 @@
 						success = 1;
 						LOG("Successfully saved stackshot to NVRAM\n");
 					} else {
+						LOG("Compressed failure stackshot is too large. size=%d bytes\n", outlen);
 						if (pid == -1) {
-							LOG("Compressed failure stackshot is too large. size=%d bytes\n", outlen);
 							pid = 0;
-						} else if (flags & STACKSHOT_INCLUDE_DRIVER_THREADS_IN_KERNEL) {
-							LOG("Compressed failure stackshot of kernel+dexts is too large size=%d bytes\n", outlen);
-							flags = flags & ~STACKSHOT_INCLUDE_DRIVER_THREADS_IN_KERNEL;
 						} else {
 							LOG("Compressed failure stackshot of only kernel is too large size=%d bytes\n", outlen);
 							break;
@@ -13259,14 +12312,20 @@
 				// then don't trigger again until at least 1 successful sleep & wake.
 				if (!(sleepCnt && (displayWakeCnt || darkWakeCnt))) {
 					LOG("Shutting down due to repeated Sleep/Wake failures\n");
-					updateTasksSuspend(kTasksSuspendSuspended, kTasksSuspendNoChange);
+					if (!tasksSuspended) {
+						tasksSuspended = TRUE;
+						updateTasksSuspend();
+					}
 					PEHaltRestart(kPEHaltCPU);
 					return;
 				}
 			}
 			if (gSwdPanic == 0) {
 				LOG("Calling panic prevented by swd_panic boot-args. Calling restart");
-				updateTasksSuspend(kTasksSuspendSuspended, kTasksSuspendNoChange);
+				if (!tasksSuspended) {
+					tasksSuspended = TRUE;
+					updateTasksSuspend();
+				}
 				PEHaltRestart(kPERestartCPU);
 			}
 		}