]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IOHibernateIO.cpp
xnu-2422.110.17.tar.gz
[apple/xnu.git] / iokit / Kernel / IOHibernateIO.cpp
index 83ab5e70320179cb38d0dfcf3c571b07debedeb5..851adac6035d329bc50785a11bf56e6cfbac0d96 100644 (file)
@@ -227,7 +227,7 @@ static IOReturn IOHibernateDone(IOHibernateVars * vars);
 
 enum { kXPRamAudioVolume = 8 };
 enum { kDefaultIOSize = 128 * 1024 };
-enum { kVideoMapSize  = 32 * 1024 * 1024 };
+enum { kVideoMapSize  = 80 * 1024 * 1024 };
 
 #ifndef kIOMediaPreferredBlockSizeKey
 #define kIOMediaPreferredBlockSizeKey  "Preferred Block Size"
@@ -240,9 +240,6 @@ enum { kVideoMapSize  = 32 * 1024 * 1024 };
 #define kIOSelectedBootDeviceKey       "boot-device"
 #endif
 
-
-enum { kIOHibernateMinPollersNeeded = 2 };
-
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 // copy from phys addr to MD
@@ -741,7 +738,8 @@ IOPolledFileOpen( const char * filename, uint64_t setFileSize,
 
        IORegistryEntry * next;
        IORegistryEntry * child;
-       OSData * data;
+       IOService       * service;
+       OSData          * data;
 
         vars->pollers = OSArray::withCapacity(4);
        if (!vars->pollers)
@@ -765,6 +763,11 @@ IOPolledFileOpen( const char * filename, uint64_t setFileSize,
            }
             else if ((poller = OSDynamicCast(IOPolledInterface, obj)))
                 vars->pollers->setObject(poller);
+
+           if ((service = OSDynamicCast(IOService, next)) 
+               && service->getDeviceMemory()
+               && !vars->pollers->getCount())  break;
+
            if ((num = OSDynamicCast(OSNumber, next->getProperty(kIOMediaPreferredBlockSizeKey))))
                vars->blockSize = num->unsigned32BitValue();
             child = next;
@@ -775,9 +778,10 @@ IOPolledFileOpen( const char * filename, uint64_t setFileSize,
        if (vars->blockSize < 4096) vars->blockSize = 4096;
 
        HIBLOG("hibernate image major %d, minor %d, blocksize %ld, pollers %d\n",
-                   major(hibernate_image_dev), minor(hibernate_image_dev), (long)vars->blockSize, vars->pollers->getCount());
+                   major(hibernate_image_dev), minor(hibernate_image_dev), (long)vars->blockSize, 
+                   vars->pollers->getCount());
 
-       if (vars->pollers->getCount() < kIOHibernateMinPollersNeeded)
+       if (!vars->pollers->getCount())
        {
             err = kIOReturnUnsupported;
            continue;
@@ -1258,11 +1262,13 @@ IOHibernateSystemSleep(void)
            bzero(&consoleInfo, sizeof(consoleInfo));
            IOService::getPlatform()->getConsoleInfo(&consoleInfo);
 
-           // estimate: 5% increase in pages compressed
+           // estimate: 6% increase in pages compressed
            // screen preview 2 images compressed 50%
-           setFileSize = ((ptoa_64((105 * pageCount) / 100) * gIOHibernateCompression) >> 8)
+           setFileSize = ((ptoa_64((106 * pageCount) / 100) * gIOHibernateCompression) >> 8)
                                + vars->page_list->list_size
-                               + (consoleInfo.v_width * consoleInfo.v_height * 4);
+                               + (consoleInfo.v_width * consoleInfo.v_height * 8);
+           enum { setFileRound = 1024*1024ULL };
+           setFileSize = ((setFileSize + setFileRound) & ~(setFileRound - 1));
 
            HIBLOG("hibernate_page_list_setall preflight pageCount %d est comp %qd setfile %qd min %qd\n", 
                    pageCount, (100ULL * gIOHibernateCompression) >> 8,
@@ -1280,6 +1286,7 @@ IOHibernateSystemSleep(void)
         err = IOPolledFileOpen(gIOHibernateFilename, setFileSize, vars->ioBuffer,
                                 &vars->fileVars, &vars->fileExtents, &data, 
                                 &vars->volumeCryptKey[0]);
+
         if (KERN_SUCCESS != err)
         {
            HIBLOG("IOPolledFileOpen(%x)\n", err);
@@ -2654,7 +2661,14 @@ hibernate_write_image(void)
             }
         }
         if (kIOReturnSuccess != err)
+        {
+            if (kIOReturnOverrun == err)
+            {
+               // update actual compression ratio on not enough space
+                gIOHibernateCompression = (compressedSize << 8) / uncompressedSize;
+            }
             break;
+        }
 
         // Header:
     
@@ -2923,9 +2937,13 @@ hibernate_machine_init(void)
     {
         vars->videoMapSize = round_page(gIOHibernateGraphicsInfo->height 
                                         * gIOHibernateGraphicsInfo->rowBytes);
-        IOMapPages(kernel_map, 
-                    vars->videoMapping, gIOHibernateGraphicsInfo->physicalAddress,
-                    vars->videoMapSize, kIOMapInhibitCache );
+       if (vars->videoMapSize > vars->videoAllocSize) vars->videoMapSize = 0;
+       else
+       {
+           IOMapPages(kernel_map, 
+                       vars->videoMapping, gIOHibernateGraphicsInfo->physicalAddress,
+                       vars->videoMapSize, kIOMapInhibitCache );
+       }
     }
 
     if (vars->videoMapSize)
@@ -3105,6 +3123,12 @@ void IOHibernateSetWakeCapabilities(uint32_t capability)
     if (kIOHibernateStateWakingFromHibernate == gIOHibernateState)
     {
        gIOHibernateStats->wakeCapability = capability;
+
+       if (kIOPMSystemCapabilityGraphics & capability)
+       {
+               vm_compressor_do_warmup();
+       }
+
     }
 }