Loading...
--- xnu/xnu-12377.121.6/iokit/Kernel/IOPMrootDomain.cpp
+++ xnu/xnu-8019.41.5/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()
@@ -321,15 +309,6 @@
#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 DISPLAY_WRANGLER_PRESENT (!NO_KERNEL_HID)
enum {
@@ -337,6 +316,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 +469,6 @@
kPMChildPreventSystemSleep,
kPMCPUAssertion,
kPMPCIUnsupported,
- kPMDKNotReady,
};
const char *
@@ -495,7 +482,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 +538,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 +606,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;
@@ -769,90 +754,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 +773,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 +815,6 @@
IOPMDriverAssertionType assertionsKernel;
IOPMDriverAssertionType assertionsUser;
IOPMDriverAssertionType assertionsCombined;
-
- IOPMAssertionLog assertionsLog;
-
- friend class IOPMrootDomain;
};
OSDefineMetaClassAndFinalStructors(PMAssertionsTracker, OSObject);
@@ -1180,30 +1094,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 +1331,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 +1353,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 +1374,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 +1398,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", "");
@@ -1656,15 +1477,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 +1498,7 @@
//
//******************************************************************************
-#define kRootDomainSettingsCount 21
+#define kRootDomainSettingsCount 20
#define kRootDomainNoPublishSettingsCount 4
bool
@@ -1732,7 +1544,6 @@
gIOPMSettingDebugPowerRelativeKey,
OSSymbol::withCString(kIOPMSettingWakeOnRingKey),
OSSymbol::withCString(kIOPMSettingRestartOnPowerLossKey),
- OSSymbol::withCString(kIOPMSettingRestartOnPowerConnectKey),
OSSymbol::withCString(kIOPMSettingWakeOnClamshellKey),
OSSymbol::withCString(kIOPMSettingWakeOnACChangeKey),
OSSymbol::withCString(kIOPMSettingTimeZoneOffsetKey),
@@ -1768,15 +1579,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 +1628,6 @@
userDisabledAllSleep = false;
systemBooting = true;
idleSleepEnabled = false;
- idleSleepRevertible = true;
sleepSlider = 0;
idleSleepTimerPending = false;
wrangler = NULL;
@@ -1908,9 +1709,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 +1716,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 +1779,8 @@
gWillShutdownSysctlRegistered = true;
#if HIBERNATION
+#if defined(__arm64__)
+#endif /* defined(__arm64__) */
IOHibernateSystemInit(this);
#endif
@@ -2214,79 +2011,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: -
@@ -2582,7 +2306,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);
@@ -2797,29 +2521,6 @@
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);
thread_call_enter_delayed(extraSleepTimer, deadline);
idleSleepTimerPending = true;
@@ -3069,19 +2770,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 +2838,7 @@
if (!_aotLastWakeTime) {
gIOLastUserSleepTime = gIOLastSleepTime;
}
+
gIOLastWakeTime.tv_sec = 0;
gIOLastWakeTime.tv_usec = 0;
gIOLastSleepAbsTime = now;
@@ -3169,23 +2858,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 +2899,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 +2933,9 @@
if (_aotTestTime) {
if (_aotWakeTimeUTC <= secs) {
- _aotTestTime = mach_continuous_time() + _aotTestInterval;
+ _aotTestTime = _aotTestTime + _aotTestInterval;
}
- if (_aotTestTime < _aotEndTime) {
- _setWakeTime(_aotTestTime);
- }
+ setWakeTime(_aotTestTime);
}
}
@@ -3293,7 +2963,6 @@
isRTCAlarmWake = false;
clamshellIgnoreClose = false;
fullWakeReason = kFullWakeReasonNone;
- idleSleepRevertible = true;
#if defined(__i386__) || defined(__x86_64__)
kdebugTrace(kPMLogSystemWake, 0, 0, 0);
@@ -3423,17 +3092,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 +3573,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 +3673,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,52 +4075,45 @@
}
//******************************************************************************
-// 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));
}
@@ -4475,68 +4124,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;
@@ -5868,7 +5481,7 @@
resetTimers = false;
}
- paramsData = OSData::withValue(params);
+ paramsData = OSData::withBytes(¶ms, sizeof(params));
if (paramsData) {
setProperty(kIOPMSystemSleepParametersKey, paramsData.get());
}
@@ -6068,7 +5681,6 @@
{
AbsoluteTime startTime, elapsedTime;
uint32_t deltaTime;
- bool nvramSync = false;
memset(&gHaltRestartCtx, 0, sizeof(gHaltRestartCtx));
gHaltRestartCtx.RootDomain = this;
@@ -6080,14 +5692,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:
@@ -6102,10 +5712,6 @@
default:
return;
- }
-
- if (nvramSync) {
- PESyncNVRAM();
}
gHaltRestartCtx.phase = kNotifyPriorityClients;
@@ -6443,17 +6049,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 +6122,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 +6178,7 @@
if ((kSystemTransitionCapability == _systemTransitionType) &&
(_pendingCapability == _currentCapability)) {
// Cancel the PM state change.
- setSystemTransitionTypeGated(kSystemTransitionNone);
+ _systemTransitionType = kSystemTransitionNone;
*inOutChangeFlags |= kIOPMNotDone;
}
if (__builtin_popcount(_pendingCapability) <
@@ -6693,12 +6287,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 +6326,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 +6341,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 +6348,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 +6363,7 @@
IOPMPowerChangeFlags changeFlags )
{
if (kSystemTransitionNewCapClient == _systemTransitionType) {
- setSystemTransitionTypeGated(kSystemTransitionNone);
+ _systemTransitionType = kSystemTransitionNone;
return;
}
@@ -6923,24 +6457,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 +6510,7 @@
tracePoint( kIOPMTracePointSystemUp );
}
- setSystemTransitionTypeGated(kSystemTransitionNone);
-
+ _systemTransitionType = kSystemTransitionNone;
_systemMessageClientMask = 0;
toldPowerdCapWillChange = false;
@@ -7596,7 +7111,7 @@
return kIOReturnBadArgument;
}
- data = OSData::withValue(*calendar);
+ data = OSData::withBytes((void *) calendar, sizeof(*calendar));
if (!data) {
return kIOReturnNoMemory;
}
@@ -7837,29 +7352,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 +7364,6 @@
err = kPMChildPreventSystemSleep; // 4. child prevent system sleep clamp
break;
}
-
if (getPMAssertionLevel( kIOPMDriverAssertionCPUBit ) ==
kIOPMDriverAssertionLevelOn) {
@@ -7951,106 +7442,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,50 +7583,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,7 +7623,7 @@
// assumes WAKEEVENT_LOCK
bool
-IOPMrootDomain::aotShouldExit(bool software)
+IOPMrootDomain::aotShouldExit(bool checkTimeSet, bool software)
{
bool exitNow = false;
const char * reason = "";
@@ -8286,6 +7639,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,13 +7675,13 @@
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 +7715,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 +7748,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 +7760,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 +7777,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 +7824,6 @@
}
}
-TUNABLE(bool, test_sleep_in_vm, "test_sleep_in_vm", false);
-
//******************************************************************************
// dispatchPowerEvent
//
@@ -8499,14 +7852,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 +7943,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 +7993,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 +8013,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 +8209,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 +8750,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 +8761,7 @@
startIdleSleepTimer(idleMilliSeconds);
#endif
}
- } else if (!extraSleepDelay && !idleSleepTimerPending && !systemDarkWake && !gNoIdleFlag) {
+ } else if (!extraSleepDelay && !idleSleepTimerPending && !systemDarkWake) {
sleepASAP = true;
}
}
@@ -9735,7 +9058,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 +9142,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 +9744,7 @@
IOLockLock(l);
IOLockLock(l);
}
-#endif /* DEVELOPMENT || DEBUG */
+#endif
}
int
@@ -11023,19 +10348,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 +10357,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 +10401,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 +10531,6 @@
WAKEEVENT_UNLOCK();
}
-void
-IOPMrootDomain::copyShutdownTime( uint64_t * time )
-{
- WAKEEVENT_LOCK();
- *time = gShutdownTime;
- WAKEEVENT_UNLOCK();
-}
-
//******************************************************************************
// acceptSystemWakeEvents
//
@@ -11377,7 +10556,6 @@
_systemWakeEventsArray->flushCollection();
}
}
- _aotWakeEventRunMode = 0;
// Remove stale WakeType property before system sleep
removeProperty(kIOPMRootDomainWakeTypeKey);
@@ -11460,21 +10638,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
@@ -11495,7 +10682,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 +10728,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 +10739,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 +10770,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 +10790,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 +10964,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 +10981,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 +10998,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 +11020,7 @@
void
PMAssertionsTracker::updateCPUBitAccounting( PMAssertStruct *assertStruct )
{
- AbsoluteTime now, elapsed;
+ AbsoluteTime now;
uint64_t nsec;
if (((assertStruct->assertionBits & kIOPMDriverAssertionCPUBit) == 0) ||
@@ -11934,11 +11028,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 +11043,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 +11056,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 +11113,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 +11125,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 +11150,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 +11184,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 +11202,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 +11291,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 +11368,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 +11481,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 +11908,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 +12172,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 +12229,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 +12253,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 +12300,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 +12337,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);
}
}