Loading...
--- xnu/xnu-12377.121.6/iokit/Kernel/IOPMrootDomain.cpp
+++ xnu/xnu-8792.61.2/iokit/Kernel/IOPMrootDomain.cpp
@@ -54,14 +54,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 +67,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>
@@ -83,14 +79,9 @@
#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 +90,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 +113,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 +182,7 @@
kPowerEventPublishSleepWakeUUID, // 13
kPowerEventSetDisplayPowerOn, // 14
kPowerEventPublishWakeType, // 15
- kPowerEventAOTEvaluate, // 16
- kPowerEventRunModeRequest // 17
+ kPowerEventAOTEvaluate // 16
};
// For evaluatePolicy()
@@ -324,11 +312,7 @@
// 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 DISPLAY_WRANGLER_PRESENT (!NO_KERNEL_HID)
@@ -337,6 +321,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 +474,6 @@
kPMChildPreventSystemSleep,
kPMCPUAssertion,
kPMPCIUnsupported,
- kPMDKNotReady,
};
const char *
@@ -495,7 +487,6 @@
SYSTEM_SLEEP_PREVENTER( kPMChildPreventSystemSleep ),
SYSTEM_SLEEP_PREVENTER( kPMCPUAssertion ),
SYSTEM_SLEEP_PREVENTER( kPMPCIUnsupported ),
- SYSTEM_SLEEP_PREVENTER( kPMDKNotReady ),
{ 0, NULL }
};
return IOFindNameForValue(preventer, systemSleepPreventers);
@@ -620,7 +611,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;
@@ -767,72 +757,6 @@
uint8_t loginWindowData;
uint8_t coreDisplayData;
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));
- }
};
/*
@@ -878,7 +802,6 @@
IOReturn handleSetUserAssertionLevels(void * arg0);
void publishProperties(void);
void reportCPUBitAccounting(void);
- PMAssertStruct *detailsForID(IOPMDriverAssertionID, int *);
private:
uint32_t tabulateProducerCount;
@@ -887,6 +810,7 @@
uint64_t maxAssertCPUDuration;
uint64_t maxAssertCPUEntryId;
+ PMAssertStruct *detailsForID(IOPMDriverAssertionID, int *);
void tabulate(void);
void updateCPUBitAccounting(PMAssertStruct * assertStruct);
@@ -897,10 +821,6 @@
IOPMDriverAssertionType assertionsKernel;
IOPMDriverAssertionType assertionsUser;
IOPMDriverAssertionType assertionsCombined;
-
- IOPMAssertionLog assertionsLog;
-
- friend class IOPMrootDomain;
};
OSDefineMetaClassAndFinalStructors(PMAssertionsTracker, OSObject);
@@ -1446,26 +1366,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 +1387,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, "");
@@ -1580,8 +1417,6 @@
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", "");
@@ -1656,15 +1491,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 +1512,7 @@
//
//******************************************************************************
-#define kRootDomainSettingsCount 21
+#define kRootDomainSettingsCount 20
#define kRootDomainNoPublishSettingsCount 4
bool
@@ -1732,7 +1558,6 @@
gIOPMSettingDebugPowerRelativeKey,
OSSymbol::withCString(kIOPMSettingWakeOnRingKey),
OSSymbol::withCString(kIOPMSettingRestartOnPowerLossKey),
- OSSymbol::withCString(kIOPMSettingRestartOnPowerConnectKey),
OSSymbol::withCString(kIOPMSettingWakeOnClamshellKey),
OSSymbol::withCString(kIOPMSettingWakeOnACChangeKey),
OSSymbol::withCString(kIOPMSettingTimeZoneOffsetKey),
@@ -1768,10 +1593,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);
@@ -1786,7 +1607,6 @@
settingsCtrlLock = IOLockAlloc();
wakeEventLock = IOLockAlloc();
gHaltLogLock = IOLockAlloc();
- setPMRootDomain(this);
extraSleepTimer = thread_call_allocate(
idleSleepTimerExpired,
@@ -1826,7 +1646,6 @@
userDisabledAllSleep = false;
systemBooting = true;
idleSleepEnabled = false;
- idleSleepRevertible = true;
sleepSlider = 0;
idleSleepTimerPending = false;
wrangler = NULL;
@@ -1908,9 +1727,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,6 +1734,7 @@
&IOPMrootDomain::dispatchPowerEvent));
gIOPMWorkLoop->addEventSource(pmPowerStateQueue);
+ _aotMode = 0;
_aotTimerES = IOTimerEventSource::timerEventSource(this,
OSMemberFunctionCast(IOTimerEventSource::Action,
this, &IOPMrootDomain::aotEvaluate));
@@ -1925,7 +1742,7 @@
// Avoid publishing service early so gIOPMWorkLoop is
// guaranteed to be initialized by rootDomain.
- publishPMRootDomain();
+ setPMRootDomain(this);
// create our power parent
gPatriarch = new IORootParent;
@@ -1984,6 +1801,8 @@
gWillShutdownSysctlRegistered = true;
#if HIBERNATION
+#if defined(__arm64__)
+#endif /* defined(__arm64__) */
IOHibernateSystemInit(this);
#endif
@@ -2214,79 +2033,6 @@
exit:
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: -
@@ -3069,19 +2815,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;
@@ -3150,6 +2883,7 @@
if (!_aotLastWakeTime) {
gIOLastUserSleepTime = gIOLastSleepTime;
}
+
gIOLastWakeTime.tv_sec = 0;
gIOLastWakeTime.tv_usec = 0;
gIOLastSleepAbsTime = now;
@@ -3169,23 +2903,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 +2944,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 +2978,9 @@
if (_aotTestTime) {
if (_aotWakeTimeUTC <= secs) {
- _aotTestTime = mach_continuous_time() + _aotTestInterval;
+ _aotTestTime = _aotTestTime + _aotTestInterval;
}
- if (_aotTestTime < _aotEndTime) {
- _setWakeTime(_aotTestTime);
- }
+ setWakeTime(_aotTestTime);
}
}
@@ -3293,7 +3008,6 @@
isRTCAlarmWake = false;
clamshellIgnoreClose = false;
fullWakeReason = kFullWakeReasonNone;
- idleSleepRevertible = true;
#if defined(__i386__) || defined(__x86_64__)
kdebugTrace(kPMLogSystemWake, 0, 0, 0);
@@ -3423,17 +3137,10 @@
// 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);
- }
+ aotShouldExit(false, false);
WAKEEVENT_UNLOCK();
- changePowerStateWithTagToPriv(newState, kCPSReasonWake);
+ changePowerStateWithTagToPriv(getRUN_STATE(), kCPSReasonWake);
break;
}
#if !__i386__ && !__x86_64__
@@ -3911,7 +3618,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
@@ -4419,45 +4125,37 @@
}
//******************************************************************************
-// 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 (updateTasksSuspend(kTasksSuspendSuspended, kTasksSuspendNoChange)) {
+ 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) */
+ }
+
_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
@@ -4475,68 +4173,32 @@
_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;
@@ -6443,17 +6105,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 +6178,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 +6234,7 @@
if ((kSystemTransitionCapability == _systemTransitionType) &&
(_pendingCapability == _currentCapability)) {
// Cancel the PM state change.
- setSystemTransitionTypeGated(kSystemTransitionNone);
+ _systemTransitionType = kSystemTransitionNone;
*inOutChangeFlags |= kIOPMNotDone;
}
if (__builtin_popcount(_pendingCapability) <
@@ -6693,12 +6343,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 +6382,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 +6397,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 +6404,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 +6419,7 @@
IOPMPowerChangeFlags changeFlags )
{
if (kSystemTransitionNewCapClient == _systemTransitionType) {
- setSystemTransitionTypeGated(kSystemTransitionNone);
+ _systemTransitionType = kSystemTransitionNone;
return;
}
@@ -6923,24 +6513,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 +6566,7 @@
tracePoint( kIOPMTracePointSystemUp );
}
- setSystemTransitionTypeGated(kSystemTransitionNone);
-
+ _systemTransitionType = kSystemTransitionNone;
_systemMessageClientMask = 0;
toldPowerdCapWillChange = false;
@@ -7837,29 +7408,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 +7420,6 @@
err = kPMChildPreventSystemSleep; // 4. child prevent system sleep clamp
break;
}
-
if (getPMAssertionLevel( kIOPMDriverAssertionCPUBit ) ==
kIOPMDriverAssertionLevelOn) {
@@ -7951,106 +7498,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
//******************************************************************************
@@ -8192,42 +7639,8 @@
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;
@@ -8270,7 +7683,7 @@
// assumes WAKEEVENT_LOCK
bool
-IOPMrootDomain::aotShouldExit(bool software)
+IOPMrootDomain::aotShouldExit(bool checkTimeSet, bool software)
{
bool exitNow = false;
const char * reason = "";
@@ -8286,6 +7699,10 @@
} else if (kIOPMWakeEventAOTExitFlags & _aotPendingFlags) {
exitNow = true;
reason = gWakeReasonString;
+ } else if (checkTimeSet && (kPMCalendarTypeInvalid == _aotWakeTimeCalendar.selector)) {
+ exitNow = true;
+ _aotMetrics->noTimeSetCount++;
+ reason = "flipbook expired";
} else if ((kIOPMAOTModeRespectTimers & _aotMode) && _calendarWakeAlarmUTC) {
clock_sec_t sec;
clock_usec_t usec;
@@ -8318,7 +7735,6 @@
ASSERT_GATED();
_aotNow = false;
- _aotRunMode = 0;
_aotReadyToFullWake = false;
if (_aotTimerScheduled) {
_aotTimerES->cancelTimeout();
@@ -8358,7 +7774,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 +7807,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 +7819,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) {
@@ -8469,8 +7889,6 @@
}
}
-TUNABLE(bool, test_sleep_in_vm, "test_sleep_in_vm", false);
-
//******************************************************************************
// dispatchPowerEvent
//
@@ -8501,12 +7919,7 @@
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);
@@ -8641,9 +8054,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 +8074,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 +8270,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__) */
}
/*
@@ -9425,12 +8811,10 @@
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
@@ -9438,7 +8822,7 @@
startIdleSleepTimer(idleMilliSeconds);
#endif
}
- } else if (!extraSleepDelay && !idleSleepTimerPending && !systemDarkWake && !gNoIdleFlag) {
+ } else if (!extraSleepDelay && !idleSleepTimerPending && !systemDarkWake) {
sleepASAP = true;
}
}
@@ -9819,9 +9203,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);
@@ -10419,7 +9805,7 @@
IOLockLock(l);
IOLockLock(l);
}
-#endif /* DEVELOPMENT || DEBUG */
+#endif
}
int
@@ -11024,18 +10410,10 @@
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);
+ if (_aotNow) {
+ OSReportWithBacktrace("IOPMrootDomain::createPMAssertion(0x%qx)", newAssertion);
}
#endif /* (DEVELOPMENT || DEBUG) */
-
- const bool waitForWakeup = (whichAssertionBits & kIOPMDriverAssertionForceWakeupBit);
- if (waitForWakeup) {
- waitForSystemTransitionToMinPowerState(AOT_STATE);
- }
-
return newAssertion;
} else {
return 0;
@@ -11046,16 +10424,8 @@
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);
- }
+ if (_aotNow) {
+ OSReportWithBacktrace("IOPMrootDomain::releasePMAssertion(0x%qx)", releaseAssertion);
}
#endif /* (DEVELOPMENT || DEBUG) */
if (!pmAssertions) {
@@ -11101,119 +10471,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 +10601,6 @@
WAKEEVENT_UNLOCK();
}
-void
-IOPMrootDomain::copyShutdownTime( uint64_t * time )
-{
- WAKEEVENT_LOCK();
- *time = gShutdownTime;
- WAKEEVENT_UNLOCK();
-}
-
//******************************************************************************
// acceptSystemWakeEvents
//
@@ -11377,7 +10626,6 @@
_systemWakeEventsArray->flushCollection();
}
}
- _aotWakeEventRunMode = 0;
// Remove stale WakeType property before system sleep
removeProperty(kIOPMRootDomainWakeTypeKey);
@@ -11460,21 +10708,30 @@
pmEventTimeStamp(×tamp);
- 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("AOP.RTP_AP_IRQ", 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
@@ -11541,20 +10798,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 +10809,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 +10840,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 +10860,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;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -11869,7 +11034,6 @@
me->assertionsCombined = 0;
me->assertionsArrayLock = IOLockAlloc();
me->tabulateProducerCount = me->tabulateConsumerCount = 0;
- bzero(&me->assertionsLog, sizeof(me->assertionsLog));
assert(me->assertionsArray);
assert(me->assertionsArrayLock);
@@ -11926,7 +11090,7 @@
void
PMAssertionsTracker::updateCPUBitAccounting( PMAssertStruct *assertStruct )
{
- AbsoluteTime now, elapsed;
+ AbsoluteTime now;
uint64_t nsec;
if (((assertStruct->assertionBits & kIOPMDriverAssertionCPUBit) == 0) ||
@@ -11934,11 +11098,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;
@@ -12065,16 +11227,12 @@
ASSERT_GATED();
if (newAssertion) {
+ IOLockLock(assertionsArrayLock);
assertStruct = newAssertion->getMutableBytesNoCopy();
-
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();
@@ -12203,7 +11361,7 @@
if ((assertStruct->assertionBits & kIOPMDriverAssertionCPUBit) &&
(assertStruct->level != _level)) {
if (_level == kIOPMDriverAssertionLevelOn) {
- assertStruct->assertCPUStartTime = mach_continuous_time();
+ assertStruct->assertCPUStartTime = mach_absolute_time();
} else {
updateCPUBitAccounting(assertStruct);
}
@@ -12393,8 +11551,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 +11978,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);